我想通过Ctypes枚举设备,转换问题
I want to enumerate devices via Ctypes,conversion problem
我想用Ctypes来枚举设备,下面的例子是C++语言我不是很擅长转换,下面的代码是我写的一半
我的问题是如何转换这个
//Enumerate through all devices in Set
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,
&DeviceInfoData);i++)
import ctypes as ct
from ctypes import wintypes as w
SetupAPI = ct.WinDLL('SetupAPI')
SetupAPI.SetupDiGetClassDevsW.argtypes = w.LPVOID,w.PWCHAR,w.HWND,w.DWORD
SetupAPI.SetupDiGetClassDevsW.restype = w.HANDLE
SetupAPI.SetupDiEnumDeviceInfo.argtypes = w.HANDLE,w.DWORD,w.HANDLE
SetupAPI.SetupDiEnumDeviceInfo.restype = w.BOOLEAN
DIGCF_DEFAULT = 0x00000001
DIGCF_PRESENT = 0x00000002
DIGCF_ALLCLASSES = 0x00000004
DIGCF_PROFILE = 0x00000008
DIGCF_DEVICEINTERFACE = 0x00000010
ClassGuid = None
Enumerator = None
hwndParent = None
Flags = DIGCF_PRESENT | DIGCF_ALLCLASSES
DeviceInfoSet = None
MemberIndex = None
DeviceInfoData = None
class SP_DEVINFO_DATA(ct.Structure):
_fields_ = [
('cbSize',w.DWORD),
('ClassGuid',w.LPVOID),
('DevInst',w.DWORD),
('Reserved',w.ULONG),
]
SP_DEVINFO_DATA = SP_DEVINFO_DATA()
hDevInfo = SetupAPI.SetupDiGetClassDevsW(
ClassGuid,
Enumerator,
hwndParent,
Flags
)
SP_DEVINFO_DATA.cbSize = ct.sizeof(SP_DEVINFO_DATA)
DeviceInfoSet = hex(hDevInfo)
MemberIndex = 1
DeviceInfoData = ct.byref(SP_DEVINFO_DATA)
SetupDiEnumDeviceInfo = SetupAPI.SetupDiEnumDeviceInfo(
DeviceInfoSet,
MemberIndex,
DeviceInfoData
)
print(SetupDiEnumDeviceInfo)
这是一个完整的类型安全示例,用于枚举特定设备类型,在本例中为 USB 主机控制器:
import ctypes as ct
from ctypes import wintypes as w
import uuid
SetupAPI = ct.WinDLL('SetupAPI')
# ULONG_PTR is defined as an unsigned integer of the same size as a pointer on the OS,
# which is ct.ulonglong on 64-bit or ct.ulong on 32-bit. w.WPARAM happens to follow
# that same definition.
ULONG_PTR = w.WPARAM
# For type safety. A ctypes function will only accept HDEVINFO not any old HANDLE.
class HDEVINFO(w.HANDLE):
pass
# A class to initialize and print GUIDs
class GUID(ct.Structure):
_fields_ = (('Data1', ct.c_ulong),
('Data2', ct.c_ushort),
('Data3', ct.c_ushort),
('Data4', ct.c_ubyte * 8))
def __repr__(self):
return f"GUID('{self}')"
def __str__(self):
return (f'{{{self.Data1:08x}-{self.Data2:04x}-{self.Data3:04x}-'
f'{bytes(self.Data4[:2]).hex()}-{bytes(self.Data4[2:]).hex()}}}')
def __init__(self,guid=None):
if guid is not None:
data = uuid.UUID(guid)
self.Data1 = data.time_low
self.Data2 = data.time_mid
self.Data3 = data.time_hi_version
self.Data4[0] = data.clock_seq_hi_variant
self.Data4[1] = data.clock_seq_low
self.Data4[2:] = data.node.to_bytes(6,'big')
PGUID = ct.POINTER(GUID)
# See https://docs.microsoft.com/en-us/windows-hardware/drivers/install/guid-devinterface-usb-host-controller
GUID_DEVINTERFACE_USB_HOST_CONTROLLER = GUID('{3ABF6F2D-71C4-462A-8A92-1E6861E6AF27}')
class SP_DEVINFO_DATA(ct.Structure):
_fields_ = (('cbSize', w.DWORD),
('ClassGuid', GUID),
('DevInst', w.DWORD),
('Reserved', ULONG_PTR))
def __repr__(self):
return f'SP_DEVINFO_DATA(ClassGuid={self.ClassGuid}, DevInst={self.DevInst})'
# Per docs, the cbSize member must be set to the size of this structure.
def __init__(self):
self.cbSize = ct.sizeof(SP_DEVINFO_DATA)
PSP_DEVINFO_DATA = ct.POINTER(SP_DEVINFO_DATA)
SetupAPI.SetupDiGetClassDevsW.argtypes = PGUID, w.PWCHAR, w.HWND, w.DWORD
SetupAPI.SetupDiGetClassDevsW.restype = HDEVINFO
SetupAPI.SetupDiEnumDeviceInfo.argtypes = HDEVINFO, w.DWORD, PSP_DEVINFO_DATA
SetupAPI.SetupDiEnumDeviceInfo.restype = w.BOOL
SetupAPI.SetupDiDestroyDeviceInfoList.argtypes = HDEVINFO,
SetupAPI.SetupDiDestroyDeviceInfoList.restype = w.BOOL
DIGCF_DEFAULT = 0x00000001
DIGCF_PRESENT = 0x00000002
DIGCF_ALLCLASSES = 0x00000004
DIGCF_PROFILE = 0x00000008
DIGCF_DEVICEINTERFACE = 0x00000010
ClassGuid = GUID_DEVINTERFACE_USB_HOST_CONTROLLER
Enumerator = None
hwndParent = None
Flags = DIGCF_DEVICEINTERFACE | DIGCF_PRESENT
devinfo = SP_DEVINFO_DATA()
# Query for the device interface,
# then enumerate them one by one by incrementing a zero-based index
hDevInfo = SetupAPI.SetupDiGetClassDevsW(ClassGuid, Enumerator, hwndParent, Flags)
try:
MemberIndex = 0
while SetupAPI.SetupDiEnumDeviceInfo(hDevInfo, MemberIndex, ct.byref(devinfo)):
print(devinfo)
MemberIndex += 1
finally:
SetupAPI.SetupDiDestroyDeviceInfoList(hDevInfo)
输出:
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=144)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=137)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=17)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=78)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=24)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=98)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=123)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=41)
我的系统有八个 USB 主机控制器,class GUID 匹配:
我想用Ctypes来枚举设备,下面的例子是C++语言我不是很擅长转换,下面的代码是我写的一半
我的问题是如何转换这个
//Enumerate through all devices in Set
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,
&DeviceInfoData);i++)
import ctypes as ct
from ctypes import wintypes as w
SetupAPI = ct.WinDLL('SetupAPI')
SetupAPI.SetupDiGetClassDevsW.argtypes = w.LPVOID,w.PWCHAR,w.HWND,w.DWORD
SetupAPI.SetupDiGetClassDevsW.restype = w.HANDLE
SetupAPI.SetupDiEnumDeviceInfo.argtypes = w.HANDLE,w.DWORD,w.HANDLE
SetupAPI.SetupDiEnumDeviceInfo.restype = w.BOOLEAN
DIGCF_DEFAULT = 0x00000001
DIGCF_PRESENT = 0x00000002
DIGCF_ALLCLASSES = 0x00000004
DIGCF_PROFILE = 0x00000008
DIGCF_DEVICEINTERFACE = 0x00000010
ClassGuid = None
Enumerator = None
hwndParent = None
Flags = DIGCF_PRESENT | DIGCF_ALLCLASSES
DeviceInfoSet = None
MemberIndex = None
DeviceInfoData = None
class SP_DEVINFO_DATA(ct.Structure):
_fields_ = [
('cbSize',w.DWORD),
('ClassGuid',w.LPVOID),
('DevInst',w.DWORD),
('Reserved',w.ULONG),
]
SP_DEVINFO_DATA = SP_DEVINFO_DATA()
hDevInfo = SetupAPI.SetupDiGetClassDevsW(
ClassGuid,
Enumerator,
hwndParent,
Flags
)
SP_DEVINFO_DATA.cbSize = ct.sizeof(SP_DEVINFO_DATA)
DeviceInfoSet = hex(hDevInfo)
MemberIndex = 1
DeviceInfoData = ct.byref(SP_DEVINFO_DATA)
SetupDiEnumDeviceInfo = SetupAPI.SetupDiEnumDeviceInfo(
DeviceInfoSet,
MemberIndex,
DeviceInfoData
)
print(SetupDiEnumDeviceInfo)
这是一个完整的类型安全示例,用于枚举特定设备类型,在本例中为 USB 主机控制器:
import ctypes as ct
from ctypes import wintypes as w
import uuid
SetupAPI = ct.WinDLL('SetupAPI')
# ULONG_PTR is defined as an unsigned integer of the same size as a pointer on the OS,
# which is ct.ulonglong on 64-bit or ct.ulong on 32-bit. w.WPARAM happens to follow
# that same definition.
ULONG_PTR = w.WPARAM
# For type safety. A ctypes function will only accept HDEVINFO not any old HANDLE.
class HDEVINFO(w.HANDLE):
pass
# A class to initialize and print GUIDs
class GUID(ct.Structure):
_fields_ = (('Data1', ct.c_ulong),
('Data2', ct.c_ushort),
('Data3', ct.c_ushort),
('Data4', ct.c_ubyte * 8))
def __repr__(self):
return f"GUID('{self}')"
def __str__(self):
return (f'{{{self.Data1:08x}-{self.Data2:04x}-{self.Data3:04x}-'
f'{bytes(self.Data4[:2]).hex()}-{bytes(self.Data4[2:]).hex()}}}')
def __init__(self,guid=None):
if guid is not None:
data = uuid.UUID(guid)
self.Data1 = data.time_low
self.Data2 = data.time_mid
self.Data3 = data.time_hi_version
self.Data4[0] = data.clock_seq_hi_variant
self.Data4[1] = data.clock_seq_low
self.Data4[2:] = data.node.to_bytes(6,'big')
PGUID = ct.POINTER(GUID)
# See https://docs.microsoft.com/en-us/windows-hardware/drivers/install/guid-devinterface-usb-host-controller
GUID_DEVINTERFACE_USB_HOST_CONTROLLER = GUID('{3ABF6F2D-71C4-462A-8A92-1E6861E6AF27}')
class SP_DEVINFO_DATA(ct.Structure):
_fields_ = (('cbSize', w.DWORD),
('ClassGuid', GUID),
('DevInst', w.DWORD),
('Reserved', ULONG_PTR))
def __repr__(self):
return f'SP_DEVINFO_DATA(ClassGuid={self.ClassGuid}, DevInst={self.DevInst})'
# Per docs, the cbSize member must be set to the size of this structure.
def __init__(self):
self.cbSize = ct.sizeof(SP_DEVINFO_DATA)
PSP_DEVINFO_DATA = ct.POINTER(SP_DEVINFO_DATA)
SetupAPI.SetupDiGetClassDevsW.argtypes = PGUID, w.PWCHAR, w.HWND, w.DWORD
SetupAPI.SetupDiGetClassDevsW.restype = HDEVINFO
SetupAPI.SetupDiEnumDeviceInfo.argtypes = HDEVINFO, w.DWORD, PSP_DEVINFO_DATA
SetupAPI.SetupDiEnumDeviceInfo.restype = w.BOOL
SetupAPI.SetupDiDestroyDeviceInfoList.argtypes = HDEVINFO,
SetupAPI.SetupDiDestroyDeviceInfoList.restype = w.BOOL
DIGCF_DEFAULT = 0x00000001
DIGCF_PRESENT = 0x00000002
DIGCF_ALLCLASSES = 0x00000004
DIGCF_PROFILE = 0x00000008
DIGCF_DEVICEINTERFACE = 0x00000010
ClassGuid = GUID_DEVINTERFACE_USB_HOST_CONTROLLER
Enumerator = None
hwndParent = None
Flags = DIGCF_DEVICEINTERFACE | DIGCF_PRESENT
devinfo = SP_DEVINFO_DATA()
# Query for the device interface,
# then enumerate them one by one by incrementing a zero-based index
hDevInfo = SetupAPI.SetupDiGetClassDevsW(ClassGuid, Enumerator, hwndParent, Flags)
try:
MemberIndex = 0
while SetupAPI.SetupDiEnumDeviceInfo(hDevInfo, MemberIndex, ct.byref(devinfo)):
print(devinfo)
MemberIndex += 1
finally:
SetupAPI.SetupDiDestroyDeviceInfoList(hDevInfo)
输出:
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=144)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=137)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=17)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=78)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=24)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=98)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=123)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=41)
我的系统有八个 USB 主机控制器,class GUID 匹配: