Функция 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, если операция выполнена успешно. В противном случае этот метод может возвращать одно из следующих значений:
Код возврата | Описание |
---|---|
|
Недопустимый входной параметр. |
|
Параметр Length равен нулю. |
|
Запрос уже выполнен или недопустим иным образом. |
|
Текущий поток не является создателем запроса ввода-вывода. |
|
Недостаточно памяти для завершения операции. |
Этот метод также может возвращать другие значения NTSTATUS.
Ошибка проверка возникает, если драйвер предоставляет недопустимый дескриптор объекта.
Комментарии
Только драйвер верхнего уровня может вызывать метод WdfRequestProbeAndLockUserBufferForRead , так как для этого метода требуется контекст процесса, создавшего запрос ввода-вывода.
Буфер ввода пользователя обычно содержит сведения для записи на устройство.
Буфер пользовательского режима, который задает параметр Buffer , может быть буфером, который извлекает WdfRequestRetrieveUnsafeUserInputBuffer , или другим входным буфером пользовательского режима. Например, код элемента управления вводом-выводом, использующий метод буферизованного доступа, может передавать структуру, содержащую внедренный указатель на буфер пользовательского режима. В этом случае драйвер может использоватьWdfRequestProbeAndLockUserBufferForRead для получения объекта памяти для буфера.
Длина буфера, указываемая параметром Length , не должна превышать фактический размер буфера. В противном случае драйверы могут получить доступ к памяти за пределами буфера, что представляет угрозу безопасности.
Если WdfRequestProbeAndLockUserBufferForRead возвращает STATUS_SUCCESS, драйвер получает дескриптор объекта памяти платформы, который представляет буфер пользовательского режима. Чтобы получить доступ к буферу, драйвер должен вызвать WdfMemoryGetBuffer.
Объект памяти платформы автоматически освобождается, когда драйвер вызывает WdfRequestComplete.
Дополнительные сведения о WdfRequestProbeAndLockUserBufferForRead см. в статье Доступ к буферам данных в драйверах Framework-Based.
Примеры
Следующий пример кода представляет собой сокращенную версию функции обратного вызова EvtIoInCallerContext , которая содержится в примере драйвера NONPNP . Когда функция обратного вызова получает запрос ввода-вывода, она определяет, содержит ли запрос управляющий код ввода-вывода с типом передачи METHOD_NEITHER. Если запрос содержит такой код элемента управления вводом-выводом, функция:
- Вызывает WdfRequestRetrieveUnsafeUserInputBuffer и WdfRequestRetrieveUnsafeUserOutputBuffer для получения виртуальных адресов буферов чтения и записи запроса.
- Вызывает 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(¶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;
}
Требования
Требование | Значение |
---|---|
Целевая платформа | Универсальное |
Минимальная версия 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) |