WdfDeviceInitAssignWdmIrpPreprocessCallback - NtDoc

Native API online documentation, based on the System Informer (formerly Process Hacker) phnt headers
// wdfdevice.h

NTSTATUS WdfDeviceInitAssignWdmIrpPreprocessCallback(
  [in]           PWDFDEVICE_INIT                  DeviceInit,
  [in]           PFN_WDFDEVICE_WDM_IRP_PREPROCESS EvtDeviceWdmIrpPreprocess,
  [in]           UCHAR                            MajorFunction,
  [in, optional] PUCHAR                           MinorFunctions,
  [in]           ULONG                            NumMinorFunctions
);
View the official Windows Driver Kit DDI reference

NtDoc

No description available.

Windows Driver Kit DDI reference (nf-wdfdevice-wdfdeviceinitassignwdmirppreprocesscallback)

WdfDeviceInitAssignWdmIrpPreprocessCallback function

Description

[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.

Parameters

DeviceInit [in]

A pointer to a WDFDEVICE_INIT structure.

EvtDeviceWdmIrpPreprocess [in]

A pointer to the driver's EvtDeviceWdmIrpPreprocess callback function.

MajorFunction [in]

One of the IRP major function codes that are defined in wdm.h.

MinorFunctions [in, optional]

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.

NumMinorFunctions [in]

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
STATUS_INVALID_PARAMETER The MajorFunction value is invalid.
STATUS_INSUFFICIENT_RESOURCES There is insufficient memory.
STATUS_INVALID_DEVICE_REQUEST 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:

The framework calls the EvtDeviceWdmIrpPreprocess callback function whenever it receives an I/O request packet (IRP) that contains an IRP major function code that matches the MajorFunction parameter and a minor function code that matches one of the minor function codes that are in the MinorFunctions array.

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;
    }
...
}

See also

WdfDeviceWdmDispatchPreprocessedIrp