Condividi tramite


funzione USBD_QueryUsbCapability (usbdlib.h)

La routine USBD_QueryUsbCapability viene chiamata da un driver client WDM per determinare se lo stack di driver USB sottostante e l'hardware del controller host supportano una funzionalità specifica. Nota per driver Windows Driver Framework (WDF): Se il driver client è un driver basato su WDF, è necessario chiamare il metodo WdfUsbTargetDeviceQueryUsbCapability anziché USBD_QueryUsbCapability.

Sintassi

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

Parametri

[in] USBDHandle

Handle USBD recuperato dal driver client in una chiamata precedente alla routine USBD_CreateHandle .

[in] CapabilityType

Puntatore a un GUID che rappresenta la funzionalità per cui il driver client desidera recuperare informazioni. I possibili valori PGUID sono i seguenti:

  • 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

Lunghezza, in byte, del buffer a cui punta OutputBuffer.

[in, out] OutputBuffer

Puntatore a un buffer allocato dal chiamante. Alcune richieste di funzionalità restituiscono informazioni aggiuntive in un buffer di output. Per tali richieste, è necessario allocare il buffer e fornire un puntatore al buffer nel parametro OutputBuffer . Attualmente, solo la richiesta di funzionalità flussi statici richiede un buffer di output del tipo USHORT. Il buffer viene riempito da USBD_QueryUsbCapability con il numero massimo di flussi supportati per endpoint.

Altre richieste di funzionalità non richiedono un buffer di output. Per tali richieste, è necessario impostare OutputBuffer su NULL e OutputBufferLength su 0.

[out, optional] ResultLength

Puntatore a una variabile ULONG che riceve il numero effettivo di byte nel buffer a cui punta OutputBuffer. Il chiamante può passare NULL in ResultLength. Se ResultLength non è NULL, il valore ricevuto è minore o uguale al valore OutputBufferLength .

Valore restituito

La routine USBD_QueryUsbCapability restituisce un codice di stato NT.

I valori possibili includono, ma non sono limitati, i codici di stato elencati nella tabella seguente.

Codice restituito Descrizione
STATUS_SUCCESS
La richiesta ha avuto esito positivo e la funzionalità specificata è supportata.
STATUS_INVALID_PARAMETER
Il chiamante ha passato un valore di parametro non valido.
  • USBDHandle o CapabilityType è NULL.
  • OutputBuffer è NULL, ma OutputBufferLength indica un valore diverso da zero. Al contrario, il chiamante ha fornito un buffer di output, ma la lunghezza del buffer è 0.
STATUS_NOT_IMPLEMENTED
La funzionalità specificata non è supportata dallo stack di driver USB sottostante.
STATUS_NOT_SUPPORTED
La funzionalità specificata non è supportata dall'hardware del controller host o dallo stack di driver USB.

Commenti

Windows 8 include un nuovo stack di driver USB per supportare dispositivi USB 3.0. Il nuovo stack di driver USB offre diverse nuove funzionalità definite, ad esempio, il supporto del flusso e gli MDL concatenati che possono essere usati da un driver client.

Un driver client può determinare la versione dello stack di driver USB sottostante chiamando la routine IsInterfaceVersionSupported .

Il driver client può usare le nuove funzionalità solo se lo stack di driver USB e l'hardware sottostanti li supportano. Ad esempio, per inviare richieste di I/O a un flusso specifico associato a un endpoint in blocco, lo stack di driver USB sottostante, l'endpoint e l'hardware del controller host devono supportare la funzionalità dei flussi statici. Il driver client non deve chiamare IsInterfaceVersionSupported e presupporre le funzionalità dello stack di driver. Al contrario, il driver client deve sempre chiamare USBD_QueryUsbCapability per determinare se lo stack di driver USB e l'hardware supportano una particolare funzionalità.

Nella tabella seguente vengono descritte le funzionalità specifiche di USB su cui un driver client può eseguire query tramite una chiamata USBD_QueryUsbCapability .

