WdfRequestProbeAndLockUserBufferForRead 関数 (wdfrequest.h)

[KMDF にのみ適用]

WdfRequestProbeAndLockUserBufferForRead メソッドは、I/O 要求のユーザー モード バッファーが読み取り可能であることを確認し、ドライバー スタック内のドライバーがバッファーを読み取ることができるようにバッファーの物理メモリ ページをロックします。

構文

NTSTATUS WdfRequestProbeAndLockUserBufferForRead(
  [in]  WDFREQUEST Request,
  [in]  PVOID      Buffer,
  [in]  size_t     Length,
  [out] WDFMEMORY  *MemoryObject
);

パラメーター

[in] Request

フレームワーク要求オブジェクトへのハンドル。

[in] Buffer

要求の入力バッファーへのポインター。 詳細については、「解説」を参照してください。

[in] Length

要求の入力バッファーの長さ (バイト単位)。

[out] MemoryObject

ユーザー入力バッファーを表すフレームワーク メモリ オブジェクトへのハンドルを受け取る場所へのポインター。

戻り値

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

リターン コード 説明
STATUS_INVALID_PARAMETER
入力パラメーターが無効です。
STATUS_INVALID_USER_BUFFER
Length パラメーターは 0 です。
STATUS_INVALID_DEVICE_REQUEST
要求は既に完了しているか、それ以外の場合は無効です。
STATUS_ACCESS_VIOLATION
現在のスレッドは、I/O 要求の作成者ではありません。
STATUS_INSUFFICIENT_RESOURCES
操作を完了するためのメモリが不足しています。
 

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

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

注釈

メソッドには I/O 要求を作成したプロセスのプロセス コンテキストが必要であるため、 WdfRequestProbeAndLockUserBufferForRead メソッドを呼び出すことができるのは、最上位ドライバーだけです。

通常、ユーザー入力バッファーには、デバイスに書き込まれる情報が含まれます。

Buffer パラメーターが指定するユーザー モード バッファーは、WdfRequestRetrieveUnsafeUserInputBuffer が取得するバッファーにすることも、別のユーザー モード入力バッファーにすることもできます。 たとえば、バッファーアクセスメソッドを使用する I/O 制御コードは、ユーザー モード バッファーへの埋め込みポインターを含む構造体を渡す場合があります。 このような場合、ドライバーはWdfRequestProbeAndLockUserBufferForRead を使用してバッファーのメモリ オブジェクトを取得できます。

Length パラメーターが指定するバッファーの長さは、バッファーの実際のサイズより大きくすることはできません。 それ以外の場合、ドライバーはバッファーの外部のメモリにアクセスできます。これはセキュリティ上のリスクです。

WdfRequestProbeAndLockUserBufferForRead がSTATUS_SUCCESSを返す場合、ドライバーは、ユーザー モード バッファーを表すフレームワーク メモリ オブジェクトへのハンドルを受け取ります。 バッファーにアクセスするには、ドライバーが WdfMemoryGetBuffer を呼び出す必要があります。

フレームワーク メモリ オブジェクトは、ドライバーが WdfRequestComplete を呼び出すと自動的に解放されます。

WdfRequestProbeAndLockUserBufferForRead の詳細については、「Framework-Based ドライバーでのデータ バッファーへのアクセス」を参照してください。

次のコード例は、NONPNP サンプル ドライバーに含まれる EvtIoInCallerContext コールバック関数の短縮バージョンです。 コールバック関数は、I/O 要求を受信すると、転送の種類が METHOD_NEITHER の I/O 制御コードが要求に含まれているかどうかを判断します。 要求にこのような I/O 制御コードが含まれている場合、関数は次のようになります。

  1. WdfRequestRetrieveUnsafeUserInputBufferWdfRequestRetrieveUnsafeUserOutputBuffer を呼び出して、要求の読み取りバッファーと書き込みバッファーの仮想アドレスを取得します。
  2. WdfRequestProbeAndLockUserBufferForRead および WdfRequestProbeAndLockUserBufferForWrite を呼び出して、バッファーをプローブおよびロックし、各バッファーを表すフレームワーク メモリ オブジェクトへのハンドルを取得します。
VOID
NonPnpEvtIoInCallerContext(
    IN WDFDEVICE  Device,
    IN WDFREQUEST Request
    )
{
    NTSTATUS  status = STATUS_SUCCESS;
    PREQUEST_CONTEXT  reqContext = NULL;
    WDF_OBJECT_ATTRIBUTES  attributes;
    WDF_REQUEST_PARAMETERS  params;
    size_t  inBufLen, outBufLen;
    PVOID  inBuf, outBuf;

    WDF_REQUEST_PARAMETERS_INIT(&params);
    WdfRequestGetParameters(
                            Request,
                            &params
                            );

    //
    // Check to see whether the driver received a METHOD_NEITHER I/O control code.
    // If not, just send the request back to the framework.
    //
    if(!(params.Type == WdfRequestTypeDeviceControl &&
            params.Parameters.DeviceIoControl.IoControlCode ==
                                    IOCTL_NONPNP_METHOD_NEITHER)) {
        status = WdfDeviceEnqueueRequest(
                                         Device,
                                         Request
                                         );
        if( !NT_SUCCESS(status) ) {
            goto End;
        }
        return;
    }

    //
    // The I/O control code is METHOD_NEITHER.
    // First, retrieve the virtual addresses of 
    // the input and output buffers.
    //
    status = WdfRequestRetrieveUnsafeUserInputBuffer(
                                                     Request,
                                                     0,
                                                     &inBuf,
                                                     &inBufLen
                                                     );
    if(!NT_SUCCESS(status)) {
        goto End;
    }
    status = WdfRequestRetrieveUnsafeUserOutputBuffer(
                                                      Request,
                                                      0,
                                                      &outBuf,
                                                      &outBufLen
                                                      );
    if(!NT_SUCCESS(status)) {
       goto End;
    }

    //
    // Next, allocate context space for the request, so that the
    // driver can store handles to the memory objects that will
    // be created for input and output buffers.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes,
                                        REQUEST_CONTEXT);
    status = WdfObjectAllocateContext(
                                      Request,
                                      &attributes,
                                      &reqContext
                                      );
    if(!NT_SUCCESS(status)) {
        goto End;
    }

    //
    // Next, probe and lock the read and write buffers.
    //
    status = WdfRequestProbeAndLockUserBufferForRead(
                                                     Request,
                                                     inBuf,
                                                     inBufLen,
                                                     &reqContext->InputMemoryBuffer
                                                     );
    if(!NT_SUCCESS(status)) {
        goto End;
    }

    status = WdfRequestProbeAndLockUserBufferForWrite(
                                                      Request,
                                                      outBuf,
                                                      outBufLen,
                                                      &reqContext->OutputMemoryBuffer
                                                      );
    if(!NT_SUCCESS(status)) {
        goto End;
    }

    //
    // Finally, return the request to the framework.
    //
    status = WdfDeviceEnqueueRequest(
                                     Device,
                                     Request
                                     );
    if(!NT_SUCCESS(status)) {
        goto End;
    }
    return;

End:
    WdfRequestComplete(
                       Request,
                       status
                       );
    return;
}

要件

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

こちらもご覧ください

WdfMemoryGetBuffer

WdfRequestProbeAndLockUserBufferForWrite

WdfRequestRetrieveUnsafeUserInputBuffer