Windows-Server-2003/tools/replaybinplace.pl

175 lines
4.0 KiB
Perl

# -----------------------------------------------------------------------------
# Purpose: recreate %_NTTREE% by re-executing all of the binplace commands
# listed in the log created during the last build.
#
# Usage: ReplayBinplace.pl [<file>]
# If <file> is given, replay commands from that file. If no <file> is
# given, use the file pointed to by %BINPLACE_MESSAGE_LOG% (or fail)
# -----------------------------------------------------------------------------
#
# dependent modules
#
use strict;
use Win32::Process;
use File::Spec;
use File::Temp qw(tempfile);
#
# Real log and temp log variables
#
my $LogToReplay;
my $TempReplayLog;
#
# see if usage() is wanted
#
if ($ARGV[0] =~ /^[-\/][hH?]/) {
Usage();
exit();
}
#
# Verify we have a message log to work with
#
if ( !defined($ARGV[0]) ) {
if ((!defined $ENV{BINPLACE_MESSAGE_LOG}) ||
(! -e $ENV{BINPLACE_MESSAGE_LOG})) {
Usage();
exit();
} else {
$LogToReplay = $ENV{BINPLACE_MESSAGE_LOG};
}
} else {
$LogToReplay = shift;
}
#
# Copy the message log to a temporary file to work with
#
(undef, $TempReplayLog) = tempfile("RBLXXXXXX", SUFFIX=>".rbl", OPEN => 0, DIR => "$ENV{TEMP}");
system("copy $LogToReplay $TempReplayLog > NUL");
printf("Created: $TempReplayLog\n");
open(hFILE, "$TempReplayLog")||die("ERROR: $0 : Can't open $TempReplayLog\n");
#
# point to the binplace executable
#
my $ExeName = "$ENV{RazzleToolPath}\\$ENV{HOST_PROCESSOR_ARCHITECTURE}\\binplace.exe";
#
# Limit the total number of processes to start
#
my $MaxProcs= $ENV{NUMBER_OF_PROCESSORS} * 4;
#
# Record keeping info
#
my $start = time();
#
# Working variables
#
my $cur_proc; # current process info array [$ProcessObj, $ResponseFile]
my $i; # loop var
my $ProcessObj; # a single process object
my @all_procs; # array of all process
my @params; # array of cmdline params
#
# Loop through the file
#
while (<hFILE> ) {
chomp;
@params = split(/\s+/,$_);
chdir($params[0]);
shift @params;
# create a response file
my($fh, $filename) = tempfile("respXXXXXX", SUFFIX=>".rbl", DIR => "$ENV{TEMP}");
printf($fh "@params");
close($fh);
# call binplace
Win32::Process::Create($ProcessObj,
"$ExeName",
"$ExeName \@${filename}",
0,
NORMAL_PRIORITY_CLASS,
".")|| die ErrorReport();
# save info about the new process
push(@all_procs, [$ProcessObj, $filename]);
# don't let the machine get over burdened
while ( $#all_procs > ($MaxProcs - 1) ) {
$cur_proc = shift(@all_procs);
$$cur_proc[0]->Wait(INFINITE);
unlink($$cur_proc[1]);
}
}
#
# wait for the still running processes to finish
#
foreach $cur_proc (@all_procs) {
$$cur_proc[0]->Wait(INFINITE);
unlink($$cur_proc[1]);
}
#
# clenaup
#
close(hFILE);
unlink($TempReplayLog);
printf("$0 : %d seconds\n",time() - $start);
exit(0);
# -----------------------------------------------------------------------------
# Subroutines
# -----------------------------------------------------------------------------
#
# Script usage
#
sub Usage {
print<<END_USAGE
Usage: perl $0 [<file>]
Purpose: recreate %_NTTREE% by re-executing all of the binplace commands
listed in the log created during the last build.
Usage: ReplayBinplace.pl [<file>]
If <file> is given, replay commands from that file. If no <file> is
given, use the file pointed to by %BINPLACE_MESSAGE_LOG% (or fail)
END_USAGE
}
#
# pretty print errors
#
sub ErrorReport{
print Win32::FormatMessage( Win32::GetLastError() );
}
#
# File::Spec theoretically cleans the path up, but it fails to
# handle "[<path>\..\<path>]"
#
sub clean_path {
my $path = shift;#File::Spec->rel2abs($_[0]);
# Remove ..\'s with path
while ( $path =~ s/^(.*?)(\\[^\\]+\\\.\.)\\/$1\\/g ) {
;
}
# Remove excessive ..\'s
$path =~ s/\\\.\.//g;
return($path);
}