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

[Относится к KMDF и UMDF]

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

Синтаксис

NTSTATUS WdfIoTargetSendWriteSynchronously(
  [in]            WDFIOTARGET               IoTarget,
  [in, optional]  WDFREQUEST                Request,
  [in, optional]  PWDF_MEMORY_DESCRIPTOR    InputBuffer,
  [in, optional]  PLONGLONG                 DeviceOffset,
  [in, optional]  PWDF_REQUEST_SEND_OPTIONS RequestOptions,
  [out, optional] PULONG_PTR                BytesWritten
);

Параметры

[in] IoTarget

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

[in, optional] Request

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

[in, optional] InputBuffer

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

[in, optional] DeviceOffset

Указатель на расположение, указывающее начальное смещение для передачи. Целевой объект ввода-вывода (т. е. драйвер следующего уровня ниже) определяет способ использования этого значения. Например, драйверы в стеке драйверов диска могут указывать смещение от начала диска. Целевой объект ввода-вывода получает эти сведения в элементе Parameters.Write.DeviceOffsetструктуры WDF_REQUEST_PARAMETERS запроса. Этот указатель является необязательным. Большинство драйверов устанавливают для этого указателя значение NULL.

[in, optional] RequestOptions

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

[out, optional] BytesWritten

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

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

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

Код возврата Описание
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.

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

Комментарии

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

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

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

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

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

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

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

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

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

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

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

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

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

    При необходимости платформа преобразует описание буфера в то, которое является правильным для метода целевого объекта ввода-вывода для доступа к буферам данных.

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

    • Укажите локальный буфер.

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

      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 , чтобы получить дескриптор для объекта памяти платформы, представляющего входной буфер полученного запроса ввода-вывода, если требуется, чтобы драйвер передавал содержимое этого буфера целевому объекту ввода-вывода. Драйвер не должен выполнять полученный запрос ввода-вывода, пока новый запрос, который WdfIoTargetSendWriteSynchronously отправляет целевому объекту ввода-вывода, не будет удален, повторно использован или переформатирован. (WdfIoTargetSendWriteSynchronous увеличивает количество ссылок объекта памяти. Удаление, повторное использование или переформатирование объекта запроса уменьшает количество ссылок объекта памяти.)

    • Укажите MDL.

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

Некоторые целевые объекты ввода-вывода принимают запросы на запись с буфером нулевой длины. Для таких целевых объектов ввода-вывода драйвер может указать NULL для параметра InputBuffer .

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

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

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

Примеры

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

WDF_MEMORY_DESCRIPTOR  MemoryDescriptor;
WDFMEMORY  MemoryHandle = NULL;
ULONG_PTR  bytesWritten = NULL;

status = WdfMemoryCreate(
                         NULL,
                         NonPagedPool,
                         POOL_TAG,
                         MY_BUFFER_SIZE,
                         &MemoryHandle,
                         NULL
                         );
WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(
                                  &MemoryDescriptor,
                                  MemoryHandle,
                                  NULL
                                  );
status = WdfIoTargetSendWriteSynchronously(
                                          ioTarget,
                                          NULL,
                                          &MemoryDescriptor,
                                          NULL,
                                          NULL,
                                          &bytesWritten
                                          );
 

Требования

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

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

EvtDriverDeviceAdd

WDF_MEMORY_DESCRIPTOR

WDF_MEMORY_DESCRIPTOR_INIT_HANDLE

WDF_REQUEST_PARAMETERS

WDF_REQUEST_SEND_OPTIONS

WdfDeviceGetIoTarget

WdfIoTargetCreate

WdfIoTargetFormatRequestForWrite

WdfMemoryCreate

WdfMemoryCreatePreallocated

WdfRequestCancelSentRequest

WdfRequestCreate

WdfRequestRetrieveInputMemory

WdfRequestRetrieveInputWdmMdl

WdfRequestReuse

WdfRequestSend