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

Изоляция пакетов драйверов — это требование для драйверов 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

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

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

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

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

Состояние реестра неизменяемых служб

Неизменяемое состояние службы — это состояние, предоставляемое пакетом драйвера, устанавливающим службу. Эти значения реестра, заданные 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 ОС. Файлы конфигурации, относящиеся к данному устройству, являются одним из примеров того, какие типы файлов будут храниться здесь. Чтобы получить доступ к расположению этого состояния, используйте одну из следующих функций из службы:

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

Состояние файла службы можно разделить на одну из трех категорий.

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

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

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

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

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

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

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

  • IoGetDriverDirectory (WDM, KMDF) с параметром DirectoryType , равным DriverDirectorySharedData

  • GetSharedServiceDirectory (службы Win32) с параметром DirectoryType , равным ServiceSharedDirectoryPersistentState

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 для RegKeyTypedriverRegKeyParameters и DriverRegKeyPersistentState
IoGetDeviceDirectory
IoGetDriverDirectory для DirectoryTypedriverDirectoryImage и DriverDirectoryData
Windows 10, 1809 RtlQueryRegistryValueWithFallback
Windows 11 21H2 IoOpenDriverRegistryKey для RegKeyTypedriverRegKeySharedPersistentState
IoGetDriverDirectory for DirectoryTypeof 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