使用WinInet :: InternetSetOption()始终返回false,GetLastError()返回12018

时间:2014-01-07 12:29:12

标签: winapi visual-c++ wininet

我想让ie的IWebBrowser不需要选择证书,所以我使用InternetSetOption()来做。代码是:

HCERTSTORE hMyStore = CertOpenSystemStore(0, _T("MY");
PCCERT_CONTEXT pDesiredCert = NULL;
pDesiredCert=CertFindCertificateInStore( 
    hMyStore, 
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
    CERT_FIND_SUBJECT_STR,
    L"cnstr",
    NULL);

if (InternetSetOption (NULL, INTERNET_OPTION_CLIENT_CERT_CONTEXT, 
        (LPVOID)pDesiredCert, sizeof(CERT_CONTEXT)) == FALSE) { 
    DOWRD i = GetLastError(); 
} 
...

我在“我的”商店获得了证书。当我使用InternetSetOption()设置证书时,它返回false,错误代码是12018.我搜索了一些有关此错误代码的信息:

  

“12018 ERROR_INTERNET_INCORRECT_HANDLE_TYPE此操作提供的句柄类型不正确。”

我想设置全局设置,所以我将NULL设置为第一个参数,函数InternetSetOption()中的第一个参数是不是NULL?我怎样才能正确设置选项?

2 个答案:

答案 0 :(得分:1)

正如您已经说过的,您不能将NULL用于INTERNET_OPTION_CLIENT_CERT_CONTEXT选项。虽然,某些选项可以拥有NULL值,例如INTERNET_OPTION_CONNECT_RETRIESINTERNET_OPTION_DATA_RECEIVE_TIMEOUT,但它不能。

Option Flags

您必须使用HINTERNETInternetOpen()来使用有效的InternetConnect()。 以下链接将指导您有效HINTERNET' HINTERNET处理范围'部分。

Setting and Retrieving Internet Options

而且,您还必须检查hMyStorepDesiredCert值是否为NULL

**编辑:**

使用HINTERNET无法获得IWebBrowser2。它只暴露了WebBrowser控件的方法和属性。因此,您必须使用InternetConnect()

  

例如,每次应用程序尝试访问Internet资源时,需要具有身份验证的代理的客户端应用程序可能不需要设置代理用户名和密码。如果给定连接上的所有请求都由同一代理处理,则在连接类型HINTERNET句柄上设置代理用户名和密码,即通过调用InternetConnect创建的句柄,将允许从此HINTERNET句柄派生的任何调用使用相同的代理用户名和密码。每次HttpOpenRequest创建HINTERNET句柄时设置代理用户名和密码都需要额外的不必要的开销。请注意,如果应用程序使用需要身份验证的代理,则应在每个新连接上设置代理凭据。

http://msdn.microsoft.com/en-us/library/windows/desktop/aa385384(v=vs.85).aspx

我还写了一些有关如何使用InternetConnect()的有用参考链接。

C++ WinHTTP InternetReadFile not retrieving entire source

SSL with WinHTTP

答案 1 :(得分:0)

我相信应用的答案是正确的。虽然存在另一个问题,但它以类似的方式表现出来 如果未正确定义常量INTERNET_OPTION_CLIENT_CERT_CONTEXT,则可能会出现错误" INCORRECT_HANDLE_TYPE"在这种情况下,你只会传递错误的选项。 WinInet中的正确值为84(dec)

#define INTERNET_OPTION_CLIENT_CERT_CONTEXT 84

WinHttp中的相应常量应为

#define WINHTTP_OPTION_CLIENT_CERT_CONTEXT 47

不要混合它们。要小心,好好编码!