Vista problem with surprise_removal of usb device

When I try to abort all pending transfer IRPs with URB_FUNCTION_ABORT_PIPE after a
surprise_removal it doesn’t always work on Vista. I sometimes get a return value of c000000e from IoCallDriver, that is - “A device which does not exist was specified”.
On WinXp I never run into that problem.

When the abort fails, I get a Bugcheck (44) - Multiple_Irp_Complete_Requests. I guess the usbport driver trys to complete an irp after I removed the device.

Furthermore I’m not really sure if the abort is the actually problem or if I have
to find the bug somewhere else in the driver.

I could fix that problem with a call to IoCancelIrp if abort fails, but why does that problem occure on Vista?

By the way, the driver is pretty good tested on Xp and W2k, thus it should really be an issue related to Vista.

Can sombody help me or does someone else have a related problem?

Many Thanks

// allocate memory for request
pUrb = myAllocateMemory(NonPagedPool, sizeof(struct URB_PIPE_REQUEST));

if (pUrb)
{
// setup the structure for aborting the pipe
RtlZeroMemory(pUrb,sizeof(struct _URB_PIPE_REQUEST));
pUrb->UrbHeader.Length = (USHORT) sizeof (struct _URP_PIPE_REQUEST);
pUrb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE;
pUrb->UrbPipeRequest.PipeHandle = pipeHandle;

// call the usbd blocked
ntStatus = myCallBlockedUSBD( pMyDeviceObject, pUrb);

NTSTATUS myCallBlockedUSBD( PDEVICE_OBJECT pMyDeviceObject, PURB pUrb)
{

pMyDeviceExtension = pMyDeviceObject->DeviceExtension;

// issue a synchronous request
KeInitializeEvent(&event, NotificationEvent, FALSE);

pIrp = IoBuildDeviceIoControlRequest(
IOCTL_INTERNAL_USB_SUBMIT_URB,
pMyDeviceExtension->pNextDeviceObject,
NULL,
0,
NULL,
0,
TRUE, /* INTERNAL */
&event,
&ioStatus);

if (pIrp == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}

// Prepare for calling the USB driver stack
pNextStack = IoGetNextIrpStackLocation(pIrp);
ASSERT(pNextStack != NULL);

// Set up the URB ptr to pass to the USB driver stack
pNextStack->Parameters.Others.Argument1 = pUrb;

// Call the USB class driver to perform the operation. If the returned status
// is PENDING, wait for the request to complete.
ntStatus = IoCallDriver(pMyDeviceExtension->pNextDeviceObject, pIrp);

DSD_error ((“return from IoCallDriver USBD %x\n”, ntStatus));

if (ntStatus == STATUS_PENDING)
{
status = KeWaitForSingleObject(
&event,
Suspended,
KernelMode,
FALSE,
NULL);
}

}