Hook called during AddDevice

Hello,

I have upper device filter driver. In AddDevice routine I create my DO, attach it to device stack, initialize my device extension and at the end I clear flag DO_DEVICE_INITIALIZING. The same sequence as in Toaster WDK sample.

But I get BSOD on WinXP 32bit with modem device. Problem is that in the middle of my device extension initialization, whereas DO_DEVICE_INITIALIZING is set, system calls my device hook (IRP_MJ_SYSTEM_CONTROL from nt!WmipForwardWmiIrp) with this DO, which is not completely initialized. In hook I use structures of extension which are not yet initialized and therefore BSOD.

Now my question is, how is it possible? Purpose of DO_DEVICE_INITIALIZING is described here http://msdn.microsoft.com/en-us/library/windows/hardware/gg487529.aspx. If it is set, system should not call my hook for that DO.

One workaround which come to my mind could be to attach DO to stack at the end of AddDevice routine right before DO_DEVICE_INITIALIZING is cleared. So first to initialize device extension and then call IoAttachDeviceToDeviceStack. But still return value of this function I put to device extension and racing can occur. But chance will be smaller.

Thanks.

Send the callstack when getting called in the middle of adddevice

d

debt from my phone


From: xxxxx@centrum.cz
Sent: 6/28/2012 6:39 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Hook called during AddDevice

Hello,

I have upper device filter driver. In AddDevice routine I create my DO, attach it to device stack, initialize my device extension and at the end I clear flag DO_DEVICE_INITIALIZING. The same sequence as in Toaster WDK sample.

But I get BSOD on WinXP 32bit with modem device. Problem is that in the middle of my device extension initialization, whereas DO_DEVICE_INITIALIZING is set, system calls my device hook (IRP_MJ_SYSTEM_CONTROL from nt!WmipForwardWmiIrp) with this DO, which is not completely initialized. In hook I use structures of extension which are not yet initialized and therefore BSOD.

Now my question is, how is it possible? Purpose of DO_DEVICE_INITIALIZING is described here http://msdn.microsoft.com/en-us/library/windows/hardware/gg487529.aspx. If it is set, system should not call my hook for that DO.

One workaround which come to my mind could be to attach DO to stack at the end of AddDevice routine right before DO_DEVICE_INITIALIZING is cleared. So first to initialize device extension and then call IoAttachDeviceToDeviceStack. But still return value of this function I put to device extension and racing can occur. But chance will be smaller.

Thanks.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

I don’t think WMI checks DO_DEVICE_INITIALIZING flag. You may need to move your IoWMIRegistrationControl call at the point where you can actually handle WMI IRPs.

> Send the callstack when getting called in the middle of adddevice

Here it is:
mydriver!Hook+0x78 (FPO: [Non-Fpo]) (CONV: stdcall)
nt!IopfCallDriver+0x31 (FPO: [0,0,0])
nt!WmipForwardWmiIrp+0x17e (FPO: [Non-Fpo])
nt!WmipSendWmiIrp+0x59 (FPO: [Non-Fpo])
nt!WmipRegisterOrUpdateDS+0x71 (FPO: [Non-Fpo])
nt!WmipRegisterDS+0xf (FPO: [Non-Fpo])
nt!WmipRegistrationWorker+0x49 (FPO: [Non-Fpo])
nt!ExpWorkerThread+0xef (FPO: [Non-Fpo])
nt!PspSystemThreadStartup+0x34 (FPO: [Non-Fpo])
nt!KiThreadStartup+0x16

device stack:
!DevObj !DrvObj !DevExt ObjectName

83523ad0 \Driver\mydriver 83523b88 000000a2
83a96a98 \Driver\Modem 83a96b50 000000a1
83a62488 \Driver\btwmodem 83a62540 BtModem2
83a9aed8 \Driver\BTKRNL 83a9af90 00000097
!DevNode 84476ee8 :
DeviceInst is “{95C7A0A0-3094-11D7-A202-00508B9D7D5A}\BTNULMDM\1&30ee4ad&0&1000000040002”
ServiceName is “Modem”

irp:
Irp is active with 10 stacks 10 is current (= 0x83a541bc)
No Mdl: System buffer=83a52000: Thread 8a533620: Irp stack trace.
cmd flg cl Device File Completion-Context

[17, 0] 0 0 83a96a98 00000000 80535506-ba507cd4
\Driver\Modem nt!WmipWmiIrpCompletion
Args: 00000000 00000000 00000000 00000000

[0, 0] 0 1 8a518248 00000000 00000000-00000000 pending
\Driver\WMIxWDM
Args: 00000000 00000000 00000000 00000000

>You may need to move your IoWMIRegistrationControl call at the point where you can actually handle WMI IRPs.

I do not call IoWMIRegistrationControl in my driver. Only WPP, which I use for logging, calls it (OS is WinXP, so WPP uses callback instead of IRP_MJ_SYSTEM_CONTROL). This BSOD is not caused by WMI request for my driver, it is request for driver below in the stack. It only passes through my driver.

If you don’t use WMI in your driver, why don’t you just forward the SYSTEM_CONTROL IRP down and be done with it? Why does it have to depend on your initialization state?

> If you don’t use WMI in your driver, why don’t you just forward the SYSTEM_CONTROL IRP down

This is a must, otherwise, Verifier complains.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

> Why does it have to depend on your initialization state?

I forward IRP_MJ_SYSTEM_CONTROL down, but in order to do that I need to access my DO’s extension. I have there remove lock among others and also next lower DO in the device stack. But my device extension has not been already initialized completely, so some values there are not valid. In this case it is remove lock, which is not initialized and therefore BSOD.

