0

I'm working in Python trying to create a simple program that reads and write from and to a fairly simple USB device. The problem I'm having is that since PyWinUSB and PyUSB don't seem to have what I need (trying to write to the device makes things explode), I have to work from scratch using the ctypes python module and the raw dll functions in WinUSB and SetupAPI.

I've been able to get my question answered about how to define the structure that I'm passing to the function, but the problem that I'm having now is that according to the specifications of the function... well, I'll just quote it.

"DeviceInterfaceData [out]

A pointer to a caller-allocated buffer that contains, on successful return, a
completed SP_DEVICE_INTERFACE_DATA structure that identifies an interface that meets
the search parameters. The caller must set DeviceInterfaceData.cbSize to
sizeof(SP_DEVICE_INTERFACE_DATA) before calling this function."

How do I translate these requirements into Python?

The structure class I'm working with right now looks like this:

class _SP_DEVINFO_DATA(ctypes.Structure):
    _fields_ = [("cbSize", wintypes.DWORD),
                ("ClassGuid", (ctypes.c_char * 16)),
                ("DevInst", wintypes.DWORD),
                ("Reserved", wintypes.LPVOID)]

    def __init__(self, guid, inst):
        self.cbSize = ctypes.sizeof(self)
        self.ClassGuid = uuid.UUID(guid).get_bytes()
        self.DevInst = (wintypes.DWORD)(inst)
        self.Reserved = None

    def __repr__(self):
        return "_SP_DEV_INFO_DATA(cbsize={}, ClassGuid={}, DevInst={})".format(
            self.cbSize, uuid.UUID(bytes=self.ClassGuid), hex(self.DevInst))

According to what I was informed by an answer to an earlier question.

Thanks.

Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
Will
  • 281
  • 1
  • 6
  • 18

1 Answers1

0

The SP_DEVINFO_DATA structure is returned by SetupDiEnumDeviceInfo. There is a different structure for SetupDiEnumDeviceInterfaces. In both cases, you device the structure, initialize just the cbSize parameter, and pass it by reference to the function:

Example (untested, just typing from memory):

class SP_DEVICE_INTERFACE_DATA(ctypes.Structure):
    _fields_ = [('cbSize',wintypes.DWORD),
                ('InterfaceClassGuid',ctypes.c_char*16),
                ('Flags',wintypes.DWORD),
                ('Reserved',wintypes.LPVOID)]
    def __init__(self):
        self.cbSize = ctypes.sizeof(self)

PSP_DEVICE_INTERFACE_DATA = ctypes.POINTER(SP_DEVICE_INTERFACE_DATA)

i = 0
idata = SP_DEVICE_INTERFACE_DATA()

while True:
    if not SetupDiEnumDeviceInterfaces(handle,None,guid,i,ctypes.byref(idata)):
        break
    <do something with idata>
    i += 1
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
  • Wouldn't if not SetupDIEnumDeviceInterfaces() be True when that function returns 0 when it fails? I tried running [this](http://pastebin.com/ygcUWWPM), and got up to over 1000 iterations before I keyboard interrupted with nothing appearing in the object I defined. Thanks again. – Will Oct 12 '12 at 16:40
  • Couldn't view your code. It said it was a private paste. Yes, when the function fails, the if is true and breaks from the loop. Did you forget to increment the index? – Mark Tolonen Oct 12 '12 at 17:46
  • Sorry about that, take a look at it again. I did remember to increment the index, but the problem is that the function fails every time. – Will Oct 12 '12 at 18:14
  • `DIGCF_DEVICEINTERFACE` isn't a string, it is a constant with the value 0x10. You have to look in the windows header files for the value. Also, you have to call `SetupDiEnumDeviceInfo` first. `SetupDiEnumDeviceInterfaces` takes an `SP_DEVINFO_DATA` pointer as its second parameter, which you have as None. is [this](http://msdn.microsoft.com/en-us/library/windows/hardware/ff540174(v=vs.85).aspx#winusb) what you are trying to do? – Mark Tolonen Oct 12 '12 at 20:01
  • I just had a realization in that I could take a look at the PyWinUSB module and see what they did in there and how I can adapt it to my needs. I can't believe it took me this long to realize that. I just wanted to stop by and say Thanks again for all the help you gave me, and if I do have any more questions I'll certainly be back. Thanks again. – Will Oct 15 '12 at 13:31