为什么某些机器上系统会hang在IoCallDriver?只有重启,内附代码
NTSTATUS
StartReadUrb(
PDEVICE_EXTENSION Extension
)
{ // StartInterruptUrb
// If the interrupt polling IRP is currently running, don't try to start
// it again.
USBD_PIPE_HANDLE PipeHandle;
BOOLEAN startirp;
KIRQL oldirql;
PIRP Irp;
PURB urb;
PUSB_DATA_PIPE_CONTEXT rwcontext;
PIO_STACK_LOCATION stack;
NTSTATUS status;
TRACE("Enter StartReadUrbnew() DO=%X\n",Extension->DeviceObject);
// KeAcquireSpinLock(&Extension->polllock, &oldirql);
if (Extension->readpending)
startirp = FALSE;
else
startirp = TRUE, Extension->readpending = TRUE;
// KeReleaseSpinLock(&Extension->polllock, oldirql);
if (!startirp)
{
TRACE("Read Pending\n");
return STATUS_DEVICE_BUSY; // already pending
}
Irp = IoAllocateIrp(Extension->TopOfStackDeviceObject->StackSize + 1, FALSE);
urb = ExAllocatePool(NonPagedPool,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER));
rwcontext = ExAllocatePool(NonPagedPool,
sizeof(struct _USB_DATA_PIPE_CONTEXT));
rwcontext->Extension = Extension;
rwcontext->urb = urb;
if(Extension->UsbInterface == NULL)
{
TRACE("Extension->UsbInterface is NULL\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
PipeHandle = Extension->UsbInterface->Pipes[Extension->DataInPipe].PipeHandle;
ASSERT(Irp && urb);
TRACE("Prepare data for StartReadUrb()\n");
// Acquire the remove lock so we can't remove the device while the IRP
// is still active.
/*
NTSTATUS status = IoAcquireRemoveLock(&Extension->RemoveLock, Irp);
if (!NT_SUCCESS(status))
{
Extension->pollpending = 0;
return status;
}
*/
// Initialize the URB we use for reading the interrupt pipe
UsbBuildInterruptOrBulkTransferRequest(
urb,
sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER),
PipeHandle,
Extension->ReadData,
NULL,
InPipeMaxSize,
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
NULL);
// Initialize the IRP for an internal control request
stack = IoGetNextIrpStackLocation(Irp);
RtlZeroMemory(stack, sizeof(IO_STACK_LOCATION));
stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
stack->Parameters.Others.Argument1 = urb;
stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
// Install "OnInterrupt" as the completion routine for the polling IRP.
IoSetCompletionRoutine(
Irp,
(PIO_COMPLETION_ROUTINE) OnReadInterrupt,
rwcontext,
TRUE,
TRUE,
TRUE);
// This IRP might have been cancelled the last time it was used, in which case
// the cancel flag will still be on. Clear it to prevent USBD from thinking that it's
// been cancelled again! A better way to do this would be to call IoReuseIrp,
// but that function is not declared in WDM.H.
Irp->Cancel = FALSE;
// UsbCom_IncrementIoCount(Extension->DeviceObject); //
TRACE("IoCallDriver\n");
status = IoCallDriver(Extension->TopOfStackDeviceObject, Irp);
TRACE("Exit StartReadUrbnew()\n");
return status;
}
经常走到status = IoCallDriver(Extension->TopOfStackDeviceObject, Irp);机器整个就hang掉了
请高手指点一二,什么原因会导致这种现象?