Leaked source code of windows server 2003
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.

1152 lines
31 KiB

  1. @echo off
  2. REM ------------------------------------------------------------------
  3. REM
  4. REM lgndata.cmd : (Engine of Language Neutral build)
  5. REM generate various control files to control the flow of Language Neutral build
  6. REM Files may be generated by this script
  7. REM $nttree\\build_logs\\LgNeutral\\lgnlist.txt -0
  8. REM $nttree\\build_logs\\LgNeutral\\lgntobuildlist.txt -g
  9. REM $nttree\\build_logs\\LgNeutral\\lgnbuildlist.txt -i
  10. REM $nttree\\build_logs\\LgNeutral\\lgnsnapt.txt -s
  11. REM $nttree\\build_logs\\LgNeutral\\lgncmflist.txt -m
  12. REM Copy RCBinary & Mofified Binary to $nttree -c
  13. REM Check the state of last LGNT build and recover the
  14. REM state terminated abnormally -v
  15. REM [Note] {RAZZLETOOLPATH} . "\\PostBuildScripts\\lgnexclude.txt contains the exclude list
  16. REM for Language Neutral
  17. REM
  18. REM You will see many places in pbuild.dat for this command.
  19. REM Language Neutral build support incremental build. It also can be restarted correctly from a
  20. REM abnormally terminated state.
  21. REM
  22. REM Copyright (c) Microsoft Corporation. All rights reserved.
  23. REM
  24. REM ------------------------------------------------------------------
  25. perl -x "%~f0" %*
  26. goto :EOF
  27. #!perl
  28. use strict;
  29. use File::Basename;
  30. use IO::File;
  31. use lib $ENV{RAZZLETOOLPATH} . "\\PostBuildScripts";
  32. use lib $ENV{RAZZLETOOLPATH};
  33. use PbuildEnv;
  34. use ParseArgs;
  35. use Logmsg;
  36. use cksku;
  37. use ReadSetupFiles;
  38. BEGIN {
  39. $ENV{SCRIPT_NAME} = 'lgndata.cmd';
  40. }
  41. sub Usage { print<<USAGE; exit(1) }
  42. lgndata [ -?] [-0] [-g] [-i] [-s] [-c]
  43. -0 generate lgnlist.txt which contains qualified binaries to be processed
  44. -g generate lgntobuildlist.txt which contains binaries to be processed
  45. -i generate lgnbuildlist.txt which contains list of LGN resource binaries
  46. -s do a snap shot from Ntreee\\ , for those files listed in PostBuildScripts\\ lgnlist.txt
  47. -c copy Modified bin and RC bin from nttree\\build_logs\\LgNeutra to nttree
  48. -v Verify if last build terminated correctly. If it's not the case, recover it.
  49. USAGE
  50. # Global variables
  51. my ($lang, $fCreateQualified,$fGenerate, $fInitial, $fSnap, $fCopy, $fVerify, $SnapFilePath, $fGenerateCMFList);
  52. my ( $Neutral_LogDir, $LGNToBuildList, $LGNBuildList, $LGNCMFList ,$LGNSnapt, $LGNSnapBak, $LGNExcludeList , $LGNList, $LGNStatus, $LGNTCopyLock );
  53. my( @FILE_LIST, $LogFilename );
  54. my( $TempDir, $TempDiffFile, $TempDiffFile1 );
  55. my( $CodeBinDir, $OrigBinDir, $RCBinDir, $CMFBinDir, $CodeBinPath, $OrigBinPath, $RCBinPath, $CMFBinPath );
  56. my( $nttree, $razpath, $TempDir);
  57. my ($STS_Freshs, $STS_OK, $STS_ToBuildList, $STS_BuildList, $STS_CMFList, $STS_Copy, $STS_RemoveRC, $STS_Unknown);
  58. my ($STS_CopyLock, $STS_CopyStart);
  59. my($fNeedGenerateCMF);
  60. $fGenerate =0;
  61. $fInitial =0;
  62. $fSnap =0;
  63. $fCopy =0;
  64. $fVerify =0;
  65. $fGenerateCMFList = 0;
  66. ##################
  67. #
  68. # parse command line
  69. #
  70. ##################
  71. parseargs( '?' => \&Usage,
  72. '0' => \$fCreateQualified,
  73. 'g' => \$fGenerate,
  74. 'i' => \$fInitial,
  75. 's' => \$fSnap,
  76. 'c' => \$fCopy,
  77. 'v' => \$fVerify,
  78. 'm' => \$fGenerateCMFList,
  79. 'l:' => \$lang,
  80. 'p:' => \$SnapFilePath
  81. );
  82. &Main();
  83. #
  84. # Check if Language Neutral is enabled or not
  85. #
  86. sub IsLGNActivated()
  87. {
  88. my ($MUI_MAGIC, $Result);
  89. $Result = 0;
  90. $MUI_MAGIC= $ENV{ "MUI_MAGIC" };
  91. if ( defined($MUI_MAGIC))
  92. {
  93. $Result=1;
  94. }
  95. return $Result
  96. }
  97. #
  98. # Check if we need generate CMF (Compact Resource File)
  99. #
  100. sub IsCMFActivated()
  101. {
  102. my ($MUI_MAGIC_CMF, $Result);
  103. $Result = 0;
  104. $MUI_MAGIC_CMF= $ENV{ "MUI_MAGIC_CMF" };
  105. if ( defined($MUI_MAGIC_CMF))
  106. {
  107. $Result=1;
  108. }
  109. return $Result
  110. }
  111. sub Main {
  112. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  113. # Begin Main code section
  114. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  115. # Return when you want to exit on error
  116. #
  117. my ($bUseDefault, $Path, $Mylang);
  118. if ( ! &IsLGNActivated())
  119. {
  120. return 0;
  121. }
  122. if ( ! defined($lang))
  123. {
  124. $lang = $ENV{LANG};
  125. if (! defined($lang))
  126. {
  127. $lang="usa";
  128. }
  129. }
  130. $Mylang="\L$lang";
  131. if ( $Mylang ne "usa")
  132. {
  133. return 0;
  134. }
  135. #
  136. # Should we generate CMF (Compact resource file ?)
  137. #
  138. $fNeedGenerateCMF=&IsCMFActivated();
  139. $Logmsg::DEBUG = 0; # set to 1 to activate logging of dbgmsg's
  140. $LogFilename = $ENV{ "LOGFILE" };
  141. if ( ! defined( $LogFilename ) )
  142. {
  143. $TempDir = $ENV{ "TMP" };
  144. $LogFilename = "$TempDir\\$0.log";
  145. }
  146. $CodeBinDir=$ENV{ "CodeBinDir" };
  147. if ( ! defined( $CodeBinDir) )
  148. {
  149. $CodeBinDir="CodeBin";
  150. }
  151. $RCBinDir=$ENV{ "RcBinDir" };
  152. if ( ! defined( $RCBinDir) )
  153. {
  154. $RCBinDir="RCBin";
  155. }
  156. $OrigBinDir=$ENV{ "OrigBinDir" };
  157. if ( ! defined( $OrigBinDir) )
  158. {
  159. $OrigBinDir="OrigBin";
  160. }
  161. $CMFBinDir=$ENV{ "CMFBinDir" };
  162. if ( ! defined( $CMFBinDir) )
  163. {
  164. $CMFBinDir="CMFBin";
  165. }
  166. timemsg( "Beginning ...");
  167. # set up paths to important files
  168. $nttree = $ENV{ "_NTPostBld" };
  169. $razpath= $ENV{ "RazzleToolPath" };
  170. $TempDir = $ENV{ "TMP" };
  171. $Neutral_LogDir = $nttree."\\build_logs\\LgNeutral";
  172. $LGNToBuildList = $Neutral_LogDir."\\lgntobuildlist.txt";
  173. $LGNBuildList = $Neutral_LogDir."\\lgnbuildlist.txt";
  174. $LGNCMFList = $Neutral_LogDir."\\lgncmflist.txt";
  175. $LGNSnapt = $Neutral_LogDir."\\lgnsnap.txt";
  176. $LGNSnapBak = $Neutral_LogDir."\\lgnsnap.txt.bak";
  177. $LGNExcludeList = $razpath."\\PostBuildScripts\\lgnexclude.txt";
  178. $LGNList = $Neutral_LogDir."\\lgnlist.txt";
  179. $LGNStatus = $Neutral_LogDir."\\lgnStatusLock.txt";
  180. $LGNTCopyLock = $Neutral_LogDir."\\lgnCopyLock.txt";
  181. $TempDiffFile = $Neutral_LogDir."\\lgbindiff.txt";
  182. $TempDiffFile1 = $Neutral_LogDir."\\lgbindiff1.txt";
  183. $OrigBinPath = "$Neutral_LogDir\\$OrigBinDir";
  184. $CodeBinPath ="$Neutral_LogDir\\$CodeBinDir";
  185. $RCBinPath ="$Neutral_LogDir\\$RCBinDir";
  186. $CMFBinPath ="$Neutral_LogDir\\$CMFBinDir";
  187. $STS_Freshs = "Fresh";
  188. $STS_OK = "OK";
  189. $STS_ToBuildList="ToBuildList";
  190. $STS_RemoveRC="RemoveRC";
  191. $STS_BuildList="BuildList";
  192. $STS_CMFList="CMFList";
  193. $STS_Copy="CopyBin";
  194. $STS_Unknown="Unknown";
  195. $STS_CopyLock ="CopyLock";
  196. $STS_CopyStart ="StartCopyBin";
  197. # Create three BIN folder if they are not exist
  198. unless( -d $Neutral_LogDir )
  199. {
  200. if (system("md $Neutral_LogDir") != 0)
  201. {
  202. errmsg("Fatal: $Neutral_LogDir doesn't exist");
  203. exit(1);
  204. }
  205. }
  206. unless ( -d $OrigBinPath)
  207. {
  208. if (system("md $OrigBinPath") != 0)
  209. {
  210. errmsg("Fatal: can't create $OrigBinPath");
  211. exit(1);
  212. }
  213. }
  214. unless ( -d $CodeBinPath)
  215. {
  216. if (system("md $CodeBinPath") != 0)
  217. {
  218. errmsg("Fatal: can't create CodeBinPath");
  219. exit(1);
  220. }
  221. }
  222. unless ( -d $RCBinPath)
  223. {
  224. if (system("md $RCBinPath") != 0)
  225. {
  226. errmsg("Fatal: can't create $RCBinPath");
  227. exit(1);
  228. }
  229. }
  230. unless ( -d $CMFBinPath)
  231. {
  232. if (system("md $CMFBinPath") != 0)
  233. {
  234. errmsg("Fatal: can't create $CMFBinPath");
  235. exit(1);
  236. }
  237. }
  238. if ($fCreateQualified)
  239. {
  240. if (! &CreateQualified())
  241. {
  242. errmsg("Generate $LGNList Failed");
  243. }
  244. }
  245. elsif ($fGenerate)
  246. {
  247. if (!&DoGenerateToBuildList())
  248. {
  249. errmsg("Generate $LGNToBuildList failed");
  250. }
  251. }
  252. elsif ( $fInitial)
  253. {
  254. if (!&DoGenerateBuildList())
  255. {
  256. errmsg("Generate $LGNBuildList failed");
  257. }
  258. }
  259. elsif ( $fGenerateCMFList)
  260. {
  261. if (!&DoGenerateCMFList())
  262. {
  263. errmsg("Generate $LGNCMFList failed");
  264. }
  265. }
  266. elsif ( $fSnap)
  267. {
  268. if (defined($SnapFilePath))
  269. {
  270. $bUseDefault=1;
  271. $Path = $SnapFilePath;
  272. }
  273. else
  274. {
  275. $bUseDefault = 0;
  276. $Path="Null";
  277. }
  278. if (!&DoGenerateSnap($bUseDefault,$Path))
  279. {
  280. errmsg("Generate $LGNSnapt failed");
  281. }
  282. }
  283. elsif ($fCopy)
  284. {
  285. if (! &DoCopyLGNBinary())
  286. {
  287. errmsg("Copy LGN binary failed");
  288. }
  289. }
  290. elsif ($fVerify)
  291. {
  292. #
  293. # Check the last state. If last build process terminated abnormally, recover it.
  294. #
  295. &DoVerify();
  296. }
  297. else
  298. {
  299. &Usage();
  300. }
  301. timemsg( "Finished." );
  302. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  303. # End Main code section
  304. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  305. }
  306. #
  307. # Check LGN's last status
  308. # LGN process should work/restart correctly from any interrupted state.
  309. # for example, operator cancels the execution of the script in the middle way, then restart.
  310. # Possible value in StatusLock
  311. # (0) Fresh
  312. # (1) ToBuildList
  313. # (2) BuildList
  314. # (3) CopyBin
  315. # (4) OK
  316. #
  317. sub GetLastStatus
  318. {
  319. my (@Bufs);
  320. if ( ! -e $LGNStatus )
  321. {
  322. return $STS_Freshs;
  323. }
  324. unless (open(INFILE, $LGNStatus))
  325. {
  326. errmsg("Fatal: can't open input for status file $LGNStatus");
  327. return $STS_Unknown;
  328. }
  329. @Bufs=<INFILE>;
  330. close(INFILE);
  331. chomp($Bufs[0]);
  332. logmsg("Current Status=$Bufs[0]");
  333. return $Bufs[0];
  334. }
  335. sub LogStatus
  336. {
  337. my ($TheStatus) = @_;
  338. my ($Result);
  339. $Result = 0;
  340. unless (open(OUTFILE, ">$LGNStatus"))
  341. {
  342. errmsg("Fatal: can't create status file $LGNStatus");
  343. return $Result;
  344. }
  345. print (OUTFILE "$TheStatus\n");
  346. close(OUTFILE);
  347. $Result = 1;
  348. return $Result;
  349. }
  350. #
  351. # Generate lgnlist.txt which contains qualified files to be processed
  352. #
  353. # Input : $nttree\\*.*
  354. # Input : {RAZZLETOOLPATH} . "\\PostBuildScripts\\lgnexclude.txt (Exclude List)
  355. # Output: $nttree\\build_logs\\LgNeutral\\lgnlist.txt
  356. #
  357. sub CreateQualified
  358. {
  359. my %FileTypeTbl = (
  360. ".exe" => 1,
  361. ".dll" => 1,
  362. ".cpl" => 1,
  363. ".ocx" => 1,
  364. ".tsp" => 1,
  365. ".scr" => 1,
  366. ".msc" => 1,
  367. );
  368. my ($Result, $Line, $Types, %ExcludeList, @Items);
  369. my(%DrvList);
  370. $Result = 0;
  371. #
  372. # Check for output
  373. #
  374. unless (open(OUTFILE,">$LGNList"))
  375. {
  376. errmsg("Can't open output: $LGNList");
  377. return $Result;
  378. }
  379. #
  380. # Check if exclude List exists
  381. #
  382. unless (open(INFILE,$LGNExcludeList))
  383. {
  384. errmsg("Can open Input: $LGNExcludeList");
  385. close(OUTFILE);
  386. return $Result;
  387. }
  388. #
  389. # Read Exclude List and build hashes
  390. #
  391. @Items =<INFILE>;
  392. close(INFILE);
  393. foreach $Line (@Items)
  394. {
  395. chomp($Line);
  396. $Line =~ s/\s//g;
  397. if (length($Line) == 0)
  398. {
  399. next;
  400. }
  401. if (substr($Line,0,1) eq ";")
  402. {
  403. next;
  404. }
  405. $Line="\L$Line";
  406. $ExcludeList{$Line}=1;
  407. }
  408. #
  409. # Read Driver List from different flavor
  410. #
  411. if (! &ReadDriverList(\%DrvList))
  412. {
  413. errmsg("Read Driver List Failed ");
  414. close(OUTFILE);
  415. return $Result;
  416. }
  417. #
  418. # Combine driver list to exclude list
  419. #
  420. foreach $Line (keys(%DrvList))
  421. {
  422. if ( ! defined($ExcludeList{$Line}) )
  423. {
  424. $ExcludeList{$Line}=1;
  425. }
  426. }
  427. #
  428. # Read Directory
  429. #
  430. unless (opendir(INDIR,$nttree))
  431. {
  432. errmsg("can't open $nttree !!");
  433. close(OUTFILE);
  434. return $Result;
  435. }
  436. @Items=readdir INDIR;
  437. foreach $Line (@Items)
  438. {
  439. if ( ($Line eq "." ) || ($Line eq "..") )
  440. {
  441. next;
  442. }
  443. if (length($Line) < 4)
  444. {
  445. next;
  446. }
  447. $Line="\L$Line";
  448. $Types = substr($Line,-4,4);
  449. if ( ! (defined ($FileTypeTbl{$Types}) ) )
  450. {
  451. next;
  452. }
  453. #
  454. # Not in the exclude List ?
  455. #
  456. if ( ! (defined ($ExcludeList{$Line} ) ) )
  457. {
  458. print (OUTFILE "$Line\n");
  459. }
  460. }
  461. close(OUTFILE);
  462. $Result = 1;
  463. return $Result;
  464. }
  465. #
  466. # Read Driver list from different flavor and build the array
  467. #
  468. sub ReadDriverList
  469. {
  470. my($pHashList) = @_;
  471. my ($BigDrvIndex, $PerDrvIndex, $BlaDrvIndex, $SbsDrvIndex, $SrvDrvIndex , $EntDrvIndex , $DtcDrvIndex);
  472. my ($Path_DrvIndex, $Result, $Flavor, $FilePath, $Line);
  473. my (@DrvIndexFiles, %CDDataSKUs,%INFPathSKUs);
  474. #
  475. # Do nothing at this moment
  476. #
  477. return 1;
  478. #
  479. # Get SKUs
  480. #
  481. %CDDataSKUs = map({uc$_ => cksku::CkSku($_, $lang, $ENV{_BuildArch})} qw(PRO PER SRV BLA SBS ADS DTC));
  482. #
  483. # Build DRiver INFs for SKUs
  484. #
  485. $BigDrvIndex = $nttree . "\\drvindex.inf";
  486. $PerDrvIndex = $nttree . "\\perinf\\drvindex.inf";
  487. $BlaDrvIndex= $nttree . "\\blainf\\drvindex.inf";
  488. $SbsDrvIndex = $nttree . "\\sbsinf\\drvindex.inf";
  489. $SrvDrvIndex = $nttree . "\\srvinf\\drvindex.inf";
  490. $EntDrvIndex = $nttree . "\\entinf\\drvindex.inf";
  491. $DtcDrvIndex= $nttree . "\\dtcinf\\drvindex.inf";
  492. # PRO
  493. $Path_DrvIndex =$BigDrvIndex;
  494. $INFPathSKUs{"PRO"} = [ ( $Path_DrvIndex) ];
  495. #PER
  496. $Path_DrvIndex =$PerDrvIndex;
  497. $INFPathSKUs{"PER"} = [ ($Path_DrvIndex ) ];
  498. #SRV
  499. $Path_DrvIndex =$SrvDrvIndex;
  500. $INFPathSKUs{"SRV"} = [ ($Path_DrvIndex) ];
  501. #BLA
  502. $Path_DrvIndex =$BlaDrvIndex;
  503. $INFPathSKUs{"BLA"} = [ ($Path_DrvIndex) ];
  504. #SBS
  505. $Path_DrvIndex =$SbsDrvIndex;
  506. $INFPathSKUs{"SBS"} = [ ($Path_DrvIndex) ];
  507. #ADS (ENT)
  508. $Path_DrvIndex =$EntDrvIndex;
  509. $INFPathSKUs{"ADS"} = [ ($Path_DrvIndex) ];
  510. #DTC
  511. $Path_DrvIndex =$DtcDrvIndex;
  512. $INFPathSKUs{"DTC"} = [ ($Path_DrvIndex) ];
  513. $Result = 0;
  514. foreach $Flavor (keys(%CDDataSKUs))
  515. {
  516. #if ( ! defined (INFPathSKUs{$Flavor})
  517. #{
  518. # errmsg("ReadDriverList:$Flavor not found in table");
  519. # return $Result;
  520. #}
  521. #($FilePath) = @{$INFPathSKUs{$Flavor}};
  522. if ( !ReadSetupFiles::ReadDrvIndex( $nttree, $Flavor, \@DrvIndexFiles) )
  523. {
  524. errmsg( "Error reading drvindex file, skipping $Flavor." );
  525. return $Result;
  526. }
  527. foreach $Line (@DrvIndexFiles)
  528. {
  529. if ( ! defined($$pHashList{$Line}) )
  530. {
  531. $$pHashList{$Line} = 1;
  532. }
  533. }
  534. }
  535. $Result=1;
  536. return $Result;
  537. }
  538. #
  539. # Generate the list from which binaries will be processed
  540. #
  541. sub DoGenerateToBuildList
  542. {
  543. my ($Fresh, $Result, $Line, $Path, @Bufs, @Diffs, $Item_no);
  544. my ($Path, $FilePath, $FileName, $Size, $Mtime, $LastStatus, $WindiffCommand);
  545. $Result = 0;
  546. $Item_no=0;
  547. #
  548. # Check last status
  549. #
  550. $LastStatus = GetLastStatus();
  551. if ( ($LastStatus ne $STS_Freshs ) && ($LastStatus ne $STS_OK) &&
  552. ($LastStatus ne $STS_Copy))
  553. {
  554. if ( -e $LGNToBuildList)
  555. {
  556. LogStatus($STS_ToBuildList);
  557. return 1;
  558. }
  559. }
  560. unless (open(INFILE, $LGNList))
  561. {
  562. errmsg("Fatal: can't open $LGNList");
  563. return $Result;
  564. }
  565. @Bufs=<INFILE>;
  566. close(INFILE);
  567. unless (open(OUTFILE, ">$LGNToBuildList"))
  568. {
  569. errmsg("Fatal: can't open output or $LGNToBuildList");
  570. return $Result;
  571. }
  572. $Fresh=0;
  573. if ( ! -e $LGNSnapt )
  574. {
  575. $Fresh=1;
  576. foreach $Line (@Bufs)
  577. {
  578. chomp($Line);
  579. $Line =~ s/\s//g;
  580. if (length($Line) == 0)
  581. {
  582. next;
  583. }
  584. $Path="$nttree\\$Line";
  585. if (-e $Path)
  586. {
  587. print (OUTFILE "$Line\n");
  588. $Item_no++;
  589. }
  590. }
  591. close(OUTFILE);
  592. }
  593. else
  594. #
  595. # Snap shot exists
  596. #
  597. {
  598. $Fresh=0;
  599. if (-e $LGNSnapt)
  600. {
  601. if (-e $LGNSnapBak)
  602. {
  603. if (system("del $LGNSnapBak") != 0)
  604. {
  605. errmsg("Fatal:Can't delete $LGNSnapBak");
  606. return $Result;
  607. }
  608. }
  609. ($FileName, $Path ) = fileparse($LGNSnapBak);
  610. if (system("ren $LGNSnapt $FileName") != 0)
  611. {
  612. errmsg("Fatal:Can't rename $LGNSnapt to $LGNSnapBak");
  613. return $Result;
  614. }
  615. }
  616. #
  617. # Create the snap files
  618. #
  619. if (! &CreateSnapFile($LGNSnapt,\@Bufs))
  620. {
  621. errmsg("Fatal:Create $LGNSnapt failed");
  622. return $Result;
  623. }
  624. system("windiff $LGNSnapBak $LGNSnapt -Fx $TempDiffFile");
  625. FilterWindiff($TempDiffFile,$TempDiffFile);
  626. #
  627. # Uniqify the $TempDiffFile
  628. #
  629. $WindiffCommand="perl $razpath\\PostBuildScripts\\unique.pl -i\:$TempDiffFile -o\:$TempDiffFile1";
  630. system("$WindiffCommand" );
  631. #
  632. # Now, Read $TempDiffFile1 and create $LGNToBuildList
  633. #
  634. unless (open(INFILE, $TempDiffFile1))
  635. {
  636. errmsg("can't open $TempDiffFile1");
  637. return $Result;
  638. }
  639. @Diffs=<INFILE>;
  640. close(INFILE);
  641. unless (open(OUTFILE, ">$LGNToBuildList"))
  642. {
  643. errmsg("Fatal: can't open output or $LGNToBuildList");
  644. return $Result;
  645. }
  646. foreach $Line (@Diffs)
  647. {
  648. chomp($Line);
  649. $Line =~ s/\s//g;
  650. if (length($Line) == 0)
  651. {
  652. next;
  653. }
  654. ($FilePath, $Size, $Mtime ) = split ( /,+/, $Line);
  655. chomp($FilePath);
  656. ($FileName, $Path ) = fileparse($FilePath);
  657. chomp($FileName);
  658. $FileName =~ s/\s//g;
  659. print (OUTFILE "$FileName\n");
  660. }
  661. close(OUTFILE);
  662. }
  663. $Result=1;
  664. #
  665. # Log the current state so that we may restart without problem
  666. #
  667. &LogStatus($STS_ToBuildList);
  668. return $Result;
  669. }
  670. #
  671. # Generate the list of binaries from which resource are move out.
  672. #
  673. sub DoGenerateBuildList
  674. {
  675. my ($Result, $Line, @FilesList, $FilePath, $CodePath, $Item_No);
  676. my($FileName, $Path);
  677. $Result = 0;
  678. unless (open(OUTFILE, ">$LGNBuildList"))
  679. {
  680. errmsg("Can't open output $LGNBuildList");
  681. return $Result;
  682. }
  683. if(!opendir(LOCBINDIR, $CodeBinPath))
  684. {
  685. errmsg ("Can't open $CodeBinPath");
  686. return $Result;
  687. }
  688. @FilesList = grep !/^\.\.?\z/ , readdir LOCBINDIR;
  689. $Item_No=scalar(@FilesList);
  690. logmsg("CodeBin total:$Item_No");
  691. close(LOCBINDIR);
  692. foreach $Line (@FilesList)
  693. {
  694. chomp($Line);
  695. $Line =~ s/\s//g;
  696. if (length($Line) == 0)
  697. {
  698. next;
  699. }
  700. ($FileName, $Path ) = fileparse($Line);
  701. #
  702. # Double check if corr. .mui file exists
  703. #
  704. $FilePath = "$RCBinPath\\$FileName.mui";
  705. $CodePath = "$CodeBinPath\\$FileName";
  706. if ( (-e $FilePath) && (-e $CodePath))
  707. {
  708. print (OUTFILE "$FileName\n");
  709. }
  710. else
  711. {
  712. errmsg("$Line exits but $FilePath / $CodePath is missed");
  713. }
  714. }
  715. close(OUTFILE);
  716. #
  717. # Log the current state so that we may restart without problem
  718. #
  719. &LogStatus($STS_BuildList);
  720. $Result = 1;
  721. return $Result;
  722. }
  723. #
  724. # Generate the list of CMF (Compact Resource file) which contain binaries, from which resource are move out.
  725. #
  726. sub DoGenerateCMFList
  727. {
  728. my ($Result, $Line, @FilesList, $FilePath, $Item_No);
  729. my($FileName, $Path);
  730. if ( ! $fNeedGenerateCMF)
  731. {
  732. return 1;
  733. }
  734. $Result = 0;
  735. unless (open(OUTFILE, ">$LGNCMFList"))
  736. {
  737. errmsg("Can't open output $LGNCMFList");
  738. return $Result;
  739. }
  740. if(!opendir(LOCBINDIR, $CMFBinPath))
  741. {
  742. errmsg ("Can't open $CMFBinPath");
  743. return $Result;
  744. }
  745. @FilesList = grep !/^\.\.?\z/ , readdir LOCBINDIR;
  746. $Item_No=scalar(@FilesList);
  747. logmsg("CMFBin total:$Item_No");
  748. close(LOCBINDIR);
  749. foreach $Line (@FilesList)
  750. {
  751. chomp($Line);
  752. $Line =~ s/\s//g;
  753. if (length($Line) == 0)
  754. {
  755. next;
  756. }
  757. ($FileName, $Path ) = fileparse($Line);
  758. #
  759. # Double check
  760. #
  761. $FilePath = "$CMFBinPath\\$FileName";
  762. if ( -e $FilePath)
  763. {
  764. print (OUTFILE "$FileName\n");
  765. }
  766. else
  767. {
  768. errmsg("$Line exits but $FilePath is missed");
  769. }
  770. }
  771. close(OUTFILE);
  772. #
  773. # Log the current state so that we may restart without problem
  774. #
  775. &LogStatus($STS_CMFList);
  776. $Result = 1;
  777. return $Result;
  778. }
  779. #
  780. # Copy Midified Binary and RC binary to $nttree
  781. #
  782. # Case: if $fNeedGenerateCMF is true, copy *.cmf from $CMFBinPath
  783. # else copy *.mui from $RCBinPath
  784. #
  785. sub DoCopyLGNBinary
  786. {
  787. my ($Result, $ErrCnt, $Line, @Bufs, @Bufs_CMF, $FilePathRC, $FilePathCode, $DestPath);
  788. $Result = 0;
  789. $ErrCnt=0;
  790. unless (open(INFILE, $LGNBuildList))
  791. {
  792. errmsg("fatal: DoCopyLGNBinary:: can't open input for $LGNBuildList");
  793. return $Result;
  794. }
  795. @Bufs=<INFILE>;
  796. close(INFILE);
  797. if ($fNeedGenerateCMF)
  798. {
  799. unless (open(INFILE, $LGNCMFList))
  800. {
  801. errmsg("fatal: DoCopyLGNBinary:: can't open input for $LGNCMFList");
  802. return $Result;
  803. }
  804. @Bufs_CMF=<INFILE>;
  805. close(INFILE);
  806. }
  807. #
  808. # Open a Status file to keep the state so that we may restart correctly
  809. #
  810. unless (open(OUTFILE, ">$LGNTCopyLock"))
  811. {
  812. errmsg("fatal: DoCopyLGNBinary:: can't open output for $LGNTCopyLock");
  813. return $Result;
  814. }
  815. print (OUTFIULE "$STS_CopyLock");
  816. close (OUTFILE);
  817. LogStatus($STS_CopyStart);
  818. foreach $Line (@Bufs)
  819. {
  820. chomp($Line);
  821. $Line =~ s/\s//g;
  822. if (length($Line) == 0)
  823. {
  824. next;
  825. }
  826. $FilePathRC = "$RCBinPath\\$Line.mui";
  827. $FilePathCode = "$CodeBinPath\\$Line";
  828. #
  829. # Copy RCBin only if CMF is not enabled
  830. #
  831. if ( ! $fNeedGenerateCMF)
  832. {
  833. $DestPath="$nttree\\$Line.mui";
  834. if ( system("copy/y $FilePathRC $DestPath") != 0)
  835. {
  836. $ErrCnt++;
  837. errmsg("DoCopyLGNBinary:: Can't copy $FilePathRC");
  838. }
  839. }
  840. $DestPath="$nttree\\$Line";
  841. if ( system("copy/y $FilePathCode $DestPath") != 0)
  842. {
  843. $ErrCnt++;
  844. errmsg("DoCopyLGNBinary:: Can't copy $FilePathCode");
  845. }
  846. }
  847. #
  848. # Copy CMF files if it's enabled
  849. #
  850. if ($fNeedGenerateCMF)
  851. {
  852. foreach $Line (@Bufs_CMF)
  853. {
  854. chomp($Line);
  855. $Line =~ s/\s//g;
  856. if (length($Line) == 0)
  857. {
  858. next;
  859. }
  860. $FilePathRC = "$CMFBinPath\\$Line";
  861. $DestPath="$nttree\\$Line";
  862. if ( system("copy/y $FilePathRC $DestPath") != 0)
  863. {
  864. $ErrCnt++;
  865. errmsg("DoCopyLGNBinary:: Can't copy $FilePathRC");
  866. }
  867. }
  868. }
  869. if ( $ErrCnt == 0)
  870. {
  871. $Result = 1;
  872. logmsg("DoCopyLGNBinary successfully");
  873. &LogStatus($STS_Copy);
  874. }
  875. else
  876. {
  877. errmsg("DoCopyLGNBinary got errors");
  878. }
  879. if (-e $LGNTCopyLock)
  880. {
  881. if ( system("del $LGNTCopyLock") != 0)
  882. {
  883. errmsg("Can't delete $LGNTCopyLock");
  884. }
  885. }
  886. return $Result;
  887. }
  888. sub DoVerify
  889. {
  890. #
  891. # Check if last operation terminated abnormally
  892. #
  893. if ( -e $LGNTCopyLock)
  894. {
  895. if ( GetLastStatus() eq $STS_CopyStart)
  896. {
  897. logmsg("Recover needed");
  898. DoCopyLGNBinary();
  899. DoGenerateSnap(0,"Null");
  900. logmsg("Recover completed");
  901. }
  902. if (system("del $LGNTCopyLock") != 0)
  903. {
  904. errmsg("Recover: can't delete $LGNTCopyLock");
  905. }
  906. }
  907. return 1;
  908. }
  909. #
  910. # Generate Snap File
  911. # This routine will be called through pbuild table when the last step of language neutral build is
  912. # executed. Keep a snap of last state will help us to support incremental build.
  913. #
  914. sub DoGenerateSnap
  915. {
  916. my ($bUseDefault, $AltFilePath) = @_;
  917. my ($Result, @Bufs, $FilePath, $FileName, $Path);
  918. $Result = 0;
  919. #
  920. # Backup previous Snap file
  921. #
  922. if ( ! $bUseDefault)
  923. {
  924. if (-e $LGNSnapBak)
  925. {
  926. if (system("del $LGNSnapBak") != 0)
  927. {
  928. errmsg("Fatal:Can't delete $LGNSnapBak");
  929. return $Result;
  930. }
  931. ($FileName, $Path ) = fileparse($LGNSnapBak);
  932. if (system("ren $LGNSnapt $FileName") != 0)
  933. {
  934. errmsg("Fatal:Can't rename $LGNSnapt to $LGNSnapBak");
  935. return $Result;
  936. }
  937. }
  938. $FilePath = $LGNSnapt;
  939. }
  940. else
  941. {
  942. $FilePath = $AltFilePath;
  943. }
  944. unless (open(INFILE, $LGNList))
  945. {
  946. errmsg("Fatal: can't open $LGNList");
  947. return $Result;
  948. }
  949. @Bufs=<INFILE>;
  950. close(INFILE);
  951. #
  952. # Create the snap files
  953. #
  954. if (! &CreateSnapFile($FilePath,\@Bufs))
  955. {
  956. errmsg("Fatal:Create $FilePath failed");
  957. return $Result;
  958. }
  959. $Result=1;
  960. return $Result;
  961. }
  962. #
  963. # Generate Snap File
  964. #
  965. # Snap File contains File size and last modification date for the binaries in $nttree
  966. #
  967. sub CreateSnapFile
  968. {
  969. my ($OutputPath, $pItemsList) = @_;
  970. my ($Line, $Result, $FilePath);
  971. my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks);
  972. $Result = 0;
  973. unless (open(OUTFILE, ">$OutputPath"))
  974. {
  975. errmsg("Can't open output $FilePath to generate Snap file");
  976. return $Result;
  977. }
  978. foreach $Line ( @$pItemsList )
  979. {
  980. chomp($Line);
  981. $Line =~ s/\s//g;
  982. if (length($Line) == 0)
  983. {
  984. next;
  985. }
  986. $FilePath = "$nttree\\$Line";
  987. #
  988. # Get the file status by using stat function
  989. #
  990. if (-e $FilePath)
  991. {
  992. ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime,
  993. $ctime, $blksize, $blocks ) = stat( $FilePath );
  994. #
  995. # Snap File contains File size and last modification date
  996. #
  997. print( OUTFILE "$FilePath , $size , $mtime\n" );
  998. }
  999. }
  1000. close( OUTFILE );
  1001. $Result =1;
  1002. return $Result;
  1003. }
  1004. #
  1005. # Filter for output of windiff
  1006. # The output of windiff is the comparison of current Snap and previous Snap file
  1007. # We'll understand which Binaries are changed.
  1008. # We use this approach to support Language Neutral Incremental build.
  1009. #
  1010. sub FilterWindiff
  1011. {
  1012. my ($InputFile,$OutputFile) = @_;
  1013. my ($Result, @InfileLines, $Line, $FileName, $Junk );
  1014. $Result = 0;
  1015. unless ( open( INFILE, $InputFile ) )
  1016. {
  1017. errmsg( "Fatal:Failed to open '$InputFile' for reading" );
  1018. return $Result;
  1019. }
  1020. @InfileLines = <INFILE>;
  1021. close( INFILE );
  1022. unless ( open( OUTFILE, ">$OutputFile" ) )
  1023. {
  1024. errmsg( "Fatal:Failed to open '$OutputFile' for writing" );
  1025. return $Result;
  1026. }
  1027. #
  1028. # now parse out the interesting lines from windiff
  1029. #
  1030. foreach $Line ( @InfileLines )
  1031. {
  1032. chomp( $Line );
  1033. if ( $Line =~ /\-\- / )
  1034. {
  1035. next;
  1036. }
  1037. ( $Junk, $Junk, $FileName, $Junk ) = split( /\s+/, $Line );
  1038. print( OUTFILE "$FileName\n" );
  1039. }
  1040. close( OUTFILE );
  1041. $Result = 1;
  1042. return $Result;
  1043. }