Windows-Server-2003/tools/postbuildscripts/lgndata.cmd

1153 lines
30 KiB
Batchfile

@echo off
REM ------------------------------------------------------------------
REM
REM lgndata.cmd : (Engine of Language Neutral build)
REM generate various control files to control the flow of Language Neutral build
REM Files may be generated by this script
REM $nttree\\build_logs\\LgNeutral\\lgnlist.txt -0
REM $nttree\\build_logs\\LgNeutral\\lgntobuildlist.txt -g
REM $nttree\\build_logs\\LgNeutral\\lgnbuildlist.txt -i
REM $nttree\\build_logs\\LgNeutral\\lgnsnapt.txt -s
REM $nttree\\build_logs\\LgNeutral\\lgncmflist.txt -m
REM Copy RCBinary & Mofified Binary to $nttree -c
REM Check the state of last LGNT build and recover the
REM state terminated abnormally -v
REM [Note] {RAZZLETOOLPATH} . "\\PostBuildScripts\\lgnexclude.txt contains the exclude list
REM for Language Neutral
REM
REM You will see many places in pbuild.dat for this command.
REM Language Neutral build support incremental build. It also can be restarted correctly from a
REM abnormally terminated state.
REM
REM Copyright (c) Microsoft Corporation. All rights reserved.
REM
REM ------------------------------------------------------------------
perl -x "%~f0" %*
goto :EOF
#!perl
use strict;
use File::Basename;
use IO::File;
use lib $ENV{RAZZLETOOLPATH} . "\\PostBuildScripts";
use lib $ENV{RAZZLETOOLPATH};
use PbuildEnv;
use ParseArgs;
use Logmsg;
use cksku;
use ReadSetupFiles;
BEGIN {
$ENV{SCRIPT_NAME} = 'lgndata.cmd';
}
sub Usage { print<<USAGE; exit(1) }
lgndata [ -?] [-0] [-g] [-i] [-s] [-c]
-0 generate lgnlist.txt which contains qualified binaries to be processed
-g generate lgntobuildlist.txt which contains binaries to be processed
-i generate lgnbuildlist.txt which contains list of LGN resource binaries
-s do a snap shot from Ntreee\\ , for those files listed in PostBuildScripts\\ lgnlist.txt
-c copy Modified bin and RC bin from nttree\\build_logs\\LgNeutra to nttree
-v Verify if last build terminated correctly. If it's not the case, recover it.
USAGE
# Global variables
my ($lang, $fCreateQualified,$fGenerate, $fInitial, $fSnap, $fCopy, $fVerify, $SnapFilePath, $fGenerateCMFList);
my ( $Neutral_LogDir, $LGNToBuildList, $LGNBuildList, $LGNCMFList ,$LGNSnapt, $LGNSnapBak, $LGNExcludeList , $LGNList, $LGNStatus, $LGNTCopyLock );
my( @FILE_LIST, $LogFilename );
my( $TempDir, $TempDiffFile, $TempDiffFile1 );
my( $CodeBinDir, $OrigBinDir, $RCBinDir, $CMFBinDir, $CodeBinPath, $OrigBinPath, $RCBinPath, $CMFBinPath );
my( $nttree, $razpath, $TempDir);
my ($STS_Freshs, $STS_OK, $STS_ToBuildList, $STS_BuildList, $STS_CMFList, $STS_Copy, $STS_RemoveRC, $STS_Unknown);
my ($STS_CopyLock, $STS_CopyStart);
my($fNeedGenerateCMF);
$fGenerate =0;
$fInitial =0;
$fSnap =0;
$fCopy =0;
$fVerify =0;
$fGenerateCMFList = 0;
##################
#
# parse command line
#
##################
parseargs( '?' => \&Usage,
'0' => \$fCreateQualified,
'g' => \$fGenerate,
'i' => \$fInitial,
's' => \$fSnap,
'c' => \$fCopy,
'v' => \$fVerify,
'm' => \$fGenerateCMFList,
'l:' => \$lang,
'p:' => \$SnapFilePath
);
&Main();
#
# Check if Language Neutral is enabled or not
#
sub IsLGNActivated()
{
my ($MUI_MAGIC, $Result);
$Result = 0;
$MUI_MAGIC= $ENV{ "MUI_MAGIC" };
if ( defined($MUI_MAGIC))
{
$Result=1;
}
return $Result
}
#
# Check if we need generate CMF (Compact Resource File)
#
sub IsCMFActivated()
{
my ($MUI_MAGIC_CMF, $Result);
$Result = 0;
$MUI_MAGIC_CMF= $ENV{ "MUI_MAGIC_CMF" };
if ( defined($MUI_MAGIC_CMF))
{
$Result=1;
}
return $Result
}
sub Main {
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
# Begin Main code section
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
# Return when you want to exit on error
#
my ($bUseDefault, $Path, $Mylang);
if ( ! &IsLGNActivated())
{
return 0;
}
if ( ! defined($lang))
{
$lang = $ENV{LANG};
if (! defined($lang))
{
$lang="usa";
}
}
$Mylang="\L$lang";
if ( $Mylang ne "usa")
{
return 0;
}
#
# Should we generate CMF (Compact resource file ?)
#
$fNeedGenerateCMF=&IsCMFActivated();
$Logmsg::DEBUG = 0; # set to 1 to activate logging of dbgmsg's
$LogFilename = $ENV{ "LOGFILE" };
if ( ! defined( $LogFilename ) )
{
$TempDir = $ENV{ "TMP" };
$LogFilename = "$TempDir\\$0.log";
}
$CodeBinDir=$ENV{ "CodeBinDir" };
if ( ! defined( $CodeBinDir) )
{
$CodeBinDir="CodeBin";
}
$RCBinDir=$ENV{ "RcBinDir" };
if ( ! defined( $RCBinDir) )
{
$RCBinDir="RCBin";
}
$OrigBinDir=$ENV{ "OrigBinDir" };
if ( ! defined( $OrigBinDir) )
{
$OrigBinDir="OrigBin";
}
$CMFBinDir=$ENV{ "CMFBinDir" };
if ( ! defined( $CMFBinDir) )
{
$CMFBinDir="CMFBin";
}
timemsg( "Beginning ...");
# set up paths to important files
$nttree = $ENV{ "_NTPostBld" };
$razpath= $ENV{ "RazzleToolPath" };
$TempDir = $ENV{ "TMP" };
$Neutral_LogDir = $nttree."\\build_logs\\LgNeutral";
$LGNToBuildList = $Neutral_LogDir."\\lgntobuildlist.txt";
$LGNBuildList = $Neutral_LogDir."\\lgnbuildlist.txt";
$LGNCMFList = $Neutral_LogDir."\\lgncmflist.txt";
$LGNSnapt = $Neutral_LogDir."\\lgnsnap.txt";
$LGNSnapBak = $Neutral_LogDir."\\lgnsnap.txt.bak";
$LGNExcludeList = $razpath."\\PostBuildScripts\\lgnexclude.txt";
$LGNList = $Neutral_LogDir."\\lgnlist.txt";
$LGNStatus = $Neutral_LogDir."\\lgnStatusLock.txt";
$LGNTCopyLock = $Neutral_LogDir."\\lgnCopyLock.txt";
$TempDiffFile = $Neutral_LogDir."\\lgbindiff.txt";
$TempDiffFile1 = $Neutral_LogDir."\\lgbindiff1.txt";
$OrigBinPath = "$Neutral_LogDir\\$OrigBinDir";
$CodeBinPath ="$Neutral_LogDir\\$CodeBinDir";
$RCBinPath ="$Neutral_LogDir\\$RCBinDir";
$CMFBinPath ="$Neutral_LogDir\\$CMFBinDir";
$STS_Freshs = "Fresh";
$STS_OK = "OK";
$STS_ToBuildList="ToBuildList";
$STS_RemoveRC="RemoveRC";
$STS_BuildList="BuildList";
$STS_CMFList="CMFList";
$STS_Copy="CopyBin";
$STS_Unknown="Unknown";
$STS_CopyLock ="CopyLock";
$STS_CopyStart ="StartCopyBin";
# Create three BIN folder if they are not exist
unless( -d $Neutral_LogDir )
{
if (system("md $Neutral_LogDir") != 0)
{
errmsg("Fatal: $Neutral_LogDir doesn't exist");
exit(1);
}
}
unless ( -d $OrigBinPath)
{
if (system("md $OrigBinPath") != 0)
{
errmsg("Fatal: can't create $OrigBinPath");
exit(1);
}
}
unless ( -d $CodeBinPath)
{
if (system("md $CodeBinPath") != 0)
{
errmsg("Fatal: can't create CodeBinPath");
exit(1);
}
}
unless ( -d $RCBinPath)
{
if (system("md $RCBinPath") != 0)
{
errmsg("Fatal: can't create $RCBinPath");
exit(1);
}
}
unless ( -d $CMFBinPath)
{
if (system("md $CMFBinPath") != 0)
{
errmsg("Fatal: can't create $CMFBinPath");
exit(1);
}
}
if ($fCreateQualified)
{
if (! &CreateQualified())
{
errmsg("Generate $LGNList Failed");
}
}
elsif ($fGenerate)
{
if (!&DoGenerateToBuildList())
{
errmsg("Generate $LGNToBuildList failed");
}
}
elsif ( $fInitial)
{
if (!&DoGenerateBuildList())
{
errmsg("Generate $LGNBuildList failed");
}
}
elsif ( $fGenerateCMFList)
{
if (!&DoGenerateCMFList())
{
errmsg("Generate $LGNCMFList failed");
}
}
elsif ( $fSnap)
{
if (defined($SnapFilePath))
{
$bUseDefault=1;
$Path = $SnapFilePath;
}
else
{
$bUseDefault = 0;
$Path="Null";
}
if (!&DoGenerateSnap($bUseDefault,$Path))
{
errmsg("Generate $LGNSnapt failed");
}
}
elsif ($fCopy)
{
if (! &DoCopyLGNBinary())
{
errmsg("Copy LGN binary failed");
}
}
elsif ($fVerify)
{
#
# Check the last state. If last build process terminated abnormally, recover it.
#
&DoVerify();
}
else
{
&Usage();
}
timemsg( "Finished." );
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
# End Main code section
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
}
#
# Check LGN's last status
# LGN process should work/restart correctly from any interrupted state.
# for example, operator cancels the execution of the script in the middle way, then restart.
# Possible value in StatusLock
# (0) Fresh
# (1) ToBuildList
# (2) BuildList
# (3) CopyBin
# (4) OK
#
sub GetLastStatus
{
my (@Bufs);
if ( ! -e $LGNStatus )
{
return $STS_Freshs;
}
unless (open(INFILE, $LGNStatus))
{
errmsg("Fatal: can't open input for status file $LGNStatus");
return $STS_Unknown;
}
@Bufs=<INFILE>;
close(INFILE);
chomp($Bufs[0]);
logmsg("Current Status=$Bufs[0]");
return $Bufs[0];
}
sub LogStatus
{
my ($TheStatus) = @_;
my ($Result);
$Result = 0;
unless (open(OUTFILE, ">$LGNStatus"))
{
errmsg("Fatal: can't create status file $LGNStatus");
return $Result;
}
print (OUTFILE "$TheStatus\n");
close(OUTFILE);
$Result = 1;
return $Result;
}
#
# Generate lgnlist.txt which contains qualified files to be processed
#
# Input : $nttree\\*.*
# Input : {RAZZLETOOLPATH} . "\\PostBuildScripts\\lgnexclude.txt (Exclude List)
# Output: $nttree\\build_logs\\LgNeutral\\lgnlist.txt
#
sub CreateQualified
{
my %FileTypeTbl = (
".exe" => 1,
".dll" => 1,
".cpl" => 1,
".ocx" => 1,
".tsp" => 1,
".scr" => 1,
".msc" => 1,
);
my ($Result, $Line, $Types, %ExcludeList, @Items);
my(%DrvList);
$Result = 0;
#
# Check for output
#
unless (open(OUTFILE,">$LGNList"))
{
errmsg("Can't open output: $LGNList");
return $Result;
}
#
# Check if exclude List exists
#
unless (open(INFILE,$LGNExcludeList))
{
errmsg("Can open Input: $LGNExcludeList");
close(OUTFILE);
return $Result;
}
#
# Read Exclude List and build hashes
#
@Items =<INFILE>;
close(INFILE);
foreach $Line (@Items)
{
chomp($Line);
$Line =~ s/\s//g;
if (length($Line) == 0)
{
next;
}
if (substr($Line,0,1) eq ";")
{
next;
}
$Line="\L$Line";
$ExcludeList{$Line}=1;
}
#
# Read Driver List from different flavor
#
if (! &ReadDriverList(\%DrvList))
{
errmsg("Read Driver List Failed ");
close(OUTFILE);
return $Result;
}
#
# Combine driver list to exclude list
#
foreach $Line (keys(%DrvList))
{
if ( ! defined($ExcludeList{$Line}) )
{
$ExcludeList{$Line}=1;
}
}
#
# Read Directory
#
unless (opendir(INDIR,$nttree))
{
errmsg("can't open $nttree !!");
close(OUTFILE);
return $Result;
}
@Items=readdir INDIR;
foreach $Line (@Items)
{
if ( ($Line eq "." ) || ($Line eq "..") )
{
next;
}
if (length($Line) < 4)
{
next;
}
$Line="\L$Line";
$Types = substr($Line,-4,4);
if ( ! (defined ($FileTypeTbl{$Types}) ) )
{
next;
}
#
# Not in the exclude List ?
#
if ( ! (defined ($ExcludeList{$Line} ) ) )
{
print (OUTFILE "$Line\n");
}
}
close(OUTFILE);
$Result = 1;
return $Result;
}
#
# Read Driver list from different flavor and build the array
#
sub ReadDriverList
{
my($pHashList) = @_;
my ($BigDrvIndex, $PerDrvIndex, $BlaDrvIndex, $SbsDrvIndex, $SrvDrvIndex , $EntDrvIndex , $DtcDrvIndex);
my ($Path_DrvIndex, $Result, $Flavor, $FilePath, $Line);
my (@DrvIndexFiles, %CDDataSKUs,%INFPathSKUs);
#
# Do nothing at this moment
#
return 1;
#
# Get SKUs
#
%CDDataSKUs = map({uc$_ => cksku::CkSku($_, $lang, $ENV{_BuildArch})} qw(PRO PER SRV BLA SBS ADS DTC));
#
# Build DRiver INFs for SKUs
#
$BigDrvIndex = $nttree . "\\drvindex.inf";
$PerDrvIndex = $nttree . "\\perinf\\drvindex.inf";
$BlaDrvIndex= $nttree . "\\blainf\\drvindex.inf";
$SbsDrvIndex = $nttree . "\\sbsinf\\drvindex.inf";
$SrvDrvIndex = $nttree . "\\srvinf\\drvindex.inf";
$EntDrvIndex = $nttree . "\\entinf\\drvindex.inf";
$DtcDrvIndex= $nttree . "\\dtcinf\\drvindex.inf";
# PRO
$Path_DrvIndex =$BigDrvIndex;
$INFPathSKUs{"PRO"} = [ ( $Path_DrvIndex) ];
#PER
$Path_DrvIndex =$PerDrvIndex;
$INFPathSKUs{"PER"} = [ ($Path_DrvIndex ) ];
#SRV
$Path_DrvIndex =$SrvDrvIndex;
$INFPathSKUs{"SRV"} = [ ($Path_DrvIndex) ];
#BLA
$Path_DrvIndex =$BlaDrvIndex;
$INFPathSKUs{"BLA"} = [ ($Path_DrvIndex) ];
#SBS
$Path_DrvIndex =$SbsDrvIndex;
$INFPathSKUs{"SBS"} = [ ($Path_DrvIndex) ];
#ADS (ENT)
$Path_DrvIndex =$EntDrvIndex;
$INFPathSKUs{"ADS"} = [ ($Path_DrvIndex) ];
#DTC
$Path_DrvIndex =$DtcDrvIndex;
$INFPathSKUs{"DTC"} = [ ($Path_DrvIndex) ];
$Result = 0;
foreach $Flavor (keys(%CDDataSKUs))
{
#if ( ! defined (INFPathSKUs{$Flavor})
#{
# errmsg("ReadDriverList:$Flavor not found in table");
# return $Result;
#}
#($FilePath) = @{$INFPathSKUs{$Flavor}};
if ( !ReadSetupFiles::ReadDrvIndex( $nttree, $Flavor, \@DrvIndexFiles) )
{
errmsg( "Error reading drvindex file, skipping $Flavor." );
return $Result;
}
foreach $Line (@DrvIndexFiles)
{
if ( ! defined($$pHashList{$Line}) )
{
$$pHashList{$Line} = 1;
}
}
}
$Result=1;
return $Result;
}
#
# Generate the list from which binaries will be processed
#
sub DoGenerateToBuildList
{
my ($Fresh, $Result, $Line, $Path, @Bufs, @Diffs, $Item_no);
my ($Path, $FilePath, $FileName, $Size, $Mtime, $LastStatus, $WindiffCommand);
$Result = 0;
$Item_no=0;
#
# Check last status
#
$LastStatus = GetLastStatus();
if ( ($LastStatus ne $STS_Freshs ) && ($LastStatus ne $STS_OK) &&
($LastStatus ne $STS_Copy))
{
if ( -e $LGNToBuildList)
{
LogStatus($STS_ToBuildList);
return 1;
}
}
unless (open(INFILE, $LGNList))
{
errmsg("Fatal: can't open $LGNList");
return $Result;
}
@Bufs=<INFILE>;
close(INFILE);
unless (open(OUTFILE, ">$LGNToBuildList"))
{
errmsg("Fatal: can't open output or $LGNToBuildList");
return $Result;
}
$Fresh=0;
if ( ! -e $LGNSnapt )
{
$Fresh=1;
foreach $Line (@Bufs)
{
chomp($Line);
$Line =~ s/\s//g;
if (length($Line) == 0)
{
next;
}
$Path="$nttree\\$Line";
if (-e $Path)
{
print (OUTFILE "$Line\n");
$Item_no++;
}
}
close(OUTFILE);
}
else
#
# Snap shot exists
#
{
$Fresh=0;
if (-e $LGNSnapt)
{
if (-e $LGNSnapBak)
{
if (system("del $LGNSnapBak") != 0)
{
errmsg("Fatal:Can't delete $LGNSnapBak");
return $Result;
}
}
($FileName, $Path ) = fileparse($LGNSnapBak);
if (system("ren $LGNSnapt $FileName") != 0)
{
errmsg("Fatal:Can't rename $LGNSnapt to $LGNSnapBak");
return $Result;
}
}
#
# Create the snap files
#
if (! &CreateSnapFile($LGNSnapt,\@Bufs))
{
errmsg("Fatal:Create $LGNSnapt failed");
return $Result;
}
system("windiff $LGNSnapBak $LGNSnapt -Fx $TempDiffFile");
FilterWindiff($TempDiffFile,$TempDiffFile);
#
# Uniqify the $TempDiffFile
#
$WindiffCommand="perl $razpath\\PostBuildScripts\\unique.pl -i\:$TempDiffFile -o\:$TempDiffFile1";
system("$WindiffCommand" );
#
# Now, Read $TempDiffFile1 and create $LGNToBuildList
#
unless (open(INFILE, $TempDiffFile1))
{
errmsg("can't open $TempDiffFile1");
return $Result;
}
@Diffs=<INFILE>;
close(INFILE);
unless (open(OUTFILE, ">$LGNToBuildList"))
{
errmsg("Fatal: can't open output or $LGNToBuildList");
return $Result;
}
foreach $Line (@Diffs)
{
chomp($Line);
$Line =~ s/\s//g;
if (length($Line) == 0)
{
next;
}
($FilePath, $Size, $Mtime ) = split ( /,+/, $Line);
chomp($FilePath);
($FileName, $Path ) = fileparse($FilePath);
chomp($FileName);
$FileName =~ s/\s//g;
print (OUTFILE "$FileName\n");
}
close(OUTFILE);
}
$Result=1;
#
# Log the current state so that we may restart without problem
#
&LogStatus($STS_ToBuildList);
return $Result;
}
#
# Generate the list of binaries from which resource are move out.
#
sub DoGenerateBuildList
{
my ($Result, $Line, @FilesList, $FilePath, $CodePath, $Item_No);
my($FileName, $Path);
$Result = 0;
unless (open(OUTFILE, ">$LGNBuildList"))
{
errmsg("Can't open output $LGNBuildList");
return $Result;
}
if(!opendir(LOCBINDIR, $CodeBinPath))
{
errmsg ("Can't open $CodeBinPath");
return $Result;
}
@FilesList = grep !/^\.\.?\z/ , readdir LOCBINDIR;
$Item_No=scalar(@FilesList);
logmsg("CodeBin total:$Item_No");
close(LOCBINDIR);
foreach $Line (@FilesList)
{
chomp($Line);
$Line =~ s/\s//g;
if (length($Line) == 0)
{
next;
}
($FileName, $Path ) = fileparse($Line);
#
# Double check if corr. .mui file exists
#
$FilePath = "$RCBinPath\\$FileName.mui";
$CodePath = "$CodeBinPath\\$FileName";
if ( (-e $FilePath) && (-e $CodePath))
{
print (OUTFILE "$FileName\n");
}
else
{
errmsg("$Line exits but $FilePath / $CodePath is missed");
}
}
close(OUTFILE);
#
# Log the current state so that we may restart without problem
#
&LogStatus($STS_BuildList);
$Result = 1;
return $Result;
}
#
# Generate the list of CMF (Compact Resource file) which contain binaries, from which resource are move out.
#
sub DoGenerateCMFList
{
my ($Result, $Line, @FilesList, $FilePath, $Item_No);
my($FileName, $Path);
if ( ! $fNeedGenerateCMF)
{
return 1;
}
$Result = 0;
unless (open(OUTFILE, ">$LGNCMFList"))
{
errmsg("Can't open output $LGNCMFList");
return $Result;
}
if(!opendir(LOCBINDIR, $CMFBinPath))
{
errmsg ("Can't open $CMFBinPath");
return $Result;
}
@FilesList = grep !/^\.\.?\z/ , readdir LOCBINDIR;
$Item_No=scalar(@FilesList);
logmsg("CMFBin total:$Item_No");
close(LOCBINDIR);
foreach $Line (@FilesList)
{
chomp($Line);
$Line =~ s/\s//g;
if (length($Line) == 0)
{
next;
}
($FileName, $Path ) = fileparse($Line);
#
# Double check
#
$FilePath = "$CMFBinPath\\$FileName";
if ( -e $FilePath)
{
print (OUTFILE "$FileName\n");
}
else
{
errmsg("$Line exits but $FilePath is missed");
}
}
close(OUTFILE);
#
# Log the current state so that we may restart without problem
#
&LogStatus($STS_CMFList);
$Result = 1;
return $Result;
}
#
# Copy Midified Binary and RC binary to $nttree
#
# Case: if $fNeedGenerateCMF is true, copy *.cmf from $CMFBinPath
# else copy *.mui from $RCBinPath
#
sub DoCopyLGNBinary
{
my ($Result, $ErrCnt, $Line, @Bufs, @Bufs_CMF, $FilePathRC, $FilePathCode, $DestPath);
$Result = 0;
$ErrCnt=0;
unless (open(INFILE, $LGNBuildList))
{
errmsg("fatal: DoCopyLGNBinary:: can't open input for $LGNBuildList");
return $Result;
}
@Bufs=<INFILE>;
close(INFILE);
if ($fNeedGenerateCMF)
{
unless (open(INFILE, $LGNCMFList))
{
errmsg("fatal: DoCopyLGNBinary:: can't open input for $LGNCMFList");
return $Result;
}
@Bufs_CMF=<INFILE>;
close(INFILE);
}
#
# Open a Status file to keep the state so that we may restart correctly
#
unless (open(OUTFILE, ">$LGNTCopyLock"))
{
errmsg("fatal: DoCopyLGNBinary:: can't open output for $LGNTCopyLock");
return $Result;
}
print (OUTFIULE "$STS_CopyLock");
close (OUTFILE);
LogStatus($STS_CopyStart);
foreach $Line (@Bufs)
{
chomp($Line);
$Line =~ s/\s//g;
if (length($Line) == 0)
{
next;
}
$FilePathRC = "$RCBinPath\\$Line.mui";
$FilePathCode = "$CodeBinPath\\$Line";
#
# Copy RCBin only if CMF is not enabled
#
if ( ! $fNeedGenerateCMF)
{
$DestPath="$nttree\\$Line.mui";
if ( system("copy/y $FilePathRC $DestPath") != 0)
{
$ErrCnt++;
errmsg("DoCopyLGNBinary:: Can't copy $FilePathRC");
}
}
$DestPath="$nttree\\$Line";
if ( system("copy/y $FilePathCode $DestPath") != 0)
{
$ErrCnt++;
errmsg("DoCopyLGNBinary:: Can't copy $FilePathCode");
}
}
#
# Copy CMF files if it's enabled
#
if ($fNeedGenerateCMF)
{
foreach $Line (@Bufs_CMF)
{
chomp($Line);
$Line =~ s/\s//g;
if (length($Line) == 0)
{
next;
}
$FilePathRC = "$CMFBinPath\\$Line";
$DestPath="$nttree\\$Line";
if ( system("copy/y $FilePathRC $DestPath") != 0)
{
$ErrCnt++;
errmsg("DoCopyLGNBinary:: Can't copy $FilePathRC");
}
}
}
if ( $ErrCnt == 0)
{
$Result = 1;
logmsg("DoCopyLGNBinary successfully");
&LogStatus($STS_Copy);
}
else
{
errmsg("DoCopyLGNBinary got errors");
}
if (-e $LGNTCopyLock)
{
if ( system("del $LGNTCopyLock") != 0)
{
errmsg("Can't delete $LGNTCopyLock");
}
}
return $Result;
}
sub DoVerify
{
#
# Check if last operation terminated abnormally
#
if ( -e $LGNTCopyLock)
{
if ( GetLastStatus() eq $STS_CopyStart)
{
logmsg("Recover needed");
DoCopyLGNBinary();
DoGenerateSnap(0,"Null");
logmsg("Recover completed");
}
if (system("del $LGNTCopyLock") != 0)
{
errmsg("Recover: can't delete $LGNTCopyLock");
}
}
return 1;
}
#
# Generate Snap File
# This routine will be called through pbuild table when the last step of language neutral build is
# executed. Keep a snap of last state will help us to support incremental build.
#
sub DoGenerateSnap
{
my ($bUseDefault, $AltFilePath) = @_;
my ($Result, @Bufs, $FilePath, $FileName, $Path);
$Result = 0;
#
# Backup previous Snap file
#
if ( ! $bUseDefault)
{
if (-e $LGNSnapBak)
{
if (system("del $LGNSnapBak") != 0)
{
errmsg("Fatal:Can't delete $LGNSnapBak");
return $Result;
}
($FileName, $Path ) = fileparse($LGNSnapBak);
if (system("ren $LGNSnapt $FileName") != 0)
{
errmsg("Fatal:Can't rename $LGNSnapt to $LGNSnapBak");
return $Result;
}
}
$FilePath = $LGNSnapt;
}
else
{
$FilePath = $AltFilePath;
}
unless (open(INFILE, $LGNList))
{
errmsg("Fatal: can't open $LGNList");
return $Result;
}
@Bufs=<INFILE>;
close(INFILE);
#
# Create the snap files
#
if (! &CreateSnapFile($FilePath,\@Bufs))
{
errmsg("Fatal:Create $FilePath failed");
return $Result;
}
$Result=1;
return $Result;
}
#
# Generate Snap File
#
# Snap File contains File size and last modification date for the binaries in $nttree
#
sub CreateSnapFile
{
my ($OutputPath, $pItemsList) = @_;
my ($Line, $Result, $FilePath);
my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks);
$Result = 0;
unless (open(OUTFILE, ">$OutputPath"))
{
errmsg("Can't open output $FilePath to generate Snap file");
return $Result;
}
foreach $Line ( @$pItemsList )
{
chomp($Line);
$Line =~ s/\s//g;
if (length($Line) == 0)
{
next;
}
$FilePath = "$nttree\\$Line";
#
# Get the file status by using stat function
#
if (-e $FilePath)
{
( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime,
$ctime, $blksize, $blocks ) = stat( $FilePath );
#
# Snap File contains File size and last modification date
#
print( OUTFILE "$FilePath , $size , $mtime\n" );
}
}
close( OUTFILE );
$Result =1;
return $Result;
}
#
# Filter for output of windiff
# The output of windiff is the comparison of current Snap and previous Snap file
# We'll understand which Binaries are changed.
# We use this approach to support Language Neutral Incremental build.
#
sub FilterWindiff
{
my ($InputFile,$OutputFile) = @_;
my ($Result, @InfileLines, $Line, $FileName, $Junk );
$Result = 0;
unless ( open( INFILE, $InputFile ) )
{
errmsg( "Fatal:Failed to open '$InputFile' for reading" );
return $Result;
}
@InfileLines = <INFILE>;
close( INFILE );
unless ( open( OUTFILE, ">$OutputFile" ) )
{
errmsg( "Fatal:Failed to open '$OutputFile' for writing" );
return $Result;
}
#
# now parse out the interesting lines from windiff
#
foreach $Line ( @InfileLines )
{
chomp( $Line );
if ( $Line =~ /\-\- / )
{
next;
}
( $Junk, $Junk, $FileName, $Junk ) = split( /\s+/, $Line );
print( OUTFILE "$FileName\n" );
}
close( OUTFILE );
$Result = 1;
return $Result;
}