KeSetEvent problem!

I have learned how to write windows’s driver for several months and I
have written several drivers!
I always follow the way Oney taught us to pass down the synchronous Irp
to the lower driver like
the following snapshot without any problem:

NTSTATUS ForwardAndWait(PDEVICE_EXTENSION pdx, PIRP Irp)
{
KEVENT event;
KeInitialize(&event, NotificationRoutine, FALSE);
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)
ForwardAndWaitCompletionRoutine, &event, TRUE, TRUE, TRUE);
< Some stuff>
NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);
if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event, Executive, KernelMode,
FALSE, NULL);
status = Irp->IoStatus.Status;
}
return status;
}

NTSTATUS ForwardAndWaitCompletionRoutine(PDEVICE_OBJECT fdo,
PIRP Irp, PKEVENT pev)
{ if (Irp->PendingReturned)
KeSetEvent(pev, IO_NO_INCREMENT, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}

But I feel rather confused when I review these code carefully today!
We allocate the KEVENT’s memory space on the stack. And then we pass down
the Irp and sleep on the event if IoCallDriver() returns STATUS_PENDING.
But when our driver sleep in a nonarbitrary thread context, the thread’s
kernel
stack may be swapped out to the disk(I meet a misunderstanding here? :frowning: )!
If the lower driver which receives the Irp from us completes the Irp at
the DISPATCH_LEVEL, Our ForwardAndWaitCompletionRoutine could be called
at the DISPATCH_LEVEL and reference the event
pointer which points to an address swapped out. Is it possible the
KeSetEvent could
cause a PAGE FAULT under this condition?

It’s really quite a silly question! My head may be short circuited tonight!
Could Anyone point out where I made the mistake?


Best Regards,
hanzhu

It could be that the routine is never swapped out during the hold in “KeWaitForSingleObject” . The WDK documentation mentions :
“If the WaitMode parameter is UserMode, the kernel stack can be swapped out during the wait.”
But if does not mention anything when you provide KernelMode .

Personalize , I do define always variables that are accessed through different routines into the device extension , or globally when
they are read only. But that is just a personal convention :slight_smile:

C.

----- Original Message -----
From: “hanzhu”
To: “Windows System Software Devs Interest List”
Sent: Sunday, January 01, 2006 1:24 PM
Subject: [ntdev] KeSetEvent problem!

> I have learned how to write windows’s driver for several months and I
> have written several drivers!
> I always follow the way Oney taught us to pass down the synchronous Irp
> to the lower driver like
> the following snapshot without any problem:
>
> NTSTATUS ForwardAndWait(PDEVICE_EXTENSION pdx, PIRP Irp)
> {
> KEVENT event;
> KeInitialize(&event, NotificationRoutine, FALSE);
> IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)
> ForwardAndWaitCompletionRoutine, &event, TRUE, TRUE, TRUE);
> < Some stuff>
> NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);
> if (status == STATUS_PENDING) {
> KeWaitForSingleObject(&event, Executive, KernelMode,
> FALSE, NULL);
> status = Irp->IoStatus.Status;
> }
> return status;
> }
>
> NTSTATUS ForwardAndWaitCompletionRoutine(PDEVICE_OBJECT fdo,
> PIRP Irp, PKEVENT pev)
> { if (Irp->PendingReturned)
> KeSetEvent(pev, IO_NO_INCREMENT, FALSE);
> return STATUS_MORE_PROCESSING_REQUIRED;
> }
>
> But I feel rather confused when I review these code carefully today!
> We allocate the KEVENT’s memory space on the stack. And then we pass down
> the Irp and sleep on the event if IoCallDriver() returns STATUS_PENDING.
> But when our driver sleep in a nonarbitrary thread context, the thread’s
> kernel
> stack may be swapped out to the disk(I meet a misunderstanding here? :frowning: )!
> If the lower driver which receives the Irp from us completes the Irp at
> the DISPATCH_LEVEL, Our ForwardAndWaitCompletionRoutine could be called
> at the DISPATCH_LEVEL and reference the event
> pointer which points to an address swapped out. Is it possible the
> KeSetEvent could
> cause a PAGE FAULT under this condition?
>
> It’s really quite a silly question! My head may be short circuited tonight!
> Could Anyone point out where I made the mistake?
>
>
> –
>
> _______________________________________________________
> Best Regards,
> hanzhu
>
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@compaqnet.be
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

