WDF and audio drivers

Hi everyone,

We need to write a driver for a hardware audio interface for Windows 10. From all the documentation we gathered, we understand that it must be written using WDM and not WDF due to the Port/Miniport mechanism. However, our hardware uses a Xilinx FPGA with XDMA, and the library they provide is written using WDF.

We have started to look into rewriting the library with WDM so that we can use it in our driver, but the more we dive into it, the harder it gets.

In light of this, I have several questions :

  • Did we understand the documentation correctly about audio drivers ? Is it actually mandatory to use WDM ?
  • If yes, is there any trick to use the WDF library in WDM code ?
  • If there’s no such trick, is there any documentation about converting WDF code to WDM ?

Thanks !

Yes, it’s mandatory to use WDM … the audio driver talks to a port class driver which sits at a layer below WDF (think of it like a layer cake), so you too must talk WDM … that said,

There are a limited (very limited) set of WDF functions that you can use in the audio driver, look at the documentation for WdfDeviceMiniportCreate() … basically just enough for you to establish a WdfIoTarget with something. You can also intercept PnP messages on the IRP stack (you need to complete them by yourself) so you can process MJ_DEVICE_CONTROL and MJ_INTERNAL_DEVICE_CONTROL IRP’s but since you’re at WDM you’ll be doing it … yourself

WDF lives at a layer above WDM so simply porting is not really going to be very easy; you’re going to be essentially trying to replicate a WDF framework which is what an entire building of MS engineers did over the course of several years … I would look into seeing if you can access the FPGA driver’s interfaces from the Audio driver and treating them as two different drivers

A good starting point for an audio driver is the “SampleAudioApplication” that was just included as part of the WDK samples; see if you can get that working first, then see if you can get that to establish a WdfIoTarget relationship with the FPGA driver and go from there. Note that the sample audio driver is very minimal so you will need to create your own ring buffer(s) and system thread(s) for actual data movement …

Which WDF objects is the library using ? Is it mostly focused on DMA? If so, you can use WDF DMA objects with a mini port WDFDEVICE.

Craig is wrong. It is absolutely not necessary to use WDM. The Sysvad sample from Microsoft itself is a KMDF driver, for gosh sakes.

However, you must use KMDF in miniport mode, so that it does not attempt to do any dispatching. Given that, it’s not entirely clear what KMDF brings to the party, but it is certainly possible.

Thanks for your answers !

There are a limited (very limited) set of WDF functions that you can use in the audio driver, look at the documentation for WdfDeviceMiniportCreate() … basically just enough for you to establish a WdfIoTarget with something. You can also intercept PnP messages on the IRP stack (you need to complete them by yourself) so you can process MJ_DEVICE_CONTROL and MJ_INTERNAL_DEVICE_CONTROL IRP’s but since you’re at WDM you’ll be doing it … yourself

That’s very interesting, it’s a whole part of the docs that we missed. It led me to https://docs.microsoft.com/en-us/windows-hardware/drivers/wdf/accessing-wdm-interfaces-in-kmdf-drivers which seem to have what we need, what do you think ? Are the WDM objects you get with these functions usable outside of WDF code ?

WDF lives at a layer above WDM so simply porting is not really going to be very easy; you’re going to be essentially trying to replicate a WDF framework which is what an entire building of MS engineers did over the course of several years

That’s why we would like to avoid it if possible ! :smile:

I would look into seeing if you can access the FPGA driver’s interfaces from the Audio driver and treating them as two different drivers

The problem with that is that we need low latency, and we fear that communicating between the audio driver and the FPGA driver might introduce some.

Which WDF objects is the library using ? Is it mostly focused on DMA? If so, you can use WDF DMA objects with a mini port WDFDEVICE.

It is mostly focused on DMA. Here is the list of WDF functions used in it :

