4


我正在用 C 编写一些 WinHttp 代码。我正在通过 SSL 发送请求,并且为了处理 SSL 错误,我正在注册一个WINHTTP_STATUS_CALLBACK 函数,通过调用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不是指针。

我是否正确解释了这一点?


我用这种方式编写了我的代码,并且它在过去一直有效。我认为!但是现在我得到了lpvStatusInformation0x0104f288。这与任何十六进制值都不一样。也不可能通过 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);
    }
}
4

1 回答 1

6

文档有点误导。 lpvStatusInformation是指向标志值的指针。我们一直将它转换为 DWORD* 并取消引用它,我们得到的值与文档中的标志值相匹配。

于 2011-06-17T22:53:26.347 回答