Поделиться через


Изоляция пакета драйвера

Изоляция пакетов драйверов — это требование для драйверов Windows, что повышает устойчивость пакетов драйверов к внешним изменениям, упрощает обновление и упрощает установку.

Примечание.

Хотя изоляция пакетов драйверов требуется для драйверов Windows, драйверы классических приложений Windows по-прежнему получают преимущества благодаря улучшенной устойчивости и доступности обслуживания.

В следующей таблице приведены примеры устаревших методов пакета драйверов, которые больше не разрешены для драйверов Windows в левом столбце, а также необходимое поведение для драйверов Windows в правом столбце.

Неизолированные драйверы Изолированный драйвер
INF копирует файлы в %windir%\System32 или %windir%\System32\drivers Файлы драйверов запускаются из хранилища драйверов
Взаимодействует с стеками устройств и драйверами с помощью жестко закодированных путей Взаимодействует с стеками устройств и драйверами с помощью системных функций или интерфейсов устройств
Путь жесткого кода к расположениям глобального реестра Использует функции HKR и системные функции для относительного расположения реестра и состояния файлов
Файл среды выполнения записывает данные в любое расположение Файлы записываются относительно расположений, предоставляемых операционной системой

Сведения о том, соответствует ли пакет драйвера требованиям к изоляции пакетов драйверов, см. в разделе "Проверка драйверов Windows". Примеры обновления INF для соответствия требованиям к изоляции пакета драйверов см. в статье Перенос INF для выполнения изоляции пакета драйвера.

Запуск из хранилища драйверов

Все изолированные пакеты драйверов покидают файлы пакетов драйверов в хранилище драйверов. Это означает, что они указывают DIRID 13 в их INF, чтобы указать расположение для файлов пакетов драйверов при установке. Дополнительные сведения о том, как использовать это в пакете драйверов, см. в разделе "Запуск из хранилища драйверов".

Чтение и запись состояния

Примечание.

Если компонент использует свойства интерфейса устройства или устройства для хранения состояния, продолжайте использовать этот метод и соответствующий API ОС для хранения и доступа к состоянию. Следующие рекомендации по состоянию реестра и файла предназначены для другого состояния, которое должно храниться компонентом.

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

В этом разделе содержатся следующие подразделы:

Состояние реестра

В этом разделе содержатся следующие подразделы:

Состояние реестра устройств PnP

Изолированные пакеты драйверов и компоненты пользовательского режима обычно используют одно из двух расположений для хранения состояния устройства в реестре. Это аппаратный ключ (ключ устройства) для устройства и программный ключ (ключ драйвера) для устройства. Аппаратный ключ обычно предназначен для параметров, связанных с взаимодействием отдельного экземпляра устройства с оборудованием. Например, чтобы включить функцию оборудования или поместить оборудование в определенный режим. Ключ программного обеспечения обычно предназначен для параметров, связанных с взаимодействием отдельного экземпляра устройства с системой и другим программным обеспечением. Например, чтобы настроить расположение файла данных, взаимодействовать с платформой или получать доступ к параметрам приложения для устройства. Чтобы получить дескриптор в этих расположениях реестра, используйте один из следующих вариантов:

[ExampleDDInstall.HW]
AddReg = Example_DDInstall.AddReg

[Example_DDInstall.AddReg] 
HKR,,ExampleValue,,%13%\ExampleFile.dll

Состояние реестра интерфейсов устройств

Для чтения и записи состояния реестра интерфейсов устройств используйте один из следующих вариантов:

Состояние реестра служб

Состояние службы должно быть классифицировано по одной из 3 категорий

Неизменяемое состояние реестра служб

Неизменяемое состояние службы — это состояние, предоставляемое пакетом драйвера, который устанавливает службу. Эти значения реестра, заданные INF для служб драйвера и Win32, должны храниться в подразделе "Параметры" службы, предоставив строку HKR в разделе AddReg , а затем ссылаясь на этот раздел в разделе установки службы в INF. Например:

[ExampleDDInstall.Services]
Addservice = ExampleService, 0x2, Example_Service_Inst

[Example_Service_Inst]
DisplayName    = %ExampleService.SvcDesc%
ServiceType    = 1
StartType      = 3
ErrorControl   = 1
ServiceBinary  = %13%\ExampleService.sys
AddReg=Example_Service_Inst.AddReg

[Example_Service_Inst.AddReg]
HKR, Parameters, ExampleValue, 0x00010001, 1

Чтобы получить доступ к расположению этого состояния из службы во время выполнения, используйте одну из следующих функций:

Эти значения реестра, предоставленные INF в подразделе "Параметры" для службы, должны быть прочитаны только во время выполнения и не изменены. Их следует рассматривать только как чтение.

Если значения реестра, предоставленные INF, являются параметрами по умолчанию, которые могут быть перезаписаны во время выполнения, значения переопределения должны быть записаны в состояние внутреннего реестра служб или состояние реестра общих служб для службы. При получении параметров этот параметр можно сначала найти в изменяемом состоянии. Если он не существует, то параметр можно найти в неизменяемом состоянии. RtlQueryRegistryValueWithFallback можно использовать для справки по параметрам запроса, таким как они имеют переопределение и значение по умолчанию.

Состояние внутреннего реестра служб

Внутреннее состояние службы — это состояние, которое записывается во время выполнения и управляется только самой службой и доступно только для этой службы. Чтобы получить доступ к расположению для внутреннего состояния службы, используйте одну из следующих функций из службы:

Если служба хочет разрешить другим компонентам изменять эти параметры, служба должна предоставить интерфейс, в который может вызвать другой компонент, который сообщает службе, как изменить эти параметры. Например, служба Win32 может предоставлять интерфейс COM или RPC, а служба драйверов может предоставлять интерфейс IOCTL через интерфейс устройства.

Состояние реестра общих служб

Состояние общей службы — это состояние, записанное во время выполнения и совместное использование с другими компонентами пользовательского режима, если они достаточно привилегированны. Чтобы получить доступ к расположению для этого состояния общей службы, используйте одну из следующих функций:

Состояние файла

В этом разделе содержатся следующие подразделы:

Состояние файла устройства

Если файлы, связанные с устройством, необходимо записать во время выполнения, эти файлы должны храниться относительно дескриптора или пути к файлу, предоставленному через API ОС. Файлы конфигурации, относящиеся к устройству, являются одним из примеров того, какие типы файлов следует хранить здесь. Чтобы получить доступ к расположению этого состояния, используйте одну из этих функций из службы:

Состояние файла службы

Состояние файла службы можно классифицировать по одной из 3 категорий

Неизменяемое состояние файла службы

Неизменяемое состояние файла службы — это файлы, которые являются частью пакета драйвера. Дополнительные сведения о доступе к этим файлам см. в разделе "Запуск из хранилища драйверов".

Состояние внутреннего файла службы

Внутреннее состояние файла службы — это состояние, которое записывается во время выполнения и управляется только самой службой и доступно только для этой службы. Чтобы получить доступ к расположению для внутреннего состояния службы, используйте одну из следующих функций из службы:

Если служба хочет разрешить другим компонентам изменять эти параметры, служба должна предоставить интерфейс, в который может вызвать другой компонент, который сообщает службе, как изменить эти параметры. Например, служба Win32 может предоставлять интерфейс COM или RPC, а служба драйверов может предоставлять интерфейс IOCTL через интерфейс устройства.

Состояние файла общей службы

Состояние файла общей службы — это состояние, записанное во время выполнения и совместное использование с другими компонентами режима пользователя, если они достаточно привилегированны. Чтобы получить доступ к расположению для этого состояния общей службы, используйте одну из следующих функций:

DriverData и ProgramData

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

