共用方式為


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。 其他傳回值包括:

傳回碼 Description
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 之前處理 IRP。 在這種情況下,驅動程式的 EvtDeviceWdmIrpPreprocess 回呼函式可以處理 IRP,然後呼叫 WdfDeviceWdmDispatchPreprocessedIrp 將 IRP 傳回架構。 根據 IRP 的函式程式代碼,架構可能會處理 IRP 本身,或者它可能會在架構要求物件中再次將 IRP 傳遞給驅動程式。

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

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

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

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

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

如需 WdfDeviceInitAssignWdmIrpPreprocessCallback 方法的詳細資訊,請參閱 處理架構外部的 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;
    }
...
}

規格需求

需求
目標平台 Universal
最小 KMDF 版本 1.0
標頭 wdfdevice.h (包含 Wdf.h)
程式庫 Wdf01000.sys (請參閱 Framework Library Versioning.)
IRQL <= DISPATCH_LEVEL
DDI 合規性規則 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)

另請參閱

WdfDeviceWdmDispatchPreprocessedIrp