The following piece of code uses only standard libraries, and runs without an error in a 32bit Python 3.6 interpreter, but returns an error in a 64bit one (Windows handle is invalid):
import ctypes, ctypes.wintypes
INVALID_HANDLE_VALUE = -1
DIGCF_PRESENT = 0x00000002
DIGCF_DEVICEINTERFACE = 0x00000010
ERROR_INSUFFICIENT_BUFFER = 122
ERROR_NO_MORE_ITEMS = 259
MAXIMUM_USB_STRING_LENGTH = 255
kernel32 = ctypes.windll.kernel32
setupapi = ctypes.windll.setupapi
SetupDiGetClassDevs = setupapi.SetupDiGetClassDevsW
SetupDiEnumDeviceInterfaces = setupapi.SetupDiEnumDeviceInterfaces
SetupDiGetDeviceInterfaceDetail = setupapi.SetupDiGetDeviceInterfaceDetailW
CM_Get_Parent = setupapi.CM_Get_Parent
CM_Get_Device_ID = setupapi.CM_Get_Device_IDW
CM_Request_Device_Eject = setupapi.CM_Request_Device_EjectW
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-%04X-%012X}' % (
self.Data1, self.Data2, self.Data3,
self.Data4[0] * 256 + self.Data4[1],
self.Data4[2] * (256 ** 5) +
self.Data4[3] * (256 ** 4) +
self.Data4[4] * (256 ** 3) +
self.Data4[5] * (256 ** 2) +
self.Data4[6] * 256 +
self.Data4[7])
class SP_DEVINFO_DATA(ctypes.Structure):
_fields_ = [("cbSize", ctypes.wintypes.DWORD),
("ClassGuid", GUID),
("DevInst", ctypes.wintypes.DWORD),
("Reserved", ctypes.c_void_p)
]
class SP_DEVICE_INTERFACE_DATA(ctypes.Structure):
_fields_ = [("cbSize", ctypes.wintypes.DWORD),
("InterfaceClassGuid", GUID),
("Flags", ctypes.wintypes.DWORD),
("Reserved", ctypes.c_void_p)
]
class SP_DEVICE_INTERFACE_DETAIL_DATA(ctypes.Structure):
_fields_ = [("cbSize", ctypes.wintypes.DWORD),
("DevicePath", ctypes.c_wchar*255)]
GUID_DEVINTERFACE_VOLUME = GUID(0x53F5630D, 0xB6BF, 0x11D0,
(ctypes.c_ubyte*8)(0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B))
hDevInfo = SetupDiGetClassDevs(ctypes.byref(GUID_DEVINTERFACE_VOLUME),
0,
0,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)
if hDevInfo == INVALID_HANDLE_VALUE:
print(ctypes.windll.GetLastError(), ctypes.windll.FormatError())
def get_device_interface(i, device=None):
interfaceData = SP_DEVICE_INTERFACE_DATA()
interfaceData.cbSize = ctypes.sizeof(SP_DEVICE_INTERFACE_DATA)
if SetupDiEnumDeviceInterfaces(
hDevInfo,
device and ctypes.byref(device) or None,
ctypes.byref(GUID_DEVINTERFACE_VOLUME),
i,
ctypes.byref(interfaceData)):
return interfaceData
elif ctypes.GetLastError() == ERROR_NO_MORE_ITEMS:
return
else:
print(ctypes.GetLastError(), ctypes.FormatError())
def connected_devices():
interface_index = 0
interface = get_device_interface(interface_index)
devices = connected_devices()
I suspect that the issue is not strictly a Python problem, but rather a difference in how 64 and 32 bit interpreter types interact with Windows.
Can anyone explain why this is happening?
User contributions licensed under CC BY-SA 3.0