7
votes

Comment obtenir l'ID de fournisseur et l'ID de produit d'un périphérique USB branchué sous Windows

J'utilise QT sur la plate-forme Windows.

Je souhaite obtenir et afficher l'ID de fournisseur et l'ID de produit d'un périphérique USB branché de mon système local. p>

ci-dessous est mon code source complet pour obtenir L'ID du fournisseur et l'ID de produit à partir du périphérique USB. P>

Quand j'exécute mon application QT, il ne me jette aucune erreur. p>

donc je branche le périphérique USB dans le système. p>

mais mon énoncé d'impression affiche le résultat comme ci-dessous p>

qdebug () DevicePath; Code>

Je reçois le résultat comme 0x4 p>

si j'ai des erreurs de mise en œuvre dans mon code source? p>

Si oui, veuillez me guider ce que je fais mal .. p>

ai-je manqué Toutes les autres fonctions? p>

est-il possible d'obtenir l'ID de fournisseur et l'ID de produit à partir du périphérique USB en fonction de mon code source. (Ma mise en œuvre du code)? P>

Veuillez trouver mon code source ci-dessous p> xxx pré>

--------------- édité à ajouter: ------------ --------- strong> p>

hi ... L'application vient et imprime cette p>

\? \ usb # vid_04f2 & pid_0111 # 5 & 1BA5A77F & 0 & 2 # {A5DCBF1 0-6530-11D2-901F-00C04FB951ED} P> blockQuote>

Encore une fois, ça va à la boucle .... Ici, il est tombé dans la déclaration d'autre ... p>

Code QT: P>

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


2 commentaires

Vous devrez mieux formater ce mur de code si vous voulez que quelqu'un le lise.


J'ai copié votre commentaire à ma réponse (ci-dessous) et j'ai annexé à votre question (où il appartient)


3 Réponses :


10
votes

Après cette ligne: xxx

ajoutez ceci: xxx

après cette ligne: xxx

Ajoutez ceci: xxx

mais éventuellement, vous allez avoir à lire les docs pour SetupDigetDeviceInterfaDeTail () . Faites-le, il y a beaucoup de fonctions qui fonctionnent comme ceci, avec des pointeurs à des structures de taille variable.

-------- édité à ajouter: -------- -

Vous allez vraiment sur ce mauvais sens. Je vois que vous suivez le conseil que vous avez ICI , et il vous a lancé le mauvais chemin. idvendor et IDPRODUCT ne peut être trouvé que dans le USB_Device_Descriptor ( MSDN ).

On dirait que vous savez déjà comment obtenir la poignée du périphérique (en utilisant Createefile () ). Après cela, vous appelez winusb_initialize () ( MSDN < / a>). Qui vous obtient un winusb_interface_handle .

Une fois que vous avez cette poignée, vous souhaitez appeler winusb_getdescriptor () ( MSDN ), avec le DescriptTortype défini sur urb_function_get_descriptor_from_device . Je ne peux pas tester le code maintenant, mais cela ressemblera à ceci: xxx

après cela, udd-> idvendor et udd -> Idéducatoire devrait avoir ce que vous voulez.

Microsoft utilisé pour fournir un code d'échantillon pour tout cela dans le DDK, et probablement toujours, mais je n'ai pas accès à un.

----------- édité pour ajouter: ------------

Daniel K écrit que le code devrait vraiment être: xxx

Voir les commentaires pour plus de détails.


6 commentaires

Salut ... l'application vient et imprime cette "\\" \ USB # vid_04f2 & pid_0111 # 5 & 1ba5a77f & 0 & 2 # {A5DCBF1 0-6530-11d2-901f-00c04fb951f-00c04fb951ed} "Encore une fois, ça va à la boucle .... Ici, il est tombé dans le Sinon Signalez ... Code QT: Si (getlasterror () == error_insufficient_buffer) {// modifier la taille du tampon. Si (tampon) localfree (tampon); tampon = (LPTR) localalloc (lptr, tampersize); } else {qdebug () << "ici il quitte l'application"; // Insérer une erreur d'erreur ici. Pause; } Des idées dans cette ....


+1 Pour cela, mais je recommanderais std :: vecteur pour C ++ code plutôt que manuellement en utilisant masloc .


Fourni Winusb_GetDescriptor () est incorrect: le deuxième paramètre doit être USB_String_Descriptor_Type et index devrait être zéro.


@Danielk: Je ne suis pas sûr que vous soyez correct et que je n'ai pas accès au projet à partir de laquelle j'ai pris mon exemple. Que pensez-vous que mon code (non testé)?


@Regrunin L'erreur "Un périphérique attaché au système ne fonctionne pas." se produit avec votre code. Si vous lisez la documentation avec précaution, le DOC dit utiliser une valeur selon la description DescriptTorType . Toutefois, dans votre exemple, vous avez pris la valeur sous le membre HDR à la place, ce qui est incorrect.


Correction de mon commentaire original, le descriptTortype doit être USB_Device_Descriptor_type pas USB_String_Descriptor_type . Cependant, les deux sont valides, juste que le plus tard est utilisé pour récupérer les chaînes IMANUFFACTURER, IPRODUCT et ISerialNumber de la structure descripteur.



0
votes

Vous énumérez l'appareil "Interface". Les interfaces ne disposent pas d'instances de périphérique Vid ou PID. Je ne sais pas si vous énumérez les interfaces pour affiner les périphériques que vous êtes intéressé, car c'est une erreur.

Si vous énumérez simplement les instances de périphérique, vous pouvez appeler setupDigetDeviceProperty avec devpkey_device_hardwareids, puis Grep l'ID matériel résultant pour la Vid et PID.

Si vous utilisez les interfaces de périphérique exprès, vous devez appeler setupDigetDeviceInterfaDeTatail une fois avec un paramètre null psp_device_interface_detail et un pointeur valide requis pour obtenir la taille de mémoire requise pour allouer, allouer cette mémoire, puis appelez à nouveau la fonction. Dans cet appel, le dernier paramètre est une structure SP_DEVINFO_DATA, qui a une fois récupérée, vous pouvez utiliser dans l'appel à setupdigetDeviceProperty comme mentionné ci-dessus.


0 commentaires

1
votes

Une alternative consiste à obtenir le disque dur qui inclut la Vid et le PID.

Call SetupDigetDeviceReGyProperty avec SPDRP_HARDWAREID AIME: P>

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


0 commentaires