2010-05-29 5 views
6

पर एक प्लग किए गए यूएसबी डिवाइस की विक्रेता आईडी और उत्पाद आईडी कैसे प्राप्त करें I विंडोज प्लेटफार्म पर क्यूटी का उपयोग कर रहा हूं।विंडोज

मैं अपने स्थानीय सिस्टम से एक प्लग किए गए यूएसबी डिवाइस की विक्रेता आईडी और उत्पाद आईडी प्राप्त करना और प्रदर्शित करना चाहता हूं।

यूएसबी डिवाइस से विक्रेता आईडी और उत्पाद आईडी प्राप्त करने के लिए मेरा पूरा स्रोत कोड नीचे दिया गया है।

जब मैं अपना क्यूटी एप्लीकेशन चलाता हूं तो यह मुझे कोई त्रुटि नहीं फेंकता है।

इसलिए मैं यूएसबी डिवाइस को सिस्टम में प्लग करता हूं।

लेकिन मेरे प्रिंट बयान

qDebug()<<pDetData->DevicePath;

नीचे के रूप में परिणाम प्रदर्शित करता है मैं 0x4

के रूप में परिणाम प्राप्त चाहे मैं अपने स्रोत कोड में किसी भी क्रियान्वयन संबंधी गलतियों है?

.. यदि ऐसा है तो मेरा मार्गदर्शन कृपया मैं गलत क्या कर रहा हूँ

मैं किसी भी अन्य कार्यों से चूक गए है?

क्या मेरे स्रोत कोड के आधार पर यूएसबी डिवाइस से विक्रेता आईडी और उत्पाद आईडी प्राप्त करना संभव है। (कोड का मेरा कार्यान्वयन)?

कृपया

static GUID GUID_DEVINTERFACE_USB_DEVICE = { 0xA5DCBF10L, 0x6530, 0x11D2, 
    { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } }; 

HANDLE hInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE,NULL,NULL, 
    DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); 

if (hInfo == INVALID_HANDLE_VALUE)  
{  
    qDebug()<<"invalid"; 
}  
else  
{   
    qDebug()<<"valid handle";  

    SP_DEVINFO_DATA DeviceInfoData; 
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 

    SP_INTERFACE_DEVICE_DATA Interface_Info;  
    Interface_Info.cbSize = sizeof(Interface_Info); 

    BYTE Buf[1024]; 
    DWORD i; 
    DWORD InterfaceNumber= 0; 

    PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd = 
     (PSP_DEVICE_INTERFACE_DETAIL_DATA) Buf; 

    for (i=0;SetupDiEnumDeviceInfo(hInfo,i,&DeviceInfoData);i++) 
    { 
     DWORD DataT; 
     LPTSTR buffer = NULL; 
     DWORD buffersize = 0; 

     while (!SetupDiGetDeviceRegistryProperty(hInfo, 
      &DeviceInfoData, 
      SPDRP_DEVICEDESC, 
      &DataT, 
      (PBYTE)buffer, 
      buffersize, 
      &buffersize))  
     { 
      if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 
      { 
       // Change the buffer size. 
       if (buffer) LocalFree(buffer); 
       buffer = (LPTSTR)LocalAlloc(LPTR,buffersize); 
      } 
      else 
      { 
       // Insert error handling here. 
       break; 
      } 

      qDebug()<<(TEXT("Device Number %i is: %s\n"),i, buffer); 

      if (buffer) LocalFree(buffer); 

      if (GetLastError() != NO_ERROR 
        && GetLastError() != ERROR_NO_MORE_ITEMS)  
      { 
       // Insert error handling here. 
       qDebug()<<"return false"; 
      } 

      InterfaceNumber = 0; // this just returns the first one, you can iterate on this 

      if (SetupDiEnumDeviceInterfaces(hInfo, 
            NULL, 
            &GUID_DEVINTERFACE_USB_DEVICE, 
            InterfaceNumber, 
            &Interface_Info)) 
      { 
       printf("Got interface"); 
       DWORD needed; 
       pspdidd->cbSize = sizeof(*pspdidd);  
       SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData = NULL; 
       DWORD dwDetDataSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) 
             + 256; 

       SetupDiGetDeviceInterfaceDetail(hInfo, 
        &Interface_Info, pDetData,dwDetDataSize, NULL, 
        &DeviceInfoData); 

       qDebug()<<pDetData->DevicePath; 
       //qDebug()<<QString::fromWCharArray(pDetData->DevicePath); 
      } 
      else 
      {  
       printf("\nNo interface"); 

       //ErrorExit((LPTSTR) "SetupDiEnumDeviceInterfaces"); 

       if (GetLastError() == ERROR_NO_MORE_ITEMS) 
        printf(", since there are no more items found."); 
       else 
        printf(", unknown reason."); 

      } 
      // Cleanup 

      SetupDiDestroyDeviceInfoList(hInfo); 
      qDebug()<<"return true"; 
     } 
    } 
} 

