Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
406 views
in Technique[技术] by (71.8m points)

c++ - how to get vendor id and product id of a plugged usb device on windows

I am using Qt on windows platform.

i want to get and display vendor id and product id of a plugged usb device from my local system.

Below is my full source code to get the vendor id and product id from the usb device.

when i run the my qt application it does not throw me any errors .

so i plug the usb device into the system.

but my print statement displays the result as below

qDebug ()<<pDetData->DevicePath;

i get the result as 0x4

Whether i have any implementation mistakes in my source code ?

if so please guide me what i am doing wrong..

Have i missed out any other functions ?

Is it possible to get the vendor id and product id from the usb device based on my source code .( my implementation of the code ) ?

kindly find my source code below

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
"),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("
No 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";
        }
    }
}

--------------- Edited to add: -----------------

Hi... the application comes and prints this

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

again it goes to while loop .... here it gets breaked in the else statement...

Qt Code:

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; 
} 

Any ideas in this....

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

After this line:

SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData = NULL;

Add this:

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);

After this line:

qDebug ()<<pDetData->DevicePath;

Add this:

free(pDetData);

But eventually you're going to have to read the docs for SetupDiGetDeviceInterfaceDetail(). Do it, there are lots of functions that work like this, with pointers to variable-size structs.

-------- Edited to add: --------

You're really going about this the wrong way. I see you're following the advice you got here, and it's taken you down the wrong path. idVendor and idProduct can only be found in the USB_DEVICE_DESCRIPTOR (MSDN).

It looks like you already know how to get the device handle (using CreateFile()). After that, you call WinUsb_Initialize() (MSDN). That gets you a WINUSB_INTERFACE_HANDLE.

Once you have that handle, you want to call WinUsb_GetDescriptor() (MSDN), with the DescriptorType set to URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE. I can't test code now, but it will look something like this:

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);

After that, udd->idVendor and udd->idProduct should have what you want.

Microsoft used to supply sample code for all this in the DDK, and probably still does, but I don't have access to one.

---------- Edited to add: ----------

Daniel K writes that the code should really be:

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);

See the comments for further details.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...