Are the dispatch routines of a simple WDM driver always called at the requestor process context?

Lets say that i have a very simple WDM driver, so its not a filter driver or file system related driver, its just a simple WFP driver for network inspection.

My question is, does my dispatch routine for IRP_MJ_DEVICE_CONTROL specifically, always gets called at the context of the process that called deviceIoControl? Assuming that no other device is attached to my device object.

I’m asking this because i want to send the Event handle from usermode to my driver for synchronization, and was reading this article:

https://www.osronline.com/article.cfm^id=108.htm

So considering that I’m a simple WDM driver and nothing file system related, can i safely go with the approach of sending the handle from user to kernel? Am i guaranteed to be in the correct process context?

Also i should note that the process is always 32 bit but the driver could be 64 bit, so I’m not sure whether the process being under wow64 in case of 64 bit systems could affect the ObReferenceObjectByHandle, considering that the input is a handle for a 32 bit process, given to a 64 bit driver?

Yes. If there are no drivers above you, then your dispatch routines are called in the caller context. Yes, the kernel understands handles from both 32- and 64-bit processes.

1 Like

The user mode event handle technique is horrible and generally unnecessary.
Why not just pend an IOCTL and complete that?
Mark Roddy

1 Like

I have always used the inverted call model, and it’s great for lots of reasons; but I am curious why, exactly, the user mode event handle technique is horrible?

The event handle pattern breaks down for a couple of reasons
1 you have to manage the PKEVENT lifetime now as you will be releasing the object when the process goes away. this leads to many possible run down bugs/race conditions and overall increase of complexity
2 the event can only signal that something has changed, but it has no data associated with it. So the app still has to send an IOCTL to query state/data after the wakeup. Of course, state can change between the signal and the query. If you just pend the IOCTL, it completes with the signal AND the data atomically.

1 Like

The article spells out how you can screw yourself but also does point out
the constraints on when it is less horrible. However, what the correct way
to safely use a user mode event within the constraints of always being in
the correct context is, is vastly more complicated than a simple IOCTL
completion for event signalling.

Mark Roddy

I like to think of it this way. Inverted call is a proper superset of the event handle method. After all, there is an event handle in the OVERLAPPED structure that make it work. Anything you can do with an event handle can be done with inverted call, but not vice versa.

It should be noted that OVERLAPPED IO does not require an event handle. Completions can also be detected via IOCP, APC and even polling.

trying to share events between UM and KM has always been a terrible idea. The reasons why are too long to write in a simple post, but think about the pattern

  1. something happens and the KM code sets the event
  2. a UM thread that has been blocking on the event is now marked as ready to run and is scheduled
  3. that UM thread returns from KM to UM and initiates an IOCTL - transitioning back to KM
  4. the driver does something with that IOCTL and it returns to UM - handling the case that whatever triggered the event is either no longer the case and there is nothing to send back, or has occurred multiple times and there is too much to send back
  5. the code in UM does something with that data

or

  1. code in UM submits several IOCTLs and the code in KM marks them pending
  2. as stuff happens, the code in KM completes a pending IOCTL back to UM
  3. code in UM does something with the data and submits a new IOCTL - which is marked pending

depending on what the requirements are, the completions can be handled by a single thread or multiple threads in UM. testing is needed to determine how many IOCTLs should be pended so that there will always be ‘enough’ and some kind of strategy for what to do if the system is under so much stress that they run out

1 Like

OP: I’m touched by your faith in OSR… but are you REALLY citing a 20 year old article as the basis for your new engineering project?

OK, OK…. I’ve recently done both, recently… use the shared event approach (because it provided compatibility with a legacy implementation), and the I/O Completion approach. Both approaches can be made to work… But signaling with I/O Completion just easier and more flexible. And the I/O path in Windows is VERY highly optimized.

What that ancient article (which I did NOT write, by the way) does NOT say is when you deref the user-mode Event. The answer to that is you deref it in Cleanup. This assumes you understand the difference between cleanup, close, and cancel… something that the many code reviews I’ve done suggests is not common. You have to be VERY careful you don’t have a race between attempting to signal the even and Cleanup. It’s so-able but it can be tricky and hard to test.

Peter

1 Like