NtWriteFile - ERROR_INVALID_PARAMETER(错误87)

时间:2017-09-12 07:04:24

标签: c winapi

我为NtWriteFile做了一个简单的包装,我遇到了来自NtWriteFile的错误。这是我的代码:

BOOL WINAPI WriteFile(HANDLE hFile, PVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten) {
    IO_STATUS_BLOCK IOBlock;
    NTSTATUS Status = NtWriteFile(hFile, NULL, 0, NULL, &IOBlock, lpBuffer, nNumberOfBytesToWrite, 0, NULL);

    DWORD A = RtlNtStatusToDosError(Status); // just to get the error code

    if (Status == STATUS_PENDING) {
        Status = NtWaitForSingleObject(hFile, FALSE, NULL);
        if (NT_SUCCESS(Status)) Status = IOBlock.Status;
    }
    if (NT_SUCCESS(Status)) {
        *lpNumberOfBytesWritten = IOBlock.uInformation;
        return TRUE;
    }
    return FALSE;
}

A之后的行87上设置断点后ERROR_INVALID_PARAMETR的值为make -j4,问题是哪个参数无效?我做错了什么?

1 个答案:

答案 0 :(得分:2)

因为您在代码中准备STATUS_PENDING并在NtWriteFile之后等待 - 在这种情况下 - 我假设您使用为异步I /打开或创建的文件( hFile ) O.否则NtWaitForSingleObject无意义之后请致电NtWriteFile。所以我假设您在致电FILE_SYNCHRONOUS_IO_ALERTFILE_SYNCHRONOUS_IO_NONALERT时使用NtOpenFileNtCreateFile(或者在FILE_FLAG_OVERLAPPED来电时使用CreateFile

在异步I / O的情况下, ByteOffset (倒数第二个)参数是必需的。来自windows源代码:

  

ByteOffset - 指定要开始的文件中的起始字节偏移量           写操作。如果未指定且文件已打开           同步I / O,然后使用当前文件位置。 如果           没有为同步I / O打开文件,参数不是           指定,然后是错误的。

和一段代码,你在内核中失败了:

} else if (!ARGUMENT_PRESENT( ByteOffset ) && !(fileObject->Flags & (FO_NAMED_PIPE | FO_MAILSLOT))) {

    //
    // The file is not open for synchronous I/O operations, but the
    // caller did not specify a ByteOffset parameter.  This is an error
    // situation, so cleanup and return with the appropriate status.
    //

    if (eventObject) {
        ObDereferenceObject( eventObject );
    }
    ObDereferenceObject( fileObject );
    return STATUS_INVALID_PARAMETER;

} 

因此,如果我们为异步I / O打开或创建,我们需要或始终直接使用 ByteOffset 。或者如果我们使用同步文件句柄 - NtWriteFile 从不返回STATUS_PENDING并且操作始终同步完成 - 这是设计使然。所以在这种情况下没有任何意义检查STATUS_PENDING。你可以放弃这个检查和NtWaitForSingleObject(如果同时在文件上进行多个操作,也可以等待hFile但不是很正确)

MSDN

  

如果对 ZwCreateFile 的调用设置了 CreateOptions   flags, FILE_SYNCHRONOUS_IO_ALERT FILE_SYNCHRONOUS_IO_NONALERT ,   I / O管理器维护当前文件位置。如果是这样,来电者    ZwWriteFile 可以指定当前文件位置偏移量   用来代替显式的 ByteOffset 值。这个规范   可以使用以下方法之一进行:

     
      
  • 指定指向LARGE_INTEGER值的指针,其中HighPart成员设置为-1,LowPart成员设置为系统定义的值
      FILE_USE_FILE_POINTER_POSITION。
  •   
  • ByteOffset 传递 NULL 指针。
  •   

尽管没有明确说明将会是什么(没有 FILE_SYNCHRONOUS_IO_ALERT FILE_SYNCHRONOUS_IO_NONALERT 标志) - 可能理解在这种情况下I / O管理器维护当前文件位置,我们不能指定使用当前文件位置偏移 - 只有显式 ByteOffset 值必须

相关问题