[英]ReadFile and WriteFile with Overlapped IO result if not ERROR_IO_PENDING?
WriteFile()
上FILE_FLAG_OVERLAPPED的文檔說,您必須提供OVERLAP並為lpNumberOfBytesWritten
建議使用NULL,因為值會產生誤導。 但是, GetOverlappedResult()
文檔說僅在WriteFile()
返回FALSE並帶有ERROR_IO_PENDING時才調用。 這樣就WriteFile()
了在API調用本身中ReadFile()
/ WriteFile()
完成的情況。 您應該如何獲得讀取/寫入的字節數? 你以為是要求的電話號碼嗎? 但是WriteFile()
表示“當寫入緩沖區空間不足的無阻塞字節模式管道句柄時,WriteFile返回TRUE,且* lpNumberOfBytesWritten <nNumberOfBytesToWrite”。
TIA!
如果使用
FILE_FLAG_OVERLAPPED
打開hFile,則lpNumberOfBytesWritten
參數應設置為NULL 。
這是不正確的(錯誤或說謊)。 lpNumberOfBytesWritten 可以設置為NULL ,但不應設置為NULL 。 如果*lpNumberOfBytesWritten
I / O請求完成並成功完成同步將是有效字節數。
還要注意lpNumberOfBytes
一定不要指向在操作完成之前才有效的位置(例如lpOverlapped
)-例如,它可以指向函數中的局部變量,並且您可以在I / O完成之前從函數退出-這將是還可以 系統只需將InternalHigh
從OVERLAPPED
復制到*lpNumberOfBytes
。 所以在偽代碼中:
if (lpNumberOfBytes) *lpNumberOfBytes = (ULONG)lpOverlapped->InternalHigh;
*lpNumberOfBytes
正確的正確值僅在I / O已成功完成的情況下才有效。 因此,只能在這種情況下使用。 系統不記得lpNumberOfBytes
值-因為它必須僅在[Write|Read]File
調用期間有效,而在I / O活動期間(在異步I / O的情況下可能更長)才有效
如果I / O請求完成與成功同步(如果ReadFile
或WriteFile
,如果Thay返回TRUE
),或者如果未返回,則可以調用GetOverlappedResult
。 僅在I / O請求只是失敗的情況下才能調用此api( ReadFile
或WriteFile
返回FALSE
和GetLastError() != ERROR_IO_PENDING
)
因此,最好是始終將不為0的lpNumberOfBytes傳遞給api並使用它(如果api成功完成的話)。 否則,請使用GetOverlappedResult
或如果您說要使用BindIoCompletionCallback
您直接在回調dwNumberOfBytesTransfered
中獲得了BindIoCompletionCallback
。
因此在概念上可以使用以下代碼:
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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.