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


Функция 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, так как для метода требуется контекст процесса процесса, создавшего запрос ввода-вывода.

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

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

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

Если 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