Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV

Before Posting...

Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


EvtIoInternalDeviceControl's level in filter drivers

CycloneCyclone Member Posts: 2

I was working on a mouse and a keyboard filter driver and decided to look at Microsoft's examples and noticed that their 'MouFilter_EvtIoInternalDeviceControl' function (same with the keyboard version) had a description that said, "This routine is the dispatch routine for internal device control requests.". After more investigating it seems like this function runs at Dispatch Level if this is true, I wonder why they would have '#pragma alloc_text (PAGE, MouFilter_EvtIoInternalDeviceControl)' and 'PAGED_CODE()' located inside the function because I thought functions running at Dispatch Level can never be paged out without causing a fault.

My second question pertains to the same function where I have been advised to add a SpinLock to the Device Extension and then acquire that lock inside of 'case IOCTL_INTERNAL_MOUSE_DISCONNECT:' and then release it before breaking out. I was advised that this was good to do in order to mitigate other threads from trying to run the 'IOCTL_INTERNAL_MOUSE_CONNECT' case while 'IOCTL_INTERNAL_MOUSE_DISCONNECT' is being ran from a separate thread. This seems very unlikely to be an issue, but I don't see what being a little extra carful could harm.

Comments

  • Doron_HolanDoron_Holan Member - All Emails Posts: 10,829

    'IOCTL_INTERNAL_MOUSE_CONNECT' and DISCONNECT will not run concurrently with the current implementation. It has been this way for 25+ years. If you feel safer synchronizing the two, go for it.

    d
  • CycloneCyclone Member Posts: 2

    @Doron_Holan said:
    'IOCTL_INTERNAL_MOUSE_CONNECT' and DISCONNECT will not run concurrently with the current implementation. It has been this way for 25+ years. If you feel safer synchronizing the two, go for it.

    Ok thanks what about the first question?

  • Scott_Noone_(OSR)Scott_Noone_(OSR) Administrator Posts: 3,679

    @Cyclone said:
    I was working on a mouse and a keyboard filter driver and decided to look at Microsoft's examples and noticed that their 'MouFilter_EvtIoInternalDeviceControl' function (same with the keyboard version) had a description that said, "This routine is the dispatch routine for internal device control requests.". After more investigating it seems like this function runs at Dispatch Level if this is true, I wonder why they would have '#pragma alloc_text (PAGE, MouFilter_EvtIoInternalDeviceControl)' and 'PAGED_CODE()' located inside the function because I thought functions running at Dispatch Level can never be paged out without causing a fault.

    The word "dispatch" is very overloaded in Windows...In the underlying Windows Driver Model (WDM) the I/O Manager dispatches I/O requests to drivers by calling their "I/O Dispatch Entry Points". WDF abstracts the Dispatch Entry Points using WDFIOQUEUEs and their associated "I/O Event Processing Callbacks". So, in this case, the "MouFilter_EvtIoInternalDeviceControl Event Processing Callback" is an abstraction of what would have originally been an "IRP_MJ_INTERNAL_DEVICE_CONTROL Dispatch Entry Point" (or "Dispatch Routine").

    Going back to the IRQL question: The I/O Dispatch Entry Points can run at IRQL <= DISPATCH_LEVEL* depending on the stack and who is sending the I/O requests. If you're writing a filter you can't know a priori at what IRQL(s) your Dispatch Entry Points (and therefore I/O Event Processing Callbacks) will run as you don't control the I/O rules of the stack. Presumably whoever wrote the sample "knows" that the Internal IOCTL requests in the mouse stack are always processes at < DISPATCH_LEVEL and therefore it's safe to put this in a pageable code section. Note that the WDFQUEUEs also have an ExecutionLevel option that allows you to force your callbacks to run at PASSIVE_LEVEL, though that's often a bad idea in a filter unless you REALLY know the rules and behavior of the stack.

    *The "dispatch" in DISPATCH_LEVEL is referring to the Thread Dispatcher, which is a different use of the word and not directly related to the I/O Dispatch Entry Points (except that they can possibly run at DISPATCH_LEVEL...Head hurt yet? 😂)

    -scott
    OSR

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 13-17 May 2024 Live, Online
Developing Minifilters 1-5 Apr 2024 Live, Online
Internals & Software Drivers 11-15 Mar 2024 Live, Online
Writing WDF Drivers 20-24 May 2024 Live, Online