Функция WdfIoTargetSendInternalIoctlSynchronously (wdfiotarget.h)

[Относится только к KMDF]

Метод WdfIoTargetSendInternalIoctlSynchronously создает внутренний запрос на управление устройством и отправляет его синхронно целевому объекту ввода-вывода.

Синтаксис

NTSTATUS WdfIoTargetSendInternalIoctlSynchronously(
  [in]            WDFIOTARGET               IoTarget,
  [in, optional]  WDFREQUEST                Request,
  [in]            ULONG                     IoctlCode,
  [in, optional]  PWDF_MEMORY_DESCRIPTOR    InputBuffer,
  [in, optional]  PWDF_MEMORY_DESCRIPTOR    OutputBuffer,
  [in, optional]  PWDF_REQUEST_SEND_OPTIONS RequestOptions,
  [out, optional] PULONG_PTR                BytesReturned
);

Параметры

[in] IoTarget

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

[in, optional] Request

Дескриптор объекта запроса платформы. Этот параметр является необязательным и может иметь значение NULL. Дополнительные сведения см. в разделе "Примечания".

[in] IoctlCode

Код элемента управления вводом-выводом (IOCTL), поддерживаемый целевым объектом ввода-вывода.

[in, optional] InputBuffer

Указатель на структуру, выделенную вызывающим объектом WDF_MEMORY_DESCRIPTOR , которая описывает буфер, который будет записан в целевой объект ввода-вывода. Дополнительные сведения см. в разделе "Примечания". Этот параметр является необязательным и может иметь значение NULL , если запрос не отправляет данные.

[in, optional] OutputBuffer

Указатель на структуру, выделенную вызывающим объектом WDF_MEMORY_DESCRIPTOR , описывающую буфер, который будет получать данные из целевого объекта ввода-вывода. Дополнительные сведения см. в разделе "Примечания". Этот параметр является необязательным и может иметь значение NULL , если запрос не получает данные.

[in, optional] RequestOptions

Указатель на структуру, выделенную вызывающим объектом, WDF_REQUEST_SEND_OPTIONS , которая задает параметры для запроса. Этот указатель является необязательным и может иметь значение NULL. Дополнительные сведения см. в разделе "Примечания".

[out, optional] BytesReturned

Указатель на расположение, которое получает сведения (например, количество переданных байтов), предоставляемые другим драйвером при выполнении запроса путем вызова WdfRequestCompleteWithInformation. Этот указатель является необязательным и может иметь значение NULL.

Возвращаемое значение

Если операция выполнена успешно, WdfIoTargetSendInternalIoctlSynchronously возвращается после завершения запроса на внутреннее управление устройством, а возвращаемое значение — это значение состояния завершения запроса. В противном случае этот метод может возвращать одно из следующих значений:

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

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

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

Комментарии

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

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

