Not getting creates in KMDF

I have a KMDF filter driver that I’m attaching as a lower filter to RFCOMM. I see the IOCTLs that I am interested in but I don’t get any creates. I have tried two different methods of getting creates - 1) using WDF_FILEOBJECT_CONFIG_INIT / WdfDeviceInitSetFileObjectConfig and 2) creating a non-default queue and using WdfDeviceConfigureRequestDispatching to send WdfRequestTypeCreate to it (it has a EvtIoDefault set to catch these).

With either of those two methods in place (and also with both in place) I don’t get a single call to my create handler(s), yet I get hundreds of IOCTLs coming through the default queue. Is this not something that KMDF is designed to be able to filter? Or do I likely just have a bug in my setup code? Basically I’d like to make some decisions based on the context (pid namely) but by the time the IOCTL comes along it’s only in the original context about 25% of the time (even in the caller context callback) and in SYSTEM the rest of the time.

-JT

Rfcomm is probably not sending the create down the stack, nor should it since it is meant for rfcomm. You would need an upper filter to see the crate before rfcomm gets it.

Sent from Outlook Mailhttp: for Windows 10

From: xxxxx@gmail.com
Sent: Tuesday, July 28, 2015 9:40 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Not getting creates in KMDF

I have a KMDF filter driver that I’m attaching as a lower filter to RFCOMM. I see the IOCTLs that I am interested in but I don’t get any creates. I have tried two different methods of getting creates - 1) using WDF_FILEOBJECT_CONFIG_INIT / WdfDeviceInitSetFileObjectConfig and 2) creating a non-default queue and using WdfDeviceConfigureRequestDispatching to send WdfRequestTypeCreate to it (it has a EvtIoDefault set to catch these).

With either of those two methods in place (and also with both in place) I don’t get a single call to my create handler(s), yet I get hundreds of IOCTLs coming through the default queue. Is this not something that KMDF is designed to be able to filter? Or do I likely just have a bug in my setup code? Basically I’d like to make some decisions based on the context (pid namely) but by the time the IOCTL comes along it’s only in the original context about 25% of the time (even in the caller context callback) and in SYSTEM the rest of the time.

-JT


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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</http:>

Thanks for the quick response. This makes me feel like I’m missing something much more fundamental here. How can IOCTLs (or reads or writes) venture down the stack to levels where a previous create has not gone? How could any lower level driver process those IOs if it was not exposed to the original open/create to know what the IO applies to in the first place?

-JT

Because low drivers are typically not processing io on a per handle basis, the device interface for the lower level driver is a contact between the upper driver (which may have a create, may not) sending io down to the lower stack. The upper driver typically does not pass through unaltered io sent on the handle, rather it will take the io request, format the next stack location to be what the lower driver expects (like taking a write and turning it into an internal ioctl) and sending it down the stack. Think of the bluetooth HID driver, which is a peer of RFCOMM…you can’t open a handle to the hid miniport and yet it sends bluetooth specific io requests to the lower driver, just like rfcomm. You will see that a lot of the IO RFCOMM sends to your lower filter will not have a PFILE_OBJECT in the stack location.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, July 28, 2015 10:45 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Not getting creates in KMDF

Thanks for the quick response. This makes me feel like I’m missing something much more fundamental here. How can IOCTLs (or reads or writes) venture down the stack to levels where a previous create has not gone? How could any lower level driver process those IOs if it was not exposed to the original open/create to know what the IO applies to in the first place?

-JT


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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

Thanks for that explanation, that clears up a lot. What I’m seeing is that all the creates are coming in to RFCOMM’s named device object, \Device\BTHMS_RFCOMM, but my upper filter gets attached to RFCOMM’s second unnamed device object and thus I still see nothing. Is there a supported way for me to filter a named control device in KMDF?

Typically the function driver in the stack (in this case RFCOMM) doesn’t send CREATE IRPs down to the lower drivers. If you need the context from the create operation, you would then need to be above RFCOMM.

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, July 28, 2015 9:39 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Not getting creates in KMDF

I have a KMDF filter driver that I’m attaching as a lower filter to RFCOMM. I see the IOCTLs that I am interested in but I don’t get any creates. I have tried two different methods of getting creates - 1) using WDF_FILEOBJECT_CONFIG_INIT / WdfDeviceInitSetFileObjectConfig and 2) creating a non-default queue and using WdfDeviceConfigureRequestDispatching to send WdfRequestTypeCreate to it (it has a EvtIoDefault set to catch these).

