次の方法で共有


WdfDeviceInitAssignWdmIrpPreprocessCallback 関数 (wdfdevice.h)

[KMDF にのみ適用]

WdfDeviceInitAssignWdmIrpPreprocessCallback メソッドは、IRP の主要な関数コードを処理するコールバック関数を登録し、必要に応じて、メジャー関数コードに関連付けられている 1 つ以上のマイナー関数コードを登録します。

構文

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 の主要な関数コードの 1 つ。

[in, optional] MinorFunctions

指定したメジャー関数コードに関連付けられている 1 つ以上の IRP マイナー関数コードの配列へのポインター。 このパラメーターは省略可能であり、 NULL にすることができます。 詳細については、「解説」を参照してください。

[in] NumMinorFunctions

MinorFunctions 配列に含まれるマイナー関数コードの数。

戻り値

操作が成功した場合、メソッドは STATUS_SUCCESSを返します。 その他の戻り値は次のとおりです。

リターン コード 説明
STATUS_INVALID_PARAMETER
MajorFunction 値が無効です。
STATUS_INSUFFICIENT_RESOURCES
メモリが不足しています。
STATUS_INVALID_DEVICE_REQUEST
ドライバーは、以前にこのメジャー関数の MinorFunctions 配列を登録し、指定された MajorFunction コードに対してマイナー関数をもう一度指定しようとしています。
 

メソッドは、他の NTSTATUS 値を返す場合があります。

注釈

ドライバーは、次の 2 つの理由のいずれかで WdfDeviceInitAssignWdmIrpPreprocessCallback メソッドを呼び出すことができます。

  • フレームワークがサポートしていない IRP のメジャーまたはマイナー関数コードを処理します。

    たとえば、フレームワークは IRP_MJ_FLUSH_BUFFERSをサポートしていません。 ドライバーがこの IRP をサポートする必要がある場合は、IRP を処理する EvtDeviceWdmIrpPreprocess コールバック関数を登録する必要があります。 ドライバーは、IRP を処理するための WDM 規則に従う必要があります。

  • フレームワークが IRP を処理する前に IRP を前処理する。

    まれに、フレームワークが IRP を処理する前に、ドライバーが IRP を処理する必要がある場合があります。 このような場合、ドライバーの EvtDeviceWdmIrpPreprocess コールバック関数は、IRP を処理し、 WdfDeviceWdmDispatchPreprocessedIrp を呼び出して IRP をフレームワークに返すことができます。 IRP の関数コードによっては、フレームワークが IRP 自体を処理するか、フレームワーク要求オブジェクトでドライバーに IRP を再び配信する場合があります。

フレームワークは、MajorFunction パラメーターに一致する IRP メジャー関数コードと MinorFunctions 配列内のマイナー関数コードのいずれかに一致するマイナー関数コードを含む I/O 要求パケット (IRP) を受信するたびに、EvtDeviceWdmIrpPreprocess コールバック関数を呼び出します。

MinorFunctions 配列ポインターが NULL の場合、フレームワークは、指定されたメジャー関数コードに関連付けられているすべてのマイナー関数コードに対してコールバック関数を呼び出します。 MinorFunctions 配列ポインターが NULL でない場合、ドライバーがその配列を永続的に保持する必要がないように、フレームワークによって配列のコピーが作成されます。

ドライバーが WdfPdoInitAllocate または EvtChildListCreateDevice イベント コールバック関数から DeviceInit ポインターを受け取った場合、ドライバーの EvtDeviceWdmIrpPreprocess コールバック関数は、IRP_MJ_PNPの主要な関数コードを含む IRP の完了ルーチンを設定できません。 それ以外の場合、 ドライバー検証ツール はエラーを報告します。

ドライバーが WdfDeviceInitAssignWdmIrpPreprocessCallback を 1 回以上呼び出す場合、フレームワークはドライバーの WDM DEVICE_OBJECT構造体の StackSize メンバー 1 回インクリメントします。 その結果、I/O マネージャーは、EvtDeviceWdmIrpPreprocess コールバック関数が IoCompletion ルーチンを設定できるように、すべての IRP に追加の I/O スタックの場所を追加します。 この追加の I/O スタックの場所は、 WdfDeviceInitAssignWdmIrpPreprocessCallback の呼び出しで指定した IRP メジャー関数コードを含む IRP だけでなく、すべての IRP に追加されることに注意してください。 そのため、非ページ メモリ プールのドライバーの使用を不必要に増やさないようにするには、代替手段がない限り 、WdfDeviceInitAssignWdmIrpPreprocessCallback の使用を避ける必要があります。

ドライバーが同じメジャー コードに対して WdfDeviceInitAssignWdmIrpPreprocessCallback を 複数回呼び出す場合、フレームワークは、このメジャー コードに対して最後に設定された EvtDeviceWdmIrpPreprocess コールバック関数のみを保持します。 (ドライバーは、1 つの主要なコードに対して複数の前処理コールバックを登録できません)。

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

要件

要件
対象プラットフォーム ユニバーサル
最小 KMDF バージョン 1.0
Header wdfdevice.h (Wdf.h を含む)
Library Wdf01000.sys (「Framework ライブラリのバージョン管理」を参照)。
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