#NEWLINE# def iterate_comports( ) : #NEWLINE# #INDENT# 'Return a generator that yields descriptions for serial ports' #NEWLINE# GUIDs = ( GUID * 8 ) ( ) #NEWLINE# guids_size = DWORD ( ) #NEWLINE# if ( not SetupDiClassGuidsFromName ( Ports , GUIDs , ctypes . sizeof ( GUIDs ) , ctypes . byref ( guids_size ) ) ) : #NEWLINE# #INDENT# raise ctypes . WinError ( ) #NEWLINE# #UNINDENT# for index in range ( guids_size . value ) : #NEWLINE# #INDENT# g_hdi = SetupDiGetClassDevs ( ctypes . byref ( GUIDs [ index ] ) , None , NULL , DIGCF_PRESENT ) #NEWLINE# devinfo = SP_DEVINFO_DATA ( ) #NEWLINE# devinfo . cbSize = ctypes . sizeof ( devinfo ) #NEWLINE# index = 0 #NEWLINE# while SetupDiEnumDeviceInfo ( g_hdi , index , ctypes . byref ( devinfo ) ) : #NEWLINE# #INDENT# index += 1 #NEWLINE# hkey = SetupDiOpenDevRegKey ( g_hdi , ctypes . byref ( devinfo ) , DICS_FLAG_GLOBAL , 0 , DIREG_DEV , KEY_READ ) #NEWLINE# port_name_buffer = byte_buffer ( 250 ) #NEWLINE# port_name_length = ULONG ( ctypes . sizeof ( port_name_buffer ) ) #NEWLINE# RegQueryValueEx ( hkey , PortName , None , None , ctypes . byref ( port_name_buffer ) , ctypes . byref ( port_name_length ) ) #NEWLINE# RegCloseKey ( hkey ) #NEWLINE# if string ( port_name_buffer ) . startswith ( 'LPT' ) : #NEWLINE# #INDENT# continue #NEWLINE# #UNINDENT# szHardwareID = byte_buffer ( 250 ) #NEWLINE# if ( not SetupDiGetDeviceInstanceId ( g_hdi , ctypes . byref ( devinfo ) , ctypes . byref ( szHardwareID ) , ( ctypes . sizeof ( szHardwareID ) - 1 ) , None ) ) : #NEWLINE# #INDENT# if ( not SetupDiGetDeviceRegistryProperty ( g_hdi , ctypes . byref ( devinfo ) , SPDRP_HARDWAREID , None , ctypes . byref ( szHardwareID ) , ( ctypes . sizeof ( szHardwareID ) - 1 ) , None ) ) : #NEWLINE# #INDENT# if ( ctypes . GetLastError ( ) != ERROR_INSUFFICIENT_BUFFER ) : #NEWLINE# #INDENT# raise ctypes . WinError ( ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# szHardwareID_str = string ( szHardwareID ) #NEWLINE# info = list_ports_common . ListPortInfo ( string ( port_name_buffer ) ) #NEWLINE# if szHardwareID_str . startswith ( 'USB' ) : #NEWLINE# #INDENT# m = re . search ( 'VID_([0-9a-f]{4})&PID_([0-9a-f]{4})(\\\\(\\w+))?' , szHardwareID_str , re . I ) #NEWLINE# if m : #NEWLINE# #INDENT# info . vid = int ( m . group ( 1 ) , 16 ) #NEWLINE# info . pid = int ( m . group ( 2 ) , 16 ) #NEWLINE# if m . group ( 4 ) : #NEWLINE# #INDENT# info . serial_number = m . group ( 4 ) #NEWLINE# #UNINDENT# #UNINDENT# loc_path_str = byte_buffer ( 250 ) #NEWLINE# if SetupDiGetDeviceRegistryProperty ( g_hdi , ctypes . byref ( devinfo ) , SPDRP_LOCATION_PATHS , None , ctypes . byref ( loc_path_str ) , ( ctypes . sizeof ( loc_path_str ) - 1 ) , None ) : #NEWLINE# #INDENT# m = re . finditer ( 'USBROOT\\((\\w+)\\)|#USB\\((\\w+)\\)' , string ( loc_path_str ) ) #NEWLINE# location = [ ] #NEWLINE# for g in m : #NEWLINE# #INDENT# if g . group ( 1 ) : #NEWLINE# #INDENT# location . append ( ( '%d' % ( int ( g . group ( 1 ) ) + 1 ) ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( len ( location ) > 1 ) : #NEWLINE# #INDENT# location . append ( '.' ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# location . append ( '-' ) #NEWLINE# #UNINDENT# location . append ( g . group ( 2 ) ) #NEWLINE# #UNINDENT# #UNINDENT# if location : #NEWLINE# #INDENT# info . location = '' . join ( location ) #NEWLINE# #UNINDENT# #UNINDENT# info . hwid = info . usb_info ( ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if szHardwareID_str . startswith ( 'FTDIBUS' ) : #NEWLINE# #INDENT# m = re . search ( 'VID_([0-9a-f]{4})\\+PID_([0-9a-f]{4})(\\+(\\w+))?' , szHardwareID_str , re . I ) #NEWLINE# if m : #NEWLINE# #INDENT# info . vid = int ( m . group ( 1 ) , 16 ) #NEWLINE# info . pid = int ( m . group ( 2 ) , 16 ) #NEWLINE# if m . group ( 4 ) : #NEWLINE# #INDENT# info . serial_number = m . group ( 4 ) #NEWLINE# #UNINDENT# #UNINDENT# info . hwid = info . usb_info ( ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# info . hwid = szHardwareID_str #NEWLINE# #UNINDENT# #UNINDENT# szFriendlyName = byte_buffer ( 250 ) #NEWLINE# if SetupDiGetDeviceRegistryProperty ( g_hdi , ctypes . byref ( devinfo ) , SPDRP_FRIENDLYNAME , None , ctypes . byref ( szFriendlyName ) , ( ctypes . sizeof ( szFriendlyName ) - 1 ) , None ) : #NEWLINE# #INDENT# info . description = string ( szFriendlyName ) #NEWLINE# #UNINDENT# ( yield port_name_buffer ) #NEWLINE# #UNINDENT# SetupDiDestroyDeviceInfoList ( g_hdi )