簡體   English   中英

如果沒有,則IO重疊的ReadFile和WriteFile結果是否為ERROR_IO_PENDING?

[英]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完成之前從函數退出-這將是還可以 系統只需將InternalHighOVERLAPPED復制到*lpNumberOfBytes 所以在偽代碼中:

if (lpNumberOfBytes) *lpNumberOfBytes = (ULONG)lpOverlapped->InternalHigh;

*lpNumberOfBytes正確的正確值僅在I / O已成功完成的情況下才有效。 因此,只能在這種情況下使用。 系統不記得lpNumberOfBytes值-因為它必須僅在[Write|Read]File調用期間有效,而在I / O活動期間(在異步I / O的情況下可能更長)才有效

如果I / O請求完成與成功同步(如果ReadFileWriteFile ,如果Thay返回TRUE ),或者如果未返回,則可以調用GetOverlappedResult 僅在I / O請求只是失敗的情況下才能調用此api( ReadFileWriteFile返回FALSEGetLastError() != 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM