WdfRequestFormatRequestUsingCurrentType() caused WDF_VIOLATION

So I’m getting further along in my generic parent. I’ve created a series of faux config descriptors and responded to the SELECT_CONFIGURATION URB successfully.

The next URB that I get from my (KMDF) function driver above is SELECT_INTERFACE. I saw no reason not to just pass this straight down, so I did.

However, this generated the following bugcheck. Why would this happen?

WDF_VIOLATION (10d)
DESCRIPTION
The Windows Driver Framework has detected that a violation has occurred This resulted
in a condition where the machine would hang forever. By crashing, the Windows Driver
Framework is attempting to get enough information into the minidump such that somebody
can pinpoint the machine crash’s cause, which is inside this driver.
Arguments:
Arg1: 00000006, Device object of the failing device
Arg2: 00000001, State that timed out
Arg3: 872f0be8
Arg4: 872f97e8

Debugging Details:

*** ERROR: Module load completed but symbols could not be loaded for hhdusbh.sys

OVERLAPPED_MODULE: kmixer

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0x10D

LAST_CONTROL_TRANSFER: from b428213a to b4291e81

STACK_TEXT:
f6c37334 b428213a 872f97e8 00000006 00000001 Wdf01000!FxVerifierBugCheck+0x24
f6c37358 bf9165c6 87361010 78c9efe8 f6c373a8 Wdf01000!imp_WdfRequestFormatRequestUsingCurrentType+0x85
f6c37368 bf916539 78c9efe8 c0000001 00000018 xxxccgp!WdfRequestFormatRequestUsingCurrentType+0x16 [c:\winddk\6000\inc\wdf\kmdf\10\wdfrequest.h @ 518]
f6c373a8 bf9162e4 873b83f8 78c9efe8 8732a3d0 xxxccgp!xxxCcgpEvtHandleSubmitUrb+0x149 [y:\xxxccgp\driver.c @ 808]
f6c373f0 b42a6ba4 78c473a8 78c9efe8 8732a3d0 xxxccgp!xxxCcgpEvtIoInternalDeviceControl+0xe4 [y:\xxxccgp\driver.c @ 713]
f6c37414 b42a7f7c 78c473a8 78c9efe8 8732a3d0 Wdf01000!FxIoQueueIoDeviceControl::Invoke+0x30
f6c37444 b42aa598 78c9efe8 87361010 873b8c50 Wdf01000!FxIoQueue::DispatchRequestToDriver+0x445
f6c37460 b42abd2c 873b8c00 b42d1188 873b8c50 Wdf01000!FxIoQueue::DispatchEvents+0x485
f6c3747c b42ace67 00000000 8735f7b0 872f0be8 Wdf01000!FxIoQueue::QueueRequest+0x237
f6c374a0 b429bd9a 872f0be8 872f0be8 8041dded Wdf01000!FxPkgIo::Dispatch+0x377
f6c374ac 8041dded 8735f7b0 872f0be8 872f0c74 Wdf01000!FxDevice::Dispatch+0x7f
f6c374c0 f6b09cf9 873b8a80 872f0be8 f6c3754c nt!IopfCallDriver+0x35

FOLLOWUP_IP:
Wdf01000!FxVerifierBugCheck+24
b4291e81 cc int 3

SYMBOL_STACK_INDEX: 0

FOLLOWUP_NAME: MachineOwner

SYMBOL_NAME: Wdf01000!FxVerifierBugCheck+24

MODULE_NAME: Wdf01000

IMAGE_NAME: Wdf01000.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 4549b23a

STACK_COMMAND: kb

FAILURE_BUCKET_ID: 0x10D_Wdf01000!FxVerifierBugCheck+24

BUCKET_ID: 0x10D_Wdf01000!FxVerifierBugCheck+24

Followup: MachineOwner

According to the help page on WDF violations, it looks like the IRP ran out of stack locations.

My general approach here was going to be to respond manually to as few URBs as possible, and then just forward the rest down.

Is that not going to generally work? How do I know if I can safely forward a request in this manner? Do I have to get the IRP manually and do the math?

If I don’t have enough stack locations left, do I have to pend it and then manually reissue my own copy? That could get tedious.

First, we know the output of !analyze -v for a WDF_VIOLATION is wrong, the next debugger drop will have the right output (I thought actually that the latest was correct, but I could be wrong).

Second, KMDF will give you PDO a DeviceObject->StackSize of 1. If you are going to fwd I/O does to your FDO, after you succesfully create the PDO, set it’s stack size to the FDO’s + 1, e.g. WdfDeviceWdmGetDeviceObject(pdo)->StackSize = WdfDeviceWdmGetDeviceObject(fdo)->StackSize+1. This will guarantee you have enough stack locations to always fwd a request down the parent’s stack and you don’t have to worry about creating your own requests. This (setting the StackSize) and not being able to fwd WDFREQUESTs from a PDO WDFQUEUE to an FDO WDFQUEUE are 2 pain points that the KMDF team is aware of and we are working to fix in a future release to make this more seemless.

d

Ok. (By the way, Merry Christmas…)

First, what exactly was wrong with the Windbg output that I got? I guess the text about “WDF detected something that would hang forever…” is not quite right, but is the 6/1 => not enough stack locations bit correct? That is, have I come to the correct conclusion from this dump?

I don’t think I am running the very latest Windbg anyway since my home machine is Win2000 and I believe there is some issue with loading symbols on versions greater than 6.4 or so (this could be wrong however).

Now, I had one more question about the terminology you used about forwarding I/O between queues. Per our previous thread I created my child PDO and its internal IOCTL queue like this:

pDeviceInit = WdfAllocatePdo(…);
WdfCreateDevice(pDeviceInit, …, &hDevice);
(initialize &queue parameters to have an internal IOCTL callback)
WdfQueueCreate(hDevice, …, &queue);

Now, in the queue callback for the PDO, I’m calling request-reformat-current-type and then sending the request straight to my device PDO (the one from usbhub). (I’ve seen this work for, say, my earlier problem with get-configuration-descriptor). So in this case am I really forwarding from a PDO WDFQUEUE to an FDO WDFQUEUE? Isn’t it more like PDO to PDO?

It’s not like I’m, say, forwarding it to my bus driver FDO, and then receiving it in an internal IOCTL queue on my FDO, and then forwarding it *again* to my device PDO.

Or when you say FDO WDFQUEUE do you just mean an WDFQUEUE that was created *from* / is owned by an FDO, and not one that would, say, receive usermode requests from a device interface?

Sorry if this doesn’t make any sense :slight_smile:

The 6/1 parameters are correct, the analysis given by !analyze -v is out of date.

When I talk about fwding a PDO request from a PDO WDFQUEUE to an FDO WDFQUEUE, i mean something like WdfRequestForwardToIoQueue(requestInPdoQueue, pFdoContext->Queue). Since you are sending the WDFREQUEST to a WDIOTARGET, there is no intermediate queue on the FDO, rather you are just sending the I/O down the parent’s stack (which is just fine).

d

Ok, thanks. I used your tip and now it’s working again (the PDO stack size is now “6”, for what it’s worth.)

Apparently, that was basically the last thing I needed before I got up and running. I can talk to my device, through my function drivers, on top of the generic parent now.

I still need to tweak things and test more (I’m only allowing SUBMIT_URB so far, but it’s been good enough for 2 out of 2 drivers…) but I think I’m past the hard part at this point (I hope).