阐明 WINHTTP_STATUS_CALLBACK 函数的用法,用于 SSL 状态代码
Posted
技术标签:
【中文标题】阐明 WINHTTP_STATUS_CALLBACK 函数的用法,用于 SSL 状态代码【英文标题】:Clarify usage of WINHTTP_STATUS_CALLBACK function, for SSL status codes 【发布时间】:2011-06-04 19:47:05 【问题描述】:我正在用 C 编写一些 WinHttp 代码。我正在通过 SSL 发送请求,并且为了处理 SSL 错误,我正在注册一个 WINHTTP_STATUS_CALLBACK function,通过调用 WinHttpSetStatusCallback 并将 dwNotificationFlags 设置为 WINHTTP_CALLBACK_STATUS_SECURE_FAILURE。
WINHTTP_STATUS_CALLBACK 的文档说,当使用dwInternetStatus
= WINHTTP_CALLBACK_STATUS_SECURE_FAILURE 调用回调时,它表明
从服务器检索安全套接字层 (SSL) 证书时遇到一个或多个错误。 lpvStatusInformation 参数包含一个标志。有关详细信息,请参阅 lpvStatusInformation 的说明。
现在,lpvStatusInformation
参数被输入为 LPVOID。但是我从文档中的那条语句中得知,在 WINHTTP_CALLBACK_STATUS_SECURE_FAILURE 的情况下,它不被视为指针。
lpvStatusInformation
的文档说:
如果 dwInternetStatus 参数为 WINHTTP_CALLBACK_STATUS_SECURE_FAILURE,则该参数可以是以下值之一。
...这些值是以下十六进制值之一:1,2,4,8,10,20,40。 (见 WinHttp.h)
这对我来说似乎很清楚。我不应该取消引用指针来获取值。 lpvStatusInformation
保存的是十六进制值,而不是指针。
我的解释正确吗?
我是这样编写代码的,而且过去一直有效。我想!但是现在我得到了 0x0104f288 的lpvStatusInformation
。这与任何十六进制值都不一样。也不可能通过 OR'ing 可能的值来创建该值(尽管文档没有说明同一个 DWORD 中的多个状态项)。它确实看起来像是指向我的指针。当我取消引用指针时,我得到 0x8,它对应于 WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA
,这至少是有道理的。
问题是,我是否应该取消引用该指针?
这里是回调代码:
void CALLBACK Iirf_WinHttpSslStatusCallback( HINTERNET hInternet,
DWORD_PTR context,
DWORD code,
void * pInfo,
DWORD infoLength)
if (code == WINHTTP_CALLBACK_STATUS_SECURE_FAILURE)
ConfigInfo * cfg = (ConfigInfo *) context; // app-specific structure
DWORD details = (DWORD) pInfo; // do not de-reference??
CHAR buffer[32];
CHAR * statusDescription = NULL;
switch (details)
case WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED:
statusDescription = "CERT_REV_FAILED";
break;
case WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT:
statusDescription = "INVALID_CERT";
break;
case WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED:
statusDescription = "CERT_REVOKED";
break;
case WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA:
statusDescription = "INVALID_CA";
break;
case WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID:
statusDescription = "CERT_CN_INVALID";
break;
case WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID:
statusDescription = "CERT_DATE_INVALID";
break;
case WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR:
statusDescription = "SECURITY_CHANNEL_ERROR";
break;
default:
statusDescription = buffer;
sprintf_s(buffer, 32, "stat(0x%08X) len(%d)",
details, infoLength);
break;
LogMessage(cfg, 1, "SslStatusCallback: %s", statusDescription);
【问题讨论】:
【参考方案1】:文档有点误导。 lpvStatusInformation
是指向标志值的指针。我们一直将它转换为 DWORD* 并取消引用它,我们得到的值与文档中的标志值相匹配。
【讨论】:
以上是关于阐明 WINHTTP_STATUS_CALLBACK 函数的用法,用于 SSL 状态代码的主要内容,如果未能解决你的问题,请参考以下文章
阐明 Hadoop 与 RabbitMQ+Celery 的用例
阐明 WINHTTP_STATUS_CALLBACK 函数的用法,用于 SSL 状态代码