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.

523 lines
16 KiB

  1. #----------------------------------------------------------------//
  2. # Script: comlib.pm
  3. #
  4. # (c) 2000 Microsoft Corporation. All rights reserved.
  5. #
  6. # Purpose: This script contains all the common perl routines.
  7. #
  8. # Version: <1.00> 07/28/2000 : Suemiao Rossognol
  9. #----------------------------------------------------------------//
  10. package comlib;
  11. $VERSION = '1.00';
  12. ###-----Require section and extern modual.----------------------//
  13. require 5.003;
  14. use strict;
  15. use lib $ENV{RazzleToolPath };
  16. use lib "$ENV{RazzleToolPath }\\PostBuildScripts";
  17. #no strict 'vars';
  18. #no strict 'subs';
  19. #no strict 'refs';
  20. use Logmsg;
  21. use cklang;
  22. use hashtext;
  23. use DfsMap;
  24. #----------------------------------------------------------------//
  25. #Function: LockProcess
  26. # Parameter: (1) Language
  27. # (2) Build Branch
  28. # (3) Lock Object
  29. #----------------------------------------------------------------//
  30. sub LockProcess
  31. {
  32. my ( $pLang, $pBranch, $pLockObj ) = @_;
  33. ##### Define Semaphore location
  34. my $lock_Location;
  35. if( !($lock_Location = &GetIniSetting::GetSettingEx( $pBranch, $pLang, "DFSSemaphore") ) )
  36. {
  37. errmsg( "[DFSSemaphore] is undefined in INI file." );
  38. return 0;
  39. }
  40. logmsg( "DFS Semaphore [$lock_Location]");
  41. ##### Acquire DFS Semaphore lock
  42. if( !(${$pLockObj} = new LockProc( $lock_Location, 60000) ) )
  43. {
  44. errmsg( "Problem acquiring lock using [$lock_Location]" );
  45. return 0;
  46. }
  47. logmsg( "Acquiring lock for exclusive DFS access..." );
  48. while ( !$$pLockObj->Lock() )
  49. {
  50. errmsg ("Failed to acquire semaphore lock.");
  51. return 0;
  52. }
  53. return 1;
  54. }
  55. #----------------------------------------------------------------//
  56. #Function: TieDfsView
  57. # Parameter: (1) Language
  58. # (2) Build Branch
  59. # (3) Tiehash Object
  60. #----------------------------------------------------------------//
  61. sub TieDfsView
  62. {
  63. my ( $pLang, $pBranch, $pTieObj ) = @_;
  64. ##### Get DFS Root name
  65. my $dfsRoot;
  66. if( !($dfsRoot = &GetIniSetting::GetSettingEx( $pBranch, $pLang,"DFSRootName" ) ) )
  67. {
  68. errmsg( "[DFSRootName] undefined in INI file." );
  69. return 0;
  70. }
  71. ##### Access DFS through a TIE hash
  72. logmsg( "Tie full DFS view [$dfsRoot] information." );
  73. if ( ! tie %$pTieObj, 'DfsMap', $dfsRoot )
  74. {
  75. errmsg( "Error accessing DFS." );
  76. return 0;
  77. }
  78. return 1;
  79. }
  80. #----------------------------------------------------------------//
  81. #Function: ParseDfsMapText
  82. # Parameter: (1) Sku (2) Build profile hash, key used:package
  83. #
  84. # Return: (1) Hash Array
  85. #----------------------------------------------------------------//
  86. sub ParseDfsMapText
  87. {
  88. my ( $pSkus, $pbldInfo ) = @_;
  89. my ( @theHash, @rtary, $theRootShare, $theSubShare, $theRootDir, $theLink );
  90. my $dfsMapFile = "$ENV{razzletoolpath}\\PostBuildScripts\\raiseall.txt";
  91. @theHash=();
  92. &HashText::Read_Text_Hash( 1, $dfsMapFile, \@theHash );
  93. my $extraLine;
  94. for my $line ( @theHash)
  95. {
  96. next if( $pbldInfo->{"package"} && lc $pbldInfo->{"package"} ne lc $line->{ Package } );
  97. next if( $pbldInfo->{"pkgtarget"} && lc $pbldInfo->{"pkgtarget"} ne "all" &&
  98. lc $line->{ Target } ne "all" && lc $pbldInfo->{"pkgtarget"} ne lc $line->{ Target } );
  99. next if( %$pSkus && !exists( $pSkus->{$line->{Sku}}) );
  100. #### Handle Micro replacement
  101. &ReplaceMicro( \$line->{ RootShare }, $line->{Sku}, $pbldInfo );
  102. &ReplaceMicro( \$line->{ SubShare }, $line->{Sku}, $pbldInfo );
  103. &ReplaceMicro( \$line->{ RootDir }, $line->{Sku}, $pbldInfo );
  104. &ReplaceMicro( \$line->{ Link }, $line->{Sku}, $pbldInfo );
  105. push( @rtary, $line );
  106. #### Add mapping for usa\<buildNO>\<archType>.cov links
  107. my %covUsaLine;
  108. if( $line->{Package} eq "OS" && lc $pbldInfo->{"lang"} eq "cov" )
  109. {
  110. %covUsaLine = %{$line};
  111. $covUsaLine{Link} =~ s/$pbldInfo->{"lang"}/usa/;
  112. $covUsaLine{Link} =~ s/$pbldInfo->{"arch"}$pbldInfo->{"type"}/$pbldInfo->{"arch"}$pbldInfo->{"type"}.cov/;
  113. push( @rtary, \%covUsaLine );
  114. }
  115. #### Add mapping for Neutral mui builds with misc links
  116. my %miscMuiLine;
  117. if( $line->{Package} eq "Neutral" )
  118. {
  119. %miscMuiLine = %{$line};
  120. $miscMuiLine{Link} =~ s/$pbldInfo->{"lang"}/misc/;
  121. push( @rtary, \%miscMuiLine );
  122. }
  123. }
  124. return ( @rtary );
  125. }
  126. #----------------------------------------------------------------//
  127. #Function: ReplaceMicro
  128. # Parameter: (1)String to be replaced (2)Sku (3)Build Profile Hash
  129. #
  130. # Return: none
  131. #----------------------------------------------------------------//
  132. sub ReplaceMicro
  133. {
  134. my ( $pStr, $pSku, $pbldInfo ) =@_;
  135. $pbldInfo->{shareno} = $pbldInfo->{no} if( !$pbldInfo->{shareno} );
  136. $$pStr =~ s/\$\(BLANK\)//g;
  137. $$pStr =~ s/\$\(SKU\)/$pSku/g;
  138. $$pStr =~ s/\$\(SERVER\)/\\\\$pbldInfo->{server}/g;
  139. $$pStr =~ s/\$\(BUILD\)/$pbldInfo->{basename}/g;
  140. $$pStr =~ s/\$\(LANG\)/$pbldInfo->{lang}/g;
  141. $$pStr =~ s/\$\(BLDNO\)/$pbldInfo->{no}/g;
  142. $$pStr =~ s/\$\(SHARENO\)/$pbldInfo->{shareno}/g;
  143. $$pStr =~ s/\$\(BRANCH\)/$pbldInfo->{branch}/g;
  144. $$pStr =~ s/\$\(RELEASE\)/$pbldInfo->{release}/g;
  145. $$pStr =~ s/\$\(SYMREL\)/$pbldInfo->{symshare}/g;
  146. $$pStr =~ s/\$\(DFSBRANCH\)/$pbldInfo->{dfsbranch}/g;
  147. $$pStr =~ s/\$\(ARCH\)/$pbldInfo->{arch}/g;
  148. $$pStr =~ s/\$\(TYPE\)/$pbldInfo->{type}/g;
  149. $$pStr =~ s/\$\(TS\)/$pbldInfo->{ts}/g;
  150. }
  151. #----------------------------------------------------------------//
  152. #Function: GetReleaseShareName
  153. # Parameter: (1) Build Branch
  154. # (2) Language
  155. #----------------------------------------------------------------//
  156. sub GetReleaseShareName
  157. {
  158. my ( $bldBranch, $lang ) = @_;
  159. my ($releaseShareName);
  160. my( @iniRequest ) = ( "AlternateReleaseDir", "ReleaseDir");
  161. for my $keyReleaseDir( @iniRequest )
  162. {
  163. $releaseShareName = &GetIniSetting::GetSettingEx( $bldBranch, $lang,$keyReleaseDir );
  164. last if( $releaseShareName );
  165. }
  166. $releaseShareName = "release" if( !$releaseShareName );
  167. return ( $releaseShareName );
  168. }
  169. #----------------------------------------------------------------//
  170. #Function: ParseNetShare
  171. #Parameter: (1) Share name
  172. # (2) Parsing String, such as "Path", "Permissions:"
  173. #
  174. # Return: Share Path or access ID and permission in hash array
  175. #----------------------------------------------------------------//
  176. sub ParseNetShare
  177. {
  178. my ( $pShareName, $pParseStr ) = @_;
  179. my ( @results, %shareInfo );
  180. if( $pShareName !~ /^\\\\(.+)\\(.+)$/ )
  181. {
  182. $pShareName = "\\\\$ENV{computername}\\$pShareName ";
  183. }
  184. my @tmpFile = `rmtshare $pShareName`;
  185. my $match;
  186. for my $theLine ( @tmpFile )
  187. {
  188. chomp $theLine;
  189. next if( !$theLine );
  190. last if( $theLine =~ "The command completed successfully." );
  191. if( $theLine =~ /$pParseStr/i )
  192. {
  193. if( $pParseStr =~ /Permissions:/i ){ $match = 1; next;}
  194. ### parse path, return key-path text, value-path
  195. @results = split( /\s+/, $theLine );
  196. return $results[1];
  197. }
  198. push ( @results, $theLine ) if( $match );
  199. }
  200. #### Parse permissions, return key-Access ID, value-permission
  201. for my $line ( @results )
  202. {
  203. my @tmp = split( /\:/, $line );
  204. for( @tmp )
  205. {
  206. $_ =~ s/(\s+)?([^\s+]+)(\s+)?/$2/;
  207. }
  208. $shareInfo{$tmp[0]}=$tmp[1];
  209. }
  210. return ( %shareInfo );
  211. }
  212. #----------------------------------------------------------------//
  213. #Function: ParseTable
  214. # Parameter: (1) Group (2) Language (3) Architecture (4) Debug type
  215. # Return: Hash Array Table
  216. #----------------------------------------------------------------//
  217. sub ParseTable
  218. {
  219. my ( $pGroup, $pLang, $pArch, $pType ) = @_;
  220. my @theHash=();
  221. &HashText::Read_Text_Hash( 1, "$ENV{RazzleToolPath}\\PostBuildScripts\\miscrel.txt", \@theHash );
  222. my @hashKey = qw( SourceDir DestDir );
  223. for (my $inx=0; $inx< @theHash ; $inx++)
  224. {
  225. my $theTarg = lc( $theHash[$inx]->{ Target } );
  226. my $theGroup = lc( $theHash[$inx]->{ Group } );
  227. my $theLang = lc( $theHash[$inx]->{ Lang } );
  228. my $theArch = lc( $theHash[$inx]->{ Arch } );
  229. my $theType = lc( $theHash[$inx]->{ Type } );
  230. if( $theGroup ne $pGroup )
  231. {
  232. splice( @theHash, $inx, 1);
  233. --$inx;
  234. next;
  235. }
  236. if( $theLang ne "all" )
  237. {
  238. if( !&cklang::CkLang( $pLang, $theLang ) )
  239. {
  240. splice( @theHash, $inx, 1);
  241. --$inx;
  242. next;
  243. }
  244. }
  245. if( $theArch ne "all" && $theArch ne $pArch )
  246. {
  247. splice( @theHash, $inx, 1);
  248. --$inx;
  249. next;
  250. }
  251. if( $theType ne "all" && $theType ne $pType )
  252. {
  253. splice( @theHash, $inx, 1);
  254. --$inx;
  255. next;
  256. }
  257. }
  258. return @theHash;
  259. }
  260. #----------------------------------------------------------------//
  261. #Function: CreateExcludeFile
  262. # Parameter: (1) String with path sepearated by ;
  263. # Return: Exclude file contains all the excluded dirs
  264. #----------------------------------------------------------------//
  265. sub CreateExcludeFile
  266. {
  267. my ( $pExcludeStr ) = @_;
  268. my $tmpfile = "$ENV{temp}\\tmpfile";
  269. if( !open( TMP, ">$tmpfile" ) )
  270. {
  271. errmsg( "Fail to open [$tmpfile] for write." );
  272. return 0;
  273. }
  274. if( $pExcludeStr )
  275. {
  276. my @tDirs = split( /\;/, $pExcludeStr );
  277. for ( @tDirs ) { print TMP "\\$_\\\n"; }
  278. }
  279. close ( TMP );
  280. return $tmpfile;
  281. }
  282. #----------------------------------------------------------------//
  283. #Function: ParsePrsListFile
  284. # Parameter: (1) Language (2) Architecture (3) Debug type (4) Table File Name
  285. # Return: Hash Array Table
  286. #----------------------------------------------------------------//
  287. sub ParsePrsListFile
  288. {
  289. my ( $pLang, $pArch, $pType, $pListFile ) = @_;
  290. my ( @theHash );
  291. @theHash=();
  292. &HashText::Read_Text_Hash( 1, $pListFile, \@theHash );
  293. for (my $inx=0; $inx< @theHash; $inx++)
  294. {
  295. my $theFileName = lc( $theHash[$inx]->{ Filename } );
  296. my $theLang = lc( $theHash[$inx]->{ ValidLangs } );
  297. my $excludLang = lc( $theHash[$inx]->{ Exceptions} );
  298. my $theArch = lc( $theHash[$inx]->{ ValidArchs } );
  299. my $theType = lc( $theHash[$inx]->{ ValidDebug } );
  300. my $theAltName = lc( $theHash[$inx]->{ AltName } );
  301. if( &cklang::CkLang( $pLang, $excludLang ) )
  302. {
  303. splice( @theHash, $inx, 1);
  304. --$inx;
  305. next;
  306. }
  307. if( $theLang ne "all" )
  308. {
  309. if( !&cklang::CkLang( $pLang, $theLang ) )
  310. {
  311. splice( @theHash, $inx, 1);
  312. --$inx;
  313. next;
  314. }
  315. }
  316. if( $theArch ne "all" && $theArch ne lc($pArch) )
  317. {
  318. splice( @theHash, $inx, 1);
  319. --$inx;
  320. next;
  321. }
  322. if( $theType ne "all" && $theType ne lc($pType) )
  323. {
  324. splice( @theHash, $inx, 1);
  325. --$inx;
  326. next;
  327. }
  328. if( $theAltName eq "none" )
  329. {
  330. my @tmpFile = split( /\\/, $theFileName);
  331. $theHash[$inx]->{ AltName } = $tmpFile[$#tmpFile];
  332. }
  333. # Add to handle fusion special mui path
  334. # path with $(ARCH)
  335. my $tmpValue;
  336. while( $theHash[$inx]->{ Filename } =~ /^(.*)(\$\(ARCH)\)(.*)$/ )
  337. {
  338. if( lc($pArch) eq "x86" ) { $tmpValue = "i386"; } else { $tmpValue = "ia64"; }
  339. $theHash[$inx]->{ Filename }= $1.$tmpValue.$3;
  340. }
  341. # path with $(CD)
  342. my $stop=0;
  343. while( $theHash[$inx]->{ Filename } =~ /^(.*)(\$\(CD)\)(.*)$/ )
  344. {
  345. if( $tmpValue = &Which_MuiCD( $pLang ) )
  346. {
  347. $theHash[$inx]->{ Filename }= $1."CD$tmpValue".$3;
  348. next;
  349. }
  350. errmsg( "[$theHash[$inx]->{ Filename }] is not valid for parsing" );
  351. splice( @theHash, $inx, 1);
  352. $stop =1;
  353. last;
  354. }
  355. next if( $stop );
  356. # path with $(LANG)
  357. while( $theHash[$inx]->{ Filename } =~ /^(.*)(\$\(lang)\)(.*)$/ )
  358. {
  359. $theHash[$inx]->{ Filename }= $1.$pLang.$3;
  360. if ($pLang!~/usa/i){
  361. # fix for like $(lang)\asms\6000\msft\vcrtlint\vcrtlint.cat in combined_fusionlist.txt
  362. &dbgmsg("renamed ". $theHash[$inx]->{ Filename }) if $theHash[$inx]->{ Filename } =~/^$pLang\\/i;
  363. $theHash[$inx]->{ Filename } =~ s/^$pLang\\//ig;
  364. if ($pLang =~ /mir/i){
  365. my $pseudoLang = $pLang;
  366. # my $pseudoLang = &cklang::FieldByName($Special_Lang, "PSEUDOLANG");
  367. $pseudoLang ="ARA" ;
  368. $theHash[$inx]->{ Filename } =~ s/\b$pLang\b/$pseudoLang/ig;
  369. &dbgmsg("renamed ". $theHash[$inx]->{ Filename });
  370. }
  371. }
  372. }
  373. }
  374. return @theHash;
  375. }
  376. #----------------------------------------------------------------//
  377. #Function: ParsePrsSubmitLog
  378. #Parameter: (1) FileName (2) Parsing string
  379. #
  380. # Return: Match Value
  381. #----------------------------------------------------------------//
  382. sub ParsePrsSubmitLog
  383. {
  384. my ( $pSubmitLog, $pParseStr ) = @_;
  385. my $parseValue = 0;
  386. my @outfile = &ReadFile( $pSubmitLog );
  387. for my $theLine ( @outfile )
  388. {
  389. if( $theLine =~ /$pParseStr(.+)/ )
  390. {
  391. $parseValue = $1;
  392. last;
  393. }
  394. }
  395. return $parseValue;
  396. }
  397. #----------------------------------------------------------------//
  398. #Function: ReadFile
  399. # Parameter: (1) FileName
  400. #
  401. # Return: Array of file content
  402. #----------------------------------------------------------------//
  403. sub ReadFile
  404. {
  405. my ( $pFileName ) = @_;
  406. my ( @tmp );
  407. if( !open( TMP, $pFileName ) )
  408. {
  409. errmsg( "Fail on open [$pFileName] for read. Exit" );
  410. return 0;
  411. }
  412. chomp( @tmp = <TMP> );
  413. close( TMP );
  414. return @tmp;
  415. }
  416. #----------------------------------------------------------------//
  417. #Function: Which_MuiCD
  418. # Parameter: (1) Abbreviated language defined in the codes.txt
  419. # Return: (1) Number of CD - 0 is not found
  420. #----------------------------------------------------------------//
  421. sub Which_MuiCD
  422. {
  423. my ( $pLang ) = @_;
  424. my %muicdLayout =
  425. ( 1 => "CHS CHH FR GER JPN KOR",
  426. 2 => "ARA BR ES HEB IT NL SV",
  427. 3 => "CS DA FI NO RU",
  428. 4 => "EL HU PL PT TR",
  429. 5 => "SK SL" );
  430. for my $theCD( keys %muicdLayout )
  431. {
  432. my @tmp = split( /\s+/, $muicdLayout{$theCD} );
  433. for my $theLang ( @tmp )
  434. {
  435. if( $theLang eq uc($pLang) ) { return $theCD; }
  436. }
  437. }
  438. return 0;
  439. }
  440. #----------------------------------------------------------------//
  441. #Function: CheckError
  442. # Parameter: (1)$pErrFile - the Error File Name with full path
  443. # Return: (0) - File exists and is not empty
  444. # (1) - File not exists or is empty
  445. #----------------------------------------------------------------//
  446. sub CheckError
  447. {
  448. my( $pErrFile, $pSucessStr )=@_;
  449. if( (-e $pErrFile) && `wc -l $pErrFile`>0 )
  450. {
  451. logmsg("Please check error at $pErrFile\n");
  452. return 0;
  453. }
  454. logmsg("$pSucessStr\n");
  455. return 1;
  456. }
  457. #------------------------------------------------------------------//
  458. #Function: ExecuteSystem
  459. #Parameter: (1) Command line for system call
  460. # (2) Extra string to be populated to error message
  461. #------------------------------------------------------------------//
  462. sub ExecuteSystem {
  463. my ( $pCmdLine, $pExtraStr)=@_;
  464. if( defined $ENV{LOGFILE} ) { logmsg("$pExtraStr$pCmdLine"); }
  465. system( $pCmdLine );
  466. if( $? )
  467. {
  468. if( defined $ENV{ERRFILE} ) { errmsg( "$pExtraStr$pCmdLine" ); }
  469. return 0;
  470. }
  471. return 1;
  472. }
  473. #----------------------------------------------------------------//
  474. 1;