Ejemplo n.º 1
0
def comports():
    """This generator scans the device registry for com ports and yields port, desc, hwid"""
    g_hdi = SetupDiGetClassDevs(ctypes.byref(GUID_CLASS_COMPORT), None, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    #~ for i in range(256):
    for dwIndex in range(256):
        did = SP_DEVICE_INTERFACE_DATA()
        did.cbSize = ctypes.sizeof(did)

        if not SetupDiEnumDeviceInterfaces(g_hdi, None, ctypes.byref(GUID_CLASS_COMPORT), dwIndex, ctypes.byref(did)):
            if ctypes.GetLastError() != ERROR_NO_MORE_ITEMS:
                raise ctypes.WinError()
            break

        dwNeeded = DWORD()
        # get the size
        if not SetupDiGetDeviceInterfaceDetail(g_hdi, ctypes.byref(did), None, 0, ctypes.byref(dwNeeded), None):
            # Ignore ERROR_INSUFFICIENT_BUFFER
            if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                raise ctypes.WinError()
        # allocate buffer
        class SP_DEVICE_INTERFACE_DETAIL_DATA_A(ctypes.Structure):
            _fields_ = [
                ('cbSize', DWORD),
                ('DevicePath', CHAR * (dwNeeded.value - ctypes.sizeof(DWORD))),
            ]
            def __str__(self):
                return "DevicePath:%s" % (self.DevicePath,)
        idd = SP_DEVICE_INTERFACE_DETAIL_DATA_A()
        if is_64bit():
            idd.cbSize = 8
        else:
            idd.cbSize = 5
        devinfo = SP_DEVINFO_DATA()
        devinfo.cbSize = ctypes.sizeof(devinfo)
        if not SetupDiGetDeviceInterfaceDetail(g_hdi, ctypes.byref(did), ctypes.byref(idd), dwNeeded, None, ctypes.byref(devinfo)):
            raise ctypes.WinError()

        # hardware ID
        szHardwareID = byte_buffer(250)
        if not SetupDiGetDeviceRegistryProperty(g_hdi, ctypes.byref(devinfo), SPDRP_HARDWAREID, None, ctypes.byref(szHardwareID), ctypes.sizeof(szHardwareID) - 1, None):
            # Ignore ERROR_INSUFFICIENT_BUFFER
            if GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                raise ctypes.WinError()

        # friendly name
        szFriendlyName = byte_buffer(250)
        if SetupDiGetDeviceRegistryProperty(g_hdi, ctypes.byref(devinfo), SPDRP_FRIENDLYNAME, None, ctypes.byref(szFriendlyName), ctypes.sizeof(szFriendlyName) - 1, None):
            # the real com port name has to read differently...
            hkey = SetupDiOpenDevRegKey(g_hdi, ctypes.byref(devinfo), DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ)
            port_name_buffer = byte_buffer(250)
            port_name_length = ULONG(ctypes.sizeof(port_name_buffer))
            RegQueryValueEx(hkey, PortName, None, None, ctypes.byref(port_name_buffer), ctypes.byref(port_name_length))
            RegCloseKey(hkey)
            yield string(port_name_buffer), string(szFriendlyName), string(szHardwareID)

    SetupDiDestroyDeviceInfoList(g_hdi)
Ejemplo n.º 2
0
def comports():
    """This generator scans the device registry for com ports and yields port, desc, hwid"""
    g_hdi = SetupDiGetClassDevs(ctypes.byref(GUID_CLASS_COMPORT), None, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
    #~ for i in range(256):
    for dwIndex in range(256):
        did = SP_DEVICE_INTERFACE_DATA()
        did.cbSize = ctypes.sizeof(did)

        if not SetupDiEnumDeviceInterfaces(g_hdi, None, ctypes.byref(GUID_CLASS_COMPORT), dwIndex, ctypes.byref(did)):
            if ctypes.GetLastError() != ERROR_NO_MORE_ITEMS:
                raise ctypes.WinError()
            break

        dwNeeded = DWORD()
        # get the size
        if not SetupDiGetDeviceInterfaceDetail(g_hdi, ctypes.byref(did), None, 0, ctypes.byref(dwNeeded), None):
            # Ignore ERROR_INSUFFICIENT_BUFFER
            if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                raise ctypes.WinError()
        # allocate buffer
        class SP_DEVICE_INTERFACE_DETAIL_DATA_A(ctypes.Structure):
            _fields_ = [
                ('cbSize', DWORD),
                ('DevicePath', CHAR*(dwNeeded.value - ctypes.sizeof(DWORD))),
            ]
            def __str__(self):
                return "DevicePath:%s" % (self.DevicePath,)
        idd = SP_DEVICE_INTERFACE_DETAIL_DATA_A()
        if is_64bit():
            idd.cbSize = 8
        else:
            idd.cbSize = 5
        devinfo = SP_DEVINFO_DATA()
        devinfo.cbSize = ctypes.sizeof(devinfo)
        if not SetupDiGetDeviceInterfaceDetail(g_hdi, ctypes.byref(did), ctypes.byref(idd), dwNeeded, None, ctypes.byref(devinfo)):
            raise ctypes.WinError()

        # hardware ID
        szHardwareID = byte_buffer(250)
        if not SetupDiGetDeviceRegistryProperty(g_hdi, ctypes.byref(devinfo), SPDRP_HARDWAREID, None, ctypes.byref(szHardwareID), ctypes.sizeof(szHardwareID) - 1, None):
            # Ignore ERROR_INSUFFICIENT_BUFFER
            if GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                raise ctypes.WinError()

        # friendly name
        szFriendlyName = byte_buffer(250)
        if not SetupDiGetDeviceRegistryProperty(g_hdi, ctypes.byref(devinfo), SPDRP_FRIENDLYNAME, None, ctypes.byref(szFriendlyName), ctypes.sizeof(szFriendlyName) - 1, None):
            # Ignore ERROR_INSUFFICIENT_BUFFER
            if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                #~ raise IOError("failed to get details for %s (%s)" % (devinfo, szHardwareID.value))
                port_name = None
        else:
            # the real com port name has to read differently...
            hkey = SetupDiOpenDevRegKey(g_hdi, ctypes.byref(devinfo), DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ)
            port_name_buffer = byte_buffer(250)
            port_name_length = ULONG(ctypes.sizeof(port_name_buffer))
            RegQueryValueEx(hkey, PortName, None, None, ctypes.byref(port_name_buffer), ctypes.byref(port_name_length))
            RegCloseKey(hkey)
            yield string(port_name_buffer), string(szFriendlyName), string(szHardwareID)

    SetupDiDestroyDeviceInfoList(g_hdi)
Ejemplo n.º 3
0
def _yeiComPorts():
    """ This generator scans the device registry for com ports and yields port,
        desc, hw_id
    """
    
    GUID_list = [GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR, GUID_DEVINTERFACE_COMPORT]
    ports_yielded = []
    bt_device_list = None
    
    for device_GUID in GUID_list:
        g_hdi = SetupDiGetClassDevs(ctypes.byref(device_GUID), None, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE)
        for dw_index in range(256):
            friendly_name_string = ""
            did = SP_DEVICE_INTERFACE_DATA()
            did.cbSize = ctypes.sizeof(did)
            
            if not SetupDiEnumDeviceInterfaces(g_hdi, None, ctypes.byref(device_GUID), dw_index, ctypes.byref(did)):
                if ctypes.GetLastError() != ERROR_NO_MORE_ITEMS:
                    if '-d' in sys.argv:
                        raise ctypes.WinError()
                break
            
            dw_needed = DWORD()
            # Get the size
            if not SetupDiGetDeviceInterfaceDetail(g_hdi, ctypes.byref(did), None, 0, ctypes.byref(dw_needed), None):
                # Ignore ERROR_INSUFFICIENT_BUFFER
                if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                    if '-d' in sys.argv:
                        raise ctypes.WinError()
            
            # Allocate buffer
            class SP_DEVICE_INTERFACE_DETAIL_DATA_A(ctypes.Structure):
                _fields_ = [
                    ('cbSize', DWORD),
                    ('DevicePath', CHAR * (dw_needed.value - ctypes.sizeof(DWORD))),
                ]
                
                def __str__(self):
                    return "DevicePath: %s" % self.DevicePath
            
            idd = SP_DEVICE_INTERFACE_DETAIL_DATA_A()
            if is_64bit():
                idd.cbSize = 8
            else:
                idd.cbSize = 5
            
            dev_info = SP_DEVINFO_DATA()
            dev_info.cbSize = ctypes.sizeof(dev_info)
            if not SetupDiGetDeviceInterfaceDetail(g_hdi, ctypes.byref(did), ctypes.byref(idd), dw_needed, None, ctypes.byref(dev_info)):
                if '-d' in sys.argv:
                    raise ctypes.WinError()
            
            # hardware ID
            sz_hardware_id = _byteBuffer(1024)
            if not SetupDiGetDeviceRegistryProperty(g_hdi, ctypes.byref(dev_info), SPDRP_HARDWAREID, None, ctypes.byref(sz_hardware_id), ctypes.sizeof(sz_hardware_id) - 1, None):
                # Ignore ERROR_INSUFFICIENT_BUFFER
                if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                    if '-d' in sys.argv:
                        raise ctypes.WinError()
            
            #Build VID/PID string
            vid_pid_string = ""
            hw_string = _string(sz_hardware_id)
            hw_string = hw_string.upper()
            vid_idx = hw_string.find("VID_")
            pid_idx = hw_string.find("PID_")
            if vid_idx != -1 and pid_idx != -1:
                vid_end = hw_string.find("&", vid_idx + 1)
                vid = hw_string[vid_idx:vid_end]
                pid_end = hw_string.find("&", pid_idx + 1)
                pid = hw_string[pid_idx:pid_end]
                vid_pid_string = vid + "&" + pid
            
            enum_name_buff = _byteBuffer(1024)
            if SetupDiGetDeviceRegistryProperty(g_hdi, ctypes.byref(dev_info), SPDRP_ENUMERATOR_NAME, None, ctypes.byref(enum_name_buff), ctypes.sizeof(enum_name_buff) - 1, None):
                if _string(enum_name_buff).upper() == "BTHENUM":
                    # This is a bluetooth enumerator, we should do further
                    # investigation
                    if bt_device_list is None:
                        bt_device_list = _getBluetoothDevices()
                    
                    device_path_str = idd.DevicePath
                    if type(device_path_str) is bytes:
                        device_path_str = bytes.decode(device_path_str)
                    start_idx = device_path_str.rfind("&") + 1
                    end_idx = start_idx + 12
                    bt_addr_string = device_path_str[start_idx:end_idx]
                    bt_address = _stringToBluetoothAddress(bt_addr_string)
                    if bt_address == _stringToBluetoothAddress("0"):
                        continue
                    connected_dev = None
                    for bt_dev in bt_device_list:
                        if bt_dev.Address == bt_address:
                            connected_dev = bt_dev
                            break
                    if connected_dev is not None:
                        if (str(connected_dev.szName).find("YEI_3SpaceBT") != -1):
                            # The device is a 3-Space Sensor!
                            vid_pid_string = "VID_2476&PID_1060"
                            friendly_name_string = "3 Space Bluetooth over Bluetooth link "
            
            sz_friendly_name = _byteBuffer(1024)
            if not SetupDiGetDeviceRegistryProperty(g_hdi, ctypes.byref(dev_info), SPDRP_FRIENDLYNAME, None, ctypes.byref(sz_friendly_name), ctypes.sizeof(sz_friendly_name) - 1, None):
                # Ignore ERROR_INSUFFICIENT_BUFFER
                if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                    if '-d' in sys.argv:
                        raise IOError("Failed to get details for %s (%s)" % (dev_info, sz_hardware_id.value))
                    port_name = None
            else:
                # The real com port name has to read differently...
                h_key = SetupDiOpenDevRegKey(g_hdi, ctypes.byref(dev_info), DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ)
                port_name_buffer = _byteBuffer(1024)
                port_name_length = ULONG(ctypes.sizeof(port_name_buffer))
                RegQueryValueEx(h_key, PortName, None, None, ctypes.byref(port_name_buffer), ctypes.byref(port_name_length))
                RegCloseKey(h_key)
                
                # We either use the generated friendly name or our overridden
                # one, with preference to the overridden one.
                if friendly_name_string == "":
                    friendly_name_string = _string(sz_friendly_name)
                else:
                    friendly_name_string += "(" + _string(port_name_buffer) + ")"
                if _string(port_name_buffer) not in ports_yielded:
                    ports_yielded.append(_string(port_name_buffer))
                    yield (_string(port_name_buffer), friendly_name_string, _string(sz_hardware_id), vid_pid_string)
        SetupDiDestroyDeviceInfoList(g_hdi)
Ejemplo n.º 4
0
def _yeiComPorts():
    """ This generator scans the device registry for com ports and yields port,
        desc, hw_id
    """

    GUID_list = [
        GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR, GUID_DEVINTERFACE_COMPORT
    ]
    ports_yielded = []
    bt_device_list = None

    for device_GUID in GUID_list:
        g_hdi = SetupDiGetClassDevs(ctypes.byref(device_GUID), None, NULL,
                                    DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)
        for dw_index in range(256):
            friendly_name_string = ""
            did = SP_DEVICE_INTERFACE_DATA()
            did.cbSize = ctypes.sizeof(did)

            if not SetupDiEnumDeviceInterfaces(
                    g_hdi, None, ctypes.byref(device_GUID), dw_index,
                    ctypes.byref(did)):
                if ctypes.GetLastError() != ERROR_NO_MORE_ITEMS:
                    if '-d' in sys.argv:
                        raise ctypes.WinError()
                break

            dw_needed = DWORD()
            # Get the size
            if not SetupDiGetDeviceInterfaceDetail(
                    g_hdi, ctypes.byref(did), None, 0, ctypes.byref(dw_needed),
                    None):
                # Ignore ERROR_INSUFFICIENT_BUFFER
                if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                    if '-d' in sys.argv:
                        raise ctypes.WinError()

            # Allocate buffer
            class SP_DEVICE_INTERFACE_DETAIL_DATA_A(ctypes.Structure):
                _fields_ = [
                    ('cbSize', DWORD),
                    ('DevicePath',
                     CHAR * (dw_needed.value - ctypes.sizeof(DWORD))),
                ]

                def __str__(self):
                    return "DevicePath: %s" % self.DevicePath

            idd = SP_DEVICE_INTERFACE_DETAIL_DATA_A()
            if is_64bit():
                idd.cbSize = 8
            else:
                idd.cbSize = 5

            dev_info = SP_DEVINFO_DATA()
            dev_info.cbSize = ctypes.sizeof(dev_info)
            if not SetupDiGetDeviceInterfaceDetail(
                    g_hdi, ctypes.byref(did), ctypes.byref(idd), dw_needed,
                    None, ctypes.byref(dev_info)):
                if '-d' in sys.argv:
                    raise ctypes.WinError()

            # hardware ID
            sz_hardware_id = _byteBuffer(1024)
            if not SetupDiGetDeviceRegistryProperty(
                    g_hdi, ctypes.byref(dev_info), SPDRP_HARDWAREID, None,
                    ctypes.byref(sz_hardware_id),
                    ctypes.sizeof(sz_hardware_id) - 1, None):
                # Ignore ERROR_INSUFFICIENT_BUFFER
                if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                    if '-d' in sys.argv:
                        raise ctypes.WinError()

            #Build VID/PID string
            vid_pid_string = ""
            hw_string = _string(sz_hardware_id)
            hw_string = hw_string.upper()
            vid_idx = hw_string.find("VID_")
            pid_idx = hw_string.find("PID_")
            if vid_idx != -1 and pid_idx != -1:
                vid_end = hw_string.find("&", vid_idx + 1)
                vid = hw_string[vid_idx:vid_end]
                pid_end = hw_string.find("&", pid_idx + 1)
                pid = hw_string[pid_idx:pid_end]
                vid_pid_string = vid + "&" + pid

            enum_name_buff = _byteBuffer(1024)
            if SetupDiGetDeviceRegistryProperty(
                    g_hdi, ctypes.byref(dev_info), SPDRP_ENUMERATOR_NAME, None,
                    ctypes.byref(enum_name_buff),
                    ctypes.sizeof(enum_name_buff) - 1, None):
                if _string(enum_name_buff).upper() == "BTHENUM":
                    # This is a bluetooth enumerator, we should do further
                    # investigation
                    if bt_device_list is None:
                        bt_device_list = _getBluetoothDevices()

                    device_path_str = idd.DevicePath
                    if type(device_path_str) is bytes:
                        device_path_str = bytes.decode(device_path_str)
                    start_idx = device_path_str.rfind("&") + 1
                    end_idx = start_idx + 12
                    bt_addr_string = device_path_str[start_idx:end_idx]
                    bt_address = _stringToBluetoothAddress(bt_addr_string)
                    if bt_address == _stringToBluetoothAddress("0"):
                        continue
                    connected_dev = None
                    for bt_dev in bt_device_list:
                        if bt_dev.Address == bt_address:
                            connected_dev = bt_dev
                            break
                    if connected_dev is not None:
                        if (str(connected_dev.szName).find("YEI_3SpaceBT") !=
                                -1):
                            # The device is a 3-Space Sensor!
                            vid_pid_string = "VID_2476&PID_1060"
                            friendly_name_string = "3 Space Bluetooth over Bluetooth link "

            sz_friendly_name = _byteBuffer(1024)
            if not SetupDiGetDeviceRegistryProperty(
                    g_hdi, ctypes.byref(dev_info), SPDRP_FRIENDLYNAME, None,
                    ctypes.byref(sz_friendly_name),
                    ctypes.sizeof(sz_friendly_name) - 1, None):
                # Ignore ERROR_INSUFFICIENT_BUFFER
                if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                    if '-d' in sys.argv:
                        raise IOError("Failed to get details for %s (%s)" %
                                      (dev_info, sz_hardware_id.value))
                    port_name = None
            else:
                # The real com port name has to read differently...
                h_key = SetupDiOpenDevRegKey(g_hdi, ctypes.byref(dev_info),
                                             DICS_FLAG_GLOBAL, 0, DIREG_DEV,
                                             KEY_READ)
                port_name_buffer = _byteBuffer(1024)
                port_name_length = ULONG(ctypes.sizeof(port_name_buffer))
                RegQueryValueEx(h_key, PortName, None, None,
                                ctypes.byref(port_name_buffer),
                                ctypes.byref(port_name_length))
                RegCloseKey(h_key)

                # We either use the generated friendly name or our overridden
                # one, with preference to the overridden one.
                if friendly_name_string == "":
                    friendly_name_string = _string(sz_friendly_name)
                else:
                    friendly_name_string += "(" + _string(
                        port_name_buffer) + ")"
                if _string(port_name_buffer) not in ports_yielded:
                    ports_yielded.append(_string(port_name_buffer))
                    yield (_string(port_name_buffer), friendly_name_string,
                           _string(sz_hardware_id), vid_pid_string)
        SetupDiDestroyDeviceInfoList(g_hdi)