usb插拔,IRP_MN_SURPRISE_REMOVAL与IRP_MN_REMOVE_DEVICE该如何处理
usb插拔,IRP_MN_SURPRISE_REMOVAL与IRP_MN_REMOVE_DEVICE该如何处理
USB的URB数据循环如下:
NTSTATUS IsoStreamTransferComplete(
IN PDEVICE_OBJECT bunkfdo,
IN PIRP Irp,
IN PVOID Context
)
{
……
IoSetCompletionRoutine(Irp,
IsoStreamTransferComplete,
transferObject,
TRUE,
TRUE,
TRUE);
if (Working == pdx->DeviceState)
status = IoCallDriver(pdx->StackDeviceObject,Irp);
……
}
当USB设备意外被拔下时:
NTSTATUS USB_DispatchPnp(
IN PDEVICE_OBJECT fdo,
IN PIRP Irp
)
{
……
case IRP_MN_SURPRISE_REMOVAL:
{
KeAcquireSpinLock(&pdx->DevStateLock, &oldIrql);
SET_NEW_PNP_STATE(pdx, SurpriseRemoved);
KeReleaseSpinLock(&pdx->DevStateLock, oldIrql);
ntStatus = USB_DefaultPnpHandler(fdo, Irp);
}
break;
case IRP_MN_REMOVE_DEVICE:
{
KeAcquireSpinLock(&pdx->DevStateLock, &oldIrql);
SET_NEW_PNP_STATE(pdx, Removed);
KeReleaseSpinLock(&pdx->DevStateLock, oldIrql);
for (i = 0; i < pdx->Interface->NumberOfPipes; i++)
{
USB_AbortPipe(fdo,(USBD_PIPE_HANDLE) pdx->Interface->Pipes[i].PipeHandle);
}
UnlockDevice(fdo); // once for LockDevice at start of dispatch
UnlockDevice(fdo); // once for initialization during AddDevice
KeWaitForSingleObject(&pdx->evRemove, Executive, KernelMode, FALSE, NULL);
if (pdx->DeviceDescriptor)
{
ExFreePool(pdx->DeviceDescriptor);
}
if (pdx->Interface != NULL)
{
ExFreePool(pdx->Interface);
}
if (pdx->NeedCleanup)
{
UNICODE_STRING deviceLinkUnicodeString;
pdx->NeedCleanup = FALSE;
RtlInitUnicodeString (&deviceLinkUnicodeString,
pdx->DeviceLinkNameBuffer);
IoDeleteSymbolicLink(&deviceLinkUnicodeString);
}
IoDetachDevice(pdx->StackDeviceObject);
IoDeleteDevice (fdo);
ntStatus = USB_DefaultPnpHandler(fdo, Irp);
}
break;
……
}
运行时,拔下USB设备:
有时候PC正常运行,再次插上USB设备,设备能够恢复正常工作。
有时候PC卡死(无法响应鼠标键盘操作)
请问程序中IRP_MN_SURPRISE_REMOVAL与IRP_MN_REMOVE_DEVICE哪里处理不当?