Thanks for your reply!
I check the Win2k3 sp1 DDK’s documents. It said :
"
If the WaitMode parameter is UserMode, the kernel stack can be swapped
out during the wait. Consequently, a caller must never attempt to pass
parameters on the stack when calling KeWaitForSingleObject using the
UserMode argument. If you allocate the event on the stack, you must set
the WaitMode parameter to KernelMode.
"
So the KeWait*** routines lock the kernel stack into memory. That’s why
we can pass a stack-based memory to the HighLevel routine. Is it right?

Christiaan Ghijselinck wrote:

It could be that the routine is never swapped out during the hold in “KeWaitForSingleObject” . The WDK documentation mentions :
“If the WaitMode parameter is UserMode, the kernel stack can be swapped out during the wait.”
But if does not mention anything when you provide KernelMode .

Personalize , I do define always variables that are accessed through different routines into the device extension , or globally when
they are read only. But that is just a personal convention :slight_smile:

C.

----- Original Message -----
From: “hanzhu”
> To: “Windows System Software Devs Interest List”
> Sent: Sunday, January 01, 2006 1:24 PM
> Subject: [ntdev] KeSetEvent problem!
>
>
>> I have learned how to write windows’s driver for several months and I
>> have written several drivers!
>> I always follow the way Oney taught us to pass down the synchronous Irp
>> to the lower driver like
>> the following snapshot without any problem:
>>
>> NTSTATUS ForwardAndWait(PDEVICE_EXTENSION pdx, PIRP Irp)
>> {
>> KEVENT event;
>> KeInitialize(&event, NotificationRoutine, FALSE);
>> IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)
>> ForwardAndWaitCompletionRoutine, &event, TRUE, TRUE, TRUE);
>> < Some stuff>
>> NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);
>> if (status == STATUS_PENDING) {
>> KeWaitForSingleObject(&event, Executive, KernelMode,
>> FALSE, NULL);
>> status = Irp->IoStatus.Status;
>> }
>> return status;
>> }
>>
>> NTSTATUS ForwardAndWaitCompletionRoutine(PDEVICE_OBJECT fdo,
>> PIRP Irp, PKEVENT pev)
>> { if (Irp->PendingReturned)
>> KeSetEvent(pev, IO_NO_INCREMENT, FALSE);
>> return STATUS_MORE_PROCESSING_REQUIRED;
>> }
>>
>> But I feel rather confused when I review these code carefully today!
>> We allocate the KEVENT’s memory space on the stack. And then we pass down
>> the Irp and sleep on the event if IoCallDriver() returns STATUS_PENDING.
>> But when our driver sleep in a nonarbitrary thread context, the thread’s
>> kernel
>> stack may be swapped out to the disk(I meet a misunderstanding here? :frowning: )!
>> If the lower driver which receives the Irp from us completes the Irp at
>> the DISPATCH_LEVEL, Our ForwardAndWaitCompletionRoutine could be called
>> at the DISPATCH_LEVEL and reference the event
>> pointer which points to an address swapped out. Is it possible the
>> KeSetEvent could
>> cause a PAGE FAULT under this condition?
>>
>> It’s really quite a silly question! My head may be short circuited tonight!
>> Could Anyone point out where I made the mistake?
>>
>>
>> –
>>
>>
>> Best Regards,
>> hanzhu
>>
>>
>>
>>
>> —
>> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>>
>> You are currently subscribed to ntdev as: xxxxx@compaqnet.be
>> To unsubscribe send a blank email to xxxxx@lists.osr.com
>>
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@gmail.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>




Best Regards,
hanzhu

> If the WaitMode parameter is UserMode, the kernel stack can be swapped

