다음을 통해 공유


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 값을 반환할 수도 있습니다.

드라이버에서 잘못된 개체 핸들을 제공하면 버그 검사가 수행됩니다.

발언

최상위 드라이버만 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 제어 코드가 포함된 경우 함수는 다음과 같습니다.

  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
헤더 wdfrequest.h(Wdf.h 포함)
라이브러리 Wdf01000.sys(프레임워크 라이브러리 버전 관리 참조)
IRQL PASSIVE_LEVEL
DDI 규정 준수 규칙 DriverCreate(kmdf), InvalidReqAccess(kmdf), InvalidReqAccessLocal(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

참고 항목

WdfMemoryGetBuffer

WdfRequestProbeAndLockUserBufferForWrite

WdfRequestRetrieveUnsafeUserInputBuffer