Do I need to de-allocate URBs that are refered to in passed off IRPs

Folks,

I have a question regarding how to handle allocation/deallocation of _URBs

If I am setting up a function driver, am allocating and sending a URB and an
IRP. The Irp is allocated via IoBuildDeviceIoControlRequest(), the urb with
ExAllocPool().

Once I have the allocated IRP, I set it up with the URB as follows

// Pass the URB to the USB driver stack
nextStack->Parameters.Others.Argument1 = urb;
ntStatus = IoCallDriver(devExt->DeviceToSendIrpsTo,irp);

// Then wait for the response as follows

if (ntStatus == STATUS_PENDING)
ntStatus = KeWaitForSingleObject(&event,Suspended,KernelMode,FALSE,NULL);
else
// USBD maps the error code for us
ntStatus = ioStatus.Status;

The DDk says that the I/O manager will clean up the allocated IRP for me,
and I know I should not touch it. Once my event is triggered, I can access
the URB freely (Or so it seems, I notice in the DDK example the URB is used
after the IRP returns).

What about freeing up the memory for the URB pointer. The DDk example seems
to have simply allocated the URB with ExAllocPool and Freeing it with
ExFreePool. When my driver does this, if my code is run on boot (i.e. The
device is on when I power the host system up) the driver BSODs on my
attempted ExFreePool on the URB I allocated. This does not happen when the
device is turned on when the system is already booted. I am assuming this
has something to do with the PnP enumeration already being complete for the
initial system config.

I know your not supposed to touch the IRP after sending it to a driver, what
about a pointer in an IRP the points to a _URB.

So does the I/O manager clean up the URB when it cleans up the IRP? Does it
technically own the URB I allocated since I pointed to it from within my IRP
?

Thanks in advance !

-Chris