driving me crazy - what is wrong with this code?

A PDO enumerated by my bus driver is sending an internal IOCTL to the
top of its own stack (for action by the attached FDO), with the
following code:

fdo =
IoGetAttachedDeviceReference(WdfDeviceWdmGetDeviceObject(device));
KeInitializeEvent(&irp_complete_event, NotificationEvent, FALSE);
irp = IoBuildDeviceIoControlRequest((ULONG)IOCTL_XEN_RECONFIGURE,
fdo, NULL,
0, NULL, 0, TRUE, &irp_complete_event, &isb);
ASSERT(irp);
status = IoCallDriver(fdo, irp);
if (status == STATUS_PENDING)
{
KdPrint((__DRIVER_NAME " Waiting for completion\n"));
status = KeWaitForSingleObject(&irp_complete_event, Executive,
KernelMode,
FALSE, NULL);
status = isb.Status;
}
KdPrint((__DRIVER_NAME " IOCTL_XEN_RECONFIGURE status = %08x\n",
status));
ObDereferenceObject(fdo);

I get “Waiting for completion” but that is it - no
“IOCTL_XEN_RECONFIGURE status =”. The above looks pretty much exactly
like all the example code I’ve ever seen. It executes from a thread
running in the context of the bus drivers FDO (via a callback).

The attached FDO has the following in its EvtIoInternalDeviceControl:


KdPrint((__DRIVER_NAME " Completing\n"));
WdfRequestComplete(request, STATUS_SUCCESS);
KdPrint((__DRIVER_NAME " Completed\n"));

I see ‘Completing’ and ‘Completed’ get printed as expected.

I’m sure I’m overlooking something obvious but I just can’t see what.
Hopefully the problem is obvious to someone else…

Thanks

James

>I get “Waiting for completion” but that is it - no

“IOCTL_XEN_RECONFIGURE status =”.

Try using IoAllocateIrp instead, and signal the event in the completion routine.

IoBuildDeviceIoControlRequest makes a threaded IRP which relies on IopCompleteRequest APC, and this mechanism can be disturbed by the lots of ways - like the caller being at > PASSIVE_LEVEL or such.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

So, if I understand right this hangs on KeWaitForSingleObject and the
notification event does not get signaled. My guess is that
WdfCompleteRequest is not compatible with this legacy way of sending IRPs
and you should use one of the Wdf functions (WdfRequestSend?) to send the
request to the other driver and to wait for it to complete. It’s sunday but
hopefully soon somebody who knows what he’s talking about will give you an
authoritative answer.

//Daniel

“James Harper” wrote in message
news:xxxxx@ntdev…
> A PDO enumerated by my bus driver is sending an internal IOCTL to the
> top of its own stack (for action by the attached FDO), with the
> following code:
>
> fdo =
> IoGetAttachedDeviceReference(WdfDeviceWdmGetDeviceObject(device));
> KeInitializeEvent(&irp_complete_event, NotificationEvent, FALSE);
> irp = IoBuildDeviceIoControlRequest((ULONG)IOCTL_XEN_RECONFIGURE,
> fdo, NULL,
> 0, NULL, 0, TRUE, &irp_complete_event, &isb);
> ASSERT(irp);
> status = IoCallDriver(fdo, irp);
> if (status == STATUS_PENDING)
> {
> KdPrint((__DRIVER_NAME " Waiting for completion\n"));
> status = KeWaitForSingleObject(&irp_complete_event, Executive,
> KernelMode,
> FALSE, NULL);
> status = isb.Status;
> }
> KdPrint((__DRIVER_NAME " IOCTL_XEN_RECONFIGURE status = %08x\n",
> status));
> ObDereferenceObject(fdo);
>
> I get “Waiting for completion” but that is it - no
> “IOCTL_XEN_RECONFIGURE status =”. The above looks pretty much exactly
> like all the example code I’ve ever seen. It executes from a thread
> running in the context of the bus drivers FDO (via a callback).
>
> The attached FDO has the following in its EvtIoInternalDeviceControl:
>
> …
> KdPrint((__DRIVER_NAME " Completing\n"));
> WdfRequestComplete(request, STATUS_SUCCESS);
> KdPrint((__DRIVER_NAME " Completed\n"));
>
> I see ‘Completing’ and ‘Completed’ get printed as expected.
>
> I’m sure I’m overlooking something obvious but I just can’t see what.
> Hopefully the problem is obvious to someone else…
>
> Thanks
>
> James
>
>

> notification event does not get signaled. My guess is that

WdfCompleteRequest is not compatible with this legacy way of sending IRPs
and you should use one of the Wdf functions (WdfRequestSend?) to send the

WdfCompleteRequest is in lower driver, while WdfRequestSend is in upper.

I do not think any notions of KMDF, including any behavior related to whether the driver is KMDF or not, ever crosses the driver boundary. KMDF driver is the same one from both upper and lower edges as the WDM one, “being KMDF” is internal implementation detail.

WDFREQUEST does not cross the driver boundary, except as a completion routine context, and even in this case it is not interpreted by the stack below.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

>

>I get “Waiting for completion” but that is it - no
>“IOCTL_XEN_RECONFIGURE status =”.

Try using IoAllocateIrp instead, and signal the event in the
completion
routine.

IoBuildDeviceIoControlRequest makes a threaded IRP which relies on
IopCompleteRequest APC, and this mechanism can be disturbed by the
lots of
ways - like the caller being at > PASSIVE_LEVEL or such.

Works perfectly. I was definitely calling at PASSIVE_LEVEL but obviously
something else was going on.

Thanks

James