WdfUsbTargetPipeFormatRequestForRead 関数 (wdfusb.h)
[KMDF と UMDF に適用]
WdfUsbTargetPipeFormatRequestForRead メソッドは、USB 入力パイプの読み取り要求をビルドしますが、要求は送信しません。
構文
NTSTATUS WdfUsbTargetPipeFormatRequestForRead(
[in] WDFUSBPIPE Pipe,
[in] WDFREQUEST Request,
[in, optional] WDFMEMORY ReadMemory,
[in, optional] PWDFMEMORY_OFFSET ReadOffset
);
パラメーター
[in] Pipe
WdfUsbInterfaceGetConfiguredPipe を呼び出して取得したフレームワーク パイプ オブジェクトへのハンドル。
[in] Request
フレームワーク要求オブジェクトへのハンドル。 詳細については、「解説」を参照してください。
[in, optional] ReadMemory
フレームワーク メモリ オブジェクトへのハンドル。 このオブジェクトは、パイプからデータを受信するバッファーを表します。 ドライバーが WdfUsbTargetPipeSetNoMaximumPacketSizeCheck を呼び出していない限り、バッファー サイズはパイプの最大パケット サイズの倍数である必要があります。 このバッファーの詳細については、次の「解説」セクションを参照してください。
[in, optional] ReadOffset
省略可能なバイト オフセットと長さの値を提供する呼び出し元によって割り当てられた WDFMEMORY_OFFSET 構造体へのポインター。 フレームワークでは、これらの値を使用して、データ転送の読み取りバッファー内の開始アドレスと長さを決定します。 このポインターが NULL の場合、データ転送はバッファーの先頭から始まり、転送サイズはバッファー サイズです。
戻り値
操作が成功した場合、WdfUsbTargetPipeFormatRequestForRead はSTATUS_SUCCESSを返します。 それ以外の場合、このメソッドは次のいずれかの値を返すことができます。
リターン コード | 説明 |
---|---|
|
無効なパラメーターが検出されました。 |
|
メモリが不足していました。 |
|
無効なメモリ記述子が指定されたか、パイプの種類が無効であるか、転送方向が無効であるか、指定された I/O 要求が既に I/O ターゲットにキューに登録されています。 |
|
Offset パラメーターが指定した オフセット が無効です。 |
|
バッファー サイズは、パイプの最大パケット サイズの倍数ではありません。 ドライバーが WdfUsbTargetPipeSetNoMaximumPacketSizeCheck を呼び出していない限り、バッファー サイズはパイプの最大パケット サイズの倍数である必要があります。 |
|
要求パラメーターが表す I/O 要求パケット (IRP) は、ドライバーが 要求 を転送できるようにするため の十 分なIO_STACK_LOCATION構造体を提供しません。 |
このメソッドは、他の NTSTATUS 値を返す場合もあります。
ドライバーが無効なオブジェクト ハンドルを提供すると、バグ チェックが発生します。
注釈
WdfUsbTargetPipeFormatRequestForRead の後に WdfRequestSend を使用して、読み取り要求を同期的または非同期的に送信します。 または、 WdfUsbTargetPipeReadSynchronously メソッドを使用して、読み取り要求を同期的に送信します。
Pipe パラメーターで指定する パイプ は入力パイプである必要があり、パイプの 種類 は WdfUsbPipeTypeBulk または WdfUsbPipeTypeInterrupt である必要があります。
ドライバーが I/O キューで受信した I/O 要求を転送することも、新しい要求を作成して送信することもできます。 どちらの場合も、フレームワークには要求オブジェクトとバッファー領域が必要です。
ドライバーが I/O キューで受信した I/O 要求を転送するには:
- WdfUsbTargetPipeFormatRequestForRead メソッドの Request パラメーターに対して、受信した要求のハンドルを指定します。
-
WdfUsbTargetPipeFormatRequestForRead メソッドの ReadMemory パラメーターには、受信した要求の出力バッファーを使用します。
ドライバーは WdfRequestRetrieveOutputMemory を呼び出して、要求の出力バッファーを表すフレームワーク メモリ オブジェクトへのハンドルを取得し、そのハンドルを ReadMemory パラメーターの値として使用する必要があります。
ドライバーは、多くの場合、受信した I/O 要求を、I/O ターゲットに送信する小さな要求に分割するため、ドライバーは新しい要求を作成する可能性があります。
新しい I/O 要求を作成するには:
-
新しい要求オブジェクトを作成し、 WdfUsbTargetPipeFormatRequestForRead メソッドの Request パラメーターのハンドルを 指定 します。
WdfRequestCreate を呼び出して、1 つ以上の要求オブジェクトを事前割り当てします。 これらの要求オブジェクトを再利用するには、 WdfRequestReuse を呼び出します。 ドライバーの EvtDriverDeviceAdd コールバック関数は、デバイスの要求オブジェクトを事前割り当てできます。
-
バッファー領域を指定し、 WdfUsbTargetPipeFormatRequestForRead メソッドの ReadMemory パラメーターのバッファーのハンドルを指定します。
ドライバーでは、フレームワークマネージド メモリへの WDFMEMORY ハンドルとしてこのバッファー領域を指定する必要があります。 ドライバーは、次のいずれかを実行できます。
- ドライバーが新しいバッファーを I/O ターゲットに渡す場合は、 WdfMemoryCreate または WdfMemoryCreatePreallocated を呼び出して新しいメモリ バッファーを作成します。
- ドライバーがそのバッファーの内容を I/O ターゲットに渡す場合は、 WdfRequestRetrieveOutputMemory を呼び出して、受信した I/O 要求のバッファーを表すメモリ オブジェクトへのハンドルを取得します。
同じ要求を使用する WdfUsbTargetPipeFormatRequestForRead を複数回呼び出しても、追加のリソース割り当ては発生しません。 そのため、 WdfRequestCreate がSTATUS_INSUFFICIENT_RESOURCESを返す可能性を減らすために、ドライバーの EvtDriverDeviceAdd コールバック関数は WdfRequestCreate を呼び出して、デバイスの 1 つ以上の要求オブジェクトを事前割り当てできます。 ドライバーは、その後、 WdfRequestReuse の呼び出し、再フォーマット ( WdfUsbTargetPipeFormatRequestForRead の呼び出し)、および WdfRequestCreate の後の呼び出しからSTATUS_INSUFFICIENT_RESOURCES戻り値を危険にさらすことなく、各要求オブジェクトを再送信 (呼び出し WdfRequestSend) できます。 再利用された要求オブジェクトに対する WdfUsbTargetPipeFormatRequestForRead に対する後続のすべての呼び出しは、パラメーター値が変更されない場合、STATUS_SUCCESSを返します。 (ドライバーが毎回同じ要求形式メソッドを呼び出さない場合は、追加のリソースが割り当てられる可能性があります)。
フレームワークは、内部 URB に USBD_SHORT_TRANSFER_OK フラグを設定します。 このフラグを設定すると、データ転送の最後のパケットが最大パケット サイズより小さくなります。
I/O 要求の完了後に状態情報を取得する方法については、「 完了情報の取得」を参照してください。
WdfUsbTargetPipeFormatRequestForRead メソッドと USB I/O ターゲットの詳細については、「USB I/O ターゲット」を参照してください。
例
次のコード例は、 kmdf_fx2 サンプル ドライバーのものです。 この例は、読み取り要求を USB パイプに転送する EvtIoRead コールバック関数です。 この例では 、WdfRequestRetrieveOutputMemory を呼び出して要求の出力バッファーを取得し、USB パイプに要求を送信できるように読み取り要求を書式設定します。 次に、 CompletionRoutine コールバック関数を登録します。 最後に、USB パイプに要求を送信します。
VOID
OsrFxEvtIoRead(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
WDFUSBPIPE pipe;
NTSTATUS status;
WDFMEMORY reqMemory;
PDEVICE_CONTEXT pDeviceContext;
//
// First, validate input parameters.
//
if (Length > TEST_BOARD_TRANSFER_BUFFER_SIZE) {
status = STATUS_INVALID_PARAMETER;
goto Exit;
}
pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
pipe = pDeviceContext->BulkReadPipe;
status = WdfRequestRetrieveOutputMemory(
Request,
&reqMemory
);
if (!NT_SUCCESS(status)){
goto Exit;
}
status = WdfUsbTargetPipeFormatRequestForRead(
pipe,
Request,
reqMemory,
NULL
);
if (!NT_SUCCESS(status)) {
goto Exit;
}
WdfRequestSetCompletionRoutine(
Request,
EvtRequestReadCompletionRoutine,
pipe
);
if (WdfRequestSend(
Request,
WdfUsbTargetPipeGetIoTarget(pipe),
WDF_NO_SEND_OPTIONS
) == FALSE) {
status = WdfRequestGetStatus(Request);
goto Exit;
}
Exit:
if (!NT_SUCCESS(status)) {
WdfRequestCompleteWithInformation(
Request,
status,
0
);
}
return;
}
要件
要件 | 値 |
---|---|
対象プラットフォーム | ユニバーサル |
最小 KMDF バージョン | 1.0 |
最小 UMDF バージョン | 2.0 |
Header | wdfusb.h (Wdfusb.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)、 UsbKmdfIrql(kmdf)、 UsbKmdfIrql2(kmdf)、UsbKmdfIrqlExplicit(kmdf) |
こちらもご覧ください
WdfRequestCompleteWithInformation