नीचे मेरी स्रोत कोड को खोजने --------------- जोड़ने के लिए संपादित: ------------- ----

हाय ... आवेदन आता है और प्रिंट इस

\? \ USB # vid_04f2 & pid_0111 # 5 & 1ba5a77f 2 # {a5dcbf 1 0-6530-11d2-901f-00c04fb951ed}

फिर यह पाश जबकि को जाता है .... यहाँ यह किसी बयान में breaked हो जाता है ...

क्यूटी कोड:

if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { 
    // Change the buffer size. 
    if (buffer) LocalFree(buffer); 
    buffer = (LPTSTR)LocalAlloc(LPTR,buffersize); 
} else { 
    qDebug()<<"Here it quits the application"; 
    // Insert error handling here. break; 
} 

इसमें कोई विचार ....

+0

यदि आप इसे पढ़ना चाहते हैं तो आपको कोड की इस दीवार को बेहतर तरीके से प्रारूपित करने की आवश्यकता होगी। –

+0

मैं कोड पुन: स्वरूपित ... – egrunin

+2

मैं अपने जवाब (नीचे) पर अपनी टिप्पणी की नकल की और अपने प्रश्न का यह संलग्न (जहां यह अंतर्गत आता है) – egrunin

उत्तर

8

इस लाइन के बाद:

SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData = NULL; 

इस जोड़ें:

DWORD dwDetDataSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA) + 256; 
pDetData = (_SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc (dwDetDataSize); 
pDetData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA); 

इस लाइन के बाद:

qDebug()<<pDetData->DevicePath; 

इस जोड़ें:

free(pDetData); 

लेकिन अंत में आपको SetupDiGetDeviceInterfaceDetail() के लिए दस्तावेज़ों को पढ़ना होगा। ऐसा करें, ऐसे बहुत सारे फ़ंक्शन हैं जो इस तरह काम करते हैं, पॉइंटर्स के साथ चर-आकार वाले structs।

-------- संपादित जोड़ने के लिए: --------

आप वास्तव में इस बारे में गलत तरीके से जा रहे हैं। मुझे लगता है कि आप here प्राप्त सलाह का पालन कर रहे हैं, और यह आपको गलत पथ से नीचे ले गया है। idVendor और idProduct केवल USB_DEVICE_DESCRIPTOR (MSDN) में पाया जा सकता है।

ऐसा लगता है कि आप पहले ही जानते हैं कि डिवाइस हैंडल कैसे प्राप्त करें (CreateFile() का उपयोग करके)। इसके बाद, आप WinUsb_Initialize() (MSDN) पर कॉल करें। यह आपको WINUSB_INTERFACE_HANDLE प्राप्त करता है।

एक बार जब आप कि संभाल है, तो आप WinUsb_GetDescriptor() (MSDN) कॉल करने के लिए, URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE को DescriptorType सेट के साथ चाहते हैं। मैं कोड अब परीक्षण कर सकते हैं नहीं है, लेकिन यह कुछ इस तरह दिखेगा:

USB_DEVICE_DESCRIPTOR udd; 
memset(&udd, 0, sizeof(udd)); 
ULONG LengthTransferred = 0; 

WinUsb_GetDescriptor(
    winusb_interface_handle, // returned by WinUsbInitialize 
    URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE, 
    0,  // not sure if we need this 
    0x409, // not sure if we need this 
    &udd, 
    sizeof(udd), 
    &LengthTransferred); 

उसके बाद, udd->idVendor और udd->idProduct आप क्या चाहते हैं होना चाहिए।

माइक्रोसॉफ्ट डीडीके में इन सभी के लिए नमूना कोड प्रदान करता था, और शायद अभी भी करता है, लेकिन मेरे पास एक तक पहुंच नहीं है।

---------- जोड़ने के लिए संपादित: ----------

डैनियल कश्मीर लिखते हैं कि कोड वास्तव में होना चाहिए:

