problem calling KeSetEvent inside DPC..Locking the KEVENT object

Hi all,

I want to notify the user mode application about the arrival of
interrupts…so I created an event and I am sending the event handle down
to the driver using an DeviceIoControl…there I get a kernel mode event
handle for the same using ObReferenceObjectByHandle(…,…,)…

Now I want to set the event in the DPC for the ISR to trigger the
WaitforSingleObject() in the User mode application. I understand that the
kernel mode event handle is in a paged pool, where as the DPC for isr is
at Dispatch level…

so I get a BSOD with IRQL_NOT_LESS_OR_EQUAL message…

but if i lock the variable representing the kernel mode event handle,
still i get the BSOD…

I am attaching the code for reference, please advice me where i am going
wrong…

struct{


PVOID gpEventObject;



}DeviceExtension,*pdx;

I want to make sure whether I am right in locking the pdx->gpEventObject

Please Note:-

When I set the event in any code at PASSIVE_LEVEL, there is no problem,
only when i set the event in the DPC, it gives the BSOD.

User Mode Creating event: -

UserEventHandle = CreateEvent(NULL, false, false, NULL);

//download event object to device driver
DeviceIoControl(HMdpc1,
IOCTL_REFERENCE_EVENT,
(LPVOID) UserEventHandle,
0,
NULL,
0,
&dwReturn,
NULL);

printf(“\nWaiting for Interrupt Event to occur\n”);

WaitForSingleObject(UserEventHandle,INFINITE);

MessageBox(“…”);

In the Kernel Mode Driver: -

#pragma code_seg(“page”)

