Conoscere i dispositivi usb di memorizzazione di massa con le funzioni esterne di libudev

Da Gambas-it.org - Wikipedia.

La libreria Libudev consente di elencare e conoscere alcune caratteristiche dei dispositivi locali del sistema.

E' dunque possibile, ad esempio, conoscere i dispositivi usb di memorizzazione di massa presenti e gestiti dal sistema.

E' necessario richiamare nell'applicazione Gambas la libreria condivisa: "libudev.so.1.7.8 ".


Mostriamo un esempio pratico:

Library "libudev:1.7.8"

' struct udev *udev_new(void)
' Create udev library context.
Private Extern udev_new() As Pointer

' struct udev_enumerate *udev_enumerate_new(struct udev *udev)
' Create, acquire and release a udev enumerate object.
Private Extern udev_enumerate_new(udev As Pointer) As Pointer

' int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem)
' Filter for a subsystem of the device to include in the list.
Private Extern udev_enumerate_add_match_subsystem(udev_enumerate As Pointer, subsystem As String) As Integer
 
' int udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate, const char *property, const char *value)
' Add a filter to match devices with the specified key and value.
Private Extern udev_enumerate_add_match_property(udev_enumerate As Pointer, propert As String, value As String) As Integer

' int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate)
' Query or modify a udev enumerate object.
Private Extern udev_enumerate_scan_devices(udev_enumerate As Pointer) As Integer

' struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate)
' Query or modify a udev enumerate object.
Private Extern udev_enumerate_get_list_entry(udev_enumerate As Pointer) As Pointer

' struct udev_list_entry *udev_list_entry_get_next(struct udev_list_entry *list_entry)
' Iterate and access udev lists.
Private Extern udev_list_entry_get_next(list_entry As Pointer) As Pointer

' const char *udev_list_entry_get_name(struct udev_list_entry *list_entry)
' Iterate and access udev lists.
Private Extern udev_list_entry_get_name(list_entry As Pointer) As String

' struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath)
' Create, acquire and release a udev device object.
Private Extern udev_device_new_from_syspath(udev As Pointer, syspath As String) As Pointer

' const char *udev_device_get_devnode(struct udev_device *udev_device)
' Returns the path to the device node itself in /dev.
Private Extern udev_device_get_devnode(udev_device As Pointer) As String

' struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype)
' Find the next parent device, with a matching subsystem and devtype value, and fill in information from the sys device and the udev database entry.
Private Extern udev_device_get_parent_with_subsystem_devtype(udev_device As Pointer, subsystem As String, devtype As String) As Pointer

' const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr)
' The retrieved value is cached in the device.
Private Extern udev_device_get_sysattr_value(udev_device As Pointer, sysattr As String) As String

' int udev_enumerate_add_match_parent(struct udev_enumerate *udev_enumerate, struct udev_device *parent)
' Modify filters.
Private Extern udev_enumerate_add_match_parent(udev_enumerate As Pointer, parent As Pointer) As Pointer

' struct udev_device *udev_device_unref(struct udev_device *udev_device)
' Drop a reference of a udev device.
Private Extern udev_device_unref(udev_device As Pointer) As Pointer

' struct udev_enumerate *udev_enumerate_unref(struct udev_enumerate *udev_enumerate)
' Drop a reference of an enumeration context.
Private Extern udev_enumerate_unref(udev_enumerate As Pointer) As Pointer

' struct udev *udev_unref(struct udev *udev)
' Drop a reference of the udev library context.
Private Extern udev_unref(udev As Pointer) As Pointer
 

Public Sub Main()
 
 Dim ud, en, ls, dev As Pointer
 Dim d, t, child_1, child_2 As Pointer
 Dim path, node_path As String

' Crea un contesto "udev":
 ud = udev_new()
 If ud == 0 Then Error.Raise("Impossibile creare un contesto 'udev' !")
   
' Crea una lista di dispositivi nel sottosistema "scsi":
 en = udev_enumerate_new(ud)
   
 udev_enumerate_add_match_subsystem(en, "scsi")
 udev_enumerate_add_match_property(en, "DEVTYPE", "scsi_device")
 udev_enumerate_scan_devices(en)
 ls = udev_enumerate_get_list_entry(en)
       
 dev = ls

 Repeat    
' Ottiene il nome del file della voce /sys per il dispositivo e crea un oggetto udev_device object(dev) che lo rappresenta:
   path = udev_list_entry_get_name(dev)
   d = udev_device_new_from_syspath(ud, path)
   If d == 0 Then Break
   child_1 = Ottiene_child(ud, d, "block")
   child_2 = Ottiene_child(ud, d, "scsi_disk")      
   node_path = udev_device_get_devnode(d)
   If Not IsNull(node_path) Then Print "Device Node Path: "; node_path
   t = udev_device_get_parent_with_subsystem_devtype(d, "usb", "usb_device")
   If t == 0 Then Break
   If child_1 <> 0 Then Print "  Device Node Path: "; udev_device_get_devnode(child_1)
   Print "  VID/PID: "; udev_device_get_sysattr_value(t, "idVendor"); ":"; udev_device_get_sysattr_value(t, "idProduct")
   If child_1 <> 0 Then Print "           "; udev_device_get_sysattr_value(d, "vendor")
   Print "           "; udev_device_get_sysattr_value(t, "manufacturer"), udev_device_get_sysattr_value(t, "product")
   Print "  serial:  "; udev_device_get_sysattr_value(t, "serial")
   Print
   If child_1 <> 0 Then udev_device_unref(child_1)
   If child_2 <> 0 Then udev_device_unref(child_2)
   udev_device_unref(d)
   dev = udev_list_entry_get_next(dev) 
 Until dev == 0

' Va in chiusura:
 udev_enumerate_unref(en)
 udev_unref(ud)
  
End


Private Function Ottiene_child(udev As Pointer, parent As Pointer, subsystem As String) As Pointer

 Dim child, enumerate, devices, dev As Pointer
 Dim path As String

 enumerate = udev_enumerate_new(udev)
 If enumerate == 0 Then Error.Raise("Errore !")

 udev_enumerate_add_match_parent(enumerate, parent)
 udev_enumerate_add_match_subsystem(enumerate, subsystem)
 udev_enumerate_scan_devices(enumerate)

 devices = udev_enumerate_get_list_entry(enumerate)
 If devices == 0 Then Error.Raise("Errore !")

 dev = devices
 Repeat
   path = udev_list_entry_get_name(dev)
   child = udev_device_new_from_syspath(udev, path)
   dev = udev_list_entry_get_next(dev)
 Until dev == 0

 udev_enumerate_unref(enumerate)
 Return child

End


Riferimenti