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


Функция 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, если операция выполнена успешно. В противном случае этот метод может вернуть одно из следующих значений:

Код возврата Описание
STATUS_INVALID_PARAMETER
Обнаружен недопустимый параметр.
STATUS_INVALID_DEVICE_REQUEST
Длина передачи была больше длины буфера, или запрос ввода-вывода уже был поставлен в очередь в целевой объект ввода-вывода.
STATUS_INSUFFICIENT_RESOURCES
Платформе не удалось выделить системные ресурсы (обычно это память).
STATUS_REQUEST_NOT_ACCEPTED
Пакет запроса ввода-вывода (IRP), который представляет параметр Request , не предоставляет достаточно IO_STACK_LOCATION структур, позволяющих драйверу пересылать запрос.
 

Этот метод также может возвращать другие значения NTSTATUS.

Ошибка проверка возникает, если драйвер предоставляет недопустимый дескриптор объекта.

Комментарии

Используйте метод WdfIoTargetFormatRequestForInternalIoctl , за которым следует метод WdfRequestSend , чтобы отправлять внутренние запросы управления устройствами синхронно или асинхронно. Кроме того, используйте метод WdfIoTargetSendInternalIoctlSynchronously для синхронной отправки внутренних запросов на управление устройствами.

Дополнительные сведения о внутренних запросах на управление устройствами см. в статье Использование кодов управления вводом-выводом.

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

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

  1. Укажите дескриптор полученного запроса для параметра Request метода WdfIoTargetFormatRequestForInternalIoctl.
  2. Используйте входной буфер полученного запроса для параметра InputBuffer метода WdfIoTargetFormatRequestForInternalIoctl.

    Драйвер должен вызвать WdfRequestRetrieveInputMemory , чтобы получить дескриптор входного буфера запроса, и использовать этот дескриптор в качестве значения inputBuffer.

  3. Используйте выходной буфер полученного запроса для параметра OutputBuffer метода WdfIoTargetFormatRequestForInternalIoctl.

    Драйвер должен вызвать WdfRequestRetrieveOutputMemory , чтобы получить дескриптор выходного буфера запроса, и использовать этот дескриптор в качестве значения для OutputBuffer.

Дополнительные сведения о переадресации запроса ввода-вывода см. в разделе Переадресация запросов ввода-вывода.

Драйверы часто делят полученные запросы ввода-вывода на небольшие запросы, отправляемые в целевой объект ввода-вывода, поэтому ваш драйвер может создавать новые запросы.

Чтобы создать новый запрос ввода-вывода, выполните приведенные далее действия.

  1. Создайте новый объект запроса и укажите его дескриптор для параметра Request метода WdfIoTargetFormatRequestForInternalIoctl.

    Вызовите WdfRequestCreate , чтобы предварительно выделить один или несколько объектов запроса. Эти объекты запросов можно использовать повторно, вызвав WdfRequestReuse. Функция обратного вызова EvtDriverDeviceAdd вашего драйвера может предварительно выделить объекты запросов для устройства.

  2. Укажите буферное пространство и укажите дескриптор буфера для параметров InputBuffer и OutputBuffer метода WdfIoTargetFormatRequestForInternalIoctl.

    Драйвер должен указать это буферное пространство, так как WDFMEMORY обрабатывает память, управляемую платформой. Драйвер может выполнять одно из следующих действий:

    • Вызовите WdfMemoryCreate или WdfMemoryCreatePreallocated , чтобы создать буфер памяти, если требуется, чтобы драйвер передал новый буфер целевому объекту ввода-вывода.
    • Вызовите WdfRequestRetrieveInputMemory или WdfRequestRetrieveOutputMemory , чтобы получить дескриптор объекта памяти, представляющего буфер полученного запроса ввода-вывода, если требуется, чтобы драйвер передавал содержимое этого буфера целевому объекту ввода-вывода.
    Обратите внимание, что если драйвер вызывает WdfRequestRetrieveInputMemory или WdfRequestRetrieveOutputMemory и передает дескриптор памяти в WdfIoTargetFormatRequestForInternalIoctl, драйвер не должен завершить полученный запрос ввода-вывода до тех пор, пока драйвер не удалит, повторно использует или переформатирует новый созданный драйвером объект запроса. (WdfIoTargetFormatRequestForInternalIoctl увеличивает количество ссылок объекта памяти. Удаление, повторное использование или переформатирование объекта запроса уменьшает количество ссылок объекта памяти.)
После того как драйвер вызывает WdfIoTargetFormatRequestForInternalIoctl для форматирования запроса на управление устройством, драйвер должен вызвать WdfRequestSend для отправки запроса (синхронно или асинхронно) целевому объекту ввода-вывода.

Несколько вызовов 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)

См. также раздел

EvtDriverDeviceAdd

WDFMEMORY_OFFSET

WdfDeviceGetIoTarget

WdfIoTargetCreate

WdfIoTargetFormatRequestForIoctl

WdfIoTargetSendInternalIoctlSynchronously

WdfIoTargetSendIoctlSynchronously

WdfMemoryCreate

WdfMemoryCreatePreallocated

WdfRequestCreate

WdfRequestRetrieveInputMemory

WdfRequestRetrieveOutputMemory

WdfRequestReuse

WdfRequestSend