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/


IRP_MJ_PNP function doesnt call

bdemirkolbdemirkol Member Posts: 9

Hi

I am trying to write simple WDM driver to catching device object that associated with plugged device. Basically i wrote DriverEntry such as following;

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
UNREFERENCED_PARAMETER(RegistryPath);

NTSTATUS status = STATUS_SUCCESS;
int i;
DriverObject->DriverUnload = DriverUnload;

for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
{
    DriverObject->MajorFunction[i] = DispatchPass;
}

// Biz sadece read request ile ilgileneceğiz.
DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnP;

DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "DriverEntry called\r\n");

return status;

}

But somehow, when i plugged flash memory or any device that connected with usb this function was not called. I tried KMDF driver with this function;
status = WdfDeviceInitAssignWdmIrpPreprocessCallback(
DeviceInit,
DispatchPnP,
IRP_MJ_PNP,
NULL,
0);

but it doesnt worked. I dont understand why. How can i catch device object which is associated plugged device?

btw, i wrote filter driver for ps2 keyboard and mouse, i want to write filter driver with same method by using pnp callback events. I'll be happy if you can help me.

Regards.

Comments

  • Doron_HolanDoron_Holan Member - All Emails Posts: 10,490

    How are you installing yourself into the stacks you want to filter? Adding a pnp handler doesn't mean you will be included in every pnp stack. Being in a pnp stack requires an explicit install step to either be added a a device or class filter. Your filter driver for a ps2 keyboard and mouse, if based on the WDK samples, are installed as device upper filters.

    d
  • bdemirkolbdemirkol Member Posts: 9

    @Doron_Holan said:
    How are you installing yourself into the stacks you want to filter? Adding a pnp handler doesn't mean you will be included in every pnp stack. Being in a pnp stack requires an explicit install step to either be added a a device or class filter. Your filter driver for a ps2 keyboard and mouse, if based on the WDK samples, are installed as device upper filters.

    Hi Doron,

    Thank you for answer, Is it necessary to call the "DispatchPnP" function in my example? I want to have a common function for all usb devices without discrimination. Can you explain a little more about what I have to do? is it about .inf file? any documentation?

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,403

    You need to do a lot more reading about Windows drivers and devices, because you don't yet understand the fundamental concepts. One of OSR's classes would be a good start.

    Each device has its own independent set of drivers, and each driver instance handles one device. There is no single spot where all I/O requests funnel through. It is possible to load a filter driver as part of a single device's stack, and it is possible to have a "class filter" where a new instance will be inserted into the stack for every device of a certain install class. If there were 8 devices in the class, you'd have 8 separate device objects.

    For each device, your filter instance would get all of the I/O requests passing through.

    What is it, exactly, that you are hoping to accomplish? What's the overall goal? Given your misunderstandings of the fundamentals, it's quite possible that your task is not achievable, or can be better achieved in another way.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • anton_bassovanton_bassov Member Posts: 5,158

    But somehow, when i plugged flash memory or any device that connected with usb this function was not called

    The most obvious question is "Why do you want to write a WDM driver in the year 2020,in the first place???"

    Notwithstanding this part, lets proceed to your actual question.

    First of all, if you want your DrvEntry() to get invoked by the system when your target device gets plugged in, you have to write an INF file that specifies your driver's PnP role in the target PnP stack(s), and take an extra step of actually installing this file. Second, when your DrvEntry() gets actually invoked, it has to register AddDevice() function (i.e the one that actually creates a new device and attaches it to the stack), as well as IRP_MJ_PNP handler. This is the very,very,very minimum that any PnP- compliant driver has to do.

    Once nothing, apart from the IRP_MJ_PNP handler registration part, has been done in so far, you are completely out of luck for the time being.....

    I want to have a common function for all usb devices without discrimination

    Just like that? A generic function for all keychains, mice, cameras, and, in general, for all USB devices of all USB classes in existence?

    Anton Bassov

  • bdemirkolbdemirkol Member Posts: 9

    Hi Tim,

    Each device has its own independent set of drivers, and each driver instance handles one device.

    An enlightenment came after this sentence :). I realized a driver called name "usbhub3". Before and after mounting the disk with usb. It is attached.

    And then i wrote this code;

    `NTSTATUS status;
    UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"\Driver\USBHUB3");

    if (NULL != OrgDispatchPnPFunc)
    {
        DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Driver already attached\r\n");
        return STATUS_SUCCESS;
    }
    
    PDRIVER_OBJECT targetDriverObject = NULL;
    
    status = ObReferenceObjectByName(&DriverName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, KernelMode,
        NULL, (PVOID*)&targetDriverObject);
    
    if (!NT_SUCCESS(status))
    {
        DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "ObjectReferenceObjectByName failed: %ld\r\n", status);
        return status;
    }
    
    ObDereferenceObject(targetDriverObject);
    
    //targetDriverObject.
    OrgDispatchPnPFunc = targetDriverObject->MajorFunction[IRP_MJ_PNP];
    targetDriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnP;`     
    

    As you can see I keep the original function address specified for IRP_MJ_PNP. Then i set the my function address. My DispatchPnP function is empty. When i run this driver nothing happened when I plugged in the usb device. So i managed to block it. In DriverUnload function i set original function pointer with same method. The question is; is it a good way to hook another driver's IRP message this way?

    What is it, exactly, that you are hoping to accomplish? What's the overall goal? Given your misunderstandings of the fundamentals, it's quite possible that your task is not achievable, or can be better achieved in another way.

    My goal is prevent usb devices for data loss. I read that this can be done with the usb bus filter driver, but I could not find an example.

  • bdemirkolbdemirkol Member Posts: 9

    Hi Anton,

    The most obvious question is "Why do you want to write a WDM driver in the year 2020,in the first place???"

    :))))))

    I found a tutorial and I'm trying to learn. I don't have a special request to write wdm. The subject is really complicated and I'm very confused. I also tried windows driver examples but I am more confused. What I am doing now is trying to learn. I prefer to write kmdf. I found a tutorial about wdm and thanks to this tutorial, I thought I could learn.

    Maybe what serves my purpose is to write a filter driver. But I could not find the right example for such a wide-ranging request.

    Just like that? A generic function for all keychains, mice, cameras, and, in general, for all USB devices of all USB classes in existence?

    In the first place, I thought it might be good to have a common capture function for all usb devices. I may be thinking wrong. I'm learning. If I'm moving right, I can filter them in the next step. I would be very glad if you check my reply to Tim and write your valuable comments.

    Regards

    @anton_bassov said:

    But somehow, when i plugged flash memory or any device that connected with usb this function was not called

    The most obvious question is "Why do you want to write a WDM driver in the year 2020,in the first place???"

    Notwithstanding this part, lets proceed to your actual question.

    First of all, if you want your DrvEntry() to get invoked by the system when your target device gets plugged in, you have to write an INF file that specifies your driver's PnP role in the target PnP stack(s), and take an extra step of actually installing this file. Second, when your DrvEntry() gets actually invoked, it has to register AddDevice() function (i.e the one that actually creates a new device and attaches it to the stack), as well as IRP_MJ_PNP handler. This is the very,very,very minimum that any PnP- compliant driver has to do.

    Once nothing, apart from the IRP_MJ_PNP handler registration part, has been done in so far, you are completely out of luck for the time being.....

    I want to have a common function for all usb devices without discrimination

    Just like that? A generic function for all keychains, mice, cameras, and, in general, for all USB devices of all USB classes in existence?

    Anton Bassov

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,403

    The question is; is it a good way to hook another driver's IRP message this way?

    Of course it's not a good way. It's slimy. You're not part of their device stack, so you won't get notified when something happens. If their driver should get reloaded, maybe because the last hub got replugged, the new driver will come up at a different address, and your remembered address will be wrong.

    There is a well-defined and supported mechanism for filtering IRPs in a device stack: a filter driver. That way, you become part of the device stack, so you get notified any time something happens, and things all come up and shut down in an orderly way.

    Windows already has group policies to block classes of USB devices from operating.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 7,807

    This is not a good learning exercise. It is a waste of time. Sort of like learning how to write with a goose quill instead of a pen or pencil. You can do it if you want to learn about how they did things back in the “days of old” ... but it has very little practical use today.

    Find a different tutorial. Stop wasting your time.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • bdemirkolbdemirkol Member Posts: 9
    edited May 14

    Hi Tim,

    There is a well-defined and supported mechanism for filtering IRPs in a device stack: a filter driver. That way, you become part of the device stack, so you get notified any time something happens, and things all come up and shut down in an orderly way.

    You mean IoAttachDeviceToDeviceStackSafe(...) function? I can attach with this function to all device objects in another driver. But this function needs device object which is part of target driver. But in my case the device object has not been created yet. My goal is to capture the moment when the device object was created. Is there a better way to do what I want? If yes, can you direct me on where to look?

    Regards.

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 7,807

    Did I mention that you're wasting your time? I can't remember if I said that yet...

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • bdemirkolbdemirkol Member Posts: 9

    Hi Peter,

    First of all, thank you for your comment. It does not mean that I do not follow your advice. I'm doing this because I'm looking for a way out. I noticed that WDM is lower level than other driver models and KMDF covers WDM. Am I wrong? Like MFC with Win32. I think the best way to learn the basics is to try to understand with WDM.
    After understanding how things happen in the background, I prefer to write KMDF. If I find a ready solution for my current problem, I would delay my learning process and prefer KMDF again. I dont insist on WDM.

    Regards.

  • Mark_RoddyMark_Roddy Member - All Emails Posts: 4,320
    via Email
    You are actually going about it backwards. Learn KMDF first, it is the
    standard for kernel and user mode driver development. After you have
    acquired a basic working knowledge of how to write a WDF driver, exploring
    WDM apis is fine.

    Mark Roddy
  • Calvin_Guan-2Calvin_Guan-2 Member Posts: 314

    OP, You don't have an AddDevice function in your DriverEntry().
    As other said, don't spend time on WDM unless you want to brain tease yourself. If you do, consider starting with a working example like toaster. Not sure if they still have it in DDK.

    Regards,
    Calvin

  • bdemirkolbdemirkol Member Posts: 9
    edited May 14
    Hi

    Returning to the problem itself, as I mentioned before, I tried to understand windows driver examples and KMDF projects and did research. But I couldn't find a solution. (This does not mean that there is no solution.) Since I could find a more understandable source about wdm, I proceeded through wdm. There is no other reason.

    I want to summarize what I want to do again. When any device is plugged into the USB, I want to capture and attach device object of this device as soon as it is created. I don't want to make a distinction about these devices right now. I would be very pleased if you say that this can be done in acceptable ways in kmdf.

    Regards.
  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,403

    My goal is to capture the moment when the device object was created. Is there a better way to do what I want?

    I TOLD you. Write a PnP filter driver. When you do that, the kernel will load your driver automatically for every new device that is created. Doing a filter driver is not just about which APIs you call. It's about marking yourself in the registry so the operating system handles the details for you. KMDF makes filter drivers almost trivially easy.

    I noticed that WDM is lower level than other driver models and KMDF covers WDM. Am I wrong?

    Only partially. It is true that KMDF is built on top of WDM, but that's almost entirely irrelevant. KMDF fixed things that are nearly impossible in WDM. KMDF manages the annoying details that everyone got wrong. It has been said that there has NEVER been a WDM driver that handles power management correctly until KMDF came along. Their state machine for handing PnP and Power events has hundreds of states.

    No GUI programmer would think of doing a C++ Windows app direct to the API any more. Everyone uses MFC or WTL or Windows Forms, because those are provably better ways of doing things. The KMDF situation is very similar.

    When any device is plugged into the USB, I want to capture and attach device object of this device as soon as it is created.

    There is essentially nothing you can do that applies generically to all USB devices. You will only cause yourself pain. However, making yourself an upper filter to your USB hub devices would allow you to do this.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • bdemirkolbdemirkol Member Posts: 9

    Hi Tim,

    Thank you for your explanations. I am reviewing this code.

    https://github.com/microsoft/Windows-driver-samples/blob/master/general/toaster/toastDrv/kmdf/filter/generic/filter.c

    I think i am going on the right way. Are there any sources other than msdn that you can recommend to me? (e-books, class, article etc.)

    Regards.

  • anton_bassovanton_bassov Member Posts: 5,158

    It has been said that there has NEVER been a WDM driver that handles power management correctly until KMDF came along.

    Well, many things "have been said" on this planet. The trick here is to filter the very obvious hype and nonsense, and to allow only those statements that may have at least some theoretical chance of being plausible, "down the stack". If this filtering criteria was applied here,
    the above "assertion" (which was, indeed, made quite a few times in this NG) would have never stood a slightest chance, and would have been immediately discarded simply as "yet another ridiculous claim that one may hear from our usual suspects" by the topmost filter
    in the stack right on the spot. However, as one can see, it gets repeated again and and again and again, for some reason.

    Let's imagine for a moment that this assertion is, indeed, true. It automatically implies that ABSOLUTELY all system-provided stacks, class drivers, bus drivers including ACPI.sys, and all other in-box drivers in existence that had been released before the advent of KMDF,
    were "getting it wrong all the way".

    This, in turn, makes one wonder how Win2K and Windows XP managed to run not only without causing widespread fires and explosions, but even without damaging the hardware on more or less regular basis (please note that we are speaking about the PM stuff here)....

    Anton Bassov

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 7,807

    Anton,

    Your ability to troll a thread astounds me, even after all these years, you know that?

    I don’t know who authored the phrase about which you object, but it could have been me. And regardless, I stand by it as being a useful, if perhaps ever so slightly exaggerated, rubric.

    Having BEEN there when KMDF’s PnP and Power State machine was being developed (and don’t forget our own Mr. Holan is one of the primary designers and developers of this work), I can tell you that nobody... NOBODY... had EVER taken the considerable time and effort required to figure out how the complete PnP and Power state machine should work before KMDF. I remember one specific occasion standing in the hallway with Mr. Oshins and (I think) Mr. Holan, looking at a diagram of the huge, evolving, PnP/Power state machine on the wall, discussing one particular state (I don’t remember what it was). None of us knew what should be done at that point. I remember one of the devs going down the hall to ask the guy who owned Power (I think) at the time exactly what he expected to happen, while we waited. He came back with the answer. And so it progressed through many, many, states.

    It is a fact that I have never seen (prior to KMDF) a WDM driver (in-box or 3rd party) that handles PnP and Power via a State Machine. OSR is the only author that I am aware of that has always written PnP/Power code this way. This failing, by itself, almost guarantees getting the implementation wrong.

    An even casually competent engineer will understand that there is a world of difference between an implementation being “correct” and an implementation working well enough “most of the time.” Clearly, the in-box WDM drivers handled PnP and Power right “most of the time.” That does not make them correct.

    Continue to troll, as you do. But at least try a little harder to make arguments that aren’t so obviously ignorant.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • Don_BurnDon_Burn Member - All Emails Posts: 1,689

    While I don't have the insider knowledge that Peter had, I was at the Driver Developer Conference where they showed the state machines. They were huge. One of the comments in the presentation was that a number of drivers were getting some of their more major holes fixed now that there was a model for "doing it right".

    So, Anton, Microsoft acknowledged years ago that there were significant holes in their implementation, why do you think you can get it right by yourself?

  • anton_bassovanton_bassov Member Posts: 5,158

    So, Anton, Microsoft acknowledged years ago that there were significant holes in their implementation, why do you think
    you can get it right by yourself

    OMG.....

    I am DEFINITELY not saying anything like that. If you bother yourself with checking my very first statement on this thread, you will see that I am asking "Why do you want to write a WDM driver in the year 2020,in the first place???"

    The only thing that I am saying is that the assertion that I was/is arguing about is a very obvious (at least from my perspective) example of unnecessary hype. I am most certainly not saying that someone should try writing a PnP driver in WDM when WDF is available, which would be a very stupid thing indeed...

    Anton Bassov

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 7,807

    I was/is arguing about is a very obvious (at least from my perspective) example of unnecessary hype

     
    Actually, the more I think about it, I would assert that the statement "there has NEVER been a WDM driver that handles power management correctly until KMDF came along" is either literally correct, or so very close to being literally correct that it's not worth arguing.
     
    Regardless of the statement's literal correctness, consider the conclusions one is asked to come to from this statement. Among them:

    • In the days of WDM, drivers had enormous problems with PnP/Power handling -- PnP/Power was The Number One problem pre-KMDF. That and IRP cancellation, actually, vie for first place in the pantheon of "Why WDM drivers crash." This is true regardless of whether the drivers were in-box or third party provided.
    • The KMDF team solved this problem by creating The Definitive State Machine for handling PnP/Power. Creating this was a lot of work, and took vast amounts of "insider" resources (Windows source code, access to the dev owners of multiple components).
    • It is folly for anyone to think that they fully understand Power Management/PnP from the WDM perspective without having similar knowledge to that of the KMDF devs, or an understanding of The Definitive State Machine. And without such knowledge, how could an entirely "correct" WDM driver be developed? I GUESS if you had a monkey and a keyboard and waited LONG enough it might happen at random EVENTUALLY...
    • It is foolish to write a device driver that supports PnP/Power today using WDM, if WDF can be used for the purpose.
       
      That is all.
       
      Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,403

    This, in turn, makes one wonder how Win2K and Windows XP managed to run not only without causing widespread
    fires and explosions, but even without damaging the hardware on more or less regular basis ...

    Maybe you weren't monitoring the forums at the turn of the century, when people were starting to try Win2K and early XP on laptops. The experience was not positive, in large part because drivers were Doing It Wrong.

    The server experience was much better, of course, because such systems rarely get any power activity.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,403

    I think i am going on the right way. Are there any sources other than msdn that you can recommend to me? (e-books, class, article etc.)

    That's a good place to start. It's impossible to tell how much experience you have. Clearly, you were good enough with the mechanics to get a simple driver to run, but what you're missing is design and philosophy. A key part of living in the kernel ecosystem is understanding how drivers are connected to each other to make up a stack, and how you can participate in that stack in a tested and well-ordered way.

    OSR has a "learning library" of articles on drivers they've collected over the decades. An OSR driver class would never be a bad idea. There are books on WDF/KMDF, although a lot of them focus on mechanics as well. Back issues of OSR's NT Insider are a good resource.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • anton_bassovanton_bassov Member Posts: 5,158

    Your ability to troll a thread astounds me, even after all these years

    Well, I do what I can :)

    An even casually competent engineer will understand that there is a world of difference between an implementation
    being “correct” and an implementation working well enough “most of the time.”

    Well, I don't really know about you, but on my books. the very phrase "an implementation working well enough most of the time "
    is just a very obvious euphemism for a "heisenbug", i.e for a buggy software that mostly works as expected but may fail
    in some edge cases, while a "correct" program is the one that works as expected in 100% cases. Please note that being "correct" does not necessarily imply being optimal, but the results a correct program produces are correct and 100% predictable. This is what makes it different from the one that ""works well enough most of the time”.

    In context of this discussion, a "correct but not optimal" implementation of ACPI driver would imply, for example, not taking the full advantage of the laptop battery's capabilities, while "working well enough most of the time " one would imply, for example, occasional CPU resets (I mean abrupt and unpredictable resets, rather than "polite" BSODs) due to overheating at the very minimum, and, probably, even occasional damage caused to the hardware in more extreme cases.

    Clearly, the in-box WDM drivers handled PnP and Power right “most of the time.” That does not make them correct.

    So were they "correct but not optimal" or "working well enough most of the time”?

    try a little harder to make arguments that aren’t so obviously ignorant.

    Well, as you can see it yourself, I try my best to provide a technically sound argumentation, while some other posters prefer
    to stay on "ad hominem side"

    Anton Bassov

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 7,807
    edited May 15

    I'm not going to debate this with you, Anton. It's off topic, and it's pointless.

    Should we put you on moderation for a few weeks until you come to your senses? Yes, I think that's a good idea. Done.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • bdemirkolbdemirkol Member Posts: 9
    Hi Tim

    < It's impossible to tell how much experience you have.

    17

    Thank you for your help. I also thank everyone else who wants to help.
    For now, I will move away from the forum and work on the subject. I will try to progress with your suggestions. There will probably be other things I would like to ask you. See you till then.

    Best Regards.
  • MBond2MBond2 Member Posts: 99

    I'm sure we miss the point by just deriding Anton.

  • anton_bassovanton_bassov Member Posts: 5,158

    I'm sure we miss the point by just deriding Anton.

    Well, Marion, in fact, the only one who really missed the point here is Truly Yours.

    This point is eternal and truly universal. It stands as "Don't argue with those who are in a position to pull the plug out", and I keep on missing this point all my life long....

    Anton Bassov

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

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 30 Mar 2020 OSR Seminar Space
Developing Minifilters 15 Jun 2020 LIVE ONLINE
Writing WDF Drivers 22 June 2020 LIVE ONLINE
Internals & Software Drivers 28 Sept 2020 Dulles, VA