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.

552 lines
16 KiB

  1. # ---------------------------------------------------------------------------
  2. # Script: assignbvt.pl
  3. #
  4. # (c) 2000 Microsoft Corporation. All rights reserved.
  5. #
  6. # Purpose: This script is an example of a perl script in the NT postbuild
  7. # environment.
  8. #
  9. # Version: 1.00 (10/05/2000) : (bensont) Assign BVT JOb
  10. #---------------------------------------------------------------------
  11. # Set Package
  12. # <Set your package name of your perl module>
  13. package assignbvt;
  14. # Set the script name
  15. # <Set your script name>
  16. $ENV{script_name} = 'assignbvt.pl';
  17. # Set version
  18. # <Set the version of your script>
  19. $VERSION = '1.00';
  20. # Set required perl version
  21. # <Set the version of perl that your script requires>
  22. require 5.003;
  23. use lib $ENV{ "RazzleToolPath" };
  24. use lib $ENV{ "RazzleToolPath" }. "\\PostBuildScripts";
  25. # Use section
  26. use Win32API::Registry 0.13 qw( :ALL );
  27. use GetParams;
  28. use LocalEnvEx;
  29. use Logmsg;
  30. use GetIniSetting;
  31. use cksku;
  32. use strict;
  33. no strict 'vars';
  34. # <Add any perl modules that you will be using for this script>
  35. # Require section
  36. require Exporter;
  37. # <Add any perl pl files that you will be using>
  38. # Global variable section
  39. # <Add any global variables here using my to preserve namespace>
  40. @platforms = qw(x86);
  41. @frechks = qw(fre);
  42. ($RemoteId, $BVTEntry, $BVTResult)=(
  43. "Booted",
  44. "\\\\intlntsetup\\bvtsrc\\runbvt.cmd",
  45. "\\\\intlntsetup\\bvtresults"
  46. );
  47. ($BVTMachine, $BVTAccount, $Noticed, $OneNotice, $administrator,
  48. $platforms, $frechks)=();
  49. ($BVTAccountUsername, $BVTAccountDomainname, $BVTAccountPassword)=();
  50. ($platform, $frechk, $BVTMachine, $sku, %skus, @BVTMachines)=();
  51. ($AdministratorGroupName, $AdministratorName)=();
  52. @NoticeList;
  53. @NoticeListForSingleMessage;
  54. sub Main {
  55. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  56. # Begin Main code section
  57. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  58. # Return when you want to exit on error
  59. # <Implement your code here>
  60. # Issue: If we need support multi-BVT Machine, we could get BVTMachines from parameter for each sku or ...
  61. # Assign BVT if we defined certain machine to run
  62. if (defined $BVTMachine) {
  63. &PrepareForBVT($BVTMachine);
  64. return; # According Dave's suggestion
  65. }
  66. # According the platforms, frechks and skus, we look for the Boot Test Machine
  67. # that we defined in <branch>.<language>.ini file to call PrepareForBVT
  68. for $platform ( @platforms ) {
  69. for $frechk ( @frechks ) {
  70. %skus = &cksku::GetSkus($lang, $platform);
  71. for $sku (keys %skus) {
  72. @BVTMachines = &WhereIsMyBootTestMachine($platform, $frechk, $sku);
  73. for $BVTMachine (@BVTMachines) {
  74. # According autoboottest.cmd, the boottest machinename
  75. # will be add "1" after the origional boottest machine
  76. $BVTMachine .= "1";
  77. # Call PrepareForBVT
  78. &PrepareForBVT($BVTMachine);
  79. }
  80. }
  81. }
  82. }
  83. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  84. # End Main code section
  85. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  86. }
  87. # <Implement your subs here>
  88. #
  89. # PrepareForBVT($BVTMachine)
  90. #
  91. # purpose: Preparing $BVTMachine for BVT
  92. # details:
  93. # 1. Net Use BVT Machine
  94. # 2. Write Auto Login Registry in BVT Machine
  95. # 3. Add Account to BVT Machine
  96. # 4. Remote Logoff BVT Machine
  97. #
  98. sub PrepareForBVT {
  99. my ($BVTMachine) = @_;
  100. my $MyNotice = "${BVTMachine}:${AdministratorName}";
  101. NoticeMessage("Preparing $BVTMachine for BVT ...", $MyNotice, @NoticeList);
  102. NoticeMessage("1. Net Use BVT Machine ($BVTMachine)", $MyNotice, @NoticeList);
  103. &MySystemCall("echo. | net use \\\\${BVTMachine} /u:${BVTMachine}\\${AdministratorName}") or return;
  104. NoticeMessage("2. Write Auto Login Registry in BVT Machine", $MyNotice, @NoticeList);
  105. &WriteRegister($BVTMachine) or return;
  106. NoticeMessage("3. Add Account to BVT Machine", $MyNotice, @NoticeList);
  107. &RemoteAddAccount($BVTMachine) or return;
  108. NoticeMessage("4. create myrunbvt.cmd", $MyNotice, @NoticeList);
  109. &WriteMyRunBVT($BVTMachine) or return;
  110. NoticeMessage("5. Remote Logoff BVT Machine", $MyNotice, @NoticeList);
  111. &RemoteLogoff($BVTMachine) or return;
  112. NoticeMessage("6. Disconnect BVT Machine ($BVTMachine)", $MyNotice, @NoticeList);
  113. &MySystemCall("echo Y | net use \\\\${BVTMachine} /d") or return;
  114. NoticeMessage("We are starting BVT Process at $BVTMachine", $MyNotice, @NoticeList, @NoticeListForSingleMessage);
  115. }
  116. #
  117. # WriteRegister($BVTMachine)
  118. #
  119. # purpose: WriteRegister, so that we can auto-login and run BVT script
  120. # details:
  121. # 1. Update DefaultDomainName at SOFTWARE\\Microsoft\\WINDOWS NT\\CurrentVersion\\Winlogon
  122. # 2. Update DefaultUserName
  123. # 3. Update DefaultPassword
  124. # 4. Set AutoAdminLogon = 1
  125. # 5. Set ForceAutoLogon = 1
  126. # 6. Add BVT Process at SOFTWARE\\Microsoft\\WINDOWS\\CurrentVersion\\RunOnce
  127. #
  128. sub WriteRegister {
  129. my ($BVTMachine) = @_;
  130. UpdateRegistry($BVTMachine, HKEY_LOCAL_MACHINE,
  131. "SOFTWARE\\Microsoft\\WINDOWS NT\\CurrentVersion\\Winlogon",
  132. "DefaultDomainName", $BVTAccountDomainname);
  133. UpdateRegistry($BVTMachine, HKEY_LOCAL_MACHINE,
  134. "SOFTWARE\\Microsoft\\WINDOWS NT\\CurrentVersion\\Winlogon",
  135. "DefaultUserName", $BVTAccountUsername);
  136. UpdateRegistry($BVTMachine, HKEY_LOCAL_MACHINE,
  137. "SOFTWARE\\Microsoft\\WINDOWS NT\\CurrentVersion\\Winlogon",
  138. "DefaultPassword", $BVTAccountPassword);
  139. UpdateRegistry($BVTMachine, HKEY_LOCAL_MACHINE,
  140. "SOFTWARE\\Microsoft\\WINDOWS NT\\CurrentVersion\\Winlogon",
  141. "AutoAdminLogon", "1");
  142. UpdateRegistry($BVTMachine, HKEY_LOCAL_MACHINE,
  143. "SOFTWARE\\Microsoft\\WINDOWS NT\\CurrentVersion\\Winlogon",
  144. "ForceAutoLogon", "1");
  145. UpdateRegistry($BVTMachine, HKEY_LOCAL_MACHINE,
  146. "SOFTWARE\\Microsoft\\WINDOWS\\CurrentVersion\\RunOnce",
  147. "Startup BVT Process", "\\tools\\perl\\bin\\perl.exe " .
  148. "\\tools\\OpShellFolder.pl CopyFileTo Startup \\tools\\myrunbvt.cmd");
  149. UpdateRegistry($BVTMachine, HKEY_LOCAL_MACHINE,
  150. "SOFTWARE\\Microsoft\\WINDOWS\\CurrentVersion\\Run",
  151. "Desktop BVT Process", "\\tools\\perl\\bin\\perl.exe " .
  152. "\\tools\\OpShellFolder.pl CopyFileTo Desktop \\tools\\myrunbvt.cmd");
  153. }
  154. #
  155. # RemoteLogoff($BVTMachine)
  156. #
  157. # purpose: Logoff BVT Machine
  158. # details:
  159. # Send Logoff command to remote console
  160. #
  161. sub RemoteLogoff {
  162. my ($BVTMachine) = @_;
  163. &MyRemoteCommand($BVTMachine, $RemoteId, "logoff");
  164. }
  165. sub WriteMyRunBVT {
  166. my ($BVTMachine) = @_;
  167. &MyRemoteCommand($BVTMachine, $RemoteId,
  168. "echo $BVTEntry ^^^\%SystemDrive^^^\%\\BVT " .
  169. "$BVTResult ^^^>^^^\%SystemDrive^^^\%\\tools\\myrunbvt.cmd");
  170. &MyRemoteCommand($BVTMachine, $RemoteId,
  171. "echo ^^^\%systemDrive^^^\%\\tools\\perl\\bin\\perl.exe " .
  172. "^^^\%systemDrive^^^\%\\tools\\OpShellFolder.pl " .
  173. "DelFile Startup myrunbvt.cmd ^^^>^^^>^^^\%SystemDrive^^^\%\\tools\\myrunbvt.cmd");
  174. }
  175. #
  176. # RemoteAddAcount($BVTMachine)
  177. #
  178. # purpose: Add BVTAccount to BVT Machine as administrator
  179. # details:
  180. # Send net localgropu command to remote console
  181. #
  182. sub RemoteAddAccount {
  183. my ($BVTMachine) = @_;
  184. &MyRemoteCommand($BVTMachine, $RemoteId,
  185. "net localgroup $AdministratorGroupName " .
  186. "/add $BVTAccountDomainname\\$BVTAccountUsername");
  187. &MyRemoteCommand($BVTMachine, $RemoteId,
  188. "if errorlevel 1 pause Please make sure account add correctly!!!");
  189. }
  190. #
  191. # NoticeMessage($Message, @Domain_Users)
  192. #
  193. # purpose: logmsg and Net Send message to Domain/Users
  194. # details:
  195. # Send net localgropu command to remote console
  196. #
  197. sub NoticeMessage {
  198. my ($Message, $BVTMachine, @Domain_Users) = @_;
  199. my ($Domain_User, $DomainName, $UserName)=();
  200. logmsg $Message;
  201. if (defined $BVTMachine) {
  202. if ($BVTMachine !~ /(\w+)\:(\w+)/) {
  203. errmsg "Echo into remote($DomainName:$RemoteId) failed";
  204. return;
  205. }
  206. ($DomainName) = $1;
  207. &MyRemoteCommand($DomainName, $RemoteId, "echo $Message");
  208. }
  209. for $Domain_User (@Domain_Users) {
  210. # Skip if not formate as "<DomainName>:<UserName>"
  211. next if ($Domain_User !~ /(\w+)\:(\w+)/);
  212. # Assign the match pattern to the variable
  213. ($DomainName, $UserName)=($1, $2);
  214. # Net Send Message to This Domain\User
  215. &MySystemCall("Net send $UserName /Domain:$DomainName $Message");
  216. }
  217. }
  218. #
  219. # UpdateRegistry($Machine, $hKey, $SubKey, $ValueName, $Data)
  220. #
  221. # purpose: Connect to Machine and update the ValueName with Data under hKey\Subkey
  222. # details:
  223. # 1. Connect $Machine Registry with $hKey (eg. HKEY_LOCAL_MACHINE) and store handle to $phKey)
  224. # 2. Open $SubKey under $phKey and store handle to $phSubKey
  225. # 3. Store $Data to $valuename under $phSubKey
  226. # 4. Close the register
  227. #
  228. sub UpdateRegistry{
  229. my ($Machine, $hKey, $SubKey, $ValueName, $Data)=@_;
  230. my ($phKey, $phSubKey, $ptype, $pvalue);
  231. RegConnectRegistry( $Machine, $hKey, $phKey ) or return 0;
  232. RegOpenKeyEx( $phKey, $SubKey, 0, KEY_ALL_ACCESS, $phSubKey) or return 0;
  233. RegSetValueEx( $phSubKey, $ValueName, 0, REG_SZ, $Data, 0 ) or return 0;
  234. RegCloseKey( $phSubKey ) or return 0;
  235. RegCloseKey( $phKey ) or return 0;
  236. return 1;
  237. }
  238. #
  239. # WhereIsMyBootTestMachine($platform, $frechk, $sku)
  240. #
  241. # purpose: Retrive the boot test machine name from <branch>.<language>.ini
  242. # details:
  243. # 1. Set the query key as "BootTestMachines::$platform$frechk::$sku"
  244. # 2. Call GetSetting to get the value from ini file
  245. #
  246. sub WhereIsMyBootTestMachine {
  247. my ($platform, $frechk, $sku) = @_;
  248. my( @Request ) = ( "BootTestMachines", "${platform}${frechk}", $sku );
  249. return &GetIniSetting::GetSetting( @Request );
  250. }
  251. #
  252. # MyRemoteCommand($Machine, $RemoteId, $cmd)
  253. #
  254. # purpose: Execute $cmd on remote console
  255. #
  256. sub MyRemoteCommand {
  257. my ($Machine, $RemoteId, $cmd) = @_;
  258. return &MySystemCall("echo $cmd|remote /c $Machine $RemoteId");
  259. }
  260. #
  261. # MySystemCall($cmd)
  262. #
  263. # purpose: Execute $cmd thru system call
  264. #
  265. sub MySystemCall {
  266. my ($cmd) = @_;
  267. my $r = system($cmd);
  268. $r >>= 8;
  269. # Because remote command always return 4, we should ignore it.
  270. if (($r)&&($r ne 4)&&($r ne 0)) {
  271. errmsg "Failed ($r): $cmd";
  272. return 0;
  273. }
  274. return 1;
  275. }
  276. #
  277. # splitcolon($str)
  278. #
  279. # purpose: split $str with delimiter ':' and return splited string
  280. #
  281. sub splitcolon {
  282. return grep {/\w+/} split(/\:/, $_[0]);
  283. }
  284. #
  285. # splitsemicolon($str)
  286. #
  287. # purpose: split $str with delimiter ';' and return splited string
  288. #
  289. sub splitsemicolon {
  290. return grep {/\w+/} split(/\;/, $_[0]);
  291. }
  292. sub GetAccount {
  293. my (@Request) = ("JoinDomain");
  294. my( $JoinDomain ) = &GetIniSetting::GetSetting( @Request );
  295. return $JoinDomain;
  296. }
  297. sub ValidateParams {
  298. #<Add your code for validating the parameters here>
  299. # Initial GetIniSetting
  300. unless ( &GetIniSetting::CheckIniFile ) {
  301. errmsg( "Failed to find ini file ..." );
  302. return;
  303. }
  304. if (!defined $BVTAccount) {
  305. @JoinDomain = split(/\s+/, &GetAccount);
  306. $BVTAccount=join(":",@JoinDomain[1,0,2]);
  307. }
  308. ($BVTAccountUsername, $BVTAccountDomainname, $BVTAccountPassword) = &splitcolon($BVTAccount);
  309. if (defined $administrator) {
  310. ($AdministratorName, $AdministratorGroupName)=&splitcolon($administrator);
  311. }
  312. if (! defined $AdministratorName) {
  313. $AdministratorName = (lc$lang ne "ger")?"Administrator":"Administrator";
  314. }
  315. if (! defined $AdministratorGroupName) {
  316. $AdministratorGroupName = (lc$lang ne "ger")?"Administrators":"Administratoren";
  317. }
  318. @NoticeList = &splitsemicolon($Noticed);
  319. @NoticeListForSingleMessage = &splitsemicolon($OneNotice);
  320. @platforms = &splitcolon($platforms) if (defined $platforms);
  321. @frechks = &splitcolon($frechks) if (defined $frechks);
  322. }
  323. # <Add your usage here>
  324. sub Usage {
  325. print <<USAGE;
  326. Purpose of program
  327. Usage: $0 [-l lang] [-m BVTMachine] [-i RemoteId] [-a BVTAccount]
  328. [-n Noticed] [-o OneNotice] [-z administrator] [-p platform]
  329. [-c frechk] [-s BVTEntry] [-t BVTResult]
  330. -l Language
  331. -m BVTMachine - BVT Machine Name; default is reference from
  332. <branch>.<lang>.ini file and add "1" after the safe boottest
  333. machine name. Specified BVTMachine name as
  334. "foomachine;boomachine". Such as i32bt0011.
  335. -i RemoteId
  336. Currently the remote ID name on BVTMachine; default is
  337. "Booted".
  338. -a BVTAccount
  339. The UserName/Domain/Password Account for re-login BVT machine.
  340. The format is "foo_user:boo_domain:goo_password"
  341. -n Noticed. The process will notice the domain/user each step.
  342. This script always notice the BVTMachine/Administrator. If
  343. you need add more, use the format as
  344. "foo_user:foo_domain;boo_user:boo_domain;"
  345. -o OneNotice. After the BVT process assigned to the BVT Machine,
  346. Send message to this domain/user. It will net send message to
  347. the domain/user. The format is the same as <Noticed>.
  348. -z administrator. Defined the localized term for administrator.
  349. The format is "<administratorgroupname>:<administratorname>".
  350. Such as "administratoren:Administrator" in German.
  351. -p platforms; such as "x86:amd64:ia64". Default is "x86".
  352. -c frechks; such as "fre:chk". Default is "fre".
  353. -s BVTEntry; the script for starting run BVT. Default is
  354. "\\\\intlntsetup\\bvtsrc\\runbvt".
  355. -t BVTResult; the path for store BVT result. We launch the BVT
  356. process as <BVTEntry> <SystemDrive>\\BVT <BVTResult>.
  357. -? Displays usage
  358. Example:
  359. $0 -l jpn
  360. USAGE
  361. }
  362. sub GetParams {
  363. # Step 1: Call pm getparams with specified arguments
  364. &GetParams::getparams(@_);
  365. # Step 2: Set the language into the enviroment
  366. $ENV{lang}=$lang;
  367. # Step 3: Call the usage if specified by /?
  368. if ($HELP) {
  369. &Usage();
  370. exit 1;
  371. }
  372. }
  373. # Cmd entry point for script.
  374. if (eval("\$0 =~ /" . __PACKAGE__ . "\\.pl\$/i")) {
  375. # Step 1: Parse the command line
  376. # <run perl.exe GetParams.pm /? to get the complete usage for GetParams.pm>
  377. &GetParams ('-o', 'l:m:i:a:n:o:z:p:c:s:t:', '-p',
  378. 'lang BVTMachine RemoteId BVTAccount Noticed OneNotice administrator platforms frechk BVTEntry BVTResult', @ARGV);
  379. # Include local environment extensions
  380. &LocalEnvEx::localenvex('initialize');
  381. # Set lang from the environment
  382. $lang=$ENV{lang};
  383. # Validate the option given as parameter.
  384. &ValidateParams;
  385. # Step 4: Call the main function
  386. &assignbvt::Main();
  387. # End local environment extensions.
  388. &LocalEnvEx::localenvex('end');
  389. }
  390. # -------------------------------------------------------------------------------------------
  391. # Script: assignbvt.pl
  392. # Purpose: Template perl perl script for the NT postbuild environment
  393. # SD Location: %sdxroot%\tools\postbuildscripts
  394. #
  395. # (1) Code section description:
  396. # CmdMain - Developer code section. This is where your work gets done.
  397. # <Implement your subs here> - Developer subs code section. This is where you write subs.
  398. #
  399. # (2) Reserved Variables -
  400. # $ENV{HELP} - Flag that specifies usage.
  401. # $ENV{lang} - The specified language. Defaults to USA.
  402. # $ENV{logfile} - The path and filename of the logs file.
  403. # $ENV{logfile_bak} - The path and filename of the logfile.
  404. # $ENV{errfile} - The path and filename of the error file.
  405. # $ENV{tmpfile} - The path and filename of the temp file.
  406. # $ENV{errors} - The scripts errorlevel.
  407. # $ENV{script_name} - The script name.
  408. # $ENV{_NTPostBld} - Abstracts the language from the files path that
  409. # postbuild operates on.
  410. # $ENV{_NTPostBld_Bak} - Reserved support var.
  411. # $ENV{_temp_bak} - Reserved support var.
  412. #
  413. # (3) Reserved Subs -
  414. # Usage - Use this sub to discribe the scripts usage.
  415. # ValidateParams - Use this sub to verify the parameters passed to the script.
  416. #
  417. # (4) Call other executables or command scripts by using:
  418. # system "foo.exe";
  419. # Note that the executable/script you're calling with system must return a
  420. # non-zero value on errors to make the error checking mechanism work.
  421. #
  422. # Example
  423. # if (system("perl.exe foo.pl -l $lang")){
  424. # errmsg("perl.exe foo.pl -l $lang failed.");
  425. # # If you need to terminate function's execution on this error
  426. # goto End;
  427. # }
  428. #
  429. # (5) Log non-error information by using:
  430. # logmsg "<log message>";
  431. # and log error information by using:
  432. # errmsg "<error message>";
  433. #
  434. # (6) Have your changes reviewed by a member of the US build team (ntbusa) and
  435. # by a member of the international build team (ntbintl).
  436. #
  437. # -------------------------------------------------------------------------------------------
  438. =head1 NAME
  439. B<mypackage> - What this package for
  440. =head1 SYNOPSIS
  441. <An code example how to use>
  442. =head1 DESCRIPTION
  443. <Use above example to describe this package>
  444. =head1 INSTANCES
  445. =head2 <myinstances>
  446. <Description of myinstances>
  447. =head1 METHODS
  448. =head2 <mymathods>
  449. <Description of mymathods>
  450. =head1 SEE ALSO
  451. <Some related package or None>
  452. =head1 AUTHOR
  453. <Your Name <your e-mail address>>
  454. =cut
  455. 1;