Help Stamp Out Sensless WDM Usage

I left software development about 12 years ago (before WDF was a thing). Since I have returned, I’ve written one new driver that was a virtual storport miniport. These beasts live somewhere between a WDM and a miniport.

Recently I have been working on a older WDM driver written by someone else about 10 years ago. I have been considering the idea of porting the driver to a WDF/KMDF driver, but have put that on the back burner because of the demands to get code shipped.

However, after reading Peter’s post, I have decided to move the port to the foreground. How difficult can it be; right?

After reading the documentation, I see that if you want to receive PNP notifications, you must be a WDM driver. In the driver I am working on, it filters IRP_MJ_PNP in order to detect special files on the volume (this is a volume filter driver, not an FS volume filter). This is done to maintain the power pageable bit while the filter is active.

Does this requirement prevent me from porting to WDF/KMDF?

– Jamey

BTW: When I reply via email, the emails get lost. I sent this same post via email, and the email is nowhere to be found, not even in my outbox. Strange. So I have to come here to the website to post. If this gets posted twice, I apologize.

>>When would someone HAVE to write a WDM driver, exactly

Kernel Service drivers.

Yes, absolutely agree that writing Kernel Services using WDM is both entirely appropriate and a Best Practice. I *thought* I said that in my long initial rant, but perhaps it was somewhere else that I ranted this carve-out.

But, in any case, agreed: Kernel Services should be WDM (though they do not HAVE to be WDM).

Peter
OSR
@OSRDrivers

Peter,

You did say it, and for a simple kernel service I totally agree. I
recently did rewrite one kernel service driver to KMDF, the original WDM had
something like 20 cancel safe queues to do weird things. Moving it to KMDF
queues made the code so much nicer!

Don Burn
Windows Driver Consulting
Website: http://www.windrvr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@osr.com
Sent: Monday, March 12, 2018 11:55 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Help Stamp Out Sensless WDM Usage

>>When would someone HAVE to write a WDM driver, exactly

>Kernel Service drivers.

Yes, absolutely agree that writing Kernel Services using WDM is both
entirely appropriate and a Best Practice. I thought I said that in my
long initial rant, but perhaps it was somewhere else that I ranted this
carve-out.

But, in any case, agreed: Kernel Services should be WDM (though they do not
HAVE to be WDM).

Peter
OSR
@OSRDrivers


NTDEV is sponsored by OSR

Visit the list online at:
http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at
http:</http:></http:></http:>

Warning: Thread Drift Ahead

No! You can still filter and receive these. WdfDeviceInitAssignWdmIrpPreprocessCallback is your friend.

You are aware that there’s WdfDeviceSetSpecialFileSupport ?

Peter
OSR
@OSRDrivers

xxxxx@osr.com wrote:

No! You can still filter and receive these. WdfDeviceInitAssignWdmIrpPreprocessCallback is your friend.

I suspect the author of the original quote really meant “at least a WDM
driver”.  All KMDF drivers are also WDM drivers.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Peter,

Does KMDF support normal flag handling for filter drivers? I thought
it did, so since the original question was on a filter, this should be let
the framework do it.

Don Burn
Windows Driver Consulting
Website: http://www.windrvr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@osr.com
Sent: Monday, March 12, 2018 12:01 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Help Stamp Out Sensless WDM Usage

Warning: Thread Drift Ahead



No! You can still filter and receive these.
WdfDeviceInitAssignWdmIrpPreprocessCallback is your friend.



You are aware that there’s WdfDeviceSetSpecialFileSupport ?

Peter
OSR
@OSRDrivers


NTDEV is sponsored by OSR

Visit the list online at:
http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at
http:</http:></http:></http:>

Peter, no. I just started digging into the documentation last night. I have zero WDF/KMDF experience. It will take me a few days to come up to speed.

I’ve run into my first issue :slight_smile:

In the WDM driver, I would check device characteristics to see if the device was something we were not interested in filtering. Here is a snippet of WDM code:

