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.

1783 lines
54 KiB

  1. @echo off
  2. REM ------------------------------------------------------------------
  3. REM
  4. REM cddata.cmd
  5. REM Reads inf files and generates file lists for postbuild
  6. REM
  7. REM Copyright (c) Microsoft Corporation. All rights reserved.
  8. REM
  9. REM ------------------------------------------------------------------
  10. perl -x "%~f0" %*
  11. goto :EOF
  12. #!perl
  13. use strict;
  14. use File::Basename;
  15. use IO::File;
  16. use lib $ENV{RAZZLETOOLPATH} . "\\PostBuildScripts";
  17. use lib $ENV{RAZZLETOOLPATH};
  18. use PbuildEnv;
  19. use ParseArgs;
  20. use Logmsg;
  21. use cksku;
  22. use A2U;
  23. BEGIN {
  24. # A2u is setting itself as the script_name
  25. $ENV{SCRIPT_NAME} = 'cddata.cmd';
  26. }
  27. sub Usage { print<<USAGE; exit(1) }
  28. cddata [-f] [-c] [-d] [-x] [-g <search>] [-o <filename>] [-l <language>]
  29. -f Force list generation -- don't read old list
  30. -c Create CDFs
  31. -d Create CD lists (compression lists, link lists)
  32. -t Create exTension lists
  33. -x Don't truncate against bindiff file
  34. -g <search> Print to STDOUT or <Filename> the results
  35. of a search on the given input (see below)
  36. -o <filename> Send search output to the given filename
  37. -n Make dosnet checks
  38. For the search command, valid expressions are:
  39. Field=xxx Return entries whose "Field" is exactly xxx
  40. Field?yyy Return entries whose "Field" contains yyy
  41. Field!zzz Return entries whose "Field" does not contain zzz
  42. Field1=xxx:Field2=yyy logically 'and's results
  43. Field names can be found in the keylist file
  44. USAGE
  45. # avoid search and replace for now, new template sets lang in the env.
  46. my $lang = $ENV{lang};
  47. # global switches/values set on the command line
  48. my ($ForceCreate, $CreateCDFs, $CreateLists, $CreateExtLists, $NoUseBindiff,
  49. $ArgSearchList, $OutputFile, $MakeDosnetChecks);
  50. parseargs('?' => \&Usage,
  51. 'f' => \$ForceCreate,
  52. 'c' => \$CreateCDFs,
  53. 'd' => \$CreateLists,
  54. 'x' => \$NoUseBindiff,
  55. 't' => \$CreateExtLists,
  56. 'g:'=> \$ArgSearchList,
  57. 'o:'=> \$OutputFile,
  58. 'n' => \$MakeDosnetChecks);
  59. # Global variables
  60. my( $LogFilename );
  61. my( $TempDir );
  62. my( $Argument, $KeyFileName, $i );
  63. my( $nttree, $razpath );
  64. my( $BigDosnet, $PerDosnet, $BlaDosnet, $SbsDosnet, $SrvDosnet, $EntDosnet, $DtcDosnet );
  65. my( $BigDrvIndex, $PerDrvIndex, $BlaDrvIndex, $SbsDrvIndex, $SrvDrvIndex, $EntDrvIndex, $DtcDrvIndex );
  66. my( $BigExc, $PerExc, $BlaExc, $SbsExc, $SrvExc, $EntExc, $DtcExc, $Media, $DrmTxt );
  67. my( $Excludes, $Specsign, $Subdirs, $Layout, $LayoutTXT );
  68. my( $BigPrint, $BldArch, $AmX86 );
  69. my( @StructFields, $NumFields, %FieldLocations, @StructDefaults );
  70. my( $DefaultSettings, $Default, @KeyListLines, %Hash, $KeyListLine );
  71. my( $KeyValues, @TheseSettings, $CurSet, $Key, @PrinterFiles, %Drmfiles );
  72. my( $Printer, $FieldName, @SearchPatterns, $SOperator, $SFieldName );
  73. my( $SFlagValue, $SearchHitCount, $FoundFlag, $SearchPattern );
  74. my( $BinDiffFile, $KeyFileName2, $IncFlag, $RootCdfDir);
  75. my( %CopyLocations );
  76. my( %CDDataSKUs );
  77. my( @ConvertList );
  78. my (%TabHash);
  79. # call into the Main sub, too much indentation to make this
  80. # toplevel right now
  81. &Main();
  82. sub Main {
  83. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  84. # Begin Main code section
  85. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  86. # Return when you want to exit on error
  87. # <Implement your code here>
  88. $Logmsg::DEBUG = 0; # set to 1 to activate logging of dbgmsg's
  89. $LogFilename = $ENV{ "LOGFILE" };
  90. if ( ! defined( $LogFilename ) ) {
  91. $TempDir = $ENV{ "TMP" };
  92. $LogFilename = "$TempDir\\$0.log";
  93. }
  94. timemsg( "Beginning ...", $LogFilename );
  95. $KeyFileName = "cddata.txt";
  96. # set up paths to important files
  97. $nttree = $ENV{ "_NTPostBld" };
  98. $razpath= $ENV{ "RazzleToolPath" };
  99. $TempDir = $ENV{ "TMP" };
  100. $BigDosnet = $nttree . "\\dosnet.inf";
  101. $PerDosnet = $nttree . "\\perinf\\dosnet.inf";
  102. $BlaDosnet = $nttree . "\\blainf\\dosnet.inf";
  103. $SbsDosnet = $nttree . "\\sbsinf\\dosnet.inf";
  104. $SrvDosnet = $nttree . "\\srvinf\\dosnet.inf";
  105. $EntDosnet = $nttree . "\\entinf\\dosnet.inf";
  106. $DtcDosnet = $nttree . "\\dtcinf\\dosnet.inf";
  107. $BigDrvIndex = $nttree . "\\drvindex.inf";
  108. $PerDrvIndex = $nttree . "\\perinf\\drvindex.inf";
  109. $BlaDrvIndex = $nttree . "\\blainf\\drvindex.inf";
  110. $SbsDrvIndex = $nttree . "\\sbsinf\\drvindex.inf";
  111. $SrvDrvIndex = $nttree . "\\srvinf\\drvindex.inf";
  112. $EntDrvIndex = $nttree . "\\entinf\\drvindex.inf";
  113. $DtcDrvIndex = $nttree . "\\dtcinf\\drvindex.inf";
  114. $BigExc = $nttree . "\\excdosnt.inf";
  115. $PerExc = $nttree . "\\perinf\\excdosnt.inf";
  116. $BlaExc = $nttree . "\\blainf\\excdosnt.inf";
  117. $SbsExc = $nttree . "\\sbsinf\\excdosnt.inf";
  118. $SrvExc = $nttree . "\\srvinf\\excdosnt.inf";
  119. $EntExc = $nttree . "\\entinf\\excdosnt.inf";
  120. $DtcExc = $nttree . "\\dtcinf\\excdosnt.inf";
  121. $Media = $nttree . "\\congeal\_scripts\\\_media.inx";
  122. $DrmTxt = $nttree . "\\congeal\_scripts\\drmlist.txt";
  123. $Excludes = $razpath . "\\PostBuildScripts\\exclude.lst";
  124. $Specsign = $razpath . "\\PostBuildScripts\\specsign.lst";
  125. $Subdirs = $razpath . "\\PostBuildScripts\\subdirs.lst";
  126. $Layout = $nttree . "\\congeal\_scripts\\layout.inx";
  127. $LayoutTXT = $nttree . "\\congeal\_scripts\\layout.txt";
  128. $BinDiffFile = $nttree . "\\build\_logs\\bindiff.txt";
  129. $RootCdfDir = "$TempDir\\CDFs";
  130. %CDDataSKUs = map({uc$_ => cksku::CkSku($_, $lang, $ENV{_BuildArch})} qw(PRO PER SRV BLA SBS ADS DTC));
  131. # Remove the RootCdfDir
  132. system ( "if exist $RootCdfDir rd /s /q $RootCdfDir" );
  133. # Set IncFlag to false until we know otherwise
  134. $IncFlag = "FALSE";
  135. $BigPrint = $nttree . "\\ntprint.inf";
  136. $BldArch = $ENV{ "\_BuildArch" };
  137. undef( $AmX86 );
  138. if ( ( $BldArch =~ /x86/i ) || ( $BldArch =~ /amd64/i ) || ( $BldArch =~ /ia64/i ) ) {
  139. $AmX86 = "TRUE";
  140. }
  141. # enumerate fields
  142. # Signed -- am i catalog signed?
  143. # Prods -- what prods am i in? any combo in order of w, p, s, e, d
  144. # Driver -- am i in driver.cab? i.e., did i come from an excdosnt?
  145. # Comp -- do i get compress by default?
  146. # Print -- am i a printer?
  147. # Dosnet -- did i come from a dosnet?
  148. # Unicode -- do i get converted to unicode?
  149. # DrvIndex -- which drivercab am i in? i.e. w p s e d
  150. # DrmLevel -- am i drm encrypted?
  151. # Tablet -- am i a Tablet PC File
  152. #
  153. # also, see default settings for each of these fields just below.
  154. @StructFields = ( "Signed", "Prods", "Driver", "Comp", "Print", "Dosnet",
  155. "Unicode", "DrvIndex", "DRMLevel" ,"TabletPC"); # CHANGEME
  156. $NumFields = @StructFields;
  157. %FieldLocations = {};
  158. for ( $i = 0; $i < $NumFields; $i++ ) {
  159. $FieldLocations{ $StructFields[ $i ] } = $i;
  160. }
  161. # create defaults
  162. @StructDefaults = ( "t", "nul", "f", "t", "f", "f", "f",
  163. "nul", "f" ,"f"); # CHANGEME
  164. undef( $DefaultSettings );
  165. foreach $Default ( @StructDefaults ) {
  166. if ( defined( $DefaultSettings ) ) {
  167. $DefaultSettings .= "\:$Default";
  168. }
  169. else { $DefaultSettings = $Default; }
  170. }
  171. # see if we've already made our lists. if so, don't regen them.
  172. if ( ( ! ( defined( $ForceCreate ) ) ) &&
  173. ( -e "$TempDir\\$KeyFileName" ) ) {
  174. logmsg( "Reading previously created key list ...",
  175. $LogFilename );
  176. # read in the list instead of creating it
  177. unless ( open( INFILE, "$TempDir\\$KeyFileName" ) ) {
  178. errmsg( "Failed to parse old keylist.txt.",
  179. $LogFilename );
  180. exit( 1 );
  181. }
  182. @KeyListLines = <INFILE>;
  183. close( INFILE );
  184. undef( %Hash );
  185. foreach $KeyListLine ( @KeyListLines ) {
  186. chomp( $KeyListLine );
  187. if ( ( length( $KeyListLine ) == 0 ) ||
  188. ( substr( $KeyListLine, 0, 1 ) eq ";" ) ) { next; }
  189. # <filename> = a:bbbb:c:d:e:f
  190. $KeyListLine =~ /^(\S*)( = )(\S*)$/;
  191. $KeyFileName2 = $1; $KeyValues = $3;
  192. @TheseSettings = split( /\:/, $KeyValues );
  193. undef( $CurSet );
  194. for ( $i = 0; $i < $NumFields; $i++ ) {
  195. if ( defined( $CurSet ) ) {
  196. $CurSet .= ":$StructFields[$i]\=$TheseSettings[$i]";
  197. } else {
  198. $CurSet = "$StructFields[$i]\=$TheseSettings[$i]";
  199. }
  200. }
  201. &NewSettings( $KeyFileName2, $CurSet );
  202. }
  203. if ( -e $BinDiffFile ) { &HandleDiffFiles(); }
  204. if ( defined( $MakeDosnetChecks ) ) {
  205. &CheckDosnet( $BigDosnet );# if ( $CDDataSKUs{'PRO'});
  206. &CheckDosnet( $PerDosnet );# if ( $CDDataSKUs{'PER'});
  207. &CheckDosnet( $SrvDosnet );# if ( $CDDataSKUs{'SRV'});
  208. &CheckDosnet( $BlaDosnet );# if ( $CDDataSKUs{'BLA'});
  209. &CheckDosnet( $SbsDosnet );# if ( $CDDataSKUs{'SBS'});
  210. &CheckDosnet( $EntDosnet );# if ( $CDDataSKUs{'ADS'});
  211. &CheckDosnet( $DtcDosnet );# if ( $CDDataSKUs{'DTC'});
  212. }
  213. logmsg( "Writing keylist to $KeyFileName ...", $LogFilename );
  214. unless ( open( OUTFILE, ">$TempDir\\$KeyFileName" ) ) {
  215. errmsg( "Failed to open $KeyFileName for writing.",
  216. $LogFilename );
  217. exit( 1 );
  218. }
  219. print( OUTFILE "; Fields are listed as follows:\n; " );
  220. foreach $FieldName ( @StructFields ) {
  221. print( OUTFILE " $FieldName" );
  222. }
  223. print( OUTFILE "\n" );
  224. foreach $Key ( keys( %Hash ) ) {
  225. print( OUTFILE "$Key = $Hash{ $Key }\n" );
  226. }
  227. close( OUTFILE );
  228. } else {
  229. # begin!
  230. undef( %Hash );
  231. undef( %CopyLocations );
  232. # Need to get these for all flavors as
  233. # this is a cumulative thing DTC = ADS + SRV + PRO
  234. &AddDosnet( $BigDosnet, "Prods+w:Dosnet=t" );
  235. &AddDosnet( $PerDosnet, "Prods+p:Dosnet=t" );
  236. &AddDosnet( $SrvDosnet, "Prods+s:Dosnet=t" );
  237. &AddDosnet( $BlaDosnet, "Prods+b:Dosnet=t" );
  238. &AddDosnet( $SbsDosnet, "Prods+l:Dosnet=t" );
  239. &AddDosnet( $EntDosnet, "Prods+e:Dosnet=t" );
  240. &AddDosnet( $DtcDosnet, "Prods+d:Dosnet=t" );
  241. # EXCDOSNT is built during postbuild, only for
  242. # required flavors -- note that AddDosnet() in this
  243. # case is actually "removing" files from dosnet
  244. # (marking them as Dosnet=f and Comp=f")
  245. &AddDosnet( $BigExc, "Driver=t:Prods+w:Dosnet=f:Comp=f" ) if ( $CDDataSKUs{'PRO'});
  246. &AddDosnet( $PerExc, "Driver=t:Prods+p:Dosnet=f:Comp=f" ) if ( $CDDataSKUs{'PER'});
  247. &AddDosnet( $SrvExc, "Driver=t:Prods+s:Dosnet=f:Comp=f" ) if ( $CDDataSKUs{'SRV'});
  248. &AddDosnet( $BlaExc, "Driver=t:Prods+b:Dosnet=f:Comp=f" ) if ( $CDDataSKUs{'BLA'});
  249. &AddDosnet( $SbsExc, "Driver=t:Prods+l:Dosnet=f:Comp=f" ) if ( $CDDataSKUs{'SBS'});
  250. &AddDosnet( $EntExc, "Driver=t:Prods+e:Dosnet=f:Comp=f" ) if ( $CDDataSKUs{'ADS'});
  251. &AddDosnet( $DtcExc, "Driver=t:Prods+d:Dosnet=f:Comp=f" ) if ( $CDDataSKUs{'DTC'});
  252. &AddDosnet( $Media, "Prods=wpsbled" );
  253. # now add specsign.lst files and subdirs.lst files
  254. &AddSpecsign( $Specsign );
  255. &AddSubdirs( $Subdirs );
  256. # at this point, we have all files from dosnet's excdosnt's and _media
  257. # now, if a key is in sedinf dir, add a listing for sedinf\key
  258. logmsg( "Adding keys for files in perinf, blainf, sbsinf, srvinf, entinf, dtcinf ...", $LogFilename );
  259. foreach $Key ( keys( %Hash ) ) {
  260. $Key = "\L$Key";
  261. if ( -e "$nttree\\dtcinf\\$Key" ) {
  262. $Hash{ "dtcinf\\$Key" } = $Hash{ $Key };
  263. &ChangeSettings( "dtcinf\\$Key", "Prods-w:Prods-p:Prods-s:Prods-e:Prods-b:Prods-l" );
  264. if ( &GetFlag( "dtcinf\\$Key", "Prods" ) eq "nul" ) {
  265. delete( $Hash{ "dtcinf\\$Key" } );
  266. }
  267. if ( defined( $Hash{ $Key } ) ) {
  268. &ChangeSettings( $Key, "Prods-d" );
  269. }
  270. }
  271. if ( -e "$nttree\\entinf\\$Key" ) {
  272. $Hash{ "entinf\\$Key" } = $Hash{ $Key };
  273. &ChangeSettings( "entinf\\$Key", "Prods-w:Prods-p:Prods-s:Prods-b:Prods-l" );
  274. if ( &GetFlag( "entinf\\$Key", "Prods" ) eq "nul" ) {
  275. delete( $Hash{ "entinf\\$Key" } );
  276. }
  277. if ( defined( $Hash{ $Key } ) ) {
  278. &ChangeSettings( $Key, "Prods-e:Prods-d" );
  279. }
  280. if ( &GetFlag( $Key, "Prods" ) eq "nul" ) { delete( $Hash{ $Key } ); }
  281. }
  282. if ( -e "$nttree\\blainf\\$Key" ) {
  283. $Hash{ "blainf\\$Key" } = $Hash{ $Key };
  284. &ChangeSettings( "blainf\\$Key", "Prods-w:Prods-p:Prods-s:Prods-e:Prods-d:Prods-l" );
  285. if ( &GetFlag( "blainf\\$Key", "Prods" ) eq "nul" ) {
  286. delete( $Hash{ "blainf\\$Key" } );
  287. }
  288. if ( defined( $Hash{ $Key } ) ) {
  289. &ChangeSettings( $Key, "Prods-b" );
  290. }
  291. }
  292. if ( -e "$nttree\\sbsinf\\$Key" ) {
  293. $Hash{ "sbsinf\\$Key" } = $Hash{ $Key };
  294. &ChangeSettings( "sbsinf\\$Key", "Prods-w:Prods-p:Prods-s:Prods-e:Prods-d:Prods-b" );
  295. if ( &GetFlag( "sbsinf\\$Key", "Prods" ) eq "nul" ) {
  296. delete( $Hash{ "sbsinf\\$Key" } );
  297. }
  298. if ( defined( $Hash{ $Key } ) ) {
  299. &ChangeSettings( $Key, "Prods-l" );
  300. }
  301. }
  302. if ( -e "$nttree\\srvinf\\$Key" ) {
  303. $Hash{ "srvinf\\$Key" } = $Hash{ $Key };
  304. &ChangeSettings( "srvinf\\$Key", "Prods-w:Prods-p" );
  305. if ( &GetFlag( "srvinf\\$Key", "Prods" ) eq "nul" ) {
  306. delete( $Hash{ "srvinf\\$Key" } );
  307. }
  308. if ( defined( $Hash{ $Key } ) ) {
  309. &ChangeSettings( $Key, "Prods-l:Prods-b:Prods-s:Prods-e:Prods-d" );
  310. }
  311. }
  312. if ( -e "$nttree\\perinf\\$Key" ) {
  313. $Hash{ "perinf\\$Key" } = $Hash{ $Key };
  314. &ChangeSettings( "perinf\\$Key", "Prods-w:Prods-s:Prods-b:Prods-l" );
  315. if ( &GetFlag( "perinf\\$Key", "Prods" ) eq "nul" ) {
  316. delete( $Hash{ "perinf\\$Key" } );
  317. }
  318. if ( defined( $Hash{ $Key } ) ) {
  319. &ChangeSettings( $Key, "Prods-p" );
  320. }
  321. }
  322. if ( &GetFlag( $Key, "Prods" ) eq "nul" ) {
  323. delete( $Hash{ $Key } );
  324. }
  325. }
  326. # mark all driver files
  327. if ( $CDDataSKUs{ 'PRO' } ) {
  328. &AddDrvIndex( $BigDrvIndex, "DrvIndex+w", "pro" );
  329. }
  330. if ( $CDDataSKUs{ 'PER' } ) {
  331. &AddDrvIndex( $PerDrvIndex, "DrvIndex+p", "per" );
  332. }
  333. if ( $CDDataSKUs{ 'SRV' } ) {
  334. &AddDrvIndex( $SrvDrvIndex, "DrvIndex+s", "srv" );
  335. }
  336. if ( $CDDataSKUs{ 'BLA' } ) {
  337. &AddDrvIndex( $BlaDrvIndex, "DrvIndex+b", "bla" );
  338. }
  339. if ( $CDDataSKUs{ 'SBS' } ) {
  340. &AddDrvIndex( $SbsDrvIndex, "DrvIndex+l", "sbs" );
  341. }
  342. if ( $CDDataSKUs{ 'ADS' } ) {
  343. &AddDrvIndex( $EntDrvIndex, "DrvIndex+e", "ads" );
  344. }
  345. if ( $CDDataSKUs{ 'DTC' } ) {
  346. &AddDrvIndex( $DtcDrvIndex, "DrvIndex+d", "dtc" );
  347. }
  348. &SpecialExclusions();
  349. # mark all printer keys
  350. timemsg( "Marking all printer entries ...", $LogFilename );
  351. # @PrinterFiles = `infflist.exe $BigPrint`;
  352. # the GetPrinterFiles subroutine will populate the @PrinterFiles array
  353. # in the same manner that calling infflist.exe would.
  354. &GetPrinterFiles( $BigPrint );
  355. foreach $Printer ( @PrinterFiles ) {
  356. chomp( $Printer );
  357. if ( length( $Printer ) == 0 ) { next; }
  358. &ChangeSettings( $Printer, "Print=t" );
  359. }
  360. # Get the list of files to convert to unicode.
  361. @ConvertList = &A2U::CdDataUpdate;
  362. foreach my $convertfile ( @ConvertList ) {
  363. &ChangeSettings( $convertfile, "Unicode=t" );
  364. }
  365. #
  366. # Get the list of files with DRMLevel attributes
  367. #
  368. undef(%Drmfiles);
  369. &GetDrmFiles( \%Drmfiles, $DrmTxt );
  370. foreach $Key ( sort keys %Drmfiles )
  371. {
  372. chomp $Key;
  373. if( length( $Key ) == 0 ) { next; }
  374. &ChangeSettings( $Key, "DRMLevel=$Drmfiles{$Key}" );
  375. }
  376. # mark all uncompressable keys
  377. timemsg( "Marking all uncompressable entries ...",
  378. $LogFilename );
  379. &MarkUncomps( $Layout );
  380. &MarkUncomps( $Media );
  381. &MarkUncomps( $LayoutTXT );
  382. # mark all unsigned keys and remove non-existent key/files:
  383. # unsigned files are printers, *.cat, and things in exclude.lst
  384. &ExcludeSigning( $Excludes ); # must be done after subdirs.lst !!!
  385. logmsg( "Marking all unsignable entries ...", $LogFilename );
  386. foreach $Key ( keys( %Hash ) ) {
  387. if ( ( ! ( -e "$nttree\\$Key" ) ) &&
  388. ( substr( $Key, -4, 4 ) ne ".cat" ) ) {
  389. delete( $Hash{ $Key } );
  390. }
  391. elsif ( ( &GetFlag( $Key, "Print" ) eq "t" ) ||
  392. ( substr( $Key, -4, 4 ) eq ".cat" ) ) {
  393. &ChangeSettings( $Key, "Signed=f" );
  394. }
  395. }
  396. # save off a copy of the full key file for bindiff.pl to cue off of
  397. if ( ( ! ( -e "$TempDir\\$KeyFileName.full" ) ) ||
  398. ( defined( $ForceCreate ) ) ) {
  399. logmsg( "Writing keylist to $KeyFileName.full ...",
  400. $LogFilename );
  401. unless ( open( OUTFILE, ">$TempDir\\$KeyFileName.full" ) ) {
  402. errmsg( "Failed to open $KeyFileName.full for " .
  403. "writing.", $LogFilename );
  404. exit( 1 );
  405. }
  406. print( OUTFILE "; Fields are listed as follows:\n; " );
  407. foreach $FieldName ( @StructFields ) {
  408. print( OUTFILE " $FieldName" );
  409. }
  410. print( OUTFILE "\n" );
  411. foreach $Key ( keys( %Hash ) ) {
  412. print( OUTFILE "$Key = $Hash{ $Key }\n" );
  413. }
  414. }
  415. close( OUTFILE );
  416. if ( -e "$TempDir\\$KeyFileName.full" ) {
  417. system( "copy $TempDir\\$KeyFileName.full $nttree\\build_logs" .
  418. "\\$KeyFileName.full" );
  419. }
  420. if ( -e $BinDiffFile ) { &HandleDiffFiles(); }
  421. # at this point, we'll check our dosnets if asked.
  422. if ( defined( $MakeDosnetChecks ) ) {
  423. &CheckDosnet( $BigDosnet );
  424. &CheckDosnet( $PerDosnet );
  425. &CheckDosnet( $BlaDosnet );
  426. &CheckDosnet( $SbsDosnet );
  427. &CheckDosnet( $SrvDosnet );
  428. &CheckDosnet( $EntDosnet );
  429. &CheckDosnet( $DtcDosnet );
  430. }
  431. # jeezuz! we're done!
  432. if ( ( ! ( -e "$TempDir\\$KeyFileName" ) ) ||
  433. ( defined( $ForceCreate ) ) ) {
  434. logmsg( "Writing keylist to $KeyFileName ...",
  435. $LogFilename );
  436. unless ( open( OUTFILE, ">$TempDir\\$KeyFileName" ) ) {
  437. errmsg( "Failed to open $KeyFileName for writing.",
  438. $LogFilename );
  439. exit( 1 );
  440. }
  441. print( OUTFILE "; Fields are listed as follows:\n; " );
  442. foreach $FieldName ( @StructFields ) {
  443. print( OUTFILE " $FieldName" );
  444. }
  445. print( OUTFILE "\n" );
  446. foreach $Key ( keys( %Hash ) ) {
  447. print( OUTFILE "$Key = $Hash{ $Key }\n" );
  448. }
  449. }
  450. close( OUTFILE );
  451. }
  452. if ( defined( $ArgSearchList ) ) {
  453. logmsg( "Search pattern is \'$ArgSearchList\' ...",
  454. $LogFilename );
  455. # user has asked to see a search on the hash
  456. if ( defined( $OutputFile ) ) {
  457. if ( open( OUTFILE, ">$OutputFile" ) ) {
  458. print( OUTFILE "; Results for search $ArgSearchList\n" );
  459. } else {
  460. errmsg( "Failed to open $OutputFile for writing.",
  461. $LogFilename );
  462. undef( $OutputFile );
  463. }
  464. }
  465. @SearchPatterns = split( /\:/, $ArgSearchList );
  466. $SearchHitCount = 0;
  467. foreach $Key ( keys( %Hash ) ) {
  468. $FoundFlag = "TRUE";
  469. foreach $SearchPattern ( @SearchPatterns ) {
  470. $SearchPattern =~ /^(\S*)([\=\?\!])(\S*)$/;
  471. $SOperator = $2;
  472. $SFieldName = $1; $SFlagValue = $3;
  473. if ( ( $SOperator eq "\=" ) &&
  474. ( &GetFlag( $Key, $SFieldName ) ne $SFlagValue ) ) {
  475. $FoundFlag = "FALSE";
  476. } elsif ( ( $SOperator eq "\?" ) &&
  477. ( &GetFlag( $Key, $SFieldName ) !~
  478. /$SFlagValue/ ) ) {
  479. $FoundFlag = "FALSE";
  480. } elsif ( ( $SOperator eq "\!" ) &&
  481. ( &GetFlag( $Key, $SFieldName ) =~
  482. /\Q$SFlagValue\E/ ) ) {
  483. $FoundFlag = "FALSE";
  484. } # matches if
  485. } # matches foreach
  486. if ( $FoundFlag eq "TRUE" ) {
  487. $SearchHitCount++;
  488. if ( defined( $OutputFile ) ) {
  489. print( OUTFILE "$Key = " . $Hash{ $Key } . "\n" );
  490. } else {
  491. print( "$Key = " . $Hash{ $Key } . "\n" );
  492. }
  493. }
  494. }
  495. if ( defined( $OutputFile ) ) { close( OUTFILE ); }
  496. logmsg( "Files found: $SearchHitCount" );
  497. }
  498. # now we can generate cdfs and any other lists we need
  499. &MakeLists();
  500. # Generate extension lists for rebase/rebind
  501. MakeExtensionLists() if ($IncFlag eq "FALSE" || defined $CreateExtLists);
  502. timemsg( "Finished.", $LogFilename );
  503. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  504. # End Main code section
  505. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  506. }
  507. # <Implement your subs here>
  508. sub AddDosnet
  509. {
  510. my( $DosnetName, $StructSettings ) = @_;
  511. my( $File, @Files, $FileName,$Key );
  512. my( $FileSpec, @FileSpecs, $ThisProd );
  513. logmsg( "Adding files in $DosnetName ...", $LogFilename );
  514. @Files = &ReadDosnet( $DosnetName );
  515. unless ( defined( @Files ) ) {
  516. errmsg( "Can't add $DosnetName files to hash.",
  517. $LogFilename );
  518. return( undef );
  519. }
  520. foreach $File ( @Files ) {
  521. chomp( $File );
  522. if ( length( $File ) == 0 ) { next; }
  523. $File = "\L$File";
  524. if ( defined( $Hash{ $File } ) ) {
  525. &ChangeSettings( $File, $StructSettings );
  526. } else {
  527. &NewSettings( $File, $StructSettings );
  528. }
  529. }
  530. if (%TabHash) {
  531. foreach $Key ( keys(%TabHash) ) {
  532. &ChangeSettings( $Key,"TabletPC=t" );
  533. }
  534. }
  535. return( "TRUE" );
  536. }
  537. sub ReadDosnet
  538. {
  539. my( $DosnetName ) = @_;
  540. my( $File, @Files, @Lines, $Line, $ReadFlag,$TabFlag, $ExtraStuff );
  541. my( $MyName, $Junk, $CopyLocation );
  542. $File = "\L$File";
  543. unless ( open( INFILE, $DosnetName ) ) {
  544. errmsg( "Failed to open $DosnetName", $LogFilename );
  545. return( undef );
  546. }
  547. @Lines = <INFILE>;
  548. close( INFILE );
  549. undef( @Files );
  550. $ReadFlag = "FALSE";
  551. undef (%TabHash);
  552. foreach $Line ( @Lines ) {
  553. chomp( $Line );
  554. if ( ( length( $Line ) == 0 ) ||
  555. ( substr( $Line, 0, 1 ) eq ";" ) ||
  556. ( substr( $Line, 0, 1 ) eq "#" ) ||
  557. ( substr( $Line, 0, 2 ) eq "@*" ) ) { next; }
  558. if ( $Line =~ /^\[/ ) { $ReadFlag = "FALSE"; }
  559. if ( ( $Line =~ /^\[Files\]/ ) ||
  560. ( $Line =~ /^\[SourceDisksFiles\]/ ) ) {
  561. $ReadFlag = "TRUE";
  562. } elsif ( ( $AmX86 eq "TRUE" ) &&
  563. ( $Line =~ /^\[SourceDisksFiles\.x86\]/ ) ) {
  564. $ReadFlag = "TRUE";
  565. } elsif ( ( $BldArch =~ /amd64/i ) &&
  566. ( $Line =~ /^\[SourceDisksFiles\.amd64\]/ ) ) {
  567. $ReadFlag = "TRUE";
  568. } elsif ( ( $BldArch =~ /ia64/i ) &&
  569. ( $Line =~ /^\[SourceDisksFiles\.ia64\]/ ) ) {
  570. $ReadFlag = "TRUE";
  571. }
  572. if ( $ReadFlag eq "TRUE" ) {
  573. if ($Line =~ /^d2/) {
  574. $TabFlag="TRUE";
  575. }
  576. $Line =~ s/^d1\,//;
  577. $Line =~ s/^d2\,//;
  578. ( $MyName, $CopyLocation ) = split( /\,/, $Line );
  579. ( $MyName, $Junk ) = split( /\s/, $MyName );
  580. push( @Files, $MyName );
  581. if ($TabFlag eq "TRUE") {
  582. $TabHash{$MyName}="TRUE";
  583. $TabFlag="FALSE";
  584. }
  585. }
  586. }
  587. return( @Files );
  588. }
  589. sub ChangeSettings
  590. {
  591. my( $File, $StructSettings ) = @_;
  592. my( @Requests, $Request );
  593. my( @Currents, $Current, $NewSettings );
  594. my( $FldLoc, $Operator, $SetVal );
  595. if ( length( $File ) == 0 ) { return( undef ); }
  596. $File = "\L$File";
  597. if ( ! ( defined( $Hash{ $File } ) ) ) { return( undef ); }
  598. @Currents = split( /\:/, $Hash{ $File } );
  599. @Requests = split( /\:/, $StructSettings );
  600. foreach $Request ( @Requests ) {
  601. $Request =~ /^(\w+)([\=\+\-]{1})(\w+)$/;
  602. $FldLoc = $FieldLocations{ $1 };
  603. $Operator = $2; $SetVal = $3;
  604. # look for a "="
  605. if ( $Operator eq "\?" ) { next; }
  606. if ( $Operator eq "\=" ) {
  607. # set the field explicitly
  608. $Currents[ $FldLoc ] = $SetVal;
  609. }
  610. # look for a "+"
  611. elsif ( $Operator eq "\+" ) {
  612. # add the field to the list if not there
  613. if ( $Currents[ $FldLoc ] eq "nul" ) {
  614. $Currents[ $FldLoc ] = $SetVal;
  615. } elsif ( ! ( $Currents[ $FldLoc ] =~ /$SetVal/ ) ) {
  616. $Currents[ $FldLoc ] .= $SetVal;
  617. }
  618. }
  619. # look for a "-"
  620. elsif ( ( $Operator eq "\-" ) && ( $Currents[ $FldLoc ] ne "nul" ) ) {
  621. # sub the field from the list if there
  622. $Currents[ $FldLoc ] =~ s/$SetVal//;
  623. if ( $Currents[ $FldLoc ] eq "" ) {
  624. $Currents[ $FldLoc ] = "nul";
  625. }
  626. }
  627. }
  628. # make a string from @Currents
  629. undef( $NewSettings );
  630. foreach $Current ( @Currents ) {
  631. if ( defined( $NewSettings ) ) { $NewSettings .= "\:$Current"; }
  632. else { $NewSettings = $Current; }
  633. }
  634. $Hash{ $File } = $NewSettings;
  635. return( "TRUE" );
  636. }
  637. sub NewSettings
  638. {
  639. my( $File, $StructSettings ) = @_;
  640. my( $DefaultString, $Default );
  641. $File = "\L$File";
  642. # use defaults for everything not in $StructSettings
  643. undef( $DefaultString );
  644. foreach $Default ( @StructDefaults ) {
  645. if ( defined( $DefaultString ) ) { $DefaultString .= "\:$Default"; }
  646. else { $DefaultString = $Default; }
  647. }
  648. $Hash{ $File } = $DefaultString;
  649. $StructSettings =~ s/\?/\=/g;
  650. &ChangeSettings( $File, $StructSettings );
  651. return( "TRUE" );
  652. }
  653. sub AddSpecsign
  654. {
  655. my( $SpecFile ) = @_;
  656. my( @SpecLines, $Line );
  657. logmsg( "Adding files in $SpecFile ...", $LogFilename );
  658. unless ( open( INFILE, $SpecFile ) ) {
  659. errmsg( "Failed to open $SpecFile.", $LogFilename );
  660. return( undef );
  661. }
  662. @SpecLines = <INFILE>;
  663. close( INFILE );
  664. foreach $Line ( @SpecLines ) {
  665. chomp( $Line );
  666. if ( ( length( $Line ) == 0 ) ||
  667. ( substr( $Line, 0, 1 ) eq ";" ) ) { next; }
  668. # add file with defaults to hash
  669. $Line = "\L$Line";
  670. if ( exists( $Hash{ $Line } ) ) {
  671. &ChangeSettings( $Line, "Prods=wpsbled:Signed=t" );
  672. } else {
  673. &NewSettings( $Line, "Prods=wpsbled:Signed=t:Comp=f" );
  674. }
  675. }
  676. return( "TRUE" );
  677. }
  678. sub AddSubdirs
  679. {
  680. my( $SubdirsFile ) = @_;
  681. my( @DirsLines, $Line, $SubName );
  682. my( $DirName, $IsRecursive, @DirList, $TreeLen );
  683. logmsg( "Adding files in $SubdirsFile ...", $LogFilename );
  684. unless ( open( INFILE, $SubdirsFile ) ) {
  685. errmsg( "Failed to open $SubdirsFile.", $LogFilename );
  686. return( undef );
  687. }
  688. @DirsLines = <INFILE>;
  689. close( INFILE );
  690. $TreeLen = length( $nttree ) + 1;
  691. foreach $Line ( @DirsLines ) {
  692. chomp( $Line );
  693. if ( ( length( $Line ) == 0 ) || ( substr( $Line, 0, 1 ) eq ";" ) ) {
  694. next;
  695. }
  696. ( $DirName, $IsRecursive ) = split( /\s+/, $Line );
  697. if ( ! ( -e "$nttree\\$DirName" ) ) {
  698. wrnmsg( "$DirName from subdirs.lst does not exist,",
  699. $LogFilename );
  700. wrnmsg( "skipping and continuing ...", $LogFilename );
  701. next;
  702. }
  703. if ( defined( $IsRecursive ) ) {
  704. @DirList = `dir /a-d /b /s $nttree\\$DirName`;
  705. } else {
  706. @DirList = `dir /a-d /b $nttree\\$DirName`;
  707. }
  708. foreach $SubName ( @DirList ) {
  709. chomp( $SubName );
  710. if ( defined( $IsRecursive ) ) {
  711. $SubName = substr( $SubName, $TreeLen );
  712. } else {
  713. $SubName = "$DirName\\" . $SubName;
  714. }
  715. $SubName = "\L$SubName";
  716. if ( length( $SubName ) == 0 ) { next; }
  717. if ( exists( $Hash{ $SubName } ) ) {
  718. &ChangeSettings( $SubName, "Prods=wpsbled:Signed=t" );
  719. } else {
  720. &NewSettings( $SubName, "Prods=wpsbled:Signed=t:Comp=f" );
  721. }
  722. if ( $DirName eq "lang" ) {
  723. &ChangeSettings( $SubName, "Comp=t" );
  724. }
  725. }
  726. }
  727. return( "TRUE" );
  728. }
  729. sub MarkUncomps
  730. {
  731. my( $InfFile ) = @_;
  732. my( @InfLines, $Line, $ReadFlag );
  733. my( $LHS, $RHS, $FileName );
  734. my( @LeftStuff, @RightStuff );
  735. unless ( open( INFILE, $InfFile ) ) {
  736. errmsg( "Unable to open $InfFile.", $LogFilename );
  737. return( undef );
  738. }
  739. @InfLines = <INFILE>;
  740. close( INFILE );
  741. $ReadFlag = "FALSE";
  742. foreach $Line ( @InfLines ) {
  743. chomp( $Line );
  744. if ( ( length( $Line ) == 0 ) || ( substr( $Line, 0, 3 ) eq "@*:" ) ) {
  745. next;
  746. }
  747. if ( $Line =~ /^\[/ ) { $ReadFlag = "FALSE"; }
  748. if ( ( $Line =~ /^\[Files\]/ ) ||
  749. ( $Line =~ /^\[SourceDisksFiles\]/ ) ) {
  750. $ReadFlag = "TRUE";
  751. } elsif ( ( $AmX86 eq "TRUE" ) &&
  752. ( $Line =~ /^\[SourceDisksFiles\.x86\]/ ) ) {
  753. $ReadFlag = "TRUE";
  754. } elsif ( ( $BldArch =~ /amd64/i ) &&
  755. ( $Line =~ /^\[SourceDisksFiles\.amd64\]/ ) ) {
  756. $ReadFlag = "TRUE";
  757. } elsif ( ( $BldArch =~ /ia64/i ) &&
  758. ( $Line =~ /^\[SourceDisksFiles\.ia64\]/ ) ) {
  759. $ReadFlag = "TRUE";
  760. }
  761. elsif ( $ReadFlag eq "TRUE" ) {
  762. if ( $Line =~ /\_/ ) {
  763. # there is an underscore, let's see where.
  764. $Line =~ s/\s//g;
  765. ( $LHS, $RHS ) = split( /=/, $Line );
  766. @RightStuff = split( /\,/, $RHS );
  767. if ( $RightStuff[6] =~ /^\_/ ) {
  768. @LeftStuff = split( /\:/, $LHS );
  769. $FileName = pop( @LeftStuff );
  770. $FileName = "\L$FileName";
  771. &ChangeSettings( $FileName, "Comp=f" );
  772. &ChangeSettings( "perinf\\$FileName", "Comp=f" );
  773. &ChangeSettings( "srvinf\\$FileName", "Comp=f" );
  774. &ChangeSettings( "blainf\\$FileName", "Comp=f" );
  775. &ChangeSettings( "sbsinf\\$FileName", "Comp=f" );
  776. &ChangeSettings( "entinf\\$FileName", "Comp=f" );
  777. &ChangeSettings( "dtcinf\\$FileName", "Comp=f" );
  778. }
  779. }
  780. }
  781. }
  782. return( "TRUE" );
  783. }
  784. sub ExcludeSigning
  785. {
  786. my( $ExcFile ) = @_;
  787. my( @ExcLines, $Line );
  788. unless ( open( INFILE, $ExcFile ) ) {
  789. errmsg( "Failed to open $ExcFile.", $LogFilename );
  790. return( undef );
  791. }
  792. @ExcLines = <INFILE>;
  793. close( INFILE );
  794. foreach $Line ( @ExcLines ) {
  795. chomp( $Line );
  796. if ( ( length( $Line ) == 0 ) || ( substr( $Line, 0, 1 ) eq ";" ) ) {
  797. next;
  798. }
  799. &ChangeSettings( $Line, "Signed=f" );
  800. }
  801. return( "TRUE" );
  802. }
  803. sub GetFlag
  804. {
  805. my( $Key, $FieldFlag ) = @_;
  806. my( @FieldList );
  807. @FieldList = split( /\:/, $Hash{ $Key } );
  808. return( $FieldList[ $FieldLocations{ $FieldFlag } ] );
  809. }
  810. sub MakeInfCdf
  811. {
  812. my( $CdfName, $Product ) = @_;
  813. my( $Key, $Flags, $CdfDir, $CdfVolDir );
  814. my ( $CdfExt, $ThisInfName );
  815. if ( $IncFlag eq "TRUE") { $CdfExt = ".icr"; }
  816. else { $CdfExt = ".cdf"; }
  817. logmsg( "Generating \'$Product\' nt5inf$CdfExt ...",
  818. $LogFilename );
  819. if ( $Product !~ /^(w|p|b|l|s|e|d)$/i ) {
  820. errmsg( "Invalid product '$Product'!" );
  821. return;
  822. }
  823. $ThisInfName = "" if ( $Product eq "w" );
  824. $ThisInfName = "\\perinf" if ( $Product eq "p" );
  825. $ThisInfName = "\\srvinf" if ( $Product eq "s" );
  826. $ThisInfName = "\\blainf" if ( $Product eq "b" );
  827. $ThisInfName = "\\sbsinf" if ( $Product eq "l" );
  828. $ThisInfName = "\\entinf" if ( $Product eq "e" );
  829. $ThisInfName = "\\dtcinf" if ( $Product eq "d" );
  830. $CdfDir = "$TempDir\\CDFs". ( $ThisInfName ?"$ThisInfName":"" );
  831. system( "if not exist $CdfDir md $CdfDir" );
  832. # Open the CDF files for writing
  833. unless ( open( CDF, ">$CdfDir\\nt5inf$CdfExt" ) ) {
  834. errmsg( "Unable to open $CdfDir\\nt5inf$CdfExt for writing ($!).",
  835. $LogFilename );
  836. return;
  837. }
  838. #print("$IncFlag");
  839. if ( $IncFlag eq "FALSE" ) {
  840. # put in CDF header crap
  841. foreach( ( "\[CatalogHeader\]",
  842. "Name=nt5inf",
  843. "PublicVersion=0x0000001",
  844. "EncodingType=0x00010001",
  845. "CATATTR1=0x10010001:OSAttr:2:5.1",
  846. "",
  847. "\[CatalogFiles\]" ) ) {
  848. print CDF "$_\n";
  849. }
  850. foreach $Key ( keys( %Hash ) ) {
  851. $Flags = &GetFlag( $Key, "Prods" );
  852. if ( ( $Flags ne "wpsbled" ) && ( $Flags ne "nul" ) &&
  853. ( $Flags =~ /$Product/ ) &&
  854. ( &GetFlag( $Key, "Signed" ) eq "t" ) ) {
  855. print CDF "<hash>$nttree\\$Key=$nttree\\$Key\n";
  856. }
  857. }
  858. # special exemptions
  859. # mark the wks layout.inf as signed in the srv nt5inf.cdf
  860. if ( $Product eq "s" ) {
  861. print CDF "<hash>$nttree\\layout.inf=$nttree\\layout.inf\n";
  862. }
  863. } else {
  864. foreach $Key ( keys( %Hash ) ) {
  865. $Flags = &GetFlag( $Key, "Prods" );
  866. if ( ( $Flags ne "wpsbled" ) && ( $Flags ne "nul" ) &&
  867. ( $Flags =~ /$Product/ ) &&
  868. ( &GetFlag( $Key, "Signed" ) eq "t" ) ) {
  869. print CDF "$nttree\\$Key\n";
  870. }
  871. }
  872. if (( $Product eq "s" ) && ( $Hash{ "srvinf\\layout.inf" } )) {
  873. print CDF "$nttree\\layout.inf\n";
  874. }
  875. }
  876. close CDF;
  877. # copy the CDF to the build_logs for intl
  878. my( $BaseCopyDir ) = "$nttree\\build_logs\\cdfs$ThisInfName";
  879. mkdir( $BaseCopyDir, 0777 ) if ( ! -d $BaseCopyDir );
  880. my( $ReturnCode ) = system( "copy $CdfDir\\nt5inf$CdfExt $BaseCopyDir" );
  881. if ( $ReturnCode != 0 ) {
  882. wrnmsg( "Failed to copy a nt5inf.cdf into the build ...",
  883. $LogFilename );
  884. }
  885. }
  886. sub MakeMainCdfs
  887. {
  888. my( $CdfName ) = @_;
  889. my( $PrtName, $Key, $Flags, $DrmLevel );
  890. my ( $CdfExt );
  891. $DrmLevel = "ATTR1=0x10010001:DRMLevel:";
  892. if ( $IncFlag eq "TRUE") { $CdfExt = ".icr"; }
  893. else { $CdfExt = ".cdf"; }
  894. $PrtName = 'ntprint';
  895. logmsg( "Generating $CdfName$CdfExt and $PrtName$CdfExt ...",
  896. $LogFilename );
  897. system( "if not exist $TempDir\\CDFs md $TempDir\\CDFs" );
  898. unless ( open( CDF, ">$TempDir\\CDFs\\$CdfName$CdfExt" ) ) {
  899. errmsg( "Unable to open $CdfName$CdfExt for writing.",
  900. $LogFilename );
  901. return( undef );
  902. }
  903. unless ( open( PRINTER, ">$TempDir\\CDFs\\$PrtName$CdfExt" ) ) {
  904. errmsg( "Unable to open $PrtName$CdfExt for writing.",
  905. $LogFilename );
  906. close( CDF );
  907. return( undef );
  908. }
  909. if ( $IncFlag eq "FALSE" ) {
  910. foreach( "\[CatalogHeader\]",
  911. "Name=$CdfName",
  912. "PublicVersion=0x0000001",
  913. "EncodingType=0x00010001",
  914. "CATATTR1=0x10010001:OSAttr:2:5.1",
  915. "",
  916. "\[CatalogFiles\]" ) {
  917. print CDF "$_\n";
  918. }
  919. foreach( "\[CatalogHeader\]",
  920. "Name=$PrtName",
  921. "PublicVersion=0x0000001",
  922. "EncodingType=0x00010001",
  923. "CATATTR1=0x10010001:OSAttr:2:5.0,2:5.1",
  924. "",
  925. "\[CatalogFiles\]" ) {
  926. print PRINTER "$_\n";
  927. }
  928. foreach $Key ( keys( %Hash ) ) {
  929. $Flags = &GetFlag( $Key, "Prods" );
  930. if ( ( ( $Flags eq "wpsbled" ) || ( $Flags eq "nul" ) ) &&
  931. ( &GetFlag( $Key, "Signed" ) eq "t" ) )
  932. {
  933. print CDF "<hash>$nttree\\$Key=$nttree\\$Key\n";
  934. print (CDF "<hash>$nttree\\$Key$DrmLevel", &GetFlag( $Key, "DRMLevel" ), "\n" ) if( &GetFlag( $Key, "DRMLevel" ) ne "f" );
  935. }
  936. if ( &GetFlag( $Key, "Print" ) eq "t" ) {
  937. print PRINTER "<hash>$nttree\\$Key=$nttree\\$Key\n";
  938. }
  939. }
  940. } else {
  941. foreach $Key ( keys( %Hash ) ) {
  942. $Flags = &GetFlag( $Key, "Prods" );
  943. if ( ( ( $Flags eq "wpsbled" ) || ( $Flags eq "nul" ) ) &&
  944. ( &GetFlag( $Key, "Signed" ) eq "t" ) ) {
  945. print CDF "$nttree\\$Key\n";
  946. }
  947. if ( &GetFlag( $Key, "Print" ) eq "t" ) {
  948. print PRINTER "$nttree\\$Key\n";
  949. }
  950. }
  951. }
  952. close CDF;
  953. close PRINTER;
  954. # copy the cdfs for intl
  955. my( $BaseCopyDir ) = "$nttree\\build_logs\\cdfs";
  956. mkdir( $BaseCopyDir, 0777 ) if ( ! -d $BaseCopyDir );
  957. my $ReturnCode = system( "copy $TempDir\\CDFs\\$CdfName$CdfExt $BaseCopyDir" );
  958. if ( $ReturnCode != 0 ) {
  959. wrnmsg( "Failed to copy nt5.cdf into the build ...",
  960. $LogFilename );
  961. }
  962. $ReturnCode = system( "copy $TempDir\\CDFs\\nt5prt$PrtName$CdfExt $BaseCopyDir" );
  963. if ( $ReturnCode != 0 ) {
  964. wrnmsg( "Failed to copy nt5prtx.cdf into the build ...",
  965. $LogFilename );
  966. }
  967. }
  968. sub MakeProdLists
  969. {
  970. my( $Product ) = @_;
  971. my( $ProductFlag, $Key, $CompName );
  972. logmsg( "Generating product lists for \'$Product\' ...",
  973. $LogFilename );
  974. unless ( ( open( ALL, ">$TempDir\\$Product.lst" ) ) &&
  975. ( open( COMP, ">$TempDir\\" . $Product . "comp.lst" ) ) &&
  976. ( open( UNCOMP, ">$TempDir\\" . $Product . "uncomp.lst" ) ) &&
  977. ( open( SUB, ">$TempDir\\" . $Product . "sub.lst" ) ) &&
  978. ( open( SUBCOMP, ">$TempDir\\" . $Product . "subcomp.lst" ) ) &&
  979. ( open( SUBUNCOMP, ">$TempDir\\" . $Product . "subuncomp.lst" ) )
  980. ) {
  981. errmsg( "Failed to open $Product comp, all, uncomp lists",
  982. $LogFilename );
  983. close( ALL );
  984. close( COMP );
  985. close( UNCOMP );
  986. close( SUB );
  987. close( SUBCOMP );
  988. close( SUBUNCOMP );
  989. return( undef );
  990. }
  991. if ( ( $Product =~ /per/i ) ||
  992. ( $Product =~ /bla/i ) ||
  993. ( $Product =~ /srv/i ) ||
  994. ( $Product =~ /dtc/i ) ) {
  995. $ProductFlag = substr( $Product, 0, 1 );
  996. } else {
  997. # now do the freak cases, wks, ent, and sbs
  998. if ( $Product =~ /pro/i ) { $ProductFlag = "w"; }
  999. if ( $Product =~ /ads/i ) { $ProductFlag = "e"; }
  1000. if ( $Product =~ /sbs/i ) { $ProductFlag = "l"; }
  1001. }
  1002. foreach $Key ( keys( %Hash ) ) {
  1003. if ( ( &GetFlag( $Key, "Driver" ) eq "t" ) &&
  1004. ( &GetFlag( $Key, "Dosnet" ) eq "f" ) ) { next; }
  1005. if ( ( &GetFlag( $Key, "Prods" ) =~ /$ProductFlag/ ) &&
  1006. ( &GetFlag( $Key, "Prods" ) ne "nul" ) ){
  1007. #In case a file is in PRO and is a tabletpc file then do not add it onto the product list for PRO SKU.
  1008. if ( !((&GetFlag( $Key, "TabletPC" ) eq "t") && ($Product =~ /pro/i) )) {
  1009. if ( $Key =~ /\\(\S*)$/ ) { print( SUB "$1\n" ); }
  1010. else { print( ALL "$Key\n" ); }
  1011. if ( &GetFlag( $Key, "Comp" ) eq "t" ) {
  1012. $CompName = &MakeCompName( $Key );
  1013. if ( $CompName =~ /\\(\S*)$/ ) { print( SUBCOMP "$1\n" ); }
  1014. else { print( COMP "$CompName\n" ); }
  1015. } else {
  1016. if ( $Key =~ /\\(\S*)$/ ) { print( SUBUNCOMP "$1\n" ); }
  1017. else { print( UNCOMP "$Key\n" ); }
  1018. }
  1019. }
  1020. }
  1021. }
  1022. close( ALL );
  1023. close( COMP );
  1024. close( UNCOMP );
  1025. close( SUB );
  1026. close( SUBCOMP );
  1027. close( SUBUNCOMP );
  1028. }
  1029. sub MakeTabletList
  1030. {
  1031. my($key,$CompName);
  1032. unless ( open( FILE, ">$TempDir\\TabletPc.lst" ) ){
  1033. errmsg( "Failed to open TabletPc.lst",$LogFilename );
  1034. }
  1035. unless ( open( FILECOMP, ">$TempDir\\TabletPcComp.lst" ) ){
  1036. errmsg( "Failed to open TabletPcComp.lst",$LogFilename );
  1037. }
  1038. foreach $key ( keys( %Hash ) ) {
  1039. if ( &GetFlag( $key, "TabletPC" ) eq "t" ){
  1040. print( FILE "$key \n");
  1041. $CompName = &MakeCompName( $key );
  1042. print( FILECOMP "$CompName \n");
  1043. }
  1044. }
  1045. close (FILE);
  1046. close (FILECOMP);
  1047. }
  1048. #
  1049. # MakeDriverCabLists
  1050. #
  1051. # Arguments: $SkuName, $SkuLetter
  1052. #
  1053. # Purpose: generate driver lists for drivercab based on the sku given
  1054. #
  1055. # Returns: nothing
  1056. #
  1057. sub MakeDriverCabLists
  1058. {
  1059. # get passed args
  1060. my( $SkuName, $SkuLetter ) = @_;
  1061. # declare locals
  1062. my( $fh ); # file handle for writing the list
  1063. my( $ListName ); # file name for this list
  1064. # generate list file name and delete the old one
  1065. $ListName = "$TempDir\\" . $SkuName . "drivers.txt";
  1066. if ( -e $ListName ) {
  1067. unlink( $ListName );
  1068. if ( -e $ListName ) {
  1069. errmsg( "Failed to delete $ListName ...",
  1070. $LogFilename );
  1071. }
  1072. }
  1073. # if we're in incremental mode, do not create a common list
  1074. if ( ( $IncFlag eq "TRUE" ) && ( $SkuName eq "common" ) ) {
  1075. return;
  1076. }
  1077. unless ( $fh = new IO::File $ListName, "w" ) {
  1078. # failed to create file for open
  1079. errmsg( "Failed to open $ListName for write ..." );
  1080. return;
  1081. }
  1082. # generate all letters that we're operating over
  1083. my( $SkuLetters );
  1084. if ( $CDDataSKUs{ 'PRO' } ) { $SkuLetters .= "w"; }
  1085. if ( $CDDataSKUs{ 'PER' } ) { $SkuLetters .= "p"; }
  1086. if ( $CDDataSKUs{ 'SRV' } ) { $SkuLetters .= "s"; }
  1087. if ( $CDDataSKUs{ 'BLA' } ) { $SkuLetters .= "b"; }
  1088. if ( $CDDataSKUs{ 'SBS' } ) { $SkuLetters .= "l"; }
  1089. if ( $CDDataSKUs{ 'ADS' } ) { $SkuLetters .= "e"; }
  1090. if ( $CDDataSKUs{ 'DTC' } ) { $SkuLetters .= "d"; }
  1091. #
  1092. # begin writing drivers to each list
  1093. #
  1094. foreach $Key ( keys( %Hash ) ) {
  1095. # check if this file is a driver for this prod
  1096. next if ( &GetFlag( $Key, "DrvIndex" ) =~ /nul/i );
  1097. if ( $IncFlag eq "TRUE" ) {
  1098. # we are in incremental mode
  1099. if ( &GetFlag( $Key, "DrvIndex" ) =~ /\Q$SkuLetter\E/i ) {
  1100. print( $fh "$Key\n" );
  1101. }
  1102. } else {
  1103. # we are in full mode
  1104. # if we're common, don't add us to uncommon lists.
  1105. # if we're not common, add us to regular lists.
  1106. if ( ( &GetFlag( $Key, "DrvIndex" ) =~ /\Q$SkuLetters\E/ ) &&
  1107. ( $SkuName eq "common" ) ) {
  1108. print( $fh "$Key\n" );
  1109. } elsif ( ( &GetFlag( $Key, "DrvIndex" ) =~ /\Q$SkuLetter\E/i ) &&
  1110. ( &GetFlag( $Key, "DrvIndex" ) !~ /\Q$SkuLetters\E/i ) ) {
  1111. print( $fh "$Key\n" );
  1112. }
  1113. }
  1114. }
  1115. undef( $fh );
  1116. # delete the list if it has zero length
  1117. if ( -z $ListName ) {
  1118. unlink( $ListName );
  1119. if ( -e $ListName ) {
  1120. errmsg( "Failed to delete zero length driver list for ".
  1121. "$SkuName ...", $LogFilename );
  1122. }
  1123. }
  1124. }
  1125. sub MakeCompLists
  1126. {
  1127. my( $Key, $CompKey, $Ext );
  1128. my $Binaries = $ENV{'_NTPOSTBLD'};
  1129. my $CompressedBinaries = "$Binaries\\comp";
  1130. logmsg( "Generating compression lists ...", $LogFilename );
  1131. unless ( ( open( ALL, ">$TempDir\\allcomp.lst" ) ) &&
  1132. ( open( PRE, ">$TempDir\\precomp.lst" ) ) &&
  1133. ( open( POST, ">$TempDir\\postcomp.lst" ) ) ) {
  1134. errmsg( "Failed to open main compression lists.",
  1135. $LogFilename );
  1136. close( ALL );
  1137. close( PRE );
  1138. close( POST );
  1139. return( undef );
  1140. }
  1141. foreach $Key ( keys( %Hash ) ) {
  1142. if ( &GetFlag( $Key, "Comp" ) eq "t" ) {
  1143. if ( $Key =~ /\\/ ) {
  1144. unless ( ( $Key =~ /^perinf/ ) || ( $Key =~ /^srvinf/ ) ||
  1145. ( $Key =~ /^entinf/ ) || ( $Key =~ /^blainf/ ) ||
  1146. ( $Key =~ /^dtcinf/ ) || ( $Key =~ /^sbsinf/ ) || ( $Key =~ /^lang/) ) {
  1147. next;
  1148. }
  1149. }
  1150. $CompKey = &MakeCompName( $Key );
  1151. print( ALL "$Binaries\\$Key $CompressedBinaries\\$CompKey\n" );
  1152. $Ext = substr( $Key, -4, 4 );
  1153. if ( ( $Ext ne ".exe" ) && ( $Ext ne ".dll" ) &&
  1154. ( $Ext ne ".cpl" ) && ( $Ext ne ".com" ) &&
  1155. ( $Ext ne ".ocx" ) && ( substr( $Ext, 1, 3 ) ne ".ax" ) &&
  1156. ( $Ext ne ".tsp" ) && ( $Ext ne ".drv" ) &&
  1157. ( $Ext ne ".scr" ) && ( $Ext ne ".cat" ) ) {
  1158. print( PRE "$Binaries\\$Key $CompressedBinaries\\$CompKey\n" );
  1159. }
  1160. if ( ( ( $Ext ne ".cab" ) && ( $Ext ne ".msi" ) &&
  1161. ( $Ext ne ".cat" ) ) && (
  1162. ( $Ext eq ".exe" ) || ( $Ext eq ".dll" ) ||
  1163. ( $Ext eq ".cpl" ) || ( $Ext eq ".com" ) ||
  1164. ( $Ext eq ".ocx" ) || ( substr( $Ext, 1, 3 ) eq ".ax" ) ||
  1165. ( $Ext eq ".tsp" ) || ( $Ext eq ".drv" ) ||
  1166. ( $Ext eq ".scr" ) ) ) {
  1167. print( POST "$Binaries\\$Key $CompressedBinaries\\$CompKey\n" );
  1168. }
  1169. }
  1170. }
  1171. close( ALL );
  1172. close( PRE );
  1173. close( POST );
  1174. }
  1175. sub MakeExtensionLists
  1176. {
  1177. logmsg( "Creating extension lists ...",
  1178. $LogFilename );
  1179. my %handles_to_extension_lists;
  1180. # Use our own subdirectory
  1181. mkdir "$ENV{_NTPostBld}\\congeal_scripts\\exts", 0777 if ( ! -d "$ENV{_NTPostBld}\\congeal_scripts\\exts" );
  1182. foreach my $key ( keys( %Hash ) ) {
  1183. my ($ext) = $key =~ /\.([^\.]+)$/;
  1184. $ext ||= 'noext';
  1185. if ( !exists $handles_to_extension_lists{$ext} ) {
  1186. $handles_to_extension_lists{$ext} = new IO::File "$ENV{_NTPostBld}\\congeal_scripts\\exts\\$ext\_files.lst", O_CREAT | O_WRONLY;
  1187. if ( !exists $handles_to_extension_lists{$ext} ) {
  1188. errmsg( "Error opening $ENV{_NTPostBld}\\congeal_scripts\\exts\\$ext\_files.lst for writing ($!)" );
  1189. return;
  1190. }
  1191. }
  1192. $handles_to_extension_lists{$ext}->print("$key\n");
  1193. }
  1194. # close all open handles
  1195. foreach ( keys %handles_to_extension_lists ) {
  1196. $handles_to_extension_lists{$_}->close();
  1197. }
  1198. return 1;
  1199. }
  1200. sub MakeLists
  1201. {
  1202. if ( ( defined( $CreateCDFs ) ) || ( defined( $CreateLists ) ) ) {
  1203. logmsg( "Beginning CDF and list generation ...",
  1204. $LogFilename );
  1205. }
  1206. &MakeTabletList();
  1207. if ( defined( $CreateCDFs ) ) {
  1208. # let's make some cdf's
  1209. &MakeMainCdfs( "nt5" );
  1210. &MakeInfCdf( "nt5winf", "w" );# if ( $CDDataSKUs{'PRO'});
  1211. &MakeInfCdf( "nt5pinf", "p" );# if ( $CDDataSKUs{'PER'});
  1212. &MakeInfCdf( "nt5sinf", "s" );# if ( $CDDataSKUs{'SRV'});
  1213. &MakeInfCdf( "nt5binf", "b" );# if ( $CDDataSKUs{'BLA'});
  1214. &MakeInfCdf( "nt5linf", "l" );# if ( $CDDataSKUs{'SBS'});
  1215. &MakeInfCdf( "nt5einf", "e" );# if ( $CDDataSKUs{'ADS'});
  1216. &MakeInfCdf( "nt5dinf", "d" );# if ( $CDDataSKUs{'DTC'});
  1217. }
  1218. if ( defined( $CreateLists ) ) {
  1219. # let's make some product lists
  1220. &MakeProdLists( "pro" );# if ( $CDDataSKUs{'PRO'});
  1221. &MakeProdLists( "per" );# if ( $CDDataSKUs{'PER'});
  1222. &MakeProdLists( "srv" );# if ( $CDDataSKUs{'SRV'});
  1223. &MakeProdLists( "bla" );# if ( $CDDataSKUs{'BLA'});
  1224. &MakeProdLists( "sbs" );# if ( $CDDataSKUs{'SBS'});
  1225. &MakeProdLists( "ads" );# if ( $CDDataSKUs{'ADS'});
  1226. &MakeProdLists( "dtc" );# if ( $CDDataSKUs{'DTC'});
  1227. # let's make some drivercab lists
  1228. &MakeDriverCabLists( "pro", "w" ) if ( $CDDataSKUs{ 'PRO' } );
  1229. &MakeDriverCabLists( "per", "p" ) if ( $CDDataSKUs{ 'PER' } );
  1230. &MakeDriverCabLists( "srv", "s" ) if ( $CDDataSKUs{ 'SRV' } );
  1231. &MakeDriverCabLists( "bla", "b" ) if ( $CDDataSKUs{ 'BLA' } );
  1232. &MakeDriverCabLists( "sbs", "l" ) if ( $CDDataSKUs{ 'SBS' } );
  1233. &MakeDriverCabLists( "ads", "e" ) if ( $CDDataSKUs{ 'ADS' } );
  1234. &MakeDriverCabLists( "dtc", "d" ) if ( $CDDataSKUs{ 'DTC' } );
  1235. &MakeDriverCabLists( "common", "c" );
  1236. # let's make some compression lists
  1237. &MakeCompLists();
  1238. logmsg( "Sorting generated lists ...", $LogFilename );
  1239. system( "sort $TempDir\\allcomp.lst /o $TempDir\\allcomp.lst" );
  1240. system( "sort $TempDir\\precomp.lst /o $TempDir\\precomp.lst" );
  1241. system( "sort $TempDir\\postcomp.lst /o $TempDir\\postcomp.lst" );
  1242. }
  1243. if ( ( defined( $CreateCDFs ) ) || ( defined( $CreateLists ) ) ) {
  1244. logmsg( "Finished creating CDFs and lists.", $LogFilename );
  1245. }
  1246. }
  1247. sub MakeCompName
  1248. {
  1249. my $fullname = shift;
  1250. my ($filename, $path) = fileparse($fullname);
  1251. $filename =~ s{(\.([^\.]*))?$}
  1252. {'.' . ((length $2 < 3) ? $2 : substr($2,0,-1)) . '_'}ex;
  1253. return ($path eq '.\\'?'':$path).$filename;
  1254. }
  1255. sub CheckDosnet
  1256. {
  1257. my( $DosnetName ) = @_;
  1258. my( @DosLines, $Line, $ReadFlag, $ListName, $MyName, $CopyLocation );
  1259. my( $Junk );
  1260. # check all the dosnet's right now
  1261. unless ( open( DOSNET, $DosnetName ) ) {
  1262. errmsg( "Failed to open $DosnetName.", $LogFilename );
  1263. return( undef );
  1264. }
  1265. @DosLines = <DOSNET>;
  1266. close( DOSNET );
  1267. $ListName = $TempDir . "\\wksnetck.lst";
  1268. if ( $DosnetName =~ /perinf/ ) { $ListName = $TempDir . "\\pernetck.lst"; }
  1269. if ( $DosnetName =~ /srvinf/ ) { $ListName = $TempDir . "\\srvnetck.lst"; }
  1270. if ( $DosnetName =~ /blainf/ ) { $ListName = $TempDir . "\\blanetck.lst"; }
  1271. if ( $DosnetName =~ /sbsinf/ ) { $ListName = $TempDir . "\\sbsnetck.lst"; }
  1272. if ( $DosnetName =~ /entinf/ ) { $ListName = $TempDir . "\\entnetck.lst"; }
  1273. if ( $DosnetName =~ /dtcinf/ ) { $ListName = $TempDir . "\\dtcnetck.lst"; }
  1274. unless ( open( LIST, ">$ListName" ) ) {
  1275. errmsg( "Failed to open $ListName for writing.",
  1276. $LogFilename );
  1277. return( undef );
  1278. }
  1279. $ReadFlag = "FALSE";
  1280. foreach $Line ( @DosLines ) {
  1281. chomp( $Line );
  1282. if ( ( length( $Line ) == 0 ) ||
  1283. ( substr( $Line, 0, 1 ) eq ";" ) ||
  1284. ( substr( $Line, 0, 1 ) eq "#" ) ||
  1285. ( substr( $Line, 0, 2 ) eq "@*" ) ) { next; }
  1286. if ( $Line =~ /^\[/ ) { $ReadFlag = "FALSE"; }
  1287. if ( ( $Line =~ /^\[Files\]/ ) ||
  1288. ( $Line =~ /^\[SourceDisksFiles\]/ ) ) {
  1289. $ReadFlag = "TRUE";
  1290. } elsif ( ( $AmX86 eq "TRUE" ) &&
  1291. ( $Line =~ /^\[SourceDisksFiles\.x86\]/ ) ) {
  1292. $ReadFlag = "TRUE";
  1293. } elsif ( ( $BldArch =~ /amd64/i ) &&
  1294. ( $Line =~ /^\[SourceDisksFiles\.amd64\]/ ) ) {
  1295. $ReadFlag = "TRUE";
  1296. } elsif ( ( $BldArch =~ /ia64/i ) &&
  1297. ( $Line =~ /^\[SourceDisksFiles\.ia64\]/ ) ) {
  1298. $ReadFlag = "TRUE";
  1299. } elsif ( $ReadFlag eq "TRUE" ) {
  1300. $Line =~ s/^d1\,//;
  1301. ( $MyName, $CopyLocation ) = split( /\,/, $Line );
  1302. ( $MyName, $Junk ) = split( /\s/, $MyName );
  1303. # myname is considered "good"
  1304. # BUGBUG
  1305. # this will NOT notice missing files of the following nature:
  1306. # if a file is different in any two products, and it's only
  1307. # missing from _one_ of the directories below, it will be
  1308. # marked as fine.
  1309. if ( ( ! ( -e "$nttree\\$MyName" ) ) &&
  1310. ( ! ( -e "$nttree\\perinf\\$MyName" ) ) &&
  1311. ( ! ( -e "$nttree\\srvinf\\$MyName" ) ) &&
  1312. ( ! ( -e "$nttree\\blainf\\$MyName" ) ) &&
  1313. ( ! ( -e "$nttree\\sbsinf\\$MyName" ) ) &&
  1314. ( ! ( -e "$nttree\\entinf\\$MyName" ) ) &&
  1315. ( ! ( -e "$nttree\\dtcinf\\$MyName" ) ) ) {
  1316. print( LIST "$MyName\n" );
  1317. }
  1318. }
  1319. }
  1320. }
  1321. sub SpecialExclusions
  1322. {
  1323. # force ntkrnlmp.exe to be uncompressed on ia64 builds
  1324. if ( $BldArch =~ /ia64/i ) {
  1325. &ChangeSettings( "ntkrnlmp.exe", "Comp=f" );
  1326. }
  1327. # Change settings only works on existing keys,
  1328. # so try to change all possible driver.cab files
  1329. # to unsigned
  1330. &ChangeSettings( "driver.cab", "Signed=f" );
  1331. &ChangeSettings( "perinf\\driver.cab", "Signed=f" );
  1332. &ChangeSettings( "srvinf\\driver.cab", "Signed=f" );
  1333. &ChangeSettings( "sbsinf\\driver.cab", "Signed=f" );
  1334. &ChangeSettings( "blainf\\driver.cab", "Signed=f" );
  1335. &ChangeSettings( "entinf\\driver.cab", "Signed=f" );
  1336. &ChangeSettings( "dtcinf\\driver.cab", "Signed=f" );
  1337. }
  1338. sub UsageAndQuit
  1339. {
  1340. print( "\n$0 [-f] [-cdf] [-cdl] [-g:<Search> [-o:<Filename>]]\n" );
  1341. print( "\n\t-f\t\tForce list generation -- don't read old list\n" );
  1342. print( "\t-cdf\t\tCreate CDFs\n" );
  1343. print( "\t-cdl\t\tCreate CD lists (compression lists, link lists)\n" );
  1344. print( "\t-g:<Search>\tPrint to STDOUT or <Filename> the results\n" );
  1345. print( "\t\t\tof a search on the given input (see below)\n" );
  1346. print( "\t-o:<Filename>\tSend search output to the given filename\n" );
  1347. print( "\n\tFor the search command, valid expressions are:\n" );
  1348. print( "\t\tField=xxx\tReturn entries whose \"Field\" is exactly xxx\n" );
  1349. print( "\t\tField?yyy\tReturn entries whose \"Field\" contains yyy\n" );
  1350. print( "\t\tField1=xxx:Field2=yyy logically \'and\'s results\n" );
  1351. print( "\n\tField names can be found in the keylist file $KeyFileName\n" );
  1352. print( "\n" );
  1353. exit( 1 );
  1354. }
  1355. sub HandleDiffFiles
  1356. {
  1357. # declare locals
  1358. my( @BinDiffs, $NumDiffsLimit, %DiffFiles, $Line );
  1359. # here we need to make a decision.
  1360. # we can either do an incremental build if the diff list is smaller than
  1361. # some number of files, or we can run a full postbuild.
  1362. # first, set the limit on the number of differing files before running
  1363. # a full postbuild.
  1364. $NumDiffsLimit = 100;
  1365. $IncFlag = "FALSE";
  1366. # if the user specifically asked for no bindiff truncation, just return
  1367. if ( defined( $NoUseBindiff ) ) {
  1368. logmsg( "Not truncating against bindiff files ...",
  1369. $LogFilename );
  1370. return( 1 );
  1371. }
  1372. # open the diff file and read it in
  1373. unless ( open( INFILE, $BinDiffFile ) ) {
  1374. errmsg( "Failed to open new file list '$BinDiffFile',",
  1375. $LogFilename );
  1376. errmsg( "will assume a full postbuild is needed.",
  1377. $LogFilename );
  1378. return( undef );
  1379. }
  1380. @BinDiffs = <INFILE>;
  1381. close( INFILE );
  1382. # make sure we're under the limit
  1383. if ( @BinDiffs > $NumDiffsLimit ) {
  1384. logmsg( "Too many files have changed, will perform a full",
  1385. $LogFilename );
  1386. logmsg( "postbuild, non-incremental.", $LogFilename );
  1387. return( undef );
  1388. }
  1389. # if we're here, then we have a small enough number of different files
  1390. # that we'll run an incremental postbuild.
  1391. # set a flag to indicate we are in incremental mode
  1392. $IncFlag = "TRUE";
  1393. # so what we want to do is remove all hashes that do NOT appear in
  1394. # the diff file.
  1395. foreach $Line ( @BinDiffs ) {
  1396. chomp( $Line );
  1397. $Line = "\L$Line";
  1398. # add the files to the temp hash
  1399. # print( "DEBUG: diff file '$Line'\n" );
  1400. $DiffFiles{ $Line } = "TRUE";
  1401. }
  1402. foreach $Key ( keys( %Hash ) ) {
  1403. $Line = "\L$nttree\\$Key";
  1404. # print( "DEBUG: key check '$Line'\n" );
  1405. unless ( $DiffFiles{ $Line } ) { delete( $Hash{ $Key } ); }
  1406. }
  1407. # and we're done!
  1408. # just return true.
  1409. return( 1 );
  1410. }
  1411. sub GetPrinterFiles
  1412. {
  1413. # get passed args
  1414. my( $PrintFileName ) = @_;
  1415. # declare locals
  1416. my( @PrintLines, $Line, $PrintMe, $PrinterName, $Junk );
  1417. unless ( open( INFILE, $PrintFileName ) ) {
  1418. errmsg( "Failed to open $PrintFileName to determine printers",
  1419. $LogFilename );
  1420. undef( @PrinterFiles );
  1421. return;
  1422. }
  1423. @PrintLines = <INFILE>;
  1424. close( INFILE );
  1425. undef( $PrintMe );
  1426. foreach $Line ( @PrintLines ) {
  1427. # first, a simple unicode conversion
  1428. $Line =~ s/\000//g;
  1429. # now a chomp that handles \r also
  1430. $Line =~ s/[\r\n]//g;
  1431. if ( ( length( $Line ) == 0 ) || ( $Line =~ /^\;/ ) ) { next; }
  1432. if ( $Line =~ /^\[/ ) { undef( $PrintMe ); }
  1433. if ( $PrintMe eq "TRUE" ) {
  1434. ( $PrinterName, $Junk ) = split( /\s+/, $Line );
  1435. push( @PrinterFiles, $PrinterName );
  1436. }
  1437. if ( $Line =~ /\[SourceDisksFiles\]/ ) { $PrintMe = "TRUE"; }
  1438. }
  1439. }
  1440. #
  1441. # AddDrvIndex
  1442. #
  1443. # Arguments: $IndexFileName, $StatusChange, $SkuName
  1444. #
  1445. # Purpose: this routine scans the given drvindex.inf file for driver files and
  1446. # adds the appropriate status change to the DrvIndex field of the hash
  1447. # the $PathFromBinaries is to find the right version of the file.
  1448. #
  1449. # Returns: nothing
  1450. #
  1451. sub AddDrvIndex
  1452. {
  1453. # get passed args
  1454. my( $IndexFileName, $StatusChange, $SkuName ) = @_;
  1455. # declare locals
  1456. my( $fh ); # file handle for the index files
  1457. my( $FileLine ); # for reading files line by line
  1458. my( $ReadFlag ); # bool for reading files or not
  1459. my( $FilePrepend ); # hold "perinf\" or whatever
  1460. # declare status
  1461. logmsg( "Marking drivers in $IndexFileName ...", $LogFilename );
  1462. #
  1463. # open the drvindex file
  1464. #
  1465. unless ( $fh = new IO::File $IndexFileName, "r" ) {
  1466. # failed to open the file
  1467. errmsg( "Failed to open $IndexFileName ...", $LogFilename );
  1468. return;
  1469. }
  1470. #
  1471. # parse the file
  1472. #
  1473. # create the filename to look for first, i.e. if the sku we're checking
  1474. # is per, look for a perinf\$FileName first
  1475. #
  1476. $FilePrepend = "";
  1477. if ( $SkuName !~ /pro/i ) { $FilePrepend = $SkuName . "inf\\"; }
  1478. if ( $SkuName =~ /ads/i ) { $FilePrepend = "entinf\\"; }
  1479. #
  1480. $ReadFlag = "FALSE";
  1481. while ( $FileLine = <$fh> ) {
  1482. chomp( $FileLine );
  1483. if ( length( $FileLine ) == 0 ) { next; }
  1484. if ( $FileLine =~ /^\;/ ) { next; }
  1485. if ( $FileLine =~ /\[/ ) { $ReadFlag = "FALSE"; }
  1486. if ( $ReadFlag eq "TRUE" ) {
  1487. # add the file to the appropriate field
  1488. # prepend with $FilePrepend to see if that file exists
  1489. if ( $Hash{ "$FilePrepend$FileLine" } ) {
  1490. &ChangeSettings( "$FilePrepend$FileLine", $StatusChange );
  1491. } elsif ( $Hash{ "$FileLine" } ) {
  1492. &ChangeSettings( $FileLine, $StatusChange );
  1493. } else {
  1494. &NewSettings( $FileLine, $StatusChange );
  1495. }
  1496. }
  1497. if ( $FileLine =~ /\[driver\]/ ) { $ReadFlag = "TRUE"; }
  1498. }
  1499. undef( $fh );
  1500. }
  1501. #--
  1502. # GetDrmFiles
  1503. #
  1504. # First parameter is reference to associate array
  1505. # Associated array will be filled with values from $DrmTxt file.
  1506. #--
  1507. sub GetDrmFiles
  1508. {
  1509. #--
  1510. # Passed parameters
  1511. #--
  1512. my( $ref, $txtfile ) = @_;
  1513. #--
  1514. # Local variables
  1515. #--
  1516. my( $line, @DrmFileLines, $filename, $drmvalue, $rem );
  1517. unless( -f $txtfile )
  1518. {
  1519. wrnmsg( "Failed to find $txtfile to determine drm files", $LogFilename );
  1520. undef( %$ref );
  1521. return;
  1522. }
  1523. unless( open( INFILE, $txtfile ) )
  1524. {
  1525. errmsg( "Failed to open $txtfile to determine drm files", $LogFilename );
  1526. undef( %$ref );
  1527. return;
  1528. }
  1529. @DrmFileLines = <INFILE>;
  1530. close( INFILE );
  1531. foreach $line ( @DrmFileLines )
  1532. {
  1533. chomp $line;
  1534. if( ( $line =~ /^\s*$/ ) || ( $line =~ /^[\;\#]/ ) ) { next; }
  1535. ( $filename, $drmvalue, $rem ) = split( /\:/, $line );
  1536. $$ref{$filename} = $drmvalue;
  1537. }
  1538. }