I've inherited a file system driver and am doing some testing with driver verifier enabled. I am testing on an up-to-date Windows 8 system. In summary, my drivers cause a driver verifier violation, however based on the MSDN documentation they are behaving correctly.
The violation occurs during OS shutdown, in the driver's thread create notify callback (set using PsSetCreateThreadNotifyRoutine). My driver calls ZwClose on a thread handle, and the call is made at APC_LEVEL. Bad move driver!
A device driver attempting to corrupt the system has been caught. This is
because the driver was specified in the registry as being suspect (by the
administrator) and the kernel has enabled substantial checking of this driver.
If the driver attempts to corrupt the system, bugchecks 0xC4, 0xC1 and 0xA will
be among the most commonly seen crashes.
Arg1: 0002001f, ID of the 'IrqlZwPassive' rule that was violated.
Arg2: 85809fd6, A pointer to the string describing the violated rule condition.
Arg3: 00000000, An optional pointer to the rule state variable(s).
Arg4: 00000000, Reserved (unused)
DV_VIOLATED_CONDITION: ZwClose should only be called at IRQL = PASSIVE_LEVEL.
DV_MSDN_LINK: !url http://go.microsoft.com/fwlink/?LinkId=216048
DV_RULE_INFO: !ruleinfo 0x2001f
LAST_CONTROL_TRANSFER: from 81109fc7 to 810e1ca4
Here's the stack:
9157f534 8126306c MyDriver!create_thread_notify_routine+0x15
9157f620 812934cc nt!PspInsertThread+0x5db
9157f7d4 812a8a7b nt!PspCreateThread+0x1db
9157f92c 812a8965 nt!PsCreateSystemThreadEx+0x104
9157f95c 81231069 nt!PsCreateSystemThread+0x26
9157f9dc 8123262c nt!PopFlushVolumes+0x217
9157faa0 81156978 nt!NtSetSystemPowerState+0x424
9157faa0 810de87d nt!KiSystemServicePostCall
9157fb24 81243c00 nt!ZwSetSystemPowerState+0x11
9157fbf4 813fd0a9 nt! ?? ::OKHAJAOM::`string'+0x34fc
9157fc08 81156978 nt!NtShutdownSystem+0x32
9157fc08 77627174 nt!KiSystemServicePostCall
00adf6b8 77624dae ntdll!KiFastSystemCallRet
00adf6bc 008fda38 ntdll!NtShutdownSystem+0xa
00adf6e8 008f8b81 wininit!WinInitShutdown+0x379
00adf76c 008f5f08 wininit!WinMain+0xe93
00adf7fc 76bb173e wininit!_initterm_e+0x169
00adf808 77666911 KERNEL32!BaseThreadInitThunk+0xe
00adf84c 776668bd ntdll!__RtlUserThreadStart+0x4a
00adf85c 00000000 ntdll!_RtlUserThreadStart+0x1c
Okay, so clearly my driver is doing something bad. BUT... it should never reach this point. An excerpt from the MSDN documentation for PsSetCreateThreadNotifyRoutine:
"The driver's thread-notify routine runs at IRQL = PASSIVE_LEVEL. When a thread is created, the thread-notify routine runs in the context of the thread that created the new thread. When a thread is deleted, the thread-notify routine runs in the context of this thread when the thread exits."
Unfortunately, in this case we are running at IRQL = APC_LEVEL, and things go bad.
So, is this a bug in Windows or a bug in the documentation? Either way, I'll have to fix it in my code but I'd like to know a bit more about what is going wrong.