Поделиться через


Функция WdfRequestProbeAndLockUserBufferForRead (wdfrequest.h)

[Относится только к KMDF]

Метод WdfRequestProbeAndLockUserBufferForRead проверяет возможность чтения буфера пользовательского режима запроса ввода-вывода, а затем блокирует страницы физической памяти буфера, чтобы драйверы в стеке драйверов могли считывать буфер.

Синтаксис

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 равен нулю.
STATUS_INVALID_DEVICE_REQUEST
Запрос уже выполнен или недопустим иным образом.
STATUS_ACCESS_VIOLATION
Текущий поток не является создателем запроса ввода-вывода.
STATUS_INSUFFICIENT_RESOURCES
Недостаточно памяти для завершения операции.
 

Этот метод также может возвращать другие значения NTSTATUS.

Ошибка проверка возникает, если драйвер предоставляет недопустимый дескриптор объекта.

Комментарии

Только драйвер верхнего уровня может вызывать метод WdfRequestProbeAndLockUserBufferForRead , так как для этого метода требуется контекст процесса, создавшего запрос ввода-вывода.

Буфер ввода пользователя обычно содержит сведения для записи на устройство.

Буфер пользовательского режима, который задает параметр Buffer , может быть буфером, который извлекает WdfRequestRetrieveUnsafeUserInputBuffer , или другим входным буфером пользовательского режима. Например, код элемента управления вводом-выводом, использующий метод буферизованного доступа, может передавать структуру, содержащую внедренный указатель на буфер пользовательского режима. В этом случае драйвер может использоватьWdfRequestProbeAndLockUserBufferForRead для получения объекта памяти для буфера.

Длина буфера, указываемая параметром Length , не должна превышать фактический размер буфера. В противном случае драйверы могут получить доступ к памяти за пределами буфера, что представляет угрозу безопасности.

Если WdfRequestProbeAndLockUserBufferForRead возвращает STATUS_SUCCESS, драйвер получает дескриптор объекта памяти платформы, который представляет буфер пользовательского режима. Чтобы получить доступ к буферу, драйвер должен вызвать WdfMemoryGetBuffer.

Объект памяти платформы автоматически освобождается, когда драйвер вызывает WdfRequestComplete.

Дополнительные сведения о WdfRequestProbeAndLockUserBufferForRead см. в статье Доступ к буферам данных в драйверах Framework-Based.

Примеры

Следующий пример кода представляет собой сокращенную версию функции обратного вызова EvtIoInCallerContext , которая содержится в примере драйвера NONPNP . Когда функция обратного вызова получает запрос ввода-вывода, она определяет, содержит ли запрос управляющий код ввода-вывода с типом передачи METHOD_NEITHER. Если запрос содержит такой код элемента управления вводом-выводом, функция:

  1. Вызывает WdfRequestRetrieveUnsafeUserInputBuffer и WdfRequestRetrieveUnsafeUserOutputBuffer для получения виртуальных адресов буферов чтения и записи запроса.
  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