首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何异步调用DeviceIOControl代码?

如何异步调用DeviceIOControl代码?
EN

Stack Overflow用户
提问于 2014-07-08 14:04:40
回答 2查看 3.4K关注 0票数 6

我试图使用MSDN上描述的重叠结构异步调用DeviceIO函数。我正在使用FSCTL_ENUM_USN_DATA控制代码来枚举NTFS驱动器的MFT,但我无法异步运行它。文件句柄是用FILE_FLAG_OVERLAPPED创建的,但是不管我是否使用FILE_FLAG_OVERLAPPED的重叠结构,都没有区别。函数不会立即返回。在这两种情况下似乎是同步的。下面的示例显示了C:\驱动器上前100.000 MFT条目的枚举。由于我不太熟悉重叠结构的用法,也许我做错了什么。我的问题是:如何执行DeviceIoControl(hDevice,FSCTL_ENUM_USN_DATA,.)异步吗?,谢谢您的帮助。

代码语言:javascript
复制
#include "stdafx.h"
#include <Windows.h>

typedef struct {
  DWORDLONG  nextusn;
  USN_RECORD FirstUsnRecord;
  BYTE Buffer[500];
}TDeviceIoControlOutputBuffer, *PTDeviceIoControlOutputBuffer;

int _tmain(int argc, _TCHAR* argv[])
{
    MFT_ENUM_DATA lInputMftData;
    lInputMftData.StartFileReferenceNumber = 0;
    lInputMftData.MinMajorVersion = 2;
    lInputMftData.MaxMajorVersion = 3;
    lInputMftData.LowUsn = 0;
    lInputMftData.HighUsn = 0;

    TDeviceIoControlOutputBuffer lOutputMftData;
    DWORD lOutBytesReturned = 0;
    HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    OVERLAPPED  lOverlapped = { 0 };
    lOverlapped.hEvent = hEvent;
    LPCWSTR path = L"\\\\.\\C:";
    HANDLE hDevice = CreateFile(path, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
    if (hDevice != INVALID_HANDLE_VALUE) {
        lOutputMftData.nextusn = 0;
        while (lOutputMftData.nextusn < 100000) {
            lInputMftData.StartFileReferenceNumber = lOutputMftData.nextusn;
            BOOL result = DeviceIoControl(hDevice, FSCTL_ENUM_USN_DATA, &lInputMftData, sizeof(lInputMftData), &lOutputMftData, sizeof(lOutputMftData), &lOutBytesReturned, &lOverlapped);
        }
    }
}
EN

回答 2

Stack Overflow用户

发布于 2020-01-28 11:50:34

TL:只有当收到请求的驱动程序发送异步行为时,才会得到异步行为。

当您调用DeviceIoControl并传递一个重叠结构时,它并不保证操作将是异步的。这意味着它可以是异步的。这取决于将接收您请求的驱动程序的实现方式。当您运行DeviceIoControl时,它会创建一个irp并将其发送给驱动程序。DeviceIoControl将把您的线程提升到内核模式,以创建和分派irp。将在该线程上调用驱动程序的回调来处理请求。如果驱动程序决定立即处理(并完成)请求,则请求将同步完成。在这个流程中,用FILE_FLAG_OVERLAPPED打开驱动程序和不打开驱动程序没有什么区别。如果驱动程序决定发送请求,那么您将看到真正的异步行为。DeviceIoControl将返回FALSE,GetLastError将返回ERROR_IO_PENDING。这意味着irp正在等待完成,您在重叠结构中提供的事件将在irp完成时发出信号。

票数 2
EN

Stack Overflow用户

发布于 2014-07-08 14:50:41

代码语言:javascript
复制
HEVENT hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
OVERLAPPED  lOverlapped = { 0 };
lOverlapped.hEvent = hEvent;

...

BOOL result = DeviceIoControl(hDevice, FSCTL_ENUM_USN_DATA, &lInputMftData, sizeof(lInputMftData), &lOutputMftData, sizeof(lOutputMftData), &lOutBytesReturned, &lOverlapped);

// If operation is asynchronous, wait for hEvent here or somewhere else
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24633898

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档