USBD_QueryUsbCapability fonction (usbdlib.h)

La routine USBD_QueryUsbCapability est appelée par un pilote client WDM pour déterminer si la pile de pilotes USB sous-jacente et le matériel du contrôleur hôte prennent en charge une fonctionnalité spécifique. Remarque pour les pilotes WDF (Windows Driver Framework) : Si votre pilote client est un pilote WDF, vous devez appeler la méthode WdfUsbTargetDeviceQueryUsbCapability au lieu de USBD_QueryUsbCapability.

Syntaxe

NTSTATUS USBD_QueryUsbCapability(
  [in]            USBD_HANDLE USBDHandle,
  [in]            const GUID  *CapabilityType,
  [in]            ULONG       OutputBufferLength,
  [in, out]       PUCHAR      OutputBuffer,
  [out, optional] PULONG      ResultLength
);

Paramètres

[in] USBDHandle

Poignée USBD récupérée par le pilote client lors d’un appel précédent à la routine USBD_CreateHandle .

[in] CapabilityType

Pointeur vers un GUID qui représente la fonctionnalité pour laquelle le pilote client souhaite récupérer des informations. Les valeurs PGUID possibles sont les suivantes :

  • GUID_USB_CAPABILITY_CHAINED_MDLS
  • GUID_USB_CAPABILITY_STATIC_STREAMS
  • GUID_USB_CAPABILITY_SELECTIVE_SUSPEND
  • GUID_USB_CAPABILITY_FUNCTION_SUSPEND
  • GUID_USB_CAPABILITY_DEVICE_CONNECTION_HIGH_SPEED_COMPATIBLE
  • GUID_USB_CAPABILITY_DEVICE_CONNECTION_SUPER_SPEED_COMPATIBLE
  • GUID_USB_CAPABILITY_TIME_SYNC

[in] OutputBufferLength

Longueur, en octets, de la mémoire tampon pointée par OutputBuffer.

[in, out] OutputBuffer

Pointeur vers une mémoire tampon allouée par l’appelant. Certaines demandes de capacité retournent des informations supplémentaires dans une mémoire tampon de sortie. Pour ces requêtes, vous devez allouer la mémoire tampon et fournir un pointeur vers la mémoire tampon dans le paramètre OutputBuffer . Actuellement, seule la demande de capacité de flux statiques nécessite une mémoire tampon de sortie de type USHORT. La mémoire tampon est remplie par USBD_QueryUsbCapability avec le nombre maximal de flux pris en charge par point de terminaison.

Les autres demandes de capacité ne nécessitent pas de mémoire tampon de sortie. Pour ces demandes, vous devez définir OutputBuffer sur NULL et OutputBufferLength sur 0.

[out, optional] ResultLength

Pointeur vers une variable ULONG qui reçoit le nombre réel d’octets dans la mémoire tampon pointée par OutputBuffer. L’appelant peut passer la valeur NULL dans ResultLength. Si ResultLength n’a pas la valeur NULL, la valeur reçue est inférieure ou égale à la valeur OutputBufferLength .

Valeur retournée

La routine USBD_QueryUsbCapability retourne un code de status NT.

Les valeurs possibles incluent, sans s’y limiter, les codes status répertoriés dans le tableau suivant.

Code de retour Description
STATUS_SUCCESS
La demande a réussi et la fonctionnalité spécifiée est prise en charge.
STATUS_INVALID_PARAMETER
L’appelant a passé une valeur de paramètre non valide.
  • USBDHandle ou CapabilityType a la valeur NULL.
  • OutputBuffer a la valeur NULL, mais OutputBufferLength indique une valeur différente de zéro. À l’inverse, l’appelant a fourni une mémoire tampon de sortie, mais la longueur de la mémoire tampon est 0.
STATUS_NOT_IMPLEMENTED
La fonctionnalité spécifiée n’est pas prise en charge par la pile de pilotes USB sous-jacente.
STATUS_NOT_SUPPORTED
La fonctionnalité spécifiée n’est pas prise en charge ni par le matériel du contrôleur hôte ni par la pile de pilotes USB.

Remarques

Windows 8 inclut une nouvelle pile de pilotes USB pour prendre en charge les périphériques USB 3.0. La nouvelle pile de pilotes USB fournit plusieurs nouvelles fonctionnalités définies telles que la prise en charge des flux et les dll MDL chaînées qui peuvent être utilisées par un pilote client.

Un pilote client peut déterminer la version de la pile de pilotes USB sous-jacente en appelant la routine IsInterfaceVersionSupported .

Le pilote client peut utiliser les nouvelles fonctionnalités uniquement si la pile de pilotes USB sous-jacente et le matériel les prennent en charge. Par exemple, pour envoyer des demandes d’E/S à un flux particulier associé à un point de terminaison en bloc, la pile de pilotes USB sous-jacente, le point de terminaison et le matériel du contrôleur hôte doivent prendre en charge la fonctionnalité de flux statiques. Le pilote client ne doit pas appeler IsInterfaceVersionSupported et supposer les fonctionnalités de la pile de pilotes. Au lieu de cela, le pilote client doit toujours appeler USBD_QueryUsbCapability pour déterminer si la pile de pilotes USB et le matériel prennent en charge une fonctionnalité particulière.

