1 2 3 4 5 6
Win32::API->new( "libusb0", "usb_init" ) or die $^E; => Win32::API::parse_prototype: bad prototype 'usb_init' at C:/Perl/lib/Win32/API.pm line 541.
my $init = Win32::API->new("libusb0", "void usb_init()" ) or die $^E;
struct usb_bus *usb_get_busses(void);
1 2 3
my $usb_get_busses = Win32::API->new("libusb0", "usb_get_busses()", "V", "T") or die $^E; => Win32::API invalid return type, structs and callbacks as return types not supported at C:/Perl/lib/Win32/API.pm line 309.
2017-02-04T07:31:08 FIFOEin struct pointer als Rückgabetyp ist ein 'P' (oder 'N', vgl. Empfehlung in der Doku). Wenn man das struct selbst nachbaut (pack), muss man die tatsächlichen Bytegrößen kennen, incl. vielleicht nicht-Standard-alignement. Oder schau Dir mal Win32::API::Struct und diesen Abschnitt an. Das Arbeiten mit C-structs unter Win32::API ist kein wirkliches Vergnügen außer in simplen Fällen, Unicode (bzw. UTF16-LE)-Strings funktionieren z.B. nicht richtig ...
Device::USB ist leider nur Linux-tauglich.
1 2
my $usb_get_busses = Win32::API->new("libusb0", "usb_get_busses()","V","N") or die $^E; => Die angegebene Prozedur wurde nicht gefunden
1
2
3
4
5
6
D:\>pxhex.exe 1A 1A F0 DB 20 0A 00 18
success: device FFFF:1122 opened
success: set configuration #1
success: claim_interface #0
success: bulk write 8 bytes
Done.
2017-02-04T08:58:39 rostiCode (perl): (dl )1 2my $usb_get_busses = Win32::API->new("libusb0", "usb_get_busses()","V","N") or die $^E; => Die angegebene Prozedur wurde nicht gefunden
2017-02-04T06:42:51 rostiEdit: Deklariere ich den ReturnValue als Integer, bekomme ich einen Solchen der offensichtlich wie eine Speicheradresse aussieht -- wo meine heißbegehrten Daten liegen könnten.
$copy_of_memblock = ReadMemory($SourcePtr, $length);
2017-02-04T07:35:54 FIFO2017-02-04T06:42:51 rostiEdit: Deklariere ich den ReturnValue als Integer, bekomme ich einen Solchen der offensichtlich wie eine Speicheradresse aussieht -- wo meine heißbegehrten Daten liegen könnten.
Code (perl): (dl )$copy_of_memblock = ReadMemory($SourcePtr, $length);
... und dann unpack(). Aber wie gesagt, Du musst die Bytegrößen der struct members kennen, mit Beachtung eines evtl. veränderten alignment ...
1 2 3 4
my $usb_get_busses = Win32::API->new("libusb0", "int usb_get_busses()") or die $^E; my $pt = $usb_get_busses->Call; print Dumper ReadMemory($pt, 14);
2017-02-04T09:11:19 rostiReadMemory mit einer angenommen $length = 14 bringt mir viele binäre Nullen und dazwischen lesbar "bus-0".
1 2 3
my $Point = Win32::API::Struct->new( 'POINT' ); => Unknown Win32::API::Struct 'POINT'
1 2 3 4 5
Win32::API::Struct->typedef('usb_device'); my $dev = Win32::API::Struct->new( 'usb_device' ); $dev->{filename} = ''; # char filename[LIBUSB_PATH_MAX]; $dev->{devnum} = 1; # unsigned char devnum;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
DLL version: 1.2.6.0
Driver version: 1.2.6.0
bus/device idVendor/idProduct
bus-0/\\.\libusb0-0001--0xffff-0x1122 FFFF/1122
- Manufacturer : HANSON
- Product : USB Remote
bLength: 18
bDescriptorType: 01h
bcdUSB: 0110h
bDeviceClass: 00h
bDeviceSubClass: 00h
bDeviceProtocol: 00h
bMaxPacketSize0: 08h
idVendor: FFFFh
idProduct: 1122h
bcdDevice: 0001h
iManufacturer: 1
iProduct: 2
iSerialNumber: 0
bNumConfigurations: 1
wTotalLength: 34
bNumInterfaces: 1
bConfigurationValue: 1
iConfiguration: 0
bmAttributes: a0h
MaxPower: 50
bInterfaceNumber: 0
bAlternateSetting: 0
bNumEndpoints: 1
bInterfaceClass: 3
bInterfaceSubClass: 0
bInterfaceProtocol: 0
iInterface: 0
bEndpointAddress: 02h
bmAttributes: 03h
wMaxPacketSize: 8
bInterval: 10
bRefresh: 0
bSynchAddress: 0
2017-02-04T15:19:37 rostiPS/Edit: Ich glaub ich habs jetzt kapiert. Mit untenstehenden Eigenschaften muss ich zunächst alle Structs erstellen entsprechend der usb.h
Sieht z.B. so aus:
Code (perl): (dl )1 2 3 4 5Win32::API::Struct->typedef('usb_device'); my $dev = Win32::API::Struct->new( 'usb_device' ); $dev->{filename} = ''; # char filename[LIBUSB_PATH_MAX]; $dev->{devnum} = 1; # unsigned char devnum;
Die Frage ist noch, wie setze ich ein struct usb_device *next, *prev; in das Struct?
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Win32::API->Import('libusb0', 'int usb_get_busses()'); my $mem_usb_bus = ReadMemory(usb_get_busses(), 532); my %usb_bus; @usb_bus{qw(next prev dirname devices location root_dev)} = unpack "VVZ512VVV", $mem_usb_bus; die Dumper \%usb_bus; $VAR1 = { 'devices' => 11880344, 'dirname' => 'bus-0', 'location' => 0, 'next' => 0, 'prev' => 0, 'root_dev' => 12579720 };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
$VAR1 = { 'bDescriptorType' => 1, 'bDeviceClass' => 0, 'bDeviceProtocol' => 0, 'bDeviceSubClass' => 0, 'bLength' => 18, 'bMaxPacketSize0' => 8, 'bNumConfigurations' => 1, 'bcdDevice' => 1, 'bcdUSB' => 272, 'dev' => 0, 'filename' => '\\\\.\\libusb0-0001--0xffff-0x1122', 'iManufacturer' => 1, 'iProduct' => 2, 'iSerialNumber' => 0, 'idProduct' => 4386, 'idVendor' => 65535, 'next' => 0, 'prev' => 0, 'usb_bus' => 9769944, 'usb_config_descriptor' => 9769760 };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct usb_device
{
struct usb_device *next, *prev;
char filename[LIBUSB_PATH_MAX];
struct usb_bus *bus;
struct usb_device_descriptor descriptor; # Frage 1
struct usb_config_descriptor *config;
void *dev; /* Darwin support */ # Frage 2
unsigned char devnum;
unsigned char num_children;
struct usb_device **children;
};
2017-02-05T18:14:31 rostiCode: (dl )1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18struct usb_device
{
struct usb_device *next, *prev;
char filename[LIBUSB_PATH_MAX];
struct usb_bus *bus;
struct usb_device_descriptor descriptor; # Frage 1
struct usb_config_descriptor *config;
void *dev; /* Darwin support */ # Frage 2
unsigned char devnum;
unsigned char num_children;
struct usb_device **children;
};
Pointer ist klar, der beansprucht 4 Bytes als little Endian.
Frage 1: Das ist kein Pointer, wieviele Bytes muss ich da veranschlagen? sizeof(usb_device_descriptor) und die Daten als Array?
Frage 2: Vermutlich 0 Bytes?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Win32::API->Import('libusb0', 'usb_open',"I","P") or die $^E; Win32::API::Struct->typedef( 'usb_device', "LPLONG","next", "LPLONG","prev", "CHAR","filename", # hat 512 byte "LPLONG","usb_bus", "CHAR","bLength", "CHAR","bDescriptorType", "SHORT","bcdUSB", "CHAR","bDeviceClass", "CHAR","bDeviceSubClass", "CHAR","bDeviceProtocol", "CHAR","bMaxPacketSize0", "SHORT","idVendor", "SHORT","idProduct", "SHORT","bcdDevice", "CHAR","iManufacturer", "CHAR","iProduct", "CHAR","iSerialNumber", "CHAR","bNumConfigurations", "LPLONG","config", "VOID","dev", "CHAR","devnum", "CHAR","num_children", "LPLONG","children" ); my $dev = Win32::API::Struct->new( 'usb_device'); foreach my $key(keys %usb_device){ $dev->{$key} = $usb_device{$key}} usb_open($dev);
2017-02-06T06:28:11 rostiUnklar auch die typedef. So ist filename lt. struct
char filename[LIBUSB_PATH_MAX];
und meine Deklaration mit CHAR ist mit Sicherheit falsch -- nur wie mache ich es richtig? In Type.pm finde ich nichts passendes und die Doku gibt es auch nicht her..
1 2 3 4 5 6
$self->_get_busses; $self->_get_fst_device; $self->_get_configuration; $self->_get_interface; $self->_usb_open;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
sub _get_busses{ my $self = shift; my $usb_get_busses = Win32::API->new('libusb0', 'int usb_get_busses()'); my $bus_addr = $usb_get_busses->Call(); #print $bus_addr,"\n"; # Erstes usb_bus-struct einlesen und entpacken my $mem_usb_bus = ReadMemory($bus_addr, 532); my %usb_bus; @usb_bus{qw(next prev dirname devices location root_dev)} = unpack "VVZ512VVV", $mem_usb_bus; # In $usb_bus{devices} ist also jetzt die Adresse des ersten usb_device-structs im ersten usb_bus # ab hier ??? --------------------------------------------------- Win32::API::Struct->typedef( 'usb_bus', "INT_PTR","devices" # ??? ); my $usb_bus = Win32::API::Struct->new( 'usb_bus'); #$self->dd($usb_bus); # bis hier ??? -------------------------------------------------- $self->{usb_bus} = \%usb_bus; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
usb_dev_handle *open_dev(void){
struct usb_bus *bus;
struct usb_device *dev;
for (bus = usb_get_busses(); bus; bus = bus->next){
for (dev = bus->devices; dev; dev = dev->next){
if (dev->descriptor.idVendor == MY_VID
&& dev->descriptor.idProduct == MY_PID){
return usb_open(dev);
}
}
}
return NULL;
}
1 2 3 4 5 6 7 8 9 10
my $mem_usb_bus = ReadMemory($bus_addr, 532); my %usb_bus; @usb_bus{qw( next prev dirname devices location root_dev )} = unpack "VVZ512VVV", $mem_usb_bus;
void *dev /* Darwin support */
2017-02-08T08:21:10 rostiusb_open() gibt mir ja den Pointer aufs Device, in Perl hätte ich die Speicheradresse. Und wie das Struct fürs Device aussieht, was LibUSB intern verwendet, gibt nicht einmal die Header Datei her.
1
2
3
4
struct usb_dev_handle;
typedef struct usb_dev_handle usb_dev_handle;
...
usb_dev_handle *usb_open(struct usb_device *dev);
2017-02-08T14:42:25 rostiGibt mir mal bitte eine Hilfe wo ich nachlesen kann wie das geht.
2017-02-08T15:30:18 FIFO