Метод WdfIoTargetSendInternalIoctlSynchronously не возвращается до завершения запроса, если драйвер не предоставляет значение времени ожидания в структуре WDF_REQUEST_SEND_OPTIONS параметра RequestOptions или если не обнаружена ошибка.

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

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

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

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

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

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

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

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

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

  1. Укажите дескриптор запроса NULL для параметра Request метода WdfIoTargetSendInternalIoctlSynchronously или создайте новый объект запроса и укажите его дескриптор:
    • Если вы предоставляете дескриптор запроса NULL , платформа использует внутренний объект запроса. Этот метод прост в использовании, но драйвер не может отменить запрос.
    • При вызове WdfRequestCreate для создания одного или нескольких объектов запроса можно повторно использовать эти объекты запроса, вызвав WdfRequestReuse. Этот метод позволяет функции обратного вызова EvtDriverDeviceAdd драйвера предварительно выделить объекты запроса для устройства. Кроме того, другой поток драйвера может вызвать WdfRequestCancelSentRequest , чтобы при необходимости отменить запрос.

    Драйвер может указать параметр RequestOptions, отличный от NULL, независимо от того, предоставляет ли драйвер параметр запроса, отличный от NULL или NULL. Например, можно использовать параметр RequestOptions , чтобы указать значение времени ожидания.

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

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

    При необходимости платформа преобразует описания буфера так, чтобы они были правильными для типа передачи IOCTL. Дополнительные сведения о типах передачи IOCTL см. в разделе Определение контрольных кодов ввода-вывода.

    Доступны следующие методы указания буферного пространства:

    • Предоставьте локальные буферы.

      Так как WdfIoTargetSendInternalIoctlSynchronously обрабатывает запросы ввода-вывода синхронно, драйвер может создавать буферы запросов, которые являются локальными для вызывающей подпрограммы, как показано в следующем примере кода.

      WDF_MEMORY_DESCRIPTOR  MemoryDescriptor;
      MY_BUFFER_TYPE  MyBuffer;
      WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&MemoryDescriptor,
                                        (PVOID) &MyBuffer,
                                        sizeof(MyBuffer));
      
    • Предоставьте дескрипторы WDFMEMORY.

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

      WDF_MEMORY_DESCRIPTOR  MemoryDescriptor;
      WDFMEMORY  MemoryHandle = NULL;
      status = WdfMemoryCreate(NULL,
                               NonPagedPool,
                               POOL_TAG,
                               MY_BUFFER_SIZE,
                               &MemoryHandle,
                               NULL);
      WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&MemoryDescriptor,
                                        MemoryHandle,
                                        NULL);
      

      Кроме того, драйвер может вызвать WdfRequestRetrieveInputMemory или WdfRequestRetrieveOutputMemory , чтобы получить дескриптор объекта памяти платформы, который представляет буфер полученного запроса ввода-вывода, если требуется, чтобы драйвер передавал содержимое этого буфера целевому объекту ввода-вывода. Драйвер не должен выполнять полученный запрос ввода-вывода, пока новый запрос, который WdfIoTargetSendInternalIoctlSynchronously отправляет в целевой объект ввода-вывода, не будет удален, повторно использован или переформатирован. (WdfIoTargetSendInternalIoctlSynchronous увеличивает число ссылок объекта памяти. Удаление, повторное использование или переформатирование объекта запроса уменьшает количество ссылок на объект памяти.)

    • Предоставление многомерных выражений.

      Драйверы могут получать многомерные списки, связанные с полученным запросом ввода-вывода, путем вызова WdfRequestRetrieveInputWdmMdl и WdfRequestRetrieveOutputWdmMdl.

Сведения о получении сведений о состоянии после завершения запроса ввода-вывода см. в разделе Получение сведений о завершении.

Дополнительные сведения о WdfIoTargetSendInternalIoctlSynchronously см. в разделе Отправка запросов ввода-вывода к общим целевым объектам ввода-вывода.

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

Примеры

В следующем примере кода определяется локальный буфер, инициализируется структура WDF_MEMORY_DESCRIPTOR и вызывается метод WdfIoTargetSendInternalIoctlSynchronously. В этом примере для дескриптора объекта запроса задается значение NULL , поэтому платформа создаст новый объект запроса для целевого объекта ввода-вывода.

WDF_MEMORY_DESCRIPTOR  outputDescriptor;
NTSTATUS  status;
MY_DRIVER_INFORMATION  driverInformation;

WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
                                  &outputDescriptor,
                                  (PVOID) &driverInformation,
                                  sizeof(MY_DRIVER_INFORMATION)
                                  );

status = WdfIoTargetSendInternalIoctlSynchronously(
                                                   hidTarget,
                                                   NULL,
                                                   IOCTL_INTERNAL_GET_MY_DRIVER_INFORMATION,
                                                   NULL,
                                                   &outputDescriptor,
                                                   NULL,
                                                   NULL
                                                   );

Требования

Требование Значение
Целевая платформа Универсальное
Минимальная версия KMDF 1,0
Верхняя часть wdfiotarget.h (включая Wdf.h)
Библиотека Wdf01000.sys (см. раздел Управление версиями библиотеки Платформы).
IRQL PASSIVE_LEVEL
Правила соответствия DDI DeferredRequestCompleted(kmdf), DriverCreate(kmdf), IoctlReqs(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), ReadReqs(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf), WriteReqs(kmdf)

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

EvtDriverDeviceAdd

WDF_MEMORY_DESCRIPTOR

WDF_REQUEST_SEND_OPTIONS

WdfDeviceGetIoTarget

WdfIoTargetCreate

WdfIoTargetFormatRequestForInternalIoctl

WdfIoTargetSendIoctlSynchronously

WdfMemoryCreate

WdfMemoryCreatePreallocated

WdfRequestCancelSentRequest

WdfRequestCompleteWithInformation

WdfRequestCreate

WdfRequestRetrieveInputMemory

WdfRequestRetrieveInputWdmMdl

WdfRequestRetrieveOutputMemory

WdfRequestRetrieveOutputWdmMdl

WdfRequestReuse

WdfRequestSend