Example #1
6
    def getDescriptor(self, desc_type, desc_index, length, endpoint = -1):
        r"""Retrieves a descriptor from the device identified by the type
        and index of the descriptor.

        Arguments:
            desc_type: descriptor type.
            desc_index: index of the descriptor.
            len: descriptor length.
            endpoint: ignored.
        """
        return control.get_descriptor(self.dev, length, desc_type, desc_index)
Example #2
0
def get_string(dev, index, langid=None):
    r"""Retrieve a string descriptor from the device.

    dev is the Device object which the string will be
    read from.

    index is the string descriptor index and langid is the Language
    ID of the descriptor. If langid is omitted, the string descriptor
    of the first Language ID will be returned.

    The return value is the unicode string present in the descriptor.
    """
    from usb.control import get_descriptor
    if langid is None:
        # Asking for the zero'th index is special - it returns a string
        # descriptor that contains all the language IDs supported by the device.
        # Typically there aren't many - often only one. The language IDs are 16
        # bit numbers, and they start at the third byte in the descriptor. See
        # USB 2.0 specification section 9.6.7 for more information.
        #
        # Note from libusb 1.0 sources (descriptor.c)
        buf = get_descriptor(dev, 254, DESC_TYPE_STRING, 0)
        assert len(buf) >= 4
        langid = buf[2] | (buf[3] << 8)

    buf = get_descriptor(
        dev,
        255,  # Maximum descriptor size
        DESC_TYPE_STRING,
        index,
        langid)
    return buf[2:buf[0]].tostring().decode('utf-16-le')
Example #3
0
    def run_internal(self):
        """
        Run the Get Descriptor Sequence.

        @returns a list of descriptor objects.

        """
        if self.device_context is None:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceFrameworkError,
                                      'Test context not found')
        device = self.device_context.device
        if device is None:
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceFrameworkError,
                'Device %04X:%04X not found' %
                (self.device_context.id_vendor,
                 self.device_context.id_product))

        configuration = device.get_active_configuration()

        # Get the actual wTotalLength by retrieving partial descriptor.
        # desc_index corresponds to the index of a configuration. Note that
        # index is of 0 base while configuration is of 1 base.
        descriptors_byte_stream = control.get_descriptor(
            dev=device,
            desc_size=9,
            desc_type=util.DESC_TYPE_CONFIG,
            desc_index=configuration.bConfigurationValue - 1,
            wIndex=0)
        if descriptors_byte_stream is None:
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceSequenceError,
                'Failed to find configuration descriptor '
                'for active configuration of device '
                '%04X:%04X' % (device.idVendor, device.idProduct))

        # Verify returned data is the requested size.
        descriptor_length = descriptors_byte_stream[0]
        if descriptor_length != 9:
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceSequenceError,
                'Expected bLength to be 9, got %d.' % (descriptor_length))

        descriptors_byte_stream = control.get_descriptor(
            dev=device,
            desc_size=descriptors_byte_stream[2],
            desc_type=util.DESC_TYPE_CONFIG,
            desc_index=configuration.bConfigurationValue - 1,
            wIndex=0)
        descriptors = [
            descriptor
            for descriptor in DescriptorParser(descriptors_byte_stream)
        ]
        return descriptors
