DO_DEVICE_INITIALIZING 到底有什么用?

来源:互联网 发布:dz论坛源码liunx 编辑:程序博客网 时间:2024/04/28 08:03

 

当设备驱动程序通过调用 IoCreateDevice 创建设备对象时,I/O 管理器在 DEVICE_OBJECT 结构的 Flags 字段中设置 DO_DEVICE_INITIALIZING。DO_DEVICE_INITIALIZING 的目的是防止其它组件在驱动程序完成初始化设备对象之前向设备发送 I/O。

每次打开设备的一个句柄时,以及任何时候驱动程序试图附加到一个设备堆栈时(检查堆栈顶部设备对象的这个标志),I/O 管理器都检查 DO_DEVICE_INITIALIZING。如果设置 DO_DEVICE_INITIALIZING,那么 I/O 管理器将不允许另一个组件使用诸如 CreateFileOpenFileIoGetDeviceObjectPointer 之类的函数通过名称打开设备。DO_DEVICE_INITIALIZING 不会阻止驱动程序接收即插即用请求或来自堆栈中高层驱动程序的请求,它仅仅防止组件打开设备。

对于驱动程序在其 DriverEntry 例程中创建的任何设备对象,由 I/O 管理器负责清除 DO_DEVICE_INITIALIZING。对于除 DriverEntry 之外的任何例程中创建的任何设备对象,由驱动程序负责清除 DO_DEVICE_INITIALIZING。

传统驱动程序(例如为 Windows NT 4 编写的非即插即用驱动程序)在 DriverEntry 中创建它们的设备对象。即插即用驱动程序通常在 AddDevice 中创建它们的设备对象,但是即插即用驱动程序可能在 DriverEntry 中创建控制设备对象(例如,公开自己的设备接口或者支持某个应用程序可以打开的独占堆栈中的设备)。(驱动程序不把控制设备对象报告给即插即用或者将它们附加到设备堆栈。)

驱动程序负责从例程(驱动程序在其中创建设备对象)返回之前准备接收 I/O 请求。对于不同类型的驱动程序,涉及的步骤有所不同;对于即插即用驱动程序,步骤通常包括将设备的 PDO 指针存储到设备扩展中、定义标志来跟踪设备的即插即用状态、设置电源管理标志以及创建或初始化软件资源(例如驱动程序用来管理其设备的事件和自旋锁)。驱动程序还可以注册设备接口或创建一个或多个到其设备的符号链接。

对于在 DriverEntry 中创建的设备对象,I/O 管理器允许 DriverEntry 一返回就打开设备。对于即插即用驱动程序,驱动程序堆栈必须在 I/O 管理器允许打开设备之前成功完成一个启动请求 (IRP_MN_START_DEVICE)。虽然即插即用驱动程序可能需要在 AddDevice 和启动请求之间处理一些来自堆栈中其它驱动程序的请求(例如,存储端口驱动程序必须在此时间间隔内处理 SRB_FUNCTION_CLAIM_DEVICE),但是驱动程序在设备被启动之前不接收任何创建请求或基于文件对象的 I/O 请求。从驱动程序清除此标志到即插即用管理器启动设备的时间,驱动程序不需要针对 IRP_MJ_CREATE 或基于文件句柄传入的 I/O 请求进行同步。

下列代码是一个简化的 AddDevice 例程的例子(基于 Windows DDK 中的 Toaster 示例)。(已经从这个例子中删除错误检查和初始化设备扩展的代码。完整的代码请参见 %winddk%/src/general/toaster/func/featured1/ 上的 Toaster 功能驱动程序示例)。

NTSTATUS ToasterAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject ) { NTSTATUS                status = STATUS_SUCCESS; PDEVICE_OBJECT          deviceObject = NULL; PFDO_DATA               fdoData; POWER_STATE             powerState;PAGED_CODE();// Create a function device object. status = IoCreateDevice (DriverObject, sizeof (FDO_DATA), NULL,  // No Name FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObject);// Code to initialize the device extension.// Attach driver to the device stack. fdoData->NextLowerDriver = IoAttachDeviceToDeviceStack (deviceObject, PhysicalDeviceObject);// Clear the DO_DEVICE_INITIALIZING flag.// Note:Do not clear this flag until the driver has set the // device power state and the power DO flags. //deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;return status; }

您应该做什么?

清除驱动程序在除 DriverEntry 之外的例程(例如即插即用驱动程序的 AddDevice 例程)中创建的任何设备对象的 DO_DEVICE_INITIALIZING 标志。

在初始化设备对象之后到从例程返回之前清除 DO_DEVICE_INITIALIZING。