对 Windows Vista Service Pack 1 (SP1) 的支持将于 2011 年 7 月 12 日结束。 若要继续接收 Windows 的安全更新,请确保运行具有 Service Pack 2 (SP2) 的 Windows Vista。 有关详细信息,请参阅此Microsoft网页: 某些版本的 Windows 的支持即将结束。
来源:Microsoft 支持部门
快速发布
快速发布文章直接从MICROSOFT支持组织内部提供信息。 此处包含的信息是针对新出现或唯一的主题创建的,或旨在补充其他知识库信息。
症状
禁用当前处于空闲状态的 USB 设备时,可能会在蓝屏上收到“停止0x44”错误消息。 此错误消息如下所示:STOP 0x00000044 ( parameter1 、parameter2 、parameter3 、parameter4 ) MULTIPLE_IRP_COMPLETE_REQUESTS
原因
如果 USB 设备使用使用内核模式驱动程序框架 (KMDF) 1.7 或更低版本编写的驱动程序,则可能会出现此问题。当 USB 设备处于空闲 (USB 选择性挂起) 状态,并且设备随后处于“已禁用” (,例如右键单击设备管理器中的设备并单击“禁用) ”,则会出现此问题。在这些情况下,KMDF 框架版本 1.7 (或更低版本) 不会等待 USB 选择性挂起 Irps 完成,因此允许在 USB 选择性挂起 Irp 完成之前删除设备堆栈, (例如,Usbhub 驱动程序) 。
解决方法
此问题在内核模式驱动程序框架 (KMDF) 1.9 及更高版本中得到解决。 内核模式驱动程序框架 (KMDF) 版本 1.9 在 Windows 7 版本的 Windows 驱动程序工具包 (WDK) 中提供。基于 KMDF 的 USB 设备驱动程序开发人员可以通过执行以下操作来解决此问题:
-
在驱动程序的 EvtDriverDeviceAdd 回调例程中注册 EvtDeviceReleaseHardware 回调例程。
-
在驱动程序的 EvtDriverDeviceAdd 回调例程中分配 WDFWORKITEM 对象。
-
分配和初始化 KEVENT 对象,在驱动程序的 EvtDeviceReleaseHardware 回调例程中将工作项排队,将此事件作为 Context 参数传递,并等待事件发出信号。
-
在工作项回调例程中,将线程延迟大约 2 秒,然后设置 事件。 所需的确切延迟值可能因系统而异,应在最终实现之前进行测试。
所述的解决方法有两个主要影响:
-
它会将工作项排队,这有助于延迟拆除设备堆栈,直到工作项队列排空到此工作项 (,因为 USB 核心堆栈可以通过工作项) 完成 USB 选择性挂起 Irp。
-
如果 USB 核心堆栈的工作项和驱动程序的工作项在多处理器/多核系统上同时执行,则会引入延迟。
注意:这不是一个全面的解决方案。 它只会帮助缓解问题。
更多信息
下面的示例代码片段演示如何实现此解决方法:EvtDriverDeviceAdd ( IN WDFDRIVER 驱动程序,IN PWDFDEVICE_INIT DeviceInit ) { PWORKER_ITEM_CONTEXT 上下文; WDF_OBJECT_ATTRIBUTES属性; WDF_WORKITEM_CONFIG workitemConfig; WDFWORKITEM workItem; ... // 设置 EvtDeviceReleaseHardware 回调 // ... pnpPowerCallbacks.EvtDeviceReleaseHardware = EvtDeviceReleaseHardware; WdfDeviceInitSetPnpPowerEventCallbacks (DeviceInit,&pnpPowerCallbacks) ; ... // 分配 WDFWORKITEM // WDF_OBJECT_ATTRIBUTES_INIT (&属性) ; WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE (&属性,WORKER_ITEM_CONTEXT) ; 属性。ParentObject = device; WDF_WORKITEM_CONFIG_INIT (&workitemConfig、EvtWorkItem) ; status = WdfWorkItemCreate (&workitemConfig,&属性,&workItem) ; 如果 (!NT_SUCCESS (状态) ) { 返回状态; } devContext->WorkItem = workItem; ...}NTSTATUSEvtDeviceReleaseHardware ( IN WDFDEVICE Device, IN WDFCMRESLIST ResourcesTranslated ) { KEVENT 事件; PWORKER_ITEM_CONTEXT上下文; WDFWORKITEM workItem; UNREFERENCED_PARAMETER (ResourcesTranslated) ; workItem = GetDeviceContext (Device) ->WorkItem; context = GetWorkItemContext (workItem) ; KeInitializeEvent (&事件、NotificationEvent、FALSE) ; context->事件 = &事件; // 将 workitem 排队 // WdfWorkItemEnqueue (workItem) ; // 等待 workitem 发出事件信号 // KeWaitForSingleObject (&事件、Executive、KernelMode、FALSE、NULL) ; return STATUS_SUCCESS;}VOIDEvtWorkItem ( IN WDFWORKITEM WorkItem ) { PWORKER_ITEM_CONTEXT context; LARGE_INTEGER间隔; context = GetWorkItemContext (WorkItem) ; // 将线程延迟 2 秒 // 间隔。QuadPart = -2 * 10 * 1000 * 1000; KeDelayExecutionThread (KernelMode, FALSE, &interval) ; // 向等待线程发出信号 // KeSetEvent (context->事件,IO_NO_INCREMENT,FALSE) ; context->事件 = NULL;}in 头文件typedef struct _WORKER_ITEM_CONTEXT { PKEVENT Event;}WORKER_ITEM_CONTEXT, * PWORKER_ITEM_CONTEXT;WDF_DECLARE_CONTEXT_TYPE_WITH_NAME (WORKER_ITEM_CONTEXT GetWorkItemContext) EVT_WDF_DEVICE_RELEASE_HARDWARE EvtDeviceReleaseHardware;EVT_WDF_WORKITEM EvtWorkItem;
免责 声明
MICROSOFT和/或其供应商不对网站上发布的文档和相关图形中包含的信息的适用性、可靠性或准确性作出任何声明或保证, (“材料”) 出于任何目的。 这些材料可能包含技术不准确或排版错误,可随时修订,不另行通知。在适用法律允许的最大范围内,MICROSOFT和/或其供应商否认并排除所有明示、默示或法定的陈述、保证和条件,包括但不限于与材料有关的所有权、不侵权、令人满意的条件或质量、适销性和特定用途适用性的陈述、保证或条件。