NTSTATUS FilterAddDevice(In PDRIVER_OBJECT Driver,
In PDEVICE_OBJECT PhysicalDevice) {
if (FlagOn(PhysicalDevice->Characteristics, FILE_REMOVABLE_MEDIA) ||
FlagOn(PhysicalDevice->Characteristics, FILE_READ_ONLY_DEVICE) ||
FlagOn(PhysicalDevice->Characteristics, FILE_READ_ONLY_VOLUME)) {
// We are not interested in removable media. Exit with nothing to do.
return STATUS_SUCCESS;
}

This would skip filtering read-only and removable devices. In WDF, I cannot get access to the lower device object to get the characteristics. I assume WdfDeviceCreate() attaches to the lower device by me having called WdfFdoInitSetFilter() prior to calling WdfDeviceCreate().

So, let’s say I have called WdfDeviceCreate(), I check the characteristics after calling WdfGetDeviceCharacteristsic(), and determine I really do not want to filter this device.

How do I go about detaching from the lower device before exiting EvtDevicedd() function? I don’t want to have a null filter sitting there just passing data along; do I?

Maybe I am missing something. I am reading the documentation while trying to do the port.

– Jamey

WdfFdoInitWdmGetPhysicalDevice and you have the same code as below without creating a WDFDEVICE

-----Original Message-----
From: xxxxx@lists.osr.com On Behalf Of xxxxx@gmail.com
Sent: Monday, March 12, 2018 3:09 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Help Stamp Out Sensless WDM Usage

I’ve run into my first issue :slight_smile:

In the WDM driver, I would check device characteristics to see if the device was something we were not interested in filtering. Here is a snippet of WDM code:

NTSTATUS FilterAddDevice(In PDRIVER_OBJECT Driver,
In PDEVICE_OBJECT PhysicalDevice) {
if (FlagOn(PhysicalDevice->Characteristics, FILE_REMOVABLE_MEDIA) ||
FlagOn(PhysicalDevice->Characteristics, FILE_READ_ONLY_DEVICE) ||
FlagOn(PhysicalDevice->Characteristics, FILE_READ_ONLY_VOLUME)) {
// We are not interested in removable media. Exit with nothing to do.
return STATUS_SUCCESS;
}

This would skip filtering read-only and removable devices. In WDF, I cannot get access to the lower device object to get the characteristics. I assume WdfDeviceCreate() attaches to the lower device by me having called WdfFdoInitSetFilter() prior to calling WdfDeviceCreate().

So, let’s say I have called WdfDeviceCreate(), I check the characteristics after calling WdfGetDeviceCharacteristsic(), and determine I really do not want to filter this device.

How do I go about detaching from the lower device before exiting EvtDevicedd() function? I don’t want to have a null filter sitting there just passing data along; do I?

Maybe I am missing something. I am reading the documentation while trying to do the port.

– Jamey


NTDEV is sponsored by OSR

Visit the list online at: https:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at https:

To unsubscribe, visit the List Server section of OSR Online at https:</https:></https:></https:>

Thanks! I hadn’t found that function yet.

One more thing: When I call WdfFoInitSetFilter(), does it also propagate the device type? In my WDM code, I had to propagate the device type to the filter device object by hand.
The WDK says it “propagates flags & characteristics”. However, it seems reasonable to expect the device type to be propagated in the context of a filter driver. In the WDK sample kbdfilter driver, it sets the device type as follows:

WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_KEYBOARD);

Otherwise, I have to have code like this:

// Get the device property class GUID.
ULONG ResultLength = 0;
WCHAR PropertyBuffer[MAX_UNICODE_STACK_BUFFER_LENGTH];
ULONG BufferLength = MAX_UNICODE_STACK_BUFFER_LENGTH;
if (NT_ERROR(WdfFdoInitQueryProperty(DeviceInit, DevicePropertyClassGuid,
BufferLength, PropertyBuffer, &ResultLength))) {
// We cannot attach to this device, so do nothing.
return STATUS_SUCCESS;
}

// Double check that someone has not tried to load this driver
// on an unsupported device type.
UNICODE_STRING DevGuid;
RtlInitUnicodeString(&DevGuid, PropertyBuffer);
if (RtlEqualUnicodeString(&DevGuid, &g_VolumeSnapshotGUID, TRUE)) {
// If this is a snapshot, we flag it as a virtual disk.
WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_VIRTUAL_DISK);
}
else if (RtlEqualUnicodeString(&DevGuid, &g_VolumeGUID, TRUE)) {
// If this is a volume, we flag it as a disk.
WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_DISK);
}
else {
// Unsupported device type, so do nothing.
return STATUS_SUCCESS;
}

– Jamey

Nevermind, using your advice above, I can make a single call to set the device type after passing the string tests.

OK, I think I am well on my way to getting this thing ported.

Thanks everyone.

– Jamey

SetFilter will propagate the device type iirc. Wdf is open sourced, you can see for yourself.

Bent from my phone


From: xxxxx@lists.osr.com on behalf of xxxxx@gmail.com
Sent: Monday, March 12, 2018 3:36:22 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Help Stamp Out Sensless WDM Usage

Nevermind, using your advice above, I can make a single call to set the device type after passing the string tests.

OK, I think I am well on my way to getting this thing ported.

Thanks everyone.

– Jamey


NTDEV is sponsored by OSR

