Generated: Tue Feb 2 17:54:31 2010 from EmbedManifest.pl 2008/08/04 13.4 KB.
################################################################################################################## # # Perl script to search for libraries and binaries which has manifest file associated with it. # The manifest is generated by each library/binary if that project uses CRT,MFC,ATL related functionality. # # perl $0 <SEARCH_BASE_DIR> <IN_CONF_FILE> <IN_MANIFEST_FILE> <OUT_FILE> <INJECT> # # SEARCH_BASE_DIR => Directory to search for files as per FILE_EXT specified IN_CONF_FILE # IN_CONF_FILE => Configuration file which specifies filters and other parameters # IN_MANIFEST_FILE => Input Manifest file to inject into all libraries/binaries # OUT_FILE => Output file to store full path of each seach result # INJECT => 1 to inject MANIFEST_FILE, 0 otherwise # ################################################################################################################## use File::Find; use File::Copy; use Cwd; # Show usage Help sub ShowHelp() { print "\n ***************************************** USAGE ******************************************\n\n"; print " perl $0 <SEARCH_BASE_DIR> <IN_CONF_FILE> <IN_MANIFEST_FILE> <OUT_FILE> <INJECT> \n\n\n"; print " SEARCH_BASE_DIR => Directory to search for files as per FILE_EXT specified IN_CONF_FILE \n\n"; print " IN_CONF_FILE => Configuration file which specifies filters and other parameters\n\n"; print " IN_MANIFEST_FILE => Input Manifest file present in PWD to inject into all libraries and binaries\n\n"; print " OUT_FILE => Output file to store full path of each seach result\n\n"; print " INJECT => 0 => Donot inject, 1 => Inject MANIFEST_FILE, 2=> Backup and Inject\n\n"; print "\n ********************************************************************************************\n\n"; } # Returns string with whitespaces removed from both ends sub Trim { my $string = shift; $string =~ s/^\s+//; $string =~ s/\s+$//; return $string; } # Print error sub PrintError { print "\n"." ERROR : ". $_[0] ."\n"; } # Read configuration parameters from file and update configuration parameters. sub ReadConf { open(INFILE, "< $IN_CONF_FILE"); $section = 0; prt( "Reading config file [$IN_CONF_FILE] ...\n" ); while (<INFILE>) { $line = $_; if ( $line =~ m/^MT_DOT_EXE=/i ) { $MT_DOT_EXE = "\"".Trim(substr($line,length("MT_DOT_EXE=")))."\""; prt( "Found MT_DOT_EXE = [$MT_DOT_EXE]\n" ); next; } if ( $line =~ m/^#FILE_EXT/i ) { $section = 1; next; } if ( $line =~ m/^#END_FILE_EXT/i ) { $section = 0; next; } if ( $line =~ m/^#STRIP_EXT/i ) { $section = 2; next; } if ( $line =~ m/^#END_STRIP_EXT/i ) { $section = 0; next; } if ( $line =~ m/^#ARCH/i ) { $section = 3; next; } if ( $line =~ m/^#END_ARCH/i ) { $section = 0; next; } if ( $line =~ m/^#TYPE/i ) { $section = 4; next; } if ( $line =~ m/^#END_TYPE/i ) { $section = 0; next; } if ( $line =~ m/^#STRICT/i ) { $section = 5; next; } if ( $line =~ m/^#END_STRICT/i ) { $section = 0; next; } if( $section >=1 && $section <= 5) { if( $section == 1 ) { $line =~ s/\./\\./g; prt( "Added:1: FILE_EXT ".($#FILE_EXT + 1)." ".Trim($line)."\n" ); $FILE_EXT[$#FILE_EXT+1] = Trim($line)."\$"; } if( $section == 2 ) { prt( "Added:2: STRIP_EXT ".($#STRIP_EXT + 1)." ".Trim($line)."\n" ); $STRIP_EXT[$#STRIP_EXT+1] = Trim($line); $line =~ s/\./\\./g; $STRIP_REG_EXT[$#STRIP_REG_EXT+1] = Trim($line); } if( $section == 3 ) { prt( "Added:3: ARCH ".($#ARCH + 1)." ".Trim($line)."\n" ); $ARCH[$#ARCH+1] = Trim($line); } if( $section == 4 ) { prt( "Added:4: TYPE ".($#TYPE + 1)." ".Trim($line)."\n" ); $TYPE[$#TYPE+1] = Trim($line); } if( $section == 5 ) { prt( "Added:5: STRICT ".($#STRICT + 1)." ".Trim($line)."\n" ); $STRICT[$#STRICT+1] = Trim($line); } } } close(INFILE); } # ProcessFileDir function which does all the processing... # This function is inovked as when each entry is either file or directory hit sub ProcessFileDir { $step = 0; $lib_type = 0; $dir_name = $File::Find::dir; $file_name = $_; $full_path = $File::Find::name; # return if $full_path is not file #return unless -f $full_path; if ( ! -f $full_path ) { print "ERROR: Returned because [$full_path] is NOT a file ...\n"; } $full_path =~ s,/,\\,g; $dir_name =~ s,/,\\,g; ############################################ # Check for FILE_EXT configuration parameter.... ############################################ if ( $#FILE_EXT < 0 ) { $step = 1; } for($ind=0;$ind<=$#FILE_EXT;$ind++) { prt( "Match [$file_name] with ".$FILE_EXT[$ind]." ...\n" ); if( $file_name =~ m/$FILE_EXT[$ind]/i ) { $step = 1; if ( $file_name =~ m/\.exe\./i ) { $lib_type = 1; } ###elsif ( $file_name =~ m/\.dll\./i ) elsif ( $file_name =~ m/\.dll$/i ) { $lib_type = 2; } elsif ( $file_name =~ m/\.dlm\./i ) { $lib_type = 2; } last; } } #return unless $step == 1; if ($step != 1) { print "ERROR: step not set to 1 ... file name = [$file_name] ... lib type [$lib_type] ...\n"; return; } ############################################ # Check for ARCH configuration parameter.... ############################################ if ( $#ARCH < 0 ) { $step = 2; } for($ind=0;$ind<=$#ARCH;$ind++) { if( $full_path =~ m/$ARCH[$ind]/i ) { $step = 2; last; } } #return unless $step == 2; if ($step != 2) { print "ERROR: step not set to 2 ... No match to [$ARCH] ...\n"; return; } ############################################ # Check for TYPE configuration parameter.... ############################################ if ( $#TYPE < 0 ) { $step = 3; } for($ind=0;$ind<=$#TYPE;$ind++) { if( $full_path =~ m/$TYPE[$ind]/i ) { $step = 3; last; } } #return unless $step == 3; if ($step != 3) { print "ERROR: step not set to 3 ...\n"; return; } ############################################ # Check for STRICT configuration parameter.... ############################################ if ( $#STRICT < 0 ) { $step = 4; } for($ind=0;$ind<=$#STRICT;$ind++) { if( $full_path =~ m/$STRICT[$ind]/i ) { $step = 4; last; } } #return unless $step == 4; if ($step != 4) { print "ERROR: step not set to 4 ...\n"; return; } for($ind=0;$ind<=$#STRIP_REG_EXT;$ind++) { if( $full_path =~ m/$STRIP_REG_EXT[$ind]$/i ) { $step = 5; last; } } #return unless $step == 5; if ($step != 5) { print "ERROR: step not set to 5 ...\n"; return; } # Now write to Console , $OUT_FILE.txt and $OUT_FILE.bat print MANIFEST_OUT $full_path."\n"; #$path_to_library = substr($file_name,0,length($file_name)-length($STRIP_EXT[$ind])); prt( "path [$full_path] and name [$file_name] ... lib type [$lib_type] \n" ); #$path_to_library = substr($full_path,0,length($full_path)-length($STRIP_EXT[$ind])); #$file_name = substr($file_name,0,length($file_name)-length($STRIP_EXT[$ind])); #prt( "Adjusted to path [$path_to_library] and name [$file_name] ...\n" ); $path_to_library = $full_path; if ( $lib_type != 0 && -f $path_to_library) { print " ".$full_path."\n"; $VALID_COUNT++; print COMMAND_OUT "$MT_DOT_EXE -nologo -manifest \"$IN_MANIFEST_FILE\" -outputresource:\"$path_to_library\";#$lib_type"."\n"; $command_param = "-nologo -manifest \"$IN_MANIFEST_FILE\" -outputresource:\"$path_to_library\";#$lib_type"; # backup original file before injecting manifest file & save backup file information in $OUT_FILE_backup.bat if( $INJECT == 2 ) { copy("$path_to_library","$path_to_library".".backup") or die "Backup failed: $!"; print BACKUP_OUT "del \"$path_to_library\""."\n"; print BACKUP_OUT "rename \"$path_to_library.backup\" \"$file_name\""."\n"; } # Now inject the manifest file if ( $INJECT >= 1 ) { if( system("$MT_DOT_EXE $command_param") != 0 ) { print LOG_OUT "ERROR : Injecting manifest failed for $path_to_library"."\n"; } else { print LOG_OUT "SUCCESS : Injected manifest into $path_to_library"."\n"; } } else { print LOG_OUT "NOTHING DONE : Inject = $INJECT"."\n"; prt( "NOTHING DONE : Inject = $INJECT"."\n" ); } } else { if ($lib_type != 0) { prt( "Rejected because [$path_to_library] is NOT a file ...\n" ); } else { prt( "Rejected because lib_type is ZERO ...\n" ); } } $COUNT++; } ################################################# ENTRY POINT #################################################### for ($count = 0; $count <=$#ARGV; $count++) { if( lc($ARGV[$count]) eq "help" || lc($ARGV[$count]) eq "h" || lc($ARGV[$count]) eq "-h" || lc($ARGV[$count]) eq "--h" || lc($ARGV[$count]) eq "/?" || lc($ARGV[$count]) eq "--help" || lc($ARGV[$count]) eq "-help" ) { ShowHelp(); exit; } } if( $#ARGV != 4 ) { PrintError("Wrong number of parameters."); ShowHelp(); exit; } # Genric paremeters $COUNT = 0; $VALID_COUNT = 0; $CUR_DIR = getcwd . "/"; #$CUR_DIR =~ s,/,\\,g; # Process command line parameters $SEARCH_BASE_DIR = $ARGV[0]; $IN_CONF_FILE = $ARGV[1]; $IN_MANIFEST_FILE = $CUR_DIR.$ARGV[2]; $OUT_FILE = $ARGV[3]; $INJECT = $ARGV[4]; # Configuration file parameteres... $MT_DOT_EXE; @FILE_EXT; @STRIP_EXT; @STRIP_REG_EXT; @ARCH; @TYPE; @STRICT; # Return if $SEARCH_BASE_DIR is not a directory if( ! -d $SEARCH_BASE_DIR ) { PrintError("\"$SEARCH_BASE_DIR\" is not a directory. Refer to usage."); exit; } # Return if $IN_CONF_FILE is not a file if( ! -f $IN_CONF_FILE ) { PrintError("\"$IN_CONF_FILE\" is not a file. Refer to usage."); exit; } # Return if $IN_MANIFEST_FILE is not a file if( ! -f $IN_MANIFEST_FILE ) { PrintError("\"$IN_MANIFEST_FILE\" is not a file. Refer to usage."); exit; } # Check whether $INJECT value range from 0 to 2 if( ! ($INJECT >=0 && $INJECT <= 2) ) { PrintError("INJECT = \"$INJECT\" is out of range. Refer to usage."); exit; } # Now read configuration file and update configuration parameters. ReadConf(); $MT_DOT_EXE =~ s,\",,g; if( ! -f $MT_DOT_EXE ) { PrintError("$MT_DOT_EXE does not exist. Refer to conf file."); exit; } $MT_DOT_EXE = "\"". $MT_DOT_EXE ."\""; if ( $#STRIP_EXT < 0 ) { PrintError("Section 2 is empty in configuration file \"$IN_CONF_FILE\"."); exit; } print "\n ********************************************************************************\n\n"; print " Searching for pattern files specified in \"$IN_CONF_FILE\" under \"".$SEARCH_BASE_DIR."\"\n\n"; print " ********************************************************************************\n\n"; # Create two output files. # $OUT_FILE.txt will contain found pattern files # $OUT_FILE.bat will contain command which can be executed manullay if # user wants to inject manifest file manually. open(LOG_OUT, "> $OUT_FILE.log"); open(MANIFEST_OUT, "> $OUT_FILE.txt"); open(COMMAND_OUT, "> $OUT_FILE.bat"); print MANIFEST_OUT "This file contains all the files that are selected before the pattern match.\n\n"; if( $INJECT == 1 ) { print "\n "."$IN_MANIFEST_FILE will be injected into selected libraries..."."\n\n\n"; print " ********************************************************************************\n\n"; } if( $INJECT == 2 ) { print "\n "."Original libraries will be backed up..!!!"; print "\n "."$IN_MANIFEST_FILE will be injected into selected libraries..."."\n\n\n"; print " ********************************************************************************\n\n"; open(BACKUP_OUT, "> $OUT_FILE.backup.bat"); } find({ wanted => \&ProcessFileDir }, $SEARCH_BASE_DIR); print "\n Found \"".$COUNT."\" pattern files under \"".$SEARCH_BASE_DIR."\"\n\n"; print "\n Only \"".$VALID_COUNT."\" file(s) will be injected with \"".$IN_MANIFEST_FILE."\""; print "\n \"".($COUNT-$VALID_COUNT)."\" file(s) either don't match the pattern or not available."."\n\n"; print " ********************************************************************************\n\n"; close(LOG_OUT); close(MANIFEST_OUT); close(COMMAND_OUT); if( $INJECT == 2) { close(BACKUP_OUT, "> $OUT_FILE.bak"); } sub prt { my ($txt) = shift; print $txt; } ##################################################################################################################