2012-05-14 8 views
5

Czy ktoś może sprawdzić, czy robię to prawo należy:Moi SetupDiEnumDeviceInterfaces nie działa

//DeviceManager.h 
#include <windows.h> 
//#include <hidsdi.h> 
#include <setupapi.h> 
#include <iostream> 
#include <cfgmgr32.h> 
#include <tchar.h> 
#include <devpkey.h> 

extern "C"{ 
    #include <hidsdi.h> 
} 

//#pragma comment (lib, "setupapi.lib") 

class DeviceManager 
{ 
public: 
    DeviceManager(); 
    ~DeviceManager(); 

    void ListAllDevices(); 
    void GetDevice(std::string vid, std::string pid); 

    HANDLE PSMove; 
    byte reportBuffer; 
private: 
    HDEVINFO deviceInfoSet;    //A list of all the devices 
    SP_DEVINFO_DATA deviceInfoData;  //A device from deviceInfoSet 

    SP_DEVICE_INTERFACE_DATA deviceInterfaceData; 
    SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailedData; 

}; 

//DeviceManager.cpp 
#include"DeviceManager.h" 

DeviceManager::DeviceManager() 
{ 
    deviceInfoSet = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES); //Gets all Devices 
} 

DeviceManager::~DeviceManager() 
{ 
} 

void DeviceManager::ListAllDevices() 
{ 
    DWORD deviceIndex = 0; 

    deviceInfoData.cbSize = sizeof(deviceInfoData); 

    while(SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex, &deviceInfoData)) 
    { 
     deviceInfoData.cbSize = sizeof(deviceInfoData); 

     ULONG tcharSize; 
     CM_Get_Device_ID_Size(&tcharSize, deviceInfoData.DevInst, 0); 
     TCHAR* deviceIDBuffer = new TCHAR[tcharSize]; //the device ID will be stored in this array, so the tcharSize needs to be big enough to hold all the info. 
                 //Or we can use MAX_DEVICE_ID_LEN, which is 200 

     CM_Get_Device_ID(deviceInfoData.DevInst, deviceIDBuffer, MAX_PATH, 0); //gets the devices ID - a long string that looks like a file path. 

     /* 
     //SetupDiGetDevicePropertyKeys(deviceInfoSet, &deviceInfoData, &devicePropertyKey, NULL, 0, 0); 
     if(deviceIDBuffer[8]=='8' && deviceIDBuffer[9]=='8' && deviceIDBuffer[10]=='8' && deviceIDBuffer[11]=='8' && //VID 
      deviceIDBuffer[17]=='0' && deviceIDBuffer[18]=='3' && deviceIDBuffer[19]=='0' && deviceIDBuffer[20]=='8') //PID 
     { 
      std::cout << deviceIDBuffer << "\t<-- Playstation Move" << std::endl; 
     } 
     else 
     { 
      std::cout << deviceIDBuffer << std::endl; 
     }*/ 

     std::cout << deviceIDBuffer << std::endl; 

     deviceIndex++; 
    } 
} 

void DeviceManager::GetDevice(std::string vid, std::string pid) 
{ 

    DWORD deviceIndex = 0; 
    deviceInfoData.cbSize = sizeof(deviceInfoData); 

    while(SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex, &deviceInfoData)) 
    { 
     deviceInfoData.cbSize = sizeof(deviceInfoData); 

     ULONG IDSize; 
     CM_Get_Device_ID_Size(&IDSize, deviceInfoData.DevInst, 0); 

     TCHAR* deviceID = new TCHAR[IDSize]; 

     CM_Get_Device_ID(deviceInfoData.DevInst, deviceID, MAX_PATH, 0); 

     if(deviceID[8]==vid.at(0) && deviceID[9]==vid.at(1) && deviceID[10]==vid.at(2) && deviceID[11]==vid.at(3) && //VID 
      deviceID[17]==pid.at(0) && deviceID[18]==pid.at(1) && deviceID[19]==pid.at(2) && deviceID[20]==pid.at(3)) //PID 
     { 
      //DWORD requiredBufferSize; 
      //SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, NULL, 0, &requiredBufferSize, 


      HDEVINFO deviceInterfaceSet = SetupDiGetClassDevs(&deviceInfoData.ClassGuid, NULL, NULL, DIGCF_ALLCLASSES); 

      DWORD deviceInterfaceIndex = 0; 
      deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); 
      while(SetupDiEnumDeviceInterfaces(deviceInterfaceSet, NULL, &deviceInterfaceData.InterfaceClassGuid, deviceInterfaceIndex, &deviceInterfaceData)) 
      { 
       deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); 
       std::cout << deviceInterfaceIndex << std::endl; 

       deviceInterfaceIndex++; 
      } 

      //std::cout << deviceInterfaceData.cbSize << std::endl; 

      break; 
     } 

     deviceIndex++; 
    } 
} 

Moje SetupDiEnumDeviceInterfaces (w funkcji GetDevice()) nie robi nic. Nawet nie wchodzi w pętlę while ... Czy ktoś może spróbować wskazać, co robię źle, proszę?

