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.

1092 lines
26 KiB

  1. use Win32::Process; #allows multiprocessing
  2. use Win32API::Registry 0.13 qw( :ALL );
  3. sub Isx86()
  4. {
  5. return(lc($PROCESSOR_ARCHITECTURE) eq "x86");
  6. }
  7. sub IsAlpha()
  8. {
  9. return(lc($PROCESSOR_ARCHITECTURE) eq "alpha");
  10. }
  11. ####################################################################################
  12. # RemovePath()
  13. # simply returns the path from a string argument (retains arguments passed as well)
  14. # a-jbilas, 04/10/99
  15. ####################################################################################
  16. sub RemovePath
  17. {
  18. local($sFile) = @_;
  19. $sFile =~ s/^\S*\/(\S*\b)/$1/g;
  20. $sFile =~ s/^\S*\\(\S*\b)/$1/g;
  21. return($sFile);
  22. }
  23. ####################################################################################
  24. # GetPath()
  25. # simply returns the path from a string (filename) argument
  26. # a-jbilas, 05/11/99
  27. ####################################################################################
  28. sub GetPath
  29. {
  30. local($sFile) = @_;
  31. $sFile =~ s/\//\\/g;
  32. $sFile =~ s/\s+.*$//g;
  33. $sFile =~ s/\\[^\\]*$//g;
  34. return($sFile);
  35. }
  36. ####################################################################################
  37. # IsMemberOf()
  38. # returns 1 if the first argument is found in the other arguments, 0 otherwise
  39. # comparisons are case-insensitive
  40. # I've been too lazy to implement __LAZY mode, but the idea is that if a list
  41. # is passed with __LAZY as one of its arguments, word completion matching will occur
  42. # a-jbilas, 03/20/99 - created
  43. ####################################################################################
  44. sub IsMemberOf
  45. {
  46. carp("Usage: bool IsMemberOf(item, list) ")
  47. unless(@_ >= 1);
  48. if (scalar(@_) == 1)
  49. {
  50. PrintL("Warning: empty list passed to IsMemberOf(@_ ...)\n", PL_VERBOSE);
  51. }
  52. my($item) = $_[0];
  53. shift(@_);
  54. if ($_[0] eq "__LAZY") #compare first letters only (lazy mode)
  55. {
  56. $item =~ s/^(.).*/$1/;
  57. foreach $member (@_)
  58. {
  59. $member =~ s/^(.).*/$1/; #assume that item will not be _.*
  60. if (lc($item) eq lc($member))
  61. {
  62. return(1);
  63. }
  64. }
  65. }
  66. else
  67. {
  68. foreach $member (@_)
  69. {
  70. if (lc($item) eq lc($member))
  71. {
  72. return(1);
  73. }
  74. }
  75. }
  76. return(0);
  77. }
  78. sub IsSubstrOf
  79. {
  80. carp("Usage: bool IsSubstrOf(item, list) ")
  81. unless(@_ >= 1);
  82. my($elem) = $_[0];
  83. shift(@_);
  84. foreach $member (@_)
  85. {
  86. if ($member =~ /$elem/i)
  87. {
  88. return(1);
  89. }
  90. }
  91. return(0);
  92. }
  93. ####################################################################################
  94. # FmtDeltaTime()
  95. # takes a ctime difference number and returns the difference formatted in an (hour),
  96. # minute, second string
  97. # dougp, 03/20/99 - created
  98. ####################################################################################
  99. sub FmtDeltaTime
  100. {
  101. local($diff) = @_;
  102. local($min) = int($diff / 60);
  103. local($sec) = $diff - $min * 60;
  104. local($hour) = int($min / 60);
  105. $min = $min - $hour * 60;
  106. if ($hour > 0)
  107. {
  108. return sprintf("%2d:%02d:%02d", $hour, $min, $sec);
  109. }
  110. else
  111. {
  112. return sprintf("%02d:%02d", $min, $sec);
  113. }
  114. }
  115. ####################################################################################
  116. # Intersect()
  117. # returns common elements of two lists (does not modify lists)
  118. # NOTE: remember to use * notation when calling (call by reference)
  119. # a-jbilas, 05/10/99 - created
  120. ####################################################################################
  121. sub Intersect
  122. {
  123. local(*list1, *list2) = @_;
  124. my(@m_lIntersectList) = ();
  125. foreach $elem (@list1)
  126. {
  127. if (IsMemberOf($elem, @list2))
  128. {
  129. push(@m_lIntersectList, $elem);
  130. }
  131. }
  132. return(@m_lIntersectList);
  133. }
  134. ####################################################################################
  135. # Subtract()
  136. # returns elements in passed list 1 but not in passed list 2 (does not modify lists)
  137. # NOTE: remember to use * notation when calling (call by reference)
  138. # a-jbilas, 06/18/99 - created
  139. ####################################################################################
  140. sub Subtract
  141. {
  142. local(*list1, *list2) = @_;
  143. local(@m_lSubtractList) = ();
  144. foreach $elem (@list1)
  145. {
  146. if (!IsMemberOf($elem, @list2))
  147. {
  148. @m_lSubtractList = ($elem, @m_lSubtractList);
  149. }
  150. }
  151. return(@m_lSubtractList);
  152. }
  153. ####################################################################################
  154. # Union()
  155. # returns elements in passed list 1 appended with elements in passed list 2 (no duplicates,
  156. # does not modify lists)
  157. # NOTE: remember to use * notation when calling (call by reference)
  158. # a-jbilas, 06/21/99 - created
  159. ####################################################################################
  160. sub Union
  161. {
  162. local(*list1, *list2) = @_;
  163. my(@m_lUnionList) = @list1;
  164. foreach $elem (@list2)
  165. {
  166. if (!IsMemberOf($elem, @m_lUnionList))
  167. {
  168. @m_lUnionList = (@m_lUnionList, $elem);
  169. }
  170. }
  171. return(@m_lUnionList);
  172. }
  173. ####################################################################################
  174. # RemoveFromList()
  175. # remove all occurrences of an element from a list
  176. # returns the number of occurrences found in the list
  177. # NOTE: remember to use * notation when calling (call by reference)
  178. # a-jbilas, 04/20/99 - created
  179. ####################################################################################
  180. sub RemoveFromList
  181. {
  182. carp("Usage: bool RemoveFromList(item, list) ")
  183. unless(@_ >= 1);
  184. if (@_ == 1)
  185. {
  186. if ($bVerbose) { print(STDOUT "Warning: empty list passed to RemoveFromList(@_ ...)\n"); }
  187. return(0);
  188. }
  189. local($item, *list) = @_;
  190. local($occurences) = 0;
  191. for ($index = (@list - 1) ; $index >= 0 ; --$index)
  192. {
  193. if ($list[$index] =~ /^$item$/)
  194. {
  195. splice(@list, $index, 1);
  196. ++$occurences;
  197. }
  198. }
  199. if ($bVerbose) { print(STDOUT "Warning: no occurences of $item in @list found in RemoveFromList()\n"); }
  200. return($occurences);
  201. }
  202. ####################################################################################
  203. # SpawnProcess()
  204. # Spawns a new instance of specified application in param1, with arguments in param2
  205. # return Process Object on success, 0 on failure
  206. # if third param provided: calling process will wait on called process for n seconds
  207. # or until the process exits. If process has not exited by specified time, it will
  208. # be killed - returns false if process failure, forced kill, process ID if process
  209. # successfully exited within specified time
  210. # a-jbilas, 06/01/99 - created
  211. ####################################################################################
  212. sub SpawnProcess($;$$)
  213. {
  214. local($sTheApp, $sTheArgs, $nTimeout) = @_;
  215. local($pTheApp) = 0;
  216. if ($sTheApp !~ /(\/|\\)/)
  217. {
  218. my($sTheAppWithPath) = FindOnPath($sTheApp);
  219. if ($sTheAppWithPath)
  220. {
  221. $sTheApp = $sTheAppWithPath;
  222. }
  223. }
  224. if (!-e $sTheApp)
  225. {
  226. PrintL("Cannot spawn process, '$sTheApp' does not exist\n", PL_BIGERROR);
  227. }
  228. else
  229. {
  230. PrintL(" - Spawning new instance of '$sTheApp $sTheArgs'\n");
  231. if (!Win32::Process::Create($pTheApp,
  232. $sTheApp,
  233. RemovePath($sTheApp)." ".$sTheArgs,
  234. 0,
  235. NORMAL_PRIORITY_CLASS,
  236. "."))
  237. {
  238. PrintL("SpawnProcess() Error\n", PL_BIGERROR);
  239. PrintMsgBlock(Win32::FormatMessage(Win32::GetLastError()));
  240. $pTheApp = 0;
  241. }
  242. elsif ($nTimeout ne "")
  243. {
  244. $pTheApp->Wait($nTimeout * 1000);
  245. if (IsProcessRunning($pTheApp))
  246. {
  247. $pTheApp->Kill(1);
  248. use integer;
  249. PrintL($sTheApp." process still running after ".($nTimeout)." seconds, process killed\n",
  250. (IsCritical() ? PL_BIGERROR : PL_ERROR));
  251. $pTheApp = 0;
  252. }
  253. }
  254. }
  255. return($pTheApp);
  256. }
  257. sub IsProcessRunning($)
  258. {
  259. if (!$_[0])
  260. {
  261. return(0);
  262. }
  263. else
  264. {
  265. if ($_[0]->Wait(1))
  266. {
  267. return(0);
  268. }
  269. else
  270. {
  271. return(1);
  272. }
  273. }
  274. }
  275. ####################################################################################
  276. # GetBuildNumber()
  277. # returns the official buildnumber based on OTOOLS standards (at startyear, monthoffset)
  278. # a-jbilas, 04/10/99 - created
  279. ####################################################################################
  280. sub GetBuildNumber
  281. #stolen from monthday.c
  282. {
  283. # REVIEW: anyone use gz time?
  284. carp("Usage: GetBuildNumber([startyear], [monthoffset]) ")
  285. unless (@_ < 3);
  286. local($nStartYear, $nMonthOffset) = @_;
  287. if ($nStartYear eq "")
  288. {
  289. $nStartYear = 1999;
  290. }
  291. local($nCurYear, $nCurMon, $nCurDay, $x) = (0, 0, 0, 0);
  292. ($x, $x, $x, $nCurDay, $nCurMon, $nCurYear, $x, $x, $x) = localtime(time());
  293. local($nBaseMonth) = $nCurMon + 1 + ($nCurYear - ($nStartYear - 1900) ) * 12;
  294. if (defined $nMonthOffset) { $nBaseMonth = $nBaseMonth + $nMonthOffset; }
  295. # stick leading 0's in front if single digit values
  296. #if (length($nBaseMonth) == 1) { $nBaseMonth = "0$nBaseMonth"; } #nBaseMonth is actually cast to a string here
  297. #if (length($nCurDay) == 1) { $nCurDay = "0$sCurDay"; } #nCurDay is actually cast to a string here
  298. #return("$nBaseMonth$nCurDay");
  299. return sprintf "%02d%02d", $nBaseMonth, $nCurDay;
  300. }
  301. ####################################################################################
  302. # Pause()
  303. # pauses the program until user hits 'enter' key
  304. # (for breakpoint/testing only, don't leave in build)
  305. # a-jbilas, 03/10/99 - created
  306. ####################################################################################
  307. sub Pause()
  308. {
  309. print(STDOUT "press <enter> to continue ...\n");
  310. while(<STDIN> ne "\n") {}
  311. }
  312. ####################################################################################
  313. # TranslateToHTTP()
  314. # returns the http address of a file
  315. # a-jbilas, 07/01/99 - created
  316. ####################################################################################
  317. sub TranslateToHTTP($)
  318. {
  319. my($sLog) = @_;
  320. if ($sLog =~ /wwwroot/)
  321. {
  322. $sLog =~ s/\\/\//g;
  323. $sLog =~ s/wwwroot\///i;
  324. return("http:".$sLog);
  325. }
  326. else
  327. {
  328. $sLog =~ s/\\/\//g;
  329. return("file:".$sLog);
  330. }
  331. }
  332. ####################################################################################
  333. # Windiff()
  334. # Spawns a new instance of Windiff and compares the two given filename arguments
  335. # return Process Object on success, 0 on failure
  336. # a-jbilas, 06/01/99 - created
  337. ####################################################################################
  338. sub Windiff($$)
  339. {
  340. local($file1, $file2) = @_;
  341. local($pWindiff) = 0;
  342. if (!-e $file1)
  343. {
  344. PrintToLogErr("Cannot run windiff, '$file1' does not exist\n");
  345. }
  346. elsif (!-e $file2)
  347. {
  348. PrintToLogErr("Cannot run windiff, '$file2' does not exist\n");
  349. }
  350. else
  351. {
  352. PrintToLog(" - Spawning new instance of 'windiff $file1 $file2'\n");
  353. if (!Win32::Process::Create($pWindiff,
  354. $cmdWindiff,
  355. "windiff $file1 $file2",
  356. 0,
  357. NORMAL_PRIORITY_CLASS,
  358. "."))
  359. {
  360. PrintToLogErr("Windiff() Error: ".Win32::FormatMessage(Win32::GetLastError()));
  361. $pWindiff = 0;
  362. }
  363. }
  364. return($pWindiff);
  365. }
  366. ####################################################################################
  367. # GetOS()
  368. # Stolen from smueller off the PDK newsgroup
  369. # a-jbilas, 06/16/99 - created
  370. ####################################################################################
  371. sub GetOS()
  372. {
  373. if (defined &Win32::IsWinNT && Win32::IsWinNT)
  374. {
  375. return("NT");
  376. }
  377. elsif (defined &Win32::IsWin95 && Win32::IsWin95)
  378. {
  379. return("95");
  380. }
  381. else
  382. {
  383. return($^O);
  384. }
  385. }
  386. ####################################################################################
  387. # WriteArrayToExcel()
  388. # Passed an Excel doc (short form) language and list, the array will be written to the appropriate
  389. # Excel spreadsheet bvtperf.xls column and percent diffs will be added to the previous column
  390. # NOTE: plData is a pointer to a list
  391. # globals used: $sBuildNumber
  392. # a-jbilas, 06/17/99 - created
  393. ####################################################################################
  394. sub WriteArrayToExcel
  395. {
  396. carp("Usage: WriteArrayToExcel(sExcelDoc, sLanguage, plData) ")
  397. unless(@_ == 3);
  398. local($m_sExcelDoc, $m_sLang, *m_lData) = @_;
  399. local($rc) = 1;
  400. if ($bOfficialBuild && !$bNoCopy)
  401. {
  402. PrintL(" - Recording results to server ...\n", PL_BLUE);
  403. eval
  404. {
  405. $ex = Win32::OLE->GetActiveObject('Excel.Application')
  406. };
  407. if ($@)
  408. {
  409. PrintL("Error in GetExcelSheet(): Excel not installed\n", PL_ERROR);
  410. $rc = 0;
  411. }
  412. elsif (!defined $ex)
  413. {
  414. $ex = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit;});
  415. if (!$ex)
  416. {
  417. PrintL("Error in GetExcelSheet(): Cannot start Excel\n", PL_ERROR);
  418. $rc = 0;
  419. }
  420. }
  421. if ($rc)
  422. {
  423. my($book) = $ex->Workbooks->Open($m_sExcelDoc);
  424. my($sheet) = $book->Worksheets(1);
  425. my($currentCell) = 'A1';
  426. my($nBuildNumber) = $sBuildNumber;
  427. # must remove leading zero to compare with Excel
  428. $nBuildNumber =~ s/^0+//;
  429. while (lc($sheet->Range($currentCell)->{'Value'}) ne lc($m_sLang))
  430. {
  431. $currentCell = NextRow($currentCell);
  432. }
  433. # we are now at the correct language in the spreadsheet (but we need to get to the correct build)
  434. my($prevCell) = NextColumn($currentCell);
  435. $currentCell = NextColumn($prevCell); # assume first buildnumber will never be blank
  436. while ($sheet->Range(NextColumn($currentCell))->{'Value'} ne ""
  437. && $sheet->Range(NextColumn($currentCell))->{'Value'} ne $nBuildNumber)
  438. {
  439. $prevCell = NextColumn($currentCell);
  440. $currentCell = NextColumn($prevCell);
  441. }
  442. # we are now at the correct build column header (if its already there, we'll just overwrite it)
  443. # this ugly bit of script will enter the values of @lFullTimeResults into the Excell
  444. # doc and enter the differencing equation in the previous column
  445. my($resultCell) = NextColumn($currentCell);
  446. $sheet->Range($currentCell)->{'Value'} = '-->';
  447. $sheet->Range($resultCell)->{'Value'} = $nBuildNumber;
  448. $prevCell = NextRow($prevCell);
  449. $currentCell = NextRow($currentCell);
  450. $resultCell = NextRow($resultCell);
  451. for ($index = 0 ; $index < @m_lData; ++$index)
  452. {
  453. $prevCell = NextRow($prevCell);
  454. $currentCell = NextRow($currentCell);
  455. $resultCell = NextRow($resultCell);
  456. $sheet->Range($resultCell)->{'Value'} = $m_lData[$index];
  457. $sheet->Range($currentCell)->{'Value'} = "\=IF(".$resultCell."\=0, 0 , ".$resultCell."\/".$prevCell."-1)";
  458. }
  459. # save and exit
  460. if (!$book->Save)
  461. {
  462. PrintL("Error: could not save Excel timing log\n", PL_ERROR);
  463. $rc = 0;
  464. }
  465. undef $book;
  466. undef $ex;
  467. }
  468. }
  469. return($rc);
  470. }
  471. ####################################################################################
  472. # GetActiveCodePage()
  473. # returns the active code page for your shell (as a string)
  474. # a-jbilas, 05/18/99 - created
  475. ####################################################################################
  476. sub GetActiveCodePage()
  477. {
  478. local($_Execute) = 1;
  479. my($success) = Execute('chcp', 0, "QUIET");
  480. my($sCodePage) = $_Execute;
  481. undef $_Execute;
  482. if ($success)
  483. {
  484. chomp($sCodePage);
  485. $sCodePage =~ s/[^\d]*(\d+)[^\d]*/$1/;
  486. }
  487. else
  488. {
  489. $sCodePage = "";
  490. }
  491. return($sCodePage);
  492. }
  493. ####################################################################################
  494. # NextColumn(), NextColumnHelper()
  495. # Excell helper function
  496. # given a cell descriptor string (ex. 'A1') it returns a cell descriptor for the
  497. # next column (of the same row)
  498. # returns null on failure
  499. # a-jbilas, 06/08/99 - created
  500. ####################################################################################
  501. sub NextColumn($)
  502. {
  503. carp("Usage: NextColumn(cell) ")
  504. unless(@_ == 1);
  505. my($sCell) = @_;
  506. my($sRow) = @_;
  507. my($sColumn) = @_;
  508. $sColumn =~ s/(\s|\d)//g;
  509. $sRow =~ s/[^\d]//g;
  510. $sColumn = uc($sColumn);
  511. if (length($sColumn - 1) <= 0)
  512. {
  513. carp("invalid cell $sCell ");
  514. return("");
  515. }
  516. return(NextColumnHelper($sColumn).$sRow);
  517. }
  518. sub NextColumnHelper($)
  519. {
  520. my($inputString) = @_;
  521. my($rightChar) = substr($inputString, length($inputString) - 1, 1);
  522. my($leftChars) = substr($inputString, 0, length($inputString) - 1);
  523. if ($rightChar eq 'Z')
  524. {
  525. $rightChar = 'A';
  526. return(NextColumnHelper($leftChars).$rightChar);
  527. }
  528. elsif ($rightChar eq '')
  529. {
  530. $rightChar = 'A';
  531. }
  532. else
  533. {
  534. ++$rightChar;
  535. return($leftChars.$rightChar);
  536. }
  537. }
  538. ####################################################################################
  539. # NextRow()
  540. # Excell helper function
  541. # given a cell descriptor string (ex. 'A1') it returns a cell descriptor for the
  542. # next row (of the same column)
  543. # a-jbilas, 06/08/99 - created
  544. ####################################################################################
  545. sub NextRow($)
  546. {
  547. carp("Usage: NextRow(cell) ")
  548. unless(@_ == 1);
  549. my($sCell) = @_;
  550. my($sRow) = @_;
  551. my($sColumn) = @_;
  552. $sColumn =~ s/(\s|\d)//g;
  553. $sRow =~ s/[^\d]//g;
  554. $sRow = $sRow + 1;
  555. return($sColumn.$sRow);
  556. }
  557. sub GetDayRange
  558. {
  559. my($nNow) = time();
  560. my($x, $nDay, $nMon, $nYear);
  561. ($x, $x, $x, $nDay, $nMon, $nYear, $x, $x, $x) = localtime($nNow);
  562. my ($retVal) = ($nMon + 1).'/'.$nDay.'/'.($nYear + 1900);
  563. if (!$_[0])
  564. {
  565. return($retVal);
  566. }
  567. ($x, $x, $x, $nDay, $nMon, $nYear, $x, $x, $x) = localtime($nNow - $_[0] * 24 * 60 * 60);
  568. return(($nMon + 1).'/'.$nDay.'/'.($nYear + 1900));
  569. }
  570. sub ResizeString($$)
  571. {
  572. my($str, $size) = @_;
  573. if (length($str) > $size)
  574. {
  575. if ($size < 6)
  576. {
  577. PrintL("CondenseString() error: Size must be greater than 5", PL_BIGWARNING);
  578. return($str);
  579. }
  580. my($size1) = (($size / 2) + ($size % 2)) - 2;
  581. my($size2) = ($size / 2) - 1;
  582. my($newStr) = substr($str, 0, $size1);
  583. $newStr .= "...";
  584. $newStr .= substr($str, (length($str) - $size2 + 1), $size2);
  585. return($newStr);
  586. }
  587. elsif (length($str) < $size)
  588. {
  589. return($str." " x ($size - length($str)));
  590. }
  591. else
  592. {
  593. return($str);
  594. }
  595. }
  596. sub HTMLToStr($)
  597. {
  598. my($str) = $_[0];
  599. $str =~ s/<[^>]*>//g;
  600. return($str);
  601. }
  602. sub GetKeyCaseInsensitive
  603. {
  604. my($matchkey, %hash) = @_;
  605. foreach $key (keys(%hash))
  606. {
  607. if (lc($key) eq lc($matchkey))
  608. {
  609. return($hash{$key});
  610. }
  611. }
  612. return("");
  613. }
  614. sub SetKeyCaseInsensitive
  615. {
  616. local($matchkey, $setkey, *hash) = @_;
  617. foreach $key (keys(%hash))
  618. {
  619. if (lc($key) eq lc($matchkey))
  620. {
  621. $hash{$key} = $setkey;
  622. return(1);
  623. }
  624. }
  625. return(0);
  626. }
  627. sub RunCheckShip
  628. {
  629. my($rc) = 1;
  630. my($sErrors) = "";
  631. foreach $file (@_)
  632. {
  633. local($_Execute) = 1;
  634. Execute($cmdChkShip.' -chxsl '.$file);
  635. foreach $line (split("\n", $_Execute))
  636. {
  637. if (!/No clean mapping found/)
  638. {
  639. $sErrors .= $line."\n";
  640. }
  641. }
  642. undef $_Execute;
  643. }
  644. if ($sErrors)
  645. {
  646. PrintL("\n");
  647. PrintL("CheckShip Errors\n", PL_BIGERROR);
  648. PrintMsgBlock($sErrors);
  649. PrintL(("-" x 60)."\n".$sErrors."\n\n", PL_ERROR);
  650. $rc = 0;
  651. }
  652. if (!$rc && IsCritical())
  653. {
  654. $bcStatus |= BC_CHKSHIPFAILED;
  655. }
  656. return($rc);
  657. }
  658. sub GetLocalTime()
  659. {
  660. local(@lst) = split(/ +/, localtime(time()));
  661. local(@tm) = split(":", $lst[3], 3);
  662. $dom = "am";
  663. if ($tm[0] > 12)
  664. {
  665. $dom = "pm";
  666. $tm[0] = $tm[0] - 12;
  667. }
  668. elsif ($tm[0] == 12)
  669. {
  670. $dom = "pm";
  671. }
  672. elsif ($tm[0] == 0)
  673. {
  674. $tm = 12;
  675. }
  676. return($lst[0]." @ ".$tm[0].":".$tm[1].":".$tm[2]." ".$dom." - ".$lst[1]." ".$lst[2].", ".$lst[4]);
  677. }
  678. sub RemoveKeyFromHash
  679. {
  680. local($elem, %hOldHash) = @_;
  681. local(%hNewHash) = ();
  682. foreach $key (keys(%hOldHash))
  683. {
  684. if ($key ne $elem)
  685. {
  686. %hNewHash->{$key} = %hOldHash->{$key};
  687. }
  688. }
  689. return(%hNewHash);
  690. }
  691. sub StrToL($)
  692. {
  693. return(split(/ +/, $_[0]));
  694. }
  695. # computer, subkey, field, [hkey]
  696. sub GetRemoteProjRegKey($$$;$)
  697. {
  698. my($hKey);
  699. RegConnectRegistry($_[0], ($_[3] ? $_[3] : HKEY_LOCAL_MACHINE), $hKey );
  700. if (!$hKey)
  701. {
  702. PrintL("Registry Error: Cannot connect to ".$_[0]."'s remote registry (cannot get key)\n\n", PL_BIGERROR);
  703. PrintMsgBlock($^E);
  704. return(0);
  705. }
  706. else
  707. {
  708. return(GetProjRegKey($_[1], $_[2], $hKey));
  709. }
  710. }
  711. # computer, subkey, field, [hkey]
  712. sub GetRemoteRegKey($$$;$)
  713. {
  714. my($hKey);
  715. RegConnectRegistry($_[0], ($_[3] ? $_[3] : HKEY_LOCAL_MACHINE), $hKey );
  716. if (!$hKey)
  717. {
  718. PrintL("Registry Error: Cannot connect to ".$_[0]."'s remote registry (cannot get key)\n\n", PL_BIGERROR);
  719. PrintMsgBlock($^E);
  720. return(0);
  721. }
  722. else
  723. {
  724. return(GetRegKey($_[1], $_[2], $hKey));
  725. }
  726. }
  727. # computer, subkey, field, value, [hkey]
  728. sub SetRemoteProjRegKey($$$$;$)
  729. {
  730. my($hKey);
  731. RegConnectRegistry($_[0], ($_[4] ? $_[4] : HKEY_LOCAL_MACHINE), $hKey);
  732. if (!$hKey)
  733. {
  734. PrintL("Registry Error: Cannot connect to ".$_[0]."'s remote registry (cannot set key)\n\n", PL_BIGERROR);
  735. PrintMsgBlock($^E);
  736. return(0);
  737. }
  738. else
  739. {
  740. return(SetProjRegKey($_[1], $_[2], $_[3], $hKey));
  741. }
  742. }
  743. # computer, subkey, field, value, [hkey]
  744. sub SetRemoteRegKey($$$$;$)
  745. {
  746. my($hKey);
  747. RegConnectRegistry($_[0], ($_[4] ? $_[4] : HKEY_LOCAL_MACHINE), $hKey);
  748. if (!$hKey)
  749. {
  750. PrintL("Registry Error: Cannot connect to ".$_[0]."'s remote registry (cannot set key)\n\n", PL_BIGERROR);
  751. PrintMsgBlock($^E);
  752. return(0);
  753. }
  754. else
  755. {
  756. return(SetRegKey($_[1], $_[2], $_[3], $hKey));
  757. }
  758. }
  759. # subkey, field, [hkey]
  760. # returns null str if key not exist
  761. sub GetProjRegKey($$;$)
  762. {
  763. if ($sRegKeyBase eq "")
  764. {
  765. PrintL("RegKeyBase not set, cannot get registry key\n\n", PL_BIGERROR);
  766. PrintMsgBlock($^E);
  767. return("");
  768. }
  769. else
  770. {
  771. return(GetRegKey($sRegKeyBase.($_[0] eq "" ? "" : "\\").$_[0], $_[1], $_[2]));
  772. }
  773. }
  774. #subkey, field, [hkey]
  775. sub GetRegKey($$;$)
  776. {
  777. my($key, $retVal);
  778. RegOpenKeyEx(($_[2] ? $_[2] : HKEY_LOCAL_MACHINE), $_[0], 0, KEY_READ, $key);
  779. if (!$key)
  780. {
  781. return("");
  782. }
  783. else
  784. {
  785. RegQueryValueEx($key, $_[1], [], REG_SZ, $retVal, 0);
  786. RegCloseKey($key);
  787. return($retVal);
  788. }
  789. }
  790. # subkey, field, value, [hkey]
  791. sub SetProjRegKey($$$;$)
  792. {
  793. if ($sRegKeyBase eq "")
  794. {
  795. PrintL("RegKeyBase not set, cannot set registry key\n\n", PL_BIGERROR);
  796. PrintMsgBlock($^E);
  797. return("");
  798. }
  799. else
  800. {
  801. return(SetRegKey($sRegKeyBase.($_[0] eq "" ? "" : "\\").$_[0], $_[1], $_[2], $_[3]));
  802. }
  803. }
  804. # subkey, field, value, [hkey]
  805. sub SetRegKey($$$;$)
  806. {
  807. my($key);
  808. my($rc) = 1;
  809. RegCreateKeyEx(($_[3] ? $_[3] : HKEY_LOCAL_MACHINE),
  810. $_[0],
  811. 0,
  812. "",
  813. REG_OPTION_NON_VOLATILE,
  814. KEY_WRITE,
  815. [],
  816. $key,
  817. []);
  818. if (!$key)
  819. {
  820. PrintL("Error inserting registry key ".$_[0]." into registry\n", PL_BIGERROR);
  821. PrintMsgBlock($^E);
  822. $rc = 0;
  823. }
  824. else
  825. {
  826. if (!RegSetValueEx($key, $_[1], 0, REG_SZ, $_[2], length($_[2])))
  827. {
  828. $rc = 0;
  829. }
  830. RegCloseKey($key);
  831. }
  832. return($rc);
  833. }
  834. # subkey, [field], [hkey]
  835. # rc only false on failure to open reg key
  836. sub DelRegKey($;$$)
  837. {
  838. my($rc) = 1;
  839. if ($_[0] eq "")
  840. {
  841. PrintL("Attempted to delete base reg key!\n\n", PL_BIGERROR);
  842. return(0);
  843. }
  844. RegOpenKeyEx(($_[2] ? $_[2] : HKEY_LOCAL_MACHINE), ($_[1] ne "" ? $_[0] : ""), 0, KEY_WRITE, $key);
  845. if (!$key)
  846. {
  847. PrintL("Error removing registry key ".$_[0]."\n", PL_BIGERROR);
  848. PrintMsgBlock($^E);
  849. $rc = 0;
  850. }
  851. else
  852. {
  853. if ($_[1] ne "")
  854. {
  855. if (!RegDeleteValue($key, $_[1]))
  856. {
  857. $rc = 0;
  858. }
  859. }
  860. else
  861. {
  862. if (!RegDeleteKey($key, $_[0]))
  863. {
  864. $rc = 0;
  865. }
  866. }
  867. RegCloseKey($key);
  868. }
  869. return($rc);
  870. }
  871. # computer, subkey, [field], [hkey]
  872. # rc only false on failure to open reg key
  873. sub DelRemoteRegKey($$;$$)
  874. {
  875. my($hKey);
  876. RegConnectRegistry($_[0], ($_[3] ? $_[3] : HKEY_LOCAL_MACHINE), $hKey);
  877. if (!$hKey)
  878. {
  879. PrintL("Registry Error: Cannot connect to ".$computer."'s remote registry (cannot set key)\n\n", PL_BIGERROR);
  880. PrintMsgBlock($^E);
  881. return(0);
  882. }
  883. else
  884. {
  885. return(DelRegKey($_[1], $_[2], $hKey));
  886. }
  887. }
  888. sub RLC
  889. {
  890. return(substr($_[0], 0, length($_[0] - 1)));
  891. }
  892. $__IITUTILPM = 1;
  893. 1;