Zugriff auf USB Gerät

Hardware- und Elektronikbasteleien, Ansteuerung von Schnittstellen und Peripherie.
Fragen zu "Consumer"-Problemen kommen in Offtopic.
Benutzeravatar
Arrag0n
Beiträge: 32
Registriert: 24.06.2005 20:49
Wohnort: Austria
Kontaktdaten:

Zugriff auf USB Gerät

Beitrag von Arrag0n »

Hallo
Ich möchte für ein purebasicprogramm eine Fernbedienung anbinden.
Habe Testweise eine von Remotec mit USB-Anschluss.
Wenn man sie ansteckt wird ein USB-HID(Human Interface Device) Installiert.
Kann mir jemand helfen wie man die Tastencodes der Fernbedienung abfragen könnte?

Grüße Arrag0n :|
Aus den Steinen, die einem in den Weg gelegt werden, kann man Schönes bauen.
Benutzeravatar
hardfalcon
Beiträge: 3447
Registriert: 29.08.2004 20:46
Wohnort: Luxemburg
Kontaktdaten:

Beitrag von hardfalcon »

*Eventuell* kannst du das Ding als Joystick behandeln (weils als HID erkannt wird). Sonst fällt mir eigentlich keine andere Möglichkeit ein, als die TreiberDDLs zu missbrauchen... :|
„Warum siehst du den Splitter im Auge deines Bruders, aber den dicken fetten schwarzen Zensurbalken vor deinem Auge bemerkst du nicht?“
Benutzeravatar
Arrag0n
Beiträge: 32
Registriert: 24.06.2005 20:49
Wohnort: Austria
Kontaktdaten:

Beitrag von Arrag0n »

Wir sind dabei den zugriff über die Windows standart Treiber zu realisieren!
Ist nur sehr kompliziert da sehr viele Instanzen zu Initialisieren sind.

Grüße und Danke Arrag0n
Aus den Steinen, die einem in den Weg gelegt werden, kann man Schönes bauen.
Robinson
Beiträge: 6
Registriert: 10.01.2006 01:42
Wohnort: Spittal a.d. Drau / Kärnten

Beitrag von Robinson »

Hallo Arrag0n!

Hier anschliesend ein komplettes Beispiel Programm, mit dem Du Zugriff auf USB HID Kompatieble Infrarot Fernsteuerungs Empfänger hast.
Und auch für alle anderen Programmierer die zugriff auf USB HID Geräte brauchen ist dies villeicht ein brauchbares Beispiel, das aber z.b. für andere Geräte etwas modifiziert weden müsste, denn es ist speziell für USB HID Infrarot Fernsteuerungs Empfänger Entwickelt.
Mein Beispielprogramm darf von Jerdermann Frei Benutzt und Modifiziert werden.
Hiermit möchte ich mich auch bei allen anderen PureBasic Programmierern Bedanken, die mir mit Ihren Beispielen geholfen haben, DANKE!! :)
Hier Der Code, in PureBasic 4.00 :

Code: Alles auswählen


; **********************  USB_Remote_Receiver_Read_2  ************************* 

; JEGLICHE BENÜTZUNG DIESES PROGRAMMS AUF EIGENE GEFAHR!
; DER AUTOR HAFTET FÜR KEINERLEI DURCH DIE BENÜTZUNG DIESES PROGRAMMS ENTSTANDENE SCHÄDEN UND VERLUSTE!
; JEGLICHE VERÄNDERUNG DES PROGRAMMS AUF EIGENE GEFAHR!

; Neue verbesserte Version

; PureBasic 4.00 Kompatiebel
; --------------------------

; Was ist USB HID ?

; HID ist die Abkürzung für Human Interface Device, und soweit ich das verstanden habe
; ist das eine Art neues Interface für Software Programmierer um einen relativ leichten zugriff auf
; USB Geräte zu Realisieren.
; Diese USB Geräte müssen Also USB HID Konform oder Kompatiebel sein, das steht meistens bei den Geräten
; irgendwo dabei.
; Und in den meisten fällen braucht man für solche Geräte keine Treiber.
; Das Gerät wird einfach an ein USB Port angesteckt dann erkennt Windows es als 
; HID Gerät,(im Gerätemanager als HID Konformes Gerät) und man kann mit einem Programm
; über die HID Schnittstelle mit diesen Geräten Kommunizieren wie im
; nachfolgenden Programm Beispiel.

; Also da gibt es also Diese Gruppe von HID Kompatiebelen Geräten, z.b. USB HID Tastatur, USB HID Maus,
; USB HID Fernsteuerungs Empfänder u.s.w.
; Und diese verschiedenen HID Geräte besitzen wiederum auch einen GUID .
; Also HID Tastaturen haben Ihren eigenen GUID, HID Mäuse und auch HID Fernsteuerungs Empfänder
; Mit diesem GUID werden diese Geräte auseinandergehalten also Identifiziert.
; Weil jede Gerätegruppe, Maus, Tastatur, Empfänger beim zugriff ein wenig anders
; gehandhabt werden, brauchen also bei den API aufrufen jeweils andere Parameter.

; Soweit ich auf den MSDN Seiten herausgefunden habe ist der Standart Class GUID für
; Fernsteuerungs Empfänder = {745A17A0-74D3-11D0-B6FE-00A0C90F57DA}

; Und mit Diesem GUID arbeitet auch dieses Programm standartmäsig beim erten start.
; Das heist wenn ein Empfänger angeschlossen ist werden sofort die Daten ausgelesen und angezeigt.
; Das Programm ist auch Hot Plug fähig, also wenn es gestartet ist und der Empfänger danach angeschlossen
; wird, wird der Empfänger erkannt und der Daten Auslesevorgang sofort gestartet.

; Wenn sich nichts tut verwendet der Empfänger einen anderen GUID oder es ist kein USB HID Gerät.
; Für den Fall das der Empfänger einen anderen GUID verwendet, kann man versuchen ihn trotzdem zu öffnen.
; Dazu die Taste Manual Setup drücken, dann wird unten eine liste mit allen USB HID geräten angezeigt.
; Aber NUR! USB HID Kompatieble Geräte, keine normalen USB Geräte, weil die könnte man auf diese weise
; sowiso nicht öffnen.

