Почему WinEnet InternetErrorDlg неправильно обрабатывает ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED? - PullRequest
0 голосов
/ 24 мая 2018

Я пытаюсь обработать ошибку ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED, используя следующую функцию:

function CallInternetErrorDialog(AInetOpenRequest: HINTERNET; ALastError: DWORD): DWORD;
var
  P: Pointer;
begin
  Result := InternetErrorDlg(GetDesktopWindow()
                            ,AInetOpenRequest
                            ,ALastError
                            ,FLAGS_ERROR_UI_FILTER_FOR_ERRORS or FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS or FLAGS_ERROR_UI_FLAGS_GENERATE_DATA
                            ,P);

  // Only to check result (this is not important right now)
  case Result of
    ERROR_SUCCESS: OutputDebugString('ERROR_SUCCESS');
    ERROR_CANCELLED: OutputDebugString('ERROR_CANCELLED');
    ERROR_INTERNET_FORCE_RETRY: OutputDebugString('ERROR_INTERNET_FORCE_RETRY');
    ERROR_INVALID_HANDLE: OutputDebugString('ERROR_INVALID_HANDLE');
  end;

  if ALastError = ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED then
    Result := ERROR_INTERNET_FORCE_RETRY;
end;

Это просто вспомогательная функция, построенная на основе функции InternetErrorDlg, и она очень проста с двумя параметрами.Первый - это дескриптор открытого запроса, возвращаемый функцией HttpOpenRequest.Второй - результат функции GetLastError.

В моей реализации, когда GetLastError возвращает ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED, я вызываю эту функцию следующим образом (пример):

CallInternetErrorDialog(OpenRequestHandle,ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED)

Поведение, которое я ожидалбыло ли диалоговое окно выбора сертификата системы по умолчанию, показываемое пользователю, выбрать какой-либо сертификат:

Select Certificate Dialog

Однако внутренний вызов InternetErrorDlg возвращает только ноль (ERROR_SUCCESS)немедленно, без показа чего-либо.

Для тех, кто требует полный исходный код, здесь идет дорожная карта.Я не буду помещать весь код, потому что это очень экстенсивно.Полный блок содержит более 800 строк кода:

  1. InternetOpenHandle: = InternetOpen (...);
  2. InternetConnectHandle: = InternetConnect (InternetOpenHandle, ...);
  3. HttpOpenRequestHandle: = HttpOpenRequest (InternetConnectHandle, ...);
  4. HttpSendRequestResult: = HttpSendRequest (HttpOpenRequestHandle, ...);
  5. GetLastError = ERROR_INTERNET_SECURITY_CHANNEL_ERROR
  6. Конец

шаг 6 называют свою функцию, которая простовызовите InternetErrorDlg со следующими (уже замененными) параметрами:

InternetErrorDlg(GetDesktopWindow()
                ,HttpOpenRequestHandle
                ,ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED
                ,FLAGS_ERROR_UI_FILTER_FOR_ERRORS or FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS or FLAGS_ERROR_UI_FLAGS_GENERATE_DATA
                ,P);

С этими параметрами функция InternetErrorDlg немедленно возвращает ERROR_SUCCESS, не показывая ничего пользователю, так чтоtratament было сделано для ошибки ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED?

Ошибка на восьмом шаге абсолютно естественна, потому чтоПосле отправки сервером ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED он ожидает загрузки следующей попытки (HttpSendRequest) с действующим сертификатом.Это доказывает, что функция InternetErrorDlg, несмотря на ваш успешный результат, не делает то, что должна

Пожалуйста, обратитесь к CallInternetErrorDialog снова для получения дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...