Adicionando um dispositivo PnP a um sistema em execução
Esta seção descreve a sequência de eventos que ocorrem quando o sistema configura um dispositivo PnP que um usuário adicionou a um computador em execução. Esta discussão destaca as funções do gerenciador PnP, dos drivers de barramento e dos drivers de função e filtro na enumeração e configuração de um novo dispositivo.
A maior parte dessa discussão também é relevante para configurar um dispositivo PnP que está presente quando o computador é inicializado. Especificamente, os dispositivos cujos drivers são marcados SERVICE_DEMAND_START em um arquivo INF são configurados essencialmente da mesma maneira se o dispositivo é adicionado dinamicamente ou está presente no momento da inicialização.
A figura a seguir mostra as primeiras etapas na configuração do dispositivo, a partir de quando o usuário conecta o hardware ao computador.
As seguintes notas correspondem aos números circulados na figura anterior:
Um usuário conecta um dispositivo PnP em um slot livre em um barramento PnP.
Neste exemplo, o usuário conecta um joystick USB PnP ao hub em um controlador de host USB. O hub USB é um dispositivo de barramento PnP porque os dispositivos filho podem ser anexados a ele.
O controlador de função para o dispositivo de barramento determina que um novo dispositivo está em seu barramento.
Como o driver determina isso depende da arquitetura do barramento. Para alguns barramentos, o driver da função de barramento recebe uma notificação de hot-plug de novos dispositivos. Se o barramento não der suporte à notificação de hot-plug, o usuário deverá tomar as medidas apropriadas no Painel de Controle para fazer com que o barramento seja enumerado.
Neste exemplo, o barramento USB dá suporte à notificação de hot-plug para que o driver de função do barramento USB seja notificado de que seus filhos foram alterados.
O driver de função do dispositivo de barramento notifica o gerenciador PnP de que seu conjunto de dispositivos filho foi alterado.
O driver de função notifica o gerenciador PnP chamando IoInvalidateDeviceRelations com um Tipo de BusRelations.
O gerenciador PnP consulta os drivers do barramento para obter a lista atual de dispositivos no barramento.
O gerenciador PnP envia uma solicitação IRP_MN_QUERY_DEVICE_RELATIONS para a pilha de dispositivos do barramento. The Parameters.QueryDeviceRelations.Type tem valor BusRelations, indicando que o gerenciador PnP está solicitando a lista atual de dispositivos presentes no barramento (relações do barramento).
O gerenciador PnP envia o IRP para o driver superior na pilha de dispositivos do barramento. De acordo com as regras para IRPs PnP, cada driver na pilha manipula o IRP, se apropriado, e passa o IRP para o próximo driver.
O driver de função para o dispositivo de barramento administra o IRP.
Consulte na página de referência de IRP_MN_QUERY_DEVICE_RELATIONS as informações detalhadas sobre como lidar com esse IRP.
Neste exemplo, o driver do hub USB manipula esse IRP para o hub FDO. O driver do hub cria um PDO para o dispositivo joystick e inclui um ponteiro referenciado para o PDO do joystick em sua lista de dispositivos filho retornados pelo IRP.
Quando o driver de barramento pai do hub USB (o par de drivers de classe/miniclasse do controlador host USB) conclui o IRP, o IRP retorna na pilha do dispositivo por meio de quaisquer rotinas de IoCompletion registradas pelos drivers do hub.
Observe que o driver de função de barramento relata uma alteração em sua lista de dispositivos filhos solicitando que o gerenciador PnP consulte sua lista de dispositivos filhos. A solicitação de IRP_MN_QUERY_DEVICE_RELATIONS resultante é vista por todos os drivers do dispositivo do barramento. Normalmente, o barramento da função de barramento é o único driver a lidar com o IRP e relatar filhos. Em algumas pilhas de dispositivos, um driver de filtro de barramento está presente e participa na construção da lista de relações de barramento. Um exemplo é o ACPI, que é anexado como um driver de filtro de barramento para dispositivos ACPI. Em algumas pilhas de dispositivos, os drivers de filtro fora do barramento lidam com a solicitação de IRP_MN_QUERY_DEVICE_RELATIONS, mas isso não é típico.
Neste ponto, o gerenciador PnP tem a lista atual de dispositivos no barramento. O gerenciador PnP determina se os dispositivos foram recém-chegados ou removidos. Neste exemplo, há um novo dispositivo. A figura a seguir mostra o gerenciador PnP criando um devnode para o novo dispositivo e começando a configurar o dispositivo.
As seguintes notas correspondem aos números circulados na figura anterior:
O gerenciador PnP cria devnodes para novos dispositivos filho no barramento.
O gerenciador PnP compara a lista de relações de barramento retornadas no IRP IRP_MN_QUERY_DEVICE_RELATIONS à lista de filhos do barramento atualmente registrado na árvore de dispositivos PnP. O gerenciador PnP cria um devnode para cada novo dispositivo e inicia o processamento de remoção para todos os dispositivos que foram removidos.
Neste exemplo, há um novo dispositivo (um joystick), portanto, o gerenciador PnP cria um devnode para o joystick. Neste ponto, o único driver configurado para o joystick é o driver de barramento do hub USB pai, responsável por criar o PDO do joystick. Os drivers de filtro de barramento opcionais também estariam presentes na pilha do dispositivo, mas o exemplo omite os drivers de filtro de barramento para simplificar.
A seta larga entre os dois devnodes na figura anterior indica que o devnode do joystick é filho do devnode do hub USB.
O gerenciador PnP coleta informações sobre o novo dispositivo e começa a configurar o dispositivo.
O gerenciador PnP envia uma sequência de IRPs para a pilha de dispositivos para coletar informações sobre o dispositivo. Neste ponto, a pilha de dispositivos consiste apenas no PDO criado pelo driver de barramento pai do dispositivo e nos DOs de filtro para quaisquer drivers opcionais de filtro de barramento. Portanto, o driver de barramento e o driver de filtro de barramento são os únicos drivers que respondem a esses IRPs. Neste exemplo, o único driver na pilha de dispositivos do joystick é o driver do barramento principal, que é o controlador do hub USB.
O gerenciador PnP coleta informações sobre um novo dispositivo enviando IRPs para a pilha de dispositivos. Esses IRPs incluem o seguinte:
IRP_MN_QUERY_ID, um IRP separado para cada um dos seguintes tipos de IDs de hardware:
BusQueryDeviceID
BusQueryInstanceID
BusQueryHardwareIDs
BusQueryCompatibleIDs
BusQueryContainerID
IRP_MN_QUERY_DEVICE_TEXT, um IRP separado para cada um dos seguintes itens:
DescriçãoDoTextoDoDispositivo
InformaçõesDeLocalizaçãoDeTextoDoDispositivo
O gerenciador PnP envia os IRPs listados acima nesta fase de processamento de um novo dispositivo PnP, mas não necessariamente na ordem listada, portanto, você não deve fazer suposições sobre a ordem na qual os IRPs são enviados. Além disso, você não deve assumir que o gerenciador PnP envia apenas os IRPs listados acima.
O gerenciador PnP verifica o registro para determinar se o dispositivo foi instalado neste computador anteriormente. O gerenciador PnP verifica se há uma subchave <>\<deviceID> de um enumerador para o dispositivo na ramificação Enum. Neste exemplo, o dispositivo é novo e deve ser configurado "do zero".
O gerenciador PnP armazena informações sobre o dispositivo no registro.
A ramificação Enum do registro é reservada para uso por componentes do sistema operacional, e o layout está sujeito a alterações. Os desenvolvedores de drivers devem usar rotinas do sistema para extrair informações relacionadas aos drivers. Não acesse a ramificação Enum diretamente de um driver. As informações de Enum a seguir são listadas apenas para fins de depuração.
O gerenciador PnP cria uma subchave para o dispositivo sob a chave para o enumerador do dispositivo.
O gerenciador PnP cria uma subchave chamada HKLM\System\CurrentControlSet\Enum\<enumerador>\<deviceID>. Ele criará a subchave <> do enumerador se ela ainda não existir.
Um enumerador é um componente que identifica dispositivos PnP com base em um padrão de hardware PnP. As tarefas de um enumerador são executadas por um motorista de ônibus PnP em parceria com o gerenciador PnP. Um dispositivo normalmente é enumerado pelo seu driver de barramento pai, como PCI ou PCMCIA. Alguns dispositivos são enumerados por um driver de filtro de barramento, como ACPI.
O gerenciador PnP cria uma subchave para esta instância do dispositivo.
Se Capabilities.UniqueID é retornado como Verdadeiro para IRP_MN_QUERY_CAPABILITIES, a ID exclusiva do dispositivo será única em todo o sistema. Caso contrário, o gerenciador PnP modificará a ID para que ela seja exclusiva em todo o sistema.
O gerenciador PnP cria uma subchave chamada HKLM\System\CurrentControlSet\Enum\<enumerador>\<deviceID>\<instanceID>.
O gerenciador PnP grava informações sobre o dispositivo na subchave da instância do dispositivo.
O gerenciador PnP armazena informações, incluindo as seguintes, se elas foram fornecidas para o dispositivo:
DeviceDesc — de IRP_MN_QUERY_DEVICE_TEXT
Local – de IRP_MN_QUERY_DEVICE_TEXT
Recursos — os sinalizadores de IRP_MN_QUERY_CAPABILITIES
NúmeroUI — de IRP_MN_QUERY_CAPABILITIES
IDHardware — de IRP_MN_QUERY_ID
IDsCompatíveis – de IRP_MN_QUERY_ID
IDContainer — de IRP_MN_QUERY_ID
LogConf\BootConfig — de IRP_MN_QUERY_RESOURCES
LogConf\BasicConfigVector — de IRP_MN_QUERY_RESOURCE_REQUIREMENTS
Neste ponto, o gerenciador PnP está pronto para localizar o driver de função e os drivers de filtro para o dispositivo, se houver. (Consulte a figura a seguir.)
As seguintes notas correspondem aos círculos numerados na figura anterior:
O gerenciador PnP no modo kernel coordena com o gerenciador PnP do modo de usuário e os componentes de configuração do modo de usuário para localizar os drivers de função e filtro para o dispositivo, se existirem.
O gerenciador PnP em modo kernel enfileira um evento para o gerenciador PnP em modo de usuário, identificando um dispositivo que precisa ser instalado. Depois que um usuário privilegiado faz logon, os componentes do modo de usuário prosseguem com a localização de drivers. Consulte a visão geral da instalação do dispositivo para obter informações sobre os componentes de instalação e sua função na instalação de um dispositivo.
Os componentes de Instalação do modo de usuário direcionam o gerenciador PnP do modo kernel para carregar os drivers de função e filtro.
Os componentes em modo usuário fazem chamadas ao modo kernel para carregar os drivers, o que aciona suas rotinas AddDevice.
A figura a seguir mostra o gerenciador PnP carregando os drivers (se apropriado), chamando suas rotinas de AddDevice e instruindo os drivers a iniciar o dispositivo.
As seguintes notas correspondem aos círculos numerados na figura anterior:
Drivers de filtro de nível inferior
Antes que o driver de funções seja anexado à pilha de dispositivos, o gerenciador PnP processa os drivers de filtro inferiores. Para cada driver de filtro inferior, o gerenciador PnP chamará a rotina DriverEntry do driver se o driver ainda não estiver carregado. Em seguida, o gerenciador PnP chama a rotina AddDevice do driver. Em sua rotina de AddDevice, o driver de filtro cria um objeto de dispositivo de filtro (DO de filtro) e o anexa à pilha de dispositivos (IoAttachDeviceToDeviceStack). Depois de anexar seu objeto de dispositivo à pilha do dispositivo, o driver assumirá a função de driver para o dispositivo.
No exemplo de joystick USB, há um driver de filtro inferior para o dispositivo.
Driver de função
Depois que os filtros inferiores forem anexados, o gerenciador PnP processará o driver de função. O gerenciador PnP chamará a rotina de do driver de função DriverEntry se o driver ainda não estiver carregado e chamará a rotina de AddDevice do driver. O driver de função cria um FDO (objeto de dispositivo de função) e o anexa à pilha do dispositivo.
Neste exemplo, o driver de função para o USB joystick é, na verdade, composto por dois drivers: o driver da classe HID e o driver da miniclasse HID. Os dois drivers trabalham juntos para funcionar como driver de função. O par de drivers cria apenas um FDO e o anexa à pilha do dispositivo.
Drivers de filtro superior
Depois que o driver de função é anexado, o gerenciador PnP processa todos os drivers de filtro superior.
Neste exemplo, há um driver de filtro superior para o dispositivo.
Atribuindo recursos e iniciando o dispositivo
O gerenciador PnP atribui recursos ao dispositivo, se necessário, e emite um IRP para iniciar o dispositivo.
Atribuindo recursos
Anteriormente no processo de configuração, o gerenciador PnP reuniu os requisitos de recursos de hardware para o dispositivo pelo driver de barramento principal do dispositivo. Depois que o conjunto completo de drivers é carregado para o dispositivo, o gerenciador PnP envia uma solicitação IRP_MN_FILTER_RESOURCE_REQUIREMENTS para a pilha de dispositivos. Todos os drivers na pilha têm a oportunidade de lidar com esse IRP e modificar a lista de requisitos de recursos do dispositivo, se necessário.
O gerenciador PnP atribuirá recursos ao dispositivo, se o dispositivo exigir algum, com base nos requisitos do dispositivo e nos recursos disponíveis no momento.
O gerenciador PnP pode precisar reorganizar as atribuições de recursos de dispositivos existentes para atender às necessidades do novo dispositivo. Essa reatribuição de recursos é chamada de "rebalanceamento". Os drivers para os dispositivos existentes recebem uma sequência de IRPs de parada e inicialização durante um reequilíbrio, mas o reequilíbrio deve ser transparente para os usuários.
No exemplo do joystick USB, os dispositivos USB não exigem recursos de hardware para que o gerenciador PnP defina a lista de recursos como NULL.
Iniciando o dispositivo (IRP_MN_START_DEVICE)
Depois que o gerenciador PnP atribui recursos ao dispositivo, ele envia um IRP IRP_MN_START_DEVICE para a pilha de dispositivos, instruindo os drivers a iniciar o dispositivo.
Depois que o dispositivo é iniciado, o gerenciador PnP envia mais três IRPs para os drivers do dispositivo:
-
Depois que o IRP inicial for concluído com sucesso, o gerenciador PnP envia outra IRP IRP_MN_QUERY_CAPABILITIES para a pilha de dispositivos. Todos os drivers do dispositivo têm a opção de lidar com o IRP. O gerenciador PnP envia esse IRP no momento, depois que todos os drivers são anexados e o dispositivo é iniciado, pois os drivers de função ou filtro podem precisar acessar o dispositivo para coletar informações de funcionalidade.
-
Esse IRP dá a um driver a oportunidade de, por exemplo, relatar que o dispositivo não deve ser exibido em interfaces de usuário, como o Gerenciador de Dispositivos e o programa Hotplug. Isso é útil para dispositivos que estão presentes em um sistema, mas não são utilizáveis na configuração atual, como uma porta de jogo em um laptop que não é utilizável quando o laptop é desencaixado.
IRP_MN_QUERY_DEVICE_RELATIONS para relações de barramento
O gerenciador PnP envia esse IRP para determinar se o dispositivo tem algum dispositivo filho. Nesse caso, o gerenciador PnP configura cada dispositivo filho.
Usando GUID_PNP_LOCATION_INTERFACE
A interface GUID_PNP_LOCATION_INTERFACE fornece a propriedade do dispositivo SPDRP_LOCATION_PATHS Plug and Play (PnP) para um dispositivo.
Para implementar essa interface no driver, faça IRP_MN_QUERY_INTERFACE IRP com InterfaceType = GUID_PNP_LOCATION_INTERFACE. Seu driver fornece um ponteiro para uma estrutura PNP_LOCATION_INTERFACE, que contém ponteiros para as rotinas individuais da interface. A rotina PnpGetLocationString fornece a parte específica do dispositivo da propriedade SPDRP_LOCATION_PATHS.