; Also wenn nun der Empfänger in der Liste aufscheint kann man ihn markieren und auf übernehmen drücken.
; Bei der übernahme wird versucht das Empfänger mit dem GUID der auch in der Liste angezeigt wird,
; zu öffnen. 
; Wenn er kompatiebel ist wird er geöffnet und der Daten Auslesevorgang gestartet, wenn nicht giebts Fehlermeldungen.

; UND, es werden auch USB HID Mäuse und Tastaturen angezeigt, aber die kann man ohne das Programm zu ändern,
; nicht öffnen, da diese Geräte bei den API aufrufen teilweise andere Parameter benötigen.
; Aber wer will kann das Programm beliebig modifizieren.
; Eine sehr gute Beschreibung und Hilfe zu USB HID gibts auf den MSDN Seiten.

; !! ABER VORSICHT !! 
; Bei den richtigen veränderungen kann man auch auf ALLE USB Geräte zugriffe realisieren und
; WENN SIE NICHT GENAU WISSEN
; WAS SIE TUN, KANN DAS ZU DATENVERLUST FÜHREN oder GAR ZU BESCHÄDIGUNGEN VON DATENTRÄGERN ODER GERÄTEN!!
; !! ALSO VORSICHT!!


; Beschreibung USB_Remote_Read_2
; ------------------------------

; Dieses Programm emöglicht den Lesezugriff auf USB HID Kompatieble Infarot Fernsteuerungs Empfänger die
; mit dem Standart Empfänger Class Giud Arbeiten.

; Es enthällt auch die Anzeige der Original Windows System Fehlermeldungen bei auftretenden Fehlern und
; in der Kopfzeile Auch die Quelle der Fehlermeldung.
; Das heist, bei den meisten Apiaufrufen wird der Variablen mit Nahmen Quelle eine nummer zugewiesen.
; Und bei einem auftretenden Fehler wird die Nummer in der Kopfzeile angezeigt.
; So weis mann gleich bei welchen API aufruf(en) der Fehler auftrat.
; In der API Hilfe auf den MSDN Seiten kann man dann nachschauen warum der Fehler auftrat.

; Dadurch kann mann das Programm nach belieben für andere HID Geräte modifizieren und auftretende Fehler
; relativ einfach eliminieren.

; --------  Strukturen  ----------- 

Structure _MyHidGuid ; {00000000-0000-0000-0000-000000000000} Definition der Structure MyHidGuid
  Data1.l    ; 4 Bytes -|      |    |    |        |
  Data2.w    ; 2 Bytes --------|    |    |        |
  Data3.w    ; 2 Bytes -------------|    |        |
  Data4.w    ; 2 Bytes ------------------|        |
  Data5.b[6] ; 6 Bytes ---------------------------|
EndStructure
  
Structure MyGuid  ;{00000000-0000-0000-0000-000000000000} ;Definition der Structure MyGuid 
  Data1.l    ; 4 Bytes -|      |    |    |        | 
  Data2.w    ; 2 Bytes --------|    |    |        | 
  Data3.w    ; 2 Bytes -------------|    |        | 
  Data4.w    ; 2 Bytes ------------------|        | 
  Data5.b[6] ; 6 Bytes ---------------------------| 
EndStructure 

Structure _MySpDevinfoData 
  cbSize.l 
  HidGuid.MyGuid 
  DevInst.l 
  Reserved.l    
EndStructure 
    
Structure _MySpDevInterfaceData 
  cbSize.l 
  InterfaceClassGuid.MyGuid 
  Flags.l 
  Reserved.l 
EndStructure 
  
Structure _MySpDevInterfaceDetailData 
  cbSize.l 
  DevicePath.b[128] 
EndStructure 

Structure _HIDP_PREPARSED_DATA 
  Value.l 
EndStructure 

Structure _HIDP_CAPS 
  Usage.w 
  UsagePage.w 
  InputReportByteLength.w 
  OutputReportByteLength.w ;Hier wird die HID Report länge gespeichert 
  FeatureReportByteLength.w 
  Reserved.w[17] 
  NumberLinkCollectionNodes.w 
  NumberInputButtonCaps.w 
  NumberInputValueCaps.w 
  NumberInputDataIndices.w 
  NumberOutputButtonCaps.w 
  NumberOutputValueCaps.w 
  NumberOutputDataIndices.w 
  NumberFeatureButtonCaps.w 
  NumberFeatureValueCaps.w 
  NumberFeatureDataIndices.w 
EndStructure 



; -----------  Konstanten  ------------ 

#RandLinks = 5 
#RandOben = 80 
#FensterBreite = 1010 
#Fensterhoehe = 600 
#Titel = "USB_Remote_Receiver_Read_2" 
#GENERIC_READ = $80000000 
#GENERIC_WRITE = $40000000 
#FILE_SHARE_READ = $1 
#FILE_SHARE_WRITE = $2 
#OPEN_EXISTING = $3 
#GMEM_FIXED = $0 
#GMEM_ZEROINIT = $40 
#DIGCF_DEVICEINTERFACE = $10 
#DIGCF_PRESENT  = $2 
#DIGCF_ALLCLASSES = $4 
#SPDRP_DEVICEDESC = $0 
#SPDRP_HARDWAREID = $1 
#SPDRP_CLASS = $7 
#SPDRP_CLASSGUID = $8 
#ERROR_NO_MORE_ITEMS = 259 
#ERROR_INSUFFICIENT_BUFFER = 122 
#HIDP_STATUS_SUCCESS = $00110000 
#HIDP_STATUS_INVALID_PREPARSED_DATA = $C0110001 
#HidP_Input = $0 
#System_Device_Change = $219 


; ------------  Arrays (sind Global)  ----------- 

Global Dim DeviceGuid.s(10) ;In dieses String Array werden bei Manualsetup die die GUIDs der Angeschlossenen USB HID Devices (Geräte) geladen 

  
; ------------  Globale Variablen  ---------------- 

