SetupApi.h in Python throwing OSError: [WinError 6] The handle is invalid. in SetupDiEnumDeviceInterfaces.

Chris Kelble 1 Reputation point
2022-07-18T18:57:06.533+00:00

Using Windows 10 Enterprise system, I have a PCI card that I want to talk to in python. I have been give a Tcl Script that seems to use the SetupApi.h method and therefore all the constant values I am using I have gotten from there. Regardless, everything works until the SetupDiEnumDeviceInterfaces part. When it get there it throws OSError: [WinError 6] The handle is invalid.

Any thoughts?

import ctypes, ctypes.wintypes  
  
win = ctypes.wintypes  
  
NULL = 0  
HDEVINFO = ctypes.c_void_p  
BOOL = ctypes.c_int  
CHAR = ctypes.c_char  
PCTSTR = win.LPCWSTR  
HWND = ctypes.c_uint  
DWORD = ctypes.c_ulong  
PDWORD = ctypes.POINTER(DWORD)  
ULONG = ctypes.c_ulong  
ULONG_PTR = ctypes.POINTER(ULONG)  
PBYTE = ctypes.c_void_p  
  
DIGCF_DEFAULT                  = 0x00000001  
DIGCF_PRESENT                  = 0x00000002  
DIGCF_ALLCLASSES               = 0x00000004  
DIGCF_PROFILE                  = 0x00000008  
DIGCF_DEVICEINTERFACE          = 0x00000010  
FILE_FLAG_OVERLAPPED           = 0x40000000  
FILE_SHARE_READ                = 0x00000001  
FILE_SHARE_WRITE               = 0x00000002  
FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100  
FORMAT_MESSAGE_FROM_SYSTEM     = 0x00001000  
GENERIC_READ                   = 0x80000000  
GENERIC_WRITE                  = 0x40000000  
OPEN_EXISTING                  = 3  
WAIT_TIMEOUT                   = 0x00000102  
INVALID_HANDLE_VALUE           = 0  
  
  
class GUID(ctypes.Structure):  
    _fields_ = [  
        ('Data1', ctypes.c_ulong),  
        ('Data2', ctypes.c_ushort),  
        ('Data3', ctypes.c_ushort),  
        ('Data4', ctypes.c_ubyte*8),  
    ]  
    def __str__(self):  
        return "{%08x-%04x-%04x-%s-%s}" % (  
            self.Data1,  
            self.Data2,  
            self.Data3,  
            ''.join(["%02x" % d for d in self.Data4[:2]]),  
            ''.join(["%02x" % d for d in self.Data4[2:]]),  
        )  
  
class SP_DEVINFO_DATA(ctypes.Structure):  
    _fields_ = [  
        ('cbSize', DWORD),  
        ('ClassGuid', GUID),  
        ('DevInst', DWORD),  
        ('Reserved', ULONG_PTR),  
    ]  
    def __init__(self):  
        self.cbSize = ctypes.sizeof(self)  
  
PSP_DEVINFO_DATA = ctypes.POINTER(SP_DEVINFO_DATA)  
  
class SP_DEVICE_INTERFACE_DATA(ctypes.Structure):  
    _fields_ = [  
        ('cbSize', DWORD),  
        ('InterfaceClassGuid', GUID),  
        ('Flags', DWORD),  
        ('Reserved', ULONG_PTR),  
    ]  
    def __init__(self):  
        self.cbSize = ctypes.sizeof(self)  
  
  
PSP_DEVICE_INTERFACE_DATA = ctypes.POINTER(SP_DEVICE_INTERFACE_DATA)  
  
PSP_DEVICE_INTERFACE_DETAIL_DATA = PBYTE  
  
  
setupapi = ctypes.WinDLL('setupapi', use_last_error=True)  
  
SetupDiGetClassDevs = setupapi.SetupDiGetClassDevsA  
SetupDiGetClassDevs.argtypes = [ctypes.POINTER(GUID), PCTSTR, HWND, DWORD]  
SetupDiGetClassDevs.restype = BOOL  
  
SetupDiEnumDeviceInterfaces = setupapi.SetupDiEnumDeviceInterfaces  
SetupDiEnumDeviceInterfaces.argtypes = [HDEVINFO, PSP_DEVINFO_DATA, ctypes.POINTER(GUID), DWORD, PSP_DEVICE_INTERFACE_DATA]  
SetupDiEnumDeviceInterfaces.restype = BOOL  
  
  
  
  
GUID_SPWR_BASE_INTERFACE = GUID(0xa480c318, 0xfd41, 0x4973,  
    (ctypes.c_ubyte*8)(0xa5,0x4a, 0xa8, 0x24, 0x93, 0x11, 0xc7, 0x71))  
GUID_SPWR_CHAN_INTERFACE = GUID(0xe1eda58b, 0xf16c, 0x4489,  
    (ctypes.c_ubyte * 8)(0xa4,0xe9, 0xb4, 0xaa, 0x4f, 0x12, 0xb1, 0x6b))  
  
  
hDevInfo = SetupDiGetClassDevs(ctypes.byref(GUID_SPWR_BASE_INTERFACE), None, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)  
  
print(hDevInfo)  
  
for index in range(1):  
    interfaceData = SP_DEVICE_INTERFACE_DATA()  
    if not SetupDiEnumDeviceInterfaces(hDevInfo, None, ctypes.byref(GUID_SPWR_BASE_INTERFACE), index, ctypes.byref(interfaceData)):  
        raise ctypes.WinError(ctypes.get_last_error())  
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,656 questions
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.