Example #4
0
def find_descriptors(idVendor, idProduct):
    dev = usb.core.find(idVendor=idVendor, idProduct=idProduct)
    if not dev:
        print("Could not find device %04x:%04x" % (idVendor, idProduct))
        return

    print("Found device:")
    print(dev._get_full_descriptor_str())
    print()
    print("USB %d.%d device found" % ((dev.bcdUSB & 0x0F00) >> 8,
                                      (dev.bcdUSB & 0x00F0) >> 4))
    if dev.bcdUSB < 0x0200:
        print("WCID descriptors are only valid for USB 2.0+")
        return

    DESC_TYPE_CONFIG = 0x02
    DESC_TYPE_STRING = 0x03
    MS_OS_STRING_IDX = 0xEE

    langids = dev.langids
    if not len(langids):
        print("The device has no language IDs")
        return

    buf = []
    for langid in langids:
        buf = get_descriptor(dev, 255, DESC_TYPE_STRING, MS_OS_STRING_IDX,
                             langid)
        if buf:
            break
    else:
        print("No Microsoft OS String Descriptor found")
        return

    ms_os_string = buf[2:buf[0]].tobytes().decode('utf-16-le')
    ms_vendor_req = buf[-2]
    if ms_os_string.startswith(u"MSFT100"):
        print("Found '%s' signature" % ms_os_string)
        print("Feature descriptor request 0x%02x" % ms_vendor_req)
        print()
    else:
        print("'MSFT100' signature not found")
        return

    try:
        feat_desc = dev.ctrl_transfer(0xC0, ms_vendor_req, 0, 0x0004, 16)
    except usb.core.USBError as e:
        print("Request failed with error: %s" % e)
        return
    if not feat_desc:
        print("No feature descriptor found")
        return
    feat_desc = dev.ctrl_transfer(0xC0, ms_vendor_req, 0, 0x0004, feat_desc[0])
    print_feature_descriptor(feat_desc)

    ext_feat_desc = dev.ctrl_transfer(0xC1, ms_vendor_req, 0, 0x0005, 255)
    if ext_feat_desc:
        print(' '.join(["%02x" % x for x in ext_feat_desc]))
    else:
        print("No extended feature descriptor found")
Example #5
0
def get_string(dev, index, langid = None):
    r"""Retrieve a string descriptor from the device.

    dev is the Device object which the string will be
    read from.

    index is the string descriptor index and langid is the Language
    ID of the descriptor. If langid is omitted, the string descriptor
    of the first Language ID will be returned.

    The return value is the unicode string present in the descriptor.
    """
    from usb.control import get_descriptor
    if langid is None:
	# Asking for the zero'th index is special - it returns a string
	# descriptor that contains all the language IDs supported by the device.
	# Typically there aren't many - often only one. The language IDs are 16
	# bit numbers, and they start at the third byte in the descriptor. See
	# USB 2.0 specification section 9.6.7 for more information.
        #
        # Note from libusb 1.0 sources (descriptor.c)
        buf = get_descriptor(
                    dev,
                    254,
                    DESC_TYPE_STRING,
                    0
                )
        assert len(buf) >= 4
        langid = buf[2] | (buf[3] << 8)

    buf = get_descriptor(
                dev,
                255, # Maximum descriptor size
                DESC_TYPE_STRING,
                index,
                langid
            )

    if hexversion >= 0x03020000:
        return buf[2:buf[0]].tobytes().decode('utf-16-le')
    else:
        return buf[2:buf[0]].tostring().decode('utf-16-le')
Example #6
0
    def getDescriptor(self, desc_type, desc_index, length, endpoint = -1):
        r"""Retrieves a descriptor from the device identified by the type
        and index of the descriptor.

        Arguments:
            desc_type: descriptor type.
            desc_index: index of the descriptor.
            len: descriptor length.
            endpoint: ignored.
        """
        return control.get_descriptor(self.dev, length, desc_type, desc_index)
Example #7
0
def get_string(dev, length, index, langid=None):
    r"""Retrieve a string descriptor from the device.

    dev is the Device object to which the request will be
    sent to.

    length is the length of string in number of characters.

    index is the string descriptor index and langid is the Language
    ID of the descriptor. If langid is omitted, the string descriptor
    of the first Language ID will be returned.

    The return value is the unicode string present in the descriptor.
    """
    from usb.control import get_descriptor
    if langid is None:
        # Asking for the zero'th index is special - it returns a string
        # descriptor that contains all the language IDs supported by the device.
        # Typically there aren't many - often only one. The language IDs are 16
        # bit numbers, and they start at the third byte in the descriptor. See
        # USB 2.0 specification section 9.6.7 for more information.
        #
        # Note from libusb 1.0 sources (descriptor.c)
        buf = get_descriptor(
            dev,
            1024,
            DESC_TYPE_STRING,
            0
        )
        assert len(buf) >= 4
        langid = buf[2] | (buf[3] << 8)

    buf = get_descriptor(
        dev,
        length * 2 + 2,  # string is utf16 + 2 bytes of the descriptor
        DESC_TYPE_STRING,
        index,
        langid
    )
    return buf[2:].tostring().decode('utf-16-le')