With either of those two methods in place (and also with both in place) I don’t get a single call to my create handler(s), yet I get hundreds of IOCTLs coming through the default queue. Is this not something that KMDF is designed to be able to filter? Or do I likely just have a bug in my setup code? Basically I’d like to make some decisions based on the context (pid namely) but by the time the IOCTL comes along it’s only in the original context about 25% of the time (even in the caller context callback) and in SYSTEM the rest of the time.

-JT


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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

Not in a controlled fashion where you know that zero creates have happened yet. You can manually open the device, attach to it and then close the handle to see subsequent io sent to the device

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, July 28, 2015 1:04 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Not getting creates in KMDF

Thanks for that explanation, that clears up a lot. What I’m seeing is that all the creates are coming in to RFCOMM’s named device object, \Device\BTHMS_RFCOMM, but my upper filter gets attached to RFCOMM’s second unnamed device object and thus I still see nothing. Is there a supported way for me to filter a named control device in KMDF?


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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

Thanks Doron. Just to be clear that would have to be done via WDM code, right? There’s no equivalent of IoAttachDevice supported in KMDF is there?

You could call IoAttachDevice with a KMDF control WDFDEVICE, you would need to manage the detach on your own as well as io forwarding (Filter behavior), since the control WDFDEVICE has no idea it is attached to anything, by registering an io handler for each major type. You would create your own “Default” io target as well using the WDM device object you attached to.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, July 28, 2015 2:01 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Not getting creates in KMDF

Thanks Doron. Just to be clear that would have to be done via WDM code, right? There’s no equivalent of IoAttachDevice supported in KMDF is there?


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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 have tried the following (error checking removed for clarity)

// BTW, what SDDL should be used here? Since I am not naming my device and don’t want it to be accessible directly, I first tried passing NULL but that bugchecks. I don’t want to limit or loosen whatever security RFCOMM is requesting…
deviceInit = WdfControlDeviceInitAllocate(MyDriver, &SDDL_DEVOBJ_KERNEL_ONLY);

ntStatus = WdfDeviceCreate(&deviceInit, WDF_NO_OBJECT_ATTRIBUTES, &MyControlDevice);

WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig, WdfIoQueueDispatchParallel);

// the docs indicate this will be set to WdfDefault which will only be WdfFalse in the case of a filter, which I am, however they also say I can’t call WdfFdoInitSetFilter on a control device so I figured I should manually override this. Correct?
ioQueueConfig.PowerManaged = WdfFalse;
ioQueueConfig.EvtIoDefault = MyFltrControlIoDefault;

ntStatus = WdfIoQueueCreate(MyControlDevice,
&ioQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&queue);

RtlInitUnicodeString(&uniTargetName, L"\Device\BTHMS_RFCOMM");

ntStatus = WdfIoTargetCreate(MyControlDevice, WDF_NO_OBJECT_ATTRIBUTES, &MyControlIoTarget);

WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME(&openParams, &uniTargetName, STANDARD_RIGHTS_ALL);

ntStatus = WdfIoTargetOpen(MyControlIoTarget, &openParams);

WdfControlFinishInitializing(MyControlDevice);

MyCtrlDevObj = WdfDeviceWdmGetDeviceObject(MyControlDevice);

ntStatus = IoAttachDevice(MyCtrlDevObj, &uniTargetName, &BTBTHMS_RFCOMMDevObj);

I kick off a timer routine and once the RFCOMM device is created this all succeeds… the problem is, the WDF control device seems to be going away shortly thereafter. A second after all of these steps succeed the WDF control device is no longer valid, nor is the WDM device object that was associated with it. But the RFCOMM device is still valid and still showing our now invalid device object as being attached so the system crashes as soon as RFCOMM gets its first request. Am I missing some step to “reference” the control device and keep it from being disposed?

Prior to the call to IoAttachDevice:

4: kd> !wdfkd.wdfdevice 0x0000057f`ef1c02a8
Treating handle as a KMDF handle!

Dumping WDFDEVICE 0x0000057fef1c02a8

WDM PDEVICE_OBJECTs: self fffffa8010e3fb40

Control WDFDEVICE

4: kd> !devobj 0xfffffa80`10e3fb40
Device object (fffffa8010e3fb40) is for:
000000e4 \Driver\MyFltr DriverObject fffffa8010473060
Current Irp 00000000 RefCount 0 Type 00000022 Flags 00000044
Dacl fffff9a100ceac51 DevExt fffffa8010e40000 DevObjExt fffffa8010e3fcb8
ExtensionFlags (0000000000)
Characteristics (0x00000180) FILE_AUTOGENERATED_DEVICE_NAME, FILE_DEVICE_SECURE_OPEN
Device queue is not busy.

