Ermittlung der Gerätepfadnamen von USB HIDs klappt nicht.

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Holger
Beiträge: 53
Registriert: 25.02.2005 21:17

Beitrag von Holger »

Klar, denn Drucker sind keine HIDs (Human Interface Device).
Alles, was nicht dem HID Standard entspricht, braucht eigene Treiber und wird nicht als HID erkannt.
Der Name "HID" ist eigentlich irreführend, weil die HID Spezifikation Control- und Interrupttransfers unterstützt und die Übertragungsrate max. 64000 Bytes/sek bei Fullspeed erlaubt. Pro Transfer kann man einen Block von bis zu 64 Bytes senden oder empfangen. Damit braucht es nicht unbedingt ein Eingabegerät zu sein - die Funktion ist völlig egal, Hauptsache, man hält sich an die HID Spezifikation.
Und das Beste - man braucht keine eigenen Treiber, denn die sind schon in Windows integriert.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Dann gibts ja Hoffnung, das Du bald mal was im Hardware-Forum postest :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Holger
Beiträge: 53
Registriert: 25.02.2005 21:17

Beitrag von Holger »

Ja, hoffe ich auch, wenn ich die Firmware hinbekommen habe :freak:

Aber im Code ist noch ein anderes Problem aufgetaucht.
ReadFile_() und WriteFile_() funktioniert mit HIDs nur, wenn im CreateFile_() die beiden Konstanten #GENERIC_READ / #GENERIC_WRITE definiert werden.
Anscheinend werden aber nur dann USB Mäuse erkannt, wenn #GENERIC_READ NICHT! angegeben wird. Auch bei meiner Maus mußte ich #GENERIC_READ löschen, damit der Code nicht abstürzt.
Mit dem Joystick funktioniert es aber und ich kann mit ReadFile_() die Werte lesen.
Hat jemand eine Ahnung, warum Mäuse nur OHNE #GENERIC_READ erkannt werden ?
Ist ja witzlos, wenn man keine Daten von der Maus empfangen kann, weil #GENERIC_READ gelöscht werden muß, um ein Handle für die Maus zu bekommen ...
Benutzeravatar
kayfr72
Beiträge: 130
Registriert: 12.09.2004 19:13
Wohnort: Lehrberg

geht nicht!

Beitrag von kayfr72 »

Habe das Listing von Holger mal ausprobiert. Bei mir beendet das Programm ohne Debuggerausgabe. Nach dem ich mir das Listing angeschaut habe,sah ich das da ein BREAK-Befehl steht und das deshalb das Proggi endete. Nach entfernen des Break bekam ich eine Fehlermeldung beim Befehl DevicePathName.s=PeekS(@DetailDataBuffer(4)) . Für was ist das Break? Und wie bekommt man das Proggi zum Laufen.
Benutzeravatar
ossy
Beiträge: 18
Registriert: 07.11.2006 23:04
Computerausstattung: Schneider CPC6128, Amiga 500 1.3, PC mit XP SP3, PC mit WIN7
Wohnort: Burladingen

Beitrag von ossy »

Nur zur Info:

diese HID.DLL erkennt nur die USB-HID Geräte.

Z.B.: USB-Maus, USB-Tastatur u.s.w.

Aber keine Drucker und keine Geräte die einen eigenen Treiber besitzen.
Gruß Wolfgang


Was tut ein Frosch, der in ein Glas Milch gefallen ist?

Der eine gibt auf und ertrinkt, ein anderer strapelt solange, bis aus der Milch Butter geworden ist und er hinausklettern kann.

Das Problem an der zweiten Strategie ist nur: " Die Arbeitgeber haben erkannt, wie man billig Butter machen kann ".
Benutzeravatar
HeX0R
Beiträge: 3040
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Beitrag von HeX0R »

Du gräbst einen drei Jahre alten Thread hervor, nur um das selbe zu sagen, wie Holger bereits vor vier Jahren (vier Beiträge über dir)? :freak:
Benutzeravatar
ossy
Beiträge: 18
Registriert: 07.11.2006 23:04
Computerausstattung: Schneider CPC6128, Amiga 500 1.3, PC mit XP SP3, PC mit WIN7
Wohnort: Burladingen

