Compartilhar via


Função WdfRequestProbeAndLockUserBufferForRead (wdfrequest.h)

[Aplica-se somente ao KMDF]

O método WdfRequestProbeAndLockUserBufferForRead verifica se o buffer de modo de usuário de uma solicitação de E/S é legível e bloqueia as páginas de memória física do buffer para que os drivers na pilha de driver possam ler o buffer.

Sintaxe

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

Parâmetros

[in] Request

Um identificador para um objeto de solicitação de estrutura.

[in] Buffer

Um ponteiro para o buffer de entrada da solicitação. Para obter mais informações, consulte a seção Comentários a seguir.

[in] Length

O comprimento, em bytes, do buffer de entrada da solicitação.

[out] MemoryObject

Um ponteiro para um local que recebe um identificador para um objeto de memória de estrutura que representa o buffer de entrada do usuário.

Retornar valor

WdfRequestProbeAndLockUserBufferForRead retornará STATUS_SUCCESS se a operação for bem-sucedida. Caso contrário, esse método pode retornar um dos seguintes valores:

Código de retorno Descrição
STATUS_INVALID_PARAMETER
Um parâmetro de entrada é inválido.
STATUS_INVALID_USER_BUFFER
O parâmetro Length é zero.
STATUS_INVALID_DEVICE_REQUEST
A solicitação já foi concluída ou é inválida.
STATUS_ACCESS_VIOLATION
O thread atual não é o criador da solicitação de E/S.
STATUS_INSUFFICIENT_RESOURCES
Não há memória suficiente para concluir a operação.
 

Esse método também pode retornar outros valores NTSTATUS.

Um bug marcar ocorrerá se o driver fornecer um identificador de objeto inválido.

Comentários

Somente um driver de nível superior pode chamar o método WdfRequestProbeAndLockUserBufferForRead , pois o método requer o contexto de processo do processo que criou a solicitação de E/S.

O buffer de entrada do usuário normalmente contém informações a serem gravadas no dispositivo.

O buffer de modo de usuário especificado pelo parâmetro Buffer pode ser o buffer que WdfRequestRetrieveUnsafeUserInputBuffer recupera ou pode ser um buffer de entrada de modo de usuário diferente. Por exemplo, um código de controle de E/S que usa o método de acesso em buffer pode passar uma estrutura que contém um ponteiro inserido para um buffer de modo de usuário. Nesse caso, o driver pode usarWdfRequestProbeAndLockUserBufferForRead para obter um objeto de memória para o buffer.

O comprimento do buffer especificado pelo parâmetro Length não deve ser maior que o tamanho real do buffer. Caso contrário, os drivers poderão acessar a memória fora do buffer, o que é um risco à segurança.

Se WdfRequestProbeAndLockUserBufferForRead retornar STATUS_SUCCESS, o driver receberá um identificador para um objeto de memória de estrutura que representa o buffer do modo de usuário. Para acessar o buffer, o driver deve chamar WdfMemoryGetBuffer.

O objeto de memória da estrutura é liberado automaticamente quando o driver chama WdfRequestComplete.

Para obter mais informações sobre WdfRequestProbeAndLockUserBufferForRead, consulte Acessando buffers de dados em drivers de Framework-Based.

Exemplos

O exemplo de código a seguir é uma versão abreviada da função de retorno de chamada EvtIoInCallerContext que o driver de exemplo NONPNP contém. Quando a função de retorno de chamada recebe uma solicitação de E/S, ela determina se a solicitação contém um código de controle de E/S com um tipo de transferência de METHOD_NEITHER. Se a solicitação contiver esse código de controle de E/S, a função :

  1. Chama WdfRequestRetrieveUnsafeUserInputBuffer e WdfRequestRetrieveUnsafeUserOutputBuffer para obter os endereços virtuais dos buffers de leitura e gravação da solicitação.
  2. Chama WdfRequestProbeAndLockUserBufferForRead e WdfRequestProbeAndLockUserBufferForWrite para investigar e bloquear os buffers e obter um identificador para um objeto de memória de estrutura que representa cada buffer.
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;
}

Requisitos

Requisito Valor
Plataforma de Destino Universal
Versão mínima do KMDF 1.0
Cabeçalho wdfrequest.h (inclua Wdf.h)
Biblioteca Wdf01000.sys (consulte Controle de versão da biblioteca de estrutura.)
IRQL PASSIVE_LEVEL
Regras de conformidade da DDI DriverCreate(kmdf), InvalidReqAccess(kmdf), InvalidReqAccessLocal(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

Confira também

WdfMemoryGetBuffer

WdfRequestProbeAndLockUserBufferForWrite

WdfRequestRetrieveUnsafeUserInputBuffer