4


C でいくつかの WinHttp コードを書いています。SSL 経由でリクエストを送信しています。SSL エラーを処理するために、dwNotificationFlags を WINHTTP_CALLBACK_STATUS_SECURE_FAILURE に設定して WinHttpSetStatusCallbackを呼び出して、WINHTTP_STATUS_CALLBACK 関数を登録しています。

WINHTTP_STATUS_CALLBACK のドキュメントによると、コールバックがdwInternetStatus= WINHTTP_CALLBACK_STATUS_SECURE_FAILURE で呼び出されると、それは

サーバーから SSL (Secure Sockets Layer) 証明書を取得中に、1 つ以上のエラーが発生しました。lpvStatusInformation パラメータにはフラグが含まれています。詳細については、lpvStatusInformation の説明を参照してください。

現在、lpvStatusInformationパラメーターは LPVOID として入力されています。しかし、ドキュメントのそのステートメントから、WINHTTP_CALLBACK_STATUS_SECURE_FAILURE の場合はポインターとして扱われないことが分かります。

のドキュメントは次のようにlpvStatusInformation述べています。

dwInternetStatus パラメータが WINHTTP_CALLBACK_STATUS_SECURE_FAILURE の場合、このパラメータは次のいずれかの値になります。

...そして、これらの値は 16 進値の 1 つです: 1、2、4、8、10、20、40。(WinHttp.h を参照)

これは私にはかなり明確に思えます。値を取得するためにポインターを逆参照するべきではありません。これ lpvStatusInformationは、ポインターではなく、16 進値を保持します。

これを正しく解釈していますか?


私はそのようにコードを書きましたが、過去には機能していました。おもう!しかし今、私はlpvStatusInformation0x0104f288 を取得しています。これは、これらの 16 進値とはまったく異なります。また、可能な値を OR してその値を作成することもできません (ドキュメントには、同じ 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 に答える