Cancelling kernel timers in Win98

(those who may have seen the last version of this, please disregard and
excuse my premature use of the send button :slight_smile: )

I’m seeing differing behavior between Win98 and Win2K/XP when removing a
device. My StopDevice code includes:

KdPrint((DRIVERNAME " - Killing timers…\n"));
KeCancelTimer(&pdx->ReadServiceDpcTimer);
KeCancelTimer(&pdx->WriteServiceDpcTimer);

KdPrint((DRIVERNAME " - Removing DPCs…\n"));
KeRemoveQueueDpc(&pdx->ReadServiceDpc);
KeRemoveQueueDpc(&pdx->WriteServiceDpc);

As I understand the docs, this should stop my timers and flush the DPC
queue of any related requests, so that when KeRemoveQueueDpc returns, no
instances of that DPC remain queued. And in 2K/XP, that’s exactly how
it works. In 98, however, I’m seeing a page fault soon after
RemoveDevice is called, and a stack trace shows 2 calls within the
symbol space of the driver, but not aligned with actual call statements
in the ASM. I suspect that the DPC queue wasn’t properly flushed and a
lingering DPC is calling into what used to be my driver. Does this
sound right? And if so, how do I assure thet the DPC queue does get
completely flushed before allowing my driver to unload.

As always, clues appreciated and thanks in advance.

“Roy M. Silvernail” wrote:

As I understand the docs, this should stop my timers and flush the DPC
queue of any related requests, so that when KeRemoveQueueDpc returns, no
instances of that DPC remain queued. And in 2K/XP, that’s exactly how
it works. In 98, however, I’m seeing a page fault soon after
RemoveDevice is called, and a stack trace shows 2 calls within the
symbol space of the driver, but not aligned with actual call statements
in the ASM. I suspect that the DPC queue wasn’t properly flushed and a
lingering DPC is calling into what used to be my driver. Does this
sound right? And if so, how do I assure thet the DPC queue does get
completely flushed before allowing my driver to unload.

Win98 isn’t very quick about reusing the code space vacated by an
unloading driver, so that’s not likely to be your problem. One potential
trap for the unwary in 98/Me is that DriverUnload will be called before
the last call to IoDeleteDevice returns. Could this help explain your
symptom?


Walter Oney, Consulting and Training
Basic and Advanced Driver Programming Seminars
Check out our schedule at http://www.oneysoft.com

KeRemoveQueueDpc does not guarantee that your DPC isn’t running, it just
removes the DPC from the queue of DPCs to be executed. The PKDPC being
removed could be executing at the time of the removal call on another
processor. You need to provide your own synchronization against the DPC
executing for this to be mor airtight.

D

This posting is provided “AS IS” with no warranties, and confers no
rights

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Roy M. Silvernail
Sent: Monday, November 17, 2003 1:23 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Cancelling kernel timers in Win98

(those who may have seen the last version of this, please disregard and
excuse my premature use of the send button :slight_smile: )

I’m seeing differing behavior between Win98 and Win2K/XP when removing a

device. My StopDevice code includes:

KdPrint((DRIVERNAME " - Killing timers…\n"));
KeCancelTimer(&pdx->ReadServiceDpcTimer);
KeCancelTimer(&pdx->WriteServiceDpcTimer);

KdPrint((DRIVERNAME " - Removing DPCs…\n"));
KeRemoveQueueDpc(&pdx->ReadServiceDpc);
KeRemoveQueueDpc(&pdx->WriteServiceDpc);

As I understand the docs, this should stop my timers and flush the DPC
queue of any related requests, so that when KeRemoveQueueDpc returns, no

instances of that DPC remain queued. And in 2K/XP, that’s exactly how
it works. In 98, however, I’m seeing a page fault soon after
RemoveDevice is called, and a stack trace shows 2 calls within the
symbol space of the driver, but not aligned with actual call statements
in the ASM. I suspect that the DPC queue wasn’t properly flushed and a
lingering DPC is calling into what used to be my driver. Does this
sound right? And if so, how do I assure thet the DPC queue does get
completely flushed before allowing my driver to unload.

As always, clues appreciated and thanks in advance.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Doron Holan wrote:

KeRemoveQueueDpc does not guarantee that your DPC isn’t running, it just
removes the DPC from the queue of DPCs to be executed. The PKDPC being
removed could be executing at the time of the removal call on another
processor. You need to provide your own synchronization against the DPC
executing for this to be mor airtight.

This is happening on Win98, though…


Walter Oney, Consulting and Training
Basic and Advanced Driver Programming Seminars
Check out our schedule at http://www.oneysoft.com

Walter Oney wrote:

Win98 isn’t very quick about reusing the code space vacated by an
unloading driver, so that’s not likely to be your problem. One potential
trap for the unwary in 98/Me is that DriverUnload will be called before
the last call to IoDeleteDevice returns. Could this help explain your
symptom?

Good call! That looks like the culprit. Can I guard that with a spinlock?

“Roy M. Silvernail” wrote:

Good call! That looks like the culprit. Can I guard that with a spinlock?

No – this isn’t a race condition. It’s just how CONFIGMG works.


Walter Oney, Consulting and Training
Basic and Advanced Driver Programming Seminars
Check out our schedule at http://www.oneysoft.com