1

Additionally as I am on Windows (this is eventually going to be for work) I am using libusb_package to use libusb on Windows as well as the PyUSB package as suggested in their documentation.

I am trying to get Mass Storage device details from the PyUSB Library which for the most part is working fine if I display all USB devices. But I only want to show Mass Storage - USB Descriptor (bInterfaceClass 0x8).

Essentially all I need is idVendor, idProduct and iSerialNumber for every Mass Storage device plugged into the machine.

Now I think some of the problem is around the data type. So in the full output of the device using the code:

def get_usb_devices():
    for dev in libusb_package.find(find_all=True):
        print('{}'.format(dev))

Yes I am using print in a function for debugging :)

The output will display:

DEVICE ID 090c:1000 on Bus 002 Address 001 =================
bLength                :   0x12 (18 bytes)
bDescriptorType        :    0x1 Device
bcdUSB                 :  0x310 USB 3.1
bDeviceClass           :    0x0 Specified at interface
bDeviceSubClass        :    0x0
bDeviceProtocol        :    0x0
bMaxPacketSize0        :    0x9 (9 bytes)
idVendor               : 0x090c
idProduct              : 0x1000
bcdDevice              : 0x1100 Device 17.0
iManufacturer          :    0x1 Samsung
iProduct               :    0x2 Flash Drive
iSerialNumber          :    0x3 0376220010001205
bNumConfigurations     :    0x1
CONFIGURATION 1: 76 mA ===================================
bLength              :    0x9 (9 bytes)
bDescriptorType      :    0x2 Configuration
wTotalLength         :   0x2c (44 bytes)
bNumInterfaces       :    0x1
bConfigurationValue  :    0x1
iConfiguration       :    0x0 
bmAttributes         :   0x80 Bus Powered
bMaxPower            :   0x26 (76 mA)
INTERFACE 0: Mass Storage ==============================
bLength            :    0x9 (9 bytes)
bDescriptorType    :    0x4 Interface
bInterfaceNumber   :    0x0
bAlternateSetting  :    0x0
bNumEndpoints      :    0x2
bInterfaceClass    :    0x8 Mass Storage
bInterfaceSubClass :    0x6
bInterfaceProtocol :   0x50
iInterface         :    0x0 
ENDPOINT 0x1: Bulk OUT ===============================
bLength          :    0x7 (7 bytes)
bDescriptorType  :    0x5 Endpoint
bEndpointAddress :    0x1 OUT
bmAttributes     :    0x2 Bulk
wMaxPacketSize   :  0x400 (1024 bytes)
bInterval        :    0x0
ENDPOINT 0x82: Bulk IN ===============================
bLength          :    0x7 (7 bytes)
bDescriptorType  :    0x5 Endpoint
bEndpointAddress :   0x82 IN
bmAttributes     :    0x2 Bulk
wMaxPacketSize   :  0x400 (1024 bytes)
bInterval        :    0x0

Now by using the following code (and I know I am going over the Interface part here (which is what I actually need)

def get_usb_devices():
        dev = libusb_package.find(find_all=True)
        for cfg in dev: # Configuration Items
            for msd in cfg: # Interface Items
                msdInt = usb.util.find_descriptor(msd, find_all=True, bInterfaceClass=8) # 0x8 MStor
                for msdDev in msdInt:
                    print('{}'.format(msdDev)) # Type <class 'usb.core.Interface'>

I get the data from the item I need which I can use in as a list msdDev[0] for example will show the ENDPOINT and so on.

INTERFACE 0: Mass Storage ==============================
bLength            :    0x9 (9 bytes)
bDescriptorType    :    0x4 Interface
bInterfaceNumber   :    0x0
bAlternateSetting  :    0x0
bNumEndpoints      :    0x2
bInterfaceClass    :    0x8 Mass Storage
bInterfaceSubClass :    0x6
bInterfaceProtocol :   0x50
iInterface         :    0x0 
ENDPOINT 0x1: Bulk OUT ===============================
bLength          :    0x7 (7 bytes)
bDescriptorType  :    0x5 Endpoint
bEndpointAddress :    0x1 OUT
bmAttributes     :    0x2 Bulk
wMaxPacketSize   :  0x400 (1024 bytes)
bInterval        :    0x0
ENDPOINT 0x82: Bulk IN ===============================
bLength          :    0x7 (7 bytes)
bDescriptorType  :    0x5 Endpoint
bEndpointAddress :   0x82 IN
bmAttributes     :    0x2 Bulk
wMaxPacketSize   :  0x400 (1024 bytes)
bInterval        :    0x0

But I just cant seem to find a way to get

DEVICE ID 090c:1000 on Bus 002 Address 001 =================
bLength                :   0x12 (18 bytes)
bDescriptorType        :    0x1 Device
bcdUSB                 :  0x310 USB 3.1
bDeviceClass           :    0x0 Specified at interface
bDeviceSubClass        :    0x0
bDeviceProtocol        :    0x0
bMaxPacketSize0        :    0x9 (9 bytes)
idVendor               : 0x090c
idProduct              : 0x1000
bcdDevice              : 0x1100 Device 17.0
iManufacturer          :    0x1 Samsung
iProduct               :    0x2 Flash Drive
iSerialNumber          :    0x3 0376220010001205
bNumConfigurations     :    0x1

Which is all I need.

I would really appreciate any direction, I have been wrapping my brains around this for a few days and I am sure it is something simple. I could not find anything else that could help on StackOverflow or popular search engines.

dlystyr
  • 103
  • 6

1 Answers1

0

I managed to fix this using

class find_class(object):
def __init__(self, class_):
    self._class = class_

def __call__(self, device):
    # first, let's check the device
    if device.bDeviceClass == self._class:
        return True
    # ok, transverse all devices to find an
    # interface that matches our class
    for cfg in device:
        # find_descriptor: what's it?
        intf = usb.util.find_descriptor(
            cfg,
            bInterfaceClass=self._class
        )
        if intf is not None:
            return True

    return False
dlystyr
  • 103
  • 6