Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
A enumeração dinâmica é a capacidade do driver de detectar e relatar alterações no número e no tipo de dispositivos conectados ao sistema enquanto o sistema está em execução.
Os drivers de barramento devem usar enumeração dinâmica se o número ou os tipos de dispositivos conectados ao dispositivo pai dependerem da configuração de um sistema. Alguns desses dispositivos podem estar sempre conectados ao sistema, e alguns podem estar conectados e desconectados enquanto o sistema está em execução.
Por exemplo, o número e o tipo de dispositivos conectados ao barramento PCI de um sistema são dependentes do sistema, mas são permanentes, a menos que um usuário desligue a energia, abra a caixa e adicione ou remova um dispositivo usando uma chave de fenda. Por outro lado, um usuário pode adicionar ou remover dispositivos USB conectando ou desconectando um cabo enquanto o sistema está em execução.
Listas filho dinâmicas
A estrutura permite que os drivers ofereçam suporte à enumeração dinâmica fornecendo objetos de lista filho da estrutura. Cada objeto de lista filho representa uma lista de dispositivos filho conectados a um dispositivo pai. O driver de barramento do dispositivo pai deve identificar os dispositivos filhos do pai, adicioná-los à lista de filhos do dispositivo pai e criar um PDO (Physical Device Object - objeto de dispositivo físico) para cada filho.
Sempre que um driver cria um objeto de dispositivo do framework que atua como um FDO para um dispositivo, o framework cria uma lista de filhos vazia e padrão para o dispositivo. O driver pode obter um identificador para a lista filho padrão de um dispositivo chamando WdfFdoGetDefaultChildList. Normalmente, se você estiver escrevendo um motorista de ônibus que enumera os filhos de um dispositivo, seu motorista poderá adicionar filhos à lista de filhos padrão. Se você precisar criar listas de filhos extras, o driver poderá chamar WdfChildListCreate.
Antes que um driver possa usar uma lista de filhos, ele deve configurar o objeto da lista de filhos inicializando uma estrutura WDF_CHILD_LIST_CONFIG e passar a estrutura para WdfFdoInitSetDefaultChildListConfig, para a lista de filhos padrão, ou para WdfChildListCreate, para listas de filhos extras.
Descrições dinâmicas de subordinados
Sempre que um motorista de ônibus identifica um dispositivo filho, ele deve adicionar a descrição do dispositivo filho a uma lista filho. Uma descrição filho consiste em uma descrição de identificação necessária e uma descrição de endereço opcional.
Descrição de identificação Uma descrição de identificação é uma estrutura que contém informações que identificam exclusivamente cada dispositivo que o driver enumera. O driver define essa estrutura, mas seu primeiro membro deve ser uma estrutura WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER .
Normalmente, uma descrição de identificação contém as cadeias de caracteres de identificação do dispositivo, possivelmente um número de série e informações sobre a localização do dispositivo no barramento, como um número de slot.
O driver pode fornecer o seguinte conjunto de funções de retorno de chamada, que permitem que o framework manipule as informações em uma descrição de identificação:
EvtChildListIdentificationDescriptionCompare, que compara o conteúdo de duas estruturas de descrição de identificação.
EvtChildListIdentificationDescriptionCopy, que copia o conteúdo de uma estrutura de descrição de identificação para outra.
EvtChildListIdentificationDescriptionDuplicate, que cria uma nova descrição de identificação duplicando uma estrutura de descrição de identificação existente e, se necessário, alocando buffers extras.
EvtChildListIdentificationDescriptionCleanup, que desaloca buffers alocados pela função de retorno de chamada EvtChildListIdentificationDescriptionDuplicate .
Normalmente, se as estruturas de descrição de identificação do seu driver contiverem ponteiros para buffers alocados dinamicamente, você precisará fornecer essas funções de retorno de chamada. Para obter mais informações sobre a finalidade dessas funções de retorno de chamada, consulte suas páginas de referência.
Descrição do endereço Uma descrição de endereço é uma estrutura que contém informações que o driver precisa para acessar o dispositivo em seu barramento, se as informações puderem ser alteradas enquanto o dispositivo estiver conectado. O driver define essa estrutura, mas seu primeiro membro deve ser uma estrutura WDF_CHILD_ADDRESS_DESCRIPTION_HEADER.
Descrições de endereço são opcionais. Se as informações de endereço de um dispositivo não puderem ser alteradas entre a hora em que o dispositivo estiver conectado e a hora em que ele estiver desconectado, todas as informações de endereço do dispositivo poderão ser armazenadas em uma descrição de identificação. Por exemplo, os controladores USB atribuem endereços a dispositivos quando os dispositivos estão conectados e esses endereços não são alterados.
Por outro lado, alguns ônibus usam informações de endereçamento que podem ser alteradas. Por exemplo, o barramento IEEE 1394 usa uma "contagem de geração", que é o número de redefinições do barramento que ocorreram. Cada solicitação de E/S assíncrona para um dispositivo IEEE 1394 deve incluir a contagem de geração. Como essas informações de endereço podem ser alteradas, o driver deve armazená-la em uma descrição de endereço.
Para manipular as informações em uma descrição de endereço, o driver pode fornecer o seguinte conjunto de callbacks:
EvtChildListAddressDescriptionCopy, que copia o conteúdo de uma estrutura de descrição de endereço para outra.
EvtChildListAddressDescriptionDuplicate, que cria uma nova descrição de endereço duplicando uma estrutura de descrição de endereço existente e, se necessário, alocando buffers extras.
EvtChildListAddressDescriptionCleanup, que desaloca buffers alocados pela função de retorno de chamada EvtChildListAddressDescriptionDuplicate.
Normalmente, você precisará fornecer essas funções de retorno de chamada se as estruturas de descrição do endereço do driver contiverem ponteiros para buffers alocados dinamicamente. Para obter mais informações sobre a finalidade dessas funções de retorno de chamada, consulte suas páginas de referência.
Adicionando dispositivos a uma lista filho dinâmica
Quando o framework chama a função de retorno de chamada EvtDriverDeviceAdd de um driver de barramento, a função de retorno de chamada deve chamar WdfDeviceCreate para criar um FDO para o dispositivo pai, que normalmente é um adaptador de barramento. Para obter mais informações sobre como criar um FDO, consulte Criando objetos de dispositivo em um driver de função. Em seguida, o driver deve enumerar os filhos do dispositivo pai e adicionar os filhos a uma lista filho.
Opcionalmente, o driver pode chamar WdfDeviceSetBusInformationForChildren para fornecer à estrutura informações sobre o barramento. É recomendável fazer isso porque facilita a identificação do barramento por dispositivos e aplicativos subordinados.
Para adicionar filhos a uma lista de filhos, o driver deve chamar WdfChildListAddOrUpdateChildDescriptionAsPresent para cada dispositivo filho encontrado. Essa chamada informa ao framework que um driver descobriu um dispositivo filho conectado a um dispositivo pai. Quando o driver chama WdfChildListAddOrUpdateChildDescriptionAsPresent, ele fornece uma descrição de identificação e, opcionalmente, uma descrição de endereço.
Depois que o driver chama WdfChildListAddOrUpdateChildDescriptionAsPresent para relatar um novo dispositivo, o framework informa ao gerenciador PnP que o novo dispositivo existe. O gerenciador PnP cria uma pilha de dispositivos e uma pilha de driver para o novo dispositivo. Como parte desse processo, a estrutura chama a função de retorno de chamada EvtChildListCreateDevice do driver de ônibus. Essa função callback deve chamar WdfDeviceCreate para criar um PDO para o novo dispositivo.
Normalmente, vários dispositivos filho são conectados a um pai, portanto, o motorista do ônibus precisa chamar WdfChildListAddOrUpdateChildDescriptionAsPresent várias vezes. A maneira mais eficiente de fazer esse processo é a seguinte:
Chame WdfChildListBeginScan.
Utilize WdfChildListAddOrUpdateChildDescriptionAsPresent para cada dispositivo filho.
Chame WdfChildListEndScan.
Se você cercar a enumeração dinâmica do driver com chamadas para WdfChildListBeginScan e WdfChildListEndScan, o framework armazenará todas as alterações na lista de filhos. Ele notifica o gerente PnP das alterações quando o driver chama WdfChildListEndScan. Posteriormente, a estrutura chama a função de retorno de chamada EvtChildListCreateDevice do driver de ônibus para cada dispositivo na lista filho. Essa função de retorno de chamada chama WdfDeviceCreate para criar um PDO para cada novo dispositivo.
Quando o driver chama WdfChildListBeginScan, o framework marca todos os dispositivos relatados anteriormente como não estando mais presentes. Portanto, o driver deve chamar WdfChildListAddOrUpdateChildDescriptionAsPresent para todas as crianças que o driver pode detectar, não apenas crianças recém-descobertas. Para adicionar um único filho a uma lista de filhos, o driver pode fazer uma única vez a chamada para WdfChildListUpdateAllChildDescriptionsAsPresent sem primeiro chamar WdfChildListBeginScan.
Atualizando uma lista filho dinâmica
Para atualizar as informações em uma lista filho dinâmica, use um dos seguintes métodos:
Quando um dispositivo pai recebe uma interrupção que indica a chegada ou remoção de um filho, a função de retorno de chamada EvtInterruptDpc do driver chama WdfChildListAddOrUpdateChildDescriptionAsPresent se um dispositivo estiver conectado ou WdfChildListUpdateChildDescriptionAsMissing se um dispositivo estiver removido.
O driver pode fornecer uma função de retorno de chamada EvtChildListScanForChildren que o framework chama sempre que o dispositivo pai entra em seu estado de trabalho (D0). Essa função de callback deve enumerar todos os dispositivos filhos chamando WdfChildListBeginScan, WdfChildListAddOrUpdateChildDescriptionAsPresent (ou WdfChildListUpdateAllChildDescriptionsAsPresent) e WdfChildListEndScan.
Você pode usar uma ou ambas essas técnicas em seu driver.
Percorrendo uma lista de filhos dinâmica
Para examinar o conteúdo de uma lista filho, o driver pode percorrer a lista usando uma das seguintes técnicas:
Para obter o conteúdo de cada descrição de dispositivo filho, uma de cada vez, o driver pode:
- Chame WdfChildListBeginIteration.
- Chame WdfChildListRetrieveNextDevice, quantas vezes for necessário.
- Chame WdfChildListEndIteration.
Ao chamar WdfChildListBeginIteration, o driver especifica um sinalizador tipo WDF_RETRIEVE_CHILD_FLAGS que indica se a estrutura deve recuperar todas as descrições do dispositivo ou apenas um subconjunto. Quando WdfChildListRetrieveNextDevice encontra uma correspondência, ele recupera as descrições de identificação e endereço do dispositivo filho, além de um handle para seu objeto de dispositivo.
Para obter a descrição do endereço atualmente contida em uma descrição de dispositivo filho, seu driver pode chamar WdfChildListRetrieveAddressDescription, especificando uma descrição de identificação. A estrutura percorre a lista de filhos até encontrar um dispositivo secundário com uma descrição de identificação correspondente. Em seguida, recupera a descrição do endereço.
Se você precisar obter um handle para o objeto de dispositivo do framework associado a um dispositivo filho específico, seu driver poderá chamar WdfChildListRetrievePdo. A estrutura percorre a lista filho até encontrar um dispositivo filho com uma descrição de identificação correspondente e, em seguida, retorna um identificador de objeto do dispositivo. Para proteger o chamador contra a remoção PnP repentina do PDO em outro thread, encapsule a chamada com WdfChildListBeginIteration e WdfChildListEndIteration.
Acessando as descrições de identificação e endereço de um PDO
O seu driver pode chamar os métodos a seguir para acessar a descrição de identificação ou de endereço de um PDO:
WdfPdoRetrieveIdentificationDescription, que recupera a descrição de identificação associada a um PDO.
WdfPdoRetrieveAddressDescription, que recupera a descrição do endereço associada a um PDO.
WdfPdoUpdateAddressDescription, que atualiza a descrição do endereço associada a um PDO.
Tratamento de solicitações de renumeração
Os drivers de barramento baseados em framework que dão suporte à enumeração dinâmica podem receber uma solicitação para reenumerar um determinado dispositivo filho por meio da interface REENUMERATE_SELF_INTERFACE_STANDARD. Para obter mais informações, consulte Tratamento de Solicitações de Enumeração.