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.

641 lines
17 KiB

  1. #!perl -w
  2. #
  3. # A tool to create boot floppy images.
  4. #
  5. # Author: Milong Sabandith (milongs)
  6. #
  7. ##############################################################################
  8. use lib $ENV{RAZZLETOOLPATH} . "\\PostBuildScripts";
  9. use lib $ENV{RAZZLETOOLPATH};
  10. use PbuildEnv;
  11. use ParseArgs;
  12. use cksku;
  13. use ReadSetupFiles;
  14. use Logmsg;
  15. sub Usage { print<<USAGE; exit(1) }
  16. Create Boot Floppy Images.
  17. Usage: $0 share
  18. Example:
  19. $0 d:\i386
  20. USAGE
  21. $MakeZdr = 1;
  22. $ErrorCode = 0;
  23. # List of files that need to be on last floppy
  24. @lastlist = ("ntdll.dll", "usetup.exe", "spcmdcon.sys", "kbdus.dll");
  25. # List of replacement destinations. Use "" for the same name as in @lastlist
  26. @lastrepl = ("system32\\ntdll.dll", "system32\\smss.exe", "","");
  27. # List of files that need to be on a particular floppy
  28. # txtsetup.sif is special because it needs to be compressed.
  29. @speciallist = ("setupldr.bin", "txtsetup.sif", "biosinfo.inf", "ntdetect.com", "ntkrnlmp.exe");
  30. @specialnum = ("1", "1", "1", "1", "2");
  31. # List of files that should come from somewhere else
  32. @differentlist = ("setupreg.hiv");
  33. @differentsource = ("..\\idw\\setup\\no_tbomb.hiv");
  34. sub onlastdisk {
  35. local($filename) = @_;
  36. while (<@lastlist>) {
  37. if ($filename =~ /^$_$/ ) {
  38. return 1;
  39. }
  40. }
  41. return 0;
  42. }
  43. sub GetFromInf {
  44. local( $filename, $section, $name, $num) = @_;
  45. $retvalue = "";
  46. open( INFFILE, "<".$filename) or die "can't open $filename: $!";
  47. LINEG: while( <INFFILE>) {
  48. chomp $_;
  49. $line = lc $_;
  50. if ($line =~ /^\[/)
  51. {
  52. $InSection = 0;
  53. }
  54. if ($line =~ /^\[$section/)
  55. {
  56. $InSection = 1;
  57. next LINEG;
  58. }
  59. if (! $InSection)
  60. {
  61. next LINEG;
  62. }
  63. @linefields = split('=', $line);
  64. # empty line
  65. if ( $#linefields == -1) {
  66. next LINEG;
  67. }
  68. $nameg = $linefields[0];
  69. #print "nameg = " . $#linefields . $nameg . "\n";
  70. if( length( $nameg) < 1)
  71. {
  72. next LINEG;
  73. }
  74. $nameg =~ s/ *$//g;
  75. if ( not ($nameg =~ /$name/)) {
  76. next LINEG;
  77. }
  78. @linefields2 = split(',', $linefields[1]);
  79. $retvalue = $linefields2[$num];
  80. # Remove spaces
  81. $retvalue =~ s/ *$//g;
  82. $retvalue =~ s/^ *//g;
  83. if( length( $retvalue) > 0) {
  84. last LINEG;
  85. }
  86. } # while (there is still data in this inputfile)
  87. close( INFFILE);
  88. return $retvalue;
  89. }
  90. sub myprocess {
  91. local($shareloc) = @_;
  92. $output = "bootfiles";
  93. $layout = $shareloc . "\\layout.inf";
  94. $dosnet = $shareloc . "\\dosnet.inf";
  95. $txtsetup = $shareloc . "\\txtsetup.sif";
  96. $allfiles = $output.".all";
  97. $modified = $output.".mod";
  98. $enum = $output.".enum";
  99. $total = $output.".total";
  100. $final = $output.".final";
  101. $languageid = "00000409";
  102. if ($MakeZdr == 1) {
  103. $txtsetup = "..\\realsign\\txtsetup.sif";
  104. }
  105. print "Share location: " . $shareloc . "\n\n";
  106. print "Finding layout.inf at: " . $layout . "\n";
  107. open(OLD, "<" . $layout) or die "can't open $layout: $!";
  108. open(NEW, ">" . $allfiles) or die "can't open $allfiles: $!";
  109. # Read txtsetup.sif for required language id.
  110. $languageid = GetFromInf( $txtsetup, "nls", "defaultlayout", 0);
  111. if ( length($languageid) < 1) {
  112. print "Could not determine DefaultLayout from txtsetup.sif.\n";
  113. return 0;
  114. }
  115. print "Lanuage Id = " . $languageid ."\n";
  116. $keyboardfile = GetFromInf( $txtsetup, "files.keyboardlayout", $languageid, 0);
  117. if ( length($languageid) < 1) {
  118. print "Could not determine keyboard file from txtsetup.sif.\n";
  119. return 0;
  120. }
  121. print "Keyboard file = " . $keyboardfile ."\n";
  122. # Make sure it's not us keyboad since this is already in our last list.
  123. if (not ($keyboardfile =~ /^kbdus.dll$/ )) {
  124. push( @lastlist, $keyboardfile);
  125. push( @lastrepl, $keyboardfile);
  126. }
  127. # Compress txtsetup.sif locally
  128. (print "\nCopying $txtsetup for compression.\n");
  129. `dcomp $txtsetup .`;
  130. # Read dosnet.inf for .fon and .nls boot files
  131. print "Finding dosnet.inf at: " . $dosnet . "\n";
  132. open(DOSNET, "<" . $dosnet) or die "can't open $dosnet: $!";
  133. $InFloppySection = 0;
  134. $disknum = "-";
  135. print "\nAdding the following font and nls files to disk3.\n";
  136. LINE1: while( <DOSNET> ) {
  137. chomp $_;
  138. $line = lc $_;
  139. if ($line =~ /^\[/)
  140. {
  141. $InFloppySection = 0;
  142. }
  143. if ($line =~ /^\[floppyfiles\./)
  144. {
  145. $InFloppySection = 1;
  146. $line2 = $line;
  147. chop $line2;
  148. @linefields= split('\.', $line2);
  149. $disknum = $linefields[1];
  150. next LINE1;
  151. }
  152. if (! $InFloppySection)
  153. {
  154. next LINE1;
  155. }
  156. if ( $line =~ /^d1\,disk1\,disk/) {
  157. next LINE1;
  158. }
  159. if ($line =~ /^d1\,/)
  160. {
  161. @linefields = split(',', $line);
  162. $filename = $linefields[1];
  163. #Remove spaces from filesname
  164. $filename =~ s/ *$//g;
  165. #Skip .fon and .nls files since they are included in dosnet.txt
  166. if ($filename !~ /\.fon$/ and $filename !~ /\.nls$/)
  167. {
  168. next LINE1;
  169. }
  170. $filenamep = $shareloc. "\\".$filename;
  171. $filename2 = $filename;
  172. if (!(-e $filenamep) ) {
  173. chop $filenamep;
  174. $filenamep = $filenamep . "_";
  175. chop $filename2;
  176. $filename2 = $filename2 . "_";
  177. }
  178. if (-e $filenamep ) {
  179. ($0,$0,$0,$0,$0,$0,$0,$size,$0,$0,$0,$0,$0) = stat($filenamep);
  180. (printf "%20s %10s", " " . $filename, $size . "\n");
  181. (printf NEW "%2s %20s %10s %20s\n", 3, " " . $filename, $size, $filename2);
  182. }
  183. }
  184. } # while (there is still data in this inputfile)
  185. close(DOSNET);
  186. $InFileSection = 0;
  187. $maxdisknum = 1;
  188. # Now add files from layout.inf
  189. LINE2: while( <OLD> )
  190. {
  191. chomp $_;
  192. $line = lc $_;
  193. if ($line =~ /^\[/)
  194. {
  195. $InFileSection = 0;
  196. }
  197. if ($line eq "[sourcedisksfiles]" or $line eq "[sourcedisksfiles.x86]")
  198. {
  199. $InFileSection = 1;
  200. next LINE2;
  201. }
  202. if (! $InFileSection)
  203. {
  204. next LINE2;
  205. }
  206. if ($line =~ /=/)
  207. {
  208. ($filename = $line) =~ s/(.*:)?(\S*.?\S*)\s*=.*/$2/;
  209. #Remove spaces from filesname
  210. $filename =~ s/ *$//g;
  211. #Skip .fon and .nls files since they are included in dosnet.txt
  212. if ($filename =~ /\.fon$/ or $filename =~ /\.nls$/)
  213. {
  214. next LINE2;
  215. }
  216. ($fields = $line) =~ s/.*=\s*(.*)/$1/;
  217. @linefields = split(',', $fields);
  218. $disknum = $linefields[6];
  219. if ($disknum =~ /^_/)
  220. {
  221. $compressed = 0;
  222. }
  223. else
  224. {
  225. $compressed = 1;
  226. }
  227. $disknum =~ s/_//;
  228. if( length($disknum) > 0 && $disknum !~ /x/)
  229. {
  230. if( int($disknum) > $maxdisknum)
  231. {
  232. $maxdisknum = int($disknum);
  233. }
  234. $filename2 = $filename;
  235. if( $compressed)
  236. {
  237. chop $filename2;
  238. $filename2 = $filename2 . "_";
  239. }
  240. $filenamep = "$shareloc\\$filename2";
  241. if (-e $filenamep ) {
  242. ($0,$0,$0,$0,$0,$0,$0,$size,$0,$0,$0,$0,$0) = stat($filenamep);
  243. }
  244. else {
  245. $size = "0";
  246. }
  247. (printf NEW "%2s %20s %10s %20s\n", $disknum, " " . $filename, $size , $filename2);
  248. print ".";
  249. }
  250. }
  251. } # while (there is still data in this inputfile)
  252. close(OLD) or die "can't close $layout: $!";
  253. close(NEW) or die "can't close $allfiles: $!";
  254. #Remove from the list any files on the first or last flopy.
  255. open(OLD, "<" . $allfiles) or die "can't open $allfiles: $!";
  256. open(NEW, ">" . $modified) or die "can't open $modified: $!";
  257. $disknum = 0;
  258. $disksize = 0;
  259. NLINE:while (<OLD>) {
  260. $save = $_;
  261. @lnfields = split(' ', $_);
  262. $filename = $lnfields[1];
  263. while (<@speciallist>) {
  264. if ($filename =~ /^$_$/ ) {
  265. next NLINE;
  266. }
  267. }
  268. while (<@lastlist>) {
  269. if ($filename =~ /^$_$/ ) {
  270. next NLINE;
  271. }
  272. }
  273. (print NEW $save);
  274. print ".";
  275. }
  276. #Put the following files on the first floppy
  277. #On FE build, if bootfont.bin exist then add it to the first floppy
  278. $fname = "bootfont.bin";
  279. $fname2 = "$shareloc\\$fname";
  280. if (-e $fname2 ) {
  281. ($0,$0,$0,$0,$0,$0,$0,$size,$0,$0,$0,$0,$0) = stat($fname2);
  282. (printf NEW "%2s %20s %10s %20s\n", 1, " " . $fname, $size, $fname);
  283. }
  284. $count = 0;
  285. while (<@speciallist>) {
  286. $fname = $_;
  287. if ($fname =~ /^txtsetup.sif$/ ) {
  288. chop $fname;
  289. $fname = $fname . "_";
  290. if (-e $fname ) {
  291. ($0,$0,$0,$0,$0,$0,$0,$size,$0,$0,$0,$0,$0) = stat($fname);
  292. }
  293. else {
  294. $size = "0";
  295. }
  296. }
  297. else {
  298. $fname2 = "$shareloc\\$fname";
  299. if (-e $fname2 ) {
  300. ($0,$0,$0,$0,$0,$0,$0,$size,$0,$0,$0,$0,$0) = stat($fname2);
  301. }
  302. else {
  303. chop $fname2;
  304. $fname2 = $fname2 . "_";
  305. if (-e $fname2 ) {
  306. chop $fname;
  307. $fname = $fname . "_";
  308. ($0,$0,$0,$0,$0,$0,$0,$size,$0,$0,$0,$0,$0) = stat($fname2);
  309. }
  310. else {
  311. $size = "0";
  312. }
  313. }
  314. }
  315. (printf NEW "%2s %20s %10s %20s\n", $specialnum[$count], " " . $_,$size ,$fname);
  316. $count = ($count +1);
  317. print ".";
  318. }
  319. #Put the following files on the last floppy
  320. $count = 0;
  321. while (<@lastlist>) {
  322. $fname = $_;
  323. $fname2 = "$shareloc\\$fname";
  324. if (-e $fname2 ) {
  325. ($0,$0,$0,$0,$0,$0,$0,$size,$0,$0,$0,$0,$0) = stat($fname2);
  326. }
  327. else {
  328. chop $fname2;
  329. $fname2 = $fname2 . "_";
  330. if (-e $fname2) {
  331. chop $fname;
  332. $fname = $fname . "_";
  333. ($0,$0,$0,$0,$0,$0,$0,$size,$0,$0,$0,$0,$0) = stat($fname2);
  334. }
  335. else {
  336. $size = "0";
  337. }
  338. }
  339. (printf NEW "%2s %20s %10s %20s\n", ($maxdisknum+1), " " . $_, $size, $fname);
  340. $count = ($count +1);
  341. print ".";
  342. }
  343. close(OLD) or die "can't close $old: $!";
  344. close(NEW) or die "can't close $new: $!";
  345. `sort $modified /o $modified`;
  346. # Reenumerate disk numbers in case all the files on the last in layout.inf
  347. # appears in our private list.
  348. open(OLD, "<" . $modified) or die "can't open $modified: $!";
  349. open(NEW, ">" . $enum) or die "can't open $enum: $!";
  350. $donefixup = 0;
  351. $disksize = 0;
  352. $maxdisknum = 1;
  353. while (<OLD>) {
  354. $save = $_;
  355. @lnfields = split(' ', $_);
  356. $cdisk = int($lnfields[0]);
  357. $fname = $lnfields[1];
  358. $fsize = $lnfields[2];
  359. $fact = $lnfields[3];
  360. if( !$donefixup and $cdisk > $maxdisknum)
  361. {
  362. $maxdisknum = $maxdisknum +1;
  363. if( $maxdisknum != $cdisk) {
  364. $donefixup = 1;
  365. }
  366. }
  367. (printf NEW "%2d %20s %10s %20s\n",$maxdisknum,$fname,$fsize,$fact);
  368. }
  369. close(OLD) or die "can't close $old: $!";
  370. close(NEW) or die "can't close $new: $!";
  371. # Create total file containing total disk sizes.
  372. open(OLD, "<" . $enum) or die "can't open $enum: $!";
  373. open(NEW, ">" . $total) or die "can't open $total: $!";
  374. $disknum = 0;
  375. $disksize = 0;
  376. $runningtotal = 0;
  377. while (<OLD>) {
  378. $save = $_;
  379. @lnfields = split(' ', $_);
  380. $cdisk = int($lnfields[0]);
  381. $sdisk = int($lnfields[2]);
  382. if( $cdisk == $disknum)
  383. {
  384. $disksize = $disksize + $sdisk;
  385. }
  386. else
  387. {
  388. if( $disknum != 0)
  389. {
  390. (printf NEW "%10s %24s", "Disk " . $disknum . ":", $disksize . "\n\n");
  391. }
  392. $disknum = $cdisk;
  393. $runningtotal = $runningtotal + $disksize;
  394. $disksize = $sdisk;
  395. }
  396. (print NEW $save);
  397. print ".";
  398. }
  399. if( $disknum != 0)
  400. {
  401. $runningtotal = $runningtotal + $disksize;
  402. (printf NEW "%10s %24s", "Disk " . $disknum . ":", $disksize . "\n");
  403. (printf NEW "Total :%24s", $runningtotal . "\n");
  404. }
  405. close(OLD) or die "can't close $old: $!";
  406. close(NEW) or die "can't close $new: $!";
  407. # Create boot floppies.
  408. # Create disk1 to be renamed accordingly for each floppy
  409. open(NEW, ">disk1") or die "Could not create disk1 file in current directory!";
  410. print NEW "\n";
  411. close NEW;
  412. # Now create list of files for each floppy
  413. open(OLD, "<" . $enum) or die "can't open $enum: $!";
  414. $disknum = 0;
  415. while (<OLD>) {
  416. @lnfields = split(' ', $_);
  417. $cdisk = int($lnfields[0]);
  418. $fname = $lnfields[1];
  419. $fact = $lnfields[3];
  420. if( $cdisk != $disknum)
  421. {
  422. if( $disknum > 0) {
  423. close( NEW);
  424. }
  425. open(NEW, ">" . $output . "\." . $cdisk) or die "can't open $: $!";
  426. # first floppy require the following information
  427. if( $cdisk == 1) {
  428. (printf NEW "\-bnt35setup\n");
  429. }
  430. (printf NEW "disk1=disk10%d\n", $cdisk);
  431. $disknum = $cdisk;
  432. }
  433. $source = $shareloc."\\".$fact;
  434. $dest = $fact;
  435. #check if this file should have a different source location
  436. if ($MakeZdr == 1) {
  437. $icount = 0;
  438. $done = 0;
  439. while (<@differentlist>) {
  440. if ($done == 0) {
  441. $save = $_;
  442. if ($fname =~ /^$_$/) {
  443. $source = $differentsource[$icount];
  444. $done = 1;
  445. }
  446. $icount = ($icount + 1);
  447. }
  448. }
  449. }
  450. $icount = 0;
  451. #if the last disk, then final name of file maybe different
  452. if( $disknum == ($maxdisknum)) {
  453. $done = 0;
  454. while (<@lastlist>) {
  455. if ($done == 0) {
  456. $save = $_;
  457. if ($fname =~ /^$_$/ and length($lastrepl[$icount]) > 0) {
  458. $dest = $lastrepl[$icount];
  459. $done = 1;
  460. }
  461. $icount = ($icount + 1);
  462. }
  463. }
  464. }
  465. else {
  466. if ($fname =~ /^txtsetup.sif$/ ) {
  467. $dest = "txtsetup\.si_";
  468. $source = "txtsetup\.si_";
  469. }
  470. }
  471. #For el use english version of usetup since el version is too big.
  472. if( ($disknum == ($maxdisknum)) && (lc $ENV{lang} eq "el") && ($fact =~ /^usetup.exe$/)) {
  473. $source = $ENV{_NTFILTER}."\\".$fact;
  474. }
  475. (printf NEW "%s=%s\n", $source, $dest);
  476. print ".";
  477. }
  478. close(OLD) or die "can't close $old: $!";
  479. close(NEW) or die "can't close $new: $!";
  480. # Creating each floppy
  481. $disknum = 1;
  482. while ( $disknum <= $maxdisknum) {
  483. $fname2 = "cdboot".$disknum."\.img";
  484. $fcmdline = "\nfcopy \-f \-3 \@$output" . "\." . $disknum . " cdboot" . $disknum . "\.img";
  485. print $fcmdline;
  486. print "\nCreating cdimage" . $disknum . "\.img";
  487. $message = `$fcmdline`;
  488. print $message;
  489. if (not -e $fname2 ) {
  490. errmsg("Could not create boot floppy $disknum!");
  491. $ErrorCode = 1;
  492. }
  493. $disknum = $disknum +1;
  494. }
  495. # Create equivalent dosnet floppyfiles sections
  496. open(OLD, "<" . $enum) or die "can't open $enum: $!";
  497. open(NEW, ">" . $final) or die "can't open $final: $!";
  498. $disknum = 0;
  499. while (<OLD>) {
  500. @lnfields = split(' ', $_);
  501. $cdisk = int($lnfields[0]);
  502. $fname = $lnfields[1];
  503. if( $cdisk != $disknum)
  504. {
  505. (printf NEW "\n[FloppyFiles.%d]\n", $disknum);
  506. (printf NEW "d1,disk1,disk10%d\n", ($disknum+1));
  507. $disknum = $cdisk;
  508. }
  509. $icount = 0;
  510. if( $disknum == ($maxdisknum)) {
  511. $done = 0;
  512. while (<@lastlist>) {
  513. if ($done == 0) {
  514. $save = $_;
  515. if ($fname =~ /^$_$/ and length($lastrepl[$icount]) > 0 ) {
  516. $fname = $fname."\,".$lastrepl[$icount];
  517. $done = 1;
  518. }
  519. $icount = ($icount + 1);
  520. }
  521. }
  522. }
  523. (printf NEW "d1,%s\n", $fname);
  524. print ".";
  525. }
  526. close(OLD) or die "can't close $old: $!";
  527. close(NEW) or die "can't close $new: $!";
  528. print "\nTotal floppies is " . $maxdisknum . "\n";
  529. }
  530. foreach $share (@ARGV) {
  531. #print "arg is $file\n";
  532. #@filelist = <$file>;
  533. #@filelist = `dir /b /a-d $file`;
  534. foreach (@ARGV) {
  535. chomp $share;
  536. myprocess( $share);
  537. }
  538. exit($ErrorCode);
  539. }