Isolamento do pacote de driver

O isolamento do pacote de driver é um requisito para drivers do Windows que torna os pacotes de driver mais resilientes a alterações externas, mais fáceis de atualizar e mais simples de instalar.

Observação

Embora o isolamento do pacote de driver seja necessário para drivers do Windows, os Drivers de Área de Trabalho do Windows ainda se beneficiam dele por meio de resiliência e capacidade de serviço aprimoradas.

A tabela a seguir mostra alguns exemplos de práticas de pacote de driver herdados que não são mais permitidas para Drivers do Windows na coluna esquerda, juntamente com o comportamento necessário para drivers do Windows na coluna direita.

Driver não isolado Driver isolado
O INF copia arquivos para %windir%\System32 ou %windir%\System32\drivers Os arquivos de driver são executados no repositório de driver
Interage com pilhas/drivers de dispositivo usando caminhos codificados Interage com pilhas/drivers de dispositivo usando funções fornecidas pelo sistema ou interfaces de dispositivo
Caminho de codificações para locais globais do Registro Usa HKR e funções fornecidas pelo sistema para o local relativo do registro e do estado do arquivo
Gravações de arquivo de runtime em qualquer local Os arquivos são gravados em relação aos locais fornecidos pelo sistema operacional

Para obter ajuda para determinar se o pacote de driver atende aos requisitos de isolamento do pacote de driver, consulte Validando drivers do Windows. Para obter exemplos de como atualizar um INF para atender aos requisitos de isolamento do pacote de driver, consulte Portabilidade de um INF para seguir o isolamento do pacote de driver.

Executar no repositório de driver

Todos os pacotes de driver isolados deixam seus arquivos de pacote de driver no repositório de driver. Isso significa que eles especificam DIRID 13 em seu INF para especificar o local para arquivos de pacote de driver na instalação. Para obter mais informações sobre como usar isso em um pacote de driver, consulte Executar no repositório de driver.

Estado de leitura e gravação

Observação

Se o componente estiver usando propriedades de interface do dispositivo ou dispositivo para armazenar o estado, continue a usar esse método e as API do sistema operacional apropriadas para armazenar e acessar o estado. As diretrizes a seguir para o registro e o estado do arquivo são para outro estado que precisa ser armazenado por um componente.

O acesso a vários registros e estado de arquivo deve ser feito chamando funções que fornecem a um chamador o local do estado e, em seguida, o estado é lido/gravado em relação a esse local. Não use caminhos de registro absolutos codificados e caminhos de arquivo.

Essa seção contém os seguintes procedimentos:

Estado do Registro

Essa seção contém os seguintes procedimentos:

Estado do registro de dispositivo PnP

Pacotes de driver isolados e componentes do modo de usuário normalmente usam um dos dois locais para armazenar o estado do dispositivo no registro. Estas são a chave de hardware (chave do dispositivo) para o dispositivo e a chave de software (chave de driver) para o dispositivo. A chave de hardware normalmente é para configurações relacionadas a como uma instância de dispositivo individual interage com o hardware. Por exemplo, para habilitar um recurso de hardware ou colocar o hardware em um modo específico. A chave de software normalmente é para configurações relacionadas a como uma instância de dispositivo individual interage com o sistema e outros softwares. Por exemplo, para configurar o local de um arquivo de dados, para interoperar com uma estrutura ou para acessar as configurações de aplicativo de um dispositivo. Para recuperar um identificador para esses locais do Registro, use uma das seguintes opções:

[ExampleDDInstall.HW]
AddReg = Example_DDInstall.AddReg

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

Estado do Registro da interface do dispositivo

Para ler e gravar o estado do Registro da interface do dispositivo, use uma das seguintes opções:

Estado do registro de serviço

O estado do serviço deve ser classificado em uma das três categorias

Estado do registro de serviço imutável