Dzięki

Edycja/Więcej informacji: Właśnie zwane funkcję GetLastError() i to zwróciło 259 - ERROR_NO_MORE_ITEMS. Czy urządzenie może nawet nie zawierać żadnych interfejsów?

+2

'SetupDiEnumDeviceInfo' powraca fałszywa wtedy. Przejrzyj dokumentację, aby ustalić, dlaczego tak się dzieje, a następnie użyj swojego debuggera. Jeśli nadal nie możesz tego rozgryźć, zadaj bardziej szczegółowe pytanie o to, gdzie utknąłeś. – AJG85

+0

Następnie proszę zapytać, czy deviceInfoData.ClassGuid zostało poprawnie przekazane? Mam na myśli, że jestem suppsem, aby przekazać ten przewodnik, aby uzyskać urządzenie InterfaceSet? Czy też mogę przekazać mu inny identyfikator GUID? – Danny

+1

Jeśli nigdy nie wprowadzisz pętli while, nigdy nie dojdziesz do tego wiersza kodu, co oznacza, że ​​używasz 'deviceInfoSet' przypisanego w konstruktorze. Wskazówka: Użyj 'FormatMessage' z' GetLastError', aby dokładnie określić, co poszło nie tak po wywołaniu 'SetupDiEnumDeviceInfo' Może to oznaczać, że w systemie nie ma obecnie aktywnych aktywnych urządzeń USB. – AJG85

Odpowiedz

7

Spróbuj z tym.


Próbowałem zhakować twój oryginalny kod tak mało jak to możliwe; następujące kody (dla mnie przynajmniej) dotrzeć do wewnętrznej while(SetupDiEnumDeviceInterfaces..):

void DeviceManager::GetDeviceUSB(std::string vid, std::string pid) 
{ 
    DWORD deviceIndex = 0; 
    deviceInfoData.cbSize = sizeof(deviceInfoData); 

    //buried somewhere deep in the ddk 
    static GUID GUID_DEVINTERFACE_USB_HUB={ 0xf18a0e88, 0xc30c, 0x11d0, {0x88, 0x15, 0x00, 0xa0, 0xc9, 0x06, 0xbe, 0xd8} }; 
    static GUID GUID_DEVINTERFACE_USB_DEVICE ={ 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } }; 
    static GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER={ 0x3abf6f2d, 0x71c4, 0x462a, {0x8a, 0x92, 0x1e, 0x68, 0x61, 0xe6, 0xaf, 0x27}}; 

    //get usb device interfaces 
    HDEVINFO deviceInterfaceSet=SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, NULL, DIGCF_DEVICEINTERFACE); 


    while(SetupDiEnumDeviceInfo(deviceInterfaceSet, deviceIndex, &deviceInfoData)) 
    { 
     deviceInfoData.cbSize = sizeof(deviceInfoData); 

     ULONG IDSize; 
     CM_Get_Device_ID_Size(&IDSize, deviceInfoData.DevInst, 0); 

     TCHAR* deviceID = new TCHAR[IDSize]; 

     CM_Get_Device_ID(deviceInfoData.DevInst, deviceID, MAX_PATH, 0); 

     if(deviceID[8]==vid.at(0) && deviceID[9]==vid.at(1) && deviceID[10]==vid.at(2) && deviceID[11]==vid.at(3) && //VID 
      deviceID[17]==pid.at(0) && deviceID[18]==pid.at(1) && deviceID[19]==pid.at(2) && deviceID[20]==pid.at(3)) //PID 
     { 
      DWORD deviceInterfaceIndex = 0; 
      deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); 

      while(SetupDiEnumDeviceInterfaces(deviceInterfaceSet, &deviceInfoData, &GUID_DEVINTERFACE_USB_DEVICE, deviceInterfaceIndex, &deviceInterfaceData)) 
      { 
       deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); 
       std::cout << deviceInterfaceIndex << std::endl; 

       //get some more details etc 
       //DWORD requiredBufferSize; 
       //SetupDiGetDeviceInterfaceDetail(deviceInterfaceSet, &deviceInterfaceData, NULL, 0, &requiredBufferSize, 

       deviceInterfaceIndex++; 
      } 
     } 

     deviceIndex++; 
    } 
} 



AFAIK, metoda ta podnosi te same urządzenia jak z PO konstruktora połączenia:
(NB: i włączone inne użyteczne GUIDs powłoka)

deviceInfoSet = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES); //Gets all Devices 


ale robię to, aby urządzenie o interfejsy:

// /coughs/ you might want to put back the DIGCF_PRESENT flag i removed for testing 
HDEVINFO deviceInterfaceSet=SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, NULL, DIGCF_DEVICEINTERFACE); 


ja także przekazać deviceInfoData do SetupDiEnumDeviceInterfaces ponieważ zgodnie z dokumentacją:

