Функция WdfIoTargetFormatRequestForIoctl (wdfiotarget.h)
[Применимо к KMDF и UMDF]
Метод WdfIoTargetFormatRequestForIoctl создает запрос управления устройством для целевого объекта ввода-вывода, но не отправляет запрос.
Синтаксис
NTSTATUS WdfIoTargetFormatRequestForIoctl(
[in] WDFIOTARGET IoTarget,
[in] WDFREQUEST Request,
[in] ULONG IoctlCode,
[in, optional] WDFMEMORY InputBuffer,
[in, optional] PWDFMEMORY_OFFSET InputBufferOffset,
[in, optional] WDFMEMORY OutputBuffer,
[in, optional] PWDFMEMORY_OFFSET OutputBufferOffset
);
Параметры
[in] IoTarget
Дескриптор для локального или удаленного целевого объекта ввода-вывода, полученного из предыдущего вызова WdfDeviceGetIoTarget или WdfIoTargetCreate, или из метода, который предоставляет специализированный целевой объект ввода-вывода.
[in] Request
Дескриптор объекта запроса платформы. Дополнительные сведения см. в разделе "Примечания".
[in] IoctlCode
Код элемента управления вводом-выводом (IOCTL), поддерживаемый целевым объектом ввода-вывода.
[in, optional] InputBuffer
Дескриптор объекта памяти платформы. Этот объект представляет буфер, содержащий данные, которые будут отправлены в целевой объект ввода-вывода. Дополнительные сведения см. в разделе "Примечания".
[in, optional] InputBufferOffset
Указатель на структуру, выделенную вызывающим объектом WDFMEMORY_OFFSET , которая предоставляет необязательные значения смещения и длины байтов. Платформа использует эти значения для определения начального адреса и длины во входных буферах для передачи данных. Если этот указатель имеет значение NULL, передача данных начинается в начале входного буфера, а размер передачи равен размеру буфера.
[in, optional] OutputBuffer
Дескриптор объекта памяти платформы. Этот объект представляет буфер, который будет получать данные из целевого объекта ввода-вывода. Дополнительные сведения см. в разделе "Примечания".
[in, optional] OutputBufferOffset
Указатель на структуру, выделенную вызывающим объектом WDFMEMORY_OFFSET , которая предоставляет необязательные значения смещения и длины байтов. Платформа использует эти значения для определения начального адреса и длины в выходном буфере для передачи данных. Если этот указатель имеет значение NULL, передача данных начинается в начале выходного буфера, а размер передачи равен размеру буфера.
Возвращаемое значение
WdfIoTargetFormatRequestForIoctl возвращает STATUS_SUCCESS, если операция выполнена успешно. В противном случае этот метод может возвращать одно из следующих значений:
Код возврата | Описание |
---|---|
|
Обнаружен недопустимый параметр. |
|
Длина передачи была больше длины буфера, или запрос ввода-вывода уже был помещен в очередь в целевой объект ввода-вывода. |
|
Платформе не удалось выделить системные ресурсы (обычно это память). |
|
Пакет запроса ввода-вывода (IRP), который представляет параметр Request , не предоставляет достаточно IO_STACK_LOCATION структур, позволяющих драйверу пересылать запрос. |
Этот метод также может возвращать другие значения NTSTATUS.
Ошибка проверка возникает, если драйвер предоставляет недопустимый дескриптор объекта.
Комментарии
Используйте метод WdfIoTargetFormatRequestForIoctl , за которым следует метод WdfRequestSend , чтобы отправлять запросы управления устройствами синхронно или асинхронно. Кроме того, можно использовать метод WdfIoTargetSendIoctlSynchronously для синхронной отправки запросов управления устройствами.
Дополнительные сведения о запросах управления устройствами см. в разделе Использование кодов управления вводом-выводом.
Вы можете переслать запрос на управление устройством, полученный драйвером в очереди ввода-вывода, или создать и отправить новый запрос. В любом случае платформе требуется объект запроса и некоторое буферное пространство.
Чтобы переслать запрос на управление устройством, полученный драйвером в очереди ввода-вывода, выполните приведенные далее действия.
- Укажите дескриптор полученного запроса для параметра Request метода WdfIoTargetFormatRequestForIoctl.
-
Используйте входной буфер полученного запроса для параметра InputBuffer метода WdfIoTargetFormatRequestForIoctl.
Драйвер должен вызвать WdfRequestRetrieveInputMemory , чтобы получить дескриптор объекта памяти платформы, который представляет входной буфер запроса, и использовать этот дескриптор в качестве значения inputBuffer.
-
Используйте выходной буфер полученного запроса для параметра OutputBuffer метода WdfIoTargetFormatRequestForIoctl.
Драйвер должен вызвать WdfRequestRetrieveOutputMemory , чтобы получить дескриптор выходного буфера запроса, и использовать этот дескриптор в качестве значения для OutputBuffer.
Драйверы часто разделяют полученные запросы ввода-вывода на более мелкие запросы, отправляемые в целевой объект ввода-вывода, поэтому драйвер может создавать новые запросы.
Чтобы создать новый запрос ввода-вывода, выполните приведенные далее действия.
-
Создайте объект запроса и укажите его дескриптор для параметра Request метода WdfIoTargetFormatRequestForIoctl.
Вызовите WdfRequestCreate , чтобы предварительно выделить один или несколько объектов запроса. Эти объекты запроса можно повторно использовать, вызвав WdfRequestReuse. Функция обратного вызова EvtDriverDeviceAdd драйвера может предварительно выделить объекты запроса для устройства.
-
Укажите буферное пространство и укажите дескриптор буфера для параметров InputBuffer и OutputBuffer метода WdfIoTargetFormatRequestForIoctl.
Драйвер должен указать это буферное пространство, так как WDFMEMORY обрабатывает память, управляемую платформой. Драйвер может выполнить одно из следующих действий:
- Вызовите WdfMemoryCreate или WdfMemoryCreatePreallocated , чтобы создать буфер памяти, если вы хотите, чтобы драйвер передал новый буфер целевому объекту ввода-вывода.
- Вызовите WdfRequestRetrieveInputMemory или WdfRequestRetrieveOutputMemory , чтобы получить дескриптор объекта памяти, который представляет буфер полученного запроса ввода-вывода, если требуется, чтобы драйвер передал содержимое этого буфера целевому объекту ввода-вывода.
Несколько вызовов WdfIoTargetFormatRequestForIoctl , использующих один и тот же запрос, не приводят к выделению дополнительных ресурсов. Таким образом, чтобы снизить вероятность того, что WdfRequestCreate вернет STATUS_INSUFFICIENT_RESOURCES, функция обратного вызова EvtDriverDeviceAdd драйвера может вызвать WdfRequestCreate для предварительного выделения одного или нескольких объектов запроса для устройства. Впоследствии драйвер может повторно использовать (вызвать WdfRequestReuse), переформатировать (вызвать WdfIoTargetFormatRequestForIoctl) и повторно отправить (вызвать WdfRequestSend) каждый объект запроса, не рискуя STATUS_INSUFFICIENT_RESOURCES возвращаемого значения при последующем вызове WdfRequestCreate. Все последующие вызовы WdfIoTargetFormatRequestForIoctl для повторно использованного объекта запроса будут возвращать STATUS_SUCCESS, если значения параметров не изменяются. (Если драйвер не вызывает один и тот же метод форматирования запросов каждый раз, могут быть выделены дополнительные ресурсы. Кроме того, если код элемента управления вводом-выводом указывает тип передачи METHOD_BUFFERED, платформа должна выделить системный буфер для каждого запроса, и это выделение может завершиться ошибкой из-за нехватки ресурсов памяти.)
Сведения о получении сведений о состоянии после завершения запроса ввода-вывода см. в разделе Получение сведений о завершении.
Дополнительные сведения о WdfIoTargetFormatRequestForIoctl см. в разделе Отправка запросов ввода-вывода к общим целевым объектам ввода-вывода.
Дополнительные сведения о целевых объектах ввода-вывода см. в разделе Использование целевых объектов ввода-вывода.
Примеры
Следующий код повторно использует предварительно выделенный объект запроса и предварительно выделенные объекты памяти. В этом примере объекты памяти назначают входные и выходные буферы, форматируют объект запроса, регистрируют функцию обратного вызова CompletionRoutine и отправляют запрос целевому объекту ввода-вывода.
NTSTATUS
NICSendOidRequestToTargetAsync(
IN WDFIOTARGET IoTarget,
IN WDFREQUEST Request,
IN PFILE_OBJECT FileObject,
IN ULONG IoctlControlCode,
IN OUT PVOID InputBuffer,
IN ULONG InputBufferLength,
IN OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength,
OUT PULONG BytesReadOrWritten
)
{
NTSTATUS status;
PREQUEST_CONTEXT reqContext;
WDF_REQUEST_REUSE_PARAMS params;
WDFMEMORY inputMem, outputMem;
WDF_REQUEST_REUSE_PARAMS_INIT(
¶ms,
WDF_REQUEST_REUSE_NO_FLAGS,
STATUS_SUCCESS
);
status = WdfRequestReuse(Request, ¶ms);
if (!NT_SUCCESS(status)){
return status;
}
reqContext = GetRequestContext(Request);
inputMem = outputMem = NULL;
if (InputBuffer != NULL) {
status = WdfMemoryAssignBuffer(
reqContext->InputMemory,
InputBuffer,
InputBufferLength
);
if (!NT_SUCCESS(status)) {
return status;
}
inputMem = reqContext->InputMemory;
}
if (OutputBuffer != NULL) {
status = WdfMemoryAssignBuffer(
reqContext->OutputMemory,
OutputBuffer,
OutputBufferLength
);
if (!NT_SUCCESS(status)) {
return status;
}
outputMem = reqContext->OutputMemory;
}
status = WdfIoTargetFormatRequestForIoctl(
IoTarget,
Request,
IoctlControlCode,
inputMem,
NULL,
outputMem,
NULL
);
if (!NT_SUCCESS(status)) {
return status;
}
WdfRequestSetCompletionRoutine(
Request,
NICSendOidRequestToTargetAsyncCompletionRoutine,
BytesReadOrWritten
);
if (WdfRequestSend(
Request,
IoTarget,
WDF_NO_SEND_OPTIONS
) == FALSE) {
status = WdfRequestGetStatus(Request);
}
return status;
}
Требования
Требование | Значение |
---|---|
Целевая платформа | Универсальное |
Минимальная версия KMDF | 1,0 |
Минимальная версия UMDF | 2,0 |
Верхняя часть | wdfiotarget.h (включая Wdf.h) |
Библиотека | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | <=DISPATCH_LEVEL |
Правила соответствия DDI | DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), RequestFormattedValid(kmdf), RequestSendAndForgetNoFormatting(kmdf), RequestSendAndForgetNoFormatting2(kmdf) |
См. также раздел
WdfIoTargetFormatRequestForInternalIoctl
WdfIoTargetSendIoctlSynchronously