Что может вызвать ошибку 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());
}
Другие вопросы по тегам