USB Deviceliste: Funktioniert nur x86 compiliert

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
TheCube
Beiträge: 169
Registriert: 20.07.2010 23:59
Computerausstattung: Risen 3400G 16MB Win10-64Bit
Wohnort: NRW

USB Deviceliste: Funktioniert nur x86 compiliert

Beitrag von TheCube »

Hallo,
habe hier ein Programmteil das alle angeschlossenen USB-Devices scannt,
um anschliessend mit einem gewünschten USB-Device zu kommunizieren.
(Der USB-Code ist nicht von mir, weiss nicht mehr aus welchem Forum o.ä. er stammt)
Problem:
Funktioniert tadellos als X86 compiliert auf Win32 und Win64.
Funktioniert nicht als X64 compiliert: Zuweisung des DevicePathName.s bleibt leer
und damit läuft das restliche auch nicht mehr.

Hier ein aufs wesentliche reduzierte Code um das Problem nachzustellen.
Ich hoffe jemand sieht den Fehler, bestimmt wieder so ein X86->X64 "Klassiker". :|

Code: Alles auswählen

; ==> Compilereinstellung : UNICODE aus ! (Sonst bei USB-Debug-Ausgaben nur Müll, no connect)
; ==> Debugger anschalten

EnableExplicit

Enumeration
  #hiddll
  #apidll 
EndEnumeration

#DasGesuchteInterface = "MS USB Mouse"   ; z.B. ... ihr könnt was nehmen aus eurer Debug-Ausgabe Product/Interface: 
#Hardware = "USB-Hardware"

;--- Variablen ---
Define a, i, IFnr=1
Define USBOK                ; Flag, ob USB-ReadWriteDev erfolgreich

Dim CfgInterface.s(5)       ; Path zum IF für bis zu 5 Devs
Dim HidDevice.l(5)
Dim ReadHandle.l(5)


;---- MAIN-Start
; -----------------------------------------------------------------------------------------
; -----------------------------------------------------------------------------------------

Gosub USBPrepare  ;  Devices suchen und öffnen

End

; ==================================================================================================