Global hWnd.l, hDevInfoSet.l, RemoteFind.l, SelectedClassGuid.s, HidHandle.l, InDat.l, BytesToRead.l, LibarysOk.b, Fehler.l, Quelle.l 
Global *HidD_GetHidGuid_z.l, *HidD_GetPreparsedData_z, *HidD_FreePreparsedData_z, *HidP_GetCaps_z 
Global *SetupDiEnumDeviceInfo_z, *SetupDiDestroyDeviceInfoList_z, *SetupDiEnumDeviceInterfaces_z, *SetupDiGetDeviceRegistryPropertyA_z, *SetupDiGetDeviceInterfaceDetailA_z 

hWnd = 0 
RemoteFind = 0 
SelectedClassGuid = "" ;In diese Globale Stringvariable wird der GUID für das gewählte Device (Gerät) geschrieben 
HidHandle = 0 
InDat = 0 
BytesToRead = 0 
LibarysOk = 0 
Fehler = 0 
Quelle = 0 

; ------------  Lokale Variablen  ---------------- 

RemoteClassGuid.s = "{745A17A0-74D3-11D0-B6FE-00A0C90F57DA}"; Standart Empfänger Class GUID (hier kann ein ein beliebiger kompatiebler GUID Eines Empfäners eingegeben werden), bei Programmstart wird nach einem Device mit diesem GUID gesucht,
SelectStatus.l = 0                                          ; und wenn ein Empfänger diesen standart Class GUID verwendet werden sofort die empfangenen Daten des Empfänger ausgelesen.


;--------- declaretion der Proceduren  ---------------- 

Declare OpenUsbDevice()        ;Sucht und öffnet gewähltes USB HID Device (GUID wird in der Globalen Variable "SelectedClassGuid" definiert) 
Declare ReadUsbDevice()        ;Liest die HID Reports des geöffneten USB HID Devices 
Declare SetupShowDevices()     ;Erstellt eine Deviceliste mit allen zurzeit angeschlossenen USB HID Devices 
Declare.l SetupSelectDevice()  ;Übernimmt das in der Deviceliste markierte Device als gewähltes Device (GUID wird in die Globalen Variable "SelectedClassGuid" geschrieben) 
Declare ShowError()            ;Zeigt die Original Windows System Fehlermeldungen an 
Declare CloseUsbDevice()       ;Schliest das USB Device mit allen Handles 
Declare CloseLibarys()         ;Schliest bei Programmende alle Libarys 




; ***********************  Hauptprogramm  Anfang  ************************** 

; -----------  Fenster initialisieren  ------------- 

