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 |
---|---|
|
Um parâmetro de entrada é inválido. |
|
O parâmetro Length é zero. |
|
A solicitação já foi concluída ou é inválida. |
|
O thread atual não é o criador da solicitação de E/S. |
|
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 :
- Chama WdfRequestRetrieveUnsafeUserInputBuffer e WdfRequestRetrieveUnsafeUserOutputBuffer para obter os endereços virtuais dos buffers de leitura e gravação da solicitação.
- 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(¶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;
}
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) |