IoAttachDevice returns success and the returned PDEVICE_OBJECT does point to RFCOMM as expected. But then I hit F5 and break in about 1 second later and now I get this:

4: kd> !wdfkd.wdfdevice 0x0000057fef1c02a8 Treating handle as a KMDF handle! Not a valid WDFDEVICE handle 4: kd\> !devobj 0xfffffa8010e3fb40
fffffa8010e3fb40: is not a device object

Are you doing this in a pnp driver? Are you creating a pnp WDFDEVICE in addition to the control WDFDEVICE below?

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, July 28, 2015 7:28 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Not getting creates in KMDF

I have tried the following (error checking removed for clarity)

// BTW, what SDDL should be used here? Since I am not naming my device and don’t want it to be accessible directly, I first tried passing NULL but that bugchecks. I don’t want to limit or loosen whatever security RFCOMM is requesting…
deviceInit = WdfControlDeviceInitAllocate(MyDriver, &SDDL_DEVOBJ_KERNEL_ONLY);

ntStatus = WdfDeviceCreate(&deviceInit, WDF_NO_OBJECT_ATTRIBUTES, &MyControlDevice);

WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig, WdfIoQueueDispatchParallel);

// the docs indicate this will be set to WdfDefault which will only be WdfFalse in the case of a filter, which I am, however they also say I can’t call WdfFdoInitSetFilter on a control device so I figured I should manually override this. Correct?
ioQueueConfig.PowerManaged = WdfFalse;
ioQueueConfig.EvtIoDefault = MyFltrControlIoDefault;

ntStatus = WdfIoQueueCreate(MyControlDevice,
&ioQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&queue);

RtlInitUnicodeString(&uniTargetName, L"\Device\BTHMS_RFCOMM");

ntStatus = WdfIoTargetCreate(MyControlDevice, WDF_NO_OBJECT_ATTRIBUTES, &MyControlIoTarget);

WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME(&openParams, &uniTargetName, STANDARD_RIGHTS_ALL);

ntStatus = WdfIoTargetOpen(MyControlIoTarget, &openParams);

WdfControlFinishInitializing(MyControlDevice);

MyCtrlDevObj = WdfDeviceWdmGetDeviceObject(MyControlDevice);

ntStatus = IoAttachDevice(MyCtrlDevObj, &uniTargetName, &BTBTHMS_RFCOMMDevObj);

I kick off a timer routine and once the RFCOMM device is created this all succeeds… the problem is, the WDF control device seems to be going away shortly thereafter. A second after all of these steps succeed the WDF control device is no longer valid, nor is the WDM device object that was associated with it. But the RFCOMM device is still valid and still showing our now invalid device object as being attached so the system crashes as soon as RFCOMM gets its first request. Am I missing some step to “reference” the control device and keep it from being disposed?

Prior to the call to IoAttachDevice:

4: kd> !wdfkd.wdfdevice 0x0000057f`ef1c02a8 Treating handle as a KMDF handle!

Dumping WDFDEVICE 0x0000057fef1c02a8

WDM PDEVICE_OBJECTs: self fffffa8010e3fb40

Control WDFDEVICE

4: kd> !devobj 0xfffffa80`10e3fb40
Device object (fffffa8010e3fb40) is for:
000000e4 \Driver\MyFltr DriverObject fffffa8010473060 Current Irp 00000000 RefCount 0 Type 00000022 Flags 00000044 Dacl fffff9a100ceac51 DevExt fffffa8010e40000 DevObjExt fffffa8010e3fcb8 ExtensionFlags (0000000000) Characteristics (0x00000180) FILE_AUTOGENERATED_DEVICE_NAME, FILE_DEVICE_SECURE_OPEN Device queue is not busy.

IoAttachDevice returns success and the returned PDEVICE_OBJECT does point to RFCOMM as expected. But then I hit F5 and break in about 1 second later and now I get this:

4: kd> !wdfkd.wdfdevice 0x0000057fef1c02a8 Treating handle as a KMDF handle! Not a valid WDFDEVICE handle 4: kd\> !devobj 0xfffffa8010e3fb40
fffffa8010e3fb40: is not a device object


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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

As far as I know it qualifies as PNP. I have this driver registered as the lower filter for RFCOMM (under HKLM\SYSTEM\CurrentControlSet\Enum\BTH\MS_RFCOMM\7&42d85a8&0&0) so I get that AddDevice call and create a normal (WDF) filter object there. That one sees IO flowing through it as expected. The creation of my control device is done out of band in the timer routine, which fires after that AddDevice (i.e. the control device is the second device to be created).

