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.

474 lines
12 KiB

  1. package SymMake;
  2. use lib $ENV{RAZZLETOOLPATH} . "\\PostBuildScripts";
  3. use lib $ENV{RAZZLETOOLPATH};
  4. use strict;
  5. use Carp;
  6. use IO::File;
  7. use Data::Dumper;
  8. use File::Basename;
  9. use File::Find;
  10. use Logmsg;
  11. # Data structure
  12. # pdbname.binext => [(var)pdbpath,size,$binext]
  13. my ($DDFHandle, $CATHandle, $INFHandle);
  14. my %pktypes = (
  15. FULL => 'ARCH',
  16. UPDATE => 'NTPB'
  17. );
  18. my %revpktypes = reverse %pktypes;
  19. sub new {
  20. my $class = shift;
  21. my $instance = {
  22. KB => {
  23. "$pktypes{'FULL'}" => $_[0],
  24. "$pktypes{'UPDATE'}" => $_[1]
  25. },
  26. SYM => {},
  27. EXT => {},
  28. HANDLE => {},
  29. PKTYPE => undef
  30. };
  31. return bless $instance, $class;
  32. }
  33. sub ReadSource
  34. {
  35. my ($self, $symbolcd) = @_;
  36. my ($fh, $kbterm, $mykey, @mylist);
  37. local $_;
  38. $kbterm = $pktypes{$self->{'PKTYPE'}};
  39. $symbolcd = "$self->{'KB'}->{$kbterm}\\symbolcd\\symbolcd.txt" if (!defined $symbolcd);
  40. $symbolcd = "$ENV{TEMP}\\symbolcd.txt" if (!-e $symbolcd);
  41. if ($self->{'PKTYPE'} =~ /FULL/i) {
  42. if (-e $symbolcd) { # reuse
  43. ($self->{'SYM'}, $self->{'EXT'}) = @{do $symbolcd};
  44. } else { # create one
  45. $self->HashArchServer($self->{'KB'}->{$kbterm});
  46. # reuse
  47. $Data::Dumper::Indent=1;
  48. $Data::Dumper::Terse=1;
  49. $fh = new IO::File $symbolcd, 'w';
  50. if (!defined $fh) {
  51. logmsg "Cannot open $symbolcd\.";
  52. } else {
  53. print $fh 'return [';
  54. print $fh Dumper($self->{'SYM'});
  55. print $fh ",\n";
  56. print $fh Dumper($self->{'EXT'});
  57. print $fh '];';
  58. $fh->close();
  59. }
  60. }
  61. } else {
  62. $self->HashSymbolCD($symbolcd);
  63. }
  64. return;
  65. #
  66. # $Data::Dumper::Indent=1;
  67. # $Data::T
  68. # print Dumper($self->{'SYM'}, qw(sym)
  69. }
  70. sub HashSymbolCD
  71. {
  72. my ($self, $file) = @_;
  73. my ($fh, $bin, $symbol, $subpath, $installpath, $kbterm);
  74. local $_;
  75. $kbterm = $pktypes{$self->{'PKTYPE'}};
  76. $fh = new IO::File $file;
  77. if (!defined $fh) {
  78. logmsg "Cannot open symbolcd.txt ($file)";
  79. return;
  80. }
  81. while(<$fh>) {
  82. chomp;
  83. ($bin,$symbol,$subpath,$installpath)=split(/\,/,$_);
  84. next if (!defined $installpath);
  85. $self->{'SYM'}->{lc"$symbol\.$installpath"} = [$kbterm, "\\" . $subpath, (-s $self->{'KB'}->{$kbterm} . '\\' . $subpath), lc$installpath];
  86. for (keys %pktypes) {
  87. $self->{'EXT'}->{$_}->{lc$installpath} = 1;
  88. }
  89. }
  90. $fh->close();
  91. }
  92. sub HashArchServer
  93. {
  94. my ($self, $path) = @_;
  95. my ($fh, $bin, $symbol, $subpath, $installpath, $kbterm, $pdbsize);
  96. local $_;
  97. $kbterm = $pktypes{$self->{'PKTYPE'}};
  98. $fh = new IO::File "dir /s/b/a-d $path\\*.*|";
  99. if (!defined $fh) {
  100. logmsg "Cannot access to $path\.";
  101. }
  102. while (<$fh>) {
  103. chomp;
  104. $pdbsize = (-s);
  105. $_ = substr($_, length($path) + 1);
  106. /\\/;
  107. ($symbol, $subpath, $installpath) = ($',$_,$`);
  108. $self->{'SYM'}->{lc"$symbol\.$installpath"} = [$kbterm, '\\' . $subpath, $pdbsize, $installpath];
  109. $self->{'EXT'}->{$self->{'PKTYPE'}}->{$installpath} = 1;
  110. }
  111. $fh->close();
  112. }
  113. #
  114. # pkinfoptr->
  115. # FULL ->
  116. # CDFNAME =>
  117. # INFNAME =>
  118. #
  119. sub Create_Symbols_CDF
  120. {
  121. my ($self, $pkinfoptr) = @_;
  122. my ($mykbterm, $mypkname, $fhandle, $fullpdb, %mywriter);
  123. local $_;
  124. &Open_Private_Handle($pkinfoptr, 'CDF');
  125. for $mypkname (keys %{$pkinfoptr}) {
  126. if ($mypkname ne 'FULL') {
  127. $mywriter{$mypkname} = &Writer($pkinfoptr->{$mypkname}->{'CDFHANDLE'}, $pkinfoptr->{'FULL'}->{'CDFHANDLE'});
  128. } else {
  129. $mywriter{$mypkname} = &Writer($pkinfoptr->{'FULL'}->{'CDFHANDLE'});
  130. }
  131. &Create_CDF_Head($pkinfoptr->{$mypkname}->{'CDFHANDLE'}, $pkinfoptr->{$mypkname}->{'CATNAME'}, $pkinfoptr->{$mypkname}->{'INFNAME'});
  132. }
  133. for (sort keys %{$self->{'SYM'}}) {
  134. $mykbterm = $self->{'SYM'}->{$_}->[0];
  135. $mypkname = $revpktypes{$mykbterm};
  136. $fullpdb = $self->{'KB'}->{$mykbterm} . $self->{'SYM'}->{$_}->[1];
  137. &{$mywriter{$mypkname}}("\<HASH\>" . $fullpdb . '=' . $fullpdb . "\n");
  138. }
  139. &Close_Private_Handle($pkinfoptr, 'CDF');
  140. }
  141. #
  142. # pkinfoptr->
  143. # FULL ->
  144. # CABNAME =>
  145. # CABDEST =>
  146. # CABSIZE =>
  147. # DDFLIST => (return cab list)
  148. #
  149. sub Create_Symbols_DDF
  150. {
  151. my ($self, $pkinfoptr) = @_;
  152. my ($symkey, $symptr, $kbterm, $subpath, $pktype, $mypkinfoptr, $cabname, $ddfname, $cabcount, $DDFHandle, $myddfname, $mycabname);
  153. local $_;
  154. # initialization
  155. map({$_->{'CURSIZE'} = $_->{'CABSIZE'}} values %{$pkinfoptr});
  156. for (sort keys %{$self->{'SYM'}}) {
  157. $symkey = $_;
  158. $symptr = $self->{'SYM'}->{$_};
  159. ($kbterm, $subpath) = ($symptr->[0],$symptr->[1]);
  160. $pktype = $revpktypes{$kbterm};
  161. # don't generate something not specify
  162. next if (!exists $pkinfoptr->{$pktype});
  163. $mypkinfoptr = $pkinfoptr->{$pktype};
  164. $mypkinfoptr->{'CURSIZE'}+=$symptr->[2];
  165. if ($mypkinfoptr->{'CURSIZE'} >= $mypkinfoptr->{'CABSIZE'}) {
  166. $mypkinfoptr->{'CURSIZE'} = $symptr->[2];
  167. ($cabname, $ddfname, $cabcount) = (
  168. $mypkinfoptr->{'CABNAME'},
  169. $mypkinfoptr->{'DDFNAME'},
  170. ++$mypkinfoptr->{'CABCOUNT'}
  171. );
  172. $myddfname = $ddfname . $cabcount . '.ddf';
  173. $mycabname = $cabname . $cabcount . '.cab';
  174. $mypkinfoptr->{'DDFHANDLE'} = new IO::File $myddfname, 'w';
  175. if (!defined $mypkinfoptr->{'DDFHANDLE'}) {
  176. logmsg "Cannot open DDF file $myddfname\.";
  177. }
  178. &Create_DDF_Head($mypkinfoptr->{'DDFHANDLE'}, $mycabname);
  179. $mypkinfoptr->{'DDFLIST'}->{$myddfname} = $mycabname;
  180. }
  181. $DDFHandle = $mypkinfoptr->{'DDFHANDLE'};
  182. print $DDFHandle '"' . $self->{'KB'}->{$kbterm} . $subpath . '" "' . $symkey . "\"\n";
  183. }
  184. &Close_Private_Handle($pkinfoptr, 'DDF');
  185. }
  186. #
  187. # pkinfoptr->
  188. # FULL ->
  189. # INFNAME =>
  190. # CDFNAME =>
  191. #
  192. sub Create_Symbols_INF
  193. {
  194. my ($self, $pkinfoptr) = @_;
  195. my ($mypkname, $mypkinfoptr, $INFHandle, %mywriter, %mysepwriter, %h, %cabnames);
  196. local $_;
  197. &Open_Private_Handle($pkinfoptr, 'INF');
  198. for $mypkname (keys %{$pkinfoptr}) {
  199. ($mypkinfoptr, $INFHandle) = ($pkinfoptr->{$mypkname}, $pkinfoptr->{$mypkname}->{'INFHANDLE'});
  200. if ($mypkname ne 'FULL') {
  201. $mywriter{$mypkname} = &Writer($INFHandle, $pkinfoptr->{'FULL'}->{'INFHANDLE'});
  202. } else {
  203. $mywriter{$mypkname} = &Writer($INFHandle);
  204. }
  205. $mysepwriter{$mypkname} = &Writer($INFHandle);
  206. &Create_INF_Version($INFHandle, $mypkinfoptr->{'CATNAME'});
  207. &Create_INF_Install($INFHandle, $self->{'EXT'}->{$mypkname});
  208. $cabnames{$mypkname} = (FileParse($mypkinfoptr->{'CABNAME'}))[0];
  209. }
  210. &Create_INF_Files($self->{'SYM'}, \%mysepwriter, \%mywriter);
  211. &Create_INF_SourceDisks($self->{'SYM'}, \%cabnames, \%mysepwriter, \%mywriter);
  212. &Close_Private_Handle($pkinfoptr, 'INF');
  213. }
  214. sub Create_DDF_Head
  215. {
  216. my ($DDFHandle, $cabname) = @_;
  217. my ($mycabname, $mycabdest) = FileParse($cabname);
  218. print $DDFHandle <<DDFHEAD;
  219. .option explicit
  220. .Set DiskDirectoryTemplate=$mycabdest
  221. .Set RptFileName=nul
  222. .Set InfFileName=nul
  223. .Set CabinetNameTemplate=$mycabname\.cab
  224. .Set CompressionType=MSZIP
  225. .Set MaxDiskSize=CDROM
  226. .Set ReservePerCabinetSize=0
  227. .Set Compress=on
  228. .Set CompressionMemory=21
  229. .Set Cabinet=ON
  230. .Set MaxCabinetSize=999999999
  231. .Set FolderSizeThreshold=1000000
  232. DDFHEAD
  233. }
  234. sub Create_CDF_Head
  235. {
  236. my ($CDFHandle, $catname, $infname) = @_;
  237. $catname = (FileParse($catname))[0];
  238. print $CDFHandle <<CDFHEAD;
  239. [CatalogHeader]
  240. Name=$catname
  241. PublicVersion=0x00000001
  242. EncodingType=0x00010001
  243. CATATTR1=0x10010001:OSAttr:2:5.X
  244. [CatalogFiles]
  245. \<HASH\>$infname\.inf=$infname\.inf
  246. CDFHEAD
  247. }
  248. sub Create_INF_Version
  249. {
  250. my ($INFHandle, $catname) = @_;
  251. $catname = (FileParse($catname))[0];
  252. print $INFHandle <<INFVERSION;
  253. [Version]
  254. AdvancedInf= 2.5
  255. Signature= "\$CHICAGO\$"
  256. CatalogFile= $catname\.CAT
  257. INFVERSION
  258. }
  259. sub Create_INF_Install
  260. {
  261. my ($INFHandle, $exthptr) = @_;
  262. my $CopyFiles = 'Files.' . join(", Files\.", sort keys %{$exthptr});
  263. print $INFHandle <<INF_INSTALL;
  264. [DefaultInstall]
  265. CustomDestination= CustDest
  266. AddReg= RegVersion
  267. BeginPrompt= BeginPromptSection
  268. EndPrompt= EndPromptSection
  269. RequireEngine= Setupapi;
  270. CopyFiles= $CopyFiles
  271. [DefaultInstall.Quiet]
  272. CustomDestination=CustDest.2
  273. AddReg= RegVersion
  274. RequireEngine= Setupapi;
  275. CopyFiles= $CopyFiles
  276. [BeginPromptSection]
  277. Title= "Microsoft Windows Symbols"
  278. [EndPromptSection]
  279. Title= "Microsoft Windows Symbols"
  280. Prompt= "Installation is complete"
  281. [RegVersion]
  282. "HKLM","SOFTWARE\\Microsoft\\Symbols\\Directories","Symbol Dir",0,"\%49100\%"
  283. "HKCU","SOFTWARE\\Microsoft\\Symbols\\Directories","Symbol Dir",0,"\%49100\%"
  284. "HKCU","SOFTWARE\\Microsoft\\Symbols\\SymbolInstall","Symbol Install",,"1"
  285. [SymCust]
  286. "HKCU", "Software\\Microsoft\\Symbols\\Directories","Symbol Dir","Symbols install directory","\%25\%\\Symbols"
  287. [CustDest]
  288. 49100=SymCust,1
  289. [CustDest.2]
  290. 49100=SymCust,5
  291. [DestinationDirs]
  292. ;49100 is \%systemroot\%\\symbols
  293. Files.inf = 17
  294. Files.system32 = 11
  295. INF_INSTALL
  296. for (sort keys %{$exthptr}) {
  297. printf $INFHandle ("Files\.%-6s\t\t\= 49100,\"%s\"\n", $_, $_);
  298. }
  299. }
  300. sub Create_INF_Files
  301. {
  302. my ($symptr, $sepwriter, $popwriter) = @_;
  303. my ($mykbterm, $mypkname, %tags);
  304. local $_;
  305. for (sort {($symptr->{$a}->[3] cmp $symptr->{$b}->[3]) or ($a cmp $b)} keys %{$symptr}) {
  306. $mykbterm = $symptr->{$_}->[0];
  307. $mypkname = $revpktypes{$mykbterm};
  308. if ($symptr->{$_}->[3] ne $tags{$mypkname}->[0]) {
  309. $tags{$mypkname} = [$symptr->{$_}->[3], - length($symptr->{$_}->[3]) -1];
  310. &{$sepwriter->{$mypkname}}("\n\[Files\.$tags{$mypkname}->[0]\]\n");
  311. }
  312. if ($symptr->{$_}->[3] ne $tags{'FULL'}->[0]) {
  313. $tags{'FULL'} = [$symptr->{$_}->[3], - length($symptr->{$_}->[3]) -1];
  314. &{$sepwriter->{'FULL'}}("\n\[Files\.$tags{'FULL'}->[0]\]\n");
  315. }
  316. &{$popwriter->{$mypkname}}(substr($_, 0, $tags{$mypkname}->[1]) . "\,$_\,\,4\n");
  317. }
  318. }
  319. sub Create_INF_SourceDisks
  320. {
  321. my ($symptr, $cabnameptr, $sepwriter, $popwriter) = @_; # $pkinfoptr) = @_;
  322. my ($INFHandle, $cabname, $mypkname);
  323. local $_;
  324. for (keys %{$cabnameptr}) {
  325. $cabname = $cabnameptr->{$_};
  326. &{$sepwriter->{$_}}(<<SOURCE_DISKS);
  327. [SourceDisksNames]
  328. 1="$cabname\.cab",$cabname\.cab,0
  329. [SourceDisksFiles]
  330. SOURCE_DISKS
  331. }
  332. for (sort keys %{$symptr}) {
  333. $mypkname = $revpktypes{$symptr->{$_}->[0]};
  334. &{$popwriter->{$mypkname}}($_ . "=1\n");
  335. }
  336. }
  337. #
  338. # $pkinfoptr->
  339. # $pktype ->
  340. # CABNAME
  341. # DDFNAME
  342. # INFNAME
  343. # CDFNAME
  344. # CATNAME
  345. # CABSIZE
  346. #
  347. # CABHANDLE
  348. # DDFHANDLE
  349. # INFHANDLE
  350. #
  351. # CABLIST
  352. #
  353. sub RegisterPackage
  354. {
  355. my ($pkinfoptr, $pktype, $hptr) = @_;
  356. my ($mykey);
  357. my @chklists = qw(CABNAME DDFNAME INFNAME CDFNAME CATNAME CABSIZE);
  358. $pkinfoptr->{$pktype} = $hptr;
  359. for $mykey (@chklists) {
  360. die "$mykey not defined in $pktype" if (!exists $pkinfoptr->{$pktype}->{$mykey});
  361. }
  362. }
  363. sub Writer {
  364. my (@handles) = @_;
  365. my ($hptr)=\@handles;
  366. return sub {
  367. my ($myhandle);
  368. for $myhandle (@{$hptr}) {
  369. print $myhandle $_[0];
  370. }
  371. };
  372. }
  373. sub Open_Private_Handle
  374. {
  375. my ($pkinfoptr, $ftype) = @_;
  376. my ($pkname);
  377. for $pkname (keys %{$pkinfoptr}) {
  378. $pkinfoptr->{$pkname}->{$ftype . 'HANDLE'} = new IO::File $pkinfoptr->{$pkname}->{$ftype . 'NAME'} . '.' . $ftype, 'w';
  379. if (!defined $pkinfoptr->{$pkname}->{$ftype . 'HANDLE'}) {
  380. logmsg "Cannot open " . $pkinfoptr->{$pkname}->{$ftype . 'NAME'} . '.' . $ftype . ".";
  381. }
  382. }
  383. }
  384. sub Close_Private_Handle
  385. {
  386. my ($pkinfoptr, $ftype) = @_;
  387. my ($pkname);
  388. for $pkname (keys %{$pkinfoptr}) {
  389. $pkinfoptr->{$pkname}->{$ftype . 'HANDLE'}->close() if (defined $pkinfoptr->{$pkname}->{$ftype . 'HANDLE'});
  390. delete $pkinfoptr->{$pkname}->{$ftype . 'HANDLE'};
  391. }
  392. }
  393. sub FileParse
  394. {
  395. my ($name, $path, $ext) = fileparse(shift, '\.[^\.]+$');
  396. $ext =~ s/^\.//;
  397. return $name, $path, $ext;
  398. }
  399. 1;