out during the wait. Consequently, a caller must never attempt to pass
parameters on the stack when calling KeWaitForSingleObject using the
UserMode argument. If you allocate the event on the stack, you must set
the WaitMode parameter to KernelMode.
"
So the KeWait*** routines lock the kernel stack into memory. That’s why
we can pass a stack-based memory to the HighLevel routine. Is it right?

Yes, you may conclude that from the DOC , but only in case you use “KernelMode”
as WaitMode parameter value. A lawyer would however not make that conclusion
out from the DOC text :slight_smile:

C.

Christiaan Ghijselinck wrote:
> It could be that the routine is never swapped out during the hold in “KeWaitForSingleObject” . The WDK documentation mentions :
> “If the WaitMode parameter is UserMode, the kernel stack can be swapped out during the wait.”
> But if does not mention anything when you provide KernelMode .
>
> Personalize , I do define always variables that are accessed through different routines into the device extension , or globally
when
> they are read only. But that is just a personal convention :slight_smile:
>
> C.
>
>
>
>
> ----- Original Message -----
> From: “hanzhu”
> > To: “Windows System Software Devs Interest List”
> > Sent: Sunday, January 01, 2006 1:24 PM
> > Subject: [ntdev] KeSetEvent problem!
> >
> >
> >> I have learned how to write windows’s driver for several months and I
> >> have written several drivers!
> >> I always follow the way Oney taught us to pass down the synchronous Irp
> >> to the lower driver like
> >> the following snapshot without any problem:
> >>
> >> NTSTATUS ForwardAndWait(PDEVICE_EXTENSION pdx, PIRP Irp)
> >> {
> >> KEVENT event;
> >> KeInitialize(&event, NotificationRoutine, FALSE);
> >> IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)
> >> ForwardAndWaitCompletionRoutine, &event, TRUE, TRUE, TRUE);
> >> < Some stuff>
> >> NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);
> >> if (status == STATUS_PENDING) {
> >> KeWaitForSingleObject(&event, Executive, KernelMode,
> >> FALSE, NULL);
> >> status = Irp->IoStatus.Status;
> >> }
> >> return status;
> >> }
> >>
> >> NTSTATUS ForwardAndWaitCompletionRoutine(PDEVICE_OBJECT fdo,
> >> PIRP Irp, PKEVENT pev)
> >> { if (Irp->PendingReturned)
> >> KeSetEvent(pev, IO_NO_INCREMENT, FALSE);
> >> return STATUS_MORE_PROCESSING_REQUIRED;
> >> }
> >>
> >> But I feel rather confused when I review these code carefully today!
> >> We allocate the KEVENT’s memory space on the stack. And then we pass down
> >> the Irp and sleep on the event if IoCallDriver() returns STATUS_PENDING.
> >> But when our driver sleep in a nonarbitrary thread context, the thread’s
> >> kernel
> >> stack may be swapped out to the disk(I meet a misunderstanding here? :frowning: )!
> >> If the lower driver which receives the Irp from us completes the Irp at
> >> the DISPATCH_LEVEL, Our ForwardAndWaitCompletionRoutine could be called
> >> at the DISPATCH_LEVEL and reference the event
> >> pointer which points to an address swapped out. Is it possible the
> >> KeSetEvent could
> >> cause a PAGE FAULT under this condition?
> >>
> >> It’s really quite a silly question! My head may be short circuited tonight!
> >> Could Anyone point out where I made the mistake?
> >>
> >>
> >> –
> >>
> >>
> >> Best Regards,
> >> hanzhu
> >>
> >>
> >>
> >>
> >> —
> >> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
> >>
> >> You are currently subscribed to ntdev as: xxxxx@compaqnet.be
> >> To unsubscribe send a blank email to xxxxx@lists.osr.com
> >>
> >
> >
> >
> > —
> > Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
> >
> > You are currently subscribed to ntdev as: xxxxx@gmail.com
> > To unsubscribe send a blank email to xxxxx@lists.osr.com
> >
>
> –
>
>

> Best Regards,
> hanzhu
>
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@compaqnet.be
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

> But when our driver sleep in a nonarbitrary thread
context, the thread’s

kernel
stack may be swapped out to the disk(I meet a

No, this occurs only if you passed UserMode to KeWaitForSingleObject.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com