Recent

Author Topic: [SOLVED] Libusb get_string_descriptor_ascii  (Read 8911 times)

minkob

  • New Member
  • *
  • Posts: 13
[SOLVED] Libusb get_string_descriptor_ascii
« on: November 09, 2014, 07:17:29 pm »
Hi All.
In my co de below everything works fine till function libusb_get_string_descriptor_ascii. Here project stops with E: Project raised exception class EXTERNAL:SIGSEGV At address B7FB0638
Code: [Select]
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, libusb;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
  max_list: size_t;
  list: PPPlibusb_device;
  myP_Device: Plibusb_device;
  myP_Descriptor: Plibusb_device_descriptor;
  myDescriptor: libusb_device_descriptor;
  myP_DevHandle : Plibusb_device_handle;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
   strDesc : packed array [0..20] of char;
   retVal : byte;
   I: Integer;
begin
  ListBox1.Items.Clear;
  libusb_init(nil);
  max_list := libusb_get_device_list(nil, @list);
  for I := 0 to max_list - 1 do
  begin
    myP_Device := @list[I]^;
    try
       retVal := libusb_open(myP_Device, @myP_DevHandle);
    except
      if (retVal <> LIBUSB_SUCCESS) then
         ShowMessage(' chyba so spravou: retVal != LIBUSB_SUCCES');
    end;
    libusb_get_device_descriptor(myP_Device, @myP_Descriptor);
    myDescriptor := Plibusb_device_descriptor(@myP_Descriptor)^;
    ListBox1.Items.Add(IntToStr(I+1) +'. -VID: ' + IntToHex(myDescriptor.idVendor,4) + '  -PID:  ' + IntToHex(myDescriptor.idProduct,4));
    libusb_get_string_descriptor_ascii(myP_DevHandle ,myDescriptor.iProduct, strDesc, length(strDesc));  // <- problem
    ListBox1.Items.Add(strDesc);
    try
        libusb_close(myP_DevHandle);
    except
        on E : ExceptioN  do ShowMessage(E.Classname+  ' chyba so spravou: '+E.Message);
    end;
    myP_DevHandle := nil;
  end;
    libusb_exit(nil);
end;
end.     

Here is function declaration from libusb.pp
Code: [Select]
function libusb_get_string_descriptor_ascii(dev:plibusb_device_handle ;index:uint8_t; data:Pchar; length:integer):Integer;cdecl;external;

Here is an assembler window
Code: [Select]
B7FB061C 8d742600                 lea    0x0(%esi,%eiz,1),%esi
libusb_submit_transfer
B7FB0620 55                       push   %ebp
B7FB0621 57                       push   %edi
B7FB0622 56                       push   %esi
B7FB0623 53                       push   %ebx
B7FB0624 83ec4c                   sub    $0x4c,%esp
B7FB0627 8b742460                 mov    0x60(%esp),%esi
B7FB062B e8c0b7ffff               call   0xb7fabdf0 <__x86.get_pc_thunk.bx>
B7FB0630 81c3d0f90000             add    $0xf9d0,%ebx
B7FB0636 8b06                     mov    (%esi),%eax
B7FB0638 8b4024                   mov    0x24(%eax),%eax          <- problem
B7FB063B 8b401c                   mov    0x1c(%eax),%eax
B7FB063E 89442420                 mov    %eax,0x20(%esp)
B7FB0642 8d46e8                   lea    -0x18(%esi),%eax

What I am doing wrong?
Linux Mageia4 32bit, Lazarus 1.2.6
« Last Edit: December 21, 2014, 02:17:16 pm by minkob »
ASUS K53S i5
Fedora fc30.x86_64
Lazarus 2.0.10
FPC 3.1.0

Cyrax

  • Hero Member
  • *****
  • Posts: 836
Re: Libusb get_string_descriptor_ascii
« Reply #1 on: November 10, 2014, 02:04:15 am »
Change:

Code: [Select]
libusb_get_string_descriptor_ascii(myP_DevHandle ,myDescriptor.iProduct, strDesc, length(strDesc));
to:

Code: [Select]
libusb_get_string_descriptor_ascii(myP_DevHandle ,myDescriptor.iProduct, @strDesc[0], length(strDesc));
data parameter expects a address to the target variable. Also when dealing with arrays or dynamic arrays, always speficy first element of the array.

minkob

  • New Member
  • *
  • Posts: 13
Re: Libusb get_string_descriptor_ascii
« Reply #2 on: November 10, 2014, 07:15:30 am »
Thanks.
But the same failure. IMHO only simply written name of  array is an adress of its first element, so if expected PChar, then strDesc is a pointer (adress) to array .
ASUS K53S i5
Fedora fc30.x86_64
Lazarus 2.0.10
FPC 3.1.0

Leledumbo

  • Hero Member
  • *****
  • Posts: 8747
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Libusb get_string_descriptor_ascii
« Reply #3 on: November 10, 2014, 07:46:43 am »
Change:

Code: [Select]
libusb_get_string_descriptor_ascii(myP_DevHandle ,myDescriptor.iProduct, strDesc, length(strDesc));
to:

