다음을 통해 공유


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. WdfRequestProbeAndLockUserBufferForReadWdfRequestProbeAndLockUserBufferForWrite를 호출하여 버퍼를 검색 및 잠그고 각 버퍼를 나타내는 프레임워크 메모리 개체에 대한 핸들을 가져옵니다.
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