2016-04-15 9 views
2

Ich benutze Setup-API-Funktionen, um ein USB-Gerät zu finden, und verwende dann createfile, um mit ihm zu kommunizieren. d. h. mit SetupDiGetClassDevs, SetupDiEnumDeviceInterfaces, SetupDiGetDeviceInterfaceDetail usw.So erkennen Sie die USB-Geschwindigkeit unter Windows

Ich möchte feststellen können, ob das Gerät mit USB2-Geschwindigkeiten oder USB3-Geschwindigkeiten verbunden ist, dh. SuperSpeed ​​oder nicht

Wie kann ich dies über die Windows-APIs tun?

Antwort

0

Ich denke, Sie müssen versuchen, WinUSB in der Verbindung gibt es einen Beispielcode für die Erkennung der Geschwindigkeit von USB. Wenn Sie die Beschreibung von WinUSB wollen, finden Sie diese unter here.

+0

Das Gerät, mit dem ich spreche, ist kein WinUSB.sys-Gerät. Gibt es nicht eine allgemeinere Art, dies zu bestimmen? – MrMoDoJoJr

0

Dies ist, was ich am Ende ging. Es ist verschachtelt. Kann nicht glauben, es gibt keinen einfacheren Weg:

#include "stdafx.h" 

#include <Windows.h> 
#include <Setupapi.h> 
#include <winusb.h> 

#undef LowSpeed 
#include <Usbioctl.h> 

#include <iostream> 
#include <string> 
#include <memory> 
#include <vector> 

class Usb_Device 
{ 
private: 
    std::wstring _driverKey; 
    char _speed; 

public: 
    Usb_Device(int adapterNumber, std::wstring devicePath, char speed); 

    virtual char GetSpeed(std::wstring driverKey); 
}; 

class Usb_Hub : public Usb_Device 
{ 
private: 
    bool _isRootHub; 
    std::wstring _deviceDescription; 
    std::wstring _devicePath; 

    std::vector<std::unique_ptr<Usb_Device>> _devices; 

public: 
    Usb_Hub(std::wstring devicePath, char speed); 

    virtual char GetSpeed(std::wstring driverKey) override; 
}; 

class Usb_Controller 
{ 
private: 

    GUID _interfaceClassGuid; 
    std::wstring _devicePath; 
    std::wstring _deviceDescription; 
    std::wstring _driverKey; 

    std::vector<std::unique_ptr<Usb_Device>> _devices; 

public: 
    Usb_Controller(); 

    char GetSpeed(std::wstring driverKey); 
}; 

static std::unique_ptr<Usb_Device> BuildDevice(int portCount, std::wstring devicePath) 
{ 
    std::unique_ptr<Usb_Device> ret; 

    HANDLE handle = INVALID_HANDLE_VALUE; 

    DWORD bytes = -1; 
    DWORD bytesReturned = -1; 
    BOOL isConnected = FALSE; 
    char speed; 

    // Open a handle to the Hub device 
    handle = CreateFile(devicePath.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); 
    if (handle != INVALID_HANDLE_VALUE) 
    { 
     bytes = sizeof(USB_NODE_CONNECTION_INFORMATION_EX); 
     PUSB_NODE_CONNECTION_INFORMATION_EX nodeConnection = (PUSB_NODE_CONNECTION_INFORMATION_EX)(new char[bytes]); 

     nodeConnection->ConnectionIndex = portCount; 

     if (DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, nodeConnection, bytes, nodeConnection, bytes, &bytesReturned, 0)) 
     { 
      isConnected = nodeConnection->ConnectionStatus == USB_CONNECTION_STATUS::DeviceConnected; 
      speed = nodeConnection->Speed; 
     } 

     if (isConnected) 
     { 
      if (nodeConnection->DeviceDescriptor.bDeviceClass == 0x09 /*HubDevice*/) 
      { 
       bytes = sizeof(USB_NODE_CONNECTION_NAME); 
       PUSB_NODE_CONNECTION_NAME nodeConnectionName = (PUSB_NODE_CONNECTION_NAME)(new char[bytes]); 
       nodeConnectionName->ConnectionIndex = portCount; 

       if (DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_NAME, nodeConnectionName, bytes, nodeConnectionName, bytes, &bytesReturned, 0)) 
       { 
        bytes = nodeConnectionName->ActualLength; 
        delete[] nodeConnectionName; 

        nodeConnectionName = (PUSB_NODE_CONNECTION_NAME)(new char[bytes]); 
        nodeConnectionName->ConnectionIndex = portCount; 

        if (DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_NAME, nodeConnectionName, bytes, nodeConnectionName, bytes, &bytesReturned, 0)) 
        { 
         std::wstring name = std::wstring(L"\\\\?\\") + std::wstring(nodeConnectionName->NodeName); 
         ret = std::unique_ptr<Usb_Device>(new Usb_Hub(name, speed)); 
        } 
       } 

       delete[] nodeConnectionName; 
      } 
      else 
      { 
       ret = std::unique_ptr<Usb_Device>(new Usb_Device(portCount, devicePath, speed)); 
      } 
     } 
     else 
     { 
      // Chuck this device 
     } 

     delete[] nodeConnection; 
     CloseHandle(handle); 
    } 

    return ret; 
} 

