Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La enumeración dinámica es la capacidad del controlador para detectar y notificar cambios en el número y el tipo de dispositivos conectados al sistema mientras se ejecuta el sistema.
Los controladores de bus deben usar la enumeración dinámica si el número o los tipos de dispositivos conectados al dispositivo primario dependen de la configuración de un sistema. Algunos de estos dispositivos pueden estar siempre conectados al sistema, y algunos podrían estar conectados y desconectados mientras el sistema se está ejecutando.
Por ejemplo, el número y el tipo de dispositivos conectados al bus PCI de un sistema dependen del sistema, pero son permanentes a menos que un usuario desactive la alimentación, abra el caso y agregue o quite un dispositivo mediante un destornillador. Por otro lado, un usuario puede agregar o quitar dispositivos USB conectando o desconectando un cable mientras el sistema se está ejecutando.
Listas dinámicas hijas
El marco permite que los controladores admitan la enumeración dinámica proporcionando objetos de lista secundaria del marco. Cada objeto de lista secundaria representa una lista de dispositivos secundarios que están conectados a un dispositivo primario. El controlador de bus del dispositivo primario debe identificar los dispositivos secundarios del dispositivo primario, agregarlos a la lista de dispositivos secundarios del dispositivo primario y crear un objeto de dispositivo físico (PDO) para cada dispositivo secundario.
Cada vez que un controlador crea un objeto de dispositivo de marco que representa un FDO para un dispositivo, el marco crea una lista secundaria vacía y predeterminada para el dispositivo. El controlador puede obtener un identificador para la lista secundaria predeterminada de un dispositivo llamando a WdfFdoGetDefaultChildList. Normalmente, si escribe un controlador de bus que enumera los nodos hijos de un dispositivo, su controlador puede agregar nodos hijos a la lista hija predeterminada. Si necesita crear listas secundarias adicionales, el controlador puede llamar a WdfChildListCreate.
Para que un controlador pueda usar una lista secundaria, debe configurar el objeto child-list inicializando una estructura de WDF_CHILD_LIST_CONFIG y pasando la estructura a WdfFdoInitSetDefaultChildListConfig, para la lista secundaria predeterminada o a WdfChildListCreate, para listas secundarias adicionales.
Descripciones de hijo dinámicas
Cada vez que un controlador de bus identifica un dispositivo secundario, debe agregar la descripción del dispositivo secundario a una lista secundaria. Una subdescripción consta de una descripción de identificación necesaria y una descripción de dirección opcional.
Descripción de la identificación Una descripción de identificación es una estructura que contiene información que identifica de forma única cada dispositivo que el controlador enumera. El controlador define esta estructura, pero su primer miembro debe ser una estructura WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER .
Normalmente, una descripción de identificación contiene las cadenas de identificación del dispositivo, posiblemente un número de serie e información sobre la ubicación del dispositivo en el bus, como un número de ranura.
El controlador puede proporcionar el siguiente conjunto de funciones de devolución de llamada, que permiten al framework manipular la información dentro de una descripción de identificación.
EvtChildListIdentificationDescriptionCompare, que compara el contenido de dos estructuras de descripción de identificación.
EvtChildListIdentificationDescriptionCopy, que copia el contenido de una estructura de descripción de identificación en otra.
EvtChildListIdentificationDescriptionDuplicate, que crea una nueva descripción de identificación duplicando una estructura de descripción de identificación existente y, si es necesario, asignando búferes adicionales.
EvtChildListIdentificationDescriptionCleanup, que desasigna los búferes que fueron asignados por la función de devolución de llamada EvtChildListIdentificationDescriptionDuplicate.
Normalmente, debe proporcionar estas funciones de callback si las estructuras de descripción de identificación del controlador contienen punteros a búferes asignados dinámicamente. Para obtener más información sobre el propósito de estas funciones de devolución de llamada, consulte sus páginas de referencia.
Descripción de la dirección Una descripción de dirección es una estructura que contiene información que el controlador requiere para acceder al dispositivo en su bus, si la información puede cambiar mientras el dispositivo está conectado. El controlador define esta estructura, pero su primer miembro debe ser una estructura WDF_CHILD_ADDRESS_DESCRIPTION_HEADER .
Las descripciones de direcciones son opcionales. Si la información de dirección de un dispositivo no puede cambiar entre el momento en que se conecta el dispositivo y la hora en que está desconectada, toda la información de dirección del dispositivo se puede almacenar en una descripción de identificación. Por ejemplo, los controladores USB asignan direcciones a los dispositivos cuando los dispositivos están conectados y estas direcciones no cambian.
Por otro lado, algunos autobuses usan información de direccionamiento que puede cambiar. Por ejemplo, el bus IEEE 1394 usa un "recuento de generación", que es el número de restablecimientos de bus que se produjeron. Cada solicitud de E/S asincrónica a un dispositivo IEEE 1394 debe incluir el recuento de generaciones. Dado que esta información de dirección puede cambiar, el controlador debe almacenarla en una descripción de dirección.
Para manipular la información en una descripción de dirección, el controlador puede proporcionar el siguiente conjunto de callbacks:
EvtChildListAddressDescriptionCopy, que copia el contenido de una estructura de descripción de dirección en otra.
EvtChildListAddressDescriptionDuplicate, que crea una nueva descripción de dirección duplicando una estructura de descripción de dirección existente y, si es necesario, asignando búferes adicionales.
EvtChildListAddressDescriptionCleanup, que desasigna los búferes que la función de devolución de llamada EvtChildListAddressDescriptionDuplicate asignó.
Normalmente, debe proporcionar estas funciones de retorno de llamada si las estructuras de descripción de direcciones del controlador contienen punteros a búferes que se han asignado dinámicamente. Para obtener más información sobre el propósito de estas funciones de devolución de llamada, consulte sus páginas de referencia.
Agregar dispositivos a una lista de subordinados dinámica
Cuando el marco llama a la función de devolución de llamada EvtDriverDeviceAdd de un controlador de bus, la función de devolución de llamada debe llamar a WdfDeviceCreate para crear un FDO para el dispositivo primario, que suele ser un adaptador de bus. Para obtener más información sobre cómo crear un FDO, consulte Creación de objetos de dispositivo en un controlador de funciones. A continuación, el controlador debe enumerar los dispositivos secundarios del dispositivo primario y agregar los dispositivos secundarios a una lista secundaria.
Opcionalmente, el controlador puede llamar a WdfDeviceSetBusInformationForChildren para proporcionar al marco información sobre el bus. Se recomienda hacerlo porque facilita que los dispositivos y aplicaciones secundarios identifiquen el bus.
Para agregar dispositivos secundarios a una lista secundaria, el controlador debe llamar a WdfChildListAddOrUpdateChildDescriptionAsPresent para cada dispositivo secundario que encuentre. Esta llamada informa al framework que un controlador ha detectado un dispositivo hijo conectado a un dispositivo padre. Cuando el controlador llama a WdfChildListAddOrUpdateChildDescriptionAsPresent, proporciona una descripción de identificación y, opcionalmente, una descripción de dirección.
Una vez que el controlador llama a WdfChildListAddOrUpdateChildDescriptionAsPresent para notificar un nuevo dispositivo, el marco informa al administrador de PnP de que existe el nuevo dispositivo. El administrador de PnP crea una pila de dispositivos y una pila de controladores para el nuevo dispositivo. Como parte de este proceso, el marco llama a la función de devolución de llamada EvtChildListCreateDevice del controlador de bus. Esta función de devolución de llamada debe llamar a WdfDeviceCreate para crear un PDO para el nuevo dispositivo.
Normalmente, varios dispositivos secundarios están conectados a un dispositivo primario, por lo que el controlador de bus debe llamar a WdfChildListAddOrUpdateChildDescriptionAsPresent varias veces. La manera más eficaz de realizar este proceso es la siguiente:
Llame a WdfChildListBeginScan.
Llame a WdfChildListAddOrUpdateChildDescriptionAsPresent para cada dispositivo secundario.
Llame a WdfChildListEndScan.
Si rodea la enumeración dinámica del controlador con llamadas a WdfChildListBeginScan y WdfChildListEndScan, el framework almacena todos los cambios en la lista de elementos secundarios. Notifica al administrador de PnP los cambios cuando el controlador llama a WdfChildListEndScan. Posteriormente, el marco llama a la función de devolución de llamada EvtChildListCreateDevice del controlador de bus para cada dispositivo de la lista secundaria. Esta función de devolución de llamada llama a WdfDeviceCreate para crear un PDO para cada dispositivo nuevo.
Cuando el controlador llama a WdfChildListBeginScan, el marco marca todos los dispositivos notificados anteriormente como ya no están presentes. Por lo tanto, el controlador debe llamar a WdfChildListAddOrUpdateChildDescriptionAsPresent para todos los elementos secundarios que el controlador pueda detectar, no solo los elementos secundarios recién detectados. Para agregar un solo niño a una lista de niños, el controlador puede realizar una llamada a WdfChildListUpdateAllChildDescriptionsAsPresent sin necesidad de llamar primero a WdfChildListBeginScan.
Actualización de una lista secundaria dinámica
Para actualizar la información de una lista secundaria dinámica, use uno de los métodos siguientes:
Cuando un dispositivo primario recibe una interrupción que indica la llegada o eliminación de un dispositivo secundario, la función de devolución de llamada EvtInterruptDpc del controlador llama a WdfChildListAddOrUpdateChildDescriptionAsPresent si un dispositivo está conectado físicamente o WdfChildListUpdateChildDescriptionAsMissing si un dispositivo está desenchufado.
El controlador puede proporcionar una función de devolución de llamada EvtChildListScanForChildren, que el framework llama cada vez que el dispositivo principal entra en su estado de trabajo (D0). Esta función de devolución de llamada debe enumerar todos los dispositivos secundarios llamando a WdfChildListBeginScan, WdfChildListAddOrUpdateChildDescriptionAsPresent (o WdfChildListUpdateAllChildDescriptionsAsPresent) y WdfChildListEndScan.
Puede usar una o ambas técnicas en el controlador.
Recorrer una lista de hijos dinámica
Para examinar el contenido de una lista secundaria, el controlador puede recorrer la lista mediante una de las técnicas siguientes:
Para obtener, de uno en uno, el contenido de la descripción de cada dispositivo hijo, el controlador puede:
- Llame a WdfChildListBeginIteration.
- Llame a WdfChildListRetrieveNextDevice, tantas veces como sea necesario.
- Llame a WdfChildListEndIteration.
Al llamar a WdfChildListBeginIteration, el controlador especifica una marca con tipo WDF_RETRIEVE_CHILD_FLAGS que indica si el marco debe recuperar todas las descripciones del dispositivo o solo un subconjunto. Cuando WdfChildListRetrieveNextDevice encuentra una coincidencia, recupera la identificación y las descripciones de direcciones del dispositivo secundario, además de un identificador para su objeto de dispositivo.
Para obtener la descripción de la dirección contenida en ese momento en una descripción del dispositivo secundario, el controlador puede llamar a WdfChildListRetrieveAddressDescription, especificando una descripción de identificación. El marco recorre la lista secundaria hasta que encuentra un dispositivo secundario con una descripción de identificación coincidente. A continuación, recupera la descripción de la dirección.
Si necesita obtener un identificador para el objeto de dispositivo del framework asociado a un dispositivo secundario particular, el controlador puede llamar a WdfChildListRetrievePdo. El marco recorre la lista secundaria hasta que encuentra un dispositivo secundario con una descripción de identificación coincidente y, a continuación, devuelve un identificador de objeto de dispositivo. Para proteger al llamador de la eliminación repentina de PnP del PDO en otro subproceso, encapsula la llamada con WdfChildListBeginIteration y WdfChildListEndIteration.
Acceso a las descripciones de identificación y direcciones de un PDO
El controlador puede llamar a los métodos siguientes para acceder a la descripción de identificación o la descripción de la dirección de un PDO:
WdfPdoRetrieveIdentificationDescription, que recupera la descripción de identificación asociada a un PDO.
WdfPdoRetrieveAddressDescription, que recupera la descripción de la dirección asociada a un PDO.
WdfPdoUpdateAddressDescription, que actualiza la descripción de la dirección asociada a un PDO.
Gestión de solicitudes de reenumeración
Los controladores de bus basados en marco que admiten la enumeración dinámica pueden recibir una solicitud para volver a enumerar un dispositivo secundario determinado a través de la interfaz REENUMERATE_SELF_INTERFACE_STANDARD . Para obtener más información, consulta Control de solicitudes de enumeración.