Visit the list online at: https:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at https:

To unsubscribe, visit the List Server section of OSR Online at https:</https:></https:></https:>

Thread drift, folks… back on topic, if we can? Mr. Kirby… start a new thread.

Peter
OSR
@OSRDrivers

Peter wrote: "Kernel Services should be WDM "

So I was looking for documentation on a dummy inf for a kernel service driver, just to get it signed, and all I could find was documentation for wdf sections in a dummy inf. I had to go back to the 7600 DDK and find a sample inf that didnt have a manufacturers section to use as a template.

So in this instance we need the WDM documentation preserved. :slight_smile:

I understand your frustration Peter, I too have started using WDF, on your recommendation, and my initial nausea soon passed as I realised it really is very robust and simple.

But I think, like using MFC in preference to the Win32 API, that it is a wrapper on a base API, and it does no harm to be aware of that base API, and to have it documented. The issue is to use the wrapper in preference because it is so damn easy to throw stuff together.

Perhaps that should be your focus?

> Perhaps that should be your focus?

Hmmmm… Well, I didn’t say I wanted to remove WDM function documentation, did I.

The thing to keep in mind about WDF, and one very crucial thing that sets it apart from MFC (yuck!), is that KMDF allows you to “escape” from the framework directly to native system calls. This is a KEY PRECEPT of KMDF, and was something the community *insisted* on very vocally .

This ability to escape the framework to the underlying “native” API is part of the real genius of KMDF and what makes it so very powerful.

So, duh! I’m not asking to strike the description of native kernel-mode functions from the documentation. There’s a difference between the WDM DRIVER MODEL – the use of which (for everything but kernel services and a few other small niches) should be loudly decried and thoroughly discouraged – and the underlying native Windows Ke, Se, Io, Mm, Ex, Ps, Ob, and friends APIs.

What I *am* advocating is, specifically (this from my FIRST POST in this thread, qv):

  1. We need to scrub the samples to make sure there are no WDM drivers around (other
    than software only “kernel services”). If you host example on GitHub or someplace else, if it’s a WDM driver , for heavens sakes make the readme say it’s a deprecated model.

  2. We need the WDK docs to very clear say, everywhere, that people should be using WDM
    as a last resort only if they are not writing a file system or a kernel service. We should put this on every single WDM function doc page: IoXxxx, KeXxxx, etc.

  3. We should warn people to NOT start a WDM sample unless they are writing a “kernel service” – We should direct them straight to WDF.

Peter
OSR
@OSRDrivers

Not sure why you say MFC doesn’t allow ‘escape’ to underlying Windows APIs. It certainly does, and I’ve used that capability many times. MFC may not be perfect, but it really isn’t bad at all, IMHO.

* Bob

? Bob Ammerman
? xxxxx@ramsystems.biz
? 716.864.8337

138 Liston St
Buffalo, NY 14223
www.ramsystems.biz

-----Original Message-----
From: xxxxx@lists.osr.com On Behalf Of xxxxx@osr.com
Sent: Wednesday, March 14, 2018 9:48 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Help Stamp Out Sensless WDM Usage

> Perhaps that should be your focus?

Hmmmm… Well, I didn’t say I wanted to remove WDM function documentation, did I.

The thing to keep in mind about WDF, and one very crucial thing that sets it apart from MFC (yuck!), is that KMDF allows you to “escape” from the framework directly to native system calls. This is a KEY PRECEPT of KMDF, and was something the community insisted on very vocally .

This ability to escape the framework to the underlying “native” API is part of the real genius of KMDF and what makes it so very powerful.

So, duh! I’m not asking to strike the description of native kernel-mode functions from the documentation. There’s a difference between the WDM DRIVER MODEL – the use of which (for everything but kernel services and a few other small niches) should be loudly decried and thoroughly discouraged – and the underlying native Windows Ke, Se, Io, Mm, Ex, Ps, Ob, and friends APIs.

What I am advocating is, specifically (this from my FIRST POST in this thread, qv):

1) We need to scrub the samples to make sure there are no WDM drivers around (other than software only “kernel services”). If you host example on GitHub or someplace else, if it’s a WDM driver , for heavens sakes make the readme say it’s a deprecated model.

2) We need the WDK docs to very clear say, everywhere, that people should be using WDM as a last resort only if they are not writing a file system or a kernel service. We should put this on every single WDM function doc page: IoXxxx, KeXxxx, etc.

3) We should warn people to NOT start a WDM sample unless they are writing a “kernel service” – We should direct them straight to WDF.

Peter
OSR
@OSRDrivers


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

