CredWrite возвращает код ошибки Win32 2 (ERROR_INVALID_FUNCTION) Неверная функция.

я пытаюсь вызвать CredWrite, но он возвращает ERROR_INVALID_FUNCTION. я могу вызвать CredRead, чтобы получить учетные данные из хранилище паролей, и я могу хранить новые учетные данные с помощью CredUIPromptForCredentials .

Но я не могу понять, как заставить CredWrite работать.

Код, который я использую:

var
   Target, Username, Password: WideString;
begin
   Target := 'StackOverflowSomething';
   Username := 'IanBoyd'; 
   Password := 'password69';

   ZeroMemory(@Credentials, SizeOf(Credentials));

   Credentials.TargetName := PWideChar(Target);
   Credentials.Type_ := CRED_TYPE_GENERIC;
   Credentials.UserName := PWideChar(Username);
   Credentials.Persist := CRED_PERSIST_ENTERPRISE;
   Credentials.CredentialBlob := PByte(Password);
   Credentials.CredentialBlobSize := 2*(Length(Password));
   Credentials.UserName := PWideChar(Username);

   if not CredWriteW(@Credentials, 0) then
      RaiseLastWin32Error;

И GetLastError возвращает 1 (ERROR_INVALID_FUNCTION)

Эта функция неверна? Он даже не возвращает ERROR_INVALID_PARAMETER, он возвращает «Неверная функция». Что неверно?

Есть ли какой-нибудь пример кода, который вызывает CredWrite?

Примечания

  • я пытался вызвать версию Ansi (CredWriteA), тот же результат
  • я пробовал использовать CRED_PERSIST_SESSION и CRED_PERSIST_LOCAL_MACHINE в дополнение к CRED_PERSIST_ENTERPRISE

person Ian Boyd    schedule 25.02.2010    source источник
comment
Проголосовал бы за закрытие как неактуальное, потому что, по-видимому, в опубликованном коде нет ничего плохого, но этот вариант больше недоступен. Вместо этого выбрал слишком локализованное, поскольку только Ян знает, что на самом деле произошло.   -  person Rob Kennedy    schedule 26.02.2010
comment
Да, мне не разрешили его удалить; и мой беглый взгляд, хотя список причин показал, что ни одна из причин не была правильной. С другой стороны, вполне функциональный код может быть полезен кому-то еще, кто хочет использовать CredWrite, особенно из Delphi.   -  person Ian Boyd    schedule 27.02.2010


Ответы (3)


Ничего себе, я разобрался.

И это не вина вызова API или моих параметров.

я просто тупой.

И я хочу дуться, не говоря, что я сделал :(

person Ian Boyd    schedule 25.02.2010

Разве это не должно

 Credentials.Type_ := CRED_TYPE_GENERIC;

Быть этим вместо этого?

 Credentials.Type := CRED_TYPE_GENERIC;
person John Knoeller    schedule 25.02.2010
comment
Нет. :-) Type является зарезервированным словом в Delphi, поэтому импорт библиотеки типов вместо этого преобразует Type в Type_, и все переназначается внутри. Хороший глаз, однако. ;-) - person Ken White; 26.02.2010
comment
@Кен Уайт: Хорошо, это имеет смысл. Спасибо за объяснение. - person John Knoeller; 26.02.2010

Мне любопытно, это для смарт-карты, верно? и вы сохраняете пин-код для смарт-карты, возможно, вложение / драйвер не загружены для работы кредитной записи? Возможно, со стандартно определенным аппаратным/программным обеспечением смарт-карты, используемым Windows, активирует функцию CredWrite, я предполагаю, что CredWrite пытается с чем-то связаться (возможно, общий вызов API стандартной функции в аппаратном обеспечении смарт-карты?) ... просто мои мысли...

Надеюсь, это поможет. С уважением, Том.

person t0mm13b    schedule 25.02.2010
comment
Это не для смарт-карты. я храню общие учетные данные. - person Ian Boyd; 26.02.2010