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を返します。 その他の戻り値は次のとおりです。
リターン コード | 形容 |
---|---|
|
MajorFunction 値が無効です。 |
|
メモリが不足しています。 |
|
ドライバーは以前、このメジャー関数の 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 を再び配信する場合があります。
配列ポインター MinorFunctions が NULL 場合、フレームワークは、指定されたメジャー関数コードに関連付けられているすべてのマイナー関数コードに対してコールバック関数を呼び出します。 MinorFunctions 配列ポインターが NULL されていない場合、ドライバーがその配列を永続的に保持する必要がないように、フレームワークによって配列のコピーが作成されます。
ドライバーが WdfPdoInitAllocate または EvtChildListCreateDevice イベント コールバック関数から DeviceInit ポインターを受け取った場合、ドライバーの EvtDeviceWdmIrpPreprocess コールバック関数は、IRP_MJ_PNPの主要な関数コードを含む IRP の完了ルーチンを設定できません。 それ以外の場合は、ドライバー検証ツール エラーが報告されます。
ドライバーが WdfDeviceInitAssignWdmIrpPreprocessCallback 1 回以上 呼び出す場合、フレームワークはドライバーの WDM DEVICE_OBJECT 構造体の StackSize メンバーを 1 回インクリメントします。 その結果、I/O マネージャーは、EvtDeviceWdmIrpPreprocess コールバック関数が ioCompletion ルーチン 設定できるように、I/O スタック位置 をすべての IRP に追加します。 この追加の I/O スタックの場所は、WdfDeviceInitAssignWdmIrpPreprocessCallback の呼び出しで指定した 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 |
ヘッダー | wdfdevice.h (Wdf.h を含む) |
ライブラリ | Wdf01000.sys (フレームワーク ライブラリのバージョン管理を参照)。 |
IRQL | <= DISPATCH_LEVEL |
DDI コンプライアンス規則 を する | ChildDeviceInitAPI(kmdf), ControlDeviceInitAPI(kmdf), DeviceInitAPI(kmdf), DriverCreate() kmdf), InitFreeDeviceCallback(kmdf), InitFreeDeviceCreate(kmdf), InitFreeNull(km)df), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), PdoDeviceInitAPI(kmdf), PdoInitFreeDeviceCallback(kmdf), PdoInitFreeDeviceCreate(kmdf) |