本文介绍了WinUSB.DLL和Python:特别是WinUsb_Initialize的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在关注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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 00:23