Seite 2 von 4

Verfasst: 02.10.2005 18:22
von bingo
habe mal diesen thread als anregung benutzt ... :wink:

Code: Alles auswählen

;auflisten aller HDDs per DiskClassGuid

DiskClassGuid.GUID

DiskClassGuid\Data1 = $53f56307
DiskClassGuid\Data2 = $b6bf
DiskClassGuid\Data3 = $11d0
DiskClassGuid\Data4[0] = $94
DiskClassGuid\Data4[1] = $f2
DiskClassGuid\Data4[2] = $00
DiskClassGuid\Data4[3] = $a0
DiskClassGuid\Data4[4] = $c9
DiskClassGuid\Data4[5] = $1e
DiskClassGuid\Data4[6] = $fb
DiskClassGuid\Data4[7] = $8b

#DIGCF_PRESENT = 2
#DIGCF_INTERFACEDEVICE = $10

Structure SP_DEVICE_INTERFACE_DATA 
  cbSize.l 
  InterfaceClassGuid.GUID 
  Flags.l 
  Reserved.l 
EndStructure

DeviceInterfaceInfoData.SP_DEVICE_INTERFACE_DATA
DeviceInterfaceInfoData\cbSize=SizeOf(DeviceInterfaceInfoData) 

Structure SP_DEVINFO_DATA 
  cbSize.l 
  ClassGuid.GUID 
  DevInst.l 
  Reserved.l 
EndStructure 

DeviceInfoData.SP_DEVINFO_DATA
DeviceInfoData\cbSize=SizeOf(DeviceInfoData) 

