初始化设备对象
IoCreateDevice 返回后,为调用方提供指向包含指向设备扩展指针的 DeviceObject 的指针后,驱动程序必须在设备对象中为其各自的物理、逻辑和/或虚拟设备设置某些字段。
IoCreateDevice 将新创建的设备对象的 StackSize 字段设置为 1。 最低级别的驱动程序可以忽略此字段。 当较高级别的驱动程序调用 IoAttachDeviceToDeviceStack 将自身附加到下一个较低级别的驱动程序时,该例程会自动将设备对象中的 StackSize 字段设置为下一个较低级别的驱动程序的设备对象加上一个。 但是,对于某些设备类型,较高级别的驱动程序可能需要将 StackSize 字段设置为更大的值,如特定于设备的文档中所述。 设置堆栈大小可确保发送到较高级别驱动程序的 IRP 将包含特定于驱动程序的 I/O 堆栈位置,以及链中所有较低级别驱动程序的正确 I/O 堆栈位置数。
IoCreateDevice 将新创建的设备对象的 AlignmentRequirement 字段设置为处理器的数据缓存行大小减 1,以确保直接 I/O 中使用的缓冲区正确对齐。 IoCreateDevice 返回后,最低级别的物理设备驱动程序必须执行以下操作:
从设备的对齐要求中减去一个。
将步骤 1 的结果与设备对象的 AlignmentRequirement 的当前值进行比较。
如果设备的对齐要求更高,请将 AlignmentRequirement 设置为步骤 1 的结果。 否则,保留由 IoCreateDevice 设置的 AlignmentRequirement 值。
在通过调用 IoGetDeviceObjectPointer 将自身链接到另一个驱动程序之后,较高级别的驱动程序必须将新创建的设备对象的 AlignmentRequirement 字段设置为下一个较低级别的驱动程序的设备对象的字段。 一般情况下,较高级别的驱动程序不应更改此值。 如果较高级别的驱动程序调用 IoAttachDevice 或 IoAttachDeviceToDeviceStack,则这些例程会自动将 device 对象中的 AlignmentRequirement 字段设置为较低级别驱动程序的设备对象的字段。
IoGetDeviceObjectPointer 返回指向较低级别驱动程序的设备对象和关联文件对象的指针。 只有 FSD (,或者可能的另一个最高级别的驱动程序) 可以使用返回的文件对象指针。 调用 IoGetDeviceObjectPointer 的 中间驱动程序应保存此文件对象指针,以便在卸载驱动程序时通过调用 ObDereferenceObject 来取消引用它。
在 FSD 装载包含表示较低驱动程序的设备对象的文件对象的卷后,中间驱动程序无法通过调用 IoAttachDevice 或 IoAttachDeviceToDeviceStack 在文件系统和较低驱动程序之间链接自身。 此外,当装载发生时,FSD 可以根据基础卷硬件的几何图形设置设备对象的 SectorSize 成员。 有关详细信息,请参阅 DEVICE_OBJECT。
中间或最低级别的驱动程序还会在设备对象的 Flags 中设置一个位,方法是在它创建的每个设备对象中使用DO_DIRECT_IO或DO_BUFFERED_IO来设置它。 逻辑或虚拟设备的最高级别驱动程序可以避免为缓冲或直接 I/O 设置 标志 ,前提是驱动程序编写器决定所涉及的其他工作将得到更好的驱动程序性能回报。 中间驱动程序必须设置其设备对象的 Flags 字段,以匹配下一个较低级别的驱动程序的设备对象的标记字段。
设置具有DO_DIRECT_IO或DO_BUFFERED_IO的设备对象 标志 字段确定 I/O 管理器如何在随后发送到驱动程序的所有数据传输请求中将访问权限传递给用户缓冲区。
然后,驱动程序可以在设备对象中设置任何其他与设备相关的值。 例如,如果可移动媒体设备的非 WDM 驱动程序在 I/O 操作期间检测到 (或怀疑) 媒体发生更改,则必须或设备对象的 Flags 成员DO_VERIFY_VOLUME。 (有关详细信息,请参阅 支持可移动媒体 。) 需要浪涌电源的设备的驱动程序必须或具有DO_POWER_INRUSH的 Flags 成员,并且不在系统分页路径上的设备的驱动程序必须或具有DO_POWER_PAGABLE 的 Flags 成员。 函数和筛选器驱动程序必须清除DO_DEVICE_INITIALIZING标志。
初始化设备对象后,驱动程序还可以初始化任何内核定义的对象以及它在设备扩展中提供了存储的其他系统定义数据结构。 驱动程序执行这些任务的确切时间取决于其设备、对象的类型和/或数据的性质。 通常,可以通过 PnP 启动和停止请求保留的任何对象或数据结构都可以在 AddDevice 例程中初始化。 当驱动程序处理IRP_MN_START_DEVICE请求时,应初始化那些需要随 PnP IRP_MN_START_DEVICE请求提供的资源信息,或者在设备停止和/或重启时可能需要更改。 有关 AddDevice 例程的详细信息,请参阅 编写 AddDevice 例程。