WdfIoTargetFormatRequestForIoctl 関数 (wdfiotarget.h)
[KMDF と UMDF に適用]
WdfIoTargetFormatRequestForIoctl メソッドは、I/O ターゲットのデバイス 制御要求をビルドしますが、要求は送信しません。
構文
NTSTATUS WdfIoTargetFormatRequestForIoctl(
[in] WDFIOTARGET IoTarget,
[in] WDFREQUEST Request,
[in] ULONG IoctlCode,
[in, optional] WDFMEMORY InputBuffer,
[in, optional] PWDFMEMORY_OFFSET InputBufferOffset,
[in, optional] WDFMEMORY OutputBuffer,
[in, optional] PWDFMEMORY_OFFSET OutputBufferOffset
);
パラメーター
[in] IoTarget
WdfDeviceGetIoTarget または WdfIoTargetCreate の以前の呼び出し、または特殊化された I/O ターゲットが提供するメソッドから取得されたローカルまたはリモートの I/O ターゲット オブジェクトへのハンドル。
[in] Request
フレームワーク要求オブジェクトへのハンドル。 詳細については、「解説」を参照してください。
[in] IoctlCode
I/O ターゲットがサポートする I/O 制御コード (IOCTL)。
[in, optional] InputBuffer
フレームワーク メモリ オブジェクトへのハンドル。 このオブジェクトは、I/O ターゲットに送信されるデータを含むバッファーを表します。 詳細については、「解説」を参照してください。
[in, optional] InputBufferOffset
省略可能なバイト オフセットと長さの値を提供する呼び出し元によって割り当てられた WDFMEMORY_OFFSET 構造体へのポインター。 フレームワークでは、これらの値を使用して、入力バッファー内のデータ転送の開始アドレスと長さを決定します。 このポインターが NULL の場合、データ転送は入力バッファーの先頭から開始され、転送サイズはバッファー サイズです。
[in, optional] OutputBuffer
フレームワーク メモリ オブジェクトへのハンドル。 このオブジェクトは、I/O ターゲットからデータを受信するバッファーを表します。 詳細については、「解説」を参照してください。
[in, optional] OutputBufferOffset
省略可能なバイト オフセットと長さの値を提供する呼び出し元によって割り当てられた WDFMEMORY_OFFSET 構造体へのポインター。 フレームワークでは、これらの値を使用して、出力バッファー内のデータ転送の開始アドレスと長さを決定します。 このポインターが NULL の場合、データ転送は出力バッファーの先頭から開始され、転送サイズはバッファー サイズです。
戻り値
操作が成功した場合、WdfIoTargetFormatRequestForIoctl はSTATUS_SUCCESSを返します。 それ以外の場合、このメソッドは次のいずれかの値を返す可能性があります。
リターン コード | 説明 |
---|---|
|
無効なパラメーターが検出されました。 |
|
転送長がバッファー長を超えているか、I/O 要求が既に I/O ターゲットにキューに入れられました。 |
|
フレームワークはシステム リソース (通常はメモリ) を割り当てませんでした。 |
|
要求パラメーターが表す I/O 要求パケット (IRP) は、ドライバーが 要求 を転送できるようにするため の十 分なIO_STACK_LOCATION構造を提供しません。 |
このメソッドは、他の NTSTATUS 値を返す場合もあります。
ドライバーが無効なオブジェクト ハンドルを提供すると、バグ チェックが発生します。
注釈
WdfIoTargetFormatRequestForIoctl メソッドの後に WdfRequestSend メソッドを使用して、デバイス制御要求を同期的または非同期的に送信します。 または、 WdfIoTargetSendIoctlSynchronously メソッドを使用して、デバイス制御要求を同期的に送信します。
デバイス制御要求の詳細については、「 I/O 制御コードの使用」を参照してください。
ドライバーが I/O キューで受信したデバイス制御要求を転送することも、新しい要求を作成して送信することもできます。 どちらの場合も、フレームワークには要求オブジェクトとバッファー領域が必要です。
ドライバーが I/O キューで受信したデバイス制御要求を転送するには:
- WdfIoTargetFormatRequestForIoctl メソッドの Request パラメーターに対して、受信した要求のハンドルを指定します。
-
WdfIoTargetFormatRequestForIoctl メソッドの InputBuffer パラメーターには、受信した要求の入力バッファーを使用します。
ドライバーは WdfRequestRetrieveInputMemory を呼び出して、要求の入力バッファーを表すフレームワーク メモリ オブジェクトへのハンドルを取得する必要があり、そのハンドルを InputBuffer の値として使用する必要があります。
-
WdfIoTargetFormatRequestForIoctl メソッドの OutputBuffer パラメーターには、受信した要求の出力バッファーを使用します。
ドライバーは、要求の出力バッファーへのハンドルを取得するために WdfRequestRetrieveOutputMemory を呼び出す必要があり、そのハンドルを OutputBuffer の値として使用する必要があります。
ドライバーは、多くの場合、受信した I/O 要求を、I/O ターゲットに送信する小さな要求に分割するため、ドライバーが新しい要求を作成する可能性があります。
新しい I/O 要求を作成するには:
-
新しい要求オブジェクトを作成し、 WdfIoTargetFormatRequestForIoctl メソッドの Request パラメーターのハンドルを 指定 します。
WdfRequestCreate を呼び出して、1 つ以上の要求オブジェクトを事前割り当てします。 これらの要求オブジェクトを再利用するには、 WdfRequestReuse を呼び出します。 ドライバーの EvtDriverDeviceAdd コールバック関数は、デバイスの要求オブジェクトを事前割り当てできます。
-
バッファー領域を指定し、 WdfIoTargetFormatRequestForIoctl メソッドの InputBuffer パラメーターと OutputBuffer パラメーターのバッファーのハンドル を 指定します。
ドライバーでは、フレームワークマネージド メモリへの WDFMEMORY ハンドルとして、このバッファー領域を指定する必要があります。 ドライバーは、次のいずれかを実行できます。
- ドライバーが新しいバッファーを I/O ターゲットに渡す場合は、 WdfMemoryCreate または WdfMemoryCreatePreallocated を呼び出して新しいメモリ バッファーを作成します。
- ドライバーがバッファーの内容を I/O ターゲットに渡す場合は、 WdfRequestRetrieveInputMemory または WdfRequestRetrieveOutputMemory を呼び出して、受信した I/O 要求のバッファーを表すメモリ オブジェクトへのハンドルを取得します。
同じ要求を使用する WdfIoTargetFormatRequestForIoctl を 複数回呼び出しても、追加のリソース割り当ては発生しません。 そのため、 WdfRequestCreate がSTATUS_INSUFFICIENT_RESOURCESを返す可能性を減らすために、ドライバーの EvtDriverDeviceAdd コールバック関数は WdfRequestCreate を呼び出して、デバイスの 1 つ以上の要求オブジェクトを事前割り当てできます。 その後、ドライバーは WdfRequestCreate の後の呼び出しから戻り値をSTATUS_INSUFFICIENT_RESOURCESすることなく、再利用 (WdfRequestReuse の呼び出し)、再フォーマット (WdfIoTargetFormatRequestForIoctl の呼び出し)、および各要求オブジェクトの再送信 (呼び出し WdfRequestSend) を行うことができます。 パラメーター値が変更されない場合、再利用された要求オブジェクトに対する WdfIoTargetFormatRequestForIoctl に 対する後続のすべての呼び出しは、STATUS_SUCCESSを返します。 (ドライバーが毎回同じ要求書式設定メソッドを呼び出さない場合は、追加のリソースが割り当てられる可能性があります。さらに、 I/O 制御コード で転送の種類がMETHOD_BUFFERED指定されている場合、フレームワークは要求ごとにシステム バッファーを割り当てる必要があり、メモリ リソースが不足しているために割り当てが失敗する可能性があります)。
I/O 要求の完了後に状態情報を取得する方法については、「 完了情報の取得」を参照してください。
WdfIoTargetFormatRequestForIoctl の詳細については、「一般的な I/O ターゲットへの I/O 要求の送信」を参照してください。
I/O ターゲットの詳細については、「I /O ターゲットの使用」を参照してください。
例
次のコードでは、事前割り当て済み要求オブジェクトと事前割り当て済みメモリ オブジェクトを再利用します。 この例では、入力バッファーと出力バッファーをメモリ オブジェクトに割り当て、要求オブジェクトの書式を設定し、 CompletionRoutine コールバック関数を登録して、要求を I/O ターゲットに送信します。
NTSTATUS
NICSendOidRequestToTargetAsync(
IN WDFIOTARGET IoTarget,
IN WDFREQUEST Request,
IN PFILE_OBJECT FileObject,
IN ULONG IoctlControlCode,
IN OUT PVOID InputBuffer,
IN ULONG InputBufferLength,
IN OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength,
OUT PULONG BytesReadOrWritten
)
{
NTSTATUS status;
PREQUEST_CONTEXT reqContext;
WDF_REQUEST_REUSE_PARAMS params;
WDFMEMORY inputMem, outputMem;
WDF_REQUEST_REUSE_PARAMS_INIT(
¶ms,
WDF_REQUEST_REUSE_NO_FLAGS,
STATUS_SUCCESS
);
status = WdfRequestReuse(Request, ¶ms);
if (!NT_SUCCESS(status)){
return status;
}
reqContext = GetRequestContext(Request);
inputMem = outputMem = NULL;
if (InputBuffer != NULL) {
status = WdfMemoryAssignBuffer(
reqContext->InputMemory,
InputBuffer,
InputBufferLength
);
if (!NT_SUCCESS(status)) {
return status;
}
inputMem = reqContext->InputMemory;
}
if (OutputBuffer != NULL) {
status = WdfMemoryAssignBuffer(
reqContext->OutputMemory,
OutputBuffer,
OutputBufferLength
);
if (!NT_SUCCESS(status)) {
return status;
}
outputMem = reqContext->OutputMemory;
}
status = WdfIoTargetFormatRequestForIoctl(
IoTarget,
Request,
IoctlControlCode,
inputMem,
NULL,
outputMem,
NULL
);
if (!NT_SUCCESS(status)) {
return status;
}
WdfRequestSetCompletionRoutine(
Request,
NICSendOidRequestToTargetAsyncCompletionRoutine,
BytesReadOrWritten
);
if (WdfRequestSend(
Request,
IoTarget,
WDF_NO_SEND_OPTIONS
) == FALSE) {
status = WdfRequestGetStatus(Request);
}
return status;
}
要件
要件 | 値 |
---|---|
対象プラットフォーム | ユニバーサル |
最小 KMDF バージョン | 1.0 |
最小 UMDF バージョン | 2.0 |
Header | wdfiotarget.h (Wdf.h を含む) |
Library | Wdf01000.sys (KMDF);WUDFx02000.dll (UMDF) |
IRQL | <=DISPATCH_LEVEL |
DDI コンプライアンス規則 | DriverCreate(kmdf)、 KmdfIrql(kmdf)、 KmdfIrql2(kmdf)、KmdfIrqlExplicit(kmdf)、 RequestFormattedValid(kmdf)、 RequestSendAndForgetNoFormatting(kmdf)、 RequestSendAndForgetNoFormatting2(kmdf) |
こちらもご覧ください
WdfIoTargetFormatRequestForInternalIoctl
WdfIoTargetSendIoctlSynchronously