Синхронная отправка запросов ввода-вывода
В следующей таблице перечислены методы целевого объекта ввода-вывода, которые драйвер может вызывать для синхронной отправки запросов ввода-вывода целевому объекту ввода-вывода. Подробные сведения об использовании этих методов см. на справочных страницах методов.
Метод | Цель |
---|---|
Отправляет запрос на чтение |
|
Отправляет запрос на запись |
|
Отправляет запрос на управление устройством |
|
Отправляет внутренний запрос на управление устройством. |
|
Отправляет нестандартный внутренний запрос на управление устройством. |
Вы также можете отправлять запросы синхронно, вызвав WdfRequestSend, но сначала необходимо отформатировать запрос, следуя правилам, описанным в разделе Асинхронная отправка запросов ввода-вывода.
Синхронную отправку запросов ввода-вывода к целевому объекту ввода-вывода проще программировать, чем асинхронную отправку запросов ввода-вывода. Однако следует использовать следующие рекомендации, чтобы решить, подходит ли синхронный ввод-вывод для вашего драйвера:
Синхронный ввод-вывод можно использовать, если драйвер не отправляет много запросов ввода-вывода и если производительность системы или устройства не снижается, так как драйвер ожидает завершения каждого запроса ввода-вывода.
Если ваш драйвер должен обрабатывать много запросов ввода-вывода за короткие периоды времени, вы, вероятно, не сможете разрешить драйверу ждать завершения каждого запроса перед отправкой следующего запроса. В противном случае драйвер может потерять данные или снизить производительность устройства (и, возможно, всей системы). В таких случаях асинхронный ввод-вывод может быть лучшим выбором.
Синхронный ввод-вывод полезен для обработки операций, которые должны запускаться и заканчиваться без дополнительных параллельных действий. Такие операции могут включать сброс USB-канала или чтение регистров устройств.
В большинстве случаев драйвер должен указывать значение времени ожидания при вызове метода объекта, который отправляет запрос ввода-вывода синхронно. Если драйвер не указывает значение времени ожидания и устройство или драйвер более низкого уровня не отвечает, драйвер может зависнуть. В результате пользователь может столкнуться с неотвеченным приложением. Кроме того, другие драйверы могут не получить системные ресурсы, например рабочие элементы, если драйвер не освобождает их.
Если драйверы выше и ниже в стеке требуют синхронного выполнения операций, драйвер должен использовать синхронные операции ввода-вывода. Поэтому следует изучить требования других драйверов, которые могут существовать в стеке драйверов.
В следующем примере показано, как отправить запрос элемента управления синхронным вводом-выводом (IOCTL):
NTSTATUS status;
WDF_MEMORY_DESCRIPTOR inputDesc, outputDesc;
PWDF_MEMORY_DESCRIPTOR pInputDesc = NULL, pOutputDesc = NULL;
ULONG_PTR bytesReturned;
UNREFERENCED_PARAMETER(FileObject);
if (InputBuffer) {
WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&inputDesc,
InputBuffer,
InputBufferLength);
pInputDesc = &inputDesc;
}
if (OutputBuffer) {
WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputDesc,
OutputBuffer,
OutputBufferLength);
pOutputDesc = &outputDesc;
}
status = WdfIoTargetSendIoctlSynchronously(
IoTarget,
WDF_NO_HANDLE, // Request
IoctlControlCode,
pInputDesc,
pOutputDesc,
NULL, // PWDF_REQUEST_SEND_OPTIONS
&bytesReturned);
if (!NT_SUCCESS(status)) {
DEBUGP(MP_ERROR,
("WdfIoTargetSendIoctlSynchronously failed 0x%x\n",
status));
}
*BytesReadOrWritten = (ULONG)bytesReturned;