WdfIoTargetFormatRequestForInternalIoctl 関数 (wdfiotarget.h)

[KMDF にのみ適用]

WdfIoTargetFormatRequestForInternalIoctl メソッドは、I/O ターゲットの内部デバイス制御要求をビルドしますが、要求は送信しません。

構文

NTSTATUS WdfIoTargetFormatRequestForInternalIoctl(
  [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 の場合、データ転送は出力バッファーの先頭から開始され、転送サイズはバッファー サイズです。

戻り値

操作が成功した場合、WdfIoTargetFormatRequestForInternalIoctl はSTATUS_SUCCESSを返します。 それ以外の場合、このメソッドは次のいずれかの値を返す可能性があります。

リターン コード 説明
STATUS_INVALID_PARAMETER
無効なパラメーターが検出されました。
STATUS_INVALID_DEVICE_REQUEST
転送長がバッファー長を超えているか、I/O 要求が既に I/O ターゲットにキューに入れられました。
STATUS_INSUFFICIENT_RESOURCES
フレームワークはシステム リソース (通常はメモリ) を割り当てませんでした。
STATUS_REQUEST_NOT_ACCEPTED
要求パラメーターが表す I/O 要求パケット (IRP) は、ドライバーが 要求 を転送できるようにするため の十 分なIO_STACK_LOCATION構造を提供しません。
 

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

ドライバーが無効なオブジェクト ハンドルを提供すると、バグ チェックが発生します。

注釈

WdfIoTargetFormatRequestForInternalIoctl メソッドの後に WdfRequestSend メソッドを使用して、内部デバイス制御要求を同期的または非同期的に送信します。 または、 WdfIoTargetSendInternalIoctlSynchronously メソッドを使用して、内部デバイス制御要求を同期的に送信します。

内部デバイス制御要求の詳細については、「 I/O 制御コードの使用」を参照してください。

ドライバーが I/O キューで受信した内部デバイス制御要求を転送することも、新しい要求を作成して送信することもできます。 どちらの場合も、フレームワークには要求オブジェクトとバッファー領域が必要です。

ドライバーが I/O キューで受信した内部デバイス制御要求を転送するには:

  1. WdfIoTargetFormatRequestForInternalIoctl メソッドの Request パラメーターに対して、受信した要求のハンドルを指定します。
  2. WdfIoTargetFormatRequestForInternalIoctl メソッドの InputBuffer パラメーターには、受信した要求の入力バッファーを使用します。

    ドライバーは、要求の入力バッファーへのハンドルを取得するために WdfRequestRetrieveInputMemory を呼び出す必要があり、 InputBuffer の値としてそのハンドルを使用する必要があります。

  3. WdfIoTargetFormatRequestForInternalIoctl メソッドの OutputBuffer パラメーターには、受信した要求の出力バッファーを使用します。

    ドライバーは、要求の出力バッファーへのハンドルを取得するために WdfRequestRetrieveOutputMemory を呼び出す必要があり、そのハンドルを OutputBuffer の値として使用する必要があります。

I/O 要求の転送の詳細については、「I /O 要求の転送」を参照してください。

ドライバーは、多くの場合、受信した I/O 要求を、I/O ターゲットに送信する小さな要求に分割するため、ドライバーが新しい要求を作成する可能性があります。

新しい I/O 要求を作成するには:

  1. 新しい要求オブジェクトを作成し、 WdfIoTargetFormatRequestForInternalIoctl メソッドの Request パラメーターのハンドルを 指定 します。

    WdfRequestCreate を呼び出して、1 つ以上の要求オブジェクトを事前割り当てします。 これらの要求オブジェクトを再利用するには、 WdfRequestReuse を呼び出します。 ドライバーの EvtDriverDeviceAdd コールバック関数は、デバイスの要求オブジェクトを事前割り当てできます。

  2. バッファー領域を指定し、 WdfIoTargetFormatRequestForInternalIoctl メソッドの InputBuffer パラメーターと OutputBuffer パラメーターのバッファーのハンドル 指定します。

    ドライバーでは、フレームワークマネージド メモリへの WDFMEMORY ハンドルとして、このバッファー領域を指定する必要があります。 ドライバーは、次のいずれかを実行できます。

    • ドライバーが新しいバッファーを I/O ターゲットに渡す場合は、 WdfMemoryCreate または WdfMemoryCreatePreallocated を呼び出して新しいメモリ バッファーを作成します。
    • ドライバーがバッファーの内容を I/O ターゲットに渡す場合は、 WdfRequestRetrieveInputMemory または WdfRequestRetrieveOutputMemory を呼び出して、受信した I/O 要求のバッファーを表すメモリ オブジェクトへのハンドルを取得します。
    ドライバーが WdfRequestRetrieveInputMemory または WdfRequestRetrieveOutputMemory を呼び出し、メモリ ハンドルを WdfIoTargetFormatRequestForInternalIoctl に渡す場合、ドライバーは、ドライバーが新しく作成した要求オブジェクトを削除、再利用、または再フォーマットするまで、受信した I/O 要求を完了しないようにする必要があることに注意してください。 (WdfIoTargetFormatRequestForInternalIoctl は 、メモリ オブジェクトの参照カウントをインクリメントします。要求オブジェクトを削除、再利用、または再フォーマットすると、メモリ オブジェクトの参照カウントがデクリメントされます)。
ドライバーが WdfIoTargetFormatRequestForInternalIoctl を呼び出してデバイス コントロール要求を書式設定した後、ドライバーは WdfRequestSend を呼び出して要求を (同期的または非同期的に) I/O ターゲットに送信する必要があります。

同じ要求を使用する WdfIoTargetFormatRequestForInternalIoctl を 複数回呼び出しても、追加のリソース割り当ては発生しません。 そのため、 WdfRequestCreate がSTATUS_INSUFFICIENT_RESOURCESを返す可能性を減らすために、ドライバーの EvtDriverDeviceAdd コールバック関数は WdfRequestCreate を呼び出して、デバイスの 1 つ以上の要求オブジェクトを事前割り当てできます。 ドライバーは後で WdfRequestCreate の呼び出しから戻り値をSTATUS_INSUFFICIENT_RESOURCESすることなく、各要求オブジェクトを再利用 (呼び出し WdfRequestReuse)、再フォーマット (WdfIoTargetFormatRequestForInternalIoctl の呼び出し)、および再送信 (WdfRequestSend の呼び出し) を行うことができます。 再利用された要求オブジェクトに対する WdfIoTargetFormatRequestForInternalIoctl に対する後続のすべての呼び出しは、パラメーター値が変更されない場合、STATUS_SUCCESSを返します。 (ただし、ドライバーが毎回同じ要求書式設定メソッドを呼び出さない場合は、追加のリソースが割り当てられる可能性があります。さらに、 I/O 制御コード で転送の種類がMETHOD_BUFFERED指定されている場合、フレームワークは要求ごとにシステム バッファーを割り当てる必要があり、メモリ リソースが不足しているために割り当てが失敗する可能性があります)。

I/O 要求の完了後に状態情報を取得する方法については、「 完了情報の取得」を参照してください。

WdfIoTargetFormatRequestForInternalIoctl の詳細については、「一般的な I/O ターゲットへの I/O 要求の送信」を参照してください。

I/O ターゲットの詳細については、「I /O ターゲットの使用」を参照してください。

次のコード例では、要求オブジェクトの子であるフレームワーク メモリ オブジェクトを作成します。 次に、メモリ オブジェクトに格納されているバッファーを取得し、バッファーを初期化します。 次に、要求の書式を設定し、 CompletionRoutine コールバック関数を設定して、I/O ターゲットに要求を送信します。

WDF_OBJECT_ATTRIBUTES memoryObjAttr;
WDFMEMORY memory;
NTSTATUS status;
IOCTL_DATA *pIoctlData;

WDF_OBJECT_ATTRIBUTES_INIT(&memoryObjAttr);
memoryObjAttr.ParentObject = Request;

status = WdfMemoryCreate(
                         &memoryObjAttr,
                         NonPagedPool,
                         0,
                         sizeof(IOCTL_DATA),
                         &memory,
                         NULL
                         );
if (!NT_SUCCESS(status)) {
    goto Done;
}
pIoctlData = WdfMemoryGetBuffer(
                                memory,
                                NULL
                                );
RtlZeroMemory(
              pIoctlData,
              sizeof(IOCTL_DATA)
              );
pIoctlData->Member1 = MY_DATA;

status = WdfIoTargetFormatRequestForInternalIoctl(
                                                  IoTarget,
                                                  Request,
                                                  IOCTL_INTERNAL_GET_MY_DATA,
                                                  memory,
                                                  NULL,
                                                  WDF_NO_HANDLE,
                                                  NULL
                                                  );

if (!NT_SUCCESS(status)) {
    goto Done;
}

WdfRequestSetCompletionRoutine(
                               Request,
                               MyRequestCompletion,
                               NULL
                               );

if (WdfRequestSend(
                   Request,
                   IoTarget,
                   NULL
                   ) == FALSE) {
    status = WdfRequestGetStatus(Request);
}
else {
    status = STATUS_SUCCESS;
}

要件

要件
対象プラットフォーム ユニバーサル
最小 KMDF バージョン 1.0
Header wdfiotarget.h (Wdf.h を含む)
Library Wdf01000.sys (「Framework ライブラリのバージョン管理」を参照)。
IRQL <=DISPATCH_LEVEL
DDI コンプライアンス規則 DriverCreate(kmdf)KmdfIrql(kmdf)KmdfIrql2(kmdf)、KmdfIrqlExplicit(kmdf)、 RequestFormattedValid(kmdf)RequestSendAndForgetNoFormatting(kmdf)RequestSendAndForgetNoFormatting2(kmdf)

こちらもご覧ください

EvtDriverDeviceAdd

WDFMEMORY_OFFSET

WdfDeviceGetIoTarget

WdfIoTargetCreate

WdfIoTargetFormatRequestForIoctl

WdfIoTargetSendInternalIoctlSynchronously

WdfIoTargetSendIoctlSynchronously

WdfMemoryCreate

WdfMemoryCreatePreallocated

WdfRequestCreate

WdfRequestRetrieveInputMemory

WdfRequestRetrieveOutputMemory

WdfRequestReuse

WdfRequestSend