问题描述
我一直在关注WinUsb MSDN HowTo ,到目前为止效果很好。
在指南中,我必须从WinUsb DLL调用WinUsb_Initialize()函数。那就是我被困住的地方。到目前为止,我的代码是这样,您无疑会确定我从PyWinUSB的WinAPI.py模块中尖叫了很多。在表示感谢,并感谢PyWinUSB的创建者。
I've been following the WinUsb MSDN HowTo here and so far it's worked pretty well.I've made it to the point in the guide where I have to call the WinUsb_Initialize() function from the WinUsb DLL. And that's where I'm stuck. My code so far is this, and you will doubtlessly ascertain that I've ripped a great deal of it screaming from the WinAPI.py module of PyWinUSB. Insert gratuitous thanks and giving credit to the creator of PyWinUSB here.
import ctypes
import platform
from ctypes import byref, POINTER, Structure, sizeof, c_ulong
from ctypes.wintypes import DWORD, WORD, BYTE, HANDLE, LPCWSTR, ULONG, WCHAR, \
BOOL
TCHAR = WCHAR
winUSB = ctypes.windll.winusb
winHID = ctypes.windll.hid
kernel32 = ctypes.windll.kernel32
setupAPI = ctypes.windll.setupapi
GENERIC_READ = (-2147483648)
GENERIC_WRITE = (1073741824)
FILE_SHARE_READ = 1
FILE_SHARE_WRITE = 2
OPEN_EXISTING = 3
FILE_FLAG_OVERLAPPED = 1073741824
if platform.architecture()[0].startswith('64'):
WIN_PACK = 8
else:
WIN_PACK = 1
class GUID(ctypes.Structure):
"""GUID Windows OS Structure"""
_pack_ = 1
_fields_ = [("data1", DWORD),
("data2", WORD),
("data3", WORD),
("data4", BYTE * 8)]
def __init__(self, data1 = None, data2 = None, data3 = None, data4 = None):
if data1 is not None:
self.data1 = data1
if data2 is not None:
self.data2 = data2
if data3 is not None:
self.data3 = data3
if data4 is not None:
self.data4 = data4
class SP_DEVICE_INTERFACE_DATA(Structure):
"""
typedef struct _SP_DEVICE_INTERFACE_DATA {
DWORD cbSize;
GUID InterfaceClassGuid;
DWORD Flags;
ULONG_PTR Reserved;
} SP_DEVICE_INTERFACE_DATA, *PSP_DEVICE_INTERFACE_DATA
"""
_pack_ = WIN_PACK
_fields_ = [("cb_size", DWORD),
("interface_class_guid", GUID),
("flags", DWORD),
("reserved", POINTER(ULONG))]
def __init__(self):
self.cb_size = sizeof(SP_DEVICE_INTERFACE_DATA)
class SP_DEVICE_INTERFACE_DETAIL_DATA(Structure):
"""
typedef struct _SP_DEVICE_INTERFACE_DETAIL_DATA {
DWORD cbSize;
TCHAR DevicePath[ANYSIZE_ARRAY];
} SP_DEVICE_INTERFACE_DETAIL_DATA, *PSP_DEVICE_INTERFACE_DETAIL_DATA;
"""
_pack_ = WIN_PACK
_fields_ = [("cb_size", DWORD),
("device_path", TCHAR * 1)] #device_path[1]
def __init__(self):
self.cb_size = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)
def get_string(self):
"""Retreive stored string"""
return ctypes.wstring_at(byref(self, sizeof(DWORD)))
class SP_DEVINFO_DATA(Structure):
"""
typedef struct _SP_DEVINFO_DATA {
DWORD cbSize;
GUID ClassGuid;
DWORD DevInst;
ULONG_PTR Reserved;
} SP_DEVINFO_DATA, *PSP_DEVINFO_DATA;
"""
_pack_ = WIN_PACK
_fields_ = [("cb_size", DWORD),
("class_guid", GUID),
("dev_inst", DWORD),
("reserved", POINTER(ULONG))]
def __init__(self):
self.cb_size = sizeof(SP_DEVINFO_DATA)
class DIGCF:
"""
Flags controlling what is included in the device information set
built by SetupDiGetClassDevs
"""
DEFAULT = 0x00000001
PRESENT = 0x00000002
ALLCLASSES = 0x00000004
PROFILE = 0x00000008
DEVICEINTERFACE = 0x00000010
def GetHidGuid():
"Get system-defined GUID for HIDClass devices"
hid_guid = GUID()
winHID.HidD_GetHidGuid(byref(hid_guid))
return hid_guid
SetupDiGetClassDevs = setupAPI.SetupDiGetClassDevsW
SetupDiGetClassDevs.restype = HANDLE
SetupDiGetClassDevs.argtypes = [
# __in_opt const GUID *ClassGuid,
# __in_opt PCTSTR Enumerator,
# __in_opt HWND hwndParent,
# __in DWORD Flags,
POINTER(GUID),
LPCWSTR,
HANDLE,
DWORD]
SetupDiGetDeviceInterfaceDetail = setupAPI.SetupDiGetDeviceInterfaceDetailW
SetupDiGetDeviceInterfaceDetail.restype = BOOL
SetupDiGetDeviceInterfaceDetail.argtypes = [
# __in HDEVINFO DeviceInfoSet,
# __in PSP_DEVICE_INTERFACE_DATA DeviceIn,
# __out_opt PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData,
# __in DWORD DeviceInterfaceDetailDataSize,
# __out_opt PDWORD RequiredSize
# __out_opt PSP_DEVINFO_DATA DeviceInfoData
HANDLE,
POINTER(SP_DEVICE_INTERFACE_DATA),
POINTER(SP_DEVICE_INTERFACE_DETAIL_DATA),
DWORD,
POINTER(DWORD),
POINTER(SP_DEVINFO_DATA)]
devGuid = GUID(0x2518E22E, 0x0F35, 0x11E2, (BYTE * 8)(0xB1, 0xD5, 0x6C, 0xF0,
0x49, 0x73, 0x78, 0x72))
classGuid = GetHidGuid()
#GUID(0x745A17A0, 0x74D3, 0x11D0, (BYTE * 8)(0xB6, 0xFE, 0x00, 0xA0,
# 0xC9, 0x0F, 0x57, 0xDA))
derp = SetupDiGetClassDevs(
byref(classGuid), None, None,
(DIGCF.PRESENT | DIGCF.DEVICEINTERFACE))
def stepDevices(herp, index = 0):
devInterfaceData = SP_DEVICE_INTERFACE_DATA()
if setupAPI.SetupDiEnumDeviceInterfaces(
herp, None, byref(classGuid), index, byref(devInterfaceData)):
yield devInterfaceData
del devInterfaceData
else:
print(kernel32.GetLastError())
def enumDevices(herp):
index = 0
devInterfaceData = SP_DEVICE_INTERFACE_DATA()
while setupAPI.SetupDiEnumDeviceInterfaces(
herp, None, byref(classGuid), index, byref(devInterfaceData)):
print(kernel32.GetLastError())
yield devInterfaceData
index += 1
del devInterfaceData
def getDetail(herp, devData, devInfo = None):
reqSize = c_ulong(0)
devDetail = SP_DEVICE_INTERFACE_DETAIL_DATA()
SetupDiGetDeviceInterfaceDetail(
herp, byref(devData), None, 0, byref(reqSize), None)
ctypes.resize(devDetail, reqSize.value)
SetupDiGetDeviceInterfaceDetail(
herp, byref(devData), byref(devDetail),
reqSize, None, byref(devInfo))
return devDetail.get_string()
dev = stepDevices(derp).next()
devInfo = SP_DEVINFO_DATA()
devString = getDetail(derp, dev, devInfo)
winUSBHandle = kernel32.CreateFileW(
devString, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, None, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, None)
#winUSB.WinUsb_Initialize(winUSBHandle, <what goes here?>)
我尝试创建一个简单的句柄并将byref(handle)作为第二个参数传递给函数,但句柄值保持为None。
我不知道Python和WinUSB.DLL做了多少工作,但如果有人能指出正确的方向,我将不胜感激。
I've tried creating a simple handle and passing that byref(handle) as the second parameter to the function, but the handle value stays as None.I don't know how much has been done with Python and WinUSB.DLL but if anyone can point me in the correct direction I'd be sincerely grateful.
提前谢谢。
推荐答案
文档说它是PWINUSB_INTERFACE_HANDLE,它是PVOID,它是 c_void_p
在 ctypes
中,因此此应该应该起作用:
The documentation says it is a PWINUSB_INTERFACE_HANDLE, which is a PVOID, which is a c_void_p
in ctypes
, so this should work:
h = ctypes.c_void_p()
winUSB.WinUsb_Initialize(winUSBHandle, ctypes.byref(h))
winUSBHandle
看起来有效吗(不是0或-1或0xFFFFFFFF)?
Does the winUSBHandle
look valid (not 0 or -1 or 0xFFFFFFFF)?
编辑
如果失败,请确保使用 ctypes
GetLastError
的副本,否则可能不正确。通过以下方式使用库引用:
If it is failing, make sure to use the ctypes
copy of GetLastError
or it may be incorrect. Make the library references with:
winUSB = ctypes.WinDLL('winusb',use_last_error=True)
并使用:
ctypes.get_last_error()
这篇关于WinUSB.DLL和Python:特别是WinUsb_Initialize的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!