Beitrag von ossy »

Hallo,

ich beschäftige mich gerade mit der USB HID.dll um einen Microcontroller
am USB anzuschliesen.
Ohne eine fremde DLL zu benützen.

Deswegen bin ich hier rein geschlittert.
Gruß Wolfgang


Was tut ein Frosch, der in ein Glas Milch gefallen ist?

Der eine gibt auf und ertrinkt, ein anderer strapelt solange, bis aus der Milch Butter geworden ist und er hinausklettern kann.

Das Problem an der zweiten Strategie ist nur: " Die Arbeitgeber haben erkannt, wie man billig Butter machen kann ".
Benutzeravatar
ossy
Beiträge: 18
Registriert: 07.11.2006 23:04
Computerausstattung: Schneider CPC6128, Amiga 500 1.3, PC mit XP SP3, PC mit WIN7
Wohnort: Burladingen

Beitrag von ossy »

Hallo HeX0R,

habe ich wohl übersehen. :lol:

Aber ich war von dem Beispielprogramm von Holger so begeistert, das ich hier was reinschreiben musste. :allright:

Das Programm von Holger hat mir sehr geholfen. Mit dem Programm ist es mir zum erstenmal gelungen, die Verbindung zwischen meinem PIC und dem Computer herzustellen.
Gruß Wolfgang


Was tut ein Frosch, der in ein Glas Milch gefallen ist?

Der eine gibt auf und ertrinkt, ein anderer strapelt solange, bis aus der Milch Butter geworden ist und er hinausklettern kann.

Das Problem an der zweiten Strategie ist nur: " Die Arbeitgeber haben erkannt, wie man billig Butter machen kann ".
Sundance
Beiträge: 24
Registriert: 25.04.2014 00:46

Re: Ermittlung der Gerätepfadnamen von USB HIDs klappt nicht

Beitrag von Sundance »

Hallo zusammen,

nach fünf Jahren grabe ich diesen Thread auch nochmal aus. Ich denke das ist legitim, da meine Frage auf dem hier geposteten Code beruht.

Also ich möchte eine Liste aller Volumes eines Gerätes ausgeben. Ich habe den hier angegebenen Code in ein Modul gepackt. Wenn ich die Funktion SetupDiGetDeviceInterfaceDetailA aufrufe und mit den Standard Compiler Einstellungen aufurfe, erhalte ich die entsprechende Liste.
Wenn ich jedoch versuche UniCode zu erstellen und dann die Funktion mit SetupDiGetDeviceInterfaceDetailW aufrufe erhalte ich zwar eine Angabe der required size aber der Gerätepfadname ist leer. Ich denke das hängt mit dem RtlMoveMemory und PeekS zusammen. Ist mir aber nicht ganz so klar. Vielleicht kann einer von euch einen kurzen Blick drauf werfen?

Code: Alles auswählen


DeclareModule SetupDiGetVolumeNames
	
	Declare GetVolumeNames(List VolumeNames.s())
	
EndDeclareModule


