阐明 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 状态代码

R语言重要数据集分析研究——需要整理分析阐明理念

阐明在函数签名中将两个对不同范围的引用对象的引用绑定到相同生命周期的含义

VCP认证怎么虚拟化?