; ----------------------------------------------------------------------------------------
;----- USB - Prepare ----
; ----------------------------------------------------------------------------------------
USBPrepare:
OpenLibrary(#hiddll,"hid.dll")
OpenLibrary(#apidll,"setupapi.dll")

Define HidGuid.GUID, *DeviceInfoSet
CallFunction(#hiddll,"HidD_GetHidGuid",HidGuid)
*DeviceInfoSet=CallFunction(#apidll,"SetupDiGetClassDevsA",HidGuid,0,0,$2|$10)

Structure SP_DEVICE_INTERFACE_DETAIL_DATA
  cbSize.l
  DevicePath.b
EndStructure

Structure HIDD_ATTRIBUTES
  size.l
  VendorID.w
  ProductID.w
  VersionNumber.w
EndStructure

Define DeviceInterfaceData.SP_DEVICE_INTERFACE_DATA
Define DeviceInterfaceDetailData.SP_DEVICE_INTERFACE_DETAIL_DATA
Define DeviceAttributes.HIDD_ATTRIBUTES

Define MemberIndex.l=0, v$

Repeat
  
  DeviceInterfaceData\cbSize=SizeOf(SP_DEVICE_INTERFACE_DATA)
  
  If CallFunction(#apidll,"SetupDiEnumDeviceInterfaces",*DeviceInfoSet,0,HidGuid,MemberIndex,DeviceInterfaceData)=0
    Break
  EndIf
  
  Debug "HID Nummer: "+Str(MemberIndex)
  Debug "InterfaceClassGuid Data1= " + Hex(DeviceInterfaceData\InterfaceClassGuid\Data1)
  Debug "InterfaceClassGuid Data2= " + Hex(DeviceInterfaceData\InterfaceClassGuid\Data2)
  Debug "InterfaceClassGuid Data3= " + Hex(DeviceInterfaceData\InterfaceClassGuid\Data3)
  Debug "Flags= "+Str(DeviceInterfaceData\Flags)
  
  Define RequiredSize.l, DetailData.l, DevicePathName.s, HidDevice.l, String.s, AnzIF, SECURITY_ATTRIBUTES, EventObject
  
  CallFunction(#apidll,"SetupDiGetDeviceInterfaceDetailA",*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(#apidll,"SetupDiGetDeviceInterfaceDetailA",*DeviceInfoSet,DeviceInterfaceData,@DetailDataBuffer(0),DetailData,@RequiredSize,0)
  
  DevicePathName.s=PeekS(@DetailDataBuffer(4))
  Debug "Gerätpfadname: "+DevicePathName                      ; <== Das / ab hier ist x64-compiliert fehlerhaft (DevicePathName="")
                                                              ; <== X32 kompliliert kommt z.B. DevicePathName="\\?\hid#vid_17ef&pid_6019#8&1de9c7&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
  
  HidDevice.l=CreateFile_(@DevicePathName,0,#FILE_SHARE_READ|#FILE_SHARE_WRITE,0,#OPEN_EXISTING,0,0)
  Debug "HidDevice Handle: "+Str(HidDevice)
  
  DeviceAttributes\Size=SizeOf(HIDD_ATTRIBUTES)
  
  CallFunction(#hiddll,"HidD_GetAttributes",HidDevice,DeviceAttributes)
  Debug "VendorID: "+Hex(DeviceAttributes\VendorID)
  Debug "ProductID: "+Hex(DeviceAttributes\ProductID)
  Debug "Versionsnummer: "+Hex(DeviceAttributes\VersionNumber)
  
  Dim StringWideChar.b(100)
  
  CallFunction(#hiddll,"HidD_GetManufacturerString",HidDevice,@StringWideChar(0),100)
  String.s=""
  For a=0 To 50
    String.s=String+PeekS(@StringWideChar(0+(a*2)))
  Next
  Debug "Manufacturer: "+String
  Dim StringWideChar.b(0) : Dim StringWideChar.b(100) ; löschen
  CallFunction(#hiddll,"HidD_GetProductString",HidDevice,@StringWideChar(0),100)
  String.s=""
  For a=0 To 50
    String.s=String+PeekS(@StringWideChar(0+(a*2)))
  Next
  Debug "Product/Interface: "+String
  If String=#DasGesuchteInterface : CfgInterface(IFnr)=DevicePathName : IFnr=IFnr+1 : EndIf     ; <----
  Debug "--------------------------------------------------"
  
  MemberIndex=MemberIndex+1
ForEver

CallFunction(#apidll,"SetupDiDestroyDeviceInfoList",*DeviceInfoSet)
CloseHandle_(HidDevice)
CloseLibrary(#hiddll)
CloseLibrary(#apidll)
IFnr=IFnr-1  ; Damit Zählung stimmt
Debug "Anzahl Interfaces : "+ StrU(IFnr)
For i=1 To IFnr: Debug StrU(i)+":  "+ CfgInterface(i):Next
Debug "=================================================="

AnzIF=IFnr
If AnzIF=0
  MessageRequester("Information", " " + #Hardware + " not found.", #MB_ICONWARNING) : End
  Return
EndIf

End
Benutzeravatar
_JON_
Beiträge: 389
Registriert: 30.03.2010 15:24

Re: USB Deviceliste: Funktioniert nur x86 compiliert

Beitrag von _JON_ »

Setze mal "Align #PB_Structure_AlignC" bei beiden Strukturen.

Außerdem sollten alle Handles ein integer sein ".i"
PureBasic 5.46 LTS (Windows x86/x64) | windows 10 x64 Oktober failure
Benutzeravatar
TheCube
Beiträge: 169
Registriert: 20.07.2010 23:59
Computerausstattung: Risen 3400G 16MB Win10-64Bit
Wohnort: NRW

Re: USB Deviceliste: Funktioniert nur x86 compiliert

Beitrag von TheCube »

Bin jetzt endlich dazu gekommen die Tipps umzusetzen und zu testen:

Alle Handles auf .i zu setzen ist natürlich richtig und wichtig, aber der
entscheidene Tipp war "Align #PB_Structure_AlignC" bei den Strukturen,
besonders bei der Ersten.
Danke !

Code: Alles auswählen

Structure SP_DEVICE_INTERFACE_DETAIL_DATA Align #PB_Structure_AlignC
  cbSize.l
  DevicePath.b
EndStructure

Structure HIDD_ATTRIBUTES Align #PB_Structure_AlignC ; (hier aber align verzichtbar ...)
  size.l
  VendorID.w
  ProductID.w
  VersionNumber.w
EndStructure
Antworten