Что может вызвать ошибку ERROR_INTERNET_INCORRECT_HANDLE_TYPE (12018) с InternetQueryOption?
Я работаю над простой маленькой функцией для загрузки файла с веб-сайта с поддержкой SSL с использованием функций WinInet, а именно InternetOpen и InternetOpenURL. Первоначально я не смог позвонить в InternetOpenURL с ERROR_INTERNET_INVALID_CA
(12045), потому что я использовал самозаверяющий сертификат на своем тестовом сервере и обнаружил ( http://support.microsoft.com/kb/q182888/), что исправление, по-видимому, заключается в использовании комбинации InternetQueryOption / InternetSetOption для передать различные флаги INTERNET_OPTION_SECURITY_FLAGS
вариант. Теперь, однако, InternetQueryOption не удается с ERROR_INTERNET_INCORRECT_HANDLE
(12018) ответ от GetLastError(). Есть идеи, почему это так? Я использую дескриптор, полученный непосредственно из InternetOpen, который ранее работал нормально с InternetOpenURL без SSL. Разве это не должно быть правильной ручкой?
У меня нет фактического кода (другой компьютер), но он очень похож на следующий, и происходит сбой в InternetGetOption с ERROR_INTERNET_INCORRECT_HANDLE
:
HINTERNET hReq = InternetOpen(...)
if (!hReq) { printf("InternetOpen Error: %d", GetLastError()); }
DWORD dwFlags = 0;
DWORD dwBuffLen = sizeof(dwFlags);
BOOL ret = false;
ret = InternetQueryOption(hReq, INTERNET_OPTION_SECURITY_FLAGS,
(LPVOID)&dwFlags, &dwBuffLen);
if (!ret) { printf("InternetQueryOption Error: %d", GetLastError()); }
dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
ret = InternetSetOption(hReq, INTERNET_OPTION_SECURITY_FLAGS,
&dwFlags, sizeof (dwFlags) );
if (!ret) { printf("InternetSetOption Error: %d", GetLastError()); }
InternetOpenURL(hReq, ...)
4 ответа
Я имел обыкновение получать подобную ошибку. Затем я передал дескриптор, возвращенный HttpOpenRequest(...) в InternetQueryOption, и он работал просто отлично. Попробуйте это.
Из документов MSDN для INTERNET_OPTION_SECURITY_FLAGS:
Имейте в виду, что полученные таким образом данные относятся к транзакции, которая произошла, уровень безопасности которой больше не может быть изменен.
В вашем дескрипторе еще не было транзакции InternetOpen дает вам корневой дескриптор HINTERNET. Это может применяться к соединениям HTTP, FTP или Gopher - тогда как параметры безопасности довольно специфичны для HTTPS и в значительной степени зависят от того, что поддерживает удаленный сервер. Таким образом, вы спрашиваете у Wininet информацию, которую он не может вам предоставить.
Я сделал это, просто (случайно) выбрал для краткости. Таким образом, здесь будет весь "пример" кода:
HINTERNET hReq = InternetOpen(...)
if (!hReq) { printf("InternetOpen Error: %d", GetLastError()); }
DWORD dwFlags = 0;
DWORD dwBuffLen = sizeof(dwFlags);
BOOL ret = false;
InternetQueryOption(hReq, INTERNET_OPTION_SECURITY_FLAGS,
(LPVOID)&dwFlags, &dwBuffLen);
if (!ret) { printf("InternetGetOption Error: %d", GetLastError()); }
dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
ret = InternetSetOption(hReq, INTERNET_OPTION_SECURITY_FLAGS,
&dwFlags, sizeof (dwFlags) );
if (!ret) { printf("InternetSetOption Error: %d", GetLastError()); }
InternetOpenURL(hReq, ...)
Кроме того, я могу использовать этот же дескриптор HINTERNET (hReq) с InternetOpenURL для загрузки файла с веб-сервера, не поддерживающего SSL (т. Е. С использованием прямого HTTP), что, по-видимому, указывает на то, что это хороший дескриптор. Является ли мое использование или понимание InternetQueryOption недействительным?
Я вижу, вы не проверяете hReq
ты вернулся из InternetOpen
, Возможно, это корень вашей проблемы. Посмотрите, что это говорит вам, если вы добавите его сразу после звонка InternetOpen
:
if (hReq == NULL) {
printf("InternetOpen Error: %d", GetLastError());
}