Эти расположения предлагают компоненты для записи временного состояния или состояния, которое предназначено для использования другими компонентами и потенциально собранных и скопированных из системы для обработки другой системой. Например, пользовательские файлы журнала или аварийные дампы соответствуют этому описанию.

Избегайте записи файлов в корне DriverData каталогов или ProgramData каталогов. Вместо этого создайте подкаталог с именем вашей компании, а затем напишите файлы и дополнительные подкаталоги в этом каталоге.

Например, для имени компании Contoso драйвер в режиме ядра может записывать настраиваемый журнал\DriverData\Contoso\Logs, а приложение пользовательского режима может собирать или анализировать файлы журналов.%DriverData%\Contoso\Logs

DriverData

Каталог DriverData доступен в Windows 10 версии 1803 и более поздних версий и доступен администраторам и драйверам UMDF.

Драйверы режима ядра обращаются к DriverData каталогу с помощью символьной ссылки \DriverData, предоставленной системой.

Программы пользовательского режима получают доступ к DriverData каталогу с помощью переменной %DriverData%среды.

ProgramData

Переменная %ProgramData% среды пользовательского режима доступна для компонентов пользовательского режима, используемых при хранении данных.

Временные файлы

Временные файлы обычно используются в промежуточных операциях. Их можно записать в вложенный путь в %TEMP% переменных или %TMP% переменных среды. Так как доступ к этим расположениям осуществляется через переменные среды, эта возможность ограничена компонентами пользовательского режима. По времени существования или сохраняемости этих временных файлов после закрытия дескрипторов не существует никаких гарантий. Операционная система или пользователь могут удалять их в любое время, и они могут не сохраняться во время перезагрузки.

Избегайте записи файлов в корне %TEMP% каталогов или %TMP% каталогов. Вместо этого создайте подкаталог с именем вашей компании, а затем напишите файлы и дополнительные подкаталоги в этом каталоге.

Состояние свойства

Устройства и интерфейсы устройств поддерживают хранение состояния с помощью модели свойств PnP. Модель свойств позволяет хранить структурированные данные свойств в интерфейсе устройства или устройства. Это предназначено для небольших данных, которые достаточно подходят для типов свойств, поддерживаемых моделью свойств.

Для доступа к свойствам устройства эти API можно использовать:

Для доступа к свойствам интерфейса устройства эти API можно использовать:

Использование интерфейсов устройств

Если драйвер хочет разрешить другим компонентам считывать или изменять внутреннее состояние драйвера, драйвер должен предоставить интерфейс, в который может вызвать другой компонент, который сообщает драйверу, какие параметры следует возвращать или как изменять определенные параметры. Например, служба драйверов может предоставлять интерфейс IOCTL через интерфейс устройства.

Как правило, драйвер, принадлежащий состоянию, предоставляет интерфейс устройства в пользовательском классе интерфейса устройства. Когда драйвер готов к доступу к состоянию других компонентов, он включает интерфейс. Чтобы получать уведомления о включении интерфейса устройства, компоненты пользовательского режима могут регистрироваться для уведомлений о прибытии интерфейса устройства и компонентах режима ядра с помощью IoRegisterPlugPlayNotification. Чтобы эти компоненты могли получить доступ к состоянию, драйвер, позволяющий интерфейсу, должен определить контракт для своего пользовательского класса интерфейса устройства. Обычно этот контракт является одним из двух типов:

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

  • Интерфейс прямого вызова , возвращаемый через интерфейс запроса. Другие драйверы могут отправлять IRP_MN_QUERY_INTERFACE для получения указателей функций от драйвера для вызова.

Кроме того, если драйвер, принадлежащий состоянию, разрешает прямой доступ к состоянию, другие драйверы могут получить доступ к состоянию с помощью системных функций для программного доступа к состоянию интерфейса устройства. Дополнительные сведения см. в разделе "Состояние реестра интерфейсов устройств".

