0

非同期 WinInet を使用する非常に単純な小さなコード サンプルがあるとします。

#include "stdafx.h"
#include "WinInet.h"
#pragma comment(lib, "wininet.lib")

DWORD LatestResult = 0;
HANDLE MayContinue = 0;

VOID CALLBACK
  CallBack(
  __in HINTERNET hInternet,
  __in DWORD_PTR dwContext,
  __in DWORD dwInternetStatus,
  __in_bcount(dwStatusInformationLength) LPVOID lpvStatusInformation,
  __in DWORD dwStatusInformationLength
  )
{
  if (dwInternetStatus == INTERNET_STATUS_REQUEST_COMPLETE)
  {
    LatestResult = ((LPINTERNET_ASYNC_RESULT)lpvStatusInformation)->dwResult;
    SetEvent (MayContinue);
  }
}

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                       _In_opt_ HINSTANCE hPrevInstance,
                       _In_ LPTSTR    lpCmdLine,
                       _In_ int       nCmdShow)
{
  MayContinue = ::CreateEvent (NULL, FALSE, FALSE, NULL);
  HINTERNET Session = InternetOpen (NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
  INTERNET_STATUS_CALLBACK CallbackPointer = InternetSetStatusCallback (Session, (INTERNET_STATUS_CALLBACK) CallBack);

  MayContinue = ::CreateEvent (NULL, FALSE, FALSE, NULL);
  InternetConnect (Session, _T ("ftp.secureftp-test.com"), INTERNET_INVALID_PORT_NUMBER, _T ("test"), _T ("test"), INTERNET_SERVICE_FTP, 0, 1);

  WaitForSingleObject (MayContinue, INFINITE);
  HINTERNET Internet = (HINTERNET) LatestResult;

  WIN32_FIND_DATA *FindData = new WIN32_FIND_DATA;
  FtpFindFirstFileW (Internet, _T ("*.*"), FindData, 0, 1);
  WaitForSingleObject (MayContinue, INFINITE);
  delete FindData;
  return 0;
}

実行後に得たもの:

Unhandled exception at 0xBAADF00D in WinInetTest.exe: 
0xC0000005: Access violation     executing location 0xBAADF00D.

それは最終的な WaitForSingleObject のどこかで発生し、コールスタックはかなり混乱します。

でも私が変われば

WIN32_FIND_DATA *FindData = new WIN32_FIND_DATA;
FtpFindFirstFileW (Internet, _T ("*.*"), FindData, 0, 1);

WIN32_FIND_DATAA *FindData = new WIN32_FIND_DATAA;
FtpFindFirstFileA (Internet, "*.*", FindData, 0, 1);

それは実行され、正常に機能します。だから私の質問は - 私は本当に正しく何かをしていないのですか、それとも WinInet 側で失敗しただけですか?

Visual Studio 2012 btwを使用して、Windows 7でテストしています。

4

2 に答える 2

1

FtpFindFirstFileW にも問題がありました。プロジェクトを MBCS から Unicode に変換すると、FtpFindFirstFileW によってアクセス違反が発生しました。これは、おそらく非同期の結果が準備されているときに、呼び出し後のどこかで 0xbaadf00d のポインター逆参照のように見えました。MBCS ビルドと Unicode ビルドの両方で、FtpFindFirstFileA、InternetFindNextFileA、および WIN32_FIND_DATAA 構造体を使用して、この問題を回避しました。次に、出力 cFileName フィールドを TCHAR 文字列に変換します。

于 2014-03-03T13:47:25.743 に答える