为什么WinInet的InternetErrorDlg无法正确处理ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED?

时间:2018-05-24 01:14:33

标签: delphi wininet

我正在尝试使用以下函数处理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函数返回的Open Request Handle。第二个是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_CLIENT_AUTH_CERT_NEEDED
  6. CallInternetErrorDialog(ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED,HttpOpenRequestHandle);
  7. 从第4步开始重复;
  8. GetLastError = ERROR_INTERNET_SECURITY_CHANNEL_ERROR
  9. 结束
  10. 步骤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,而不向用户显示任何内容,那么,ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED错误的处理方式是什么?

    步骤8中的错误是绝对自然的,因为在服务器发送ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED之后,它等待下一次尝试(HttpSendRequest)已经加载了有效证书。这证明InternetErrorDlg函数尽管取得了成功,却没有做到它应该做的事情

    请再次查看CallInternetErrorDialog以获取更多信息。

0 个答案:

没有答案
相关问题