Code: [Select]
libusb_get_string_descriptor_ascii(myP_DevHandle ,myDescriptor.iProduct, @strDesc[0], length(strDesc));
data parameter expects a address to the target variable. Also when dealing with arrays or dynamic arrays, always speficy first element of the array.
strDesc is declared as static array, this won't change anything but indeed is a good practice when incidental change to dynamic array is done (no need to change). What I wonder is the packed keyword. I don't think it's required, so maybe you want to try removing it.

minkob

  • New Member
  • *
  • Posts: 13
Re: Libusb get_string_descriptor_ascii
« Reply #4 on: November 10, 2014, 01:28:20 pm »
After removing packed is it still the same problem.
ASUS K53S i5
Fedora fc30.x86_64
Lazarus 2.0.10
FPC 3.1.0

Laksen

  • Hero Member
  • *****
  • Posts: 724
    • J-Software
Re: Libusb get_string_descriptor_ascii
« Reply #5 on: November 10, 2014, 02:22:06 pm »
The error is here:
Code: [Select]
    libusb_get_device_descriptor(myP_Device, @myP_Descriptor);
    myDescriptor := Plibusb_device_descriptor(@myP_Descriptor)^;

That should be
Code: [Select]
var
    libusb_get_device_descriptor(myP_Device, @myDescriptor);

minkob

  • New Member
  • *
  • Posts: 13
Re: Libusb get_string_descriptor_ascii
« Reply #6 on: November 10, 2014, 03:24:52 pm »
@Laksen
Code: [Select]
libusb_get_device_descriptor(myP_Device, @myDescriptor);this will bring back 0000 as a VID and PID
ASUS K53S i5
Fedora fc30.x86_64
Lazarus 2.0.10
FPC 3.1.0

minkob

  • New Member
  • *
  • Posts: 13
Re: Libusb get_string_descriptor_ascii
« Reply #7 on: December 18, 2014, 04:36:43 pm »
Partially solved.
When starting as a regular user from CLI
Code: [Select]
milan @ localhost ~/ide/lazarus/usbtest $ ./project1
TApplication.HandleException Access violation
  Stack trace:
  $B7702428
WARNING: TLCLComponent.Destroy with LCLRefCount>0. Hint: Maybe the component is processing an event?

but the same started as a root works perfect  :(
Any hints?
Now Mageia 5
ASUS K53S i5
Fedora fc30.x86_64
Lazarus 2.0.10
FPC 3.1.0

Cyrax

  • Hero Member
  • *****
  • Posts: 836
Re: Libusb get_string_descriptor_ascii
« Reply #8 on: December 18, 2014, 06:13:46 pm »
Which groups your user belong? You might want to change/create udev rule for USB devices so they will get/inherit special group id for them so you don't need to run your apps in root rights.

minkob

  • New Member
  • *
  • Posts: 13
Re: Libusb get_string_descriptor_ascii
« Reply #9 on: December 18, 2014, 07:10:39 pm »
Thank You. So tomorrow I will fight with udev rules. (Something new to learn  :))
ASUS K53S i5
Fedora fc30.x86_64
Lazarus 2.0.10
FPC 3.1.0

minkob

  • New Member
  • *
  • Posts: 13
Re: Libusb get_string_descriptor_ascii
« Reply #10 on: December 20, 2014, 05:30:06 pm »
So I have created new group myusb (id477) added me as a member and written udev rule:
Code: [Select]
KERNEL=="sd[b-z]1", SUBSYSTEM=="block", GROUP="myusb", MODE="0660"It is saved in /etc/udev/rules.d. But it does not work.
Adding me to the root group does not work too. What's wrong?

Info about device:
Code: [Select]
root @ localhost /home/milan # udevadm info -a -p $(udevadm info -q path -n /dev/sdb1)                                                                         

  looking at device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/host6/target6:0:0/6:0:0:0/block/sdb/sdb1':
    KERNEL=="sdb1"
    SUBSYSTEM=="block"
    DRIVER==""
    ATTR{ro}=="0"
    ATTR{size}=="63968"
    ATTR{stat}=="     323        0     1513     1060        0        0        0        0        0     1060     1060"
    ATTR{partition}=="1"
    ATTR{start}=="32"
    ATTR{discard_alignment}=="0"
    ATTR{alignment_offset}=="0"
    ATTR{inflight}=="       0        0"

  looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/host6/target6:0:0/6:0:0:0/block/sdb':                                     
    KERNELS=="sdb"                                                             
    SUBSYSTEMS=="block"                                                         
    DRIVERS==""                                                                 
    ATTRS{ro}=="0"                                                             
    ATTRS{size}=="64000"
    ........     
ASUS K53S i5
Fedora fc30.x86_64
Lazarus 2.0.10
FPC 3.1.0

Cyrax

  • Hero Member
  • *****
  • Posts: 836
Re: Libusb get_string_descriptor_ascii
« Reply #11 on: December 21, 2014, 02:15:43 am »
See Arch documentation on the matter : https://wiki.archlinux.org/index.php/udev

What does lsusb command print?

minkob

  • New Member
  • *
  • Posts: 13
[SOLVED] Re: Libusb get_string_descriptor_ascii
« Reply #12 on: December 21, 2014, 02:16:02 pm »
I don't no why but today everything works fine without restarting computer.
Rule, permisions ...nothing was changed  :o .
Thank You boys, especially Cyrax.
ASUS K53S i5
Fedora fc30.x86_64
Lazarus 2.0.10
FPC 3.1.0

 

TinyPortal © 2005-2018