Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
321 views
in Technique[技术] by (71.8m points)

c++ - Access violation using FtpFindFirstFile unicode version in async mode

Let's say I have very simple little code sample which uses async 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;
}

What I've got after execution:

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

It happens somewhere around final WaitForSingleObject and callstack is rather confusing.

But if I change

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

to

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

It executes and works as it should. So my question is - am I really not doing something correctly or it just failure on WinInet side?

I'm testing it on Windows 7 using Visual Studio 2012 btw.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I also had difficulty with FtpFindFirstFileW. When I converted my project from MBCS to Unicode FtpFindFirstFileW resulted in an access violation that appeared to be a pointer dereference of 0xbaadf00d somewhere after the call, possibly when the async result was being prepared. I worked around this by using FtpFindFirstFileA, InternetFindNextFileA and the WIN32_FIND_DATAA struct in both MBCS and Unicode builds. I then convert the output cFileName field to a TCHAR string.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...