Функция WdfUsbTargetPipeWriteSynchronously (wdfusb.h)
[Применимо к KMDF и UMDF]
Метод WdfUsbTargetPipeWriteSynchronous создает запрос на запись и отправляет его синхронно в указанный usb-выходной канал.
Синтаксис
NTSTATUS WdfUsbTargetPipeWriteSynchronously(
[in] WDFUSBPIPE Pipe,
[in, optional] WDFREQUEST Request,
[in, optional] PWDF_REQUEST_SEND_OPTIONS RequestOptions,
[in, optional] PWDF_MEMORY_DESCRIPTOR MemoryDescriptor,
[out, optional] PULONG BytesWritten
);
Параметры
[in] Pipe
Дескриптор объекта канала платформы, полученный путем вызова WdfUsbInterfaceGetConfiguredPipe.
[in, optional] Request
Дескриптор объекта запроса платформы. Этот параметр является необязательным и может быть null. Дополнительные сведения см. в следующем разделе "Примечания".
[in, optional] RequestOptions
Указатель на структуру, выделенную вызывающим объектом, WDF_REQUEST_SEND_OPTIONS, которая задает параметры запроса. Этот указатель необязателен и может быть null. Дополнительные сведения см. в следующем разделе "Примечания".
[in, optional] MemoryDescriptor
Указатель на выделенную вызывающим WDF_MEMORY_DESCRIPTOR структуру, описывающую буфер, содержащий данные, которые будут записаны на устройство. Дополнительные сведения об этом буфере см. в следующем разделе "Примечания".
[out, optional] BytesWritten
Указатель на расположение, которое получает число записанных байтов, если операция выполнена успешно. Этот параметр является необязательным и может быть null.
Возвращаемое значение
WdfUsbTargetPipeWriteSynchronous возвращает значение состояния завершения целевого объекта ввода-вывода, если операция завершается успешно. В противном случае этот метод может вернуть одно из следующих значений:
Возвращаемый код | Описание |
---|---|
|
Размер структуры |
|
Обнаружен недопустимый параметр. |
|
Недостаточно памяти было доступно. |
|
IrQL вызывающего объекта не был PASSIVE_LEVEL, указан недопустимый дескриптор памяти, тип канала недействителен, направление передачи было недопустимым, или указанный запрос ввода-вывода уже помещался в целевой объект ввода-вывода. |
|
Драйвер предоставил значение времени ожидания и запрос не завершился в течение выделенного времени. |
|
Пакет запроса ввода-вывода ( |
Этот метод также может возвращать другие значения NTSTATUS.
Ошибка возникает, если драйвер предоставляет недопустимый дескриптор объекта.
Замечания
Используйте метод WdfUsbTargetPipeWriteSynchronous для отправки запросов на запись синхронно. Чтобы асинхронно отправлять запросы на запись, используйте WdfUsbTargetPipeFormatRequestForWrite, а затем WdfRequestSend.
Указанный канал должен быть выходным, а тип
Метод WdfUsbTargetPipeWriteSynchronous не возвращается до завершения запроса, если драйвер не предоставляет значение времени ожидания в структуре RequestOptions параметра WDF_REQUEST_SEND_OPTIONS или если не обнаружена ошибка.
Вы можете пересылать запрос ввода-вывода, полученный драйвером в очереди ввода-вывода, или создать и отправить новый запрос. В любом случае для платформы требуется объект запроса и некоторое пространство буфера.
Чтобы перенаправить запрос ввода-вывода, полученный драйвером в очереди ввода-вывода:
-
Укажите дескриптор полученного запроса для параметра запроса
. -
Используйте входной буфер полученного запроса для параметра MemoryDescriptor.
Драйвер должен вызвать WdfRequestRetrieveInputMemory, чтобы получить дескриптор объекта памяти платформы, представляющего входной буфер запроса, а затем поместить его в структуру WDF_MEMORY_DESCRIPTOR, на которую MemoryDescriptor указывает.
Драйверы часто делят полученные запросы ввода-вывода на небольшие запросы, которые они отправляют в целевой объект ввода-вывода, поэтому ваш драйвер может создавать новые запросы.
Чтобы создать новый запрос ввода-вывода:
-
Укажите дескриптор запроса NULL для параметра WdfUsbTargetPipeWriteSynchronous метода request или создайте новый объект запроса и предоставьте его дескриптор:
- Если вы предоставляете дескриптор запроса NULL, платформа использует внутренний объект запроса. Этот метод прост в использовании, но драйвер не может отменить запрос.
- При вызове WdfRequestCreate для создания одного или нескольких объектов запроса можно повторно использовать эти объекты запроса, вызвав WdfRequestReuse. Этот метод позволяет
драйвера EvtDriverDeviceAdd функцию обратного вызова для предварительного размещения объектов запросов для устройства. Кроме того, другой поток драйвера может вызывать WdfRequestCancelSentRequest, чтобы отменить запрос при необходимости.
Драйвер может указать параметр, отличный отNULLRequestOptions, предоставляет ли драйвер параметрNULL или параметр NULLRequest. Например, можно использовать параметр RequestOptions для указания значения времени ожидания.
-
Предоставьте буферное пространство для параметра memoryDescriptor метода WdfUsbTargetPipeWriteSynchronous.
Драйвер может указать это буферное пространство в качестве локально выделенного буфера, в качестве дескриптора WDFMEMORY или в виде MDL. Вы можете использовать любой метод, наиболее удобный.
При необходимости платформа преобразует описание буфера в то, что правильно для метода целевого объекта ввода-вывода для доступа к буферам данных.
Доступны следующие методы:
-
Укажите локальный буфер
Так как WdfUsbTargetPipeWriteSynchronous обрабатывает запросы ввода-вывода синхронно, драйвер может создавать буферы запросов, которые являются локальными для вызывающей подпрограммы, как показано в следующем примере кода.
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 для получения дескриптора к объекту памяти платформы, представляющего входной буфер запроса ввода-вывода, если требуется передать содержимое этого буфера целевому объекту ввода-вывода. Драйвер не должен завершить полученный запрос ввода-вывода, пока новый запрос, который WdfUsbTargetPipeWriteWriteSynchronous отправляется в целевой объект ввода-вывода, был удален, повторно использован или переформатирован. (WdfUsbTargetPipeWriteSynchronous увеличивает количество ссылок объекта памяти. Удаление, повторное использование или переформатирование объекта запроса уменьшает количество ссылок объекта памяти.)
-
Укажите MDL
Драйверы могут получить MDL, связанный с полученным запросом ввода-вывода, вызвав WdfRequestRetrieveInputWdmMdl.
-
Укажите локальный буфер
Дополнительные сведения о методе WdfUsbTargetPipeWriteSynchronous и целевых объектов usb-ввода-вывода см. в целевых объектов USB-ввода-вывода.
Примеры
В следующем примере кода создается объект памяти, получает указатель на буфер объекта, заполняет буфер и использует буфер в качестве входных данных для WdfUsbTargetPipeWriteSynchronous.
WDF_MEMORY_DESCRIPTOR writeBufDesc;
WDFMEMORY wdfMemory;
ULONG writeSize, bytesWritten;
size_t bufferSize;
NTSTATUS status;
writeSize = SMALL_BUF_LEN;
status = WdfMemoryCreate(
WDF_NO_OBJECT_ATTRIBUTES,
NonPagedPool,
0,
writeSize,
&wdfMemory,
NULL
);
if (!NT_SUCCESS(status)){
return status;
}
writeBuffer = WdfMemoryGetBuffer(
wdfMemory,
&bufferSize
);
FillMyBuffer(
writeBuffer,
writeSize
);
WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
&writeBufDesc,
writeBuffer,
writeSize
);
status = WdfUsbTargetPipeWriteSynchronously(
pipeHandle,
NULL,
NULL,
&writeBufDesc,
&bytesWritten
);
Требования
Требование | Ценность |
---|---|
целевая платформа | Всеобщий |
минимальная версия KMDF | 1.0 |
минимальная версия UMDF | 2.0 |
заголовка | wdfusb.h (include Wdfusb.h) |
библиотеки |
Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | PASSIVE_LEVEL |
правил соответствия DDI |
DriverCreate(kmdf), InternalIoctlReqs(kmdf), IoctlReqs(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExpExplicit(kmdf), ReadReqs(kmdf), SyncReqSend(kmdf), UsbKmdfIrql(kmdf), UsbKmdfIrql2(kmdf), UsbKmdfIrqlExplicit(kmdf) |