631 lines
18 KiB
Batchfile
631 lines
18 KiB
Batchfile
@echo off
|
|
REM ------------------------------------------------------------------
|
|
REM
|
|
REM movefiles.cmd
|
|
REM Rearrange and collect files in preparation for PRS signing.
|
|
REM
|
|
REM Copyright (c) Microsoft Corporation. All rights reserved.
|
|
REM Version: < 1.0 > 04/09/2001 Suemiao Rossignol
|
|
REM ------------------------------------------------------------------
|
|
perl -x "%~f0" %*
|
|
goto :EOF
|
|
#!perl
|
|
use strict;
|
|
use lib $ENV{RAZZLETOOLPATH} . "\\PostBuildScripts";
|
|
use lib $ENV{RAZZLETOOLPATH};
|
|
use PbuildEnv;
|
|
use Logmsg;
|
|
use ParseArgs;
|
|
use File::Basename;
|
|
use GetIniSetting;
|
|
use comlib;
|
|
#use HashText;
|
|
use cksku;
|
|
|
|
|
|
my $scriptname = basename( $0 );
|
|
|
|
sub Usage {
|
|
print<<USAGE;
|
|
|
|
Rearrange and collect files in preparation for PRS signing.
|
|
|
|
Usage:
|
|
$scriptname: -l:<language> [-d:<Aggregate Path>] [-n:<Build name>] [-undo] [-final]
|
|
|
|
-l Language.
|
|
Default is "usa".
|
|
|
|
-d Aggregate path.
|
|
A path to conglomerate PRS files at before submitting to the prslab.
|
|
|
|
-n Build name.
|
|
The name of the service pack or QFE being built.
|
|
|
|
-undo
|
|
Undo the signing steps.
|
|
Default is doing signing steps.
|
|
|
|
-final
|
|
Sign the finished binary, instead of the internal cats, etc.
|
|
|
|
-? Display Usage.
|
|
|
|
Example:
|
|
$scriptname -l:ger -d:\\prs
|
|
|
|
|
|
USAGE
|
|
exit(1)
|
|
}
|
|
|
|
my ( $lang, $aggDir, $undo, $final );
|
|
my ( @tableHash, $rootCatDir, $rootHashDir, $rootBackupDir );
|
|
my ( @prodSkus,%skusDirName, @realSignFiles, @workDir );
|
|
my ( $dash, $cmdLine );
|
|
my ( $name, $buildName, %certLog, %certFileList, %certPath, %certReqID );
|
|
|
|
|
|
exit(1) if( !&GetParams() );
|
|
timemsg( "Start [$scriptname]" );
|
|
|
|
exit(1) if( !&InitVars() );
|
|
|
|
if( $undo )
|
|
{
|
|
exit(1) if ( !&CopySignFiles );
|
|
exit(1) if ( !&BackupRollbackTestSign );
|
|
}
|
|
else
|
|
{
|
|
if( !$final ) {
|
|
exit(1) if ( !&BackupRollbackTestSign );
|
|
exit(1) if ( !&CopyRealSign );
|
|
exit(1) if ( !&FixCatalogs );
|
|
}
|
|
exit(1) if ( !&CopySignFiles );
|
|
}
|
|
exit(1) if( !&ErrorCheck );
|
|
|
|
timemsg( "Complete [$scriptname]\n$dash" );
|
|
exit(0);
|
|
|
|
#-----------------------------------------------------------------------------
|
|
sub GetParams
|
|
{
|
|
parseargs('?' => \&Usage, 'd:' => \$aggDir, 'n:' => \$name, 'undo' => \$undo , 'final' => \$final);
|
|
$lang = $ENV{lang};
|
|
if( !$aggDir )
|
|
{
|
|
if( !$undo )
|
|
{
|
|
$aggDir="$ENV{_NTPOSTBLD}\\..\\build_logs\\prs";
|
|
}
|
|
else
|
|
{
|
|
#####Retrieve Build name
|
|
if( ! ( $buildName = build_name() ))
|
|
{
|
|
#errmsg( "[$ENV{_ntpostbld}\\build_logs\\buildname.txt] not found, exit." );
|
|
return 0;
|
|
}
|
|
chomp( $buildName );
|
|
#####Define submit log
|
|
if( !$final )
|
|
{
|
|
%certLog =( "prs" => "$ENV{_ntpostbld}\\build_logs\\$buildName\\submit_prs.log",
|
|
"fusion" => "$ENV{_ntpostbld}\\build_logs\\$buildName\\submit_fusion.log" );
|
|
} else {
|
|
%certLog =( "external" => "$ENV{_ntpostbld}\\build_logs\\$buildName\\submit_ext.log" );
|
|
}
|
|
|
|
#####Define Share location
|
|
$aggDir = &comlib::ParsePrsSubmitLog( $certLog{prs}, "Aggregation Path - " );
|
|
}
|
|
}
|
|
if( !$name )
|
|
{
|
|
$name = "sp1";
|
|
}
|
|
return 1;
|
|
}
|
|
#-----------------------------------------------------------------------------
|
|
sub InitVars
|
|
{
|
|
#####Defind PRS file aggregation path
|
|
%certPath = ();
|
|
$certPath{"prs"} = "$aggDir\\prs" if !$final;
|
|
$certPath{"fusion"} = "$aggDir\\fusion" if !$final;
|
|
$certPath{"external"} = "$aggDir\\pack" if $final;
|
|
|
|
if( !$buildName )
|
|
{
|
|
#####Retrieve Build name
|
|
if( ! ($buildName = build_name() ))
|
|
{
|
|
errmsg( "[$ENV{_ntpostbld}\\build_logs\\buildname.txt] not found, exit." );
|
|
return 0;
|
|
}
|
|
chomp( $buildName );
|
|
|
|
#####Define submit log
|
|
system( "md \"$ENV{_ntpostbld}\\build_logs\\$buildName\" ") if( !( -e "$ENV{_ntpostbld}\\build_logs\\$buildName" ) );
|
|
if( !$final )
|
|
{
|
|
%certLog =( "prs" => "$ENV{_ntpostbld}\\build_logs\\$buildName\\submit_prs.log",
|
|
"fusion" => "$ENV{_ntpostbld}\\build_logs\\$buildName\\submit_fusion.log" );
|
|
} else {
|
|
%certLog =( "external" => "$ENV{_ntpostbld}\\build_logs\\$buildName\\submit_ext.log" );
|
|
}
|
|
}
|
|
|
|
#####Log to the file for future reference
|
|
for my $theCert( keys %certPath)
|
|
{
|
|
if( !open( OUT, ">$certLog{$theCert}" ) )
|
|
{
|
|
errmsg( "Fail on opening [$certLog{$theCert}] for write." );
|
|
return 0;
|
|
}
|
|
print OUT "$dash\n";
|
|
print OUT "Aggregation Path - $aggDir\n";
|
|
print OUT "$dash\n";
|
|
close( OUT );
|
|
}
|
|
|
|
####Define list text files for Prs cert and fusion cert
|
|
if( !$final )
|
|
{
|
|
%certFileList = ( "prs" => "$ENV{RazzleToolPath}\\sp\\prs\\fullprslist\.txt",
|
|
"fusion" => "$ENV{RazzleToolPath}\\sp\\prs\\fusionlist\.txt" );
|
|
} else {
|
|
%certFileList = ( "external" => "$ENV{RazzleToolPath}\\sp\\prs\\finallist\.txt" );
|
|
}
|
|
|
|
for my $theCert ( keys %certFileList )
|
|
{
|
|
if( !(-e $certFileList{$theCert} ) )
|
|
{
|
|
errmsg( "[$certFileList{$theCert}] not found, exit." );
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
#####Misc Init
|
|
$dash = '-' x 60;
|
|
$rootCatDir = $ENV{_ntpostbld};
|
|
$rootHashDir = "$ENV{razzletoolpath}\\sp\\data\\catalog\\$ENV{lang}\\$ENV{_BuildArch}$ENV{_BuildType}";
|
|
$rootBackupDir = "$ENV{_ntpostbld}\\congeal_scripts";
|
|
|
|
#####Set Product Skus
|
|
%skusDirName=( "pro" => ".", "per" => "perinf");
|
|
|
|
if ( $ENV{_BuildArch} =~ /x86/i ) {
|
|
@prodSkus=("pro","per");
|
|
}
|
|
else {
|
|
@prodSkus=("pro");
|
|
}
|
|
|
|
# my %validSkus = &cksku::GetSkus( $lang, $ENV{_BuildArch} );
|
|
# @prodSkus = keys %validSkus;
|
|
|
|
#####Set Real Sign Files
|
|
@realSignFiles = ( "layout.inf", "dosnet.inf", "txtsetup.sif" );
|
|
|
|
#####Set Working directories
|
|
push( @workDir, "." );
|
|
|
|
logmsg( "Language ................[$lang]" );
|
|
logmsg( "Build Name ..............[$buildName\]" );
|
|
logmsg( "PRS Share Name...........[$aggDir]" );
|
|
logmsg( "Is Undo signing..........[$undo]" );
|
|
for my $theCert ( keys %certFileList )
|
|
{
|
|
logmsg( "$theCert File Path ......[$certPath{$theCert}]" );
|
|
logmsg( "$theCert File List ......[$certFileList{$theCert}]" );
|
|
}
|
|
logmsg( "Product Skus.............[@prodSkus]" );
|
|
logmsg( "Real Sign Files..........[@realSignFiles]" );
|
|
logmsg( "Working Directories......[@workDir]" );
|
|
logmsg( "Root Catalog Directories.[$rootCatDir]" );
|
|
logmsg( "Root Hash Directories....[$rootHashDir]" );
|
|
logmsg( "Root Backup Directories..[$rootBackupDir]" );
|
|
logmsg( "Log file ................[$ENV{LOGFILE}]" );
|
|
logmsg( "Error file ..............[$ENV{ERRFILE}]" );
|
|
|
|
return 1;
|
|
}
|
|
|
|
#-----------------------------------------------------------------------------
|
|
sub BackupRollbackTestSign
|
|
{
|
|
my ( $catDir, $hashDir, $backupDir );
|
|
my ( $rtChk, $srcDir, $destDir, $to, $from );
|
|
|
|
logmsg( $dash );
|
|
if( !$undo )
|
|
{
|
|
logmsg( "-----Backing up the test sign files-----\n" );
|
|
}
|
|
else
|
|
{
|
|
logmsg( "-----Rolling back the test sign files-----\n" );
|
|
}
|
|
|
|
$rtChk = &CheckSigningType;
|
|
|
|
#####No files need to be backed up
|
|
if( $rtChk == 0)
|
|
{
|
|
logmsg( "Found no test or real sign files. No backups needed." );
|
|
return 1;
|
|
}
|
|
|
|
#####mixed type with test and real sign files both exist
|
|
if( $rtChk == 3)
|
|
{
|
|
errmsg( "Found mixed realsign and testsign files, exit." );
|
|
return 0;
|
|
}
|
|
#####All files are real sign
|
|
if( $rtChk == 2 && !$undo )
|
|
{
|
|
logmsg( "Found realsign files in place, skip backing up test sign files" );
|
|
return 1;
|
|
}
|
|
####Return 1.All files are test sign
|
|
if( $rtChk == 1 && $undo )
|
|
{
|
|
logmsg( "Found Testsign files in place, skip rolling back test sign files" );
|
|
return 1;
|
|
}
|
|
|
|
|
|
for my $wDir ( @workDir )
|
|
{
|
|
if( $wDir ne "." )
|
|
{
|
|
$catDir = "$rootCatDir\\$wDir";
|
|
$hashDir = "$rootHashDir\\$wDir";
|
|
$backupDir = "$rootBackupDir\\$wDir";
|
|
}
|
|
else
|
|
{
|
|
$catDir = $rootCatDir;
|
|
$hashDir = $rootHashDir;
|
|
$backupDir = $rootBackupDir;
|
|
}
|
|
for my $skus ( @prodSkus )
|
|
{
|
|
#####Set Source and Target path
|
|
$srcDir = "$catDir\\$skusDirName{ $skus }";
|
|
$destDir = "$backupDir\\$skusDirName{ $skus }\\PRSbackups";
|
|
|
|
#####Flip between do and undo
|
|
if( $undo )
|
|
{
|
|
$from = $destDir;
|
|
$to=$srcDir;
|
|
}
|
|
else
|
|
{
|
|
$from = $srcDir;
|
|
$to = $destDir;
|
|
if( -e $to )
|
|
{
|
|
return 0 if( !&comlib::ExecuteSystem( "rd /s /q $to" ) );
|
|
}
|
|
return 0 if( !&comlib::ExecuteSystem( "md $to" ) );
|
|
}
|
|
|
|
#####Backup/rollback nt5inf.cat and test sign file
|
|
push( @realSignFiles, "nt5inf.cat" );
|
|
for my $file( @realSignFiles )
|
|
{
|
|
next if( !( -e "$from\\$file" ) );
|
|
$cmdLine = "copy /Y /V $from\\$file $to\\$file";
|
|
return 0 if( !&comlib::ExecuteSystem( $cmdLine ) );
|
|
|
|
if ( $undo )
|
|
{
|
|
# In an undo, need to touch the files to make sure they get
|
|
# compressed, as they are likely older than the real-sign files
|
|
return 0 if ( !&comlib::ExecuteSystem( "touch $to\\$file" ) );
|
|
}
|
|
}
|
|
splice( @realSignFiles, $#realSignFiles, 1);
|
|
|
|
# #####Backup/rollback nt5inf.hash
|
|
# $srcDir = "$hashDir\\$skusDirName{ $skus }";
|
|
# if( $undo )
|
|
# {
|
|
# $from = $destDir;
|
|
# $to=$srcDir;
|
|
# }
|
|
# else
|
|
# {
|
|
# $from = $srcDir;
|
|
# $to = $destDir;
|
|
# }
|
|
# next if( !( -e "$from\\nt5inf.hash" ) );
|
|
# $cmdLine = "copy /Y /V $from\\nt5inf.hash $to\\nt5inf.hash";
|
|
# return 0 if( !&comlib::ExecuteSystem( $cmdLine) );
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
#-----------------------------------------------------------------------------
|
|
sub CopyRealSign
|
|
{
|
|
my ( $srcDir, $destDir );
|
|
|
|
logmsg( $dash );
|
|
logmsg( "-----Copying Real Sign Files in place-----\n" );
|
|
|
|
for my $skus ( @prodSkus )
|
|
{
|
|
$srcDir = "$ENV{_NtPostBld}\\$skusDirName{ $skus }\\realsign";
|
|
$destDir = "$ENV{_NtPostBld}\\$skusDirName{ $skus }";
|
|
|
|
for my $file( @realSignFiles )
|
|
{
|
|
next if ( !(-e "$destDir\\$file") );
|
|
system( "touch $srcDir\\$file" );
|
|
$cmdLine = "copy /y $srcDir\\$file $destDir\\$file";
|
|
return 0 if( !&comlib::ExecuteSystem( $cmdLine ) );
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
#-----------------------------------------------------------------------------
|
|
sub FixCatalogs
|
|
{
|
|
logmsg( $dash );
|
|
logmsg( "Refresh Catalog file with right hash value.............\n" );
|
|
|
|
my ( @mFields, $tmp, @hashValue, $newHashStr, $tmpValue );
|
|
my ( $catDir, $hashDir, $fileName );
|
|
my ( $srcDir, $hashFile, $catFile, $oldHashStr, $hashLine, $newHashStr);
|
|
|
|
my $oldHash = "$ENV{_NTPOSTBLD}\\build_logs\\oldHash.tmp";
|
|
my $newHash = "$ENV{_NTPOSTBLD}\\build_logs\\newHash.tmp";
|
|
|
|
$tmp = "$ENV{_NTPOSTBLD}\\build_logs\\tmpfile";
|
|
|
|
for my $wDir ( @workDir )
|
|
{
|
|
|
|
if( $wDir ne "." )
|
|
{
|
|
$catDir = "$rootCatDir\\$wDir";
|
|
$hashDir = "$rootHashDir\\$wDir";
|
|
}
|
|
else
|
|
{
|
|
$catDir = $rootCatDir;
|
|
$hashDir = $rootHashDir;
|
|
}
|
|
for my $skus ( @prodSkus )
|
|
{
|
|
$catFile = "$catDir\\$skusDirName{ $skus }\\nt5inf.cat";
|
|
$hashFile = "$hashDir\\$skusDirName{ $skus }\\nt5inf.hash";
|
|
|
|
next if !-e $catFile;
|
|
for my $file( @realSignFiles )
|
|
{
|
|
&comlib::ExecuteSystem( "del /f $oldHash" ) if ( -e $oldHash );
|
|
&comlib::ExecuteSystem( "del /f $newHash" ) if ( -e $newHash );
|
|
|
|
if( $skus ne "pro" )
|
|
{
|
|
$fileName = "$ENV{_NtPostBld}\\$skusDirName{ $skus }\\$file";
|
|
}
|
|
else
|
|
{
|
|
$fileName = "$ENV{_NtPostBld}\\$file";
|
|
}
|
|
next if( !( -e $fileName ) );
|
|
|
|
#####Find old hash value
|
|
my $fileName_base = basename($fileName);
|
|
return 0 if( !&comlib::ExecuteSystem( "findstr /iC:$fileName_base $hashFile > $oldHash" ) );
|
|
my @file= &comlib::ReadFile( $oldHash );
|
|
@mFields = split( /\s+/, $file[0]);
|
|
$oldHashStr = $mFields[2];
|
|
|
|
#####Update cat file with Old hash value
|
|
if (-e $catFile) {
|
|
return 0 if( !&comlib::ExecuteSystem("updcat.exe $catFile -a $fileName >NUL 2>NUL") );
|
|
}
|
|
|
|
#####Update SP cat file with Old hash value
|
|
if (-e "$catDir\\$name.cat") {
|
|
return 0 if( !&comlib::ExecuteSystem("updcat.exe $catDir\\sp1.cat -a $fileName >NUL 2>NUL") );
|
|
}
|
|
|
|
#####Calculate new hash value & put in the $newhash file
|
|
return 0 if( !&comlib::ExecuteSystem( "calchash.exe $fileName >$tmp") );
|
|
@file= &comlib::ReadFile( $tmp );
|
|
@hashValue = split( /\s+/, $file[0]);
|
|
unlink( $tmp );
|
|
|
|
$newHashStr = "";
|
|
for my $tmpValue ( @hashValue ){$newHashStr .= $tmpValue };
|
|
|
|
if( !open( TMP, ">$newHash" ) )
|
|
{
|
|
errmsg( "Fail on opening $newHash" );
|
|
return 0;
|
|
}
|
|
print TMP "$fileName - $newHashStr\n";
|
|
close ( TMP );
|
|
|
|
|
|
#####Replace old hash with new hash in the hash file
|
|
# return 0 if( !&comlib::ExecuteSystem("$ENV{RazzleToolPath}\\postbuildscripts\\hashrep.cmd $newHash $hashFile" ) );
|
|
}
|
|
#####Sign the Cat file
|
|
return 0 if( !&comlib::ExecuteSystem("$ENV{RazzleToolPath}\\ntsign.cmd -n -f $catFile") );
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
#-----------------------------------------------------------------------------
|
|
sub CheckSigningType
|
|
{
|
|
my ( $chkFile );
|
|
my ( $chkValue ) =0;
|
|
|
|
|
|
for my $sku ( @prodSkus )
|
|
{
|
|
for my $file ( @realSignFiles )
|
|
{
|
|
$chkFile = "$ENV{_ntpostbld}\\$skusDirName{ $sku}\\$file";
|
|
|
|
next if ( !(-e $chkFile) );
|
|
|
|
###Test sign
|
|
if( !system ( "findstr /i /l testroot $chkFile >NUL 2>NUL" ) )
|
|
{
|
|
$chkValue |= 1;
|
|
}
|
|
else
|
|
{
|
|
$chkValue |= 2;
|
|
}
|
|
|
|
}
|
|
}
|
|
return $chkValue;
|
|
}
|
|
#-----------------------------------------------------------------------------
|
|
sub CopySignFiles
|
|
{
|
|
my ( $src, $dest, $from, $to, $newFileName );
|
|
|
|
my $name2 = $name;
|
|
$name2 = "xp$name2" if $final and $name2 !~ /^q/i;
|
|
|
|
for my $theCert( keys %certPath)
|
|
{
|
|
logmsg( $dash );
|
|
|
|
@tableHash = &comlib::ParsePrsListFile( $lang, $ENV{_buildArch}, $ENV{_buildType}, $certFileList{$theCert} );
|
|
|
|
if( !$undo )
|
|
{
|
|
|
|
logmsg( "-----Copying files to [$certPath{$theCert}] for $theCert----------\n" );
|
|
}
|
|
else
|
|
{
|
|
logmsg( "-----Rolling back files from [$certPath{$theCert}] for $theCert-----\n" );
|
|
}
|
|
for (my $inx=0; $inx< @tableHash; $inx++)
|
|
{
|
|
$src = "$ENV{_ntpostbld}\\$tableHash[$inx]->{ Filename }";
|
|
$newFileName = "$ENV{_buildArch}$ENV{_buildType}.$lang.$tableHash[$inx]->{ AltName }";
|
|
$dest = "$certPath{$theCert}\\$newFileName";
|
|
$src =~ s/\%name\%/$name2/ig;
|
|
$newFileName =~ s/\%name\%/$name2/ig;
|
|
$dest =~ s/\%name\%/$name2/ig;
|
|
if( !$undo )
|
|
{
|
|
$from = $src;
|
|
$to = $dest;
|
|
}
|
|
else
|
|
{
|
|
$from = $dest;
|
|
$to = $src;
|
|
}
|
|
if( lc $theCert eq "prs" && lc $tableHash[$inx]->{DisplayName} ne "default" && !$undo)
|
|
{
|
|
&WriteListTxtFile( $tableHash[$inx]->{Filename}, $tableHash[$inx]->{DisplayName} );
|
|
}
|
|
next if( !( -e $from ) );
|
|
if( !&comlib::ExecuteSystem( "copy /y $from $to" ) )
|
|
{
|
|
errmsg( "Fail on copy $from to $to." );
|
|
next;
|
|
}
|
|
}
|
|
|
|
if( !&comlib::ExecuteSystem( "touch /c $certPath{$theCert}\\..\\$theCert.$ENV{_buildArch}$ENV{_buildType}.$lang.txt" ) ) {
|
|
errmsg( "Unable to mark the copy operation as complete." );
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
#-----------------------------------------------------------------------------
|
|
sub WriteListTxtFile
|
|
{
|
|
my ( $pNewFileName, $pDisplayName ) = @_;
|
|
|
|
my $listFile = "$ENV{temp}\\displayname.$ENV{_BUILDARCH}$ENV{_BUILDTYPE}.txt";
|
|
|
|
if( -e $listFile )
|
|
{
|
|
if( !open( LISTFILE, ">>$listFile" ))
|
|
{
|
|
errmsg( "Fail on open [$listFile] for append." );
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( !open( LISTFILE, ">$listFile" ))
|
|
{
|
|
errmsg( "Fail on open [$listFile] for write." );
|
|
return 0;
|
|
}
|
|
}
|
|
print LISTFILE "$pNewFileName $pDisplayName\n";
|
|
close( LISTFILE );
|
|
}
|
|
#-----------------------------------------------------------------------------
|
|
sub ErrorCheck
|
|
{
|
|
#####Check error logs
|
|
if( -e $ENV{errfile} && !(-z $ENV{errfile}) )
|
|
{
|
|
$ENV{errfile} =~ /(.*)\.tmp$/;
|
|
errmsg( $dash );
|
|
errmsg("Please check error at $1");
|
|
return 0;
|
|
|
|
}
|
|
return 1;
|
|
}
|
|
#-----------------------------------------------------------------------------
|
|
sub build_name
|
|
{
|
|
return $name if $name =~ /^q/i;
|
|
my $buildPath="$ENV{_ntpostbld}\\congeal_scripts";
|
|
my $buildFileName="__qfenum__";
|
|
if (-e "$buildPath\\$buildFileName") {
|
|
open F,"$buildPath\\$buildFileName" or die "unable to ipen $buildPath\\$buildFileName ";
|
|
my $buildNumber=<F>;
|
|
if ( $buildNumber=~/^QFEBUILDNUMBER=(\d*)$/ ){
|
|
return $1;
|
|
}
|
|
else{
|
|
wrnmsg "$buildPath\\$buildFileName format is not correct. Defaulting to 9999";
|
|
return 9999;
|
|
}
|
|
close F;
|
|
}
|
|
else {
|
|
wrnmsg "$buildPath\\$buildFileName not found. Defaulting to 9999";
|
|
return 9999;
|
|
}
|
|
}
|
|
|
|
1;
|
|
|
|
|