在异步模式下使用FtpFindFirstFile unicode版本访问违反



假设我有一个非常简单的代码示例使用异步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.

它发生在final WaitForSingleObject的某个地方,callstack相当令人困惑。

但是如果我改变
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方面?

我正在Windows 7上使用Visual Studio 2012进行测试。

我使用FtpFindFirstFileW也有困难。当我将我的项目从MBCS转换为Unicode时,FtpFindFirstFileW导致访问冲突,似乎是调用后某个地方的0xbaadf00d的指针解引用,可能是在准备异步结果时。我通过在MBCS和Unicode构建中使用FtpFindFirstFileA, InternetFindNextFileA和WIN32_FIND_DATAA结构体来解决这个问题。然后将输出的cFileName字段转换为TCHAR字符串。

我建议将编译器设置字符集从Unicode改为多字节字符集。同样的事情也发生在我身上。

最新更新