Usb_Controller::Usb_Controller() 
{ 
    BOOL success = TRUE; 
    for (int index = 0; success; index++) 
    { 
     GUID guid; 
     HRESULT hr = CLSIDFromString(L"{3abf6f2d-71c4-462a-8a92-1e6861e6af27}", (LPCLSID)&guid); 

     unsigned char* ptr = new unsigned char[2048]; // Should really do two calls, but that's more effort 

     HDEVINFO deviceInfoHandle = SetupDiGetClassDevs(&guid, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); 

     // Create a device interface data structure 
     SP_DEVICE_INTERFACE_DATA deviceInterfaceData = { 0 }; 
     deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); 

     // Start the enumeration. 
     success = SetupDiEnumDeviceInterfaces(deviceInfoHandle, 0, &guid, index, &deviceInterfaceData); 
     if (success) 
     { 
      _interfaceClassGuid = deviceInterfaceData.InterfaceClassGuid; 

      // Build a DevInfo data structure. 
      SP_DEVINFO_DATA deviceInfoData = { 0 }; 
      deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 

      // Now we can get some more detailed informations. 
      DWORD nRequiredSize = 0; 

      SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, &deviceInterfaceData, 0, 0, &nRequiredSize, 0); 
      if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) 
      { 
       PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)(new char[nRequiredSize]); 
       memset(deviceInterfaceDetailData, 0, nRequiredSize); 
       deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); 

       if (SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, &deviceInterfaceData, deviceInterfaceDetailData, nRequiredSize, &nRequiredSize, &deviceInfoData)) 
       { 
        _devicePath = deviceInterfaceDetailData->DevicePath; 

        // Get the device description and driver key name. 
        DWORD requiredSize = 0; 
        DWORD regType = REG_SZ; 

        if (SetupDiGetDeviceRegistryProperty(deviceInfoHandle, &deviceInfoData, SPDRP_DEVICEDESC, &regType, ptr, 2048, &requiredSize)) 
        { 
         _deviceDescription = reinterpret_cast<wchar_t*>(ptr); 
        } 

        if (SetupDiGetDeviceRegistryProperty(deviceInfoHandle, &deviceInfoData, SPDRP_DRIVER, &regType, ptr, 2048, &requiredSize)) 
        { 
         _driverKey = reinterpret_cast<wchar_t*>(ptr); 
        } 
       } 

       delete[] deviceInterfaceDetailData; 
      } 

      SetupDiDestroyDeviceInfoList(deviceInfoHandle); 

      std::unique_ptr<Usb_Device> hub(new Usb_Hub(_devicePath, -1)); 
      _devices.push_back(std::move(hub)); 
     } 
     else 
     { 
      success = false; 
     } 

     delete[] ptr; 
    } 
} 

char Usb_Controller::GetSpeed(std::wstring driverKey) 
{ 
    char speed = -1; 

    for (auto it = _devices.begin(); it != _devices.end() && speed == -1; ++it) 
    { 
     if (*it != nullptr) 
     { 
      speed = (*it)->GetSpeed(driverKey); 
     } 
    } 

    return speed; 
} 

