############################################################## # # GenFileLayout.pm # # 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]"; $gBuildArch = $ENV{_BuildArch}; $gFileLayoutSectionName = $gFileLayoutSectionNameCommon; $gProfessionalOption = "P"; $gServerOption = "S"; $gAdvancedServerOption = "A"; $gDataCenterOption = "D"; $gBladeServerOption = "B"; $gSmallBusinessServerOption = "L"; # # All of the target platforms in mui.inx. # Currently, they are Professional, Server, and Advanced Server. # $gAllPlatforms = "$gProfessionalOption,$gServerOption,$gAdvancedServerOption,$gDataCenterOption,$gBladeServerOption,$gSmallBusinessServerOption"; # # @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 - and @b and @l too) # @e Enterprise (implies @d) # @d Data Center # @b Blade only # @s!e @s but NOT @e and @d # @s!d @s but NOT @d # @e!d @e but NOT @d # @s!e!d @s but NOT @e and @d # @@!d!b everything except for Datacenter and Blade Server # @l Small Business Server # %gPlatforms = ( '@p' , '', '@w' , $gProfessionalOption, '@w!p' , $gProfessionalOption, '@@!p' , "$gProfessionalOption,$gServerOption,$gAdvancedServerOption,$gDataCenterOption,$gBladeServerOption,$gSmallBusinessServerOption", '@@!d', "$gProfessionalOption,$gServerOption,$gAdvancedServerOption,$gBladeServerOption,$gSmallBusinessServerOption", '@@' , "$gProfessionalOption,$gServerOption,$gAdvancedServerOption,$gDataCenterOption,$gBladeServerOption,$gSmallBusinessServerOption", '@s' , "$gServerOption,$gAdvancedServerOption,$gDataCenterOption,$gBladeServerOption,$gSmallBusinessServerOption", '@e' , "$gAdvancedServerOption,$gDataCenterOption", '@d' , $gDataCenterOption, '@b', $gBladeServerOption, '@l', $gSmallBusinessServerOption, '@s!e' , "$gServerOption,$gBladeServerOption,$gSmallBusinessServerOption", '@s!d' , "$gServerOption,$gAdvancedServerOption,$gBladeServerOption,$gSmallBusinessServerOption", '@e!d' , $gAdvancedServerOption, '@s!e!b' , "$gServerOption,$gSmallBusinessServerOption", '@s!d!e' , "$gServerOption,$gBladeServerOption,$gSmallBusinessServerOption", '@s!e!d' , "$gServerOption,$gBladeServerOption,$gSmallBusinessServerOption", '@s!e!b!l' ,$gServerOption, '@s!d!e!b' ,"$gServerOption,$gSmallBusinessServerOption", '@@!d!b' , "$gProfessionalOption,$gServerOption,$gAdvancedServerOption,$gSmallBusinessServerOption" ); #$gPlatforms{'@w'} = $gProfessionalOption; %gStrings = GetProfileValues($gLayoutTxtFileName, '[Strings]'); $fileCount = 0; $warnings = 0; NEXTSECTION: open LAYOUTFILE, $gLayoutFileName; # | die "Can not open " . $ARGV[0]; $FindFileLayoutSection = 0; while () { # # 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 () { # # 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) { # $1 is the target platform, $2 is the [optional] architecture 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, here, we filter out unwanted platforms # since we are not relying on the build environment to help us with this now. if (($gFileLayoutSectionName eq $gFileLayoutSectionNameCommon) || (($gFileLayoutSectionName eq $gFileLayoutSectionNamex86) && ($ENV{_BuildArch} =~/x86/i)) || (($gFileLayoutSectionName eq $gFileLayoutSectionNameia64) && ($ENV{_BuildArch} =~/ia64/i))) { print $fileName . "=" . $renameFile . "," . $option . "\n"; } # output warning if specified to do so # if (-e ($gUSBinDir . "\\" . $renameFile)) # { # $warnings++; # print "; 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 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 () { # # 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 () { # # 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); }