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 값을 반환할 수도 있습니다.
드라이버가 잘못된 개체 핸들을 제공하는 경우 버그 검사 발생합니다.
설명
최상위 드라이버만 WdfRequestProbeAndLockUserBufferForRead 메서드를 호출할 수 있습니다. 메서드에는 I/O 요청을 만든 프로세스의 프로세스 컨텍스트가 필요하기 때문입니다.
사용자 입력 버퍼에는 일반적으로 디바이스에 쓸 정보가 포함됩니다.
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 |
머리글 | wdfrequest.h(Wdf.h 포함) |
라이브러리 | Wdf01000.sys(프레임워크 라이브러리 버전 관리 참조) |
IRQL | PASSIVE_LEVEL |
DDI 규정 준수 규칙 | DriverCreate(kmdf), InvalidReqAccess(kmdf), InvalidReqAccessLocal(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf) |