MmGetSystemRoutineAddress() and KeAcquireInterruptSpinLock()

To have my driver work for both WIN2k and XP, I have the following code:

In my Start routine:

typedef KIRQL (FASTCALL *KEACQUIREINTERRUPTSPINLOCK)(PKINTERRUPT);
typedef VOID (FASTCALL *KERELEASEINTERRUPTSPINLOCK)(PKINTERRUPT, KIRQL);

RtlInitUnicodeString(&us, L"KeAcquireInterruptSpinLock");
pDevExt->pKeAcquireInterruptSpinLock = (KEACQUIREINTERRUPTSPINLOCK)
GetSystemRoutineAddress(&us);

RtlInitUnicodeString(&us, L"KeReleaseInterruptSpinLock");
pDevExt->pKeReleaseInterruptSpinLock = (KERELEASEINTERRUPTSPINLOCK)
GettystemRoutineAddress(&us);

if (pDevExt->pKeAcquireInterruptSpinLock) {
DbgPrint(" XP - KeAcquireInterruptSpinLock() is available …\n");
pDevExt->IsWXP = TRUE;
}
else {
DbgPrint(" NON_XP - NO KeAcquireInterruptSpinLock() …\n");
pDevExt->IsWXP = FALSE;
}

In my Dispatch routine:

case Read_Mem:
if (pDevExt->IsWXP) {
OldIrql =
(*pDevExt->pKeAcquireInterruptSpinLock)(pDevExt->InterruptObject);
} else {
KeAcquireSpinLock(&pDevExt->MemLock, &OldIrql);
}


if (pDevExt->IsWXP) {
(*pDevExt->pKeReleaseInterruptSpinLock)(pDevExt->InterruptObject,
OldIrql);//It crashes here!!!
} else {
KeReleaseSpinLock(&pDevExt->MemLock, OldIrql);
}

Hmmm, unfortunately it crashed in XP at
“(*pDevExt->pKeReleaseInterruptSpinLock)(pDevExt->InterruptObject,
OldIrql);”. The following is from windbg:

FAULTING_IP:
nt!KefReleaseSpinLockFromDpcLevel+0
805309f0 c60100 mov byte ptr [ecx],0x0

EXCEPTION_RECORD: ffffffff – (.exr ffffffffffffffff)
ExceptionAddress: 805309f0 (nt!KefReleaseSpinLockFromDpcLevel)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000001
Parameter[1]: 001c001c
Attempt to write to address 001c001c

ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at “0x%08lx” referenced
memory at “0x%08lx”. The memory could not be “%s”.

WRITE_ADDRESS: 001c001c

BUGCHECK_STR: ACCESS_VIOLATION

DEFAULT_BUCKET_ID: DRIVER_FAULT

LAST_CONTROL_TRANSFER: from 804f3d84 to 805309f0

STACK_TEXT:
ef0c67c8 804f3d84 f8829d40 829774d8 82669a48
nt!KefReleaseSpinLockFromDpcLevel
ef0c67cc f8829d40 829774d8 82669a48 00000000
nt!KeReleaseInterruptSpinLock+0xc
ef0c6c40 804eb4ab 82927030 8258e808 806bd2cc mydrv!DrvDispatch+0x172e
[f:\myprojects\mydrv\dispatch.c @ 2080]

OK, my first question is why it crashes? Second question is
KefReleaseSpinLockFromDpcLevel called? I thought I used an interrupt spin
lock.

Thanks a lot!

AH


Get ready for school! Find articles, homework help and more in the Back to
School Guide! http://special.msn.com/network/04backtoschool.armx

Ta H. wrote:

OK, my first question is why it crashes? Second question is
KefReleaseSpinLockFromDpcLevel called? I thought I used an interrupt
spin lock.

It crashed because your prototype of the function call is wrong. The
calling convention for KeReleaseInterruptSpinLock is not FASTCALL. See
NTDDK.H.

The reason you’re seeing the ReleaseSpinLockFromDpcLevel is just an
artifact of the implementation of this function. There IS no (standard,
C-language) generfic function that releases a spin lock without changing
IRQL – Except that’s precisely what KeReleaseSpinLockFromDpcLevel does.
If you disasembled the KeReleaseInterruptSpinLockCode (did you try
this before posting?), the next thing that you’d see is a call to
KeLowerIrql back to your original IRQL.

Peter
OSR