Developing Drivers with the Windows Driver Foundation (Pro Developer)

File Handle I/O Targets in UMDF Drivers

A UMDF driver communicates with some devices by using a Windows file handle, as in the following examples:

The driver obtains the file handle by calling a Windows function such as socket, CreateFile, or CreateNamedPipe that returns a file handle.

A driver can bind this handle to a framework I/O target by using the FileHandle I/O target. The driver can then use the framework's I/O target interface to send I/O requests to the file handle, thereby getting all the benefits of I/O targets.

The IWDFFileHandleTargetFactory interface creates an I/O target that is associated with a file handle. A driver gets a pointer to this interface by querying the framework device object. The driver can then call the CreateFileHandleTarget method and pass the file handle to create the I/O target object in the framework.

The framework device object is the parent of the I/O target object, so the lifetime of the I/O target object is by default the same as that of the device object. If the driver finishes using an I/O target object while the device object remains active, the driver can delete the I/O target object by calling IWDFObject::DeleteWdfObject.

Listing 9-16 shows how a UMDF driver creates a FileHandle I/O target that represents a named pipe.

Listing 9-16: Creating a file handle I/O target in a UMDF driver

HANDLE m_WriteHandle; // Device Handle IWDFIoTarget * m_WriteTarget; // I/O target HRESULT hr = S_OK; IWDFFileHandleTargetFactory * pFileHandleTargetFactory = NULL; // Create a pipe and get the handle. m_WriteHandle = CreateNamedPipe(NP_NAME, . . . //Additional parameters omitted for brevity); if (SUCCEEDED(hr)) { hr = m_FxDevice->QueryInterface(IID_PPV_ARGS(&pFileHandleTargetFactory)); if (SUCCEEDED(hr)) { hr = pFileHandleTargetFactory->CreateFileHandleTarget (m_WriteHandle, &m_WriteTarget); } } . . . //Additional code omitted SAFE_RELEASE(pFileHandleTargetFactory);

In the listing, the driver calls the Windows CreateNamedPipe function to open a handle to a named pipe. If this function succeeds, the driver queries the framework's device object for a pointer to the IWDFFileHandleTargetFactory interface. It then calls the CreateFileHandleTarget method, which creates a framework I/O target object that corresponds to the file handle and returns a pointer to the I/O target object's IWDFIoTarget interface. When the driver has finished using the IWDFFileHandleTargetFactory interface, it releases its reference on the interface.

After creating the I/O target, the driver can call methods on the IWDFIoTarget and IWDFIoTargetStateManagement interfaces to format I/O requests for the target device, get information about the target, and manage the state of the target.

Why Should I Use a File Handle I/O Target Instead of the Windows API?

You should use a file handle I/O target if your driver can create a Windows file handle for the target and your UMDF driver is not loaded as part of the device stack for the target devnode. For example, if your driver uses a socket, you should use a file handle I/O target. However, if your driver loads as part of the device stack for the target devnode, you should just use the default I/O target.

Although you can use the Windows API directly, you should consider using a file handle I/O target for the following reasons:

For the same reasons, you should use an I/O target to communicate with the kernel-mode portion of your device stack.-Praveen Rao, Windows Driver Foundation Team, Microsoft

Категории