Функция WdfIoTargetFormatRequestForInternalIoctl (wdfiotarget.h)
[Применяется только к KMDF]
Метод WdfIoTargetFormatRequestForInternalIoctl создает внутренний запрос на управление устройством для целевого объекта ввода-вывода, но не отправляет запрос.
Синтаксис
NTSTATUS WdfIoTargetFormatRequestForInternalIoctl(
[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, передача данных начинается в начале выходного буфера, а размер передачи равен размеру буфера.
Возвращаемое значение
WdfIoTargetFormatRequestForInternalIoctl возвращает STATUS_SUCCESS, если операция выполнена успешно. В противном случае этот метод может вернуть одно из следующих значений:
Код возврата | Описание |
---|---|
|
Обнаружен недопустимый параметр. |
|
Длина передачи была больше длины буфера, или запрос ввода-вывода уже был поставлен в очередь в целевой объект ввода-вывода. |
|
Платформе не удалось выделить системные ресурсы (обычно это память). |
|
Пакет запроса ввода-вывода (IRP), который представляет параметр Request , не предоставляет достаточно IO_STACK_LOCATION структур, позволяющих драйверу пересылать запрос. |
Этот метод также может возвращать другие значения NTSTATUS.
Ошибка проверка возникает, если драйвер предоставляет недопустимый дескриптор объекта.
Комментарии
Используйте метод WdfIoTargetFormatRequestForInternalIoctl , за которым следует метод WdfRequestSend , чтобы отправлять внутренние запросы управления устройствами синхронно или асинхронно. Кроме того, используйте метод WdfIoTargetSendInternalIoctlSynchronously для синхронной отправки внутренних запросов на управление устройствами.
Дополнительные сведения о внутренних запросах на управление устройствами см. в статье Использование кодов управления вводом-выводом.
Вы можете переслать внутренний запрос на управление устройством, полученный драйвером в очереди ввода-вывода, или создать и отправить новый запрос. В любом случае для платформы требуется объект запроса и некоторое буферное пространство.
Чтобы перенаправить внутренний запрос на управление устройством, полученный драйвером в очереди ввода-вывода, выполните приведенные далее действия.
- Укажите дескриптор полученного запроса для параметра Request метода WdfIoTargetFormatRequestForInternalIoctl.
-
Используйте входной буфер полученного запроса для параметра InputBuffer метода WdfIoTargetFormatRequestForInternalIoctl.
Драйвер должен вызвать WdfRequestRetrieveInputMemory , чтобы получить дескриптор входного буфера запроса, и использовать этот дескриптор в качестве значения inputBuffer.
-
Используйте выходной буфер полученного запроса для параметра OutputBuffer метода WdfIoTargetFormatRequestForInternalIoctl.
Драйвер должен вызвать WdfRequestRetrieveOutputMemory , чтобы получить дескриптор выходного буфера запроса, и использовать этот дескриптор в качестве значения для OutputBuffer.
Драйверы часто делят полученные запросы ввода-вывода на небольшие запросы, отправляемые в целевой объект ввода-вывода, поэтому ваш драйвер может создавать новые запросы.
Чтобы создать новый запрос ввода-вывода, выполните приведенные далее действия.
-
Создайте новый объект запроса и укажите его дескриптор для параметра Request метода WdfIoTargetFormatRequestForInternalIoctl.
Вызовите WdfRequestCreate , чтобы предварительно выделить один или несколько объектов запроса. Эти объекты запросов можно использовать повторно, вызвав WdfRequestReuse. Функция обратного вызова EvtDriverDeviceAdd вашего драйвера может предварительно выделить объекты запросов для устройства.
-
Укажите буферное пространство и укажите дескриптор буфера для параметров InputBuffer и OutputBuffer метода WdfIoTargetFormatRequestForInternalIoctl.
Драйвер должен указать это буферное пространство, так как WDFMEMORY обрабатывает память, управляемую платформой. Драйвер может выполнять одно из следующих действий:
- Вызовите WdfMemoryCreate или WdfMemoryCreatePreallocated , чтобы создать буфер памяти, если требуется, чтобы драйвер передал новый буфер целевому объекту ввода-вывода.
- Вызовите WdfRequestRetrieveInputMemory или WdfRequestRetrieveOutputMemory , чтобы получить дескриптор объекта памяти, представляющего буфер полученного запроса ввода-вывода, если требуется, чтобы драйвер передавал содержимое этого буфера целевому объекту ввода-вывода.
Несколько вызовов WdfIoTargetFormatRequestForInternalIoctl , использующих один и тот же запрос, не приводят к выделению дополнительных ресурсов. Таким образом, чтобы снизить вероятность того, что WdfRequestCreate вернет STATUS_INSUFFICIENT_RESOURCES, функция обратного вызова EvtDriverDeviceAdd драйвера может вызвать WdfRequestCreate для предварительного выделения одного или нескольких объектов запроса для устройства. Впоследствии драйвер может повторно использовать (вызвать WdfRequestReuse), переформатировать (вызвать WdfIoTargetFormatRequestForInternalIoctl) и повторно отправить (вызвать WdfRequestSend) каждый объект запроса без риска STATUS_INSUFFICIENT_RESOURCES возвращаемого значения при последующем вызове WdfRequestCreate. Все последующие вызовы WdfIoTargetFormatRequestForInternalIoctl для повторно использованного объекта запроса будут возвращать STATUS_SUCCESS, если значения параметров не изменяются. (Однако если драйвер не вызывает один и тот же метод форматирования запросов каждый раз, могут быть выделены дополнительные ресурсы. Кроме того, если код элемента управления вводом-выводом указывает тип передачи METHOD_BUFFERED, платформа должна выделить системный буфер для каждого запроса, и это выделение может завершиться ошибкой из-за нехватки ресурсов памяти.)
Сведения о получении сведений о состоянии после завершения запроса ввода-вывода см. в разделе Получение сведений о завершении.
Дополнительные сведения о WdfIoTargetFormatRequestForInternalIoctl см. в разделе Отправка запросов ввода-вывода в общие целевые объекты ввода-вывода.
Дополнительные сведения о целевых объектах ввода-вывода см. в разделе Использование целевых объектов ввода-вывода.
Примеры
В следующем примере кода создается объект памяти платформы, который является дочерним по отношению к объекту запроса. Далее в примере получается буфер, содержащийся в объекте памяти, и инициализируется буфер. Затем пример форматирует запрос, задает функцию обратного вызова CompletionRoutine и отправляет запрос целевому объекту ввода-вывода.
WDF_OBJECT_ATTRIBUTES memoryObjAttr;
WDFMEMORY memory;
NTSTATUS status;
IOCTL_DATA *pIoctlData;
WDF_OBJECT_ATTRIBUTES_INIT(&memoryObjAttr);
memoryObjAttr.ParentObject = Request;
status = WdfMemoryCreate(
&memoryObjAttr,
NonPagedPool,
0,
sizeof(IOCTL_DATA),
&memory,
NULL
);
if (!NT_SUCCESS(status)) {
goto Done;
}
pIoctlData = WdfMemoryGetBuffer(
memory,
NULL
);
RtlZeroMemory(
pIoctlData,
sizeof(IOCTL_DATA)
);
pIoctlData->Member1 = MY_DATA;
status = WdfIoTargetFormatRequestForInternalIoctl(
IoTarget,
Request,
IOCTL_INTERNAL_GET_MY_DATA,
memory,
NULL,
WDF_NO_HANDLE,
NULL
);
if (!NT_SUCCESS(status)) {
goto Done;
}
WdfRequestSetCompletionRoutine(
Request,
MyRequestCompletion,
NULL
);
if (WdfRequestSend(
Request,
IoTarget,
NULL
) == FALSE) {
status = WdfRequestGetStatus(Request);
}
else {
status = STATUS_SUCCESS;
}
Требования
Требование | Значение |
---|---|
Целевая платформа | Универсальное |
Минимальная версия KMDF | 1,0 |
Верхняя часть | wdfiotarget.h (включая Wdf.h) |
Библиотека | Wdf01000.sys (см. раздел Управление версиями библиотеки платформы). |
IRQL | <=DISPATCH_LEVEL |
Правила соответствия DDI | DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), RequestFormattedValid(kmdf), RequestSendAndForgetNoFormatting(kmdf), RequestSendAndForgetNoFormatting2(kmdf) |
См. также раздел
WdfIoTargetFormatRequestForIoctl
WdfIoTargetSendInternalIoctlSynchronously
WdfIoTargetSendIoctlSynchronously