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.

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