Structure SP_DEVICE_INTERFACE_DETAIL_DATA
cbSize.l
DevicePath.b[#ANYSIZE_ARRAY]
EndStructure

DEVICE_INTERFACE_DETAIL_DATA.SP_DEVICE_INTERFACE_DETAIL_DATA
DEVICE_INTERFACE_DETAIL_DATA\cbSize=SizeOf(DEVICE_INTERFACE_DETAIL_DATA) 

hDeviceInfoSet = SetupDiGetClassDevs_(@DiskClassGuid,0,0,#DIGCF_PRESENT|#DIGCF_INTERFACEDEVICE)

#SPDRP_HARDWAREID = 1

buffer = 500
*MemoryID = AllocateMemory(buffer)

i=0 
OpenLibrary(1,"setupapi.dll")
*F1 = IsFunction(1, "SetupDiEnumDeviceInterfaces") 
*F2 = IsFunction(1, "SetupDiGetDeviceInterfaceDetailA")
*F3 = IsFunction(1, "SetupDiGetDeviceRegistryPropertyA") 

While CallFunctionFast(*F1,hDeviceInfoSet,0,@DiskClassGuid,i,@DeviceInterfaceInfoData)
i+1 

CallFunctionFast(*F2,hDeviceInfoSet,@DeviceInterfaceInfoData,0,0,@laenge,@DeviceInfoData)

Dim DetailDataBuffer.b(laenge) 

RtlMoveMemory_(@DetailDataBuffer(0),@DEVICE_INTERFACE_DETAIL_DATA\cbSize,4) 

CallFunctionFast(*F2,hDeviceInfoSet,@DeviceInterfaceInfoData,@DetailDataBuffer(0),laenge,@tmp,0)

Debug PeekS(@DetailDataBuffer(4))

CallFunctionFast(*F3,hDeviceInfoSet,@DeviceInfoData,#SPDRP_HARDWAREID,0,*MemoryID,buffer,@laengehid) 

Debug PeekS(*MemoryID)
zeromemory_(*MemoryID,buffer)

hdevice = CreateFile_(PeekS(@DetailDataBuffer(4)),#GENERIC_READ|#GENERIC_WRITE,#FILE_SHARE_READ|#FILE_SHARE_WRITE,0,#OPEN_EXISTING,0,0)

;weitere operationen nun möglich mit DeviceIoControl...
Debug hdevice

Wend

SetupDiDestroyDeviceInfoList_(hDeviceInfoSet) 

CloseLibrary(1) 

FreeMemory(*MemoryID)
...um geräte anhand von klassen zu finden .

Verfasst: 02.10.2005 18:36
von ts-soft
@bingo
:allright: funzt

Verfasst: 02.10.2005 22:02
von Holger
So, funktioniert:

Code: Alles auswählen

OpenLibrary(0,"hid.dll") 
OpenLibrary(1,"setupapi.dll")
 
HidGuid.GUID 
CallFunction(0,"HidD_GetHidGuid",HidGuid) 
*DeviceInfoSet=CallFunction(1,"SetupDiGetClassDevsA",HidGuid,0,0,$2|$10)

Structure SP_DEVICE_INTERFACE_DATA 
cbSize.l 
InterfaceClassGuid.GUID 
Flags.l 
Reserved.l 
EndStructure 

Structure SP_DEVICE_INTERFACE_DETAIL_DATA 
cbSize.l 
DevicePath.b
EndStructure

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

Structure HIDP_CAPS
Usage.w
UsagePage.w
InputReportByteLength.w
OutputReportByteLength.w
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
 

DeviceInterfaceData.SP_DEVICE_INTERFACE_DATA 
DeviceInterfaceDetailData.SP_DEVICE_INTERFACE_DETAIL_DATA 
DeviceAttributes.HIDD_ATTRIBUTES
DeviceCaps.HIDP_CAPS

MemberIndex.l=0

;Beginn der HID Erkennung

Repeat

DeviceInterfaceData\cbSize=SizeOf(SP_DEVICE_INTERFACE_DATA)

Result.l=CallFunction(1,"SetupDiEnumDeviceInterfaces",*DeviceInfoSet,0,HidGuid,MemberIndex,DeviceInterfaceData) 
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) 

RequiredSize.l 

Result.l=CallFunction(1,"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(1,"SetupDiGetDeviceInterfaceDetailA",*DeviceInfoSet,DeviceInterfaceData,@DetailDataBuffer(0),DetailData,@RequiredSize,0)

DevicePathName.s=PeekS(@DetailDataBuffer(4))
Debug "Gerätpfadname: "+DevicePathName

HidDevice.l=CreateFile_(@DevicePathName,$80000000|$40000000,$1|$2,0,3,0,0)

Debug "HidDevice Handle: "+Str(HidDevice)

DeviceAttributes\Size=SizeOf(HIDD_ATTRIBUTES)

CallFunction(0,"HidD_GetAttributes",HidDevice,DeviceAttributes)
Debug "VendorID: "+Hex(DeviceAttributes\VendorID)
Debug "ProductID: "+Hex(DeviceAttributes\ProductID)
Debug "Versionsnummer: "+Hex(DeviceAttributes\VersionNumber)

MemberIndex=MemberIndex+1

Until Result=0

;Ende der HID Erkennung

;Die Repeat/Until Schleife kann man mit bekannten Vendor-/ProductIDs vergleichen
;um sie bei Erreichen des gesuchten HIDs zu verlassen.
;Das Handle (HidDevice.l) des HIDs wird für andere HidD_xxx Funktionen benötigt.
;Falls die "SetupDiGetDeviceInterfaceDetailA" Funktion Result=0 ausgibt, ist
;kein weiteres HID verfügbar.
;Jetzt ist per WriteFile_() / Read_File_() ein Datentransfer möglich, falls
;man alle Eigenschaften des HID kennt
;falls nicht, weiter ...

;---------------------------------------------------------------------------
;um an weitere Infos des aktuellen HIDs zu kommen ( wie z.B. Hersteller- /
;Produktstring:  

;WideChar Konvertierung
;eine andere Lösung fiel mir für den Test nicht ein, vielleicht gibt es
;dafür eine API Funktion ?

Dim StringWide.b(100) ; 100Bytes müßten ausreichen

CallFunction(0,"HidD_GetManufacturerString",HidDevice,@StringWide(0),100)
String.s=""
For a=0 To 50
String.s=String+PeekS(@StringWide(0+(a*2)))
Next
Debug "Manufacturer: "+String

CallFunction(0,"HidD_GetProductString",HidDevice,@StringWide(0),100)
String.s=""
For a=0 To 50
String.s=String+PeekS(@StringWide(0+(a*2)))
Next
Debug "Product: "+String

;weitere nützliche HidD_xxx Funktionen im DDK oder auf der MSDN

;---------------------------------------------------------------------------
;noch mehr HID Infos ( z.B. Länge der Input / Output Reports )
;per HidP_xxx Funktionen: 
;"HidD_GetPreparsedData" muss einmalig vor einer oder mehreren
;HidP_xxx Funktion(en) aufgerufen werden

*PreparsedData.l
CallFunction(0,"HidD_GetPreparsedData",HidDevice,@*PreparsedData.l)

CallFunction(0,"HidP_GetCaps",*PreparsedData,DeviceCaps)
Debug "Input Report Länge: "+Str(DeviceCaps\InputReportByteLength)
Debug "Output Report Länge: "+Str(DeviceCaps\OutputReportByteLength)

;weitere nützliche HidP_xxx Funktionen im DDK oder auf der MSDN
;z.B. für Mengen an Infos: HidP_GetValueCaps_()

;---------------------------------------------------------------------------
;Beim Beenden des HID Kommunikation müssen die Ressourcen freigegen werden:

CallFunction(0,"HidD_FreePreparsedData",*PreparsedData)
CallFunction(1,"SetupDiDestroyDeviceInfoList",*DeviceInfoSet)
CloseHandle_(HidDevice)

End
Ich hoffe, daß kein Fehler drinsteckt, weil ich nur einen USB Joystick dranhabe, aber die Schleife müßte funktionieren
( ein Device muss aber eingestöpselt sein, da die Schleife ohne If/EndIf mindestens einmal durchläuft ).

Ist in erster Linie für diejenigen interessant, die ein eigenes HID bauen ( HIDs, wie z.B. Mäuse oder Joysticks werden ja von PB unterstützt ).
An den Datentransfer mit WriteFile_() / ReadFile_() werde ich mich dransetzen, wenn ich es geschafft habe, daß mein USB Interface von Windows als HID erkannt wird.

Vielleicht gibt es hier noch andere USB Bastler? Ich benutze den NationalSemiconductor USBN9603...

Nochmals vielen Dank für die Antworten

PS: Habe vergessen, die beiden Libs zu schließen.

Verfasst: 02.10.2005 22:31
von ts-soft
@Holger
Zeile 145 gibts nen Speicherzugriffsfehler. Bis auf die ersten Werte, ist alles leer. Hab allerdings nur ne Maus und nen ausgeschalteten Drucker über USB angeschlossen.

Verfasst: 03.10.2005 00:18
von Holger
Eventuell liegts an dem Reserved Array in der HIDP_CAPS Struktur. Das Array wird in der MSDN mit 17 Words angegeben.
Vielleicht das Array in der Struktur mit 16 Words angeben, denn 0-16 sind ja 17 Words ?
Kannst Du mal bitte den "Result.l" debuggen und den MemberIndex auf 0 und 1 setzen ?
Wenn Result 0 ergibt, wird die Maus nicht als HID erkannt.
Bitte auch noch Deine Debuggerwerte.

Übrigens mit v3.94 geschrieben.

Mein Debugger:

MemberIndex: 0
InterfaceClassGuid Data1= 4D1E55B2
InterfaceClassGuid Data2= FFFFF16F
InterfaceClassGuid Data3= 11CF
Flags= 1
Erster SetupDiGetDeviceInterfaceDetailA() Aufruf: RequiredSize= 86
Gerätpfadname: \\?\hid#vid_046d&pid_c20c#6&9a4567e&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
HidDevice Handle: 892
VendorID: 46D
ProductID: FFFFC20C
Versionsnummer: 103
Manufacturer: Logitech
Product: WingMan Precision USB
Input Report Länge: 4
Output Report Länge: 0

Wenn ich am Anfang den MemberIndex auf 1 setze, bekomme ich:

MemberIndex: 1
InterfaceClassGuid Data1= 0
InterfaceClassGuid Data2= 0
InterfaceClassGuid Data3= 0
Flags= 0
Erster SetupDiGetDeviceInterfaceDetailA() Aufruf: RequiredSize= 0

Dann brichts ab und ich bekomme den Error "Array index out of bounds"
bei Zeile 80 DevicePathName.s=PeekS(@DetailDataBuffer(4)).

Verfasst: 03.10.2005 01:30
von ts-soft
Bei MemberIndex 0:
InterfaceClassGuid Data1= 4D1E55B2
InterfaceClassGuid Data2= FFFFF16F
InterfaceClassGuid Data3= 11CF
Flags= 1
Erster SetupDiGetDeviceInterfaceDetailA() Aufruf: RequiredSize= 86
Gerätpfadname: \\?\hid#vid_05fe&pid_0011#6&e7bdac4&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
HidDevice Handle: -1
VendorID: 0
ProductID: 0
Versionsnummer: 0
Manufacturer:
Product:
und Fehler in Zeile 144

Bei MemberIndex1 ist der Fehler bereits in Zeile 80 und alle Debuggerausgaben sind 0

Verfasst: 03.10.2005 02:08
von Holger
Der Gerätepfad wird ermittelt, allerdings schlägt in Zeile 83 die Ermittlung des Handles fehl (HidDevice=-1):

Code: Alles auswählen

HidDevice.l=CreateFile_(@DevicePathName,$80000000|$40000000,$1|$2,0,3,0,0)
Wenn ich diese Zeile ersetze durch

Code: Alles auswählen

HidDevice.l=CreateFile_(@DevicePathName,0,0,0,3,0,0)
bekomme ich dieselben DebuggerWerte - funktioniert bei mir also.
Aber mit den Konstanten blicke ich sowieso noch nicht durch.
Wie bekomme ich die Werte der Konstanten, die in der MSDN mit z.B. GENERIC_READ oder FILE_SHARE_WRITE beschrieben werden ?

MSDN: http://msdn.microsoft.com/library/defau ... tefile.asp

Eventuell liegts daran, daß die Maus im System schon aktiviert wurde, eine Art Schutzfunktion von Windows, die den Zugriff verweigert ?

Verfasst: 03.10.2005 02:24
von Holger
Auweia, schlimmer Fehler ;)
Die Konstanten hat ja PB schon drin ...

Code: Alles auswählen

HidDevice.l=CreateFile_(@DevicePathName,#GENERIC_READ|#GENERIC_WRITE,#FILE_SHARE_READ|#FILE_SHARE_WRITE,0,#OPEN_EXISTING,0,0)
Danke an bingo :D

Heute werde ich mich durch die Konstanten in CreateFile_() durchgraben, aber jetzt erstmal ab ins Bett ...

Verfasst: 03.10.2005 23:24
von Holger
Jetzt funktioniert es bei allen HIDs ( ich habe eine Maus und einen Joystick dran).

Code: Alles auswählen

OpenLibrary(0,"hid.dll") 
OpenLibrary(1,"setupapi.dll")
 
HidGuid.GUID 
CallFunction(0,"HidD_GetHidGuid",HidGuid) 
*DeviceInfoSet=CallFunction(1,"SetupDiGetClassDevsA",HidGuid,0,0,$2|$10)

Structure SP_DEVICE_INTERFACE_DATA 
cbSize.l 
InterfaceClassGuid.GUID 
Flags.l 
Reserved.l 
EndStructure 

Structure SP_DEVICE_INTERFACE_DETAIL_DATA 
cbSize.l 
DevicePath.b
EndStructure

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

DeviceInterfaceData.SP_DEVICE_INTERFACE_DATA 
DeviceInterfaceDetailData.SP_DEVICE_INTERFACE_DETAIL_DATA 
DeviceAttributes.HIDD_ATTRIBUTES

MemberIndex.l=0

Repeat

DeviceInterfaceData\cbSize=SizeOf(SP_DEVICE_INTERFACE_DATA)

If CallFunction(1,"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) 

RequiredSize.l 

CallFunction(1,"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(1,"SetupDiGetDeviceInterfaceDetailA",*DeviceInfoSet,DeviceInterfaceData,@DetailDataBuffer(0),DetailData,@RequiredSize,0)

DevicePathName.s=PeekS(@DetailDataBuffer(4))
Debug "Gerätpfadname: "+DevicePathName

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(0,"HidD_GetAttributes",HidDevice,DeviceAttributes)
Debug "VendorID: "+Hex(DeviceAttributes\VendorID)
Debug "ProductID: "+Hex(DeviceAttributes\ProductID)
Debug "Versionsnummer: "+Hex(DeviceAttributes\VersionNumber)

Dim StringWideChar.b(100)

CallFunction(0,"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

CallFunction(0,"HidD_GetProductString",HidDevice,@StringWideChar(0),100)
String.s=""
For a=0 To 50
String.s=String+PeekS(@StringWideChar(0+(a*2)))
Next
Debug "Product: "+String

Debug "--------------------------------------------------"

MemberIndex=MemberIndex+1
ForEver

CallFunction(1,"SetupDiDestroyDeviceInfoList",*DeviceInfoSet)
CloseHandle_(HidDevice)
CloseLibrary(0)
CloseLibrary(1)

End

Verfasst: 03.10.2005 23:46
von ts-soft
HID Nummer: 0
InterfaceClassGuid Data1= 4D1E55B2
InterfaceClassGuid Data2= FFFFF16F
InterfaceClassGuid Data3= 11CF
Flags= 1
Erster SetupDiGetDeviceInterfaceDetailA() Aufruf: RequiredSize= 86
Gerätpfadname: \\?\hid#vid_05fe&pid_0011#6&e7bdac4&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
HidDevice Handle: 1960
VendorID: 5FE
ProductID: 11
Versionsnummer: 1
Manufacturer: Cypress Semi.
Product: Cypress Ultra Mouse
--------------------------------------------------
Aber meine Drucker kriege ich nicht zu fassen. Aber schön, das Du doch noch zum Erfolg gekommen bist