Usb_Hub::Usb_Hub(std::wstring devicePath, char speed) : 
    Usb_Device(-1, devicePath, speed) 
{ 
    HANDLE handle1 = INVALID_HANDLE_VALUE; 
    HANDLE handle2 = INVALID_HANDLE_VALUE; 
    _deviceDescription = L"Standard-USB-Hub"; 
    _devicePath = devicePath; 

    DWORD bytesReturned = -1; 
    DWORD bytes = -1; 

    BOOL success = TRUE; 

    // Open a handle to the host controller. 
    handle1 = CreateFile(devicePath.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); 
    if (handle1 != INVALID_HANDLE_VALUE) 
    { 
     USB_ROOT_HUB_NAME rootHubName; 
     memset(&rootHubName, 0, sizeof(USB_ROOT_HUB_NAME)); 

     // Get the root hub name. 
     if (DeviceIoControl(handle1, IOCTL_USB_GET_ROOT_HUB_NAME, nullptr, 0, &rootHubName, sizeof(USB_ROOT_HUB_NAME), &bytesReturned, 0)) 
     { 
      if (rootHubName.ActualLength > 0) 
      { 
       PUSB_ROOT_HUB_NAME actualRootHubName = (PUSB_ROOT_HUB_NAME)(new char[rootHubName.ActualLength]); 

       if (DeviceIoControl(handle1, IOCTL_USB_GET_ROOT_HUB_NAME, nullptr, 0, actualRootHubName, rootHubName.ActualLength, &bytesReturned, 0)) 
       { 
        _isRootHub = true; 
        _deviceDescription = L"RootHub"; 
        _devicePath = std::wstring(L"\\\\?\\") + std::wstring(actualRootHubName->RootHubName); 
       } 

       delete[] actualRootHubName; 
      } 
     } 

     // Now let's open the hub (based upon the hub name we got above). 
     int PortCount = 0; 
     handle2 = CreateFile(_devicePath.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); 
     if (handle2 != INVALID_HANDLE_VALUE) 
     { 
      bytes = sizeof(USB_NODE_INFORMATION); 
      PUSB_NODE_INFORMATION nodeInfo = (PUSB_NODE_INFORMATION)(new char[bytes]); 
      memset(nodeInfo, 0, sizeof(USB_NODE_INFORMATION)); 

      nodeInfo->NodeType = USB_HUB_NODE::UsbHub; 

      // Get the hub information. 
      if (DeviceIoControl(handle2, IOCTL_USB_GET_NODE_INFORMATION, nodeInfo, bytes, nodeInfo, bytes, &bytesReturned, 0)) 
      { 
       DWORD d = GetLastError(); 

       PortCount = nodeInfo->u.HubInformation.HubDescriptor.bNumberOfPorts; 
      } 

      delete[] nodeInfo; 

      CloseHandle(handle2); 
     } 

     CloseHandle(handle1); 

     for (int index = 1; index <= PortCount; index++) 
     { 
      std::unique_ptr<Usb_Device> device = BuildDevice(index, _devicePath); 
      _devices.push_back(std::move(device)); 
     } 
    } 
    else 
    { 
     success = FALSE; 
    } 
} 

char Usb_Hub::GetSpeed(std::wstring driverKey) 
{ 
    char speed = Usb_Device::GetSpeed(driverKey); 

    if (speed == -1) 
    { 
     for (auto it = _devices.begin(); it != _devices.end() && speed == -1; ++it) 
     { 
      if (*it != nullptr) 
      { 
       speed = (*it)->GetSpeed(driverKey); 
      } 
     } 
    } 

    return speed; 
} 

Usb_Device::Usb_Device(int adapterNumber, std::wstring devicePath, char speed) 
{ 
    _speed = speed; 

    HANDLE handle = CreateFile(devicePath.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); 
    if (handle != INVALID_HANDLE_VALUE) 
    { 
     // Get the Driver Key Name (usefull in locating a device) 
     DWORD bytesReturned = -1; 
     DWORD bytes = sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME); 
     PUSB_NODE_CONNECTION_DRIVERKEY_NAME driverKey = (PUSB_NODE_CONNECTION_DRIVERKEY_NAME)(new char[bytes]); 

     driverKey->ConnectionIndex = adapterNumber; 

     // Use an IOCTL call to request the Driver Key Name 
     if (DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, driverKey, bytes, driverKey, bytes, &bytesReturned, 0)) 
     { 
      bytes = driverKey->ActualLength; 
      delete[] driverKey; 

      driverKey = (PUSB_NODE_CONNECTION_DRIVERKEY_NAME)(new char[bytes]); 
      driverKey->ConnectionIndex = adapterNumber; 

      if (DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, driverKey, bytes, driverKey, bytes, &bytesReturned, 0)) 
      { 
       _driverKey = driverKey->DriverKeyName; 
      } 
     } 

     delete[] driverKey; 

     CloseHandle(handle); 
    } 
} 

