Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Предупреждение
UMDF 2 является последней версией UMDF и заменяет UMDF 1. Все новые драйверы UMDF должны быть написаны с помощью UMDF 2. Новые функции не добавляются в UMDF 1, а поддержка UMDF 1 в более новых версиях Windows 10 ограничена. Универсальные драйверы Windows должны использовать UMDF 2.
Архивные примеры UMDF 1 можно найти в Windows 11, версии 22H2 — обновление примеров драйверов от мая 2022 года.
Дополнительные сведения см. в статье "Начало работы с UMDF".
Предупреждение
См. также раздел "Поддержка клиентов Kernel-Mode" в UMDF 2.x.
UMDF версии 1.9 и более поздних версий позволяют драйверам UMDF поддерживать клиенты в режиме ядра. Клиент в режиме ядра может быть следующим:
Драйвер режима ядра, который существует над драйвером UMDF в стеке драйверов устройства.
Драйвер режима ядра для одного стека устройств, который поддерживает одно устройство, открывает дескриптор для другого устройства, а стек драйверов последнего устройства содержит драйвер UMDF.
Другими словами, драйвер UMDF, поддерживающий клиенты в режиме ядра, может получать запросы ввода-вывода от драйвера режима ядра. Драйвер режима ядра может пересылать запросы ввода-вывода, полученные из приложения пользовательского режима, или создавать новые запросы ввода-вывода и отправлять их в драйвер пользовательского режима.
Чтобы определить, должен ли драйвер UMDF поддерживать клиенты в режиме ядра, необходимо понять стек драйверов, в который будет добавлен драйвер, и где будет находиться драйвер. Кроме того, необходимо определить, может ли драйвер из другого стека отправлять запросы ввода-вывода на устройство драйвера.
Драйвер должен поддерживать клиенты в режиме ядра, если:
Драйвер в режиме ядра может находиться непосредственно над драйвером UMDF в стеке драйверов. Например, драйвер фильтра в режиме ядра может находиться непосредственно над драйвером функции на основе UMDF.
Драйвер режима ядра из другого стека может отправлять запросы ввода-вывода на устройство драйвера. Например, ваш драйвер может создать символьную ссылку, которую драйвер в режиме ядра в другом стеке может использовать для открытия дескриптора на устройстве вашего драйвера. Затем драйвер режима ядра может отправлять запросы ввода-вывода на устройство.
Поддержка клиентов в режиме ядра в драйвере UMDF
Драйвер UMDF может получать запросы ввода-вывода от драйвера режима ядра, только если драйвер UMDF включил поддержку клиентов в режиме ядра. Кроме того, если установка устройства пытается загрузить драйверы в режиме ядра над драйвером UMDF в стеке драйверов устройства, платформа позволяет драйверам загружаться только в том случае, если драйвер UMDF включил поддержку клиентов в режиме ядра.
Чтобы включить поддержку драйвера UMDF для клиентов в режиме ядра, INF-файл драйвера UMDF должен содержать директиву UmdfKernelModeClientPolicy в разделе INF-DDInstallWDF. Если INF-файл драйвера UMDF не включает эту директиву, UMDF не разрешает запуск драйвера в режиме ядра, установленного над драйвером UMDF.
Платформа предоставляет два метода, которые полезны для драйверов, поддерживающих клиенты в режиме ядра. Драйвер может вызвать метод IWDFIoRequest2::GetRequestorMode , чтобы определить, поступил ли запрос ввода-вывода из режима ядра или пользовательского режима. Если запрос ввода-вывода поступил из пользовательского режима, драйвер может вызвать IWDFIoRequest2::IsFromUserModeDriver , чтобы определить, поступил ли запрос из приложения или другого драйвера пользовательского режима.
Ограничения драйверов в режиме ядра
Драйвер UMDF может обрабатывать запросы ввода-вывода из драйвера режима ядра, только если драйвер режима ядра соответствует следующим требованиям:
Драйвер режима ядра должен работать на уровне IRQL = PASSIVE_LEVEL при отправке запроса на ввод-вывод.
Если драйвер не установил директиву INF UmdfFileObjectPolicy в значение AllowNullAndUnknownFileObjects, каждый запрос ввода-вывода, который драйвер режима ядра отправляет драйверу пользовательского режима, должен иметь связанный объект файла. Платформа должна быть ранее уведомлена о том, что диспетчер ввода-вывода создал объект файла. (Такое уведомление заставляет платформу вызвать необязательную функцию обратного вызова IQueueCallbackCreate::OnCreateFile в режиме пользователя драйвера.)
Запрос ввода-вывода не может содержать код функции IRP_MJ_INTERNAL_DEVICE_CONTROL.
Буферы запроса ввода-вывода не должны содержать указатели на дополнительные сведения, так как драйвер пользовательского режима не может разыменовывать указатели.
Если запрос ввода-вывода содержит код управления вводом-выводом , который указывает метод доступа к буферу 'ни тот, ни другой', драйвер режима ядра должен отправить запрос ввода-вывода в контексте процесса приложения, создавшего этот запрос. Дополнительные сведения о поддержке метода "ни один" в базовом драйвере UMDF см. в статье "Использование не буферизованного ввода-вывода или прямого ввода-вывода" в драйверах UMDF.
Драйвер UMDF может изменить выходные данные запроса ввода-вывода в пользовательском режиме. Таким образом, драйвер режима ядра должен проверить все выходные данные, полученные из драйвера пользовательского режима.
Клиент режима ядра обычно должен проверять значение Information, которое драйвер UMDF передает в IWDFIoRequest::CompleteWithInformation. Если клиент является драйвером KMDF, он может вызывать WdfRequestGetCompletionParams, чтобы получить эти сведения в структуре IO_STATUS_BLOCK.
Как правило, платформа не проверяет значение информации, которое драйвер UMDF передает iWDFIoRequest::CompleteWithInformation. (Обычно этот параметр указывает количество переданных байтов.) Платформа проверяет значение информации только для выходных буферов и только для метода доступа к данным буферизованного ввода-вывода. (Например, платформа проверяет, что количество передаваемых байтов не превышает размер выходного буфера операции чтения, если метод доступа буферен ввода-вывода.)
Обработка возвращаемых значений состояния в драйвере UMDF 1.x
Передача значений состояния возврата из пользовательского режима в режим ядра требует особого внимания, как показано ниже.
Драйверы UMDF версии 1 обычно получают возвращаемые значения HRESULT, а драйверы режима ядра на основе KMDF и WDM обычно получают значения типа NTSTATUS. Драйвер UMDF 1.x завершает запрос ввода-вывода, и если у драйвера есть клиент в режиме ядра, то вызов драйвера к IWDFIoRequest::Complete или IWDFIoRequest::CompleteWithInformation должен указать значение HRESULT, которое драйвер генерирует из значения NTSTATUS. Как правило, драйверы UMDF версии 1.x должны использовать макрос HRESULT_FROM_NT (определенный в Winerror.h), чтобы возвращать статус клиенту, работающему в режиме ядра. В следующем примере показано, как использовать этот макрос при выполнении запроса.
hr = HRESULT_FROM_NT(STATUS_BUFFER_OVERFLOW) request->Complete(HRESULT_FROM_NT(STATUS_BUFFER_OVERFLOW); return hr;Чтобы вернуть определенное значение HRESULT клиенту в режиме ядра, следующие обратные вызовы должны использовать макрос HRESULT_FROM_NT:
- IPnpCallback::OnQueryRemove
- IPnpCallback::OnQueryStop
- IPnpCallbackHardware::OnPrepareHardware
- IPnpCallbackHardware::OnReleaseHardware
Чтобы использовать значения NTSTATUS, определенные в ntstatus.h, UMDF 1. Драйвер x должен включать эти две строки, прежде чем включать дополнительные заголовки.
#define UMDF_USING_NTSTATUS #include <ntstatus.h>Не используйте макрос HRESULT_FROM_NT для преобразования STATUS_SUCCESS из значения NTSTATUS в значение HRESULT. Просто верните S_OK, как показано в следующем примере.
request->Complete(S_OK);Платформа завершает некоторые запросы ввода-вывода от имени драйверов UMDF. Иногда фреймворк не преобразует возвращаемые значения типа HRESULT в эквивалентные значения NTSTATUS, поэтому он может передавать статус завершения типа HRESULT клиенту режима ядра.
Из-за этой ситуации клиенты в режиме ядра не должны использовать макрос NT_ERROR при тестировании состояния завершения запроса ввода-вывода, так как макрос NT_ERROR не возвращает значение TRUE для значений ошибок HRESULT. Драйверы режима ядра должны использовать макрос NT_SUCCESS при тестировании состояния завершения запроса ввода-вывода.
Поддержка клиентов в режиме ядра в более ранних версиях UMDF
Для версий UMDF, предшествующих версии 1.9, INF-файл драйвера может включать директиву INF AddReg для создания значения реестра REG_DWORD размера UpperDriverOk в подразделе WUDFаппаратного ключа устройства.
Если для параметра реестра UpperDriverOk задано ненулевое число, платформа позволяет драйверам режима ядра загружаться над драйвером пользовательского режима. Драйверы режима ядра могут пересылать запросы ввода-вывода из приложений пользовательского режима в драйвер UMDF, но драйверы режима ядра не могут отправлять запросы ввода-вывода, созданные в режиме ядра, драйверу UMDF.
Для версий UMDF версии 1.9 и более поздних версий значение реестра UpperDriverOk устарело и поддерживается только для существующих драйверов. Новые драйверы должны использовать директиву UmdfKernelModeClientPolicy .