Я пишу некоторый код WinHttp на C. Я отправляю запросы по SSL, и для обработки ошибок SSL я регистрирую функцию WINHTTP_STATUS_CALLBACK через вызов WinHttpSetStatusCallback с dwNotificationFlags, установленным в WINHTTP_CALLBACK_STATUS_SECURE_FAILURE.
В документации для WINHTTP_STATUS_CALLBACK говорится, что когда обратный вызов вызывается с dwInternetStatus
= WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, это указывает, что
Обнаружена одна или несколько ошибок при получении сертификата Secure Sockets Layer (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. Это не похоже ни на одно из этих шестнадцатеричных значений. Также невозможно создать это значение с помощью ИЛИ возможных значений (хотя в документе ничего не сказано о нескольких элементах состояния в одном и том же 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);
}
}