Example #8
0
def get_langids(dev):
    r"""Retrieve the list of supported Language IDs from the device.

    Most client code should not call this function directly, but instead use
    the langids property on the Device object, which will call this function as
    needed and cache the result.

    USB LANGIDs are 16-bit integers familiar to Windows developers, where
    for example instead of en-US you say 0x0409. See the file USB_LANGIDS.pdf
    somewhere on the usb.org site for a list, which does not claim to be
    complete. It requires "system software must allow the enumeration and
    selection of LANGIDs that are not currently on this list." It also requires
    "system software should never request a LANGID not defined in the LANGID
    code array (string index = 0) presented by a device." Client code can
    check this tuple before issuing string requests for a specific language ID.

    dev is the Device object whose supported language IDs will be retrieved.

    The return value is a tuple of integer LANGIDs, possibly empty if the
    device does not support strings at all (which USB 3.1 r1.0 section
    9.6.9 allows). In that case client code should not request strings at all.

    A USBError may be raised from this function for some devices that have no
    string support, instead of returning an empty tuple. The accessor for the
    langids property on Device catches that case and supplies an empty tuple,
    so client code can ignore this detail by using the langids property instead
    of directly calling this function.
    """
    from usb.control import get_descriptor
    buf = get_descriptor(
                dev,
                254,
                DESC_TYPE_STRING,
                0
            )

    # The array is retrieved by asking for string descriptor zero, which is
    # never the index of a real string. The returned descriptor has bLength
    # and bDescriptorType bytes followed by pairs of bytes representing
    # little-endian LANGIDs. That is, buf[0] contains the length of the
    # returned array, buf[2] is the least-significant byte of the first LANGID
    # (if any), buf[3] is the most-significant byte, and in general the LSBs of
    # all the LANGIDs are given by buf[2:buf[0]:2] and MSBs by buf[3:buf[0]:2].
    # If the length of buf came back odd, something is wrong.

    if len(buf) < 4 or buf[0] < 4 or buf[0]&1 != 0:
        return ()

    return tuple(map(lambda x,y: x+(y<<8), buf[2:buf[0]:2], buf[3:buf[0]:2]))
Example #9
0
def get_langids(dev):
    r"""Retrieve the list of supported Language IDs from the device.

    Most client code should not call this function directly, but instead use
    the langids property on the Device object, which will call this function as
    needed and cache the result.

    USB LANGIDs are 16-bit integers familiar to Windows developers, where
    for example instead of en-US you say 0x0409. See the file USB_LANGIDS.pdf
    somewhere on the usb.org site for a list, which does not claim to be
    complete. It requires "system software must allow the enumeration and
    selection of LANGIDs that are not currently on this list." It also requires
    "system software should never request a LANGID not defined in the LANGID
    code array (string index = 0) presented by a device." Client code can
    check this tuple before issuing string requests for a specific language ID.

    dev is the Device object whose supported language IDs will be retrieved.

    The return value is a tuple of integer LANGIDs, possibly empty if the
    device does not support strings at all (which USB 3.1 r1.0 section
    9.6.9 allows). In that case client code should not request strings at all.

    A USBError may be raised from this function for some devices that have no
    string support, instead of returning an empty tuple. The accessor for the
    langids property on Device catches that case and supplies an empty tuple,
    so client code can ignore this detail by using the langids property instead
    of directly calling this function.
    """
    from usb.control import get_descriptor
    buf = get_descriptor(
                dev,
                254,
                DESC_TYPE_STRING,
                0
            )

    # The array is retrieved by asking for string descriptor zero, which is
    # never the index of a real string. The returned descriptor has bLength
    # and bDescriptorType bytes followed by pairs of bytes representing
    # little-endian LANGIDs. That is, buf[0] contains the length of the
    # returned array, buf[2] is the least-significant byte of the first LANGID
    # (if any), buf[3] is the most-significant byte, and in general the LSBs of
    # all the LANGIDs are given by buf[2:buf[0]:2] and MSBs by buf[3:buf[0]:2].
    # If the length of buf came back odd, something is wrong.

    if len(buf) < 4 or buf[0] < 4 or buf[0]&1 != 0:
        return ()

    return tuple(map(lambda x,y: x+(y<<8), buf[2:buf[0]:2], buf[3:buf[0]:2]))
