다음을 통해 공유


USBD_QueryUsbCapability 함수(usbdlib.h)

USBD_QueryUsbCapability 루틴은 기본 USB 드라이버 스택과 호스트 컨트롤러 하드웨어가 특정 기능을 지원하는지 여부를 확인하기 위해 WDM 클라이언트 드라이버에 의해 호출됩니다. WDF(Windows 드라이버 프레임워크) 드라이버에 대한 참고 사항: 클라이언트 드라이버가 WDF 기반 드라이버인 경우 USBD_QueryUsbCapability대신 WdfUsbTargetDeviceQueryUsbCapability 메서드를 호출해야 합니다.

통사론

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

매개 변수

[in] USBDHandle

USBD_CreateHandle 루틴에 대한 이전 호출에서 클라이언트 드라이버가 검색한 USBD 핸들입니다.

[in] CapabilityType

클라이언트 드라이버가 정보를 검색하려는 기능을 나타내는 GUID에 대한 포인터입니다. 가능한 PGUID 값은 다음과 같습니다.

  • 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

OutputBuffer 가리키는 버퍼의 길이(바이트)입니다.

[in, out] OutputBuffer

호출자가 할당한 버퍼에 대한 포인터입니다. 특정 기능 요청은 출력 버퍼에 추가 정보를 반환합니다. 이러한 요청의 경우 버퍼를 할당하고 OutputBuffer 매개 변수의 버퍼에 대한 포인터를 제공해야 합니다. 현재 정적 스트림 기능 요청만 USHORT 형식의 출력 버퍼가 필요합니다. 버퍼는 엔드포인트당 지원되는 최대 스트림 수로 USBD_QueryUsbCapability 채워집니다.

다른 기능 요청에는 출력 버퍼가 필요하지 않습니다. 이러한 요청의 경우 OutputBuffer NULL로 설정하고 OutputBufferLength 0으로 설정해야 합니다.

[out, optional] ResultLength

OutputBuffer가리키는 버퍼의 실제 바이트 수를 수신하는 ULONG 변수에 대한 포인터입니다. 호출자는 ResultLengthNULL을 전달할 수 있습니다. ResultLength NULL이 아니면 수신된 값이 OutputBufferLength 값보다 작거나 같습니다.

반환 값

USBD_QueryUsbCapability 루틴은 NT 상태 코드를 반환합니다.

가능한 값은 다음 표에 나열된 상태 코드를 포함하지만 제한되지는 않습니다.

반환 코드 묘사
STATUS_SUCCESS
요청이 성공했으며 지정된 기능이 지원됩니다.
STATUS_INVALID_PARAMETER
호출자가 잘못된 매개 변수 값을 전달했습니다.
  • USBDHandle 또는 CapabilityType NULL입니다.
  • OutputBuffer NULL이지만 outputBufferLength 0이 아닌 값을 나타냅니다. 반대로 호출자는 출력 버퍼를 제공했지만 버퍼 길이는 0입니다.
STATUS_NOT_IMPLEMENTED
지정된 기능은 기본 USB 드라이버 스택에서 지원되지 않습니다.
STATUS_NOT_SUPPORTED
지정된 기능은 호스트 컨트롤러 하드웨어 또는 USB 드라이버 스택에서 지원되지 않습니다.

발언

Windows 8에는 USB 3.0 디바이스를 지원하는 새로운 USB 드라이버 스택이 포함되어 있습니다. 새 USB 드라이버 스택은 클라이언트 드라이버에서 사용할 수 있는 스트림 지원 및 연결된 MDL과 같이 정의된 몇 가지 새로운 기능을 제공합니다.

클라이언트 드라이버는 IsInterfaceVersionSupported 루틴을 호출하여 기본 USB 드라이버 스택의 버전을 확인할 수 있습니다.

클라이언트 드라이버는 기본 USB 드라이버 스택 하드웨어에서 지원하는 경우에만 새 기능을 사용할 수. 예를 들어 대량 엔드포인트와 연결된 특정 스트림에 I/O 요청을 보내려면 기본 USB 드라이버 스택, 엔드포인트 및 호스트 컨트롤러 하드웨어가 정적 스트림 기능을 지원해야 합니다. 클라이언트 드라이버 isInterfaceVersionSupported 호출하지 드라이버 스택의 기능을 가정하면 안 됩니다. 대신 클라이언트 드라이버 항상 USBD_QueryUsbCapability 호출하여 USB 드라이버 스택 및 하드웨어가 특정 기능을 지원하는지 여부를 확인하기 합니다.

다음 표에서는 클라이언트 드라이버가 USBD_QueryUsbCapability 호출을 통해 쿼리할 수 있는 USB 관련 기능에 대해 설명합니다.

