Partager via


fonction USBD_QueryUsbCapability (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

Handle USBD récupéré par le pilote client dans 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 de 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 fonctionnalité 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 fonctionnalité de flux statiques nécessite une mémoire tampon de sortie du 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 requêtes, 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 NULL dans ResultLength. Si ResultLength n’est pas NULL, la valeur reçue est inférieure ou égale à la valeur OutputBufferLength.

Valeur de retour

La routine USBD_QueryUsbCapability retourne un code d’état NT.

Les valeurs possibles incluent, mais ne sont pas limitées à, les codes d’état répertoriés dans le tableau suivant.

Retourner le code 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 par le matériel du contrôleur hôte ou la pile de pilotes USB.

Remarques

Windows 8 inclut une nouvelle pile de pilotes USB pour prendre en charge les appareils 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 MDL chaînés qui peuvent être utilisés 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 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 des 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 à USB qu’un pilote client peut interroger via un appel USBD_QueryUsbCapability.

GUID de fonctionnalité Description
GUID_USB_CAPABILITY_CHAINED_MDLS Si la pile de pilotes USB prend en charge les DLL chaînées, le pilote client peut fournir les données de transfert sous forme de chaîne de DLL qui font référence à des mémoires tampons segmentées en mémoire physique. Pour plus d’informations, consultez MDL . Les DLL chaînées empêchent l’allocation et la copie de la mémoire pour créer des mémoires tampons pratiquement contiguës, ce qui rend les transferts d’E/S plus efficaces. Pour plus d’informations, consultez Comment envoyer des DLL chaînées.
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 demande 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 du 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 de suspension 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 le ré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 : pilote chargé en tant qu’objet de périphérique de fonction (FDO) dans la pile d’appareils de l’appareil composite. Par défaut, le pilote parent générique USB fourni par Microsoft (Usbccgp.sys) est chargé en tant que FDO.

Si votre pilote remplace Usbccgp.sys, le pilote doit être en mesure de demander le ré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 fonction en appelant USBD_QueryUsbCapability. Usbccgp.sys dans Windows 8 implémente la suspension de la fonction.

Pour obtenir un exemple de code et plus d’informations sur la suspension de fonction, consultez Comment implémenter la suspension de fonction dans unde 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 de suspension sélective USB.

GUID_USB_CAPABILITY_DEVICE_CONNECTION_HIGH_SPEED_COMPATIBLE Détermine si le bus fonctionne à haute vitesse ou plus.
GUID_USB_CAPABILITY_DEVICE_CONNECTION_SUPER_SPEED_COMPATIBLE Détermine si le bus fonctionne à SuperSpeed ou supérieur.
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;

}

Exigences

Exigence Valeur
client minimum 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 Bureau
d’en-tête usbdlib.h (include 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