Seite 4 von 4

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

Verfasst: 28.05.2014 14:59
von Sundance
Hallo Nic,

dank dir für die superschnelle Antwort. #PB_Ascii führt noch nicht zum Erfolg. Aber ich schaue da auch mal weiter.

Dank dir
Sundance

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

Verfasst: 28.05.2014 17:24
von ossy
Hallo,

versuche mal diesen Code.

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,"SetupDiGetDeviceInterfaceDetailA",*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





Grus Wolfgang

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

Verfasst: 28.05.2014 17:40
von Sundance
Hallo Wolfgang,

danke für deine Hilfe. Du rufst ja die Funktion SetupDiGetDeviceInterfaceDetailA auf. Die ist aber im UniCode nicht die Richtige. Es muss ja die SetupDiGetDeviceInterfaceDetailW sein. Die required size ist ja auch richtig. Verdoppelt sich Pi*Daumen :-)
Aber der Volumenpfad wird nicht zurück gegeben. Ich denke, ich werde wohl das Programm nicht in UniCode schreiben. Ich versuch noch ein wenig...

Danke
Sundance

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

Verfasst: 30.05.2014 14:13
von Sundance
So. Ich habe alles mögliche ausprobiert und bin zu dem Schluss gekommen, dass ich mit den entsprechenden UniCode Funktionsaufrufen nicht weiter komme. Deshalb habe ich die ANSI Funktionen genutzt und unterscheide nur beim Auslesen des Pfades ob ich ANSI oder UNI Code habe.

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)
		
		If Not #PB_Compiler_Unicode
			*DeviceInfoSet=CallFunction(1,"SetupDiGetClassDevsA",@VolGuid,0,0,#DIGCF_PRESENT | #DIGCF_DEVICEINTERFACE)
			If GetLastError_() : Debug "Call to SetupDiGetClassDevsA failed." : EndIf
		Else
			*DeviceInfoSet=CallFunction(1,"SetupDiGetClassDevsW",@VolGuid,0,0,#DIGCF_PRESENT | #DIGCF_DEVICEINTERFACE)
			If GetLastError_() : Debug "Call to SetupDiGetClassDevsW failed." : EndIf
		EndIf
		
		Structure SP_DEVICE_INTERFACE_DETAIL_DATA; Align #PB_Structure_AlignC
			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
			
			
				Result = CallFunction(1,"SetupDiGetDeviceInterfaceDetailA",*DeviceInfoSet,@DeviceInterfaceData,0,0,@RequiredSize,0)
				If GetLastError_() = #ERROR_INSUFFICIENT_BUFFER
					Debug "Call to SetupDiGetDeviceInterfaceDetailA : insufficient buffer. Is okay."
				EndIf
				
				
			; 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)
			

			Result = CallFunction(1,"SetupDiGetDeviceInterfaceDetailA",*DeviceInfoSet,@DeviceInterfaceData,@DetailDataBuffer(0),DetailData,#Null,0)
			
			
			Debug "Required Size: " + Str(RequiredSize)
			
			DevicePathName.s = ""
			
			If Not #PB_Compiler_Unicode
				DevicePathName=PeekS(@DetailDataBuffer(4))
			Else
				For Counter = 1 To RequiredSize
				DevicePathName + Chr(PeekA(@DetailDataBuffer(Counter)))
				Next	
			EndIf
				
				
			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())

viele Grüße
Sundance