Функция WdfIoTargetSendIoctlSynchronously (wdfiotarget.h)
[Применимо к KMDF и UMDF]
Метод WdfIoTargetSendIoctlSynchronous создает запрос на управление устройством и отправляет его в целевой объект ввода-вывода синхронно.
Синтаксис
NTSTATUS WdfIoTargetSendIoctlSynchronously(
[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.
Возвращаемое значение
Если операция выполнена успешно, WdfIoTargetSendIoctlSynchronous возвращается после завершения запроса на управление устройством, а возвращаемое значение — значение состояния завершения запроса. В противном случае этот метод может вернуть одно из следующих значений:
Возвращаемый код | Описание |
---|---|
|
Обнаружен недопустимый параметр. |
|
Размер структуры WDF_REQUEST_SEND_OPTIONS, на которую указывает параметр RequestOptions, был неверным. |
|
Запрос уже был помещен в очередь в целевой объект ввода-вывода. |
|
Платформа не может выделить системные ресурсы (обычно память). |
|
Пакет запроса ввода-вывода ( |
Этот метод также может возвращать другие значения NTSTATUS.
Ошибка возникает, если драйвер предоставляет недопустимый дескриптор объекта.
Замечания
Используйте метод WdfIoTargetSendIoctlSynchronous для отправки запросов управления устройствами синхронно. Чтобы асинхронно отправлять запросы на управление устройствами, используйте метод WdfIoTargetFormatRequestForIoctl, а затем метод WdfRequestSend.
Дополнительные сведения о запросах управления устройствами см. в разделе использование кодов управления ввода-вывода.
Метод WdfIoTargetSendIoctlSynchronous не возвращается до завершения запроса, если драйвер не предоставляет значение времени ожидания в структуре WDF_REQUEST_SEND_OPTIONS параметра RequestOptionsWDF_REQUEST_SEND_OPTIONS или если не обнаружена ошибка.
Вы можете пересылать запрос на управление устройством, полученный драйвером в очереди ввода-вывода, или создать и отправить новый запрос. В любом случае для платформы требуется объект запроса и некоторое пространство буфера.
Чтобы перенаправить запрос на управление устройствами, полученный драйвером в очереди ввода-вывода:
- Укажите дескриптор полученного запроса для параметра WdfIoTargetSendIoctlSynchronous метода request.
-
Используйте входной буфер полученного запроса для параметра WdfIoTargetSendIoctlSynchronous метода InputBuffer.
Драйвер должен вызвать WdfRequestRetrieveInputMemory, чтобы получить дескриптор объекта памяти платформы, представляющего входной буфер запроса. Затем драйвер должен поместить этот дескриптор в структуру WDF_MEMORY_DESCRIPTOR, которую драйвер предоставляет для параметра InputBufferWdfIoTargetSendIoctlSynchronous.
-
Используйте выходной буфер полученного запроса для параметра WdfIoTargetSendIoctlSynchronous метода OutputBuffer.
Драйвер должен вызвать WdfRequestRetrieveOutputMemory, чтобы получить дескриптор объекта памяти платформы, представляющего выходной буфер запроса. Затем драйвер должен поместить этот дескриптор в структуру WDF_MEMORY_DESCRIPTOR, которую драйвер предоставляет для параметра OutputBufferWdfIoTargetSendIoctlSynchronous.
Драйверы часто делят полученные запросы ввода-вывода на небольшие запросы, которые они отправляют в целевой объект ввода-вывода, поэтому ваш драйвер может создавать новые запросы.
Чтобы создать новый запрос ввода-вывода:
-
Укажите дескриптор запроса NULL WdfIoTargetSendIoctlSynchronous метода request или создайте новый объект запроса и предоставьте его дескриптор:
- Если вы предоставляете дескриптор запроса NULL, платформа использует внутренний объект запроса. Этот метод прост в использовании, но драйвер не может отменить запрос.
- При вызове WdfRequestCreate для создания одного или нескольких объектов запроса можно повторно использовать эти объекты запроса, вызвав WdfRequestReuse. Этот метод позволяет
драйвера EvtDriverDeviceAdd функцию обратного вызова для предварительного размещения объектов запросов для устройства. Кроме того, другой поток драйвера может вызывать WdfRequestCancelSentRequest, чтобы отменить запрос при необходимости.
Драйвер может указать параметр, отличный отNULLRequestOptions, предоставляет ли драйвер параметрNULL или параметр NULLRequest. Например, можно использовать параметр RequestOptions для указания значения времени ожидания.
-
Предоставьте буферное пространство для WdfIoTargetSendIoctlSynchronous метода InputBuffer и OutputBuffer параметры, если запрос требует их.
Драйвер может указать это буферное пространство как локальные выделенные буферы, как дескриптор WDFMEMORY или как списки дескрипторов памяти (MDLs). Вы можете использовать любой метод, наиболее удобный.
При необходимости платформа преобразует описания буфера, чтобы они были правильными для типа передачи IOCTL. Дополнительные сведения о типах передачи IOCTL см. в определении кодов управления ввода-вывода.
Доступны следующие методы указания пространства буфера:
-
Укажите локальные буферы.
Так как WdfIoTargetSendIoctlSynchronous обрабатывает запросы ввода-вывода синхронно, драйвер может создавать буферы запросов, которые являются локальными для вызывающей подпрограммы, как показано в следующем примере кода.
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 для получения дескриптора в объект памяти платформы, представляющий буфер полученного запроса ввода-вывода, если требуется, чтобы драйвер передал содержимое этого буфера целевому объекту ввода-вывода. Драйвер не должен завершить полученный запрос ввода-вывода, пока новый запрос, который WdfIoTargetSendIoctlSynchronous отправляется в целевой объект ввода-вывода, был удален, повторно использован или переформатирован. (WdfIoTargetSendIoctlSynchronous увеличивает количество ссылок объекта памяти. Удаление, повторное использование или переформатирование объекта запроса уменьшает количество ссылок объекта памяти.)
-
Предоставьте многомерные выражения.
Драйверы могут получить многомерные ключи, связанные с полученным запросом ввода-вывода, вызвав WdfRequestRetrieveInputmMdl и WdfRequestRetrieveOutputMdl.
-
Укажите локальные буферы.
Дополнительные сведения о WdfIoTargetSendIoctlSynchronousсм. в отправке запросов ввода-вывода в общие целевые объекты ввода-вывода.
Дополнительные сведения о целевых объектах ввода-вывода см. в разделе Использование целевых объектов ввода-вывода.
Примеры
Следующий пример кода определяет локальный буфер, инициализирует структуру WDF_MEMORY_DESCRIPTOR и вызывает WdfIoTargetSendIoctlSynchronous. В этом примере указывается null для дескриптора объекта запроса, поэтому платформа создаст новый объект запроса для целевого объекта ввода-вывода.
WDF_MEMORY_DESCRIPTOR outputDescriptor;
NTSTATUS status;
HID_COLLECTION_INFORMATION collectionInformation;
WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
&outputDescriptor,
(PVOID) &collectionInformation,
sizeof(HID_COLLECTION_INFORMATION)
);
status = WdfIoTargetSendIoctlSynchronously(
hidTarget,
NULL,
IOCTL_HID_GET_COLLECTION_INFORMATION,
NULL,
&outputDescriptor,
NULL,
NULL
);
Требования
Требование | Ценность |
---|---|
целевая платформа | Всеобщий |
минимальная версия KMDF | 1.0 |
минимальная версия UMDF | 2.0 |
заголовка | wdfiotarget.h (include Wdf.h) |
библиотеки |
Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | PASSIVE_LEVEL |
правил соответствия DDI |
DeferredRequestCompleted(kmdf), DriverCreate(kmdf), InternalIoctlReqs(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), ReadReqs(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf), SyncReqSend(kmdf), WriteReqs(kmdf) |
См. также
WDF_MEMORY_DESCRIPTOR_INIT_BUFFER
WdfIoTargetFormatRequestForIoctl
WdfIoTargetSendInternalIoctlSynchronous
WdfRequestCompleteWithInformation
WdfRequestRetrieveOutputMemory