If OpenWindow(0,#RandLinks,#RandOben,#FensterBreite,#FensterHoehe,#Titel,#PB_Window_MinimizeGadget) And CreateGadgetList(WindowID(0)) 
  
  
  ;------------  Die folgenden DLLs müssen auch bei PureBasic 3.94 Initialisiert werden.  --------------- 
  
  ;------------  hid.dll öffnen  ------------- 
  
  If OpenLibrary(0,"hid.dll")      
    *HidD_GetHidGuid_z = GetFunction (0,"HidD_GetHidGuid") 
    *HidD_GetPreparsedData_z = GetFunction (0,"HidD_GetPreparsedData") 
    *HidD_FreePreparsedData_z = GetFunction (0,"HidD_FreePreparsedData") 
    *HidP_GetCaps_z = GetFunction (0,"HidP_GetCaps")                  
    If *HidD_GetHidGuid_z And *HidD_GetPreparsedData_z And *HidD_FreePreparsedData_z And *HidP_GetCaps_z 
      LibarysOk = 1        
    Else 
      CloseLibarys() 
      MessageRequester("Error","Eine oder mehrere Funktionen der hid.dll nicht verfügbar.",#PB_MessageRequester_Ok)        
    EndIf    
  Else 
    CloseLibarys() 
    MessageRequester("Error","Konnte hid.dll nicht öffnen.",#PB_MessageRequester_Ok) 
  EndIf 
  
  ; ------------  setupapi.dll öffnen  -------------- 
    
  If OpenLibrary(1,"setupapi.dll")        
    *SetupDiEnumDeviceInfo_z = GetFunction (1,"SetupDiEnumDeviceInfo") 
    *SetupDiDestroyDeviceInfoList_z = GetFunction (1,"SetupDiDestroyDeviceInfoList") 
    *SetupDiEnumDeviceInterfaces_z = GetFunction (1,"SetupDiEnumDeviceInterfaces") 
    *SetupDiGetDeviceInterfaceDetailA_z = GetFunction (1,"SetupDiGetDeviceInterfaceDetailA") 
    *SetupDiGetDeviceRegistryPropertyA_z = GetFunction (1,"SetupDiGetDeviceRegistryPropertyA") 
    If *SetupDiEnumDeviceInfo_z And *SetupDiDestroyDeviceInfoList_z And *SetupDiEnumDeviceInterfaces_z And *SetupDiGetDeviceInterfaceDetailA_z And  *SetupDiGetDeviceRegistryPropertyA_z 
      LibarysOk = 1        
    Else 
      CloseLibarys() 
      MessageRequester("Error","Eine oder mehrere Funktionen der setupapi.dll nicht verfügbar.",#PB_MessageRequester_Ok)        
    EndIf    
  Else 
    CloseLibarys() 
    MessageRequester("Error","Konnte setupapi.dll nicht öffnen.",#PB_MessageRequester_Ok) 
  EndIf 
    
  If LibarysOk = 1 
    CreateGadgetList(WindowID(0)) 
    
    
    ;-----------  Erstellt Gadgets  ------------- 
  
    ButtonGadget(1,180,400,120,30,"Manual Setup",#PB_Button_MultiLine) 
    ButtonGadget(2,180,450,120,30,"Übernehmen",#PB_Button_MultiLine)  
    ListIconGadget(3,350,20,630,150,"Geöffnetes USB HID Device",1000,#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection) 
    TextGadget(4,20,20,300,20,"Window Handle = -------------------") 
    TextGadget(5,20,40,300,20,"HID Class Handle = -------------------------")  
    TextGadget(6,20,60,300,20,"DevInfoSet Handle = -----------------------------")  
    TextGadget(7,20,80,300,20,"MemberIndex = ----------------------------")  
    TextGadget(8,20,100,300,20,"DevicePath RequiredSize = -----------------------") 
    ListIconGadget(9,350,400,630,150,"Alle zurzeit Angeschlossene USB HID Devices",1000,#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection) 
    TextGadget(10,20,140,300,20,"") 
    TextGadget(11,20,160,300,20,"HidHandle = ------------------------") 
    TextGadget(12,20,180,300,20,"GetPreparsedDataRet = -----------------------") 
    TextGadget(13,20,200,300,20,"GetCapsRet = -----------------------") 
    TextGadget(14,20,220,300,20,"") 
    TextGadget(15,20,240,300,20,"RemoteFind = -----------------------") 
    TextGadget(16,20,260,300,20,"") 
    TextGadget(17,20,280,300,20,"-----------------------") 
    TextGadget(18,350,200,300,20,"USB HID Reportlänge = ----------------------")    
    TextGadget(19,350,230,100,20,"Report Byte 0  ----->") 
    TextGadget(20,470,230,80,20,"---------",#PB_Text_Border) 
    TextGadget(21,350,255,100,20,"Report Byte 1  ----->") 
    TextGadget(22,470,255,80,20,"---------",#PB_Text_Border) 
    TextGadget(23,350,280,100,20,"Report Byte 2  ----->") 
    TextGadget(24,470,280,80,20,"---------",#PB_Text_Border) 
    TextGadget(25,350,305,100,20,"Report Byte 3  ----->") 
    TextGadget(26,470,305,80,20,"---------",#PB_Text_Border) 
    TextGadget(27,350,330,100,20,"Report Byte 4  ----->") 
    TextGadget(28,470,330,80,20,"---------",#PB_Text_Border) 
    TextGadget(29,350,355,100,20,"Report Byte 5  ----->") 
    TextGadget(30,470,355,80,20,"---------",#PB_Text_Border)    
    ButtonGadget(31,180,500,120,30,"Abbrechen",#PB_Button_MultiLine) 
    HideGadget(9,1) 
    HideGadget(2,1) 
    HideGadget(31,1) 
    
    hWnd = WindowID(0) 
    
    SetGadgetText(4,"Window Handle = "+Str(hWnd)) 
    
    SelectedClassGuid = RemoteClassGuid ;Standart Empfänger Class GUID wird als Ausgewählter Class GUID übernommen 
        
    OpenUsbDevice() ;Zugriff auf USB Fernsteuerungs Empfänger wird Initialisiert und zum lesen vorbereitet 
    
    ;-------------  Hauptschleife  ------------------                                    
    Repeat 
      Select WindowEvent() 
        Case #System_Device_Change ;Wenn ein USB Device hinzugefügt oder entfernt wird, wird überprüft ob Empfänger betriebsbereit ist 
          CloseUsbDevice() 
          OpenUsbDevice() 
        Case #PB_Event_CloseWindow 
          CloseUsbDevice() 
          CloseLibarys() 
          End 
        Case #PB_Event_Gadget 
          Select EventGadget() 
            Case 1 ;Taste "Manual Setup" = USB Device wird geschlossen und alle zurzeit angeschlossenen USB HID Devices werden in der Deviceliste angezeigt 
              CloseUsbDevice() 
              SetupShowDevices() 
            Case 2 ;Taste "Übernehmen" = USB Device wird mit neu ausgewähltem GUID geöffnet 
              SelectStatus = SetupSelectDevice() 
              If SelectStatus = 1 
                OpenUsbDevice() 
              EndIf 
            Case 31 ;Taste "Abbrechen" = Manueller Setup wird beendet und USB Device wird mit vorher verwendetem GUID geöffnet 
              HideGadget(9,1) 
              HideGadget(2,1) 
              HideGadget(31,1) 
              OpenUsbDevice()  
          EndSelect 
      EndSelect 
      Delay(10) 
      SetGadgetText(15,"RemoteFind = " + Str(RemoteFind)) 
      If RemoteFind = 1 
        ReadUsbDevice()  ;Wenn gewähltes USB Device bereit ist, dann wird bei jedem schleifendurchlauf der HID Report gelesen 
      EndIf 
    ForEver              
  EndIf  
EndIf    
End 

; -------------  Ende der Hauptschleife  ------------------ 

; ***********************  Hauptprogramm  Ende  ************************** 




; *****************************  Alle Subrutienen  ***************************** 


; -------------  Sucht und öffnet gewähltes USB HID Device  ---------------------- 
  
Procedure OpenUsbDevice() 
  
  MyHidGuid._MyHidGuid
  MySpDevinfoData._MySpDevinfoData 
  MySpDevInterfaceData._MySpDevInterfaceData 
  MySpDevInterfaceDetailData._MySpDevInterfaceDetailData 
  HIDP_PREPARSED_DATA._HIDP_PREPARSED_DATA 
  HIDP_CAPS._HIDP_CAPS 
  
  MemberIndex.l 
  OpenSequez.l 
  AllScanned.l 
  DetailDataSize.l 
  RequiredSize.l 
  hPropertyBuffer.l 
  PropertyBufferSize.l 
  ReadPos.l 
  Zeler1.l 
  ReadWert.b 
  GuidString.s 
  PathString.s 
  StartPosition.l 
  ret1.l 
  ret2.l 
  ret3.l 
  ViewPos.l 
  HIDP_REPORT_TYPE.l 
  ret4.l 
  GetCapsRet.l 
  

  ClearGadgetItemList(3) 
  SetGadgetText(5,"HID Class Handle = --------------") 
  SetGadgetText(6,"DevInfoSet Handle = ---------------") 
  SetGadgetText(7,"MemberIndex = ---------------") 
  SetGadgetText(8,"DevicePath RequiredSize = -----------------") 
  SetGadgetText(11,"HidHandle = --------------") 
  SetGadgetText(12,"GetPreparsedDataRet = ---------------") 
  SetGadgetText(13,"GetCapsRet = -----------------") 
  SetGadgetText(18,"USB HID Reportlänge =  -----------------") 
  

  MemberIndex = 0 
  OpenSequez = 0 
  AllScanned = 0 
  Fehler = 0 
  Quelle = 0 
  DetailDataSize = 0 
  RequiredSize = 0 
  hPropertyBuffer = 0 
  PropertyBufferSize = 0 
  ReadPos = 0 
  Zeler1 = 0 
  ReadWert = 0 
  GuidString = "" 
  PathString = "" 
  StartPosition = 0 
  ret1 = 0 
  ret2 = 0 
  ret3 = 0 
  ViewPos = 0 
  HIDP_REPORT_TYPE = 0 
  ret4 = 0 
  GetCapsRet = 0 

  ;----------  System USB HID Device Klassen Handle ermitteln  ------------ 
          
  CallFunctionFast(*HidD_GetHidGuid_z,@MyHidGuid) 
  SetGadgetText(5,"HID Class Handle = "+Str(MyHidGuid)) 
  
    
  ;----------  Info Set Handle für USB HID Device Klassen ermitteln  ----------- 
  
  OpenSequez = 1 
  hDevInfoSet = SetupDiGetClassDevs_(@MyHidGuid,0,0,#DIGCF_DEVICEINTERFACE|#DIGCF_PRESENT)            
  SetGadgetText(6,"DevInfoSet Handle = "+Str(hDevInfoSet)) 
  If hDevInfoSet < 1 
    Fehler = GetLastError_()    
    Quelle = 1 
    ShowError() 
    OpenSequez = 0 
  EndIf 
        
;--------------  In der folgenden Repeat Schleife werden alle im System zurzeit angeschlossenen  ------------------- 
;--------------  USB HID Devices  ermittelt und es wird überprüft ob das gewählte Device  dabei ist  --------------- 

  MySpDevinfoData\cbSize = SizeOf(MySpDevinfoData) 
  MySpDevInterfaceData\cbSize = SizeOf(MySpDevInterfaceData) 
  MySpDevInterfaceDetailData\cbSize = $5 
  MemberIndex = 0 
  
  Repeat 
    
    If OpenSequez = 1 
      SetGadgetText(7,"MemberIndex = "+Str(MemberIndex)) 
      ret1 = CallFunctionFast(*SetupDiEnumDeviceInterfaces_z,hDevInfoSet,0,@MyHidGuid,MemberIndex,@MySpDevInterfaceData)      
      If ret1 < 1 
        Fehler = GetLastError_()        
        If Fehler = #ERROR_NO_MORE_ITEMS 
          AllScanned = 1 
        Else 
          Quelle = 2 
          ShowError() 
          OpenSequez = 0 
        EndIf 
      EndIf 
    EndIf 
          
    DetailDataSize = 0 
    RequiredSize = 0 
    
    ;--------  Ermittelt den DevicePath des Enumerierten Devices  --------- 
    
    If OpenSequez = 1 
      CallFunctionFast(*SetupDiGetDeviceInterfaceDetailA_z,hDevInfoSet,@MySpDevInterfaceData,0,DetailDataSize,@RequiredSize,0) 
      Fehler = 0 
      Fehler = GetLastError_() 
      If Fehler <> #ERROR_INSUFFICIENT_BUFFER    
        OpenSequez = 0 
        Quelle = 3 
        ShowError() 
        OpenSequez = 0 
      EndIf 
      SetGadgetText(8,"DevicePath RequiredSize = "+Str(RequiredSize)) 
    EndIf 
    
    If OpenSequez = 1 
      DetailDataSize = RequiredSize    
      ret2 = CallFunctionFast(*SetupDiGetDeviceInterfaceDetailA_z,hDevInfoSet,@MySpDevInterfaceData,@MySpDevInterfaceDetailData,DetailDataSize,@RequiredSize,@MySpDevinfoData)      
      If ret2 < 1      
        Fehler = GetLastError_()    
        Quelle = 4 
        ShowError() 
        OpenSequez = 0 
      EndIf 
    EndIf 
    
    ;--------  Stellt den Datenpuffer für den ClassGuid des Enumerierten Devices bereit  ---------- 
    
    If OpenSequez = 1 
      PropertyBufferSize = 255 
      hPropertyBuffer = GlobalAlloc_(#GMEM_FIXED|#GMEM_ZEROINIT,PropertyBufferSize) 
      If hPropertyBuffer < 1 
        Fehler = GetLastError_()    
        Quelle = 5 
        ShowError() 
        OpenSequez = 0 
      EndIf 
    EndIf 
    
    ;--------  Ermittelt den ClassGuid des Enumerierten Devices  --------- 
    
    If OpenSequez = 1 
      ret3 = CallFunctionFast(*SetupDiGetDeviceRegistryPropertyA_z,hDevInfoSet,@MySpDevinfoData,#SPDRP_CLASSGUID,0,hPropertyBuffer,PropertyBufferSize,0) 
      If ret3 < 1 
        Fehler = GetLastError_()    
        Quelle = 6 
        ShowError() 
        OpenSequez = 0 
      EndIf 
    EndIf 
    
    If OpenSequez = 1 
    
      ;---------  Device CLASS GUID String erstellen  --------- 
      ReadPos = 0 
      Zeler1 = 0 
      ReadWert = 0 
      GuidString = "" 
      ReadPos = hPropertyBuffer 
      Repeat 
        ReadWert = PeekB(ReadPos) 
        ReadPos + 1 
        Zeler1 + 1 
        GuidString = GuidString + Chr(ReadWert) 
      Until ReadWert = 0 Or Zeler1 > 128 
                
      ;--------  DevicePath String erstellen  ------------      
      ViewPos + 1 
      ReadPos = 0 
      Zeler1 = 0 
      ReadWert = 0 
      PathString = "" 
      ReadPos = @MySpDevInterfaceDetailData\DevicePath 
      Repeat 
        ReadWert = PeekB(ReadPos) 
        ReadPos + 1 
        Zeler1 + 1 
        PathString = PathString+Chr(ReadWert) 
      Until ReadWert = 0 Or Zeler1 > 128 
      
      ;----------  Vergleicht den Ermittelten GuidString mit dem Gewählten GUID  ------------- 
      
      StartPosition = FindString(GuidString,SelectedClassGuid,1) 
      If StartPosition > 0 
        RemoteFind = 1 
      EndIf 
    EndIf 
    MemberIndex + 1 
    
  Until OpenSequez = 0 Or RemoteFind = 1 Or AllScanned = 1 Or MemberIndex > 10 
  
  ;----------  Zeigt das gesuchte Devices an  -------------- 
  If RemoteFind = 1 
    AddGadgetItem(3,ViewPos,"USB HID Device "+Str(MemberIndex - 1)) 
    ViewPos + 1 
    AddGadgetItem(3,ViewPos,"Device GUID ----> "+GuidString) 
    ViewPos + 1 
    AddGadgetItem(3,ViewPos,"DevicePath    ----> "+PathString) 
    ViewPos + 1 
  Else 
    AddGadgetItem(3,ViewPos,"Gewähltes Device nicht gefunden.") 
    ViewPos + 1 
  EndIf 
    
  ;---------  Wenn Gewähltes Device nicht gefunden wurde, Initialisierung abbrechen  ---------- 
  If RemoteFind = 0 
    OpenSequez = 0 
  EndIf 
    
  ;---------  USB HID Device zugriffs Handle erstellen  ----------- 
  If OpenSequez = 1 
    HidHandle = CreateFile_(@MySpDevInterfaceDetailData\DevicePath,#GENERIC_READ|#GENERIC_WRITE,#FILE_SHARE_READ|#FILE_SHARE_WRITE,0,#OPEN_EXISTING,0,0) 
    If HidHandle < 1 
      Fehler = GetLastError_()    
      Quelle = 7 
      ShowError() 
      OpenSequez = 0 
    EndIf 
    SetGadgetText(11,"HidHandle = "+Str(HidHandle)) 
  EndIf 
  
  ;---------  Pointer für PreparsedData anfordern, Pointer wird in Structure HIDP_PREPARSED_DATA\Value geschrieben  ------- 
  If OpenSequez = 1 
    ret4 = CallFunctionFast(*HidD_GetPreparsedData_z,HidHandle,@HIDP_PREPARSED_DATA) 
    If ret4 < 1 
      Fehler = GetLastError_()    
      Quelle = 8 
      ShowError() 
      OpenSequez = 0 
    EndIf 
    SetGadgetText(12,"GetPreparsedDataRet = "+Hex(ret4)) 
  EndIf 
  
  ;--------  Parameter von Hid Device in HIDP_CAPS Structure laden  ----------- 
  If OpenSequez = 1 
    GetCapsRet = CallFunctionFast(*HidP_GetCaps_z,HIDP_PREPARSED_DATA\Value,@HIDP_CAPS) 
    SetGadgetText(13,"GetCapsRet = " + Hex(GetCapsRet)) 
    If GetCapsRet <> #HIDP_STATUS_SUCCESS 
      MessageRequester("Fehler bei Quelle 9","HIDP_STATUS_INVALID_PREPARSED_DATA",#PB_MessageRequester_Ok) 
      Quelle = 9 
      OpenSequez = 0 
    EndIf 
  EndIf 
  
  BytesToRead = HIDP_CAPS\InputReportByteLength ;die Globale Variable "BytesToRead" enthällt die HID Report länge 
  
  ;-----------  Datenpuffer für HID Report wird bereitgestellt  ------------ 
  If OpenSequez = 1  
    InDat = GlobalAlloc_(#GMEM_FIXED|#GMEM_ZEROINIT,256) 
    If InDat < 1 
      Fehler = GetLastError_()    
      Quelle = 10 
      ShowError() 
      OpenSequez = 0 
    EndIf 
  EndIf 
  
  
  ;------------  Nicht mehr benötigte Handles schliesen  --------------- 
  
  CallFunctionFast(*HidD_FreePreparsedData_z,@HIDP_PREPARSED_DATA) 
  SetupDiDestroyDeviceInfoList_(hDevInfoSet) 
  CloseHandle_(hPropertyBuffer) 
  
  If Quelle > 0 
    SetGadgetText(17,"Fehler bei Quelle = " + Str(Quelle)) 
  Else 
    SetGadgetText(17,"--------------------") 
  EndIf 
  
  SetGadgetText(18,"USB HID Reportlänge =  " + Str(BytesToRead) +  " Bytes") 
  
EndProcedure 


;------------  Liest die HID Reports des geöffneten USB HID Devices  -------------- 

Procedure ReadUsbDevice() 

  If RemoteFind = 1 
    
    ReadFileRet.l = 0 
    BytesRead.l = 0 
    ReadWert.b = 0 
    ReadPos.l = 0 
    DatBuffer.s = "" 
    ReportByte0.s = "" 
    ReportByte1.s = "" 
    ReportByte2.s = "" 
    ReportByte3.s = "" 
    ReportByte4.s = "" 
    ReportByte5.s = "" 
    
            
    ReadFileRet = ReadFile_(HidHandle,@InDat,BytesToRead,@BytesRead,0) 
    If ReadFileRet < 1 ; Falls ein Lesefehler autritt werden in Hauptschleife alle folgenden Lesezugriffe übersprungen 
      Fehler = GetLastError_()    
      Quelle = 11 
      ShowError() 
      RemoteFind = 0 
    EndIf 
        
    ;-------- HID Report länge ist 6 Bytes  ------- 
    
    ;--------  Byte Nummer 0 von HID Report  -----------    
    ReadWert = 0 
    ReadPos = @InDat 
    ReadWert = PeekB(ReadPos) 
    If ReadWert = -86 Or ReadWert = -1        
      DatBuffer = "*" 
    Else 
      DatBuffer = Str(ReadWert) 
    EndIf 
    If ReportByte0 <> DatBuffer 
      ReportByte0 = DatBuffer  
      SetGadgetText(20,ReportByte0) 
    EndIf 
    
    ;--------  Byte Nummer 1 von HID Report  ----------- 
    ReadWert = 0 
    ReadWert = PeekB(ReadPos + 1) 
    If ReadWert = -86 Or ReadWert = -1        
      DatBuffer = "*" 
    Else 
      DatBuffer = Str(ReadWert) 
    EndIf 
    If ReportByte1 <> DatBuffer 
      ReportByte1 = DatBuffer        
      SetGadgetText(22,ReportByte1) 
    EndIf 
    
    ; --------  Byte Nummer 2 von HID Report  ----------- 
    ReadWert = 0 
    ReadWert = PeekB(ReadPos + 2) 
    If ReadWert = -86 Or ReadWert = -1        
      DatBuffer = "*" 
    Else 
      DatBuffer = Str(ReadWert) 
    EndIf 
    If ReportByte2 <> DatBuffer 
      ReportByte2 = DatBuffer        
      SetGadgetText(24,ReportByte2) 
    EndIf 
    
    ;--------  Byte Nummer 3 von HID Report  -----------    
    ReadWert = 0 
    ReadPos = @InDat 
    ReadWert = PeekB(ReadPos + 3) 
    If ReadWert = -86 Or ReadWert = -1        
      DatBuffer = "*" 
    Else 
      DatBuffer = Str(ReadWert) 
    EndIf 
    If ReportByte3 <> DatBuffer 
      ReportByte3 = DatBuffer  
      SetGadgetText(26,ReportByte3) 
    EndIf 
    
    ;--------  Byte Nummer 4 von HID Report  ----------- 
    ReadWert = 0 
    ReadWert = PeekB(ReadPos + 4) 
    If ReadWert = -86 Or ReadWert = -1        
      DatBuffer = "*" 
    Else 
      DatBuffer = Str(ReadWert) 
    EndIf 
    If ReportByte4 <> DatBuffer 
      ReportByte4 = DatBuffer        
      SetGadgetText(28,ReportByte4) 
    EndIf 
    
    ; --------  Byte Nummer 5 von HID Report  ----------- 
    ReadWert = 0 
    ReadWert = PeekB(ReadPos + 5) 
    If ReadWert = -86 Or ReadWert = -1        
      DatBuffer = "*" 
    Else 
      DatBuffer = Str(ReadWert) 
    EndIf 
    If ReportByte5 <> DatBuffer 
      ReportByte5 = DatBuffer        
      SetGadgetText(30,ReportByte5) 
    EndIf 
        
  Else 
    MessageRequester("Error","Gewähltes Device nicht gefunden.",#PB_MessageRequester_Ok) 
  EndIf 
      
EndProcedure 


;---------------  Zeigt alle zurzeit angeschlossenen USB HID Devices an  ------------------ 

Procedure SetupShowDevices() 
  
  MemberIndex.l = 0 
  ViewPos.l = 0 
  PropertyBufferSize.l = 0 
  PropStringBuffer.s = "" 
  DeviceString.s = "" 
  
  HideGadget(9,0) 
  HideGadget(2,0) 
  HideGadget(31,0) 
  ClearGadgetItemList(3) 
  ClearGadgetItemList(9) 
  SetGadgetText(5,"HID Class Handle = --------------") 
  SetGadgetText(6,"DevInfoSet Handle = ---------------") 
  SetGadgetText(7,"MemberIndex = ---------------") 
  SetGadgetText(8,"DevicePath RequiredSize = -----------------") 
  SetGadgetText(11,"HidHandle = --------------") 
  SetGadgetText(12,"GetPreparsedDataRet = ---------------") 
  SetGadgetText(13,"GetCapsRet = -----------------") 
  SetGadgetText(18,"USB HID Reportlänge =  -----------------") 
  
  ;-----------  System USB HID Device Klassen Handle ermitteln  ------------ 
  
  ;MyHidGuid = 0 
  CallFunctionFast(*HidD_GetHidGuid_z,@MyHidGuid) 
  SetGadgetText(5,"HID Class Handle = "+Str(MyHidGuid)) 
    
  ;-----------  Info Set Handle für USB HID Device Klassen ermitteln  ----------- 
  
  hDevInfoSet = 0 
  hDevInfoSet = SetupDiGetClassDevs_(@MyHidGuid,0,0,#DIGCF_DEVICEINTERFACE|#DIGCF_PRESENT) 
  SetGadgetText(6,"DevInfoSet Handle = "+Str(hDevInfoSet)) 
        
  ;-----------  Alle im System zurzeit angeschlossenen USB HID Devices  ermitteln und anzeigen  ----------- 
  
  MySpDevinfoData._MySpDevinfoData 
  MySpDevinfoData\cbSize = SizeOf(MySpDevinfoData) 
  
  While CallFunctionFast(*SetupDiEnumDeviceInfo_z,hDevInfoSet,MemberIndex,@MySpDevinfoData)    
    PropertyBufferSize = 255 
    PropStringBuffer = Space(PropertyBufferSize) 
    CallFunctionFast(*SetupDiGetDeviceRegistryPropertyA_z,hDevInfoSet,@MySpDevinfoData,#SPDRP_DEVICEDESC,0,@PropStringBuffer,PropertyBufferSize,0) 
    DeviceString = "Device " + Str(MemberIndex) + " --->   Description = " + PropStringBuffer 
    CallFunctionFast(*SetupDiGetDeviceRegistryPropertyA_z,hDevInfoSet,@MySpDevinfoData,#SPDRP_HARDWAREID,0,@PropStringBuffer,PropertyBufferSize,0) 
    DeviceString = DeviceString + "          HardwareID = " + PropStringBuffer 
    CallFunctionFast(*SetupDiGetDeviceRegistryPropertyA_z,hDevInfoSet,@MySpDevinfoData,#SPDRP_CLASSGUID,0,@PropStringBuffer,PropertyBufferSize,0) 
    DeviceGuid(MemberIndex) = PropStringBuffer ;In diesem String Array werden alle gefundenen HID Device GUIDs gespeichert 
    DeviceString = DeviceString + "          ClassGUID = " + PropStringBuffer 
    AddGadgetItem(9,ViewPos,DeviceString) 
    ViewPos + 1 
    MemberIndex + 1    
  Wend 
  
  CallFunctionFast(*SetupDiDestroyDeviceInfoList_z,hDevInfoSet) 
  CloseHandle_(hDevInfoSet) 
    
EndProcedure 


;------------  Übernimmt das in der Deviceliste markierte Device als gewähltes Device  --------------- 

Procedure.l SetupSelectDevice() 
  
  SelectedItem.l = 0 
  SelectStatus.l = 0 
  
  SelectedItem = GetGadgetState(9)  
  If SelectedItem < 0 
    MessageRequester("Fehler","Sie haben kein Device markiert",#PB_MessageRequester_Ok) 
  Else 
    SelectedClassGuid = DeviceGuid(SelectedItem) 
    SelectStatus = 1 
    HideGadget(9,1) 
    HideGadget(2,1) 
    HideGadget(31,1) 
  EndIf 
  
  ProcedureReturn SelectStatus 
  
EndProcedure 


;----------  Zeigt die Original Windows System Fehlermeldungen an  ------------ 

Procedure ShowError() 
  
  ErrMsg.s 
  
  FormatMessage_(#FORMAT_MESSAGE_ALLOCATE_BUFFER|#FORMAT_MESSAGE_FROM_SYSTEM,0,Fehler,#LANG_NEUTRAL,@MsgBuffer,0,0) 
  ErrMsg = "" 
  ErrMsg = PeekS(MsgBuffer) 
  MessageRequester("Fehler bei Quelle " + Str(Quelle),ErrMsg + " (FehlerCode = " + Str(Fehler) + ")",#PB_MessageRequester_Ok) 
  Fehler = 0 
  
EndProcedure 


;------------  ;Schliest das USB Device mit allen Handles  ------------ 

Procedure CloseUsbDevice() 
  
  RemoteFind = 0 
  CloseHandle_(HidHandle) 
  CloseHandle_(InDat) 
    
EndProcedure    


;------------  ;Schliest bei Programmende alle Libarys  ------------ 

Procedure CloseLibarys() 

  LibarysOk = 0    
  CloseLibrary(0) 
  CloseLibrary(1) 
  
EndProcedure 


; IDE Options = PureBasic v4.00 (Windows - x86)
; CursorPosition = 81
; FirstLine = 63
; EnableAsm
; EnableXP
; Executable = t023.exe
Beschreibung:

Beim ersten Programmstart wird versucht das USB HID Device mit dem in der Variable "RemotecClassGuid" definierten GUID zu öffnen.
falls das gewünschte device nicht verfügbar ist, kann man im Programmfenster mit der Taste Manual Setup ALLE ZURZEIT ANGESCHLOSSENEN USB HID DEVICES ANZEIGEN LASSEN.
Dann Kann man ein Device Markieren und mit der Taste "Übernehmen" das Device öffnen und lesen.
Es wird auch HotPlugging Unterstützt, das heist, das laufende Programm erkennt automatisch ob der Gewünschte USB HID Fernsteuerungs Empfänger angeschlossen wird und öffnet ihn automatisch.

Aber wie Gesagt Dieses Beispiel funktioniert nur Für USB HID Kompatieble Infarot Empfänger, Kann aber durch ändern des Codes auch für andere USB Geräte verwendet werden.
Sehr Gute beschreibungen dafür giebts dafür auf Microsofts MSDN Seiten.
Also Viel Spass mit meinem Beispiel Programm und beim Programmieren!!
Falls mein Programm nicht ganz allen Standarts Entspricht möge man das mir Bitte Verzeihen.
L.G. Robinson

__________________
codetags ergänzt - bobobo
Zuletzt geändert von Robinson am 28.02.2007 15:59, insgesamt 4-mal geändert.
Benutzeravatar
hardfalcon
Beiträge: 3447
Registriert: 29.08.2004 20:46
Wohnort: Luxemburg
Kontaktdaten:

Beitrag von hardfalcon »

@Robinson: super Arbeit, fehlen nur noch die Codetags! (Ja, ich bin hauptberuflicher Haarspalter, Erbsenzähler und Kleinkrämer....) :D
„Warum siehst du den Splitter im Auge deines Bruders, aber den dicken fetten schwarzen Zensurbalken vor deinem Auge bemerkst du nicht?“
Robinson
Beiträge: 6
Registriert: 10.01.2006 01:42
Wohnort: Spittal a.d. Drau / Kärnten

Beitrag von Robinson »

@hardfalcon, Danke! :)
Benutzeravatar
Arrag0n
Beiträge: 32
Registriert: 24.06.2005 20:49
Wohnort: Austria
Kontaktdaten:

Beitrag von Arrag0n »

@Robinson

Das ist was gaaanz feines!!
Funktioniert super, Danke! :mrgreen: :mrgreen: :mrgreen:

Grüße Arrag0n
Aus den Steinen, die einem in den Weg gelegt werden, kann man Schönes bauen.
Benutzeravatar
Max_der_Held
Beiträge: 594
Registriert: 18.04.2006 17:01
Wohnort: Bavaria
Kontaktdaten:

Re: Zugriff auf USB Gerät

Beitrag von Max_der_Held »

watsefaaQ?
wo kommt denn das her, das ist gold wert!
danke Robinson, great work! :) (hoffentlich läuft alles noch^^)
damit steht einem irgendwann einmal- 2-mäuse support game nicht mehr viel im wege^^
Robinson
Beiträge: 6
Registriert: 10.01.2006 01:42
Wohnort: Spittal a.d. Drau / Kärnten

Re: Zugriff auf USB Gerät

Beitrag von Robinson »

@Max_der_Held, Danke ! :)
John
Beiträge: 33
Registriert: 10.11.2010 11:23
Computerausstattung: Ein stinknormales ASUS Notebook, 15,2 Zoll.
Wohnort: Deutschland, Niedersachsen
Kontaktdaten:

Re: Zugriff auf USB Gerät

Beitrag von John »

Hi Robinson,

das ist wirklich ein toller Code.

Ich brauche den zwar aktuell nicht, leg ihn mir aber bei Seite.

Dennoch meine Frage; das ist jetzt aber "nur" für Windows, oder?

Gibts da nicht einen PB universellen Code, denn USB HIDs gibts doch auch für nicht Windows Rechner, oder?

Wie werden die denn dort angesteuert?
Grüße
John

Weniger ist mehr :-)
http://www.loetseite.de - noch ganz jung: etwas über Elektronik.
Antworten