wskaźnik do SP_DEVINFO_DATA struktura określająca element informacji w DeviceInfoSet. Ten parametr jest opcjonalny, a może mieć wartość NULL. Jeśli ten parametr zostanie określony, SetupDiEnumDeviceInterfaces ogranicza wyliczanie do interfejsów obsługiwanych przez określone urządzenie. Jeśli ten parametr ma wartość NULL, powtarzające się wywołania metody SetupDiEnumDeviceInterfaces zwracają informacje o interfejsach powiązanych ze wszystkimi elementami informacji o urządzeniu w DeviceInfoSet. Wskaźnik ten jest zwykle zwracany przez SetupDiEnumDeviceInfo.



    [Edit: dodatkowe noty (; wnioskowane;)]


Urządzenie USB jest skojarzony konfigurację klasy i interfejs klasa (-y):

Od device setup classes documentation:

Klasa Ustawienia urządzenia definiuje instalatora klasy i klasy współpracowników instalatorów, które są zaangażowane w instalacji urządzenia

Z device interface classes documentation: klasa interfejs

Urządzenie jest sposobem funkcji eksportowania urządzenia i sterownika do innych składników systemu, w tym innych sterowników, jako oraz aplikacji trybu użytkownika


Also, see this handy comparison
Also, this related doc is useful


Więc:

deviceInfoSet = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL,DIGCF_PRESENT|DIGCF_ALLCLASSES); 

ten pobiera wszystkie konfiguracji zestawów informacyjnych klasa i filtrowanie na "USB"


You mógł to zrobić:

deviceInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES|DIGCF_DEVICEINTERFACE);` 

ten pobiera informacje klasa ustawia dla urządzeń, które obsługują interfejs urządzenia z dowolnej klasy. (Zastosowanie emumerator ID S/A "USB" wydaje się mieć żadnego wpływu) Co najważniejsze jednak: The function adds to the device information set a device information element that represents such a device and then adds to the device information element a device interface list that contains all the device interfaces that the device supports.


(I uwaga:SP_DEVINFO_DATA.ClassGuid jest zawsze GUID urządzenia za konfiguracji klasa)


AFAIK:
ale potem jeszcze trzeba zapewnić InterfaceClassGuid WH en wywołując SetupDiEnumDeviceInterfaces() ~ tbh, naprawdę nie rozumiem, dlaczego byłoby to konieczne, jeśli rozmówca zapewnia opcjonalne DeviceInfoData , ale ponieważ jest to zamknięte źródło, jak mógłbym wiedzieć!:)


& Oto info regarding GUID_DEVINTERFACE_USB_DEVICE


(; Zastrzeżenie: Nie pracuję dla M $; traktują powyższe infos z podejrzeniem :) & & z dyoRs oczywiście;)


mam nadzieję, że to pomoże, powodzenia!

+0

, który działa i jest dokładnie tym, czego potrzebuję! Wielkie dzięki: D. Jeśli nie masz nic przeciwko, czy mogę poprosić Cię o wyjaśnienie nieco więcej informacji na temat GUID, który zadeklarowałeś na szczycie? Dlaczego potrzebujemy ich, gdy używam TEKSTU ("USB")? Jaka jest różnica? A może co najmniej dostarczysz mi link, w którym mogę znaleźć więcej informacji na temat identyfikatorów GUID, które zadeklarowałeś? Dzięki: D – Danny

+0

noP, patrz poprawiona odpowiedź ,, btw lol, jestem * nie jest [dużo] (http://hyperboleandahalf.blogspot.co.uk/2010/04/alot-is-better-than-you-at -everything.html) XD – violet313

+1

Chciałbym móc zagłosować jeszcze raz. Musiałeś włożyć dużo wysiłku w tę odpowiedź. Mam jeszcze jedną informację do dodania, po tym, jak szukałem jej przez ponad dzień: Jeśli twoje urządzenie jest urządzeniem WinUSB, to identyfikator GUID, który przekażesz do 'SetupDiEnumDeviceInterfaces()' będzie wartością "DeviceInterfaceGUIDs" z rejestru/inf plik. Bardzo wątpię, że jest to udokumentowane w dowolnym miejscu. –

3

Problem zaczyna się od wywołania metody SetupDiGetClassDevs.

Jeśli szukasz, aby uzyskać ścieżkę urządzenia, użyj SetupDiGetClassDevs (& GUID_DEVINTERFACE_USB_DEVICE ,,,)

SetupDiEnumDeviceInterfaces nie powiedzie się z powodu błędu 259 jeśli SetupDiGetClassDevs podano niewłaściwą GUID w ClassGuid który mówi pani Pomoc jest Wskaźnik do GUID dla klasy instalacji urządzenia lub klasy interfejsu urządzenia.

Dołącz plik devguid.h zawiera zestaw wartości GUID_DEVCLASS. Są to wartości takie same jak GUID_DEVINTERFACE_ *, które są potrzebne.

Użyj #include <uuids.h>, która zawiera ksuuids.h, gdzie znajdziesz wartości GUID_DEVINTERFACE_ *.

Na mojej stronie znajduje się bardziej szczegółowy opis z kodem źródłowym, który powinien pomóc w prawidłowym wyliczeniu urządzeń USB.

Zobacz http://pixcl.com/SetupDiEnumInterfaces_Fail.htm

Powiązane problemy