Greetings!
I call the following function from my NDIS protocol unload handler:
APIRET Cleanup(VOID)
{
NTSTATUS status;
LARGE_INTEGER liTimeout;
SignalEvent(hTerminateThread);
//
// In NT kernel mode, we must wait for the thread
// itself to terminate. Otherwise we will unload
// while the thread is still active. => KABOOM!
//
PAGED_CODE();
ASSERT(hThread != 0);
liTimeout.QuadPart = -10000000LL; // Wait one second
status = KeWaitForSingleObject(hThread,
Executive,
KernelMode,
FALSE,
&liTimeout);
// Close handle, we'll not be using it anymore.
ZwClose(hThread);
hThread = 0;
DestroyHashTable(hHashTable);
return APIRET_OK;
}
This results in an IRQL_NOT_LESS_OR_EQUAL exception with the following
params:
Arg1: 80000548, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000000, value 0 = read operation, 1 = write operation
Arg4: 804ea528, address which referenced memory
READ_ADDRESS: 80000548
CURRENT_IRQL: 2
FAULTING_IP:
nt!KeWaitForSingleObject+b9
804ea528 803b02 cmp byte ptr [ebx],0x2
Which I find a bit puzzling. The "Memory referenced" argument is the
same as the value of hThread. hThread was created at the init of the
driver by PsCreateThread.
As you can see, both the PAGED_CODE() macro and the ASSERT for checking
the thread handle is passed successfully.
This is on a plain Windows XP Professional GA with no fixes btw... Just
to have a clean test environment.
Is there any other preferred way to do this, or any obvious mistakes
that I've done with regards to KeWaitForSingleObject? I have tried not
waiting too, but that traps when the sleeping thread wakes up after the
driver image has been unloaded... :/
Take Care!
Harald Eilertsen!