WdfDeviceInitAssignWdmIrpPreprocessCallback function (wdfdevice.h)
[Applies to KMDF only]
The WdfDeviceInitAssignWdmIrpPreprocessCallback method registers a callback function to handle an IRP major function code and, optionally, one or more minor function codes that are associated with the major function code.
Syntax
NTSTATUS WdfDeviceInitAssignWdmIrpPreprocessCallback(
[in] PWDFDEVICE_INIT DeviceInit,
[in] PFN_WDFDEVICE_WDM_IRP_PREPROCESS EvtDeviceWdmIrpPreprocess,
[in] UCHAR MajorFunction,
[in, optional] PUCHAR MinorFunctions,
[in] ULONG NumMinorFunctions
);
Parameters
[in] DeviceInit
A pointer to a WDFDEVICE_INIT structure.
[in] EvtDeviceWdmIrpPreprocess
A pointer to the driver's EvtDeviceWdmIrpPreprocess callback function.
[in] MajorFunction
One of the IRP major function codes that are defined in wdm.h.
[in, optional] MinorFunctions
A pointer to an array of one or more IRP minor function codes that are associated with the specified major function code. This parameter is optional and can be NULL. For more information, see the following Remarks section.
[in] NumMinorFunctions
The number of minor function codes that are contained in the MinorFunctions array.
Return value
If the operation succeeds, the method returns STATUS_SUCCESS. Additional return values include:
Return code | Description |
---|---|
|
The MajorFunction value is invalid. |
|
There is insufficient memory. |
|
The driver previously registered a MinorFunctions array for this major function and is attempting to specify minor functions again for the specified MajorFunction code. |
The method might return other NTSTATUS values.
Remarks
Drivers can call the WdfDeviceInitAssignWdmIrpPreprocessCallback method for either of two reasons:
-
To handle an IRP major or minor function code that the framework does not support.
For example, the framework does not support IRP_MJ_FLUSH_BUFFERS. If your driver must support this IRP, it must register an EvtDeviceWdmIrpPreprocess callback function that handles the IRP. The driver must follow WDM rules for processing IRPs.
-
To preprocess an IRP before the framework handles it.
In rare cases, it might be necessary for a driver to process an IRP before the framework processes it. In such cases, the driver's EvtDeviceWdmIrpPreprocess callback function can process the IRP and then call WdfDeviceWdmDispatchPreprocessedIrp to return the IRP to the framework. Depending on the IRP's function code, the framework might process the IRP itself or it might deliver the IRP to the driver again in a framework request object.
If the MinorFunctions array pointer is NULL, the framework calls the callback function for all minor function codes that are associated with the specified major function code. If the MinorFunctions array pointer is not NULL, the framework makes a copy of the array so that the driver does not have to permanently keep its array.
If the driver received DeviceInit pointer from WdfPdoInitAllocate or an EvtChildListCreateDevice event callback function, the driver's EvtDeviceWdmIrpPreprocess callback function cannot set a completion routine for IRPs that contain a major function code of IRP_MJ_PNP. Otherwise, Driver Verifier will report an error.
If your driver calls WdfDeviceInitAssignWdmIrpPreprocessCallback one or more times, the framework increments the StackSize member of the driver's WDM DEVICE_OBJECT structure one time. As a result, the I/O manager adds an additional I/O stack location to all IRPs so that the EvtDeviceWdmIrpPreprocess callback function can set an IoCompletion routine. Note that this extra I/O stack location is added to all IRPs, not just the ones that contain an IRP major function code that you specify in a call to WdfDeviceInitAssignWdmIrpPreprocessCallback. Therefore, to avoid unnecessarily increasing your driver's use of the nonpaged memory pool, you should avoid using WdfDeviceInitAssignWdmIrpPreprocessCallback unless there is no alternative.
If your driver calls WdfDeviceInitAssignWdmIrpPreprocessCallback more than once for the same major code, the framework retains only the most recently set EvtDeviceWdmIrpPreprocess callback function for this major code. (Your driver can’t register multiple preprocess callbacks for a single major code.)
For more information about the WdfDeviceInitAssignWdmIrpPreprocessCallback method, see Handling WDM IRPs Outside of the Framework.
Examples
The following code example defines an EvtDeviceWdmIrpPreprocess event callback function, and then registers the callback function to handle IRP_MJ_QUERY_INFORMATION IRPs.
NTSTATUS
SerialQueryInformationFile(
IN WDFDEVICE Device,
IN PIRP Irp
)
/*++
Routine Description:
This routine is used to query the end of file information on
the opened serial port. Any other file information request
is returned with an invalid parameter.
This routine always returns an end of file of 0.
Arguments:
DeviceObject - Pointer to the device object for this device
Irp - Pointer to the IRP for the current request
Return Value:
The function value is the final status of the call
--*/
{
NTSTATUS Status;
PIO_STACK_LOCATION IrpSp;
SerialDbgPrintEx(TRACE_LEVEL_INFORMATION, DBG_PNP, ">SerialQueryInformationFile(%p, %p)\n", Device, Irp);
PAGED_CODE();
IrpSp = IoGetCurrentIrpStackLocation(Irp);
Irp->IoStatus.Information = 0L;
Status = STATUS_SUCCESS;
if (IrpSp->Parameters.QueryFile.FileInformationClass ==
FileStandardInformation) {
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(FILE_STANDARD_INFORMATION))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
PFILE_STANDARD_INFORMATION Buf = Irp->AssociatedIrp.SystemBuffer;
Buf->AllocationSize.QuadPart = 0;
Buf->EndOfFile = Buf->AllocationSize;
Buf->NumberOfLinks = 0;
Buf->DeletePending = FALSE;
Buf->Directory = FALSE;
Irp->IoStatus.Information = sizeof(FILE_STANDARD_INFORMATION);
}
} else if (IrpSp->Parameters.QueryFile.FileInformationClass ==
FilePositionInformation) {
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(FILE_POSITION_INFORMATION))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
((PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer)->
CurrentByteOffset.QuadPart = 0;
Irp->IoStatus.Information = sizeof(FILE_POSITION_INFORMATION);
}
} else {
Status = STATUS_INVALID_PARAMETER;
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS
SerialEvtDeviceAdd(
IN WDFDRIVER Driver,
IN PWDFDEVICE_INIT DeviceInit
)
{
...
status = WdfDeviceInitAssignWdmIrpPreprocessCallback(
DeviceInit,
SerialQueryInformationFile,
IRP_MJ_QUERY_INFORMATION,
NULL, // Pointer to the minor function table
0 // Number of entries in the table
);
if (!NT_SUCCESS(status)) {
return status;
}
...
}
Requirements
Requirement | Value |
---|---|
Target Platform | Universal |
Minimum KMDF version | 1.0 |
Header | wdfdevice.h (include Wdf.h) |
Library | Wdf01000.sys (see Framework Library Versioning.) |
IRQL | <= DISPATCH_LEVEL |
DDI compliance rules | ChildDeviceInitAPI(kmdf), ControlDeviceInitAPI(kmdf), DeviceInitAPI(kmdf), DriverCreate(kmdf), InitFreeDeviceCallback(kmdf), InitFreeDeviceCreate(kmdf), InitFreeNull(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), PdoDeviceInitAPI(kmdf), PdoInitFreeDeviceCallback(kmdf), PdoInitFreeDeviceCreate(kmdf) |