在异步模式下使用 FtpFindFirstFile unicode 版本的访问冲突
Posted
技术标签:
【中文标题】在异步模式下使用 FtpFindFirstFile unicode 版本的访问冲突【英文标题】:Access violation using FtpFindFirstFile unicode version in async mode 【发布时间】:2013-05-03 12:04:47 【问题描述】:假设我有一个使用异步 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 上对其进行测试。
【问题讨论】:
您应该说明您是在 Unicode(16 位字符)模式还是 ANSI(8 位字符)模式下编译。此外,您的“如果我改变”位将函数从FtpFindFirstFileW
首次引用到 FtpFindFirstFile
,因此其中一个是错误的。
@Bryan 是的,显然我是在 Unicode 模式下构建的,所以这都是关于 FtpFindFirstFileW
。
【参考方案1】:
我在使用 FtpFindFirstFileW 时也遇到了困难。当我将我的项目从 MBCS 转换为 Unicode 时,FtpFindFirstFileW 导致访问冲突,这似乎是调用后某处的 0xbaadf00d 指针取消引用,可能是在准备异步结果时。我通过在 MBCS 和 Unicode 构建中使用 FtpFindFirstFileA、InternetFindNextFileA 和 WIN32_FIND_DATAA 结构来解决这个问题。然后我将输出 cFileName 字段转换为 TCHAR 字符串。
【讨论】:
是的,看起来这是来自 Miscrosoft 的错误)实际上我已经完全放弃了使用异步 WinInet 来处理这些东西,因为缺乏好的文档,我只是无法弄清楚一些事情。 我正在将几个项目从 MBCS 迁移到 Unicode,并且我不想重写在 MBCS 构建中运行良好的异步 FTP 客户端代码。这种解决方法对我来说是一个破坏性较小的选择。我在 7 年前写它的时候经历了这一切,我不想再做一遍......【参考方案2】:我建议将编译器设置字符集从 Unicode 更改为多字节字符集。同样的事情也发生在我身上。
【讨论】:
以上是关于在异步模式下使用 FtpFindFirstFile unicode 版本的访问冲突的主要内容,如果未能解决你的问题,请参考以下文章
Android MediaCodec在异步模式下比在同步模式下慢吗?
powershell 在异步模式下使用Start-BitsTransfer下载文件
在异步模式下使用 MediaCodec,问题是,我没有得到 MediaCodec.BUFFER_FLAG_END_OF_STREAM