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を返します。 それ以外の場合、このメソッドは次のいずれかの値を返す可能性があります。
リターン コード | 説明 |
---|---|
|
入力パラメーターが無効です。 |
|
Length パラメーターは 0 です。 |
|
要求は既に完了しているか、それ以外の場合は無効です。 |
|
現在のスレッドは、I/O 要求の作成者ではありません。 |
|
操作を完了するためのメモリが不足しています。 |
このメソッドは、他の 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 制御コードが含まれている場合、関数は次のようになります。
- WdfRequestRetrieveUnsafeUserInputBuffer と WdfRequestRetrieveUnsafeUserOutputBuffer を呼び出して、要求の読み取りバッファーと書き込みバッファーの仮想アドレスを取得します。
- 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(¶ms);
WdfRequestGetParameters(
Request,
¶ms
);
//
// 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) |