DO_DEVICE_INITIALIZING 到底有什么用?

简介:   当设备驱动程序通过调用 IoCreateDevice 创建设备对象时,I/O 管理器在 DEVICE_OBJECT 结构的 Flags 字段中设置 DO_DEVICE_INITIALIZING。

 

当设备驱动程序通过调用 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。

目录
相关文章
|
程序员 C++ Windows
Windows C++ 启动子进程并绑定子进程,主进程结束关闭后自动结束关闭子进程
在Windows平台上主进程启动子进程,并使主进程结束关闭后自动结束关闭子进程
466 0
|
NoSQL Java Redis
介绍Redis的各种用途以及使用场景
介绍Redis的各种用途以及使用场景 Redis 一、为什么使用 解决应用服务器的cpu和内存压力 减少io的读操作,减轻io的压力 关系型数据库的扩展性不强,难以改变表结构 二、优点: nosql数据库没有关联关系,数据结构简单,拓展表比较容易 nosql读取速度快,对较大数据.
12110 1
|
安全 C++ Windows
好工具推荐系列:VC++开发必备神器 -- Dependencies,查看依赖库DLL,支持win10,比depends更好用
好工具推荐系列:VC++开发必备神器 -- Dependencies,查看依赖库DLL,支持win10,比depends更好用
4162 0
好工具推荐系列:VC++开发必备神器 -- Dependencies,查看依赖库DLL,支持win10,比depends更好用
|
人工智能 自然语言处理 数据可视化
通义灵码上新功能:用代码画流程图
不想读前人“骨灰级”代码,不想当“牛马”程序员,想像看图片一样快速读复杂代码和架构。通义灵码刚刚支持代码逻辑可视化,可以把你的每段代码画成流程图。像个脑图工具一样帮你图文并茂画出代码逻辑和框架,再也不用迷失在代码迷宫啦!
|
Java Linux
【网络】高并发场景处理:线程池和IO多路复用
【网络】高并发场景处理:线程池和IO多路复用
327 2
|
存储 数据安全/隐私保护 Windows
逆向学习Windows篇:进程句柄操作详解
逆向学习Windows篇:进程句柄操作详解
699 0
|
监控 关系型数据库 MySQL
MySQL Binlog实战:在生产环境中的应用与最佳实践【实战应用】
MySQL Binlog实战:在生产环境中的应用与最佳实践【实战应用】
559 0
|
编译器 Linux C语言
CMake构建大型C/C++项目:跨平台设计与高级应用(一)
CMake构建大型C/C++项目:跨平台设计与高级应用
1432 0
|
机器学习/深度学习 人工智能 安全
一文搞懂隐私计算
一文搞懂隐私计算
4469 0