Isolamento do pacote de driver
O isolamento dos pacotes de drivers é um requisito para Drivers do Windows. Com ele, esses pacotes ficam mais resistentes às mudanças externas e se tornam mais fáceis de atualizar e de instalar.
Observação
Embora o isolamento do pacote de driver seja necessário para drivers do Windows, os drivers do Windows Desktop ainda se beneficiam dele por meio de resiliência e capacidade de manutenção aprimoradas.
A tabela a seguir mostra alguns exemplos de práticas de pacotes de drivers legados que não são mais permitidas para drivers do Windows na coluna da esquerda, juntamente com o comportamento necessário para drivers do Windows na coluna da direita.
Driver não isolado | Driver isolado |
---|---|
INF copia arquivos para %windir%\System32 ou %windir%\System32\drivers | Os arquivos de driver são executados no repositório de drivers |
Interage com pilhas/drivers de dispositivos usando caminhos codificados | Interage com pilhas/drivers de dispositivos usando funções fornecidas pelo sistema ou interfaces de dispositivos |
Caminho de códigos rígidos para locais de registro globais | Usa HKR e funções fornecidas pelo sistema para localização relativa do registro e estado do arquivo |
O arquivo de tempo de execução é gravado 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 Validação de Drivers do Windows. Para obter exemplos de como atualizar um INF para atender aos requisitos de isolamento do pacote de driver, consulte Portando um INF para seguir o isolamento do pacote de driver.
Executar do repositório de drivers
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 dos arquivos de pacote de driver na instalação. Para obter mais informações sobre como usar isso em um pacote de driver, consulte Executar do repositório de drivers.
Estado de leitura e gravação
Observação
Se o seu componente estiver usando propriedades de dispositivo ou interface de dispositivo para armazenar estado, continue a usar esse método e as APIs do sistema operacional apropriadas para armazenar e acessar o estado. As orientações a seguir para o estado do registro e do arquivo são para outros estados que precisam ser armazenados por um componente.
O acesso a vários estados de registro e arquivo deve ser feito chamando funções que fornecem ao chamador a localização do estado e então o estado é lido/gravado em relação a essa localização. Não use caminhos de registro e caminhos de arquivo absolutos codificados.
Essa seção contém os seguintes procedimentos:
Estado do registro
Essa seção contém os seguintes procedimentos:
Estado do registro do dispositivo PnP
Pacotes de driver isolados e componentes de modo de usuário geralmente 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 do driver) para o dispositivo. A chave de hardware costuma ser usada para configurações relacionadas à forma 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 geralmente é usada para configurações relacionadas à forma 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 do aplicativo de um dispositivo. Para recuperar um identificador para esses locais de registro, use uma das seguintes opções:
IoOpenDeviceRegistryKey (WDM)
CM_Open_DevNode_Key (código do modo de usuário)
Diretiva INF AddReg usando entradas reg-root de HKR em uma add-registry-section referenciado de uma seção INF DDInstall ou seção DDInstall.HW, como mostrado abaixo:
[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:
CM_Open_Device_Interface_Key (código do modo de usuário)
Diretiva INF AddReg usando entradas reg-root de HKR em uma add-registry-section referenciada de uma seção add-interface-section
Estado do registro de serviço
O estado de serviço deve ser classificado em uma das 3 categorias
Estado de registro de serviço imutável
O estado de 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 depois 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 tempo de execução, use uma destas funções:
IoOpenDriverRegistryKey (WDM) com um DRIVER_REGKEY_TYPE de DriverRegKeyParameters
GetServiceRegistryStateKey (serviços do Win32) com um SERVICE_REGISTRY_STATE_TYPE de ServiceRegistryStateParameters
Esses valores de registro fornecidos pelo INF na subchave "Parâmetros" do serviço devem ser lidos somente em tempo de execução e não modificados. Eles devem ser tratados como somente leitura.
Se os valores de registro fornecidos pelo INF forem configurações padrão que podem ser substituídas em tempo de execução, 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 do serviço. Ao recuperar as configurações, a configuração pode ser procurada primeiro no estado mutável. Se não existir lá, a configuração pode ser procurada 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 do registro de serviço interno
O estado de serviço interno é o estado que é gravado em tempo de execução 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 do serviço interno, use uma destas funções do serviço:
IoOpenDriverRegistryKey (WDM) com um DRIVER_REGKEY_TYPE de DriverRegKeyPersistentState
GetServiceRegistryStateKey (serviços do Win32) com um SERVICE_REGISTRY_STATE_TYPE de ServiceRegistryStatePersistent
Se o serviço quiser permitir que outros componentes modifiquem essas configurações, o serviço deverá expor uma interface que outro componente possa chamar que informe ao serviço como alterar essas configurações. Por exemplo, um serviço do 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 gravado em tempo de execução e pode ser compartilhado com outros componentes do modo de usuário se eles forem suficientemente privilegiados. Para acessar o local desse estado de serviço compartilhado, use uma destas funções:
IoOpenDriverRegistryKey (WDM) com um DRIVER_REGKEY_TYPE de DriverRegKeySharedPersistentState
GetSharedServiceRegistryStateKey (serviços do Win32) com um SERVICE_SHARED_REGISTRY_STATE_TYPE de ServiceSharedRegistryPersistentState
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 tempo de execução, esses arquivos deverão ser armazenados em relação a um identificador ou caminho de arquivo fornecido por meio das APIs do sistema operacional. Os arquivos de configuração específicos desse dispositivo são um exemplo de quais tipos de arquivos devem ser armazenados aqui. Para acessar a localização desse estado, use uma destas funções do serviço:
IoGetDeviceDirectory (WDM) com o parâmetro DirectoryType definido como DeviceDirectoryData
Estado do arquivo de serviço
O estado do arquivo de serviço pode ser classificado em uma das 3 categorias
Estado de arquivo de serviço imutável
Os arquivos de estado de serviço imutáveis são arquivos que fazem parte do pacote de driver. Para obter mais informações sobre como acessar esses arquivos, consulte Executar do repositório de drivers.
Estado do arquivo de serviço interno
O estado do arquivo de serviço interno é o estado que é gravado em tempo de execução 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 do serviço interno, use uma destas funções do serviço:
IoGetDriverDirectory (WDM, KMDF) com o parâmetro DirectoryType definido como DriverDirectoryData
GetServiceDirectory (serviços do Win32) com o parâmetro eDirectoryType definido como ServiceDirectoryPersistentState
Se o serviço quiser permitir que outros componentes modifiquem essas configurações, o serviço deverá expor uma interface que outro componente possa chamar que informe ao serviço como alterar essas configurações. Por exemplo, um serviço do 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 arquivo de serviço compartilhado
O estado do arquivo de serviço compartilhado é o estado gravado em tempo de execução e pode ser compartilhado com outros componentes do modo de usuário se eles forem suficientemente privilegiados. 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 (serviços do Win32) com o parâmetro DirectoryType definido como ServiceSharedDirectoryPersistentState
DriverData e ProgramData
Arquivos que podem ser compartilhados com outros componentes, mas que não se enquadram na categoria de estado de arquivo de serviço compartilhado, podem ser gravados em locais DriverData
ou ProgramData
.
Esses locais oferecem aos componentes um local para gravar um estado temporário ou estado que deve ser consumido por outros componentes e possivelmente coletado e copiado de um sistema para ser processado por outro sistema. Por exemplo, arquivos de log personalizados ou despejos de memória se enquadram nessa descrição.
Evite escrever arquivos na raiz dos diretórios DriverData
ou ProgramData
. Em vez disso, crie um subdiretório com o nome da sua empresa e então grave arquivos e outros subdiretórios dentro desse diretório.
Por exemplo, para um nome de empresa Contoso, um driver de modo kernel pode gravar um log personalizado em \DriverData\Contoso\Logs
e um aplicativo em modo de usuário pode coletar ou analisar os arquivos de log de %DriverData%\Contoso\Logs
.
DriverData
O diretório DriverData
está disponível no Windows 10, versão 1803 e posteriores, e pode ser acessado por administradores e drivers UMDF.
Os drivers do modo kernel acessam o diretório DriverData
usando um link simbólico fornecido pelo sistema chamado \DriverData
.
Os programas em modo de usuário acessam o diretório DriverData
usando a variável de ambiente %DriverData%
.
ProgramData
A variável de ambiente do modo de usuário %ProgramData%
está disponível para componentes do modo de usuário usarem ao armazenar dados.
Arquivos temporários
Arquivos temporários costumam ser usados em operações intermediárias. Eles podem ser gravados em um subcaminho sob as variáveis de ambiente %TEMP%
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 quanto à duração ou persistência desses arquivos temporários depois que seus identificadores são fechados. O sistema operacional ou o usuário pode removê-los a qualquer momento e eles podem não persistir após uma reinicialização.
Evite escrever arquivos na raiz dos diretórios %TEMP%
ou %TMP%
. Em vez disso, crie um subdiretório com o nome da sua empresa e então grave arquivos e outros subdiretórios dentro desse diretório.
Estado da propriedade
Ambos os dispositivos e interfaces de dispositivos oferecem suporte ao armazenamento de estado por meio do modelo de propriedade PnP. O modelo de propriedade permite que dados de propriedade estruturados sejam armazenados em um dispositivo ou interface de dispositivo. Isso se destina a dados menores que se encaixam razoavelmente nos tipos de propriedade compatíveis com o modelo de propriedade.
Para acessar as propriedades do dispositivo, estas APIs podem ser usadas:
Drivers WDM
Drivers WDF
Código do modo de usuário
Para acessar as propriedades da interface do dispositivo, estas APIs podem ser usadas:
Drivers WDM
Drivers WDF
Código do modo de usuário
Usar interfaces de dispositivo
Se um driver quiser permitir que outros componentes leiam ou modifiquem o estado interno do driver, o driver deve expor uma interface que outro componente possa chamar e que informe 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 de dispositivo.
Geralmente, o driver que possui o estado expõe uma interface de dispositivo em uma classe de interface de dispositivo personalizada. Quando o driver está pronto para que outros componentes tenham acesso ao estado, ele habilita a interface. Para ser notificado quando uma interface de dispositivo estiver habilitada, os componentes do modo de usuário podem ser registrados para receber 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. Este contrato geralmente é de dois tipos:
Um contrato de E/S pode ser associado à 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 que estejam em conformidade com o contrato.
Uma interface de chamada direta que é retornada por meio de uma interface de consulta. Outros motoristas podem enviar IRP_MN_QUERY_INTERFACE para recuperar ponteiros de função do driver a ser chamado.
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 estados (dependendo do método de compartilhamento usado) precisam ser versionados corretamente para que o driver que possui o estado possa ser atendido independentemente de outros componentes que acessam esse estado. Os fornecedores de drivers não podem confiar que outros componentes serão reparados ao mesmo tempo que o driver e permanecerão na mesma versão.
Como os dispositivos e drivers que controlam as interfaces vêm e vão, os 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 receber notificações de chegada ou remoção da interface do dispositivo e depois chamar a função apropriada para obter a lista de interfaces habilitadas existentes na máquina.
Para obter mais informações sobre interfaces de dispositivos, consulte:
Registrar-se para notificação de chegada e remoção de interface de dispositivo
Registrando-se para notificação de alteração da interface do dispositivo
Referência rápida de suporte do sistema operacional para APIs de gerenciamento de estado
A maioria dos pacotes de driver precisa oferecer suporte a uma variedade de versões de sistemas operacionais. 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 do 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
Drivers UMDF
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 |