NTSTATUS DispatchControl(PDEVICE_OBJECT fdo, PIRP Irp)
{


switch(code)
{
case IOCTL_REFERENCE_EVENT:
{
KdPrint((“Inside IOCTL_REFERENCE_EVENT”));
hEvent = (HANDLE) stack ->parameters.DeviceIoControl.Type3InputBuffer;
KdPrint((“the kernel mode hevent 0x%x”,hEvent));
status = STATUS_SUCCESS;

status = ObReferenceObjectByHandle(
hEvent,
GENERIC_ALL,
NULL,
KernelMode,
&pdx->gpEventObject,
&objHandleInfo);
if(status != STATUS_SUCCESS)
{
DbgPrint(“ObReferenceObjectByHandle failed! status = %x\n”, status);
break;
}

/**************Here I am locking the
“&pdx->gpEventObject”*******************/

KdPrint((“Locking the Event object which is inside Paged Code”));
pdx->hPageDataSection=MmLockPagableDataSection((PVOID) &pdx-

gpEventObject);

pdx->EventFlag=TRUE;
DbgPrint(“Referenct object sussfully!\n”);

In the DPC for ISR: -

#pragma LOCKEDCODE

VOID DpcForIsr(PKDPC Dpc, PDEVICE_OBJECT fdo, PIRP junk, PDEVICE_EXTENSION
pdx)
{ // DpcForIsr
KdPrint((“Entering DpcForISR Function”));
NTSTATUS status=STATUS_SUCCESS;

ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);

/*****here I am setting the Kernel mode Event Object*****************/

KeSetEvent((KEVENT*)pdx->gpEventObject,
0,
FALSE);
KdPrint((“KeSetEvent sussfully!\n”));

//Enable Pci interrupt

KdPrint((“Quitting DpcForISR Function”));
} // DpcForIsr
break;
}

In the StopDriver(): -

I am Unlocking the variable in the StopDriver function

KdPrint((“Unlocking the Kernel Event Object”));
MmUnlockPagableImageSection(pdx->hPageDataSection);

But here I got one more problem, when i uninstall it gives me
KMODE_EXECPTION_UNHANDLED,

so I would also like to know where I can again UNlock the locked data…

In anticipation of some suggestions…

thanx,

shiv

a handle is simply an index into the process handle table. The process
handle table is in paged memory. The handle table contains a pointer to
the referrant as well as some other data.

when you call ObReferenceObjectByHandle(handle) you get that pointer to
the kernel event object. This object is in non-paged pool and there is
no need to lock it down in order to use it.

MmLockPagableDataSection is for locking down sections in a kernel binary
image (like a device driver’s .SYS file) which have been marked as
pagable. It has absolutely nothing to do with locking down data
pointers which is completely unnecessary in this case anyway.

IRQL_NOT_LESS_OR_EQUAL could come from a number of sources. The pointer
you’re handing into KeSetEvent could have been corrupted for example.
You should probably walk through the routine in the debugger and make
sure the event pointer you hand in is the same one you got from
ObReferenceObjectByPointer.

You also probably don’t want to specify KernelMode when calling
ObReferenceObjectByPointer since you are handing in untrusted values (in
particular the Handle) which you received from user-mode. The better
option would be to let the kernel do the proper security and parameter
checks.

-p

-----Original Message-----
From: Shiva Prasad T. S. [mailto:xxxxx@techie.com]
Sent: Monday, September 16, 2002 9:44 PM
To: NT Developers Interest List
Subject: [ntdev] problem calling KeSetEvent inside DPC…Locking the
KEVENT object

Hi all,

I want to notify the user mode application about the arrival of
interrupts…so I created an event and I am sending the event handle down
to the driver using an DeviceIoControl…there I get a kernel mode event
handle for the same using ObReferenceObjectByHandle(…,…,)…

Now I want to set the event in the DPC for the ISR to trigger the
WaitforSingleObject() in the User mode application. I understand that
the kernel mode event handle is in a paged pool, where as the DPC for
isr is at Dispatch level…

so I get a BSOD with IRQL_NOT_LESS_OR_EQUAL message…

but if i lock the variable representing the kernel mode event handle,
still i get the BSOD…

I am attaching the code for reference, please advice me where i am going
wrong…

struct{


PVOID gpEventObject;



}DeviceExtension,*pdx;

I want to make sure whether I am right in locking the pdx->gpEventObject

Please Note:-

When I set the event in any code at PASSIVE_LEVEL, there is no problem,
only when i set the event in the DPC, it gives the BSOD.

User Mode Creating event: -

UserEventHandle = CreateEvent(NULL, false, false, NULL);

//download event object to device driver
DeviceIoControl(HMdpc1,
IOCTL_REFERENCE_EVENT,
(LPVOID) UserEventHandle,
0,
NULL,
0,
&dwReturn,
NULL);

printf(“\nWaiting for Interrupt Event to occur\n”);

WaitForSingleObject(UserEventHandle,INFINITE);

MessageBox(“…”);

In the Kernel Mode Driver: -

#pragma code_seg(“page”)

NTSTATUS DispatchControl(PDEVICE_OBJECT fdo, PIRP Irp)
{


switch(code)
{
case IOCTL_REFERENCE_EVENT:
{
KdPrint((“Inside IOCTL_REFERENCE_EVENT”));
hEvent = (HANDLE) stack
->parameters.DeviceIoControl.Type3InputBuffer;
KdPrint((“the kernel mode hevent 0x%x”,hEvent));
status = STATUS_SUCCESS;

status = ObReferenceObjectByHandle(
hEvent,
GENERIC_ALL,
NULL,
KernelMode,
&pdx->gpEventObject,
&objHandleInfo);
if(status != STATUS_SUCCESS)
{
DbgPrint(“ObReferenceObjectByHandle failed! status = %x\n”,
status);
break;
}

/**************Here I am locking the
“&pdx->gpEventObject”*******************/

KdPrint((“Locking the Event object which is inside Paged
Code”));
pdx->hPageDataSection=MmLockPagableDataSection((PVOID) &pdx-

gpEventObject);

pdx->EventFlag=TRUE;
DbgPrint(“Referenct object sussfully!\n”);

In the DPC for ISR: -

#pragma LOCKEDCODE

VOID DpcForIsr(PKDPC Dpc, PDEVICE_OBJECT fdo, PIRP junk,
PDEVICE_EXTENSION
pdx)
{ // DpcForIsr
KdPrint((“Entering DpcForISR Function”));
NTSTATUS status=STATUS_SUCCESS;

ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);

/*****here I am setting the Kernel mode Event Object*****************/

KeSetEvent((KEVENT*)pdx->gpEventObject,
0,
FALSE);
KdPrint((“KeSetEvent sussfully!\n”));

//Enable Pci interrupt

KdPrint((“Quitting DpcForISR Function”));
} // DpcForIsr
break;
}

In the StopDriver(): -

I am Unlocking the variable in the StopDriver function

KdPrint((“Unlocking the Kernel Event Object”));
MmUnlockPagableImageSection(pdx->hPageDataSection);

But here I got one more problem, when i uninstall it gives me
KMODE_EXECPTION_UNHANDLED,

so I would also like to know where I can again UNlock the locked data…

In anticipation of some suggestions…

thanx,

shiv


You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to %%email.unsub%%

Thanks Peter,

when I created an Kernel Event Object using ObReferenceObjectByHandle

I checked with the Kernel Debugger for the following code and got the
following output:

status = ObReferenceObjectByHandle(
hEvent,
GENERIC_ALL,
NULL,//*ExEventObjectType,
KernelMode,//Irp->RequestorMode ,
&pdx->gpEventObject,
&objHandleInfo);

if(pdx->gpEventObject==NULL)
{
KdPrint((“Event Object not created”));
return STATUS_UNSUCCESSFUL;
}
KdPrint((“KEvent object created”));
KdPrint((“The KEvent Object : 0x%x”,pdx->gpEventObject));

if(status != STATUS_SUCCESS)
{
DbgPrint(“ObReferenceObjectByHandle failed! status = %x\n”, status);
break;
}
pdx->EventFlag=TRUE;
DbgPrint(“Referenct object sussfully!\n”);

/******For testing purpose I use Kesetevent here ,it works fine********/
KeSetEvent((KEVENT*)pdx->gpEventObject,
0,
FALSE);
KdPrint((“KeSetEvent sussfully!\n”));
KdPrint((“The KEvent Object after setting event:
0x%x”,pdx->gpEventObject));

/***********************************************************************/

Debugger output: -

Inside IOCTL_REFERENCE_EVENT
the kernel mode hevent 0x68
KEvent object created
The KEvent Object : 0x8116ffc0
Referenct object sussfully!
KeSetEvent sussfully!
The KEvent Object after setting event: 0x8116ffc0

In this DispatchControl Function the “pdx->gpEventObject” is 0x8116ffc0

But “pdx->gpEventObject” a variable in the Device Extension… shows zero
other than the this function…

ie , when i checked the “pdx->gpEventObject” value in DpcForISr it shows
me 0x0…

VOID DpcForIsr(PKDPC Dpc, PDEVICE_OBJECT fdo, PIRP junk, PDEVICE_EXTENSION
pdx)
{ // DpcForIsr
KdPrint((“Entering DpcForISR Function”));
NTSTATUS status=STATUS_SUCCESS;

ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);

KdPrint((“The KEvent Object inside DPC for ISR:
0x%x”,pdx->gpEventObject));

/*KeSetEvent((KEVENT*)pdx->gpEventObject,
0,
FALSE);
KdPrint((“KeSetEvent sussfully!\n”)); */

//Enable Pci interrupt

KdPrint((“Quitting DpcForISR Function”));
}

Debugger Output: -

Entering On Interrupt Function
Requesting for DPC for ISR
Quitting OnInterrupt Function
Entering DpcForISR Function
The KEvent Object inside DPC for ISR: 0x0
Quitting DpcForISR Function

Also elsewhere other than the first time KEvent Object is created in
Dispatchcontrol function, the value of “pdx->gpEventObject” is NULL…

My Question:

  1. Is this the reason why when i use KeSetEvent in the DpcforISr, it is
    crashing with IRQL_NOT_LESS_OR_EQUAL message…

  2. What would be the reason for this, can u pls tell me what i should do
    to have the “pdx->gpEventObject” value retained in the DpcForISr.

thanx,

shiv

Why are you setting the input buffer size to ZERO?

Vijay

User Mode Creating event: -

UserEventHandle = CreateEvent(NULL, false, false, NULL);

//download event object to device driver
DeviceIoControl(HMdpc1,
IOCTL_REFERENCE_EVENT,
(LPVOID) UserEventHandle,
0, // WHY???
NULL,
0,
&dwReturn,
NULL);

  1. yes - this is probably the case

  2. something in your code is probably corrupting the data structure and
    clearing that field. Using the kernel debugger you can set a write
    watch break point on the field address (ba w 4

) and see when
it hits. Any code zeroing the data structure should trip over this.

-p

-----Original Message-----
From: Shiva Prasad T. S. [mailto:xxxxx@techie.com]
Sent: Monday, September 16, 2002 11:55 PM
To: NT Developers Interest List
Subject: [ntdev] RE: problem calling KeSetEvent inside DPC..Locking the
KEVENT object

Thanks Peter,

when I created an Kernel Event Object using ObReferenceObjectByHandle

I checked with the Kernel Debugger for the following code and got the
following output:

status = ObReferenceObjectByHandle(
hEvent,
GENERIC_ALL,
NULL,//*ExEventObjectType,
KernelMode,//Irp->RequestorMode ,
&pdx->gpEventObject,
&objHandleInfo);

if(pdx->gpEventObject==NULL)
{
KdPrint(("Event Object not created"));
return STATUS_UNSUCCESSFUL;
}
KdPrint(("KEvent object created"));
KdPrint(("The KEvent Object :
0x%x",pdx->gpEventObject));

if(status != STATUS_SUCCESS)
{
DbgPrint("ObReferenceObjectByHandle failed! status =
%x\n", status);
break;
}
pdx->EventFlag=TRUE;
DbgPrint("Referenct object sussfully!\n");

/ ******For testing purpose I use Kesetevent here ,it works fine******** /
KeSetEvent((KEVENT*)pdx->gpEventObject,
0,
FALSE);
KdPrint(("KeSetEvent sussfully!\n"));
KdPrint(("The KEvent Object after setting event:
0x%x",pdx->gpEventObject));

/ ***********************************************************************
/

Debugger output: -
====================
Inside IOCTL_REFERENCE_EVENT
the kernel mode hevent 0x68
KEvent object created
The KEvent Object : 0x8116ffc0
Referenct object sussfully!
KeSetEvent sussfully!
The KEvent Object after setting event: 0x8116ffc0

In this DispatchControl Function the "pdx->gpEventObject" is 0x8116ffc0

But "pdx->gpEventObject" a variable in the Device Extension... shows
zero other than the this function..

ie , when i checked the "pdx->gpEventObject" value in DpcForISr it shows
me 0x0..

VOID DpcForIsr(PKDPC Dpc, PDEVICE_OBJECT fdo, PIRP junk,
PDEVICE_EXTENSION
pdx)
{ // DpcForIsr
KdPrint(("Entering DpcForISR Function"));
NTSTATUS status=STATUS_SUCCESS;

ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);

KdPrint(("The KEvent Object inside DPC for ISR:
0x%x",pdx->gpEventObject));

/*KeSetEvent((KEVENT*)pdx->gpEventObject,
0,
FALSE);
KdPrint(("KeSetEvent sussfully!\n")); */

//Enable Pci interrupt

KdPrint(("Quitting DpcForISR Function"));
}

Debugger Output: -
====================

Entering On Interrupt Function
Requesting for DPC for ISR
Quitting OnInterrupt Function
Entering DpcForISR Function
The KEvent Object inside DPC for ISR: 0x0
Quitting DpcForISR Function

Also elsewhere other than the first time KEvent Object is created in
Dispatchcontrol function, the value of "pdx->gpEventObject" is NULL...

My Question:

1) Is this the reason why when i use KeSetEvent in the DpcforISr, it is
crashing with IRQL_NOT_LESS_OR_EQUAL message..

2) What would be the reason for this, can u pls tell me what i should do
to have the "pdx->gpEventObject" value retained in the DpcForISr.

thanx,

shiv

---
You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to %%email.unsub%%

Hi,

Thanks Peter and Vijay…

I was making

pdx->gpEventObject=NULL;

at one point which was the reason for the crash…

Thanx for your suggestions…

shiv