Le tableau suivant décrit les fonctionnalités spécifiques à l’USB qu’un pilote client peut interroger par le biais d’un appel de USBD_QueryUsbCapability .

GUID de capacité Description
GUID_USB_CAPABILITY_CHAINED_MDLS Si la pile de pilotes USB prend en charge les dll MDL chaînées, le pilote client peut fournir les données de transfert sous la forme d’une chaîne de listes MDL qui référencent des mémoires tampons segmentées dans la mémoire physique. Pour plus d’informations, consultez MDL. Les dll MDL chaînées empêchent l’allocation et la copie de la mémoire pour créer des mémoires tampons pratiquement contiguës et, par conséquent, rendre les transferts d’E/S plus efficaces. Pour plus d’informations, consultez How to Send Chained MDLs.
GUID_USB_CAPABILITY_STATIC_STREAMS S’il est pris en charge, le pilote client peut envoyer des demandes d’E/S aux flux dans un point de terminaison en bloc.

Pour la requête de requête de flux statiques, le pilote client est requis pour fournir une mémoire tampon de sortie (USHORT). Une fois l’appel terminé et si la fonctionnalité de flux statiques est prise en charge, la mémoire tampon de sortie reçoit le nombre maximal de flux pris en charge par le contrôleur hôte.

La valeur de la mémoire tampon de sortie n’indique pas le nombre maximal de flux pris en charge par le point de terminaison en bloc dans l’appareil. Pour déterminer ce nombre, le pilote client doit inspecter le descripteur complémentaire du point de terminaison.

La pile de pilotes USB dans Windows 8 prend en charge jusqu’à 255 flux.

Si les flux statiques sont pris en charge, le pilote client peut envoyer des demandes d’E/S au premier flux (également appelé flux par défaut) à l’aide du handle de canal obtenu via une demande de configuration de sélection. Pour les autres flux dans le point de terminaison, le pilote client doit ouvrir ces flux et obtenir des handles de canal pour eux afin d’envoyer des demandes d’E/S. Pour plus d’informations sur l’ouverture de flux, consultez Comment ouvrir et fermer des flux statiques dans un point de terminaison en bloc USB.

GUID_USB_CAPABILITY_FUNCTION_SUSPEND Cette fonctionnalité détermine si la pile de pilotes USB sous-jacente prend en charge les fonctionnalités d’interruption de fonction USB et de Wake-Up à distance. Si elle est prise en charge, la pile de pilotes peut traiter un signal de reprise (pour une mise en éveil à distance) à partir d’une fonction individuelle dans un périphérique composite USB 3.0. En fonction de ce signal, un pilote de fonction individuel peut quitter l’état de faible puissance de sa fonction.

La fonctionnalité est destinée à être utilisée par un pilote composite : le pilote chargé en tant qu’objet de périphérique de fonction (FDO) dans la pile d’appareils pour l’appareil composite. Par défaut, le pilote parent générique USB (Usbccgp.sys) fourni par Microsoft est chargé en tant que FDO.

Si votre pilote remplace Usbccgp.sys, il doit être en mesure de demander une mise en éveil à distance et de propager le signal de reprise à partir de la pile de pilotes USB. Avant d’implémenter cette logique, le pilote doit déterminer la prise en charge de la pile de pilotes USB pour la fonctionnalité d’interruption de la fonction en appelant USBD_QueryUsbCapability. Usbccgp.sys dans Windows 8 implémente la suspension de fonction.

Pour obtenir un exemple de code et plus d’informations sur l’interruption de fonction, consultez Comment implémenter la suspension de fonction dans un pilote composite.

GUID_USB_CAPABILITY_SELECTIVE_SUSPEND Détermine si la pile de pilotes USB sous-jacente prend en charge la suspension sélective.

Pour plus d’informations sur la suspension sélective, consultez Suspension sélective USB.

GUID_USB_CAPABILITY_DEVICE_CONNECTION_HIGH_SPEED_COMPATIBLE Détermine si le bus fonctionne à grande vitesse ou à une vitesse supérieure.
GUID_USB_CAPABILITY_DEVICE_CONNECTION_SUPER_SPEED_COMPATIBLE Détermine si le bus fonctionne à SuperSpeed ou à une vitesse supérieure.
GUID_USB_CAPABILITY_TIME_SYNC Détermine si le numéro d’image et la fonctionnalité d’association QPC sont pris en charge sur le contrôleur. 
 

Exemples

L’extrait de code montre comment appeler USBD_QueryUsbCapability pour déterminer les fonctionnalités de la pile de pilotes USB sous-jacente.


/*++

Routine Description:
This helper routine queries the underlying USB driver stack
for specific capabilities. This code snippet assumes that 
USBD handle was retrieved by the client driver in a 
previous call to the USBD_CreateHandle routine.

Parameters:

fdo: Pointer to the device object that is the current top
of the stack as reported by IoAttachDeviceToDeviceStack.

Return Value: VOID
--*/

