Creating and Using Driver-Created File Objects

Warning

UMDF 2 is the latest version of UMDF and supersedes UMDF 1. All new UMDF drivers should be written using UMDF 2. No new features are being added to UMDF 1 and there is limited support for UMDF 1 on newer versions of Windows 10. Universal Windows drivers must use UMDF 2.

The archived UMDF 1 samples can be found in the Windows 11, version 22H2 - May 2022 Driver Samples Update.

For more info, see Getting Started with UMDF.

If your driver needs to create and send an I/O request that is independent of the application to the next driver in the stack (the default I/O target), the driver must create and close its own file objects.

Creating a File Object

Your driver must call the IWDFDevice::CreateWdfFile method to create a file object for the driver's use. When the driver calls IWDFDevice::CreateWdfFile, the framework sends a create request to the next driver in the stack. The next driver in the stack could be in kernel mode or in user mode.

This create-file request processing is different in the Windows Driver Model (WDM). In WDM, a call to the ZwCreateFile function causes a create IRP to go to the top of the kernel-mode stack. The following figure shows create-file request processing in UMDF versus WDM:

create-file request handling in umdf versus wdm.

By calling IWDFDevice::CreateWdfFile, the driver can create a file object and then send I/O requests during device start, before the whole stack has started.

The next driver in the stack must determine if it can handle the create-file request or if it must forward the request further down the stack.

After calling IWDFDevice::CreateWdfFile, a driver cannot cancel the create operation.

Using the File Object

To send an asynchronous read request to the next driver stacked below it, your driver can use the following pattern.

  1. Call IWDFDevice::CreateWdfFile to create the file object.
  2. Call IWDFDevice::GetDefaultIoTarget to retrieve the interface representing the lower level driver.
  3. Call IWDFDevice::CreateRequest to create an unformatted IWDFIoRequest object.
  4. Call IWDFIoRequest::SetCompletionCallback to register a IRequestCallbackRequestCompletion interface for the OnCompletion method that the framework calls when an I/O request completes.
  5. Call IWDFIoTarget::FormatRequestForRead, providing a pointer to the IWDFDriverCreatedFile interface in the pFile parameter.
  6. Call IWDFIoRequest::Send to send the request.

Closing the File Object

The driver that called IWDFDevice::CreateWdfFile must later call IWDFDriverCreatedFile::Close.

Typically, your driver calls IWDFDriverCreatedFile::Close either from its IPnpCallbackHardware::OnReleaseHardware or IPnpCallbackSelfManagedIo::OnSelfManagedIoCleanup callback method.

When the driver calls IWDFDriverCreatedFile::Close, the framework calls the next driver's IFileCallbackCleanup::OnCleanupFile method. In this method, the next driver must cancel or complete all pending I/O requests that are associated with the file object. The framework then cancels any I/O requests created by the driver that called IWDFDevice::CreateWdfFile. The framework does not cancel any I/O requests that lower drivers in the stack may have associated with the file object. It is the driver's responsibility to cancel any such requests. The file object only closes after all I/O requests associated with it have completed.

Next, the framework calls the next driver's IFileCallbackClose::OnCloseFile method. At this point, the framework guarantees that the next driver will not receive additional I/O requests for this file object.

After the framework calls OnCloseFile, it destroys the IWDFFile interface that represents the file object.

If driver-created file objects remain after the driver's device-removal methods (for example IPnpCallbackHardware::OnReleaseHardware and IPnpCallbackSelfManagedIo::OnSelfManagedIoCleanup) return, the framework generates a driver stop. For information about troubleshooting this problem, see Determining Why UMDF Indicates Outstanding Files at Device Removal Time.