Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

352 lines
9.1 KiB

  1. ##############################################################
  2. #
  3. # GenFileLayout.pl
  4. #
  5. # Perl script to generate the [File_Layout] section in mui.inx.
  6. #
  7. # Note:
  8. #
  9. # The sciprt does the following:
  10. #
  11. # 1. This script will scan the content of layout.inx
  12. # (in %_NTDRIVE%%_NTROOT%\MergedComponents\SetupInfs\layout.inx)
  13. # and layout.txt
  14. # (in %_NTDRIVE%%_NTROOT%\MergedComponents\SetupInfs\usa\layout.txt).
  15. #
  16. # 2. And then it will figure out the files to be renamed from these two
  17. # files for different platforms (Pro/Server/Advanced Server/DataCenter).
  18. #
  19. # 3. From the file list, it will check the binary folder to see
  20. # if the file to be renamed already exists. If yes, it will
  21. # mark a warning in the output.
  22. #
  23. # 00/12/23 Created by YSLin
  24. #
  25. ##############################################################
  26. if ($#ARGV < 2)
  27. {
  28. PrintUsage();
  29. exit 1;
  30. }
  31. $gLayoutFileName = $ARGV[0];
  32. $gLayoutTxtFileName = $ARGV[1];
  33. $gUSBinDir = $ARGV[2];
  34. if ($#ARGV>=2)
  35. {
  36. $gMUIBinDir = $ARGV[3];
  37. } else
  38. {
  39. $gMUIBinDir = "";
  40. }
  41. #
  42. # The name for the [SourceDisksFiles] section in layout.inx.
  43. #
  44. $gFileLayoutSectionNameCommon = "[SourceDisksFiles]";
  45. $gFileLayoutSectionNamex86 = "[SourceDisksFiles.x86]";
  46. $gFileLayoutSectionNameia64 = "[SourceDisksFiles.ia64]";
  47. $gFileLayoutSectionName = $gFileLayoutSectionNameCommon;
  48. $gProfessionalOption = "P";
  49. $gServerOption = "S";
  50. $gAdvancedServerOption = "A";
  51. $gDataCenterOption = "D";
  52. #
  53. # All of the target platforms in mui.inx.
  54. # Currently, they are Professional, Server, and Advanced Server.
  55. #
  56. $gAllPlatforms = "$gProfessionalOption,$gServerOption,$gAdvancedServerOption,$gDataCenterOption";
  57. #
  58. # @p Personal Only
  59. # @w Professional (implies @p)
  60. # @w!p Professional but not Personal
  61. # @@!p Everything except Personal
  62. # @@!d Everything except Data Center
  63. # @s Server (implies @e and @d)
  64. # @e Enterprise (implies @d)
  65. # @d Data Center
  66. # @s!e @s but NOT @e and @d
  67. # @s!d @s but NOT @d
  68. # @e!d @e but NOT @d
  69. #
  70. %gPlatforms = (
  71. '@p' , '',
  72. '@w' , $gProfessionalOption,
  73. '@w!p' , $gProfessionalOption,
  74. '@@!p' , "$gProfessionalOption,$gServerOption,$gAdvancedServerOption",
  75. '@@!d', "$gProfessionalOption,$gServerOption,$gAdvancedServerOption",
  76. '@@' , "$gProfessionalOption,$gServerOption,$gAdvancedServerOption",
  77. '@s' , "$gServerOption,$gAdvancedServerOption,$gDataCenterOption",
  78. '@e' , "$gAdvancedServerOption,$gDataCenterOption",
  79. '@d' , $gDataCenterOption,
  80. '@s!e' , $gServerOption,
  81. '@s!d' , $gServerOption,
  82. '@e!d' , $gAdvancedServerOption,
  83. '@s!e!b', $gServerOption,
  84. );
  85. #$gPlatforms{'@w'} = $gProfessionalOption;
  86. %gStrings = GetProfileValues($gLayoutTxtFileName, '[Strings]');
  87. $fileCount = 0;
  88. $warnings = 0;
  89. NEXTSECTION:
  90. open LAYOUTFILE, $gLayoutFileName; # | die "Can not open " . $ARGV[0];
  91. $FindFileLayoutSection = 0;
  92. while (<LAYOUTFILE>)
  93. {
  94. #
  95. # Match the [SourceDiskFiles] at the beginning of a line.
  96. # \Q\E is used because "[" & "]" are used in the pattern.
  97. #
  98. if (/^\Q$gFileLayoutSectionName\E/ )
  99. {
  100. $FindFileLayoutSection = 1;
  101. last;
  102. }
  103. }
  104. if (!$FindFileLayoutSection)
  105. {
  106. print "No $gFileLayoutSectionName section is found.\n";
  107. close LAYOUTFILE;
  108. exit 1;
  109. }
  110. while (<LAYOUTFILE>)
  111. {
  112. #
  113. # If another line beginning with "[" is encountered, that's the beginning
  114. # of another secion, we can stop the processing.
  115. #
  116. # Match (Beginning of line)(Optional spaces)([)
  117. #
  118. if (/^\s*\Q[\E/)
  119. {
  120. last;
  121. }
  122. #
  123. # Match (Optional spaces)(Non-space characters):(Non-Spaces characters)(Optional spaces)=(Optional Spaces)(Non-space characters)
  124. # The part before the ":" will be $1.
  125. # The part after ":" and before "=" will be $2.
  126. # The part after the "=" will be $3.
  127. #
  128. if (!/\s*(\S*):(\S*).*=\s*(\S*)/)
  129. {
  130. #
  131. # If the pattern does not match, skip to next line.
  132. #
  133. next;
  134. }
  135. $targetPlatforms = $1;
  136. $fileName = $2;
  137. $fieldData = $3;
  138. #print "$targetPlatforms, $fileName, $fieldData\n";
  139. if ($targetPlatforms =~ /@\*/ || $targetPlatforms =~ /\s*;/)
  140. {
  141. #
  142. # Skip the comment line. A comment line will contain "@*" or begin with ";"
  143. #
  144. next;
  145. }
  146. #
  147. # Split the fields using comma separator.
  148. #
  149. @fields = split /,/, $fieldData;
  150. $renameFile = $fields[10];
  151. my $MUIFileExist = 0;
  152. if ($gMUIBinDir eq "")
  153. {
  154. # Don't check if the file exists in the MUI bin folder,
  155. # so just set the following flag to 1.
  156. $MUIFileExist = 1;
  157. } else
  158. {
  159. # Check if the file exists in the MUI bin folder.
  160. $muiFile = "$gMUIBinDir\\$fileName.mui";
  161. if (-e $muiFile)
  162. {
  163. $MUIFileExist = 1;
  164. } else
  165. {
  166. $muiFile = "$gMUIBinDir\\$fileName";
  167. if (-e $muiFile)
  168. {
  169. $MUIFileExist = 1;
  170. }
  171. }
  172. }
  173. # print "$muiFile\n";
  174. if (length($renameFile) > 0 && $MUIFileExist)
  175. {
  176. if ($targetPlatforms =~ /(.*):.*/)
  177. {
  178. $targetPlatforms = $1;
  179. }
  180. #for ($i = 0; $ i <= $#fields; $i++)
  181. #{
  182. # print " [$fields[$i]]\n";
  183. #}
  184. # print " [" . $fields[10] . "]\n";
  185. # print "[". $gPlatforms{$targetPlatforms} . "]\n";
  186. if ($renameFile =~ /.*%(.*)%.*/)
  187. {
  188. # print "!$1!$gStrings{$1}!\n";
  189. $key = $1;
  190. $renameFile =~ s/%$key%/$gStrings{$key}/;
  191. }
  192. $option = $gPlatforms{lc($targetPlatforms)};
  193. if (!(defined $option))
  194. {
  195. print "; WARNING: Unknown platform filter: $targetPlatforms.\n";
  196. next;
  197. }
  198. if (length($option) > 0)
  199. {
  200. $fileCount++;
  201. # Append proper filter flags for different sections
  202. if ($gFileLayoutSectionName eq $gFileLayoutSectionNameCommon)
  203. {
  204. print $targetPlatforms.":".$fileName . "=" . $renameFile . "," . $option . "\n";
  205. }
  206. elsif ($gFileLayoutSectionName eq $gFileLayoutSectionNamex86)
  207. {
  208. print $targetPlatforms.":\@i:".$fileName . "=" . $renameFile . "," . $option . "\n";
  209. }
  210. elsif ($gFileLayoutSectionName eq $gFileLayoutSectionNameia64)
  211. {
  212. print $targetPlatforms.":\@m:".$fileName . "=" . $renameFile . "," . $option . "\n";
  213. }
  214. if (-e ($gUSBinDir . "\\" . $renameFile))
  215. {
  216. $warnings++;
  217. printf "; WARNING: $renameFile has the same name\n";
  218. }
  219. }
  220. }
  221. #
  222. # Match (Optional spaces)(Non-space characters):(Non-Spaces characters)(Optional spaces)=(Optional Spaces)(Non-space characters)
  223. # The part before the ":" will be $1.
  224. # The part after ":" and before "=" will be $2.
  225. # The part after the "=" will be $3.
  226. #
  227. /\s*(\S*):(\S*).*=\s*(\S*)/;
  228. $targetPlatforms = $1;
  229. $fileName = $2;
  230. }
  231. close LAYOUTFILE;
  232. if ($gFileLayoutSectionName eq $gFileLayoutSectionNameCommon)
  233. {
  234. $gFileLayoutSectionName = $gFileLayoutSectionNameia64;
  235. print ";$gFileLayoutSectionName\n";
  236. goto NEXTSECTION;
  237. } elsif ($gFileLayoutSectionName eq $gFileLayoutSectionNameia64)
  238. {
  239. $gFileLayoutSectionName = $gFileLayoutSectionNamex86;
  240. print ";$gFileLayoutSectionName\n";
  241. goto NEXTSECTION;
  242. }
  243. print "; Total files to be renamed: $fileCount\n";
  244. if ($warnings > 0)
  245. {
  246. print "; Total files have warnings: $warnings\n";
  247. }
  248. sub PrintUsage
  249. {
  250. print "Usage: perl GenFileLayout.pl <Path to layout.inx> <Path to layout.txt> <US binary direcotry> [Path to MUI binary directory]\n";
  251. print "[Path to MUI binary directory] is optional."
  252. }
  253. sub GetProfileValues
  254. {
  255. my ($profileName, $section) = @_;
  256. my $findSection = 0;
  257. my ($key, $value);
  258. my ($result);
  259. open PROFILE, $profileName;
  260. while (<PROFILE>)
  261. {
  262. #
  263. # Match (Beginning of line)(Optional white spaces)([$section])
  264. #
  265. if (/^\s*\Q$section\E/)
  266. {
  267. $findSection = 1;
  268. last;
  269. }
  270. }
  271. if (!$findSection)
  272. {
  273. print "$section is not found in $profileName.\n";
  274. exit 1;
  275. }
  276. while (<PROFILE>)
  277. {
  278. #
  279. # If another line beginning with "[" is encountered, that's the beginning
  280. # of another secion, we can stop the processing.
  281. #
  282. # Match (Beginning of line)(Optional spaces)([)
  283. #
  284. if (/^\s*\Q[\E/)
  285. {
  286. last;
  287. }
  288. #
  289. # Match (Optional spaces)(Non-space characters)(Optional spaces)=(Optional Spaces)(Non-space character)(Everything after)
  290. # The part before "=" will be $1.
  291. # The part after the "=" will be $2.
  292. #
  293. /\s*(\S*).*=\s*(\S.*)/;
  294. $key = $1;
  295. $value = $2;
  296. #print "[$key]=[$value]\n";
  297. $result{$key} = $value;
  298. }
  299. close PROFILE;
  300. return (%result);
  301. }