WdfCmResourceListGetCount(
WdfCmResourceListGetDescriptor(
WdfCommonBufferCreate(
WdfCommonBufferGetAlignedLogicalAddress(
WdfCommonBufferGetAlignedVirtualAddress(
WdfCommonBufferGetLength(
WdfDeviceCreate(
WdfDeviceCreateDeviceInterface(
WdfDeviceInitSetFileObjectConfig(
WdfDeviceInitSetIoType(
WdfDeviceInitSetPnpPowerEventCallbacks(
WdfDeviceInitSetPowerPolicyEventCallbacks(
WdfDeviceSetAlignmentRequirement(
WdfDmaEnablerCreate(
WdfDmaTransactionCreate(
WdfDmaTransactionDmaCompleted(
WdfDmaTransactionExecute(
WdfDmaTransactionGetBytesTransferred(
WdfDmaTransactionGetRequest(
WdfDmaTransactionInitializeUsingRequest(
WdfDmaTransactionRelease(
WdfDriverCreate(
WdfDriverOpenParametersRegistryKey(
WdfFdoQueryForInterface(
WdfFileObjectGetDevice(
WdfFileObjectGetFileName(
WdfGetDriver(
WdfInterruptAcquireLock(
WdfInterruptCreate(
WdfInterruptQueueDpcForIsr(
WdfInterruptReleaseLock(
WdfIoQueueCreate(
WdfMemoryCopyFromBuffer(
WdfMemoryCopyToBuffer(
WdfMemoryGetBuffer(
WdfRegistryClose(
WdfRegistryQueryULong(
WdfRequestComplete(
WdfRequestCompleteWithInformation(
WdfRequestForwardToIoQueue(
WdfRequestGetFileObject(
WdfRequestGetIoQueue(
WdfRequestGetParameters(
WdfRequestMarkCancelableEx(
WdfRequestRetrieveInputBuffer(
WdfRequestRetrieveInputMemory(
WdfRequestRetrieveOutputBuffer(
WdfRequestRetrieveOutputMemory(
WdfRequestUnmarkCancelable(
WdfResourceCmGetDescriptor(
WdfSpinLockAcquire(
WdfSpinLockCreate(
WdfSpinLockRelease(

The problem is that all the interrupts part is not usable in a WDF Miniport if I understand correctly.

Craig is wrong. It is absolutely not necessary to use WDM. The Sysvad sample from Microsoft itself is a KMDF driver, for gosh sakes.

We did notice the SysVAD example, but we understand from this documentation : https://docs.microsoft.com/fr-fr/windows-hardware/drivers/gettingstarted/choosing-a-driver-model#choosing-a-driver-model-for-a-software-driver that it’s written in KMDF because it’s purely software. All the other documentation on audio drivers talks about WDM. According to what you are saying, it should still be possible then ?

@Tim_Roberts said:
Craig is wrong. It is absolutely not necessary to use WDM. The Sysvad sample from Microsoft itself is a KMDF driver, for gosh sakes.

However, you must use KMDF in miniport mode, so that it does not attempt to do any dispatching. Given that, it’s not entirely clear what KMDF brings to the party, but it is certainly possible.

Hmm … good to know, thanks, KMDF in “miniport” mode! When I had worked with SysVAD in the past there were always problems accessing some of the traditional KMDF functions like interface change notifications, PnP dispatching (I had to use DRIVER_DISPATCH) rather than simply using WdfDeviceInitSetFileObjectConfig and similar, it didn’t let me create WdfIoQueue’s or WdfCreateDeviceInterface or WdfDeviceSetPnPCapabilities or even WdfDeviceSetDeviceState. WMI static and dynamic registrations wouldn’t work, and even the WdfPreprocessIrp function wouldn’t work …

It’s true that both SysVAD and a KMDF driver started with WdfDriverCreate, but right there in a comment block in SysVAD above that function it states that we need to set the WdfDriverInitNoDispatchOverride flag to tell the framework to specifically NOT provide dispatch routines for the driver (which I had always seen as being a core feature of a KMDF driver) … implying that you’re on your own to set up the handlers in DispatchDriver … one of the hallmarks I had always seen of KMDF (and UMDF) was that it handled all of the cruft involved in IRP collection, completion, cancellation and dispatching, you just needed to provide a callback function and you’re gold versus simply being given a raw IRP through DRIVER_DISPATCH and a hearty pat on the back as you’re pushed back into the weeds …

KMDF in miniport mode, with so many things off the table or not working, to me says just use WDM and forget all about KMDF (in any flavor) … otherwise, you’re spending time hunting bugs that you don’t know if they are bad business logic or simply something that miniport KMDF doesn’t handle and it’s on you to implement (hence my statement to the OP that you have a very limited set of KMDF functions available).

Looking at the list of Wdf functions the OP provided, easily 80% of them I wasn’t able to get to work in “KMDF” SysVAD, helpful functions like WdfRequestXX (I needed to crack the IRP’s myself) and WdfSpinLockCreate (needed to use KSPIN_LOCK) which were all easily doable using WDM …

Hmm … SysVAD is a “KMDF” driver, you say … OK, again good toknow, I’ve got some research to do! :slight_smile: