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.

388 lines
13 KiB

  1. # ---------------------------------------------------------------------------
  2. # Script: filechk.pl
  3. #
  4. # (c) 2000 Microsoft Corporation. All rights reserved.
  5. #
  6. # Purpose: this program will search through dosnet.inf for each product and
  7. # make sure all the files exist on the CDImage shares on the local
  8. # machine.
  9. #
  10. # Version: 1.00 (06/13/2000) : (dmiura) Make international complient
  11. #---------------------------------------------------------------------
  12. #@echo off
  13. #REM ------------------------------------------------------------------
  14. #REM
  15. #REM <<template_script.cmd>>
  16. #REM <<purpose of this script>>
  17. #REM
  18. #REM Copyright (c) Microsoft Corporation. All rights reserved.
  19. #REM
  20. #REM ------------------------------------------------------------------
  21. #perl -x "%~f0" %*
  22. #goto :EOF
  23. #!perl
  24. #line 25
  25. use strict;
  26. use lib $ENV{RAZZLETOOLPATH} . "\\PostBuildScripts";
  27. use lib $ENV{RAZZLETOOLPATH};
  28. use PbuildEnv;
  29. use ParseArgs;
  30. use cksku;
  31. use ReadSetupFiles;
  32. use Logmsg;
  33. use strict;
  34. use GetIniSetting;
  35. sub Usage { print<<USAGE; exit(1) }
  36. Find missing files via dosnet.inf, log them to stdout
  37. %TMP%\\misswks.txt for wks, for instance.
  38. Usage: $0 [-d -l lang]
  39. -d Show debug info
  40. -l Language
  41. -? Displays usage
  42. Example:
  43. $0 -l jpn
  44. USAGE
  45. parseargs('?' => \&Usage,
  46. 'd' => \$Logmsg::DEBUG);
  47. # Global variable section
  48. my $Lang = $ENV{LANG};
  49. my( $ErrorCode, $Flavor, $BaseDir, $BuildArch);
  50. my( $RazPath, $RelPath );
  51. my( $TempDir, $OutFileName, %ValidFlavors );
  52. # Run the script
  53. Main();
  54. sub Main {
  55. # initialize global variables
  56. $ErrorCode = 0;
  57. $RazPath = $ENV{ "RazzleToolPath" };
  58. $TempDir = $ENV{ "TMP" };
  59. # look at _buildarch and _buildtype to see what kind of a machine
  60. # we're checking
  61. $BuildArch = $ENV{ "_BuildArch" };
  62. if ( ! ( defined( $BuildArch ) ) ) {
  63. errmsg( "Failed to find _BuildArch, exiting.");
  64. $ErrorCode++;
  65. goto ERREND;
  66. }
  67. # exclude skus even it defined in prodskus.txt
  68. my %ValidSkus = &cksku::GetSkus($ENV{lang}, $ENV{_BuildArch});
  69. my $excludeSkus = 'per pro';
  70. for my $validSku ( sort keys %ValidSkus ){
  71. $ValidFlavors{$validSku}=1 if( $excludeSkus !~ /$validSku/i );
  72. }
  73. my $PlatCode;
  74. if ( $BuildArch =~ /x86/i ) {
  75. $PlatCode = "i386";
  76. } elsif ( $BuildArch =~ /ia64/i ) {
  77. $PlatCode = "ia64";
  78. } elsif ( $BuildArch =~ /amd64/i ) {
  79. $PlatCode = "amd64";
  80. } else {
  81. errmsg( "$BuildArch is an invalid build type.");
  82. $ErrorCode++;
  83. goto ERREND;
  84. }
  85. dbgmsg( "PlatCode is $PlatCode.");
  86. # use _NTPostBld as a base if it exists, otherwise use the latest release
  87. $BaseDir = $ENV{ "_NTPostBld" };
  88. if ( ! ( -e $BaseDir ) ) {
  89. my ($LatestReturn, $ReleaseDir);
  90. $LatestReturn = `$RazPath\\PostBuildScripts\\GetLatestRelease.cmd -l:$Lang`;
  91. chomp( $LatestReturn );
  92. if ( $LatestReturn =~ /^none/i ) {
  93. errmsg( "No release tree to check, exiting.");
  94. $ErrorCode++;
  95. goto ERREND;
  96. }
  97. $ReleaseDir = &GetReleaseDir( $LatestReturn ) . "\\$Lang";
  98. if ( ! ( defined( $ReleaseDir ) ) ) {
  99. errmsg( "No release tree found, exiting.");
  100. $ErrorCode++;
  101. goto ERREND;
  102. }
  103. $RelPath = "$ReleaseDir\\$LatestReturn";
  104. if ( ! ( -e $RelPath ) ) {
  105. errmsg( "No release found at $RelPath.");
  106. $ErrorCode++;
  107. goto ERREND;
  108. }
  109. } else {
  110. $RelPath = $BaseDir;
  111. }
  112. # go into the loop to check all supported flavors
  113. foreach $Flavor ( keys %ValidFlavors ) {
  114. my (@DosnetFiles, @DosnetSecondaryFiles, @ExcDosnetFiles, @DrvIndexFiles) = ((),(),(),());
  115. my (@DriverCabLines, @DriverCabFiles, $DriverCab) = ( (), (), "");
  116. my ($ReadLine, $Line, $File);
  117. my (%HashedExcDosnetFiles, %HashedDrvIndexFiles, %HashedDriverCabFiles);
  118. my $flavor_path;
  119. $Flavor = lc( $Flavor );
  120. logmsg( "Checking $Flavor shares ...");
  121. $flavor_path = "$RelPath\\$Flavor";
  122. # Read in dosnet, excdosnt, drvindex and the contents of driver.cab
  123. if ( !ReadSetupFiles::ReadDosnet( $RelPath,
  124. $Flavor,
  125. $BuildArch,
  126. \@DosnetFiles,
  127. \@DosnetSecondaryFiles ) ) {
  128. errmsg( "Error reading dosnet file, skipping $Flavor." );
  129. next;
  130. }
  131. if ( !ReadSetupFiles::ReadExcDosnet( $RelPath,
  132. $Flavor,
  133. \@ExcDosnetFiles) ) {
  134. errmsg( "Error reading excdosnt file, skipping $Flavor." );
  135. next;
  136. }
  137. #
  138. # open the output file for this flavor
  139. #
  140. $OutFileName = "$TempDir\\miss" . $Flavor . ".txt";
  141. unless ( open( OUTFILE, ">$OutFileName" ) ) {
  142. errmsg( "Failed to open $OutFileName for writing, " .
  143. "continuing ...");
  144. $ErrorCode++;
  145. next;
  146. }
  147. # Store the excdosnt files in a hash for quick lookup
  148. %HashedExcDosnetFiles = map { lc $_ => 1 } @ExcDosnetFiles;
  149. # Loop through all of the standard files in dosnet,
  150. # checking if they exist -- ignoring files that
  151. # also appear in excdosnt as they should be in
  152. # the driver.cab
  153. foreach $File ( @DosnetFiles ) {
  154. if ( exists $HashedExcDosnetFiles{ lc $File } ) {
  155. dbgmsg( "dosnet.inf $File appears in excdosnt, ignoring..." );
  156. } else {
  157. my $CompFileName = &MakeCompName( $File );
  158. if ( ( ! ( -e "$flavor_path\\$PlatCode\\$File" ) ) &&
  159. ( ! ( -e "$flavor_path\\$PlatCode\\$CompFileName" ) ) &&
  160. ( ! ( -e "$flavor_path\\$File" ) ) &&
  161. ( ! ( -e "$flavor_path\\$CompFileName" ) ) ) {
  162. errmsg( "$Flavor missing $File");
  163. print( OUTFILE "$File\n" );
  164. $ErrorCode++;
  165. }
  166. }
  167. }
  168. # Loop through all of the secondary/d2 files (if any),
  169. # verifying their existence
  170. foreach $File ( @DosnetSecondaryFiles )
  171. {
  172. my $CompFileName = &MakeCompName( $File );
  173. my $fSuccess = 1;
  174. # WOW files
  175. if ( lc$ENV{_BUILDARCH} eq "amd64" ||
  176. lc$ENV{_BUILDARCH} eq "ia64" ) {
  177. if ( ! ( -e "$flavor_path\\i386\\$File" ) &&
  178. ! ( -e "$flavor_path\\i386\\$CompFileName" ) ) {
  179. errmsg( "$Flavor missing WOW file $File");
  180. undef $fSuccess;
  181. }
  182. }
  183. # Tablet PC Files
  184. else {
  185. if ( ! ( -e "$flavor_path\\cmpnents\\tabletpc\\i386\\$File" ) &&
  186. ! ( -e "$flavor_path\\cmpnents\\tabletpc\\i386\\$CompFileName" ) ) {
  187. errmsg( "$Flavor missing TabletPC file $File");
  188. undef $fSuccess;
  189. }
  190. }
  191. if ( !$fSuccess ) {
  192. print( OUTFILE "$File\n" );
  193. $ErrorCode++;
  194. }
  195. }
  196. #
  197. # Check contents of driver.cab
  198. #
  199. if ( !ReadSetupFiles::ReadDrvIndex( $RelPath,
  200. $Flavor,
  201. \@DrvIndexFiles) ) {
  202. errmsg( "Error reading drvindex file, skipping $Flavor." );
  203. }
  204. $DriverCab = $RelPath . "\\" . ReadSetupFiles::GetSetupDir($Flavor) . "\\driver.cab";
  205. if ( ! ( -e $DriverCab ) ) {
  206. errmsg( "File $DriverCab not found, skipping driver.cab check for $Flavor ...");
  207. $ErrorCode++;
  208. next;
  209. }
  210. # Read driver.cab
  211. @DriverCabLines = `cabarc.exe l $DriverCab`;
  212. if ( $? || !@DriverCabLines ) {
  213. errmsg( "Failed to execute \"cabarc.exe l $DriverCab\", skipping driver.cab check for $Flavor ...");
  214. $ErrorCode++;
  215. next;
  216. }
  217. # Parse output
  218. undef $ReadLine;
  219. foreach $Line ( @DriverCabLines )
  220. {
  221. chomp $Line;
  222. next if ( 0 == length( $Line ) );
  223. if ( $Line =~ /^-----------------------------/ ) { $ReadLine = 1; }
  224. elsif ( $ReadLine )
  225. {
  226. $Line =~ s/\s*(\S+)\s+.+/$1/;
  227. push @DriverCabFiles, $Line;
  228. }
  229. }
  230. # Create a hash of drvindex.inf and the
  231. # driver.cab files for quick lookup
  232. %HashedDrvIndexFiles = map { lc $_ => 1 } @DrvIndexFiles;
  233. %HashedDriverCabFiles = map { lc $_ => 1 } @DriverCabFiles;
  234. #print "\n\nARRAY VALUES:\n";
  235. #foreach ( @DrvIndexFiles ) { print "$_ "; } print "\n\n";
  236. #print "\n\nHASH VALUES:\n";
  237. #foreach ( sort keys %HashedDrvIndexFiles ) { print "$_, "; } print "\n\n";
  238. # Verify that all files that are in
  239. # excdosnt are also in drvindex
  240. # ** Not sure if this should be an error? **
  241. foreach $File ( @ExcDosnetFiles ) {
  242. if ( !exists $HashedDrvIndexFiles{ lc $File } ) {
  243. errmsg( "excdosnt.inf / drvindex.inf discrepancy in $Flavor ($File)." );
  244. # No error for now
  245. # $ErrorCode++;
  246. }
  247. }
  248. # Verify that all files that in the
  249. # driver.cab are also in drvindex
  250. # ** Not sure if this should be an error? **
  251. foreach $File ( @DriverCabFiles ) {
  252. if ( !exists $HashedDrvIndexFiles{ lc $File } ) {
  253. errmsg( "$Flavor driver.cab contains extra file $File." );
  254. # No error for now
  255. # $ErrorCode++;
  256. }
  257. }
  258. # Finally, verify that all files in
  259. # drvindex are in the driver.cab
  260. foreach $File ( @DrvIndexFiles ) {
  261. if ( !exists $HashedDriverCabFiles{ lc $File } ) {
  262. errmsg( "$Flavor driver.cab missing $File" );
  263. print( OUTFILE "(driver.cab) $File" );
  264. $ErrorCode++;
  265. }
  266. }
  267. # close the output file
  268. close( OUTFILE );
  269. }
  270. # finish up
  271. ERREND:
  272. if ( $ErrorCode > 1 ) {
  273. timemsg( "Finished with $ErrorCode errors.");
  274. } elsif ( $ErrorCode == 1 ) {
  275. timemsg( "Finished with $ErrorCode error.");
  276. } else {
  277. timemsg( "Finished.");
  278. }
  279. # remove the exit statement
  280. # exit( $ErrorCode );
  281. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  282. # End Main code section
  283. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  284. }
  285. # <Implement your subs here>
  286. #
  287. # GetReleaseDir
  288. #
  289. # returns a scalar containing the full path of the release tree
  290. sub GetReleaseDir
  291. {
  292. my( $ReleaseDirName ) = @_;
  293. my( @NetShareReturn, $Return, $NetShareLine );
  294. my( $FieldName, $FieldValue );
  295. $Return = system( "net share release >nul 2>nul" );
  296. if ( $Return != 0 ) {
  297. errmsg( "No release share found.");
  298. return( undef );
  299. }
  300. @NetShareReturn = `net share release`;
  301. # note that i'm using the second line of the net share return
  302. # to get this data. if this changes, it'll break.
  303. $NetShareLine = $NetShareReturn[1];
  304. dbgmsg( "NetShareLine is $NetShareLine");
  305. chomp( $NetShareLine );
  306. ( $FieldName, $FieldValue ) = split( /\s+/, $NetShareLine );
  307. if ( $FieldName ne "Path" ) {
  308. wrnmsg( "Second line of net share does not start with " .
  309. "\'Path\' -- possibly another language?");
  310. }
  311. dbgmsg( "FieldValue for release path is $FieldValue");
  312. return( $FieldValue );
  313. }
  314. sub MakeCompName
  315. {
  316. my( $GivenName ) = @_;
  317. my( $FilePath, $FullName, $FileExt, $NewFileExt );
  318. my( $FileName );
  319. if ( $GivenName =~ /\\/ ) {
  320. # we have a path as well as file
  321. # seperate the path from the full filename
  322. $GivenName =~ /(\S*\\)(\S+?)$/;
  323. $FilePath = $1; $FullName = $2;
  324. } else {
  325. $FilePath = ""; $FullName = $GivenName;
  326. }
  327. if ( $GivenName =~ /\./ ) {
  328. # we have an extension
  329. # seperate ext from file name
  330. $FullName =~ /(\S*\.)(\S+?)$/;
  331. $FileName = $1; $FileExt = $2;
  332. } else {
  333. $FileName = $FullName; $FileExt = "";
  334. }
  335. if ( length( $FileExt ) < 3 ) {
  336. if ( length( $FileExt ) == 0 ) { $FileExt = "\."; }
  337. $NewFileExt = $FileExt . "\_";
  338. } else {
  339. $NewFileExt = substr( $FileExt, 0, 2 ) . "\_";
  340. }
  341. return( "$FilePath$FileName$NewFileExt" );
  342. }
  343. sub ValidateParams {
  344. #<Add your code for validating the parameters here>
  345. }