USB_DEVICE_DESCRIPTOR udd; 
memset(&udd, 0, sizeof(udd)); 
ULONG LengthTransferred = 0; 

WinUsb_GetDescriptor(
    winusb_interface_handle, // returned by WinUsbInitialize 
    USB_DEVICE_DESCRIPTOR_TYPE, // Daniel K's suggestion 
    0, 
    0x409,  // asks for English 
    &udd, 
    sizeof(udd), 
    &LengthTransferred); 

अधिक जानकारी के लिए टिप्पणियां देखें।

+0

हाय ... आवेदन आता है और प्रिंट इस "\\? \ यूएसबी # vid_04f2 और pid_0111 # 5 और 1ba5a77f और 0 और 2 # {a5dcbf1 0-6530-11d2-901f-00c04fb951ed} " फिर यह पाश जबकि को जाता है .... यहाँ यह किसी बयान में breaked हो जाता है ... क्यूटी कोड: अगर (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // बफर आकार बदलें। यदि (बफर) स्थानीय फ्री (बफर); बफर = (एलपीटीस्ट्र) लोकलएलोक (एलपीटीआर, बफरसाइज); } अन्य { qDebug() << "यहां यह एप्लिकेशन छोड़ देता है"; // यहां त्रुटि प्रबंधन डालें। ब्रेक; } इस में कोई भी विचार .... – user198725878

+0

इस के लिए +1, लेकिन मैं मैन्युअल malloc' का उपयोग कर 'से अनुशंसा करते हैं सी ++ कोड के लिए' std :: वेक्टर 'बल्कि। –

+0

@ बिली ओनेल: अच्छा विचार। – egrunin

0

आप डिवाइस "इंटरफ़ेस" का आकलन कर रहे हैं। इंटरफेस में वीआईडी ​​या पीआईडी ​​नहीं है - डिवाइस के उदाहरण करते हैं। मुझे यकीन नहीं है कि आप रुचि रखने वाले उपकरणों को कम करने के लिए इंटरफेस की गणना कर रहे हैं, क्योंकि यह एक त्रुटि है।

यदि आप डिवाइस के उदाहरणों की गणना करते हैं, तो आप DEVPKEY_Device_HardwareIds के साथ SetupDiGetDeviceProperty को कॉल कर सकते हैं और फिर VID और PID के परिणामस्वरूप हार्डवेयर आईडी को grep कर सकते हैं।

अगर आपने जानबूझकर डिवाइस इंटरफेस का उपयोग कर रहे हैं, तो आप एक शून्य PSP_DEVICE_INTERFACE_DETAIL पैरामीटर और एक मान्य requiredSize सूचक के साथ एक बार SetupDiGetDeviceInterfaceDetail कॉल करने के लिए, आवंटित है कि स्मृति को आबंटित और फिर समारोह फिर से कॉल करने के लिए स्मृति के अपेक्षित आकार प्राप्त करने की आवश्यकता । उस कॉल में, अंतिम पैरामीटर एक SP_DEVINFO_DATA संरचना है, जिसे एक बार पुनर्प्राप्त किया गया है, जैसा कि मैंने उपर्युक्त उल्लेख किया है, आप SetupDiGetDeviceProperty को कॉल में उपयोग कर सकते हैं।

0

हार्डवेयर आईडी प्राप्त करने का एक विकल्प है जिसमें वीआईडी ​​और पीआईडी ​​शामिल है। इसलिए जैसे SPDRP_HARDWAREID साथ

कॉल SetupDiGetDeviceRegistryProperty:

wchar_t *hardwareID; 

// First get requiredLength 
SetupDiGetDeviceRegistryProperty(deviceInfoList, &deviceInfoData, SPDRP_HARDWAREID, NULL, NULL, 0, &requiredLength); 

hardwareID = (wchar_t*)(new char[requiredLength]()); 

// Second call to populate hardwareID 
SetupDiGetDeviceRegistryProperty(deviceInfoList, &deviceInfoData, SPDRP_HARDWAREID, NULL, (PBYTE)hardwareID, requiredLength, NULL); 

// Display the string 
qDebug() << "hardwareID =" << QString::fromWCharArray(hardwareID); 

यह आपको USB\ROOT_HUB20&VID1002&PID4396&REV0000 जो आप पार्स कर सकते हैं इस तरह की स्ट्रिंग दे देंगे।

* नोट: सभी उपकरणों में वीआईडी ​​और पीआईडी ​​नहीं होगी, जैसे गैर-यूएसबी डिवाइस।