Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
[Применимо только к 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, так как для метода требуется контекст процесса процесса, создавшего запрос ввода-вывода.
Буфер ввода пользователя обычно содержит сведения, записываемые на устройство.
Буфер пользовательского режима, указывающий параметр буфера, может быть буфером, который WdfRequestRetrieveUnsafeUserInputBuffer или может быть другим буфером ввода в режиме пользователя. Например, код элемента управления ввода-вывода, использующий буферный метод доступа, может передать структуру, содержащую внедренный указатель на буфер пользовательского режима. В таком случае драйвер может использоватьWdfRequestProbeAndLockUserBufferForRead для получения объекта памяти для буфера.
Длина буфера, указываемая параметром длины, не должна превышать фактический размер буфера. В противном случае драйверы могут получить доступ к памяти за пределами буфера, что является угрозой безопасности.
Если 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) |