windows-nt/Source/XPSP1/NT/sdktools/restools/mui/other/genfilelayout.pl
2020-09-26 16:20:57 +08:00

353 lines
9.1 KiB
Perl

##############################################################
#
# GenFileLayout.pl
#
# Perl script to generate the [File_Layout] section in mui.inx.
#
# Note:
#
# The sciprt does the following:
#
# 1. This script will scan the content of layout.inx
# (in %_NTDRIVE%%_NTROOT%\MergedComponents\SetupInfs\layout.inx)
# and layout.txt
# (in %_NTDRIVE%%_NTROOT%\MergedComponents\SetupInfs\usa\layout.txt).
#
# 2. And then it will figure out the files to be renamed from these two
# files for different platforms (Pro/Server/Advanced Server/DataCenter).
#
# 3. From the file list, it will check the binary folder to see
# if the file to be renamed already exists. If yes, it will
# mark a warning in the output.
#
# 00/12/23 Created by YSLin
#
##############################################################
if ($#ARGV < 2)
{
PrintUsage();
exit 1;
}
$gLayoutFileName = $ARGV[0];
$gLayoutTxtFileName = $ARGV[1];
$gUSBinDir = $ARGV[2];
if ($#ARGV>=2)
{
$gMUIBinDir = $ARGV[3];
} else
{
$gMUIBinDir = "";
}
#
# The name for the [SourceDisksFiles] section in layout.inx.
#
$gFileLayoutSectionNameCommon = "[SourceDisksFiles]";
$gFileLayoutSectionNamex86 = "[SourceDisksFiles.x86]";
$gFileLayoutSectionNameia64 = "[SourceDisksFiles.ia64]";
$gFileLayoutSectionName = $gFileLayoutSectionNameCommon;
$gProfessionalOption = "P";
$gServerOption = "S";
$gAdvancedServerOption = "A";
$gDataCenterOption = "D";
#
# All of the target platforms in mui.inx.
# Currently, they are Professional, Server, and Advanced Server.
#
$gAllPlatforms = "$gProfessionalOption,$gServerOption,$gAdvancedServerOption,$gDataCenterOption";
#
# @p Personal Only
# @w Professional (implies @p)
# @w!p Professional but not Personal
# @@!p Everything except Personal
# @@!d Everything except Data Center
# @s Server (implies @e and @d)
# @e Enterprise (implies @d)
# @d Data Center
# @s!e @s but NOT @e and @d
# @s!d @s but NOT @d
# @e!d @e but NOT @d
#
%gPlatforms = (
'@p' , '',
'@w' , $gProfessionalOption,
'@w!p' , $gProfessionalOption,
'@@!p' , "$gProfessionalOption,$gServerOption,$gAdvancedServerOption",
'@@!d', "$gProfessionalOption,$gServerOption,$gAdvancedServerOption",
'@@' , "$gProfessionalOption,$gServerOption,$gAdvancedServerOption",
'@s' , "$gServerOption,$gAdvancedServerOption,$gDataCenterOption",
'@e' , "$gAdvancedServerOption,$gDataCenterOption",
'@d' , $gDataCenterOption,
'@s!e' , $gServerOption,
'@s!d' , $gServerOption,
'@e!d' , $gAdvancedServerOption,
'@s!e!b', $gServerOption,
);
#$gPlatforms{'@w'} = $gProfessionalOption;
%gStrings = GetProfileValues($gLayoutTxtFileName, '[Strings]');
$fileCount = 0;
$warnings = 0;
NEXTSECTION:
open LAYOUTFILE, $gLayoutFileName; # | die "Can not open " . $ARGV[0];
$FindFileLayoutSection = 0;
while (<LAYOUTFILE>)
{
#
# Match the [SourceDiskFiles] at the beginning of a line.
# \Q\E is used because "[" & "]" are used in the pattern.
#
if (/^\Q$gFileLayoutSectionName\E/ )
{
$FindFileLayoutSection = 1;
last;
}
}
if (!$FindFileLayoutSection)
{
print "No $gFileLayoutSectionName section is found.\n";
close LAYOUTFILE;
exit 1;
}
while (<LAYOUTFILE>)
{
#
# If another line beginning with "[" is encountered, that's the beginning
# of another secion, we can stop the processing.
#
# Match (Beginning of line)(Optional spaces)([)
#
if (/^\s*\Q[\E/)
{
last;
}
#
# Match (Optional spaces)(Non-space characters):(Non-Spaces characters)(Optional spaces)=(Optional Spaces)(Non-space characters)
# The part before the ":" will be $1.
# The part after ":" and before "=" will be $2.
# The part after the "=" will be $3.
#
if (!/\s*(\S*):(\S*).*=\s*(\S*)/)
{
#
# If the pattern does not match, skip to next line.
#
next;
}
$targetPlatforms = $1;
$fileName = $2;
$fieldData = $3;
#print "$targetPlatforms, $fileName, $fieldData\n";
if ($targetPlatforms =~ /@\*/ || $targetPlatforms =~ /\s*;/)
{
#
# Skip the comment line. A comment line will contain "@*" or begin with ";"
#
next;
}
#
# Split the fields using comma separator.
#
@fields = split /,/, $fieldData;
$renameFile = $fields[10];
my $MUIFileExist = 0;
if ($gMUIBinDir eq "")
{
# Don't check if the file exists in the MUI bin folder,
# so just set the following flag to 1.
$MUIFileExist = 1;
} else
{
# Check if the file exists in the MUI bin folder.
$muiFile = "$gMUIBinDir\\$fileName.mui";
if (-e $muiFile)
{
$MUIFileExist = 1;
} else
{
$muiFile = "$gMUIBinDir\\$fileName";
if (-e $muiFile)
{
$MUIFileExist = 1;
}
}
}
# print "$muiFile\n";
if (length($renameFile) > 0 && $MUIFileExist)
{
if ($targetPlatforms =~ /(.*):.*/)
{
$targetPlatforms = $1;
}
#for ($i = 0; $ i <= $#fields; $i++)
#{
# print " [$fields[$i]]\n";
#}
# print " [" . $fields[10] . "]\n";
# print "[". $gPlatforms{$targetPlatforms} . "]\n";
if ($renameFile =~ /.*%(.*)%.*/)
{
# print "!$1!$gStrings{$1}!\n";
$key = $1;
$renameFile =~ s/%$key%/$gStrings{$key}/;
}
$option = $gPlatforms{lc($targetPlatforms)};
if (!(defined $option))
{
print "; WARNING: Unknown platform filter: $targetPlatforms.\n";
next;
}
if (length($option) > 0)
{
$fileCount++;
# Append proper filter flags for different sections
if ($gFileLayoutSectionName eq $gFileLayoutSectionNameCommon)
{
print $targetPlatforms.":".$fileName . "=" . $renameFile . "," . $option . "\n";
}
elsif ($gFileLayoutSectionName eq $gFileLayoutSectionNamex86)
{
print $targetPlatforms.":\@i:".$fileName . "=" . $renameFile . "," . $option . "\n";
}
elsif ($gFileLayoutSectionName eq $gFileLayoutSectionNameia64)
{
print $targetPlatforms.":\@m:".$fileName . "=" . $renameFile . "," . $option . "\n";
}
if (-e ($gUSBinDir . "\\" . $renameFile))
{
$warnings++;
printf "; WARNING: $renameFile has the same name\n";
}
}
}
#
# Match (Optional spaces)(Non-space characters):(Non-Spaces characters)(Optional spaces)=(Optional Spaces)(Non-space characters)
# The part before the ":" will be $1.
# The part after ":" and before "=" will be $2.
# The part after the "=" will be $3.
#
/\s*(\S*):(\S*).*=\s*(\S*)/;
$targetPlatforms = $1;
$fileName = $2;
}
close LAYOUTFILE;
if ($gFileLayoutSectionName eq $gFileLayoutSectionNameCommon)
{
$gFileLayoutSectionName = $gFileLayoutSectionNameia64;
print ";$gFileLayoutSectionName\n";
goto NEXTSECTION;
} elsif ($gFileLayoutSectionName eq $gFileLayoutSectionNameia64)
{
$gFileLayoutSectionName = $gFileLayoutSectionNamex86;
print ";$gFileLayoutSectionName\n";
goto NEXTSECTION;
}
print "; Total files to be renamed: $fileCount\n";
if ($warnings > 0)
{
print "; Total files have warnings: $warnings\n";
}
sub PrintUsage
{
print "Usage: perl GenFileLayout.pl <Path to layout.inx> <Path to layout.txt> <US binary direcotry> [Path to MUI binary directory]\n";
print "[Path to MUI binary directory] is optional."
}
sub GetProfileValues
{
my ($profileName, $section) = @_;
my $findSection = 0;
my ($key, $value);
my ($result);
open PROFILE, $profileName;
while (<PROFILE>)
{
#
# Match (Beginning of line)(Optional white spaces)([$section])
#
if (/^\s*\Q$section\E/)
{
$findSection = 1;
last;
}
}
if (!$findSection)
{
print "$section is not found in $profileName.\n";
exit 1;
}
while (<PROFILE>)
{
#
# If another line beginning with "[" is encountered, that's the beginning
# of another secion, we can stop the processing.
#
# Match (Beginning of line)(Optional spaces)([)
#
if (/^\s*\Q[\E/)
{
last;
}
#
# Match (Optional spaces)(Non-space characters)(Optional spaces)=(Optional Spaces)(Non-space character)(Everything after)
# The part before "=" will be $1.
# The part after the "=" will be $2.
#
/\s*(\S*).*=\s*(\S.*)/;
$key = $1;
$value = $2;
#print "[$key]=[$value]\n";
$result{$key} = $value;
}
close PROFILE;
return (%result);
}