O estado do serviço imutável é o estado fornecido pelo pacote de driver que instala o serviço. Esses valores de registro definidos pelo INF para serviços de driver e Win32 devem ser armazenados na subchave "Parâmetros" do serviço fornecendo uma linha HKR em uma seção AddReg e, em seguida, referenciando essa seção na seção de instalação do serviço no INF. Por exemplo:

[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

Para acessar o local desse estado do serviço em runtime, use uma destas funções:

Esses valores de registro fornecidos pelo INF na subchave "Parâmetros" para o serviço só devem ser lidos em runtime e não modificados. Eles devem ser tratados como somente leitura.

Se os valores do Registro fornecidos pelo INF forem configurações padrão que podem ser substituídas em runtime, os valores de substituição deverão ser gravados no estado do Registro de serviço interno ou no estado do Registro de serviço compartilhado para o serviço. Ao recuperar as configurações, a configuração pode ser pesquisada primeiro no estado mutável. Se ele não existir lá, a configuração poderá ser pesquisada no estado imutável. RtlQueryRegistryValueWithFallback pode ser usado para ajudar a consultar configurações como essas que têm uma substituição e um valor padrão.

Estado interno do registro de serviço

O estado do serviço interno é o estado escrito em runtime e de propriedade e gerenciado apenas pelo próprio serviço e só pode ser acessado por esse serviço. Para acessar o local do estado de serviço interno, use uma destas funções do serviço:

Se o serviço quiser permitir que outros componentes modifiquem essas configurações, o serviço deverá expor uma interface para a qual outro componente pode chamar que informa ao serviço como alterar essas configurações. Por exemplo, um serviço Win32 pode expor uma interface COM ou RPC e um serviço de driver pode expor uma interface IOCTL por meio de uma interface de dispositivo.

Estado do registro de serviço compartilhado

O estado do serviço compartilhado é o estado escrito em runtime e pode ser compartilhado com outros componentes do modo de usuário se eles tiverem privilégios suficientes. Para acessar o local desse estado de serviço compartilhado, use uma destas funções:

Estado do arquivo

Essa seção contém os seguintes procedimentos:

Estado do arquivo do dispositivo

Se os arquivos relacionados a um dispositivo precisarem ser gravados em runtime, esses arquivos deverão ser armazenados em relação a um identificador ou caminho de arquivo fornecido por meio da API do sistema operacional. Arquivos de configuração específicos para esse dispositivo são um exemplo dos tipos de arquivos a serem armazenados aqui. Para acessar o local desse estado, use uma destas funções do serviço:

Estado do arquivo de serviço

O estado do arquivo de serviço pode ser classificado em uma das três categorias

Estado do arquivo de serviço imutável

O estado do arquivo de serviço imutável são arquivos que fazem parte do pacote de driver. Para obter mais informações sobre como acessar esses arquivos, consulte Executar no Repositório de Driver.

Estado do arquivo de serviço interno

O estado do arquivo de serviço interno é o estado gravado em runtime e de propriedade e gerenciado apenas pelo próprio serviço e que só é acessível a esse serviço. Para acessar o local do estado de serviço interno, use uma destas funções do serviço:

Se o serviço quiser permitir que outros componentes modifiquem essas configurações, o serviço deverá expor uma interface para a qual outro componente pode chamar que informa ao serviço como alterar essas configurações. Por exemplo, um serviço Win32 pode expor uma interface COM ou RPC e um serviço de driver pode expor uma interface IOCTL por meio de uma interface do dispositivo.

Estado do arquivo de serviço compartilhado

O estado do arquivo de serviço compartilhado é o estado que é gravado em runtime e pode ser compartilhado com outros componentes do modo de usuário se eles tiverem privilégios suficientes. Para acessar o local desse estado de serviço compartilhado, use uma destas funções:

  • IoGetDriverDirectory (WDM, KMDF) com o parâmetro DirectoryType definido como DriverDirectorySharedData

  • GetSharedServiceDirectory (Win32 Services) com o parâmetro DirectoryType definido como ServiceSharedDirectoryPersistentState

DriverData e ProgramData

Arquivos que podem ser compartilhados com outros componentes, mas que não se encaixam na categoria de estado do arquivo de serviço compartilhado , podem ser gravados DriverData em locais ou ProgramData .

Esses locais oferecem aos componentes um local para gravar estado ou estado temporário que deve ser consumido por outros componentes e potencialmente coletado e copiado de um sistema a ser processado por outro sistema. Por exemplo, arquivos de log personalizados ou despejos de falha se encaixam nessa descrição.

Evite gravar arquivos na raiz dos DriverData diretórios ou ProgramData . Em vez disso, crie um subdiretório com o nome da empresa e, em seguida, escreva arquivos e subdiretórios adicionais dentro desse diretório.

Por exemplo, para um nome de empresa da Contoso, um driver no modo kernel poderia gravar um log \DriverData\Contoso\Logs personalizado e um aplicativo de modo de usuário poderia coletar ou analisar os arquivos de log do %DriverData%\Contoso\Logs.

DriverData

O DriverData diretório está disponível em Windows 10, versão 1803 e posterior e pode ser acessado por administradores e drivers UMDF.

Os drivers no modo kernel acessam o DriverData diretório usando um link simbólico fornecido pelo sistema chamado \DriverData.

Os programas no modo de usuário acessam o DriverData diretório usando a variável %DriverData%de ambiente .

ProgramData

A %ProgramData% variável de ambiente do modo de usuário está disponível para os componentes do modo de usuário usarem ao armazenar dados.

Arquivos temporários

Normalmente, os arquivos temporários são usados em operações intermediárias. Eles podem ser gravados em um sub-caminho nas %TEMP% variáveis de ambiente ou %TMP% . Como esses locais são acessados por meio de variáveis de ambiente, essa capacidade é limitada aos componentes do modo de usuário. Não há garantias sobre o tempo de vida ou persistência desses arquivos temporários depois que os identificadores para eles são fechados. O sistema operacional ou o usuário pode removê-los a qualquer momento e ele pode não persistir em uma reinicialização.

Evite gravar arquivos na raiz dos %TEMP% diretórios ou %TMP% . Em vez disso, crie um subdiretório com o nome da empresa e, em seguida, escreva arquivos e subdiretórios adicionais dentro desse diretório.

Estado da propriedade

Os dispositivos e as interfaces do dispositivo dão suporte ao estado de armazenamento por meio do modelo de propriedade PnP. O modelo de propriedade permite que os dados de propriedade estruturados sejam armazenados em uma interface de dispositivo ou dispositivo. Isso destina-se a dados menores que se ajustam razoavelmente aos tipos de propriedade compatíveis com o modelo de propriedade.

Para acessar as propriedades do dispositivo, essas APIs podem ser usadas:

Para acessar as propriedades da interface do dispositivo, essas APIs podem ser usadas:

Usando interfaces de dispositivo

Se um driver quiser permitir que outros componentes leiam ou modifiquem o estado interno do driver, o driver deverá expor uma interface para a qual outro componente pode chamar que informa ao driver quais configurações retornar ou como modificar configurações específicas. Por exemplo, o serviço de driver pode expor uma interface IOCTL por meio de uma interface do dispositivo.

Normalmente, o driver que possui o estado expõe uma interface do dispositivo em uma classe de interface de dispositivo personalizada. Quando o driver estiver pronto para que outros componentes tenham acesso ao estado, ele habilitará a interface. Para serem notificados quando uma interface do dispositivo estiver habilitada, os componentes do modo de usuário podem se registrar para notificações de chegada da interface do dispositivo e os componentes do modo kernel podem usar IoRegisterPlugPlayNotification. Para que esses componentes acessem o estado, o driver que habilita a interface deve definir um contrato para sua classe de interface de dispositivo personalizada. Normalmente, esse contrato é de dois tipos:

  • Um contrato de E/S pode ser associado a essa classe de interface do dispositivo que fornece um mecanismo para acessar o estado. Outros componentes usam a interface do dispositivo habilitada para enviar solicitações de E/S em conformidade com o contrato.

  • Uma interface de chamada direta que é retornada por meio de uma interface de consulta. Outros drivers podem enviar IRP_MN_QUERY_INTERFACE para recuperar ponteiros de função do driver para chamar.

Como alternativa, se o driver que possui o estado permitir acesso direto ao estado, outros drivers poderão acessar o estado usando funções fornecidas pelo sistema para acesso programático ao estado da interface do dispositivo. Consulte Estado do Registro da Interface do Dispositivo para obter mais informações.

Essas interfaces ou estado (dependendo do método de compartilhamento usado) precisam ser devidamente versão para que o driver proprietário do estado possa ser atendido independentemente de outros componentes que acessam esse estado. Os fornecedores de driver não podem contar com outros componentes sendo atendidos ao mesmo tempo que o driver e permanecendo na mesma versão.

Como os dispositivos e drivers que controlam interfaces vêm e vão, drivers e aplicativos devem evitar chamar IoGetDeviceInterfaces na inicialização do componente para obter uma lista de interfaces habilitadas. Em vez disso, a melhor prática é registrar-se para notificações de chegada ou remoção da interface do dispositivo e, em seguida, chamar a função apropriada para obter a lista de interfaces habilitadas existentes no computador.

Para obter mais informações sobre interfaces de dispositivo, consulte:

Referência rápida do suporte do sistema operacional para APIs de gerenciamento de estado

A maioria dos pacotes de driver precisa dar suporte a uma variedade de versões do sistema operacional. Consulte Suporte a várias versões do sistema operacional para obter mais informações sobre como fazer isso em um pacote de driver. As tabelas a seguir fornecem uma referência rápida de quando o suporte ao sistema operacional foi adicionado para várias APIs de gerenciamento de estado.

Drivers WDM

Sistema operacional Suporte adicionado
Windows 2000 IoOpenDeviceRegistryKey
IoOpenDeviceInterfaceRegistryKey
Windows Vista IoGetDevicePropertyData
IoSetDevicePropertyData
Windows 8 IoGetDeviceInterfacePropertyData
IoSetDeviceInterfacePropertyData
Windows 8.1 IoQueryFullDriverPath
Windows 10 1803 IoOpenDriverRegistryKey para RegKeyType de DriverRegKeyParameters e DriverRegKeyPersistentState
IoGetDeviceDirectory
IoGetDriverDirectory para DirectoryType de DriverDirectoryImage e DriverDirectoryData
Windows 10 1809 RtlQueryRegistryValueWithFallback
Windows 11 21H2 IoOpenDriverRegistryKey para RegKeyType de DriverRegKeySharedPersistentState
IoGetDriverDirectory para DirectoryType de DriverDirectorySharedData

Drivers KMDF

Versão do KMDF Suporte adicionado
1.0 WdfDeviceOpenRegistryKey
WdfFdoInitOpenRegistryKey
WdfDriverOpenParametersRegistryKey
WdfDeviceQueryProperty
WdfDeviceAllocAndQueryProperty
WdfFdoInitQueryProperty
WdfFdoInitAllocAndQueryProperty
1.13 WdfDeviceQueryPropertyEx
WdfDeviceAllocAndQueryPropertyEx
WdfDeviceAssignProperty
WdfFdoInitQueryPropertyEx
WdfFdoInitAllocAndQueryPropertyEx
1,25 WdfDriverOpenPersistentStateRegistryKey (Windows 10 1803)

Drivers UMDF

Versão do UMDF Suporte adicionado
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

Código do modo de usuário

Sistema operacional Suporte adicionado
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