Эти интерфейсы или состояние (в зависимости от используемого метода общего доступа) должны быть правильно версиями, чтобы драйвер, принадлежащий состоянию, можно обслуживать независимо от других компонентов, обращаюющихся к такому состоянию. Поставщики драйверов не могут полагаться на другие компоненты, обслуживаемые одновременно с драйвером и оставаясь в той же версии.

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

Дополнительные сведения об интерфейсах устройств см. в следующем разделе:

Краткий справочник по поддержке операционной системы для API управления состоянием

Большинство пакетов драйверов должны поддерживать ряд версий операционной системы. Дополнительные сведения о том, как достичь этого в пакете драйверов, см. в разделе "Поддержка нескольких версий операционной системы". В следующих таблицах приведен краткий справочник по добавлению поддержки операционной системы для различных API управления состояниями.

Драйверы WDM

Операционная система Добавлена поддержка
Windows 2000 IoOpenDeviceRegistryKey
IoOpenDeviceInterfaceRegistryKey
Windows Vista IoGetDevicePropertyData
IoSetDevicePropertyData
Windows 8 IoGetDeviceInterfacePropertyData
IoSetDeviceInterfacePropertyData
Windows 8.1 IoQueryFullDriverPath
Windows 10 1803 IoOpenDriverRegistryKey для RegKeyType driverRegKeyParameters и DriverRegKeyPersistentState
IoGetDeviceDirectory
IoGetDriverDirectory для DirectoryType DriverDirectoryImage и DriverDirectoryData
Windows 10, 1809 RtlQueryRegistryValueWithFallback
Windows 11 21H2 IoOpenDriverRegistryKey для RegKeyType driverRegKeySharedPersistentState
IoGetDriverDirectory для DirectoryType driverDirectorySharedData

Драйверы KMDF

Версия KMDF Добавлена поддержка
1.0 WdfDeviceOpenRegistryKey
WdfFdoInitOpenRegistryKey
WdfDriverOpenParametersRegistryKey
WdfDeviceQueryProperty
WdfDeviceAllocAndQueryProperty
WdfFdoInitQueryProperty
WdfFdoInitAllocAndQueryProperty
1,13 WdfDeviceQueryPropertyEx
WdfDeviceAllocAndQueryPropertyEx
WdfDeviceAssignProperty
WdfFdoInitQueryPropertyEx
WdfFdoInitAllocAndQueryPropertyEx
1.25 WdfDriverOpenPersistentStateRegistryKey (Windows 10 1803)

Драйверы UMDF

Версия UMDF Добавлена поддержка
2.0 WdfDeviceOpenRegistryKey
WdfFdoInitOpenRegistryKey
WdfDriverOpenParametersRegistryKey
WdfDeviceQueryProperty
WdfDeviceAllocAndQueryProperty
WdfDeviceQueryPropertyEx
WdfDeviceAllocAndQueryPropertyEx
WdfDeviceAssignProperty
WdfFdoInitQueryProperty
WdfFdoInitAllocAndQueryProperty
WdfFdoInitQueryPropertyEx
WdfFdoInitAllocAndQueryPropertyEx
WdfDeviceQueryInterfaceProperty (Windows 8.1)
WdfDeviceAllocAndQueryInterfaceProperty (Windows 8.1)
WdfDeviceAssignInterfaceProperty (Windows 8.1)
2,25 WdfDeviceRetrieveDeviceDirectoryString
WdfDriverOpenPersistentStateRegistryKey (Windows 10 1803)
2.27 WdfDriverRetrieveDriverDataDirectoryString

Код пользовательского режима

Операционная система Добавлена поддержка
Windows 2000 CM_Open_DevNode_Key
Windows Vista CM_Open_Device_Interface_Key
CM_Get_DevNode_Property
CM_Set_DevNode_Property
CM_Get_Device_Interface_Property
CM_Set_Device_Interface_Property
Windows 10 2004 GetServiceRegistryStateKey
GetServiceDirectory
Windows 11 21H2 GetSharedServiceRegistryStateKey
GetSharedServiceDirectory