Module SetupDiGetVolumeNames
	
	Declare String2GUID(Gstring.s, *Identifier.GUID)
	
	Procedure GetVolumeNames(List VolumeNames.s())
		
		ClearList(VolumeNames())
		
		OpenLibrary(1,"setupapi.dll")
		
		StringGuid.s
		
		VolGuid.GUID
		String2GUID("53F5630D-B6BF-11D0-94F2-00A0C91EFB8B", @VolGuid)
		
		*DeviceInfoSet=CallFunction(1,"SetupDiGetClassDevsA",VolGuid,0,0,#DIGCF_PRESENT | #DIGCF_DEVICEINTERFACE)
		
		Structure SP_DEVICE_INTERFACE_DETAIL_DATA
			cbSize.l
			DevicePath.b
		EndStructure
		
		DeviceInterfaceData.SP_DEVICE_INTERFACE_DATA
		DeviceInterfaceDetailData.SP_DEVICE_INTERFACE_DETAIL_DATA
		
		MemberIndex.l=0
		
		Repeat
			
			DeviceInterfaceData\cbSize=SizeOf(SP_DEVICE_INTERFACE_DATA)
			
			If CallFunction(1,"SetupDiEnumDeviceInterfaces",*DeviceInfoSet,0,VolGuid,MemberIndex,DeviceInterfaceData)=0
				Break
			EndIf
			
			RequiredSize.l
			
			CallFunction(1,"SetupDiGetDeviceInterfaceDetailW",*DeviceInfoSet,@DeviceInterfaceData,0,0,@RequiredSize,0)
			; Debug "Erster SetupDiGetDeviceInterfaceDetailA() Aufruf: RequiredSize= "+Str(RequiredSize)
			
			DetailData=RequiredSize
			DeviceInterfaceDetailData\cbSize=SizeOf(SP_DEVICE_INTERFACE_DETAIL_DATA)
			
			Dim DetailDataBuffer.b(RequiredSize)
			
			RtlMoveMemory_(@DetailDataBuffer(0),@DeviceInterfaceDetailData\cbSize,4)
			
			CallFunction(1,"SetupDiGetDeviceInterfaceDetailW",*DeviceInfoSet,@DeviceInterfaceData,@DetailDataBuffer(0),DetailData,@RequiredSize,0)
			
			Debug "Required Size: " + Str(RequiredSize)
			DevicePathName.s=PeekS(@DetailDataBuffer(4))
			Debug "Gerätpfadname: "+DevicePathName
			
			If FindString(UCase(DevicePathName), "VOLUME")
				FirstBracketPos = FindString(DevicePathName,"{")
				SecondBracketPos = FindString(DevicePathName,"}")
				StringGuid = Mid(DevicePathName, FirstBracketPos, SecondBracketPos-FirstBracketPos+1)
				AddElement(VolumeNames())
				VolumeNames() = "\\?\Volume" + StringGuid + "\"
			EndIf
			
			
			
			MemberIndex=MemberIndex+1
		ForEver
		
		CallFunction(1,"SetupDiDestroyDeviceInfoList",*DeviceInfoSet)
		CloseLibrary(1)
		
	EndProcedure
	
	Procedure String2GUID(Gstring.s, *Identifier.GUID)
		
		; 	Protected Bytes.c(32)
		Protected Counter.a
		
		Gstring = ReplaceString(Gstring,"{","")
		Gstring = ReplaceString(Gstring,"}","")
		Gstring = ReplaceString(Gstring,"-","")
		
		If Len(Gstring) <> 32 :	ProcedureReturn #Null : EndIf
		
		*Identifier\Data1 = Val("$" + Mid(Gstring,1,8))
		*Identifier\Data2 = Val("$" + Mid(Gstring,9,4))
		*Identifier\Data3 = Val("$" + Mid(Gstring,13,4))
		*Identifier\Data4[0] = Val("$" + Mid(Gstring,17,2))
		*Identifier\Data4[1] = Val("$" + Mid(Gstring,19,2))
		*Identifier\Data4[2] = Val("$" + Mid(Gstring,21,2))
		*Identifier\Data4[3] = Val("$" + Mid(Gstring,23,2))
		*Identifier\Data4[4] = Val("$" + Mid(Gstring,25,2))
		*Identifier\Data4[5] = Val("$" + Mid(Gstring,27,2))
		*Identifier\Data4[6] = Val("$" + Mid(Gstring,29,2))
		*Identifier\Data4[7] = Val("$" + Mid(Gstring,31,2))
	EndProcedure
	
EndModule


NewList VolNames.s()
SetupDiGetVolumeNames::GetVolumeNames(VolNames())

Debug "Es wurden " + ListSize(VolNames()) + " volumes gefunden."
FirstElement(VolNames())
If ListSize(VolNames()) : Debug VolNames() : EndIf


Vielen Dank
Sundance
Zuletzt geändert von Sundance am 28.05.2014 14:59, insgesamt 1-mal geändert.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8808
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Ermittlung der Gerätepfadnamen von USB HIDs klappt nicht

Beitrag von NicTheQuick »

Versuch mal bei 'PeekS()' den letzten Parameter zu nutzen und dort '#PB_Ascii' anzugeben, also 'PeekS(..., -1, #PB_Ascii)'.
Ansonsten kann ich es hier unter Linux eh nicht testen.
Antworten