Counter rant: WDF is kind of a cluster duck anyway. Gone are to good old days of using grep to find a function in a file. Grep WDF looking for a function; good luck. For example, grep for “WdfFdoInitSetFilter()” in the WDF source and you find yourself at a dead end; looking at a pointer to a member function. You could load the WDF source in the compiler, and search that way. But really? We’re talking about device drivers here. If you need C++ abstraction in your driver, maybe you need to rethink your design. All I wanted to do was see if WdfFdoInitSetFilter() propagated the device type field; I gave up, and just propagate it from the physical device because I have a job to do, and a deadline to meet. Maybe I am just getting too old…

C++ class hierarchy is exactly what WDM needed in order to provide a simple
api that provides default functionality that meets 90% or more of standard
wdm driver functionality. This the proliferation of many third party
wrappers around WDM that did just that.

And now this thread is going to go down this rathole.

Mark Roddy

On Wed, Mar 14, 2018 at 12:06 PM, xxxxx@gmail.com > wrote:

> Counter rant: WDF is kind of a cluster duck anyway. Gone are to good old
> days of using grep to find a function in a file. Grep WDF looking for a
> function; good luck. For example, grep for “WdfFdoInitSetFilter()” in the
> WDF source and you find yourself at a dead end; looking at a pointer to a
> member function. You could load the WDF source in the compiler, and search
> that way. But really? We’re talking about device drivers here. If you need
> C++ abstraction in your driver, maybe you need to rethink your design. All
> I wanted to do was see if WdfFdoInitSetFilter() propagated the device type
> field; I gave up, and just propagate it from the physical device because I
> have a job to do, and a deadline to meet. Maybe I am just getting too old…
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

The classes also provide abstraction between user and kernel mode, UMDF and KMDF are built from the same source.

d

From: xxxxx@lists.osr.com On Behalf Of xxxxx@gmail.com
Sent: Wednesday, March 14, 2018 10:10 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Help Stamp Out Sensless WDM Usage

C++ class hierarchy is exactly what WDM needed in order to provide a simple api that provides default functionality that meets 90% or more of standard wdm driver functionality. This the proliferation of many third party wrappers around WDM that did just that.

And now this thread is going to go down this rathole.

Mark Roddy

On Wed, Mar 14, 2018 at 12:06 PM, xxxxx@gmail.commailto:xxxxx > wrote:
Counter rant: WDF is kind of a cluster duck anyway. Gone are to good old days of using grep to find a function in a file. Grep WDF looking for a function; good luck. For example, grep for “WdfFdoInitSetFilter()” in the WDF source and you find yourself at a dead end; looking at a pointer to a member function. You could load the WDF source in the compiler, and search that way. But really? We’re talking about device drivers here. If you need C++ abstraction in your driver, maybe you need to rethink your design. All I wanted to do was see if WdfFdoInitSetFilter() propagated the device type field; I gave up, and just propagate it from the physical device because I have a job to do, and a deadline to meet. Maybe I am just getting too old…


NTDEV is sponsored by OSR

Visit the list online at: http:>

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:>

To unsubscribe, visit the List Server section of OSR Online at http:>

— NTDEV is sponsored by OSR Visit the list online at: MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers! Details at To unsubscribe, visit the List Server section of OSR Online at</http:></http:></http:></mailto:xxxxx>

REALLY? I found THIS in the very first .CPP file listed:

_drv_maxIRQL(PASSIVE_LEVEL)
VOID
WDFEXPORT(WdfFdoInitSetFilter)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
PWDFDEVICE_INIT DeviceInit
)
{
DDI_ENTRY();

PFX_DRIVER_GLOBALS pFxDriverGlobals;

FxPointerNotNull(GetFxDriverGlobals(DriverGlobals), DeviceInit);
pFxDriverGlobals = DeviceInit->DriverGlobals;

if (!NT_SUCCESS(FxVerifierCheckIrqlLevel(pFxDriverGlobals,
PASSIVE_LEVEL))) {
return;
}
if (DeviceInit->IsNotFdoInit()) {
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
“Not a PWDFDEVICE_INIT for an FDO”);

FxVerifierDbgBreakPoint(pFxDriverGlobals);
return;
}

DeviceInit->Fdo.Filter = TRUE;
}

I’ve heard this complaint about the WDF sources before. But, understand, what you’re complaining about is simply your own lack of familiarity with the source code.

You expect to be able to grep the I/O Manager source code and INSTANTLY be able to figure out… say… what a simple function like IoCallDriver does? Because I don’t think that’s a reasonable thing.

The source code to (anything) is super useful. But I don’t think it’s reasonable to expect to be able to dive-in and find an answer with little/no preliminary work.

Peter
OSR
@OSRDrivers