def __init__(self, path: str, epIn: int, epOut: int, onReceive: Callable[[bytes], None], onReceiveSize: int = 1): """Constructor. @param path: The device path. @param epIn: The endpoint to read data from. @param epOut: The endpoint to write data to. @param onReceive: A callable taking a received input report as its only argument. """ if _isDebug(): log.debug("Opening device %s" % path) readPath = "{path}\\{endpoint}".format(path=path, endpoint=epIn) writePath = "{path}\\{endpoint}".format(path=path, endpoint=epOut) readHandle = CreateFile(readPath, winKernel.GENERIC_READ, 0, None, winKernel.OPEN_EXISTING, FILE_FLAG_OVERLAPPED, None) if readHandle == INVALID_HANDLE_VALUE: if _isDebug(): log.debug("Open read handle failed: %s" % ctypes.WinError()) raise ctypes.WinError() writeHandle = CreateFile(writePath, winKernel.GENERIC_WRITE, 0, None, winKernel.OPEN_EXISTING, FILE_FLAG_OVERLAPPED, None) if writeHandle == INVALID_HANDLE_VALUE: if _isDebug(): log.debug("Open write handle failed: %s" % ctypes.WinError()) raise ctypes.WinError() super(Bulk, self).__init__(readHandle, onReceive, writeFileHandle=writeHandle, onReceiveSize=onReceiveSize)
def __init__(self, path, onReceive): """Constructor. @param path: The device path. This can be retrieved using L{hwPortUtils.listHidDevices}. @type path: unicode @param onReceive: A callable taking a received input report as its only argument. @type onReceive: callable(str) """ if _isDebug(): log.debug("Opening device %s" % path) handle = CreateFile(path, winKernel.GENERIC_READ | winKernel.GENERIC_WRITE, 0, None, winKernel.OPEN_EXISTING, FILE_FLAG_OVERLAPPED, None) if handle == INVALID_HANDLE_VALUE: if _isDebug(): log.debug("Open failed: %s" % ctypes.WinError()) raise ctypes.WinError() pd = ctypes.c_void_p() if not ctypes.windll.hid.HidD_GetPreparsedData(handle, byref(pd)): raise ctypes.WinError() caps = HIDP_CAPS() ctypes.windll.hid.HidP_GetCaps(pd, byref(caps)) ctypes.windll.hid.HidD_FreePreparsedData(pd) if _isDebug(): log.debug("Report byte lengths: input %d, output %d, feature %d" % (caps.InputReportByteLength, caps.OutputReportByteLength, caps.FeatureReportByteLength)) self._featureSize = caps.FeatureReportByteLength # Reading any less than caps.InputReportByteLength is an error. # On Windows 7, writing any less than caps.OutputReportByteLength is also an error. super(Hid, self).__init__(handle, onReceive, onReceiveSize=caps.InputReportByteLength, writeSize=caps.OutputReportByteLength)
def __init__(self, path: str, epIn: int, epOut: int, onReceive: Callable[[bytes], None], onReceiveSize: int = 1, onReadError: Optional[Callable[[int], bool]] = None): """Constructor. @param path: The device path. @param epIn: The endpoint to read data from. @param epOut: The endpoint to write data to. @param onReceive: A callable taking a received input report as its only argument. @param onReadError: An optional callable that handles read errors. It takes an error code and returns True if the error has been handled, allowing the read loop to exit cleanly, or False if an exception should be thrown. """ if _isDebug(): log.debug("Opening device %s" % path) readPath = "{path}\\{endpoint}".format(path=path, endpoint=epIn) writePath = "{path}\\{endpoint}".format(path=path, endpoint=epOut) readHandle = CreateFile(readPath, winKernel.GENERIC_READ, 0, None, winKernel.OPEN_EXISTING, FILE_FLAG_OVERLAPPED, None) if readHandle == INVALID_HANDLE_VALUE: if _isDebug(): log.debug("Open read handle failed: %s" % ctypes.WinError()) raise ctypes.WinError() writeHandle = CreateFile(writePath, winKernel.GENERIC_WRITE, 0, None, winKernel.OPEN_EXISTING, FILE_FLAG_OVERLAPPED, None) if writeHandle == INVALID_HANDLE_VALUE: if _isDebug(): log.debug("Open write handle failed: %s" % ctypes.WinError()) raise ctypes.WinError() super(Bulk, self).__init__(readHandle, onReceive, writeFileHandle=writeHandle, onReceiveSize=onReceiveSize, onReadError=onReadError)
def _getHidInfo(hwId, path): info = {"hardwareID": hwId, "devicePath": path} hwId = hwId.split("\\", 1)[1] if hwId.startswith("VID"): info["provider"] = "usb" info["usbID"] = hwId[:17] # VID_xxxx&PID_xxxx elif hwId.startswith("{00001124-0000-1000-8000-00805f9b34fb}"): info["provider"] = "bluetooth" else: # Unknown provider. info["provider"] = None return info # Fetch additional info about the HID device. from serial.win32 import CreateFile, INVALID_HANDLE_VALUE, FILE_FLAG_OVERLAPPED handle = CreateFile(path, 0, winKernel.FILE_SHARE_READ | winKernel.FILE_SHARE_WRITE, None, winKernel.OPEN_EXISTING, FILE_FLAG_OVERLAPPED, None) if handle == INVALID_HANDLE_VALUE: if _isDebug(): log.debugWarning( "Opening device {dev} to get additional info failed: {exc}". format(dev=path, exc=ctypes.WinError())) return info try: attribs = HIDD_ATTRIBUTES() if ctypes.windll.hid.HidD_GetAttributes(handle, ctypes.byref(attribs)): info["vendorID"] = attribs.VendorID info["productID"] = attribs.ProductID info["versionNumber"] = attribs.VersionNumber else: if _isDebug(): log.debugWarning("HidD_GetAttributes failed") buf = ctypes.create_unicode_buffer(128) bytes = ctypes.sizeof(buf) if ctypes.windll.hid.HidD_GetManufacturerString(handle, buf, bytes): info["manufacturer"] = buf.value if ctypes.windll.hid.HidD_GetProductString(handle, buf, bytes): info["product"] = buf.value pd = ctypes.c_void_p() if ctypes.windll.hid.HidD_GetPreparsedData(handle, ctypes.byref(pd)): try: caps = hidpi.HIDP_CAPS() ctypes.windll.hid.HidP_GetCaps(pd, ctypes.byref(caps)) info['HIDUsagePage'] = caps.UsagePage finally: ctypes.windll.hid.HidD_FreePreparsedData(pd) finally: winKernel.closeHandle(handle) return info
def _getHidInfo(hwId, path): info = {"hardwareID": hwId, "devicePath": path} hwId = hwId.split("\\", 1)[1] if hwId.startswith("VID"): info["provider"] = "usb" info["usbID"] = hwId[:17] # VID_xxxx&PID_xxxx return info if not hwId.startswith( "{00001124-0000-1000-8000-00805f9b34fb}"): # Not Bluetooth # Unknown provider. info["provider"] = None return info info["provider"] = "bluetooth" # Fetch additional info about the HID device. # This is a bit slow, so we only do it for Bluetooth, # as this info might be necessary to identify Bluetooth devices. from serial.win32 import CreateFile, INVALID_HANDLE_VALUE, FILE_FLAG_OVERLAPPED handle = CreateFile(path, 0, winKernel.FILE_SHARE_READ | winKernel.FILE_SHARE_WRITE, None, winKernel.OPEN_EXISTING, FILE_FLAG_OVERLAPPED, None) if handle == INVALID_HANDLE_VALUE: if _isDebug(): log.debug( u"Opening device {dev} to get additional info failed: {exc}". format(dev=path, exc=ctypes.WinError())) return info try: attribs = HIDD_ATTRIBUTES() if ctypes.windll.hid.HidD_GetAttributes(handle, ctypes.byref(attribs)): info["vendorID"] = attribs.VendorID info["productID"] = attribs.ProductID info["versionNumber"] = attribs.VersionNumber buf = ctypes.create_unicode_buffer(128) bytes = ctypes.sizeof(buf) if ctypes.windll.hid.HidD_GetManufacturerString(handle, buf, bytes): info["manufacturer"] = buf.value if ctypes.windll.hid.HidD_GetProductString(handle, buf, bytes): info["product"] = buf.value finally: winKernel.closeHandle(handle) return info
def __init__(self, path: str, onReceive: Callable[[bytes], None], exclusive: bool = True): """Constructor. @param path: The device path. This can be retrieved using L{hwPortUtils.listHidDevices}. @param onReceive: A callable taking a received input report as its only argument. @param exclusive: Whether to block other application's access to this device. """ if _isDebug(): log.debug("Opening device %s" % path) handle = CreateFile( path, winKernel.GENERIC_READ | winKernel.GENERIC_WRITE, 0 if exclusive else winKernel.FILE_SHARE_READ | winKernel.FILE_SHARE_WRITE, None, winKernel.OPEN_EXISTING, FILE_FLAG_OVERLAPPED, None) if handle == INVALID_HANDLE_VALUE: if _isDebug(): log.debug("Open failed: %s" % ctypes.WinError()) raise ctypes.WinError() pd = ctypes.c_void_p() if not hidDll.HidD_GetPreparsedData(handle, byref(pd)): raise ctypes.WinError() self._pd = pd caps = self.caps self.usagePage = caps.UsagePage if _isDebug(): log.debug("usage ID: 0X%X" % caps.Usage) log.debug("usage page: 0X%X" % caps.UsagePage) log.debug("Report byte lengths: input %d, output %d, feature %d" % (caps.InputReportByteLength, caps.OutputReportByteLength, caps.FeatureReportByteLength)) self._featureSize = caps.FeatureReportByteLength self._writeSize = caps.OutputReportByteLength self._readSize = caps.InputReportByteLength # Reading any less than caps.InputReportByteLength is an error. super().__init__(handle, onReceive, onReceiveSize=caps.InputReportByteLength)