函数或筛选器驱动程序中的 AddDevice 例程

函数或筛选器驱动程序中的 AddDevice 例程应执行以下步骤:

  1. 调用 IoCreateDevice 以 (FDO 或筛选器 DO) 为要添加的设备创建功能或筛选器设备对象。

    不要为设备对象指定 DeviceName ,因为这样做会绕过 PnP 管理器的安全性。 如果用户模式组件需要指向设备的符号链接,请注册设备接口 (请参阅下面的下一步) 。 如果内核模式组件需要旧设备名称,驱动程序必须命名设备对象,但不建议命名。

    DeviceCharacteristics 参数中包含FILE_DEVICE_SECURE_OPEN。 此特征指示 I/O 管理器针对所有打开的请求(包括相对打开和尾随文件名打开)的设备对象执行安全检查。

  2. [可选]创建一个或多个指向设备的符号链接。

    调用 IoRegisterDeviceInterface 来注册设备功能,并创建应用程序或系统组件可用于打开设备的符号链接。 驱动程序应在处理IRP_MN_START_DEVICE请求时通过调用 IoSetDeviceInterfaceState 来启用 接口 。 有关详细信息,请参阅 设备接口类

  3. 将指向设备 PDO 的指针存储在设备扩展中。

    PnP 管理器提供指向 PDO 的指针,作为 AddDevicePhysicalDeviceObject 参数。 驱动程序在调用 IoGetDeviceProperty 等例程时使用 PDO 指针。

  4. 在设备扩展中定义标志以跟踪设备的某些 PnP 状态,例如设备暂停、删除和意外删除。

    例如,定义一个标志以指示在设备处于暂停状态时应保留传入的 IRP。 如果驱动程序还没有排队 IRP 的机制,请创建一个队列来存放 IRP。 有关详细信息 ,请参阅排队和取消排队 IRP

    此外,在设备扩展中分配 IO_REMOVE_LOCK 结构,并调用 IoInitializeRemoveLock 来初始化此结构。 有关详细信息,请参阅 使用删除锁

  5. 在设备对象中设置DO_BUFFERED_IO或DO_DIRECT_IO标志位,以指定 I/O 管理器用于发送到设备堆栈的 I/O 请求的缓冲类型。 较高级别的驱动程序 或此成员,其值与堆栈中下一个较低级别的驱动程序相同,但可能最高级别驱动程序除外。 有关详细信息,请参阅 初始化设备对象

  6. 如有必要,请设置电源管理的DO_POWER_INRUSH或DO_POWER_PAGABLE标志。 可分页的驱动程序必须设置DO_POWER_PAGABLE标志。 设备对象标志通常由总线驱动程序在为设备创建 PDO 时设置。 但是,较高级别的驱动程序在创建 FDO 或筛选器 DO 时,有时可能需要在其 AddDevice 例程中更改这些标志的值。 有关详细信息 ,请参阅为电源管理设置设备对象标志

  7. 创建和/或初始化驱动程序用于管理此设备的任何其他软件资源,例如事件、旋转锁或其他对象。 (硬件资源(如 I/O 端口)稍后配置,以响应 IRP_MN_START_DEVICE 请求。)

    由于 AddDevice 例程在 IRQL = PASSIVE_LEVEL 的系统线程上下文中运行,因此,只要驱动程序不控制保存系统页文件的设备,使用 ExAllocatePoolWithTag 在初始化期间专门使用的任何内存都可以来自分页池。 在 AddDevice 返回控制权之前,必须使用 ExFreePool 释放此类内存分配。

  8. 将设备对象附加到设备堆栈 (IoAttachDeviceToDeviceStack) 。

    TargetDevice 参数中指定指向设备的 PDO 的指针。

    存储 IoAttachDeviceToDeviceStack 返回的指针。 此指针指向设备下一低级驱动程序的设备对象,是向设备堆栈传递 IRP 时 IoCallDriverPoCallDriver 的必需参数。

  9. 使用如下所示的语句清除 FDO 或筛选器 DO 中的DO_DEVICE_INITIALIZING标志:

    FunctionalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    
  10. 准备好处理设备 (的 PnP IRP,例如 IRP_MN_QUERY_RESOURCE_REQUIREMENTSIRP_MN_START_DEVICE) 。

驱动程序在收到包含 PnP 管理器分配给设备的硬件资源列表 的IRP_MN_START_DEVICE 之前,不得开始控制设备。