共用方式為


WdfDeviceInitAssignWdmIrpPreprocessCallback 函式 (wdfdevice.h)

[僅適用於 KMDF]

WdfDeviceInitAssignWdmIrpPreprocessCallback 方法會註冊回呼函式來處理 IRP 主要函式程式代碼,並選擇性地註冊一或多個與主要函式程式代碼相關聯的次要函式程序代碼。

語法

NTSTATUS WdfDeviceInitAssignWdmIrpPreprocessCallback(
  [in]           PWDFDEVICE_INIT                  DeviceInit,
  [in]           PFN_WDFDEVICE_WDM_IRP_PREPROCESS EvtDeviceWdmIrpPreprocess,
  [in]           UCHAR                            MajorFunction,
  [in, optional] PUCHAR                           MinorFunctions,
  [in]           ULONG                            NumMinorFunctions
);

參數

[in] DeviceInit

WDFDEVICE_INIT 結構的指標。

[in] EvtDeviceWdmIrpPreprocess

驅動程式 EvtDeviceWdmIrpPreprocess 回呼函式的指標。

[in] MajorFunction

wdm.h 中定義的其中一個 IRP 主要函式程式碼

[in, optional] MinorFunctions

與指定的主要函式程式代碼相關聯的一或多個 IRP 次要函式代碼數位數組指標。 這個參數是選擇性的,而且可以 NULL。 如需詳細資訊,請參閱下列一節。

[in] NumMinorFunctions

MinorFunctions 陣列中包含的次要函式代碼數目。

傳回值

如果作業成功,方法會傳回STATUS_SUCCESS。 其他傳回值包括:

傳回碼 描述
STATUS_INVALID_PARAMETER
MajorFunction 值無效。
STATUS_INSUFFICIENT_RESOURCES
記憶體不足。
STATUS_INVALID_DEVICE_REQUEST
驅動程式先前註冊了這個主要函式的 MinorFunctions 陣列,並嘗試再次為 指定的 MajorFunction 程式代碼指定次要函式。
 

方法可能會 傳回其他NTSTATUS 值。

言論

驅動程式可以呼叫 WdfDeviceInitAssignWdmIrpPreprocessCallback 方法,原因有兩種:

  • 處理架構不支援的 IRP 主要或次要函式程式代碼。

    例如,架構不支援 IRP_MJ_FLUSH_BUFFERS。 如果您的驅動程式必須支援此 IRP,則必須註冊處理 IRP 的 EvtDeviceWdmIrpPreprocess 回呼函式。 驅動程式必須遵循 WDM 規則來處理 IRP。

  • 在架構處理 IRP 之前先處理 IRP。

    在罕見的情況下,驅動程式可能需要先處理 IRP,再處理架構。 在這種情況下,驅動程式的 EvtDeviceWdmIrpPreprocess 回呼函式可以處理 IRP,然後呼叫 WdfDeviceWdmDispatchPreprocessedIrp 將 IRP 傳回架構。 根據 IRP 的函式程式代碼,架構可能會處理 IRP 本身,或在架構要求物件中再次將 IRP 傳遞至驅動程式。

架構會呼叫 EvtDeviceWdmIrpPreprocess 回呼函式,每當它收到 I/O 要求封包 (IRP),其中包含符合 MajorFunction 參數的 IRP 主要函式程式代碼,以及符合 MinorFunctions 數位中其中一個次要函式程式代碼的次要函式程式代碼。

如果 MinorFunctions 陣列指標 NULL,則架構會針對與指定的主要函式程式代碼相關聯的所有次要函式程式代碼呼叫回呼函式。 如果 MinorFunctions 陣列指標未 NULL,則架構會建立數位的複本,讓驅動程式不必永久保留其陣列。

如果驅動程式從 WdfPdoInitAllocateEvtChildListCreateDevice 事件回呼函式收到 DeviceInit 指標,則驅動程式的 EvtDeviceWdmIrpPreprocess 回呼函式無法設定包含IRP_MJ_PNP主要函式程式代碼的 IRP 完成例程。 否則,驅動程式驗證器 會回報錯誤。

如果您的驅動程式呼叫 WdfDeviceInitAssignWdmIrpPreprocessCallback 一次或多次,架構就會遞增驅動程式 WDM DEVICE_OBJECT 結構 成員 StackSize。 因此,I/O 管理員會將額外的 I/O 堆棧位置 新增至所有 IRP,讓 EvtDeviceWdmIrpPreprocess 回呼函式可以設定 IoCompletion 例程。 請注意,這個額外的 I/O 堆疊位置會新增至所有 IRP,而不只是包含您在呼叫 WdfDeviceInitAssignWdmIrpPreprocessCallback 中所指定的 IRP 主要函式程式代碼。 因此,為了避免不必要地增加驅動程式使用非分頁記憶體集區,您應該避免使用 WdfDeviceInitAssignWdmIrpPreprocessCallback,除非沒有替代方案。

如果您的驅動程式針對相同的主要程式代碼多次呼叫 WdfDeviceInitAssignWdmIrpPreprocessCallbackCallback 多次,架構只會保留這個主要程序代碼的最新設定 EvtDeviceWdmIrpPreprocess 回呼函式。 (您的驅動程式無法為單一主要程式碼註冊多個前置處理回呼。

如需 WdfDeviceInitAssignWdmIrpPreprocessCallback 方法的詳細資訊,請參閱 處理 Framework 外部的 WDM IRP

例子

下列程式代碼範例會定義 EvtDeviceWdmIrpPreprocess 事件回呼函式,然後註冊回呼函式來處理 IRP_MJ_QUERY_INFORMATION IRP。

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

要求

要求 價值
目標平臺 普遍
最低 KMDF 版本 1.0
標頭 wdfdevice.h (包括 Wdf.h)
連結庫 Wdf01000.sys (請參閱架構連結庫版本控制。)
IRQL <= DISPATCH_LEVEL
DDI 合規性規則 ChildDeviceInitAPI(kmdf)ControlDeviceInitAPI(kmdf)DeviceInitAPI(kmdf)DriverCreate (kmdf)InitFreedeviceCallback(kmdf)InitFreedeviceCreate(kmdf)InitFreenull(kmdf) kmdf)KmdfIrql(kmdf)KmdfIrql2(kmdf),KmdfIrqlExplicit(kmdf),PdoDeviceInitAPI(kmdf)PdoInitFreeDeviceCallback(kmdf)PdoInitFreeDeviceCreate(kmdf)

另請參閱

WdfDeviceWdmDispatchPreprocessedIrp