IoCompletion 例程完成 I/O作的处理。
语法
IO_COMPLETION_ROUTINE IoCompletionRoutine;
NTSTATUS IoCompletionRoutine(
[in] PDEVICE_OBJECT DeviceObject,
[in] PIRP Irp,
[in, optional] PVOID Context
)
{...}
参数
[in] DeviceObject
调用方提供的指向 DEVICE_OBJECT 结构的指针。 这是目标设备的设备对象,以前由驱动程序的 AddDevice 例程创建。
[in] Irp
调用方提供的指向描述 I/O作的 IRP 结构的指针。
[in, optional] Context
调用方提供的指向驱动程序特定上下文信息的指针,以前在调用 IoSetCompletionRoutine 或 IoSetCompletionRoutineEx时提供。 上下文信息必须存储在非分页内存中,因为可以在DISPATCH_LEVEL调用 IoCompletion 例程。 有关详细信息,请参阅以下“备注”部分。
返回值
如果 ioCompletion 例程 确定 IRP 需要其他处理,则必须返回STATUS_MORE_PROCESSING_REQUIRED。 有关详细信息,请参阅以下“备注”部分。 否则,它应返回STATUS_SUCCESS。 (I/O 管理器仅检查是否存在STATUS_MORE_PROCESSING_REQUIRED。
言论
驱动程序的 IoCompletion 例程在任意线程或 DPC 上下文中执行,在小于或等于DISPATCH_LEVEL的 IRQL 中执行。 由于写入DISPATCH_LEVEL执行的代码也将在较低级别执行,因此 IoCompletion 例程设计为在 DISPATCH_LEVEL 执行。 但是,由于这些例程不能保证在DISPATCH_LEVEL运行,因此它们不得调用实际需要在DISPATCH_LEVEL执行的系统例程。 (有关 IRCL 的详细信息,请参阅 管理硬件优先级。)
若要为特定 IRP 注册 IoCompletion 例程,驱动程序必须调用 IoSetCompletionRoutine 或 IoSetCompletionRoutineEx,该例程将 IoCompletion 例程的地址存储在下一个较低驱动程序的 I/O 堆栈位置。 (因此,最低级别的驱动程序无法注册 IoCompletion 例程。驱动程序通常从其中一个调度例程调用 IoSetCompletionRoutine 或 IoSetCompletionRoutineEx,每次收到 IRP 时。 大多数驱动程序(包括所有 PnP 驱动程序)都可以使用 IoSetCompletionRoutine 来注册其 IoCompletion 例程。 在执行 IoCompletion 例程之前可能卸载的非 PnP 驱动程序应改为使用 IoSetCompletionRoutineEx。
当任何驱动程序完成 IRP 时,它将调用 IoCompleteRequest,后者又调用每个更高级别的驱动程序的 IoCompletion 例程,从下一个最高到最高,直到调用所有更高 IoCompletion 例程,或直到一个例程返回STATUS_MORE_PROCESSING_REQUIRED。
创建 IRP 时,请为当前驱动程序以及任何较低的驱动程序分配堆栈位置。 如果未分配足够的堆栈位置,则调用完成例程时,DeviceObject 指针可能设置为 NULL。 如果使用 上下文 字段将信息传递给 IoCompletion,而不是依赖于 DeviceObject 参数,则可以避免为当前驱动程序分配额外的堆栈位置。
如果 IoCompletion 例程返回STATUS_MORE_PROCESSING_REQUIRED,则下一个驱动程序调用 IoCompleteRequest 立即返回。 在这种情况下,高级驱动程序必须调用 IoCompleteRequest 才能完成 IRP。
有关实现 IoCompletion 例程的详细信息,请参阅 完成 IRP。
例子
若要定义 IoCompletion 回调例程,必须先提供一个函数声明,用于标识要定义的回调例程的类型。 Windows 为驱动程序提供一组回调函数类型。 使用回调函数类型声明函数有助于 驱动程序代码分析、静态驱动程序验证程序(SDV)和其他验证工具查找错误,这是为 Windows作系统编写驱动程序的要求。
例如,若要定义名为 MyIoCompletion
的 IoCompletion 回调例程,请使用IO_COMPLETION_ROUTINE类型,如以下代码示例所示:
IO_COMPLETION_ROUTINE MyIoCompletion;
然后,按如下所示实现回调例程:
_Use_decl_annotations_
NTSTATUS
MyIoCompletion(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
)
{
// Function body
}
IO_COMPLETION_ROUTINE函数类型在 Wdm.h 头文件中定义。 若要在运行代码分析工具时更准确地识别错误,请务必将 _Use_decl_annotations_
注释添加到函数定义。
_Use_decl_annotations_
批注可确保使用应用于头文件中IO_COMPLETION_ROUTINE函数类型的批注。 有关函数声明要求的详细信息,请参阅 使用 WDM 驱动程序的函数角色类型来声明函数。 有关 _Use_decl_annotations_
的信息,请参阅 批注函数行为。
要求
要求 | 价值 |
---|---|
目标平台 | 桌面 |
标头 | wdm.h (包括 Wdm.h、Ntddk.h、Ntifs.h) |
IRQL | 在 IRQL <调用 = DISPATCH_LEVEL (请参阅“备注”部分)。 |