TIA !! WriteFile()
上FILE_FLAG_OVERLAPPED的文档说,您必须提供OVERLAP并为lpNumberOfBytesWritten
建议使用NULL,因为值会产生误导。但是GetOverlappedResult()
的文档说只有在WriteFile()
返回FALSE并带有ERROR_IO_PENDING时才调用。这样就剩下了ReadFile()
/ WriteFile()
在API调用本身中完成的情况。您应该如何获得读取/写入的字节数?你以为是要求的电话号码吗?但是WriteFile()
说:“当写入缓冲区空间不足的非阻塞字节模式管道句柄时,WriteFile返回TRUE,并带有* lpNumberOfBytesWritten
答案 0 :(得分:2)
如果 hFile 是用
FILE_FLAG_OVERLAPPED
打开的lpNumberOfBytesWritten
参数应设置为 NULL 。
这不是真的(错误或说谎)。可以将 lpNumberOfBytesWritten 设置为 NULL ,但不应该。如果 *lpNumberOfBytesWritten
中I / O请求完成并成功完成同步,将是有效字节数。
还请注意,lpNumberOfBytes
一定不能指向在操作完成之前才有效的位置(例如 lpOverlapped
)-它可以指向例如到函数中的局部变量,您可以在I / O完成之前从函数退出-这也可以。系统只需将InternalHigh
从OVERLAPPED
复制到 *lpNumberOfBytes
。所以在伪代码中:
if (lpNumberOfBytes) *lpNumberOfBytes = (ULONG)lpOverlapped->InternalHigh;
仅当I / O已成功完成时, *lpNumberOfBytes
中的正确的正确值。因此,只能在这种情况下使用。系统不记得 lpNumberOfBytes
的值-因为它必须仅在[Write|Read]File
调用期间有效,而在I / O活动期间无效(如果异步I / O)
GetOverlappedResult
,如果I / O请求成功完成并成功同步(在ReadFile
或WriteFile
,如果返回TRUE
的情况下),则可以调用是否返回未决。仅在I / O请求只是失败(ReadFile
或WriteFile
返回FALSE
和GetLastError() != ERROR_IO_PENDING
)的情况下,才能调用此api
因此,如果api成功完成,最好将始终不传递0 lpNumberOfBytes 到api并使用它。否则,请使用GetOverlappedResult
,或者如果您说要使用BindIoCompletionCallback
-您直接在回调函数中获得了dwNumberOfBytesTransfered
。
因此在概念上可以使用下一个代码:
inline ULONG BOOL_TO_ERROR(BOOL f)
{
return f ? NOERROR : GetLastError();
}
HANDLE hFile = CreateFile(*, FILE_GENERIC_READ, FILE_SHARE_READ, 0,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
UCHAR buf[0x200];
OVERLAPPED ov = {};
ULONG NumberOfBytesRead;
ULONG dwError = BOOL_TO_ERROR(ReadFile(hFile, buf, sizeof(buf), &NumberOfBytesRead, &ov));
switch (dwError)
{
case ERROR_IO_PENDING:
dwError = BOOL_TO_ERROR(GetOverlappedResult(hFile, &ov, &NumberOfBytesRead, TRUE));
if (dwError != NOERROR) goto __default;
[[fallthrough]];
case NOERROR:
DbgPrint("NumberOfBytesRead=%x\n", NumberOfBytesRead);
// use GetOverlappedResult(hFile, &ov, &NumberOfBytesRead, TRUE) here also possible
break;
__default:
default:
DbgPrint("dwError = %u\n", dwError);
}
CloseHandle(hFile);
}