기능 GUID 묘사
GUID_USB_CAPABILITY_CHAINED_MDLS USB 드라이버 스택이 연결된 MDL을 지원하는 경우 클라이언트 드라이버는 물리적 메모리에서 분할된 버퍼를 참조하는 MDL 체인으로 전송 데이터를 제공할 수 있습니다. 자세한 내용은 MDL 참조하세요. 연결된 MDL은 메모리를 할당하고 복사하여 사실상 연속 버퍼를 만들고 따라서 I/O 전송을 보다 효율적으로 만들 필요가 없습니다. 자세한 내용은 연결된 MDL보내는 방법을 참조하세요.
GUID_USB_CAPABILITY_STATIC_STREAMS 지원되는 경우 클라이언트 드라이버는 대량 엔드포인트의 스트림에 I/O 요청을 보낼 수 있습니다.

정적 스트림 쿼리 요청의 경우 클라이언트 드라이버는 출력 버퍼(USHORT)를 제공해야 합니다. 호출이 완료되고 정적 스트림 기능이 지원되면 출력 버퍼는 호스트 컨트롤러에서 지원되는 최대 스트림 수를 받습니다.

출력 버퍼 값은 디바이스의 대량 엔드포인트에서 지원하는 최대 스트림 수를 나타내지 않습니다. 해당 수를 확인하려면 클라이언트 드라이버가 엔드포인트 도우미 설명자를 검사해야 합니다.

Windows 8의 USB 드라이버 스택은 최대 255개의 스트림을 지원합니다.

정적 스트림이 지원되는 경우 클라이언트 드라이버는 select-configuration 요청을 통해 얻은 파이프 핸들을 사용하여 첫 번째 스트림(기본 스트림이라고도 함)에 I/O 요청을 보낼 수 있습니다. 엔드포인트의 다른 스트림의 경우 클라이언트 드라이버는 해당 스트림을 열고 I/O 요청을 보내기 위해 해당 스트림에 대한 파이프 핸들을 가져와야 합니다. 스트림 열기에 대한 자세한 내용은 USB 대량 엔드포인트정적 스트림을 열고 닫는 방법을 참조하세요.

GUID_USB_CAPABILITY_FUNCTION_SUSPEND 이 기능은 기본 USB 드라이버 스택이 USB 함수 일시 중단 및 원격 Wake-Up 기능을 지원하는지 여부를 결정합니다. 지원되는 경우 드라이버 스택은 USB 3.0 복합 디바이스의 개별 함수에서 다시 시작 신호(원격 절전 모드 해제용)를 처리할 수 있습니다. 해당 신호에 따라 개별 함수 드라이버는 해당 함수의 저전력 상태를 종료할 수 있습니다.

이 기능은 복합 드라이버( 복합 디바이스에 대한 디바이스 스택에서 FDO(함수 디바이스 개체)로 로드되는 드라이버에서 사용됩니다. 기본적으로 Microsoft에서 제공하는 USB 제네릭 부모 드라이버(Usbccgp.sys)는 FDO로 로드됩니다.

드라이버가 Usbccgp.sys교체하는 경우 드라이버는 원격 절전 모드 해제를 요청하고 USB 드라이버 스택에서 다시 시작 신호를 전파할 수 있어야 합니다. 해당 논리를 구현하기 전에 드라이버는 USBD_QueryUsbCapability호출하여 함수 일시 중단 기능에 대한 USB 드라이버 스택의 지원을 결정해야 합니다. Windows 8의 Usbccgp.sys 함수 일시 중단을 구현합니다.

코드 예제 및 함수 일시 중단에 대한 자세한 내용은 복합 드라이버 함수 일시 중단을 구현하는 방법참조하세요.

GUID_USB_CAPABILITY_SELECTIVE_SUSPEND 기본 USB 드라이버 스택이 선택적 일시 중단을 지원하는지 여부를 결정합니다.

선택적 일시 중단에 대한 자세한 내용은 USB 선택적 일시 중단참조하세요.

GUID_USB_CAPABILITY_DEVICE_CONNECTION_HIGH_SPEED_COMPATIBLE 버스가 고속 또는 그 이상으로 운행되는지 여부를 결정합니다.
GUID_USB_CAPABILITY_DEVICE_CONNECTION_SUPER_SPEED_COMPATIBLE 버스가 SuperSpeed 이상에서 운행되는지 여부를 결정합니다.
GUID_USB_CAPABILITY_TIME_SYNC 컨트롤러에서 프레임 번호 및 QPC 연결 기능이 지원되는지 여부를 결정합니다. 
 

예제

코드 조각은 USBD_QueryUsbCapability 호출하여 기본 USB 드라이버 스택의 기능을 확인하는 방법을 보여줍니다.


/*++

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;

}

요구 사항

요구
지원되는 최소 클라이언트 Windows 8용 WDK가 필요합니다. Windows Vista 이상 버전의 Windows 운영 체제를 대상으로 합니다.
대상 플랫폼 바탕 화면
헤더 usbdlib.h(Usbdlib.h 포함)
라이브러리 Usbdex.lib
IRQL PASSIVE_LEVEL

참고 항목

USB 디바이스 드라이버 프로그래밍 참조