1

ここでWinUsb MSDN HowTo に従っていますが、これまでのところかなりうまく機能しています。ガイドで、WinUsb DLL から WinUsb_Initialize() 関数を呼び出さなければならないところまで来ました。そして、それが私が立ち往生しているところです。これまでの私のコードはこれであり、PyWinUSB の WinAPI.py モジュールから大量の叫び声を上げていることを間違いなく確認できます。PyWinUSB の作成者への無償の感謝とクレジットをここに挿入します。

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) を関数の 2 番目のパラメーターとして渡そうとしましたが、ハンドル値は None のままです。Python と WinUSB.DLL でどれだけのことが行われたかはわかりませんが、誰かが私を正しい方向に向けることができれば、心から感謝します。

前もって感謝します。

4

1 に答える 1

0

c_void_pドキュメントには、それがinである PVOID である PWINUSB_INTERFACE_HANDLE であると記載されctypesているため、これは機能するはずです。

h = ctypes.c_void_p()
winUSB.WinUsb_Initialize(winUSBHandle, ctypes.byref(h))

winUSBHandle外観は有効ですか (0 または -1 または 0xFFFFFFFF ではありません) 。

編集

失敗する場合は、必ず のctypesコピーを使用しGetLastErrorてください。そうしないと、正しくない可能性があります。以下を使用してライブラリ参照を作成します。

winUSB = ctypes.WinDLL('winusb',use_last_error=True)

そして使用:

ctypes.get_last_error()
于 2012-10-17T15:46:53.777 に答える