GUID funzionalità Descrizione
GUID_USB_CAPABILITY_CHAINED_MDLS Se lo stack di driver USB supporta gli ELENCHI MDL concatenati, il driver client può fornire i dati di trasferimento come catena di MDL che fanno riferimento a buffer segmentati in memoria fisica. Per altre informazioni, vedere MDL. Gli MDL concatenati impediscono la necessità di allocare e copiare memoria per creare buffer virtualmente contigui e quindi rendere più efficienti i trasferimenti di I/O. Per altre informazioni, vedere How to Send Chained MDLs .For more information, see How to Send Chained MDLs.
GUID_USB_CAPABILITY_STATIC_STREAMS Se supportato, il driver client può inviare richieste di I/O ai flussi in un endpoint in blocco.

Per la richiesta di query dei flussi statici, il driver client è necessario per fornire un buffer di output (USHORT). Al termine della chiamata e se la funzionalità flussi statici è supportata, il buffer di output riceve il numero massimo di flussi supportati dal controller host.

Il valore del buffer di output non indica il numero massimo di flussi supportati dall'endpoint in blocco nel dispositivo. Per determinare tale numero, il driver client deve controllare il descrittore complementare dell'endpoint.

Lo stack di driver USB in Windows 8 supporta fino a 255 flussi.

Se sono supportati flussi statici, il driver client può inviare richieste di I/O al primo flusso (detto anche flusso predefinito) usando l'handle pipe ottenuto tramite una richiesta di configurazione di selezione. Per altri flussi nell'endpoint, il driver client deve aprire tali flussi e ottenere handle di pipe per l'invio di richieste di I/O. Per altre informazioni sull'apertura dei flussi, vedere Come aprire e chiudere flussi statici in un endpoint bulk USB.

GUID_USB_CAPABILITY_FUNCTION_SUSPEND Questa funzionalità determina se lo stack di driver USB sottostante supporta le funzionalità di sospensione della funzione USB e remote Wake-Up. Se supportato, lo stack di driver può elaborare un segnale di ripresa (per la riattivazione remota) da una singola funzione in un dispositivo composito USB 3.0. In base a tale segnale, un singolo driver di funzione può uscire dallo stato di bassa potenza della relativa funzione.

La funzionalità deve essere usata da un driver composito: il driver caricato come oggetto dispositivo funzione nello stack di dispositivi per il dispositivo composito. Per impostazione predefinita, il driver padre generico (Usbccgp.sys) fornito da Microsoft viene caricato come fdO.

Se il driver sostituisce Usbccgp.sys, il driver deve essere in grado di richiedere la riattivazione remota e propagare il segnale di ripresa dallo stack di driver USB. Prima di implementare tale logica, il driver deve determinare il supporto dello stack di driver USB per la funzionalità di sospensione della funzione chiamando USBD_QueryUsbCapability. Usbccgp.sys in Windows 8 implementa la sospensione della funzione.

Per un esempio di codice e altre informazioni sulla sospensione della funzione, vedere How to Implement Function Suspend in a Composite Driver.For a code example and more information about function suspend, see How to Implement Function Suspend in a Composite Driver.

GUID_USB_CAPABILITY_SELECTIVE_SUSPEND Determina se lo stack di driver USB sottostante supporta la sospensione selettiva.

Per informazioni sulla sospensione selettiva, vedere Sospensione selettiva USB.

GUID_USB_CAPABILITY_DEVICE_CONNECTION_HIGH_SPEED_COMPATIBLE Determina se l'autobus funziona ad alta velocità o superiore.
GUID_USB_CAPABILITY_DEVICE_CONNECTION_SUPER_SPEED_COMPATIBLE Determina se l'autobus funziona a SuperSpeed o superiore.
GUID_USB_CAPABILITY_TIME_SYNC Determina se il numero di frame e la funzionalità di associazione QPC sono supportati nel controller. 
 

Esempio

Il frammento di codice mostra come chiamare USBD_QueryUsbCapability per determinare le funzionalità dello stack di driver USB sottostante.


/*++

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;

}

Requisiti

Requisito Valore
Client minimo supportato Richiede WDK per Windows 8. È destinato a Windows Vista e versioni successive del sistema operativo Windows.
Piattaforma di destinazione Desktop
Intestazione usbdlib.h (includono Usbdlib.h)
Libreria Usbdex.lib
IRQL PASSIVE_LEVEL

Vedi anche

Informazioni di riferimento sulla programmazione del driver di dispositivo USB