函数或筛选器驱动程序中的 AddDevice 例程应执行以下步骤:
- 调用 IoCreateDevice 为要添加的设备创建功能或筛选器设备对象(FDO 或筛选器 DO)。 - 不要为设备对象指定 DeviceName ,因为这样做会绕过 PnP 管理器的安全性。 如果用户模式组件需要指向设备的符号链接,请注册设备接口(请参阅下面的下一步)。 如果内核模式组件需要旧版设备名称,驱动程序必须命名设备对象,但不建议命名。 - 在 DeviceCharacteristics 参数中包含FILE_DEVICE_SECURE_OPEN。 此特征指示 I/O 管理器对所有打开请求的设备对象执行安全检查,包括相对打开和尾随文件名打开。 
- [可选]创建指向设备的一个或多个符号链接。 - 调用 IoRegisterDeviceInterface 注册设备功能,并创建应用程序或系统组件可用于打开设备的符号链接。 驱动程序应在处理IRP_MN_START_DEVICE请求时调用 IoSetDeviceInterfaceState 来启用接口。 有关详细信息,请参阅 设备接口类。 
- 将指向设备的 PDO 的指针存储在设备扩展中。 - PnP 管理器将指向 PDO 的指针作为 PhysicalDeviceObject 参数提供给 AddDevice。 驱动程序在对例程(如 IoGetDeviceProperty)的调用中使用 PDO 指针。 
- 定义设备扩展中的标志以监控设备的某些 PnP 状态,例如设备暂停、移除和意外移除。 - 例如,定义一个标志以指示在设备处于暂停状态时应保留传入的 IRP。 如果驱动程序还没有用于排队 IRP 的机制,请创建用于存储 IRP 的队列。 有关详细信息,请参阅 IRP 的排队与出队。 - 此外,在设备扩展中分配 IO_REMOVE_LOCK 结构,并调用 IoInitializeRemoveLock 来初始化此结构。 有关详细信息,请参阅 使用删除锁。 
- 设置设备对象中的DO_BUFFERED_IO或DO_DIRECT_IO标志位,以指定 I/O 管理器用于发送到设备堆栈的 I/O 请求的缓冲类型。 高级驱动程序或此成员的值与堆栈中下一个较低驱动程序的值相同,但可能用于最高级别的驱动程序除外。 有关详细信息,请参阅 初始化设备对象。 
- 根据需要为电源管理设置DO_POWER_INRUSH或DO_POWER_PAGABLE标志。 可分页的驱动程序必须设置DO_POWER_PAGABLE标志。 设备对象标志通常在为设备创建 PDO 时由总线驱动程序设置。 但是,在创建 FDO 或筛选器 DO 时,高级驱动程序有时可能需要更改其 AddDevice 例程中的这些标志的值。 有关详细信息,请参阅 设置设备对象标志以进行电源管理。 
- 创建和/或初始化驱动程序用于管理此设备的任何其他软件资源,例如事件、旋转锁或其他对象。 (硬件资源(如 I/O 端口)稍后配置,以响应 IRP_MN_START_DEVICE 请求。 - 由于 AddDevice 例程在 IRQL = PASSIVE_LEVEL 的系统线程环境中运行,因此在初始化期间用 ExAllocatePoolWithTag 分配的任何内存可以来自分页池,前提是驱动程序不控制系统页文件所在的设备。 在 AddDevice 返回控件之前,必须使用 ExFreePool 释放此类内存分配。 
- 将设备对象附加到设备堆栈(IoAttachDeviceToDeviceStack)。 - 在 TargetDevice 参数中指定指向设备的 PDO 的指针。 - 存储 IoAttachDeviceToDeviceStack 返回的指针。 此指针指向设备的下一个较低级别驱动程序的设备对象,是在将 IRP 向下传递到设备堆栈时 IoCallDriver 和 PoCallDriver 的必要参数。 
- 使用如下语句清理 FDO 或筛选器 DO 中的 DO_DEVICE_INITIALIZING 标志: - FunctionalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
- 为处理设备的 PnP IRP 做好准备(例如 IRP_MN_QUERY_RESOURCE_REQUIREMENTS 和 IRP_MN_START_DEVICE)。 
在驱动程序收到包含 PnP 管理器分配给设备的硬件资源列表 的IRP_MN_START_DEVICE 之前,驱动程序不得开始控制设备。