VOID QueryUsbDriverStackCaps (PDEVICE_OBJECT fdo)
{
    NTSTATUS ntStatus = STATUS_SUCCESS;   
    PDEVICE_EXTENSION deviceExtension;

    deviceExtension = (PDEVICE_EXTENSION)fdo->DeviceExtension;

    if (!deviceExtension->UsbdHandle)
    {
        return;
    }

    // Check if the underlying USB driver stack
    // supports USB 3.0 devices.

    if (!USBD_IsInterfaceVersionSupported(
        deviceExtension->UsbdHandle,                                       
        USBD_INTERFACE_VERSION_602))
    {
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Old USB stack loaded.\n" ));
    }
    else
    {
        // Call USBD_QueryUsbCapability to determine 
        // function suspend support.     
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "New USB stack loaded.\n" ));
        ntStatus = USBD_QueryUsbCapability ( deviceExtension->UsbdHandle,  
            (GUID*)&GUID_USB_CAPABILITY_FUNCTION_SUSPEND,  
            0,  
            NULL,
            NULL);

        if (NT_SUCCESS(ntStatus)) 
        {
            deviceExtension->FunctionSuspendSupported = TRUE;
            KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Function suspend supported.\n" ));
        } 
        else 
        {
            deviceExtension->FunctionSuspendSupported  = FALSE;
            ntStatus = STATUS_SUCCESS;
            KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Function suspend not supported.\n" ));
        }
    }

    // Call USBD_QueryUsbCapability to determine 
    // chained MDL support. 

    ntStatus = USBD_QueryUsbCapability(
        deviceExtension->UsbdHandle,
        (GUID*)&GUID_USB_CAPABILITY_CHAINED_MDLS,
        0,
        NULL,
        NULL);

    if (NT_SUCCESS(ntStatus)) 
    {
        deviceExtension->ChainedMDLSupport = TRUE;
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Chained MDLs supported.\n" ));
    } 
    else 
    {
        deviceExtension->ChainedMDLSupport = FALSE;
        ntStatus = STATUS_SUCCESS;
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Chained MDLs not supported.\n" ));
    }

    // Call USBD_QueryUsbCapability to determine 
    // stream support. 

    ntStatus = USBD_QueryUsbCapability (deviceExtension->UsbdHandle, 
        (GUID*)&GUID_USB_CAPABILITY_STATIC_STREAMS, 
        sizeof(ULONG), 
        (PUCHAR) &deviceExtension->MaxSupportedStreams, 
        NULL);  


    if (!NT_SUCCESS(ntStatus)) 
    {
        deviceExtension->MaxSupportedStreams = 0;
        ntStatus = STATUS_SUCCESS;
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Static streams not supported.\n" ));
    }

    // Call USBD_QueryUsbCapability to determine 
    // selective suspend support. 

    ntStatus = USBD_QueryUsbCapability (deviceExtension->UsbdHandle, 
        (GUID*)&GUID_USB_CAPABILITY_SELECTIVE_SUSPEND, 
        0, 
        NULL, 
        NULL);

    if (!NT_SUCCESS(ntStatus)) 
    {
        ntStatus = STATUS_SUCCESS;
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Selective suspend not supported.\n" ));
    }
    else
    {
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Selective suspend supported.\n" ));
    }

    // Call USBD_QueryUsbCapability to determine 
    // device speed. 
    ntStatus = USBD_QueryUsbCapability (deviceExtension->UsbdHandle, 
        (GUID*)&GUID_USB_CAPABILITY_DEVICE_CONNECTION_HIGH_SPEED_COMPATIBLE, 
        0, 
        NULL, 
        NULL);

    if (!NT_SUCCESS(ntStatus)) 
    {
        ntStatus = STATUS_SUCCESS;
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "The device is operating at full speed or lower.\n The device can operate at high speed or higher." ));
    }
    else
    {
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "The device is operating at high speed or higher.\n" ));
    }

    // Call USBD_QueryUsbCapability to determine 
    // device speed. 
    ntStatus = USBD_QueryUsbCapability (deviceExtension->UsbdHandle, 
        (GUID*)&GUID_USB_CAPABILITY_DEVICE_CONNECTION_SUPER_SPEED_COMPATIBLE, 
        0, 
        NULL, 
        NULL);

    if (!NT_SUCCESS(ntStatus)) 
    {
        ntStatus = STATUS_SUCCESS;
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "The device is operating at high speed or lower.\n The device can operate at Superspeed or higher." ));
    }
    else
    {
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "The device is operating at SuperSpeed or higher.\n" ));
    }

    return;

}

Configuration requise

Condition requise Valeur
Client minimal pris en charge Nécessite WDK pour Windows 8. Cible Windows Vista et les versions ultérieures du système d’exploitation Windows.
Plateforme cible Desktop (Expérience utilisateur)
En-tête usbdlib.h (inclure Usbdlib.h)
Bibliothèque Usbdex.lib
IRQL PASSIVE_LEVEL

Voir aussi

Informations de référence sur la programmation du pilote de périphérique USB