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.

471 lines
11 KiB

  1. #
  2. # iisinfsp.pl
  3. #
  4. # Perl script
  5. #
  6. # generates iis.inf for service packs from its gold version.
  7. # goldfiles\<lang>\<arch>\iis.inf.gold are checked in files.
  8. # this script pick up changes in iisend.inx, merge into iis.inf.
  9. # it also find changed files from spfiles.txt, edit iis.inf
  10. # so the source disk points to service pack CD.
  11. # lastly, it update cdname section with mednames.txt
  12. #
  13. # the script is designed and tested for WinXP. it runs on two
  14. # platforms: ia64 and x86.
  15. #
  16. ######################################
  17. # main program
  18. #
  19. sub ProcessInf;
  20. sub prepare_change_list;
  21. sub toUnicode;
  22. sub toAnsi;
  23. $setupinf = "$ENV{'SDXROOT'}\\MergedComponents\\SetupInfs\\";
  24. local %edit_sections;
  25. prepare_change_list();
  26. # deal with all files in 'goldfiles\pro' folder
  27. #
  28. chdir("goldfiles/pro") or die "?";
  29. @dirlist = <*>;
  30. foreach $dir (@dirlist)
  31. {
  32. $lang = $dir;
  33. if ($ENV{"_BuildArch"} =~ /x86/i)
  34. {
  35. chdir("$dir/x86fre") or die "could not cd to $dir/x86fre";
  36. print "processing $dir/x86fre\n";
  37. ProcessInf;
  38. chdir("../..") or die "?";
  39. }
  40. if ($ENV{"_BuildArch"} =~ /ia64/i) #optional
  41. {
  42. if (chdir("$dir/ia64fre"))
  43. {
  44. print "processing $dir/ia64fre\n";
  45. ProcessInf;
  46. chdir("../..") or die "?";
  47. }
  48. }
  49. }
  50. chdir("../..") or die "?";
  51. # deal with all files in 'goldfiles\per' folder
  52. #
  53. chdir("goldfiles/per") or die "?";
  54. @dirlist = <*>;
  55. foreach $dir (@dirlist)
  56. {
  57. $lang = $dir;
  58. if ($ENV{"_BuildArch"} =~ /x86/i)
  59. {
  60. chdir("$dir/x86fre") or die "could not cd to $dir/x86fre";
  61. # just copy then binplace iis.inf personal
  62. $target = "$lang\\perinf";
  63. $target = "perinf" if $lang=~ /usa/i;
  64. system("copy iis.inf.gold iis.inf");
  65. system("echo iis.inf $target >bp.txt");
  66. system("binplace -p bp.txt iis.inf");
  67. unlink("bp.txt");
  68. chdir("../..") or die "?";
  69. }
  70. }
  71. chdir("../..");
  72. # end of main program
  73. ########################################
  74. sub toUnicode
  75. {
  76. my $r = shift @_;
  77. $r =~ s/(.)/$1\0/g;
  78. $r =~ s/(\n)/$1\0/g;
  79. return $r;
  80. }
  81. # !not a unicode-to-widechar conversion!
  82. # it only works for ascii character. non-ascii characters a toasted
  83. sub toAnsi
  84. {
  85. my $r = shift @_;
  86. $r =~ s/\0//g;
  87. return $r;
  88. }
  89. # unicode file may have 0x0a as part of a character
  90. # keep reading until we see the sequence 0x0a 0x00 and call that a line.
  91. # well, strictly speaking that's not correct as you can have two characters
  92. # like (xx 0a) (00 yy). but this is unlikely, this func is a hack anyway.
  93. sub unicodeReadline
  94. {
  95. my $file = shift @_;
  96. my $r = "";
  97. while (<$file>)
  98. {
  99. read ($file, $nextch, 1);
  100. $r .= $_ . $nextch;
  101. return $_=$r if ord($nextch) == 0;
  102. }
  103. return 0;
  104. }
  105. sub prepare_change_list
  106. {
  107. get_iisend_inx_changes();
  108. get_spfiles_list();
  109. }
  110. sub get_spfiles_list
  111. {
  112. # get all files from spfiles.txt
  113. #
  114. open(SRC, "$ENV{SDXROOT}/tools/spfiles.txt") or die "could not open spfiles.txt";
  115. while (<SRC>)
  116. {
  117. s/^.\s*//; # remove leading flag and spaces
  118. s/.*[\\\/]//; # remove path, only need file name
  119. next if /coUA\.css/i; # name collision, we didn't want to ship this file
  120. $spfiles{$_}++;
  121. }
  122. close SRC;
  123. }
  124. # find all modified sections in iisend.inx,
  125. # which will be merge changes to iis.inf.gold later
  126. #
  127. sub get_iisend_inx_changes
  128. {
  129. print "digesting iisend.inx changes\n";
  130. # start by calling sd diff
  131. #
  132. #$ret = system("sd diff iisend.inx#1 iisend.inx#have > inf.tmp");
  133. $ret = system("sd diff iisend.inx#1 iisend.inx > inf.tmp");
  134. die "can't run sd diff" if $ret != 0;
  135. open(SRC, "inf.tmp") or die "can't open inf.tmp";
  136. my %lines;
  137. my %new_sections;
  138. # parse result from sd diff
  139. #
  140. while (<SRC>)
  141. {
  142. # changed lines
  143. # 6183a6185,6187
  144. if (/^\d/)
  145. {
  146. s/^[\d,]+[a-z](\d+).*/$1/;
  147. $lines{0+$_}++;
  148. }
  149. # new section
  150. # > @@!p:[OC_COMPLETE_INSTALLATION_install.iis_ftp.GUIMODE]
  151. elsif (/^>.*:\[.*\]$/)
  152. {
  153. s/.*\[/\[/;
  154. chomp;
  155. $new_sections{lc($_)}++;
  156. }
  157. # deleted sections
  158. # < @@!p:[OC_COMPLETE_INSTALLATION_install.iis_ftp.GUIMODE]
  159. elsif (/^<.*:\[.*\]$/)
  160. {
  161. die "deleting sections from iis.inf not supported, just leave them empty"
  162. }
  163. }
  164. close SRC;
  165. if ($debug)
  166. {
  167. foreach $line (sort keys %lines)
  168. {
  169. print "$line, @lines{$line}\n";
  170. }
  171. }
  172. # looking for sections where we had diffs
  173. #
  174. open(SRC, "iisend.inx") or die "can't open iisend.inx";
  175. binmode(SRC);
  176. $line = 0;
  177. $sectioni = 0;
  178. $sectionu = 0;
  179. @section = (());
  180. while (unicodeReadline(SRC))
  181. {
  182. $line++;
  183. s/\0//g;
  184. s/[\r\n]//g;
  185. s/^@.*://;
  186. if (@lines{$line} != 0)
  187. {
  188. $lines{$line} = \@{$section[$sectioni]};
  189. $sectionu = 1;
  190. }
  191. if (/^\[/ && !($new_sections{lc($_)}))
  192. {
  193. $sectioni += $sectionu;
  194. $sectionu = 0;
  195. $section[$sectioni] = ();
  196. }
  197. push(@{$section[$sectioni]}, $_);
  198. }
  199. close(SRC);
  200. if ($debug)
  201. {
  202. foreach $line (sort keys %lines)
  203. {
  204. foreach $txt (@{$lines{$line}})
  205. {
  206. print "$line, $txt \n";
  207. }
  208. }
  209. }
  210. # consolidate changed lines to hash
  211. #
  212. foreach $line (sort keys %lines)
  213. {
  214. @text = @{$lines{$line}};
  215. $text[0] = lc(toUnicode($text[0] . "\r\n"));
  216. $edit_sections{$text[0]} = toUnicode((join "\r\n", @text[1..$#text]) . "\r\n");
  217. }
  218. if ($debug)
  219. {
  220. foreach $section (keys %edit_sections)
  221. {
  222. print "\n$section\n$edit_sections{$section}";
  223. }
  224. }
  225. }
  226. # read mednames.txt for current language
  227. # fake a section edit from it. that assumes the first line
  228. # never changes (cdname)
  229. #
  230. sub get_mednames_txt_changes
  231. {
  232. my $path = "$setupinf$dir\\mednames.txt";
  233. $path = "${setupinf}cht\\mednames.txt" if $dir =~ /CHH/i;
  234. # prodfilt on mednames.txt
  235. $ret = system("prodfilt $path mednames1.tmp +w >nul");
  236. die "can't run prodfilt" if $ret != 0;
  237. $ret = system("prodfilt mednames1.tmp mednames2.tmp +i >nul");
  238. die "can't run prodfilt" if $ret != 0;
  239. #print "reading mednames2.tmp\n";
  240. # read in the file
  241. open MEDFILE, "mednames2.tmp";
  242. # not a unicode file, we just need its \r with \n
  243. binmode MEDFILE;
  244. while (<MEDFILE>) { last if /\S/ }
  245. my $line1 = toUnicode(lc($_));
  246. my $rest = "";
  247. while (<MEDFILE>) { $rest .= toUnicode($_) };
  248. close MEDFILE;
  249. if ($debug)
  250. {
  251. print ">>>$line1<<<";
  252. print $rest;
  253. }
  254. $edit_sections{$line1} = $rest;
  255. unlink("mednames1.tmp");
  256. unlink("mednames2.tmp");
  257. }
  258. sub ProcessInf
  259. {
  260. # add mednames.txt to edit_sections
  261. get_mednames_txt_changes();
  262. # get all file names from iis.inf.gold
  263. # match files from spfiles.txt, record line number and file name
  264. #
  265. open(SRC, "iis.inf.gold") or die "could not open iis.ans";
  266. binmode(SRC);
  267. my @edits; # lines to edit
  268. my %changefiles; # file names may need to change from IIS_xxx to xxx
  269. my $x;
  270. my $line = 0;
  271. while (unicodeReadline(SRC))
  272. {
  273. $line++;
  274. $_ = toAnsi($_);
  275. $x+=2 if /^\[SourceDisksFiles\]/;
  276. if ($x)
  277. {
  278. if (/=.*,/)
  279. {
  280. s/^IIS_//;
  281. s/=.*//;
  282. if ($spfiles{$_})
  283. {
  284. push @edits, $line;
  285. chomp;
  286. $changefiles{$_}++;
  287. }
  288. }
  289. $x-- if /^\[/;
  290. }
  291. }
  292. # munge iis.inf.gold to produce iis.inf
  293. # 1) do section edits
  294. # 2) do file location changes
  295. open(SRC, "iis.inf.gold") or die "can't open iis.inf.gold";
  296. open(DST, "> iis.inf") or die "can't open iis.inf";
  297. binmode(SRC);
  298. binmode(DST);
  299. #binmode(STDOUT);
  300. $line = 0;
  301. push @edits, 999999; # in case the list is empty
  302. @edits = reverse sort { $a <=> $b } @edits;
  303. my $toline = pop(@edits);
  304. while (unicodeReadline(SRC))
  305. {
  306. $line++;
  307. while ($edit_sections{lc($_)})
  308. {
  309. $newtext = $edit_sections{lc($_)};
  310. print DST $_;
  311. if ($debug)
  312. {
  313. print toAnsi($_);
  314. #print toAnsi($newtext);
  315. }
  316. #skip this section in source files
  317. A: while (unicodeReadline(SRC))
  318. {
  319. $line++;
  320. last A if /^\[/;
  321. # end of section for mednames.txt
  322. $_ = toAnsi($_);
  323. if (/disk106/)
  324. {
  325. unicodeReadline(SRC);
  326. $line++;
  327. last A;
  328. }
  329. }
  330. # print replacement
  331. print DST $newtext;
  332. # if we passed toline, we have a conflict
  333. if ($line > $toline)
  334. {
  335. die "file relocation conflicts with manual edits (toline=$toline)";
  336. }
  337. }
  338. if ($line == $toline)
  339. {
  340. # this file changed in service pack
  341. s/^I\0I\0S\0_\0//; # remove prefix IIS_
  342. s/\0=\0\61\0/\0=\0\64\0/; # change source disk from cab to SP
  343. s/\0=\0\60\0/\0=\0\64\0/; # change source disk from gold to SP
  344. $toline = pop(@edits);
  345. }
  346. elsif (/,\0I\0I\0S\0_\0/)
  347. {
  348. # get file name after ,IIS_
  349. my $org = $_;
  350. $_ = toAnsi($_);
  351. # special case (sigh)
  352. # this is a hack. query.asp2 only exists in localized builds
  353. # server version of query.asp was not localized, but is
  354. # packaged in XP media regardless. the build script give them
  355. # two names and put them all in the media. we really want to
  356. # fix query.asp2 in those builds. same situation exists for
  357. # search.asp and default.asp - everything in iisdoc_files_ismcore_misc_shared
  358. #
  359. s/query.asp2/query.asp/;
  360. s/search.asp2/search.asp/;
  361. s/default.asp2/default.asp/;
  362. @comp = split /,IIS_([\w\d\.]+)\b/;
  363. if ($changefiles{$comp[1]})
  364. {
  365. $_ = toUnicode("$comp[0],$comp[1]$comp[2]");
  366. }
  367. else
  368. {
  369. $_ = $org;
  370. }
  371. }
  372. print DST $_;
  373. }
  374. close SRC;
  375. close DST;
  376. # binplace this file
  377. $target = $lang;
  378. $target = "." if $lang=~ /usa/i;
  379. system("echo iis.inf $target >bp.txt");
  380. system("binplace -p bp.txt iis.inf");
  381. # unlink("bp.txt");
  382. }