common/tools/findPhysicalDrive.pl
changeset 891 6c56420d1006
parent 858 f9fc2a3f8f70
child 924 a5ed0e6ca679
equal deleted inserted replaced
890:41f3579ef67e 891:6c56420d1006
    10 # Symbian Foundation Ltd - initial contribution.
    10 # Symbian Foundation Ltd - initial contribution.
    11 # 
    11 # 
    12 # Contributors:
    12 # Contributors:
    13 #
    13 #
    14 # Description:
    14 # Description:
    15 # Find and output the drive letter mapped to the physical volume with the
    15 # Search physical drives to find either:
    16 # largest amount of free space
    16 #  * The one with the largest amount of free space
    17 # 
    17 #  * The one with the greatest capacity
       
    18 #  * The list of all such drives
    18 
    19 
    19 use strict;
    20 use strict;
    20 
    21 
       
    22 use Getopt::Long;
       
    23 
       
    24 # Read option arguments
       
    25 my $option;
       
    26 my $ok = GetOptions(
       
    27 	'capacity' => \$option->{capacity},
       
    28 	'space' => \$option->{space},
       
    29 	'all' => \$option->{all},
       
    30 	'help|?' => \$option->{help},
       
    31 );
       
    32 
       
    33 if (defined $option->{help})
       
    34 {
       
    35 	usage();
       
    36 	exit;
       
    37 }
       
    38 
       
    39 if (!$ok || @ARGV || 1 != scalar grep { defined $option->{$_} } keys %$option)
       
    40 {
       
    41 	warn "Exactly one option must be supplied to indicate the required output\n$ok\n@ARGV\n";
       
    42 	usage();
       
    43 	exit(1);
       
    44 }
       
    45 
    21 # Use Windows command to list physical volumes on the machine
    46 # Use Windows command to list physical volumes on the machine
    22 # (No substed drives, or mapped network drives)
    47 # (No substed drives, or mapped network drives)
    23 my @drives = map {chomp;$_} `echo list volume | diskpart`;
    48 my @details = map {chomp;$_} `echo list volume | diskpart`;
    24 
    49 
    25 my %drives;
    50 my @drives;
    26 for my $driveLine (@drives)
    51 my %space;
       
    52 my %capacity;
       
    53 for my $driveLine (@details)
    27 {
    54 {
    28 	# If this line of output is actually about a healthy HD volume...
    55 	# If this line of output is actually about a healthy HD volume...
    29 	if ($driveLine =~ m{^\s+Volume \d+\s+([A-Z]).*?(Partition|RAID-5)\s+\d+ [A-Z]+\s+Healthy} )
    56 	if ($driveLine =~ m{^\s+Volume \d+\s+([A-Z]).*?(Partition|RAID-5)\s+(\d+) ([A-Z]+)\s+Healthy} )
    30 	{
    57 	{
    31 		my $letter = $1;
    58 		my ($letter, $capacityValue, $capacityUnit) = ($1, $3, $4);
       
    59 		
       
    60 		my %multiplier = (
       
    61 			MB => 1000000,
       
    62 			GB => 1000000000,
       
    63 			TB => 1000000000000,
       
    64 		);
       
    65 
       
    66 		if (not exists $multiplier{$capacityUnit})
       
    67 		{
       
    68 			warn "Don't know how to interpret $capacityValue $capacityUnit\n";
       
    69 			next;
       
    70 		}
       
    71 		$capacityValue *= $multiplier{$capacityUnit};
       
    72 
    32 		# Ignore the system drive
    73 		# Ignore the system drive
    33 		next if ($driveLine =~ m{System\s*$});
    74 		next if ($driveLine =~ m{System\s*$});
    34 
    75 
    35 		# Use dir to get the freespace (bytes)
    76 		# Use dir to get the freespace (bytes)
    36 		my @bytesFree = grep { s{^.*?(\d+) bytes free\s*$}{$1} } map {chomp;$_} `cmd /c dir /-C $letter:\\`;
    77 		my @bytesFree = grep { s{^.*?(\d+) bytes free\s*$}{$1} } map {chomp;$_} `cmd /c dir /-C $letter:\\`;
    37 		# Take the value from the bottom of the report
    78 		# Take the value from the bottom of the report
    38 		my $bytesFree = $bytesFree[-1];
    79 		my $bytesFree = $bytesFree[-1];
    39 
    80 
    40 		# Record info for this volume
    81 		# Record info for this volume
    41 		$drives{$letter} = $bytesFree;
    82 		push @drives, $letter;
       
    83 		$space{$bytesFree} = $letter;
       
    84 		$capacity{$capacityValue} = $letter;
    42 	}
    85 	}
    43 }
    86 }
    44 
    87 
    45 die "Unable to find any suitable drives at all\n" unless %drives;
    88 die "Unable to find any suitable drives at all\n" unless %space;
    46 
    89 
    47 # Switch keys and values
    90 if ($option->{all})
    48 %drives = reverse %drives;
    91 {
    49 # Sort by space to find the volume with the largest amount of space and print out the corresponding letter
    92 	print join ",", map { "$_:" } @drives;
    50 print "$drives{(reverse sort keys %drives)[0]}:\n";
    93 	print "\n";
       
    94 	exit;
       
    95 }
       
    96 elsif ($option->{capacity})
       
    97 {
       
    98 	# Sort by capacity to find the largest volume and print out the corresponding letter
       
    99 	print "$capacity{(reverse sort keys %capacity)[0]}:\n";
       
   100 }
       
   101 elsif ($option->{space})
       
   102 {
       
   103 	# Sort by space to find the volume with the largest amount of space and print out the corresponding letter
       
   104 	print "$space{(reverse sort keys %space)[0]}:\n";
       
   105 }
    51 
   106 
       
   107 exit;
       
   108 
       
   109 sub usage
       
   110 {
       
   111 	$0 =~ m{[\\/]([^\\/]*)$};
       
   112 	print <<EOT;
       
   113 
       
   114 Usage: $1 -all | -capacity | -space | -help
       
   115 
       
   116   -all          Outputs all physical drives in the system (separated by ',').
       
   117   -capacity     Outputs physical drive of greatest capacity in the system.
       
   118   -space        Outputs physical drive with greatest free space in the system.
       
   119   -help         Outputs this help message.
       
   120 
       
   121 EOT
       
   122 }
       
   123