我在我的应用程序中使用本机NT API来访问文件(NtCreateFile/etc)。为了避免处理STATUS_PENDING,我在打开相关文件时使用FILE_SYNCHRONOUS_IO_NONALERT标志。因此,打开文件如下所示:如何正确等待NtCreateFile/etc的完成?
UNICODE_STRING fname = toNtUnicode(ntpath);
OBJECT_ATTRIBUTES oa;
InitializeObjectAttributes(&oa, &fname, 0, at.handle(), NULL);
HANDLE h;
IO_STATUS_BLOCK io_status;
NTSTATUS r = NtOpenFile(&h, GENERIC_READ|SYNCHRONIZE, &oa, &io_status,
FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE);
if (r != STATUS_SUCCESS)
...; // error handling
不幸的是,它导致内核序列化给定句柄上的所有操作。即如果我尝试并行执行多个读取(使用多个线程) - 只有一个请求将在任何时间点处理。
我能摆脱系列化:
HANDLE h;
IO_STATUS_BLOCK io_status;
NTSTATUS r = NtOpenFile(&h, GENERIC_READ|SYNCHRONIZE, &oa, &io_status,
FILE_SHARE_READ, FILE_DIRECTORY_FILE);
if (r == STATUS_PENDING)
...; // what to do here???
,但究竟如何,我应该等待完成 - WaitForSingleObject()
对文件处理?据我所知,由于许多原因它可以改变为信号状态 - 是否有任何方法可以告诉我打开的文件(或dir)操作已完成?同样,如果我提交多个读取(来自多个线程) - 我怎么知道哪一个(如果有的话)完成了?
奇怪......我发誓,我观察到STATUS_UPDATE时打开目录。我会再试一次。同时,关于其他操作 - 我是否应该等待该事件传递给NtReadFile?如果是,那么我并不需要SYNCHRONIZE标志,对吧? –
NtClose()怎么样 - 它保证是同步的吗?另外,我是否可以假定所有关于NtXXX函数的说法都同样适用于相应的ZwXXX函数(如果在用户模式下调用)? –
@ C.M。 'ZwOpenFile'和'ZwClose'是**同步** api的设计。它**从不**返回'STATUS_PENDING'。 * Nt *和* Zw *函数 - 在用户模式下是别名。这是相同的功能(两个名称指向相同的地址) – RbMm