<s> import os , sys <EOL> import win32api as Api <EOL> import win32file as File <EOL> import win32net as Net <EOL> try : <EOL> from win32con import * <EOL> except ImportError : <EOL> DRIVE_UNKNOWN = <NUM_LIT:0> <EOL> DRIVE_NO_ROOT_DIR = <NUM_LIT:1> <EOL> DRIVE_REMOVABLE = <NUM_LIT:2> <EOL> DRIVE_FIXED = <NUM_LIT:3> <EOL> DRIVE_REMOTE = <NUM_LIT:4> <EOL> DRIVE_CDROM = <NUM_LIT:5> <EOL> DRIVE_RAMDISK = <NUM_LIT:6> <EOL> MAX_PATH = <NUM_LIT> <EOL> SEM_FAILCRITICALERRORS = <NUM_LIT:1> <EOL> from ctypes import * <EOL> kernel32 = windll . kernel32 <EOL> kernel32 . SetErrorMode ( SEM_FAILCRITICALERRORS ) <EOL> drivetypes = { <EOL> DRIVE_UNKNOWN : "<STR_LIT>" , <EOL> DRIVE_NO_ROOT_DIR : "<STR_LIT>" , <EOL> DRIVE_REMOVABLE : "<STR_LIT>" , <EOL> DRIVE_FIXED : "<STR_LIT>" , <EOL> DRIVE_REMOTE : "<STR_LIT>" , <EOL> DRIVE_CDROM : "<STR_LIT>" , <EOL> DRIVE_RAMDISK : "<STR_LIT>" , <EOL> - <NUM_LIT:1> : "<STR_LIT>" , <EOL> - <NUM_LIT:2> : "<STR_LIT>" , <EOL> } <EOL> def prettySize ( bytes ) : <EOL> if bytes is None : return "<STR_LIT:->" <EOL> size = float ( bytes ) <EOL> l = - <NUM_LIT:1> <EOL> while size >= <NUM_LIT:1000> : <EOL> size /= <NUM_LIT> <EOL> l += <NUM_LIT:1> <EOL> return "<STR_LIT>" % ( size , "<STR_LIT>" [ l ] if l >= <NUM_LIT:0> else "<STR_LIT>" ) <EOL> def EnumVolumes ( ) : <EOL> buf = create_unicode_buffer ( <NUM_LIT> ) <EOL> volumes = [ ] <EOL> h = kernel32 . FindFirstVolumeW ( buf , sizeof ( buf ) ) <EOL> if h : <EOL> yield buf . value <EOL> while kernel32 . FindNextVolumeW ( h , buf , sizeof ( buf ) ) : <EOL> yield buf . value <EOL> kernel32 . FindVolumeClose ( h ) <EOL> def wszarray_to_list ( array ) : <EOL> output = [ ] <EOL> offset = <NUM_LIT:0> <EOL> while offset < sizeof ( array ) : <EOL> sz = wstring_at ( addressof ( array ) + offset * <NUM_LIT:2> ) <EOL> if sz : <EOL> output . append ( sz ) <EOL> offset += len ( sz ) + <NUM_LIT:1> <EOL> else : <EOL> break <EOL> return output <EOL> def GetPathNamesForVolume ( volume ) : <EOL> buf = create_unicode_buffer ( <NUM_LIT> ) <EOL> length = c_int32 ( ) <EOL> if kernel32 . GetVolumePathNamesForVolumeNameW ( c_wchar_p ( volume ) , buf , sizeof ( buf ) , byref ( length ) ) : <EOL> return wszarray_to_list ( buf ) <EOL> else : <EOL> raise OSError <EOL> def QueryDosDevice ( dev ) : <EOL> dev = dev [ : dev . index ( "<STR_LIT::>" ) + <NUM_LIT:1> ] <EOL> target = File . QueryDosDevice ( dev ) <EOL> return target . split ( "<STR_LIT>" ) [ <NUM_LIT:0> ] <EOL> def GetMountVolume ( path ) : <EOL> volume_name = create_unicode_buffer ( <NUM_LIT:64> ) <EOL> res = kernel32 . GetVolumeNameForVolumeMountPointW ( <EOL> c_wchar_p ( path ) , volume_name , sizeof ( volume_name ) ) <EOL> if res : <EOL> return volume_name . value <EOL> def GetCanonicalName ( disk ) : <EOL> target = QueryDosDevice ( disk ) <EOL> if target is None : <EOL> print ( "<STR_LIT>" % ( letter , target ) ) <EOL> return None <EOL> elif target . startswith ( "<STR_LIT>" ) : <EOL> if target . startswith ( "<STR_LIT>" ) : <EOL> target = target [ len ( "<STR_LIT>" ) : ] <EOL> return target , False <EOL> elif target . startswith ( "<STR_LIT>" ) : <EOL> return Net . NetUseGetInfo ( None , disk [ <NUM_LIT:0> ] + "<STR_LIT::>" ) [ "<STR_LIT>" ] , True <EOL> elif target . startswith ( "<STR_LIT>" ) : <EOL> return target [ <NUM_LIT:4> : ] , True <EOL> else : <EOL> return GetMountVolume ( letter ) , False <EOL> def GetDriveType ( root ) : <EOL> return kernel32 . GetDriveTypeW ( c_wchar_p ( root ) ) <EOL> def GetVolumeInformation ( root ) : <EOL> volume_name = create_unicode_buffer ( MAX_PATH + <NUM_LIT:1> ) <EOL> serial_number = c_int32 ( ) <EOL> max_component_length = c_int32 ( ) <EOL> flags = c_int32 ( ) <EOL> fs_name = create_unicode_buffer ( MAX_PATH + <NUM_LIT:1> ) <EOL> if kernel32 . GetVolumeInformationW ( c_wchar_p ( root ) , volume_name , <EOL> sizeof ( volume_name ) , byref ( serial_number ) , byref ( max_component_length ) , <EOL> byref ( flags ) , fs_name , sizeof ( fs_name ) ) : <EOL> return ( volume_name . value , serial_number . value , byref ( max_component_length ) , <EOL> flags . value , fs_name . value ) <EOL> else : raise OSError <EOL> def IsVolumeReady ( root ) : <EOL> try : GetVolumeInformation ( root ) <EOL> except : return False <EOL> else : return True <EOL> def GetLogicalDriveStrings ( ) : <EOL> return Api . GetLogicalDriveStrings ( ) . split ( "<STR_LIT>" ) [ : - <NUM_LIT:1> ] <EOL> LINE_FORMAT = "<STR_LIT>" <EOL> header = LINE_FORMAT % ( "<STR_LIT:path>" , "<STR_LIT:label>" , "<STR_LIT:type>" , "<STR_LIT:size>" , "<STR_LIT>" , "<STR_LIT>" ) <EOL> print ( header ) <EOL> print ( "<STR_LIT:->" * len ( header ) ) <EOL> Letters = GetLogicalDriveStrings ( ) <EOL> Letters . sort ( ) <EOL> Drives = { } <EOL> Maps = { } <EOL> Volumes = { } <EOL> Printed = [ ] <EOL> Volumes = { guid : { "<STR_LIT>" : GetPathNamesForVolume ( guid ) , <EOL> "<STR_LIT>" : IsVolumeReady ( guid ) } for guid in EnumVolumes ( ) } <EOL> DosDevices = { } <EOL> for letter in Letters : <EOL> target = DosDevices [ letter ] = QueryDosDevice ( letter ) <EOL> if target is None : <EOL> print ( "<STR_LIT>" % ( letter , target ) ) <EOL> elif target . startswith ( "<STR_LIT>" ) : <EOL> if target . startswith ( "<STR_LIT>" ) : <EOL> target = target [ len ( "<STR_LIT>" ) : ] <EOL> Maps [ letter ] = target <EOL> elif target . startswith ( "<STR_LIT>" ) : <EOL> Maps [ letter ] = GetCanonicalName ( letter ) <EOL> Drives [ letter ] = Maps [ letter ] <EOL> pass <EOL> elif target . startswith ( "<STR_LIT>" ) : <EOL> pass <EOL> else : <EOL> Drives [ letter ] = GetMountVolume ( letter ) <EOL> for letter in Letters : <EOL> isMapped = letter in Maps <EOL> if isMapped : <EOL> target = Maps [ letter ] <EOL> type = - <NUM_LIT:1> <EOL> free , total , diskfree = Api . GetDiskFreeSpaceEx ( letter ) <EOL> used = <NUM_LIT:100> - ( <NUM_LIT:100> * diskfree / total ) <EOL> else : <EOL> root = Drives [ letter ] <EOL> if root in Printed : <EOL> continue <EOL> Printed . append ( root ) <EOL> pathnames = Volumes [ root ] [ "<STR_LIT>" ] [ : ] <EOL> isReady = Volumes [ root ] [ "<STR_LIT>" ] <EOL> if isReady : <EOL> type = GetDriveType ( root ) <EOL> info = GetVolumeInformation ( root ) <EOL> label , filesystem = info [ <NUM_LIT:0> ] , info [ <NUM_LIT:4> ] <EOL> else : <EOL> type , label , filesystem = - <NUM_LIT:2> , "<STR_LIT>" , None <EOL> if isReady and type != DRIVE_REMOTE : <EOL> free , total , diskfree = Api . GetDiskFreeSpaceEx ( root ) <EOL> used = <NUM_LIT:100> - ( <NUM_LIT:100> * diskfree / total ) <EOL> else : <EOL> free , total , diskfree , used = None , None , None , None <EOL> if filesystem : <EOL> strtype = "<STR_LIT>" % ( drivetypes [ type ] , filesystem ) <EOL> else : <EOL> strtype = drivetypes [ type ] <EOL> print ( LINE_FORMAT % ( <EOL> letter , <EOL> label or "<STR_LIT>" , <EOL> strtype , <EOL> prettySize ( total ) , <EOL> prettySize ( diskfree ) , <EOL> "<STR_LIT>" % used if used is not None else "<STR_LIT:->" , <EOL> ) ) <EOL> if isMapped : <EOL> print ( "<STR_LIT>" % ( "<STR_LIT>" , target ) ) <EOL> else : <EOL> pathnames . remove ( letter ) <EOL> for path in pathnames : <EOL> print ( "<STR_LIT>" % ( "<STR_LIT>" , path ) ) <EOL> for root in Volumes . keys ( ) : <EOL> if root in Printed : <EOL> continue <EOL> pathnames = Volumes [ root ] [ "<STR_LIT>" ] [ : ] <EOL> isReady = Volumes [ root ] [ "<STR_LIT>" ] <EOL> if isReady : <EOL> type = GetDriveType ( root ) <EOL> info = GetVolumeInformation ( root ) <EOL> label , filesystem = info [ <NUM_LIT:0> ] , info [ <NUM_LIT:4> ] <EOL> else : <EOL> type , label , filesystem = - <NUM_LIT:2> , "<STR_LIT>" , None <EOL> if isReady and type != DRIVE_REMOTE : <EOL> free , total , diskfree = Api . GetDiskFreeSpaceEx ( root ) <EOL> used = <NUM_LIT:100> - ( <NUM_LIT:100> * diskfree / total ) <EOL> else : <EOL> free , total , diskfree , used = None , None , None , None <EOL> if filesystem : <EOL> strtype = "<STR_LIT>" % ( drivetypes [ type ] , filesystem ) <EOL> else : <EOL> strtype = drivetypes [ type ] <EOL> print ( LINE_FORMAT % ( <EOL> "<STR_LIT:*>" , <EOL> label or "<STR_LIT>" , <EOL> strtype , <EOL> prettySize ( total ) , <EOL> prettySize ( diskfree ) , <EOL> "<STR_LIT>" % used if used is not None else "<STR_LIT:->" , <EOL> ) ) <EOL> for path in pathnames : <EOL> print ( "<STR_LIT>" % ( "<STR_LIT>" , path ) ) </s>
