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.

615 lines
17 KiB

  1. #---------------------------------------------------------------------------
  2. # Script: fixprn.pl
  3. #
  4. # (c) 2000 Microsoft Corporation. All rights reserved.
  5. #
  6. # Purpose: This script populates the fixprnsv tree with the driver files.
  7. #
  8. # Version: <1.00> (10/03/2000) : (hsingh) Wrote it
  9. # <1.01> (<mm/dd/yyyy>) : (<your alias>) <Purpose>
  10. #---------------------------------------------------------------------
  11. # Set Package
  12. package fixprn;
  13. # Set the script name
  14. $ENV{script_name} = 'fixprn.pl';
  15. # Set version
  16. $VERSION = '1.00';
  17. # Set required perl version
  18. require 5.003;
  19. # Use section
  20. use lib $ENV{RAZZLETOOLPATH} . "\\PostBuildScripts";
  21. use lib $ENV{RAZZLETOOLPATH};
  22. use GetParams;
  23. use LocalEnvEx;
  24. use CkSKU;
  25. use Logmsg;
  26. use strict;
  27. no strict 'vars';
  28. sub Main {
  29. # Convert to uppercase the env var names.
  30. &UCENV();
  31. #
  32. # Get/Create Various Environment Variables.
  33. # $lang : The build language.
  34. # For US builds, this will be USA
  35. # LOGFILE : Path to log file
  36. # FIXPRNSRC : Root of fixprnsv tree. (the source)
  37. # FIXPRNDST : Root of fixprnsv tree. (the destination)
  38. # PRNTOOLS : Points to directory where we have infs etc ($FIXPRNROOT$\inf)...
  39. # TEMP : temporary directory
  40. # NTPOSTBLD : Path to the postbuild directory. This is where files are placed
  41. # after buing built (or after being built & localized as the case may be)
  42. &GetEnv();
  43. &CreateEnv();
  44. #
  45. # Lets ensure that the required source files are present,
  46. # lets create all the directories files etc...
  47. #
  48. &EnsurePathCorrectness();
  49. #
  50. # Create list of printer driver files
  51. # NT4FILES : will have list of NT4 files.
  52. # W2KFILES : will have list of Win2k/Whistler files.
  53. #
  54. $NT4FILES = "$TEMP\\nt4.txt";
  55. $W2KFILES = "$TEMP\\w2k.txt";
  56. #
  57. # Lets create the list of NT4FILES and W2KFILES
  58. # from the badnt4.inf and badw2k.inf
  59. #
  60. &CreateW2KFileList();
  61. &CreateNT4FileList();
  62. #
  63. # Converting the contents of the file lists to lower case
  64. #
  65. &uc_to_lc($NT4FILES);
  66. &uc_to_lc($W2KFILES);
  67. #
  68. # Copy Win2k/Whistler files from _NTPOSTBUILD
  69. # to $FIXPRNDST\win2k\i386
  70. #
  71. &cp_w2k_files();
  72. #
  73. # Copy NT4 files from ............
  74. # to $FIXPRNDST\nt4\i386
  75. #
  76. &cp_nt4_files();
  77. #
  78. # Create the catalogue files and do PRS signing.
  79. # AdinaS says that international build lab people
  80. # will own the signing of the non-US bld cats.
  81. # But we still have to create cat for all languages.
  82. #
  83. logmsg("The lang is $lang");
  84. &make_cats();
  85. }
  86. #
  87. # Copy files in $W2KFILES to $FIXPRNDST\win2k\i386
  88. #
  89. sub cp_w2k_files
  90. {
  91. logmsg ("Deleting all files in $FIXPRNDST\\win2k\\i386");
  92. do_cmd("del /q", "$FIXPRNDST\\win2k\\i386\\*.*");
  93. logmsg ("Copying Whistler files");
  94. open(W2K, "$W2KFILES") or &ExitError("Can not open $W2KFILES, created by infflist");
  95. while(<W2K>)
  96. {
  97. $FILE = $_;
  98. chomp($FILE);
  99. if ($FILE ne "badw2k.inf")
  100. {
  101. if ( $FILE =~ /^srgb .+\.icm/i ) {
  102. $FILE="srgb.icm";
  103. }
  104. logmsg ("Copying $NTPOSTBLD\\$FILE to $FIXPRNDST\\win2k\\i386");
  105. do_cmd("copy /y", "$NTPOSTBLD\\$FILE", "$FIXPRNDST\\win2k\\i386");
  106. }
  107. }
  108. }
  109. #
  110. # Copy files in $NT4FILES to $FIXPRNDST\nt4\i386
  111. # NT4 files are of 3 types
  112. # 1. Those that are similar to Win2k. (mainly gpd's)
  113. # 2. Those that are specific to NT4 and do not need to be localized (gpds)
  114. # 3. Those that are specific to NT4 but have to be localized (e.g. .dlls, .hlp)
  115. # Files of type 2,3 will be checked into the source depot. During the build process
  116. # they will be (localized and) binplaced into $FIXPRNDST\nt4\i386.
  117. # Therefore we dont need to copy them using this script. We only need
  118. # to take care of files of type 1.
  119. # So we need to a list of files that are of type 1. This
  120. # list will be checked into SD and placed in \printers\fixprnsv\nt4w2kcm.lst
  121. # during the build process.
  122. #
  123. sub cp_nt4_files
  124. {
  125. #
  126. # Because of some build/postbuild script that I dont really know about,
  127. # some files are getting copied to $FIXPRNDST\\nt4\\386.
  128. # Lets delete those files.
  129. #
  130. logmsg ("Deleting any files in $FIXPRNDST\\nt4\\i386");
  131. do_cmd("del /q", "$FIXPRNDST\\nt4\\i386\\*.*");
  132. #
  133. # NT4 files are gathered from 2 places.
  134. # 1. Those that are NT4 specific are copied from scratch directory.
  135. # 2. Those that are common with Whistler are copied from Whistler
  136. # post build directory.
  137. #
  138. # Lets first deal with files of type 1.
  139. # Copying NT4 files that were binplaced during build time but
  140. # are now in some scratch directory.
  141. # Postbuild should not delete any files that has been binplaced
  142. # during build time. Since we dont want to ship the uncompressed files
  143. # and we cannot delete them either, therefore the build has to place
  144. # the files in a scratch tree.
  145. #
  146. logmsg ("Copying files from scratch tree - $FIXPRN_NT4_SCRATCH");
  147. do_cmd("copy /y", "$FIXPRN_NT4_SCRATCH\\nt4\\i386\\*.*", "$FIXPRNDST\\nt4\\i386");
  148. logmsg ("Copying NT4 files that are same as Whistler files");
  149. $nt4w2kcommon = "$FIXPRN_NT4_SCRATCH\\nt4w2kcm.lst";
  150. #
  151. # File of type 2. (i.e. those common with Whistler).
  152. # 1. Open nt4w2kcm.lst (which has list of common files).
  153. # 2. clean it i.e. remove blank lines, needless spaces etc..
  154. # 3. Copy files from %NTPOSTBLD% to \printers\fixprnsv\nt4\i386
  155. #
  156. open(NT4W2K, "$nt4w2kcommon") or &ExitError("Can not open $nt4w2kcommon : list of files common to nt4,w2k");
  157. while(<NT4W2K>)
  158. {
  159. $FILE = $_;
  160. chomp($FILE);
  161. if ($FILE ne "")
  162. {
  163. logmsg ("Copying $NTPOSTBLD\\$FILE to $FIXPRNDST\\nt4\\i386");
  164. do_cmd("copy /y", "$NTPOSTBLD\\$FILE", "$FIXPRNDST\\nt4\\i386");
  165. }
  166. }
  167. close NT4W2K;
  168. #
  169. # Dont need the filelist anymore.
  170. # But should not delete it since post build can run more than once.
  171. # Whenever this script runs, it needs this file. So if this file
  172. # is deleted, script will fail, and that will be a build break.
  173. # logmsg ("Deleting $nt4w2kcommon");
  174. # do_cmd("del /q", "$nt4w2kcommon");
  175. }
  176. sub make_cats
  177. {
  178. my $CDFPATH="$TEMP\\cdf";
  179. $W2KPATH = "$FIXPRNDST\\win2k";
  180. $NT4PATH = "$FIXPRNDST\\nt4";
  181. system "if not exist $CDFPATH md $CDFPATH";
  182. #
  183. # To create the .cat file there are two steps
  184. # Step 1 = Create .cdf file
  185. # Step 2 = Use the .cdf file to create .cat file.
  186. #
  187. #
  188. # Step 1 . Create .cdf file for Whistler drivers.
  189. #
  190. logmsg("Creating w2kfspx.cat");
  191. @W2KFILES = `dir /b /a-d $W2KPATH\\i386`;
  192. open(CDFFILE, ">$CDFPATH\\w2kfpsx.cdf" ) or &ExitError("Can not create w2kfpsx.cdf");
  193. print CDFFILE "\[CatalogHeader\]\nName=w2kfpsx\nPublicVersion=0x0000001\nEncodingType=0x00010001\nCATATTR1=0x10010001:OSAttr:2:5.2,2:5.1,2:5.0\n\[CatalogFiles\]\n";
  194. print CDFFILE "<hash>$W2KPATH\\badw2k.inf=$W2KPATH\\badw2k.inf\n";
  195. print CDFFILE "<hash>$FIXPRNDST\\printupg.inf=$FIXPRNDST\\printupg.inf\n";
  196. foreach (@W2KFILES) {
  197. chomp $_;
  198. print CDFFILE "<hash>$W2KPATH\\i386\\$_=$W2KPATH\\i386\\$_\n";
  199. }
  200. close CDFFILE;
  201. #
  202. # Step 2. Create the .cat file for Whistler drivers
  203. #
  204. chdir "$W2KPATH";
  205. if ( system ("makecat $CDFPATH\\w2kfpsx.cdf") )
  206. {
  207. &ExitError( "makecat $CDFPATH\\w2kfpsx.cdf failed" );
  208. }
  209. if ( $lang eq "usa" )
  210. {
  211. logmsg("Attempting to sign w2kfpsx.cat");
  212. system ("ntsign.cmd -f w2kfpsx.cat");
  213. }
  214. #
  215. # Compress the files in $W2KPATH\\i386 directory.
  216. # Removes the uncompressed files.
  217. #
  218. &CompressAndRemove("$W2KPATH\\i386");
  219. #
  220. # Step 1. Create .cdf file for NT4 Drivers.
  221. #
  222. logmsg("Creating nt4fpsx.cat");
  223. @NTXFILES = `dir /b /a-d $NT4PATH\\i386`;
  224. open(CDFFILE, ">$CDFPATH\\nt4fpsx.cdf" ) or &ExitError("Can not create nt4fpsx.cdf");
  225. print CDFFILE "\[CatalogHeader\]\nName=nt4fpsx\nPublicVersion=0x0000001\nEncodingType=0x00010001\nCATATTR1=0x10010001:OSAttr:2:4.x\n\[CatalogFiles\]\n";
  226. print CDFFILE "<hash>$NT4PATH\\badnt4.inf=$NT4PATH\\badnt4.inf\n";
  227. foreach(@NTXFILES) {
  228. chomp $_;
  229. print CDFFILE "<hash>$NT4PATH\\i386\\$_=$NT4PATH\\i386\\$_\n";
  230. }
  231. close CDFFILE;
  232. #
  233. # Step 2. Create .cat file for NT4 Drivers.
  234. #
  235. chdir "$NT4PATH";
  236. if ( system ("makecat $CDFPATH\\nt4fpsx.cdf"))
  237. {
  238. &ExitError( "makecat $CDFPATH\\nt4fpsx.cdf failed" );
  239. }
  240. if ( $lang eq "usa" )
  241. {
  242. logmsg("Attempting to sign nt4fpsx.cat");
  243. system ("ntsign.cmd -f nt4fpsx.cat");
  244. }
  245. &CompressAndRemove("$NT4PATH\\i386");
  246. # $CDFPATH is in temp directory. So no need to remove it (Bug # 342330)
  247. # logmsg("Deleting $CDFPATH");
  248. # system "rd /s /q $CDFPATH";
  249. }
  250. #
  251. # Compresses files in the directory.
  252. # Renames them by adding _ at the end of file name
  253. # (e.g. unirv.dll will be renames unidrv.dl_ ).
  254. # Removes the orginal file
  255. #
  256. sub CompressAndRemove {
  257. #
  258. # 1) First compress the files. Compressed files will have _ at end.
  259. # Now the directory will have both compressed and non-compressed
  260. # files.
  261. # 2) Make the files with _ read only.
  262. # 3) Delete all the files that are not read only.
  263. # 4) remove the read only attribute from the _ files.
  264. # (not sure if this is required, but lets just do it)
  265. #
  266. $DIRECTORY = $_[0];
  267. logmsg("Compressing files in $DIRECTORY");
  268. system "compress -r $DIRECTORY\\*.* > nul";
  269. system "attrib +r $DIRECTORY\\*.*_";
  270. system "del /q /a:-R $DIRECTORY\\*";
  271. system "attrib -r $DIRECTORY\\*";
  272. }
  273. #
  274. # (Read comment for CreateW2KFileList)
  275. #
  276. sub CreateNT4FileList {
  277. &GetInfflist( "$NTPOSTBLD\\printers\\fixprnsv\\nt4", "badnt4.inf", $NT4FILES );
  278. }
  279. #
  280. # Create list of Win2K/Whistler Files. For US builds, this will be the list
  281. # of files in badw2k.inf. For FE builds, this list will, in addition,
  282. # have files that are required only for FE builds. (Assuming that
  283. # badw2k.inf will already have have language specific entries merged into it).
  284. #
  285. sub CreateW2KFileList {
  286. &GetInfflist( "$NTPOSTBLD\\printers\\fixprnsv\\win2k", "badw2k.inf", $W2KFILES );
  287. }
  288. #
  289. # Gets the list of files in an inf.
  290. # 1st param = path of the inf file (i.e. the directory)
  291. # 2nd param = the inf file name
  292. # 3rd param = the destination of the list of driver file names
  293. # as extracted from the inf.
  294. #
  295. sub GetInfflist {
  296. my ( $infpath, $inffile, $flist) = @_;
  297. logmsg ("Extracting file list from $infpath\\$inffile");
  298. if ( ! -e "$infpath\\$inffile" ) {
  299. &ExitError ( "Unable to find $infpath\\$inffile");
  300. }
  301. chdir($infpath);
  302. system "infflist.exe $infpath\\$inffile > $flist";
  303. }
  304. #
  305. # Convert contents to lower case.
  306. #
  307. sub uc_to_lc
  308. {
  309. logmsg("Converting to lowercase: $_[0]");
  310. open(FILE, $_[0] ) or &ExitError( "Can not open $_[0]");
  311. open(TEMP, ">$TEMP\\tmp.txt") or &ExitError( "Can not open temp file");
  312. $CHG = <FILE>;
  313. while($CHG)
  314. {
  315. $CHG =~ tr/A-Z/a-z/;
  316. print TEMP "$CHG";
  317. $CHG = <FILE>;
  318. }
  319. close FILE;
  320. close TEMP;
  321. system "del $_[0]";
  322. do_cmd("copy /y", "$TEMP\\tmp.txt", "$_[0]");
  323. }
  324. #
  325. # Ensures the various paths/files required are present.
  326. # If they are not, then it either exits or creates (as the
  327. # case may be)
  328. #
  329. sub EnsurePathCorrectness
  330. {
  331. if ( ! -e "$FIXPRNSRC" )
  332. {
  333. &ExitError("Fixprnsv source directory not found : $FIXPRNSRC");
  334. }
  335. if ( ! -e "$NTPOSTBLD" )
  336. {
  337. &ExitError("Post Build directory not available : $NTPOSTBLD");
  338. }
  339. if ( ! -e "$FIXPRNDST" ) {
  340. &ExitError("Building of fixprnsv should have created $FIXPRNDST directory. Cant continue without it");
  341. }
  342. if ( ! -e "$FIXPRN_NT4_SCRATCH\\nt4w2kcm.lst" )
  343. {
  344. &ExitError("Building of fixprnsv should have binplaced nt4w2kcm.lst in $FIXPRN_NT4_SCRATCH directory. Cant continue without it");
  345. }
  346. system "if not exist $FIXPRNDST\\nt4\\i386 md $FIXPRNDST\\nt4\\i386";
  347. system "if not exist $FIXPRNDST\\win2k\\i386 md $FIXPRNDST\\win2k\\i386";
  348. }
  349. #
  350. # Changes environment variables to uppercase.
  351. #
  352. sub UCENV {
  353. %UCENV=();
  354. foreach (%ENV) {
  355. $UCENV{uc($_)}=$ENV{$_};
  356. }
  357. }
  358. sub GetEnv
  359. { $SCRIPT_NAME="fixprn.pl";
  360. if ( exists $UCENV{'LANG'} ) {
  361. $LANG = $UCENV{'LANG'};
  362. } else {
  363. $LANG="";
  364. }
  365. if ( exists $UCENV{'_NTPOSTBLD'} ) {
  366. $NTPOSTBLD = $UCENV{'_NTPOSTBLD'};
  367. } else {
  368. die "_NTPOSTBLD environment variable not defined.";
  369. }
  370. if ( exists $UCENV{'TEMP'} ) {
  371. $TEMP = $UCENV{'TEMP'};
  372. if ( $LANG ) {
  373. $TEMP = "$TEMP\\$LANG";
  374. }
  375. } else {
  376. die "TEMP environment variable not defined.";
  377. }
  378. system "if not exist $TEMP md $TEMP";
  379. }
  380. #
  381. # Create various environment variables
  382. # that will be required by script.
  383. #
  384. sub CreateEnv {
  385. #
  386. # Define the LOGFILE if noy already defined.
  387. #
  388. if ( exists $UCENV{'LOGFILE'} ) {
  389. $LOGFILE =$UCENV{'LOGFILE'};
  390. } else {
  391. $LOGFILE="$TEMP\\FIXPRVSV.LOG";
  392. if ( -e $LOGFILE ) { unlink $LOGFILE; }
  393. }
  394. #
  395. # Check the environment
  396. # FIXPRNSRC : will point to the directory where
  397. # we have infs, any text files for special processing
  398. # etc...
  399. # FIXPRNDST : will point to the destination (where the files
  400. # need to be copied after all processing has been done)
  401. #
  402. #
  403. if ( exists $UCENV{'_NTBINDIR'} ) {
  404. $NTBINDIR = $UCENV{'_NTBINDIR'};
  405. } else {
  406. &ExitError("Undefined _NTBINDIR");
  407. }
  408. if ( exists $UCENV{'FIXPRNSRC'} ) {
  409. $FIXPRNSRC = $UCENV{'FIXPRNSRC'};
  410. } else {
  411. $FIXPRNSRC = "$NTPOSTBLD\\printers\\fixprnsv";
  412. }
  413. if ( exists $UCENV{'PRNTOOLS'} ) {
  414. $PRNTOOLS = $UCENV{'PRNTOOLS'};
  415. } else {
  416. $PRNTOOLS = "$NTPOSTBLD\\printers\\fixprnsv\\infs";
  417. }
  418. if ( exists $UCENV{'FIXPRNDST'} ) {
  419. $FIXPRNDST = $UCENV{'FIXPRNDST'};
  420. } else {
  421. $FIXPRNDST = "$NTPOSTBLD\\printers\\fixprnsv";
  422. }
  423. if ( exists $UCENV{'FIXPRN_NT4_SCRATCH'} ) {
  424. $FIXPRN_NT4_SCRATCH = $UCENV{'FIXPRN_NT4_SCRATCH'};
  425. } else {
  426. $FIXPRN_NT4_SCRATCH = "$NTPOSTBLD\\fixprnscratch";
  427. }
  428. }
  429. sub ExitError {
  430. my ($errmsg) = @_;
  431. errmsg ("$errmsg\n");
  432. exit(1);
  433. }
  434. sub do_cmd
  435. {
  436. $CMD = $_[0];
  437. $SRC = $_[1];
  438. $DEST = $_[2];
  439. $ERR = system "$CMD $SRC $DEST > nul";
  440. if($ERR)
  441. {
  442. errmsg("Could not $CMD $SRC to $DEST");
  443. }
  444. }
  445. sub CopyFile {
  446. my ($file, $dest) = @_;
  447. logmsg( "Copying $file $dest");
  448. if ( ! -e $file ) {
  449. &ExitError( "File $file not found");
  450. }
  451. do_cmd("copy /y", "$file", "$dest");
  452. }
  453. sub ValidateParams {
  454. #<Add your code for validating the parameters here>
  455. }
  456. sub Usage {
  457. print <<USAGE;
  458. Usage : perl fixprn.pl <Path to Windows 2000 binary directory
  459. (where files are placed after being built (and localized)>
  460. <Path to the compressed binaries share>
  461. [<Path to NT4 files>]
  462. Script populates %binaries%\\printers\\fixprnsv with the Windows 2000 drivers.
  463. NT4 files updated if NT4 parameter is specified.
  464. Parameter 1 (Mandatory) - Path to the Windows 2000 driver.cab
  465. e.g. \\\\ntbuilds\\release\\usa\\2180\\x86\\fre.wks
  466. Parameter 2 (Mandatory) - Path to the compressed binaries share
  467. e.g. \binaries.comp
  468. Parameter 3 (Optional) - Give NT4 as second parameter
  469. if refresh of NT4 binaries is required.
  470. Parameter 4 (Mandatory if Paraneter 2 is NT4)
  471. Path to NT Service Pack till the place where unidrv5.4
  472. driver files are present.
  473. e.g. \\\\ntbuilds\\release\\usa\\svcpack\\sp6\\1.058\\support\\printersEOM
  474. USAGE
  475. }
  476. sub GetParams {
  477. # Step 1: Call pm getparams with specified arguments
  478. &GetParams::getparams(@_);
  479. # Step 2: Set the language into the enviroment
  480. $ENV{lang}=$lang;
  481. # Step 3: Call the usage if specified by /?
  482. if ($HELP) {
  483. &Usage();
  484. exit 1;
  485. }
  486. }
  487. if (eval("\$0 =~ /" . __PACKAGE__ . "\\.pl\$/i")) {
  488. # Step 1: Parse the command line
  489. # <run perl.exe GetParams.pm /? to get the complete usage for GetParams.pm>
  490. &GetParams ('-o', 'l:', '-p', 'lang', @ARGV);
  491. # Include local environment extensions
  492. &LocalEnvEx::localenvex('initialize');
  493. # Set lang from the environment
  494. $lang=$ENV{lang};
  495. # Validate the option given as parameter.
  496. &ValidateParams;
  497. # Exit if not a server product
  498. %ValidFlavors = &cksku::GetSkus($ENV{lang}, $ENV{_BuildArch});
  499. if ( exists $ValidFlavors{'bla'} || $ValidFlavors{'sbs'} || exists $ValidFlavors{'srv'} || exists $ValidFlavors{'ads'} || exists $ValidFlavors{'dtc'} ) {
  500. # Step 4: Call the main function
  501. &fixprn::Main();
  502. } else {
  503. logmsg("Fixprnsv not applicable to this pro-only language.");
  504. }
  505. # End local environment extensions.
  506. &LocalEnvEx::localenvex('end');
  507. }