Minimum what I need valid is next lower DO in my device extension. And it can happen, that my AddDevice routine didn’t catchto save that address to device extension and system calls my hook with WMI IRP. Then I am not able to forward IRP down at all, since I do not know next lower DO’s address.

Why don’t you attach the DO before you enable WPP?

> Why don’t you attach the DO before you enable WPP?

I think this IRP_MJ_SYSTEM_CONTROL is not related to fact, my driver uses WPP. WPP uses IRP_MJ_SYSTEM_CONTROL only on Win2k, otherwise WppTraceCallback is called. And this OS is WinXP, where WPP is initialized with DriverObject and not DeviceObject. Next, WPP is disabled for my driver in OS.

In moment of BSOD my hook called IoCallDriver right before and returned status is STATUS_NOT_SUPPORTED. Then I call IoReleaseRemoveLock and BSOD occurs. I don’t know if IRP coming to my hook is valid in this moment, but if so, then you can see (I posted it above) all args are zero and minor code is 0 (IRP_MN_QUERY_ALL_DATA). DO is device object of Modem driver, which is next lower driver in device stack.

I think this problem has nothing to do with WPP or am I wrong?

There is nothing you can do to completely remove this race condition if it is happening during adddevice. The best you can do is attach to the stack at the end of your callback.

d

debt from my phone


From: xxxxx@centrum.cz
Sent: 7/1/2012 10:58 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Hook called during AddDevice

Send the callstack when getting called in the middle of adddevice

Here it is:
mydriver!Hook+0x78 (FPO: [Non-Fpo]) (CONV: stdcall)
nt!IopfCallDriver+0x31 (FPO: [0,0,0])
nt!WmipForwardWmiIrp+0x17e (FPO: [Non-Fpo])
nt!WmipSendWmiIrp+0x59 (FPO: [Non-Fpo])
nt!WmipRegisterOrUpdateDS+0x71 (FPO: [Non-Fpo])
nt!WmipRegisterDS+0xf (FPO: [Non-Fpo])
nt!WmipRegistrationWorker+0x49 (FPO: [Non-Fpo])
nt!ExpWorkerThread+0xef (FPO: [Non-Fpo])
nt!PspSystemThreadStartup+0x34 (FPO: [Non-Fpo])
nt!KiThreadStartup+0x16

device stack:
!DevObj !DrvObj !DevExt ObjectName

83523ad0 \Driver\mydriver 83523b88 000000a2
83a96a98 \Driver\Modem 83a96b50 000000a1
83a62488 \Driver\btwmodem 83a62540 BtModem2
83a9aed8 \Driver\BTKRNL 83a9af90 00000097
!DevNode 84476ee8 :
DeviceInst is “{95C7A0A0-3094-11D7-A202-00508B9D7D5A}\BTNULMDM\1&30ee4ad&0&1000000040002”
ServiceName is “Modem”

irp:
Irp is active with 10 stacks 10 is current (= 0x83a541bc)
No Mdl: System buffer=83a52000: Thread 8a533620: Irp stack trace.
cmd flg cl Device File Completion-Context

[17, 0] 0 0 83a96a98 00000000 80535506-ba507cd4
\Driver\Modem nt!WmipWmiIrpCompletion
Args: 00000000 00000000 00000000 00000000

[0, 0] 0 1 8a518248 00000000 00000000-00000000 pending
\Driver\WMIxWDM
Args: 00000000 00000000 00000000 00000000


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

> The best you can do is attach to the stack at the end of your callback.

Ok, but still there can be racing problem with NextLowerDeviceObject which I get as return value from IoAttachDeviceToDeviceStack. If my hook is called between IoAttachDeviceToDeviceStack and saving the result to device extension, then I can not forward IRP down in device hook. Solution can be to wait in device hook till next lower DO address is valid in my device extension. Is it OK?

So the OS calls WMI for the modem.sys driver. It calls IoGetAttachedDeviceReference, which has your devobj as top of the stack returned.

Apparently, you were able to forward the IRP to modem.sys. Then it returned and you crashed. No problem, just don’t do what makes you crash.

How do you forward the IRPs to the lower device? Show your code. I suspect it is incorrect.

> How do you forward the IRPs to the lower device? Show your code. I suspect it is incorrect.

There are 2 threads in that moment where my driver is in call stack. One is AddDevice, where initialization of my device extension is still not finished (it is inside IoGetDeviceProperty, which I call there). Other one is my device hook, where I use device extension. Fortunately next lower driver address in device extension has been already set in AddDevice, so I am able to call IoCallDriver to modem.sys. At the beginning of my device hook I call IoAcquireRemoveLock on still not initialized remove lock in device extension. This passes (although it could crash here), but then after IoCallDriver to modem.sys I call IoReleaseRemoveLock and BSOD occurs, what is obvious, since remove lock was not initialized in AddDevice due to threads racing.

This problem occurs very rarely, I observed it only 2 times. For my driver I used toaster sample from WDK, so logic is the same.

> Ok, but still there can be racing problem with NextLowerDeviceObject which I get as return value from IoAttachDeviceToDeviceStack.

Maybe this I can solve with IoAttachDeviceToDeviceStackSafe instead of IoAttachDeviceToDeviceStack. In MSDN there is written that this safe function is dedicated for filesystem filter drivers, can I use it in device filter driver as well?

  1. You can initialize your remove lock early.
  2. You don’t need to use a remove lock when you forward SYSTEM_CONTROL IRP.