char Usb_Device::GetSpeed(std::wstring driverKey) 
{ 
    return _speed; 
} 

int main() 
{ 
    Usb_Controller controller; 

    GUID guid; 
    HRESULT hr = CLSIDFromString(L"{AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA}", (LPCLSID)&guid); 

    HDEVINFO deviceInfoHandle = SetupDiGetClassDevs(&guid, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); 

    if (deviceInfoHandle != INVALID_HANDLE_VALUE) 
    { 
     int deviceIndex = 0; 
     while (true) 
     { 
      SP_DEVICE_INTERFACE_DATA deviceInterface = { 0 }; 
      deviceInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); 

      if (SetupDiEnumDeviceInterfaces(deviceInfoHandle, 0, &guid, deviceIndex, &deviceInterface)) 
      { 
       DWORD cbRequired = 0; 

       SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, &deviceInterface, 0, 0, &cbRequired, 0); 
       if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) 
       { 
        PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)(new char[cbRequired]); 
        memset(deviceInterfaceDetail, 0, cbRequired); 
        deviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); 

        if (!SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, &deviceInterface, deviceInterfaceDetail, cbRequired, &cbRequired, 0)) 
        { 
         deviceIndex++; 
         continue; 
        } 

        // Initialize the structure before using it. 
        memset(deviceInterfaceDetail, 0, cbRequired); 
        deviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); 

        // Call the API a second time to retrieve the actual 
        // device path string. 
        BOOL status = SetupDiGetDeviceInterfaceDetail(
         deviceInfoHandle, // Handle to device information set 
         &deviceInterface,  // Pointer to current node in devinfo set 
         deviceInterfaceDetail, // Pointer to buffer to receive device path 
         cbRequired, // Length of user-allocated buffer 
         &cbRequired, // Pointer to arg to receive required buffer length 
         NULL);  // Not interested in additional data 

        BOOL success = TRUE; 
        for (int i = 0; success; i++) 
        { 
         SP_DEVINFO_DATA deviceInterfaceData = { 0 }; 
         deviceInterfaceData.cbSize = sizeof(SP_DEVINFO_DATA); 

         // Start the enumeration. 
         success = SetupDiEnumDeviceInfo(deviceInfoHandle, i, &deviceInterfaceData); 

         DWORD RequiredSize = 0; 
         DWORD regType = REG_SZ; 
         unsigned char* ptr = new unsigned char[2048]; 
         if (SetupDiGetDeviceRegistryProperty(deviceInfoHandle, &deviceInterfaceData, SPDRP_DRIVER, &regType, ptr, 2048, &RequiredSize)) 
         { 
          char speed = controller.GetSpeed(reinterpret_cast<wchar_t*>(ptr)); 
          std::wcout << std::wstring(reinterpret_cast<wchar_t*>(ptr)) << std::endl; 
          std::wcout << L"Speed: " << (int)speed << std::endl; 
         } 

         delete[] ptr; 
        } 

        auto hDeviceHandle = CreateFile(
         deviceInterfaceDetail->DevicePath, 
         GENERIC_READ | GENERIC_WRITE, 
         FILE_SHARE_READ | FILE_SHARE_WRITE, 
         NULL, 
         OPEN_EXISTING, 
         FILE_FLAG_OVERLAPPED, 
         NULL); 

        CloseHandle(hDeviceHandle); 

        delete[] deviceInterfaceDetail; 
       } 
      } 
      else 
      { 
       break; 
      } 

      ++deviceIndex; 
     } 

     SetupDiDestroyDeviceInfoList(deviceInfoHandle); 
    } 

    return 0; 
} 
Verwandte Themen