函数或筛选器驱动程序中的 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 的指针作为 PhysicalDeviceObject 参数提供给 AddDevice。 驱动程序在对例程(如 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 之前,驱动程序不得开始控制设备。