Example #10
0
def get_string(dev, index, langid = None):
    r"""Retrieve a string descriptor from the device.

    dev is the Device object which the string will be read from.

    index is the string descriptor index and langid is the Language
    ID of the descriptor. If langid is omitted, the string descriptor
    of the first Language ID will be returned.

    Zero is never the index of a real string. The USB spec allows a device to
    use zero in a string index field to indicate that no string is provided.
    So the caller does not have to treat that case specially, this function
    returns None if passed an index of zero, and generates no traffic
    to the device.

    The return value is the unicode string present in the descriptor, or None
    if the requested index was zero.

    It is a ValueError to request a real string (index not zero), if: the
    device's langid tuple is empty, or with an explicit langid the device does
    not support.
    """
    if 0 == index:
        return None

    from usb.control import get_descriptor
    langids = dev.langids

    if 0 == len(langids):
        raise ValueError("The device has no langid")
    if langid is None:
        langid = langids[0]
    elif langid not in langids:
        raise ValueError("The device does not support the specified langid")

    buf = get_descriptor(
                dev,
                255, # Maximum descriptor size
                DESC_TYPE_STRING,
                index,
                langid
            )
    if hexversion >= 0x03020000:
        return buf[2:buf[0]].tobytes().decode('utf-16-le')
    else:
        return buf[2:buf[0]].tostring().decode('utf-16-le')
Example #11
0
def get_string(dev, index, langid=None):
    r"""Retrieve a string descriptor from the device.

    dev is the Device object which the string will be read from.

    index is the string descriptor index and langid is the Language
    ID of the descriptor. If langid is omitted, the string descriptor
    of the first Language ID will be returned.

    Zero is never the index of a real string. The USB spec allows a device to
    use zero in a string index field to indicate that no string is provided.
    So the caller does not have to treat that case specially, this function
    returns None if passed an index of zero, and generates no traffic
    to the device.

    The return value is the unicode string present in the descriptor, or None
    if the requested index was zero.
    """
    if 0 == index:
        return None

    from usb.control import get_descriptor

    if langid is None:
        langids = dev.langids
        if 0 == len(langids):
            raise ValueError(
                "The device has no langid"
                " (permission issue, no string descriptors supported or device error)"
            )
        langid = langids[0]

    buf = get_descriptor(
        dev,
        254,  # maximum even length
        DESC_TYPE_STRING,
        index,
        langid)
    blen = buf[0] & 0xfe  # should be even, ignore any trailing byte (see #154)
    if hexversion >= 0x03020000:
        return buf[2:blen].tobytes().decode('utf-16-le')
    else:
        return buf[2:blen].tostring().decode('utf-16-le')
Example #12
0
def get_langids(dev):
    r"""Retrieve the list of supported Language IDs from the device.

    Most client code should not call this function directly, but instead use
    the langids property on the Device object, which will call this function as
    needed and cache the result.

    USB LANGIDs are 16-bit integers familiar to Windows developers, where
    for example instead of en-US you say 0x0409. See the file USB_LANGIDS.pdf
    somewhere on the usb.org site for a list, which does not claim to be
    complete. It requires "system software must allow the enumeration and
    selection of LANGIDs that are not currently on this list." It also requires
    "system software should never request a LANGID not defined in the LANGID
    code array (string index = 0) presented by a device." Client code can
    check this tuple before issuing string requests for a specific language ID.

    dev is the Device object whose supported language IDs will be retrieved.

    The return value is a tuple of integer LANGIDs, possibly empty if the
    device does not support strings at all (which USB 3.1 r1.0 section
    9.6.9 allows). In that case client code should not request strings at all.

    A USBError may be raised from this function for some devices that have no
    string support, instead of returning an empty tuple. The accessor for the
    langids property on Device catches that case and supplies an empty tuple,
    so client code can ignore this detail by using the langids property instead
    of directly calling this function.
    """
    from usb.control import get_descriptor
    buf = get_descriptor(dev, 254, DESC_TYPE_STRING, 0)

    if len(buf) < 4 or buf[0] < 4 or buf[0] & 1 != 0:
        return ()

    return tuple(
        map(lambda x, y: x + (y << 8), buf[2:buf[0]:2], buf[3:buf[0]:2]))
Example #13
0
def sendRequest():
    d = usb.core.find(idVendor=0x2b24, idProduct=0x0001)
    buf = get_descriptor(d, 0x0FFE, DESC_TYPE_STRING, d.iProduct, 1033)
    return buf