So I thought I'd give you all an end to end sample of how to forward requests to a lower driver w/ UMDF, or at least how I have it set up for the 1394 virtual device driver sample. Your usage may vary and so may your mileage.
First off, UMDF uses file handles for associations, so we need to create one. What I'm doing is storing the IWDFDriverCreatedFile object in my device class;
class VdevDevice :
// This is our file object to the KMDF File
// we'll need this to create and submit IOCTLs down to the kmdf stub
// the life of the object will follow the life of the driver.
IWDFDriverCreatedFile * m_KmdfTargetFile;
// We'll need these later
return static_cast <IPnpCallbackHardware *> (this);
(HRESULT, OnReleaseHardware) (
__in IWDFDevice * wdfDevice);
I'll also carry a copy of that file handle in my callback queue class;
class VdevSequentialQueue :
// ...some other members and such...
IWDFDevice * m_BaseDevObj;
IWDFFile * m_FileHandle;
Next during our device configuration, I'll create the file object;
// ...some other stuff...
m_FxDevice->CreateWdfFile (L"KMDF_VDEV_DRIVER\n", &m_KmdfTargetFile);
//...initialize the callback queues and some other things here...
m_SequentialQueue->m_FileHandle = m_KmdfTargetFile;
m_SequentialQueue->m_BaseDevObj = m_FxDevice;
// ...and yet more stuff...
You'll notice I'm also carrying a loose reference the device object above, you'll see why in this next block;
__in IWDFIoQueue *FxQueue,
__in IWDFIoRequest *wdfRequest,
__in ULONG ControlCode,
__in SIZE_T InputBufferSizeInBytes,
__in SIZE_T OutputBufferSizeInBytes)
IWDFIoTarget * kmdfIoTarget = NULL;
IWDFIoRequest * kmdfIoRequest = NULL;
// ....code, code, code...
hr = m_BaseDevObj->CreateRequest (
NULL, // we'll deal with completion later
NULL, // defaults the object to self
if (FAILED (hr))
hr = kmdfIoTarget->FormatRequestForIoctl (
if (FAILED (hr))
hr = kmdfIoRequest->Send (
There are built in methods for getting the values of m_BaseDevObj and m_FileHandle, but I found for my usage in this particular case, it's best to just keep a loose reference to those objects in my queue class(es). As you probably have gathered, this request is being sent on a sequential queue and we're not doing anything with completion callbacks. I'm working on adding asynchronous support in the KMDF driver, because if you have the WDK, you'll notice all the requests sent from the current virtual device driver are done so synchronously. Yes, even the async requests. 😉
Now for the clean up, we'll need to release file handle in a clean up routine and it's best to do it during the OnReleaseHardware or OnSelfManagedIoCleanup to protect against a possible condition where a lower filter driver would have the IoTarget in a delete state;
__in IWDFDevice * wdfDevice)
// Close the handle to the file object we've been using for
// our requests to the KMDF stub