Hi Doron. I figured out the problem with the WDF control device going away. When using IoAttachDevice cleanup and close are sent through to the WDF device before the call even returns (obviously you know this). When this was happening the framework was deleting the WDF device due to the last reference going away. Now that I have switched over to IoGetDeviceObjectPointer/IoAttachDeviceToDeviceStackSafe this problem is resolved and the control device starts receiving requests destined for RFCOMM.

Now the new problem is that I can’t figure out how to forward those requests along to RFCOMM in a manner that makes it happy.

I’m doing this:

WdfRequestFormatRequestUsingCurrentType(Request);

WdfRequestSetCompletionRoutine(Request, MyFltrControlIoCompletion, NULL);

brc = WdfRequestSend(Request, MyControlIoTarget, NULL);

if (!brc)
{
status = WdfRequestGetStatus(Request);

WdfRequestComplete(Request, status);
}

My completion routine shows a bunch of STATUS_INVALID_HANDLE and STATUS_INVALID_ADDRESS statuses. I had first tried no completion routine and just setting the SEND_AND_FORGET flag and things still weren’t working, I just didn’t know the specific statuses. I’ve confirmed that the IoTarget I set up is pointing at the RFCOMM device object (via !wdfkd.wdfiotarget). Is there some other step I need to take to format the request in a way that a non-KMDF target will be able to understand it? If this is a no-go for one reason or another could I extract the IRP from the WDFREQUEST and send it down via IoCallDriver and then just complete the WDFREQUEST in a completion routine tied to the IRP? That’s a bit hacky so I didn’t want to go there if there is a KMDF-approved solution.

Thanks!
-JT

My gut tells me for STATUS_INVALID_HANDLE, you need to make sure the right PFILE_OBJECT s in the next stack location is set in the request

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Thursday, July 30, 2015 1:34 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Not getting creates in KMDF

Hi Doron. I figured out the problem with the WDF control device going away. When using IoAttachDevice cleanup and close are sent through to the WDF device before the call even returns (obviously you know this). When this was happening the framework was deleting the WDF device due to the last reference going away. Now that I have switched over to IoGetDeviceObjectPointer/IoAttachDeviceToDeviceStackSafe this problem is resolved and the control device starts receiving requests destined for RFCOMM.

Now the new problem is that I can’t figure out how to forward those requests along to RFCOMM in a manner that makes it happy.

I’m doing this:

WdfRequestFormatRequestUsingCurrentType(Request);

WdfRequestSetCompletionRoutine(Request, MyFltrControlIoCompletion, NULL);

brc = WdfRequestSend(Request, MyControlIoTarget, NULL);

if (!brc)
{
status = WdfRequestGetStatus(Request);

WdfRequestComplete(Request, status);
}

My completion routine shows a bunch of STATUS_INVALID_HANDLE and STATUS_INVALID_ADDRESS statuses. I had first tried no completion routine and just setting the SEND_AND_FORGET flag and things still weren’t working, I just didn’t know the specific statuses. I’ve confirmed that the IoTarget I set up is pointing at the RFCOMM device object (via !wdfkd.wdfiotarget). Is there some other step I need to take to format the request in a way that a non-KMDF target will be able to understand it? If this is a no-go for one reason or another could I extract the IRP from the WDFREQUEST and send it down via IoCallDriver and then just complete the WDFREQUEST in a completion routine tied to the IRP? That’s a bit hacky so I didn’t want to go there if there is a KMDF-approved solution.

Thanks!
-JT


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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

Hi Doron,

I confirmed the next stack location is set up correctly and that WdfRequestFormatRequestUsingCurrentType is doing the same thing as IoCopyCurrentIrpStackLocationToNext. I also set a breakpoint in RFCOMM’s dispatch and I can see when the IRP gets to it that the file object and device object both look correct.

Just to confirm that something else wasn’t the problem I created a WDM filter object and attached it and re-wrote all the driver object dispatch entries. In my new dispatch I send them along to the previous KMDF entry point if it’s not my control dev and I forward the IRP the WDM way if it is my control dev. This all works. I see everything and the device functions properly. But it’s ugly and I’d prefer to keep it all KMDF if possible. One thing that this exercise did highlight is that with the WDM filter I get create followed by ioctls whereas with the KMDF approach I just get the ioctls (which is ironically where this whole thread started). Because the error is related to handles, which are obviously related to creates, this has me curious. I was trying to setup up the file config stuff on my KMDF control device but I’m not sure I understand how I can get it to handle cleanup and close properly. Those handlers only get the file object, not the request. In my case I need to forward to a remote IO target so I don’t know how I could do this from within those handlers, nor do I understand how the framework could auto-forward in this case.

Any additional advice for me?

Thanks!
-JT