WdfWorkItemCreate error STATUS_WDF_INCOMPATIBLE_EXECUTION_LEVEL

Looks like either the editor or my last good eye went south on my last post- some of the debugger commands appear inline. Hopefully you can sort that out.

Bob,

I just put a print in the driver code.

DbgPrint(“Registry Path %wZ\n”, RegistryPath);

Registry Path \REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\WdfDio

I will email you an image of the registry on the target machine.

'Greg

“Bob Kjelgaard” wrote in message
news:xxxxx@ntdev…
No need to worry about flames for doing something wrong here [unless I get
the idea you’re doing something totally unsafe, and won’t listen to advice].
Stuff happens, even with the best devs [even if it didn’t, I’ve plenty of
bonehead moves of my own to recall].

For instance, I should have asked for the next 128 bytes of the dc dump
(forgot to check the structure size), but I don’t think that’s necessary.
I’m sure it’s not the extension nor a build issue from what’s already here.

The path is pretty short from here (these commands will work assuming you
have symbols for your driver), so I’ll add more detail than you may need:

kd> sxeld wdfdio.sys
kd> g

Then disable/enable the device from device manager (or reboot if your driver
can’t be unloaded). The debugger will break when your driver is loaded, but
before it calls any code in it.

kd> bp wdfdio!DriverEntry
kd> g < this should then break at your DriverEntry>
kd> dv

The second parameter is a Unicode string the debugger should resolve for
you- the name of the service key for the driver. Just keep it handy.

kd> sxdld wdfdio.sys (unless you really want a break every time you load it
with the debugger attached).
kd> g

Then open up regedit, look for that key name- it should have a
Parameters/Wdf subkey (it should be the one you already edited). That
subkey should have a keyword named VerifierOn [spelling matters, but not
case], which is a DWORD, and has a non-zero value.

If that’s there, then something heretofore unseen has failed in
WdfDriverCreate- you DID pass the Registry path you received in DriverEntry
on to that, correct?

Let’s see where that all leads for now- there aren’t [as far as I can
recall] that many more places [if any] something can both let your driver
load, but simultaneously miss that setting. So presumably we then switch to
the bottom edge of the framework and start looking at the Registry calls.

PS if you don’t have symbols for your driver, that’s OK by me, too. I can
give you a separate set of instructions for that situation.

To allude to the hot debate of the day, I lived in SoftIce most of the time
I was an independent- I just never used symbols. Didn’t have them when I
began debugging at the machine level (I think Jobs and Wozniak were still
working out of the garage bout that time), and never really used them until
recently [must admit they usually do save time]. But I do have what was
once a new monitor it destroyed when its display driver made an apparently
invalid mode switch on a Sony Vaio 9x box still acting as a paper weight
somewhere in my apartment…

That leaves two places then, as I see it:

(1) The flag is changed after WdfDriverCreate returns (you can just stop after the call, and !wdfdriverinfo)
(2) The registry calls to get the flag out of the registry failed.

Either way, you can drill down pretty close to the point of failure from here.

IF it’s #1, then you can set a data mod breakpoint on the actual flag’s address and see who’s clobbering it.

IF it isn’t #1, you can set a breakpoint on DriverEntry, then when you hit it, set one on ZwOpenKey and one on RtlQueryRegistryValues, and use them to see why the value couldn’t be read from the registry or was read improperly. (If for some reason you use these calls or think something else may call them, then step up to your call to WdfDriverCreate, then set these breakpoints).

You can try to get the parameters with “dv” (not sure it will work with ZwOpenKey) but you may need to step past the code that creates the stack frame (like mov bp,sp; sub sp:wink: first. But all that should matter at this point is the returns, and maybe the value block returned from the latter entry.

You can get the return codes by entering
“k” (stack trace)

The first address in the second column is the return address for the call.

g ;r

The eax register will have the return code for each call. It should be 0 in each case. If it is, then

You should see a call to ZwOpenKey to open the service key, followed by a second to open the Parameters\Wdf subkey, and then the RtlQueryRegistryValues call to get all those settings.

To avoid one more pass, before you proceed past the bp on RtlQueryRegistryValues, get the address of the value list. One way to do this is just “dd esp l 4” when you hit the breakpoint- the address you need should be the last one listed (the first one should be the return address, or course). Alternatively, kb after the stack frame is constructed will also work, I don’t care how the cat gets skinned.

So if all three turn up with 0 returns, then
dt -a5 RTL_QUERY_REGISTRY_TABLE will do most of the work to get at the values. The “EntryContext” member is the address od the returned values, so you can “dd l 1” to see what the registry calls told the framework.

My apologies if I got some of this instruction wrong- I’d usually try all this first to make sure I didn’t miss something, but I’m having some trouble with the test machine attached to the debugger at the moment.

Also, my thanks in advance for your assistance- if this is a genuine bug, nobody has seen it before, so I’d prefer to just root cause it now if I can.