澄清WINHTTP_STATUS_CALLBACK函数的用法,用于SSL状态代码

Che*_*eso 3 winhttp


我在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保持的十六进制值,而不是一个指针.

我能正确地解释这个吗?


我已经用这种方式编写了代码,并且它在过去也有用.我认为!但是现在我得到的lpvStatusInformation是0x0104f288.这与任何十六进制值都没有任何关系.也不可能通过对可能的值进行OR运算来创建该值(尽管doc在同一个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);
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 6

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