0

I'm trying to create a simple read/write application for a fairly simple USB device, but it's turning out to be not so simple at all.

I'm using WinUSB and SetupAPI DLLs and working from scratch since I can't seem to find anything that actually works for what I need. PyWinUSB and PyUSB and so on and so forth came close, but when I tried actually writing to the device with them they failed.

Anyway, right now I'm still at about ground zero. Following the instructions, I'm calling the SetupDiGetClassDevsExW function from the SetupAPI.dll. The function executes correctly as indicated by a call to the kernel32.lasterror function returning zero, but the only thing I'm getting back from the call is an integer value. Is that correct? Is this even the correct function? (There are 4 that are similar, and there is no just plain SetupDiGetClassDevs function. The 4 functions are SetupGetClassDevsExW, SetupGetCLassDevsExA, SetupGetClassDevsA, and SetupGetClassDevsW.) Do I need to create a class to work with this? I ask because calling the next function, SetupDiEnumDeviceInterfaces, has only been returning a fail with code 259, which means ERROR_NO_MORE_ITEMS according to a quick google search.

I've made some headway in that someone has showed me the correct class structure method for creating a structure for holding some information, but being that I've never actually worked with programming for a USB device before, let alone in Python, I'm still kind of stuck. I'll provide any more information that is needed for an answer, but right now I don't want to bog this Q/A down with needless information.

Thanks.

Chris Morgan
  • 86,207
  • 24
  • 208
  • 215
Will
  • 281
  • 1
  • 6
  • 18

1 Answers1

0

There is a SetupDiGetClassDevsA and SetupDiGetClassDevsW. The Ex versions allow connecting to a remote machine. The A version takes a byte string for the second parameter, while the W version takes a Unicode string. The return value is a handle to a device information set.

The device information set has to be iterated with either SetupDiEnumDeviceInfo or SetupDiEnumDeviceInterfaces. The second function only works if you pass DIGCF_DEVICEINTERFACE as a flag to SetupDiGetClassDevs and pass an interface GUID for the ClassGuid parameter; otherwise, you pass a device class GUID and only SetupDiEnumDeviceInfo will return anything.

Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
  • So just receiving a returned Integer value from calling SetupDiGetCLassDevsA(uuid.UUID(classGuid).get_bytes()) with None or NULL for the remaining arguments is correct? As long as classGuid is a correctly formatted GUID string of hex values? – Will Oct 12 '12 at 16:00
  • For example, `SetupDiGetClassDevs(None,None,None,DIGCF_ALLCLASSES|DIGCF_PRESENT)` will find all devices in the system. With a GUID it will find all of a particular class, with an enumerator parameter like `'PCI'` it will find all PCI devices. – Mark Tolonen Oct 12 '12 at 16:41
  • `SetupDiGetClassDevs(interfaceClassGuid,None,None,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE)` will find a particular kind of device interface (devices can have more than one interface class). – Mark Tolonen Oct 12 '12 at 16:42
  • The handle returned in either case is passed to `SetupDiEnumDeviceInfo` with an index. Pass 0 to get the first device, 1 to get the second, etc. If you queried an interfaceClassGuid, once you have the device info handle you can pass that to `SetupDiEnumDeviceInterfaces` to get the device interface data, and from that returned structure you can finally get the device path string to use with CreateDevice to open whatever device you are looking for. It's quite complicated, but I recently had to go through this for a project I'm working on. – Mark Tolonen Oct 12 '12 at 16:46
  • The only problem is that, with Python, SetupDiEnumDeviceInfo only ever returns an integer value. Trying to call the function with no GUID and a string flag returns an invalid parameter error, and trying to call the function with an unquoted literal returns a python error. So I guess to backtrack a little bit, how do I pass this function the flags it's looking for? – Will Oct 12 '12 at 17:54