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.

971 lines
28 KiB

  1. /*--
  2. Copyright (c) 1997-1997 Microsoft Corporation
  3. Module Name:
  4. dssetdc.c
  5. Abstract:
  6. Command line tool for promoting/demoting servers into and out of the Ds
  7. Author:
  8. 1-Apr-1997 Mac McLain (macm) Created
  9. Environment:
  10. User mode only.
  11. Requires ANSI C extensions: slash-slash comments, long external names.
  12. Revision History:
  13. --*/
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. #include <windows.h>
  18. #include <ntlsa.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <dsrole.h>
  22. #include <dsrolep.h>
  23. #define TAG_DNS "dns"
  24. #define TAG_FLAT "flat"
  25. #define TAG_SITE "site"
  26. #define TAG_DB "db"
  27. #define TAG_LOG "log"
  28. #define TAG_SYSVOL "sysvol"
  29. #define TAG_PARENT "parent"
  30. #define TAG_REPLICA "replica"
  31. #define TAG_USER "user"
  32. #define TAG_PASSWORD "password"
  33. #define TAG_SERVER "server"
  34. #define TAG_OPTIONS "options"
  35. #define TAG_LEVEL "level"
  36. #define TAG_ROLE "role"
  37. #define TAG_LASTDC "lastdc"
  38. #define TAG_ADMINPWD "adminpwd"
  39. #define TAG_WAIT "wait"
  40. #define TAG_FIXDC "fixdc"
  41. //
  42. // Macro to help command line parsing...
  43. //
  44. #define PARSE_CMD_VALUE_AND_CONTINUE( tag, value, buff, ptr ) \
  45. if ( !_strnicmp( value, tag, sizeof( tag ) - 1 ) ) { \
  46. value += sizeof(tag) - 1; \
  47. if ( *value == ':' ) { \
  48. value++; \
  49. mbstowcs(buff, value, strlen(value) + 1); \
  50. ptr = buff; \
  51. continue; \
  52. } \
  53. }
  54. VOID
  55. Usage (
  56. PWSTR DefaultDns,
  57. PWSTR DefaultFlat,
  58. PWSTR DefaultSite,
  59. PWSTR DefaultPath
  60. )
  61. /*++
  62. Routine Description:
  63. Displays the expected usage
  64. Arguments:
  65. Return Value:
  66. VOID
  67. --*/
  68. {
  69. printf("dssetdc -promote <parameters>\n");
  70. printf(" -info <parameters>\n");
  71. printf(" -demote <parameters>\n");
  72. printf(" -save\n");
  73. printf(" -abort <parameters>\n");
  74. printf(" -upgrade <parameters>\n");
  75. printf(" -fixdc <parameters>\n");
  76. printf(" where:\n");
  77. printf(" promote parameters are:\n");
  78. printf(" -%s:dns domain name of the new domain/domain to install as replica "
  79. "of. Defaults to %ws\n", TAG_DNS, DefaultDns);
  80. printf(" -%s:NetBIOS domain name. Defaults to %ws\n", TAG_FLAT, DefaultFlat);
  81. printf(" -%s:site name. Defaults to %ws\n", TAG_SITE, DefaultSite);
  82. printf(" -%s:db path Defaults to %ws.\n", TAG_DB, DefaultPath);
  83. printf(" -%s:log path Defaults to %ws.\n", TAG_LOG, DefaultPath);
  84. printf(" -%s:sysvol path. Defaults to %ws. [Must be NT5 NTFS]\n", TAG_SYSVOL, DefaultPath);
  85. printf(" [-%s:parent dns domain name if this is a child domain]\n", TAG_PARENT);
  86. printf(" [-%s:replica partner]\n", TAG_REPLICA);
  87. printf(" [-%s:account]\n", TAG_USER);
  88. printf(" [-%s:password]\n", TAG_PASSWORD);
  89. printf(" [-%s:options]\n", TAG_OPTIONS);
  90. printf(" [-%s:if 1, block until the call has completed\n",TAG_WAIT);
  91. printf(" info parameters are:\n");
  92. printf(" -%s:Remote server to obtain the information for\n", TAG_SERVER);
  93. printf(" -%s:info level\n", TAG_LEVEL);
  94. printf(" Valid info levels are:\n");
  95. printf(" 1 - PrimaryDomainInformation\n");
  96. printf(" 2 - Upgrade State information\n");
  97. printf(" demote parameters are:\n");
  98. printf(" -%s:server role\n", TAG_ROLE);
  99. printf(" Valid server roles are:\n");
  100. printf(" 2 - Member server\n");
  101. printf(" 3 - Standalone server\n");
  102. printf(" [-%s:account]\n", TAG_USER);
  103. printf(" [-%s:password]\n", TAG_PASSWORD);
  104. printf(" [-%s:options]\n", TAG_OPTIONS);
  105. printf(" [-%s:Whether this is the last dc in the domain]\n", TAG_LASTDC);
  106. printf(" Valid options are:\n");
  107. printf(" 0 - Not the last dc in the domain\n");
  108. printf(" 1 - Last DC in the domain\n");
  109. printf(" [-%s:if 1, block until the call has completed\n",TAG_WAIT);
  110. printf(" -abort parameters are:\n");
  111. printf(" -%s:new administrator password. Defaults to NULL\n", TAG_ADMINPWD );
  112. printf(" -upgrade parameters are:\n");
  113. printf(" -%s:dns domain name of the new domain. Defaults to %ws\n", TAG_DNS, DefaultDns);
  114. printf(" -%s:site name. Defaults to %ws\n", TAG_SITE, DefaultSite);
  115. printf(" -%s:db path Defaults to %ws.\n", TAG_DB, DefaultPath);
  116. printf(" -%s:log path Defaults to %ws.\n", TAG_LOG, DefaultPath);
  117. printf(" -%s:sysvol path. Defaults to %ws. [Must be NT5 NTFS]\n", TAG_SYSVOL, DefaultPath);
  118. printf(" [-%s:parent dns domain]\n", TAG_PARENT);
  119. printf(" [-%s:account]\n", TAG_USER);
  120. printf(" [-%s:password]\n", TAG_PASSWORD);
  121. printf(" [-%s:options]\n", TAG_OPTIONS);
  122. printf(" -fixdc parameters are:\n");
  123. printf(" [-%s:server]Remote server to obtain the information for\n", TAG_SERVER);
  124. printf(" [-%s:server]Remote server to sync with\n", TAG_REPLICA);
  125. printf(" [-%s:account]\n", TAG_USER);
  126. printf(" [-%s:password]\n", TAG_PASSWORD);
  127. printf(" [-%s:options]\n", TAG_OPTIONS);
  128. printf(" Valid options (in HEX) are:\n");
  129. printf(" 0x00000001 - Create the machine account if necessary\n");
  130. printf(" 0x00000002 - Sync the machine password\n");
  131. printf(" 0x00000004 - Change the account time\n");
  132. printf(" 0x00000008 - Re-init the time service\n");
  133. printf(" 0x00000010 - Reconfigure the default services\n");
  134. printf(" 0x00000020 - Force a DS replication cycle\n");
  135. printf(" 0x00000040 - Fixup NTFRS\n");
  136. }
  137. DWORD
  138. GetAndDumpInfo(
  139. IN PWSTR Server,
  140. IN ULONG Level
  141. )
  142. {
  143. DWORD Win32Error = ERROR_SUCCESS;
  144. PDSROLE_UPGRADE_STATUS_INFO UpgradeInfo = NULL;
  145. PDSROLE_PRIMARY_DOMAIN_INFO_BASIC DomainInfo = NULL;
  146. PBYTE Buffer = NULL;
  147. PWSTR Roles[ ] = {
  148. L"DsRole_RoleStandaloneWorkstation",
  149. L"DsRole_RoleMemberWorkstation",
  150. L"DsRole_RoleStandaloneServer",
  151. L"DsRole_RoleMemberServer",
  152. L"DsRole_RoleBackupDomainController",
  153. L"DsRole_RolePrimaryDomainController"
  154. };
  155. PWSTR ServerRoles[ ] = {
  156. L"Unknown",
  157. L"Primary",
  158. L"Backup"
  159. };
  160. Win32Error = DsRoleGetPrimaryDomainInformation( Server,
  161. Level,
  162. ( PBYTE * )&Buffer );
  163. if ( Win32Error == ERROR_SUCCESS ) {
  164. switch ( Level ) {
  165. case DsRolePrimaryDomainInfoBasic:
  166. DomainInfo = ( PDSROLE_PRIMARY_DOMAIN_INFO_BASIC )Buffer;
  167. printf( "Machine Role: %lu ( %ws )\n", DomainInfo->MachineRole,
  168. Roles[ DomainInfo->MachineRole ] );
  169. printf( "Flags: 0x%lx\n", DomainInfo->Flags );
  170. printf( "Flat name: %ws\n", DomainInfo->DomainNameFlat );
  171. printf( "Dns Domain name: %ws\n", DomainInfo->DomainNameDns );
  172. printf( "Dns Forest name: %ws\n", DomainInfo->DomainForestName );
  173. break;
  174. case DsRoleUpgradeStatus:
  175. UpgradeInfo = ( PDSROLE_UPGRADE_STATUS_INFO )Buffer;
  176. printf( "Upgrade: %s\n",
  177. ( UpgradeInfo->OperationState & DSROLE_UPGRADE_IN_PROGRESS ) ?
  178. "TRUE" : "FALSE" );
  179. printf( "Previous server role: %ws\n", ServerRoles[ UpgradeInfo->PreviousServerState ] );
  180. }
  181. DsRoleFreeMemory( DomainInfo );
  182. } else {
  183. printf( "DsRoleGetPrimaryDomainInformation failed with %lu\n", Win32Error );
  184. }
  185. return( Win32Error );
  186. }
  187. DWORD
  188. BuildDefaults(
  189. IN PWSTR Dns,
  190. IN PWSTR Flat,
  191. IN PWSTR Site,
  192. IN PWSTR Path
  193. )
  194. {
  195. DWORD Win32Error = ERROR_SUCCESS;
  196. PWSTR Scratch;
  197. ULONG Options;
  198. //
  199. // First, the easy ones
  200. //
  201. wcscpy( Site, L"First Site" );
  202. ExpandEnvironmentStrings( L"%systemroot%\\ntds", Path, MAX_PATH );
  203. return( Win32Error );
  204. }
  205. DWORD
  206. CopyDsDitFiles(
  207. IN LPWSTR DsPath
  208. )
  209. {
  210. DWORD Win32Error = ERROR_SUCCESS;
  211. WCHAR Source[MAX_PATH + 1];
  212. WCHAR Dest[MAX_PATH + 1];
  213. ULONG SrcLen, DestLen = 0;
  214. PWSTR DsDitFiles[] = {
  215. L"ntds.dit",
  216. L"schema.ini"
  217. };
  218. PWSTR CleanupFiles[] = {
  219. L"edb.chk",
  220. L"edb.log",
  221. L"hierarch.dat",
  222. L"ntds.dit",
  223. L"res1.log",
  224. L"res2.log",
  225. L"schema.ini",
  226. L"edb00001.log",
  227. L"edb00002.log",
  228. L"edb00003.log"
  229. L"edb00004.log"
  230. L"edb00005.log"
  231. L"edb00006.log"
  232. };
  233. PWSTR Current;
  234. ULONG i;
  235. if( ExpandEnvironmentStrings( L"%WINDIR%\\system32\\", Source, MAX_PATH ) == FALSE ) {
  236. Win32Error = GetLastError();
  237. } else {
  238. SrcLen = wcslen( Source );
  239. wcscpy( Dest, DsPath );
  240. if ( *(Dest + (wcslen( DsPath ) - 1 )) != L'\\' ) {
  241. wcscat( Dest, L"\\" );
  242. }
  243. DestLen = wcslen( Dest );
  244. }
  245. //
  246. // See if the source directory exists...
  247. //
  248. if ( Win32Error == ERROR_SUCCESS && GetFileAttributes( DsPath ) == 0x10 ) {
  249. for ( i = 0; i < sizeof( CleanupFiles) / sizeof( PWSTR ); i++ ) {
  250. wcscpy( Dest + DestLen, CleanupFiles[i] );
  251. if ( DeleteFile( Dest ) == FALSE ) {
  252. Win32Error = GetLastError();
  253. if ( Win32Error == ERROR_FILE_NOT_FOUND ) {
  254. Win32Error = ERROR_SUCCESS;
  255. } else {
  256. printf("Failed to remove %ws: %lu\n", Dest, Win32Error );
  257. break;
  258. }
  259. }
  260. }
  261. }
  262. //
  263. // Then, create the destination directory
  264. //
  265. if ( Win32Error == ERROR_SUCCESS ) {
  266. Current = wcschr( DsPath + 4, L'\\' );
  267. while ( Win32Error == ERROR_SUCCESS ) {
  268. if ( Current != NULL ) {
  269. *Current = UNICODE_NULL;
  270. }
  271. if ( CreateDirectory( DsPath, NULL ) == FALSE ) {
  272. Win32Error = GetLastError();
  273. if ( Win32Error == ERROR_ALREADY_EXISTS) {
  274. Win32Error = ERROR_SUCCESS;
  275. }
  276. }
  277. if ( Current != NULL ) {
  278. *Current = L'\\';
  279. Current = wcschr( Current + 1, L'\\' );
  280. } else {
  281. break;
  282. }
  283. }
  284. }
  285. return( Win32Error );
  286. }
  287. DWORD
  288. Promote( LPWSTR Dns, LPWSTR Flat, LPWSTR Site, LPWSTR Db, LPWSTR Log,
  289. LPWSTR SysVol, LPWSTR Parent, LPWSTR Replica, LPWSTR User,
  290. LPWSTR Password, LPWSTR Server, ULONG Options, BOOL Block
  291. )
  292. {
  293. DWORD Win32Error = ERROR_SUCCESS;
  294. DSROLE_SERVEROP_HANDLE Handle;
  295. PDSROLE_SERVEROP_STATUS Status;
  296. PDSROLE_SERVEROP_RESULTS Results;
  297. if ( !Server ) {
  298. Win32Error = CopyDsDitFiles( Db );
  299. if ( Win32Error != ERROR_SUCCESS ) {
  300. return( Win32Error );
  301. }
  302. }
  303. //
  304. // Now, do the install
  305. //
  306. if ( Replica != NULL ) {
  307. Win32Error = DsRoleDcAsReplica( Server,
  308. Dns,
  309. Replica,
  310. Site,
  311. Db,
  312. Log,
  313. NULL,
  314. SysVol,
  315. NULL,
  316. User,
  317. Password,
  318. NULL,
  319. Options,
  320. &Handle );
  321. } else {
  322. Win32Error = DsRoleDcAsDc( Server,
  323. Dns,
  324. Flat,
  325. NULL,
  326. Site,
  327. Db,
  328. Log,
  329. SysVol,
  330. Parent,
  331. NULL,
  332. User,
  333. Password,
  334. NULL,
  335. Options,
  336. &Handle );
  337. }
  338. if ( Win32Error == ERROR_SUCCESS ) {
  339. if ( !Block ) {
  340. do {
  341. Sleep( 6000 );
  342. Win32Error = DsRoleGetDcOperationProgress( NULL,
  343. Handle,
  344. &Status );
  345. if ( Win32Error == ERROR_SUCCESS || Win32Error == ERROR_IO_PENDING ) {
  346. printf("%ws\n", Status->CurrentOperationDisplayString );
  347. DsRoleFreeMemory( Status );
  348. }
  349. } while( Win32Error == ERROR_IO_PENDING);
  350. if ( Win32Error != ERROR_SUCCESS ) {
  351. printf("Failed determining the operation progress: %lu\n", Win32Error );
  352. }
  353. } else {
  354. printf( "Block on DsRoleGetDcOperationResutls call\n" );
  355. }
  356. } else {
  357. printf( "Failed to install as a Dc: %lu\n", Win32Error );
  358. }
  359. if ( Win32Error == ERROR_SUCCESS ) {
  360. Win32Error = DsRoleGetDcOperationResults( NULL,
  361. Handle,
  362. &Results );
  363. if ( Win32Error == ERROR_SUCCESS ) {
  364. Win32Error = Results->OperationStatus;;
  365. printf( "OperationResults->OperationStatusDisplayString: %ws\n",
  366. Results->OperationStatusDisplayString );
  367. printf( "OperationResults->ServerInstalledSite: %ws\n",
  368. Results->ServerInstalledSite );
  369. DsRoleFreeMemory( Results );
  370. } else {
  371. printf( "Failed to determine the operation results: %lu\n", Win32Error );
  372. }
  373. }
  374. return( Win32Error );
  375. }
  376. DWORD
  377. Demote( LPWSTR User, LPWSTR Password, ULONG Role, ULONG Options, BOOL LastDc )
  378. {
  379. DWORD Win32Error = ERROR_SUCCESS;
  380. DSROLE_SERVEROP_HANDLE Handle;
  381. PDSROLE_SERVEROP_STATUS Status;
  382. PDSROLE_SERVEROP_RESULTS Results;
  383. Win32Error = DsRoleDemoteDc( NULL, NULL, Role, User, Password, Options,
  384. LastDc, NULL, &Handle );
  385. if ( Win32Error == ERROR_SUCCESS ) {
  386. do {
  387. Sleep( 6000 );
  388. Win32Error = DsRoleGetDcOperationProgress( NULL,
  389. Handle,
  390. &Status );
  391. if ( Win32Error == ERROR_SUCCESS || Win32Error == ERROR_IO_PENDING ) {
  392. printf("%ws\n", Status->CurrentOperationDisplayString );
  393. DsRoleFreeMemory( Status );
  394. }
  395. } while( Win32Error == ERROR_IO_PENDING);
  396. if ( Win32Error != ERROR_SUCCESS ) {
  397. printf("Failed determining the operation progress: %lu\n", Win32Error );
  398. }
  399. } else {
  400. printf( "Failed to demote a Dc: %lu\n", Win32Error );
  401. }
  402. if ( Win32Error == ERROR_SUCCESS ) {
  403. Win32Error = DsRoleGetDcOperationResults( NULL,
  404. Handle,
  405. &Results );
  406. if ( Win32Error == ERROR_SUCCESS ) {
  407. Win32Error = Results->OperationStatus;;
  408. printf( "OperationResults->OperationStatusDisplayString: %ws\n",
  409. Results->OperationStatusDisplayString );
  410. printf( "OperationResults->ServerInstalledSite: %ws\n",
  411. Results->ServerInstalledSite );
  412. DsRoleFreeMemory( Results );
  413. } else {
  414. printf( "Failed to determine the operation results: %lu\n", Win32Error );
  415. }
  416. }
  417. return( Win32Error );
  418. }
  419. DWORD
  420. Save( VOID )
  421. {
  422. DWORD Win32Error = ERROR_SUCCESS;
  423. Win32Error = DsRoleServerSaveStateForUpgrade( NULL );
  424. if ( Win32Error != ERROR_SUCCESS ) {
  425. printf("DsRoleServerSaveStateForUpgrade failed with %lu\n", Win32Error );
  426. }
  427. return( Win32Error );
  428. }
  429. DWORD
  430. Abort(
  431. PWSTR AdminPwd
  432. )
  433. {
  434. DWORD Win32Error = ERROR_SUCCESS;
  435. Win32Error = DsRoleAbortDownlevelServerUpgrade( AdminPwd, NULL, NULL, 0 );
  436. if ( Win32Error != ERROR_SUCCESS ) {
  437. printf("DsRoleAbortDownlevelServerUpgrade failed with %lu\n", Win32Error );
  438. }
  439. return( Win32Error );
  440. }
  441. DWORD
  442. Upgrade( LPWSTR Dns, LPWSTR Site, LPWSTR Db, LPWSTR Log, LPWSTR SysVol,
  443. LPWSTR Parent, LPWSTR User, LPWSTR Password, ULONG Options )
  444. {
  445. DWORD Win32Error = ERROR_SUCCESS;
  446. DSROLE_SERVEROP_HANDLE Handle;
  447. PDSROLE_SERVEROP_STATUS Status;
  448. PDSROLE_SERVEROP_RESULTS Results;
  449. Win32Error = DsRoleUpgradeDownlevelServer( ( LPCWSTR )Dns, ( LPCWSTR )Site, ( LPCWSTR )Db,
  450. ( LPCWSTR )Log, ( LPCWSTR )SysVol,
  451. ( LPCWSTR )Parent, NULL, ( LPCWSTR )User,
  452. ( LPCWSTR )Password, NULL, Options, &Handle );
  453. if ( Win32Error == ERROR_SUCCESS ) {
  454. do {
  455. Sleep( 6000 );
  456. Win32Error = DsRoleGetDcOperationProgress( NULL,
  457. Handle,
  458. &Status );
  459. if ( Win32Error == ERROR_SUCCESS || Win32Error == ERROR_IO_PENDING ) {
  460. printf("%ws\n", Status->CurrentOperationDisplayString );
  461. DsRoleFreeMemory( Status );
  462. }
  463. } while( Win32Error == ERROR_IO_PENDING);
  464. if ( Win32Error != ERROR_SUCCESS ) {
  465. printf("Failed determining the operation progress: %lu\n", Win32Error );
  466. }
  467. } else {
  468. printf( "Failed to install as a Dc: %lu\n", Win32Error );
  469. }
  470. if ( Win32Error == ERROR_SUCCESS ) {
  471. Win32Error = DsRoleGetDcOperationResults( NULL,
  472. Handle,
  473. &Results );
  474. if ( Win32Error == ERROR_SUCCESS ) {
  475. Win32Error = Results->OperationStatus;;
  476. printf( "OperationResults->OperationStatusDisplayString: %ws\n",
  477. Results->OperationStatusDisplayString );
  478. printf( "OperationResults->ServerInstalledSite: %ws\n",
  479. Results->ServerInstalledSite );
  480. DsRoleFreeMemory( Results );
  481. } else {
  482. printf( "Failed to determine the operation results: %lu\n", Win32Error );
  483. }
  484. }
  485. return( Win32Error );
  486. }
  487. INT
  488. __cdecl main (
  489. int argc,
  490. char *argv[])
  491. /*++
  492. Routine Description:
  493. The main the for this executable
  494. Arguments:
  495. argc - Count of arguments
  496. argv - List of arguments
  497. Return Value:
  498. VOID
  499. --*/
  500. {
  501. DWORD Win32Error = ERROR_SUCCESS, OpErr;
  502. WCHAR DnsBuff[MAX_PATH + 1], SiteBuff[MAX_PATH + 1];
  503. WCHAR DbBuff[MAX_PATH + 1], LogBuff[MAX_PATH + 1], ParentBuff[MAX_PATH + 1];
  504. WCHAR ReplicaBuff[MAX_PATH + 1], UserBuff[MAX_PATH + 1], PasswordBuff[MAX_PATH + 1];
  505. WCHAR ScratchBuff[MAX_PATH], ServerBuff[MAX_PATH], FlatBuff[MAX_PATH + 1];
  506. WCHAR SysVolBuff[MAX_PATH + 1], RoleBuff[ 10 ], LastDCBuff[ 10 ], WaitBuff[ 10 ];
  507. WCHAR AdminPwdBuff[ MAX_PATH + 1 ];
  508. ULONG Options = 0, Level = 0, Role = 0, FailedOperation, CompletedOperations;
  509. PWSTR Parent = NULL, Replica = NULL, User = NULL, Password = NULL, Dns = NULL, Flat = NULL;
  510. PWSTR Site = NULL, Db = NULL, Log = NULL, Scratch = NULL, Server = NULL;
  511. PWSTR SysVol = NULL, RoleScratch = NULL, LastDCScratch = NULL, AdminPwd = NULL, Wait = NULL;
  512. INT i = 1;
  513. BOOL LastDC = FALSE, BuildDefaultsFailed = FALSE, Block = FALSE;
  514. PSTR Current;
  515. Win32Error = BuildDefaults( DnsBuff, FlatBuff, SiteBuff, DbBuff );
  516. if ( Win32Error == ERROR_SUCCESS ) {
  517. Dns = DnsBuff;
  518. Site = SiteBuff;
  519. Db = DbBuff;
  520. Log = DbBuff;
  521. Flat = FlatBuff;
  522. } else {
  523. BuildDefaultsFailed = TRUE;
  524. }
  525. if (argc > 1 && (_stricmp( argv[1], "-?") == 0 || _stricmp( argv[1], "/?") == 0 ) ) {
  526. if ( BuildDefaultsFailed ) {
  527. printf( "Failed to get the defaults: %lu\n", Win32Error );
  528. }
  529. Usage( Dns, Flat, Site, Db );
  530. goto Done;
  531. } else if (argc > 1 && ( _stricmp( argv[ 1 ], "-info" ) == 0 || _stricmp( argv[ 1 ], "/info" ) == 0 ) ) {
  532. for (i = 2; i < argc; i++ ) {
  533. Current = argv[i];
  534. if ( !( *Current == '-' || *Current == '/' ) ) {
  535. Win32Error = ERROR_INVALID_PARAMETER;
  536. break;
  537. }
  538. Current++;
  539. PARSE_CMD_VALUE_AND_CONTINUE( TAG_SERVER, Current, ServerBuff, Server );
  540. PARSE_CMD_VALUE_AND_CONTINUE( TAG_LEVEL, Current, ScratchBuff, Scratch );
  541. }
  542. if ( Win32Error == ERROR_SUCCESS && Scratch ) {
  543. Level = wcstol( Scratch, &Scratch, 10 );
  544. }
  545. Win32Error = GetAndDumpInfo( Server, Level );
  546. goto Done;
  547. } else if (argc > 1 && ( _stricmp( argv[ 1 ], "-promote" ) == 0 || _stricmp( argv[ 1 ], "/promote" ) == 0) ) {
  548. if ( BuildDefaultsFailed ) {
  549. printf( "Failed to get the defaults: %lu\n", Win32Error );
  550. goto Done;
  551. }
  552. for (i = 2; i < argc; i++ ) {
  553. Current = argv[i];
  554. if ( !( *Current == '-' || *Current == '/' ) ) {
  555. Win32Error = ERROR_INVALID_PARAMETER;
  556. break;
  557. }
  558. Current++;
  559. PARSE_CMD_VALUE_AND_CONTINUE( TAG_DNS, Current, DnsBuff, Dns );
  560. PARSE_CMD_VALUE_AND_CONTINUE( TAG_FLAT, Current, FlatBuff, Flat );
  561. PARSE_CMD_VALUE_AND_CONTINUE( TAG_SITE, Current, SiteBuff, Site );
  562. PARSE_CMD_VALUE_AND_CONTINUE( TAG_DB, Current, DbBuff, Db );
  563. PARSE_CMD_VALUE_AND_CONTINUE( TAG_LOG, Current, LogBuff, Log );
  564. PARSE_CMD_VALUE_AND_CONTINUE( TAG_SYSVOL, Current, SysVolBuff, SysVol );
  565. PARSE_CMD_VALUE_AND_CONTINUE( TAG_PARENT, Current, ParentBuff, Parent );
  566. PARSE_CMD_VALUE_AND_CONTINUE( TAG_REPLICA, Current, ReplicaBuff, Replica );
  567. PARSE_CMD_VALUE_AND_CONTINUE( TAG_USER, Current, UserBuff, User );
  568. PARSE_CMD_VALUE_AND_CONTINUE( TAG_PASSWORD, Current, PasswordBuff, Password );
  569. PARSE_CMD_VALUE_AND_CONTINUE( TAG_SERVER, Current, ServerBuff, Server );
  570. PARSE_CMD_VALUE_AND_CONTINUE( TAG_OPTIONS, Current, ScratchBuff, Scratch );
  571. PARSE_CMD_VALUE_AND_CONTINUE( TAG_WAIT, Current, WaitBuff, Wait );
  572. printf("Unexpected command line value %s\n\n", argv[i] );
  573. Win32Error = ERROR_INVALID_PARAMETER;
  574. break;
  575. }
  576. if ( Scratch != NULL ) {
  577. Options = wcstoul( Scratch, &Scratch, 0 );
  578. }
  579. //
  580. // Validate the parameters
  581. //
  582. if ( Dns == NULL || Db == NULL || Log == NULL || Flat == NULL ) {
  583. Win32Error = ERROR_INVALID_PARAMETER;
  584. }
  585. if( Win32Error == ERROR_INVALID_PARAMETER ) {
  586. Usage( Dns, Flat, Site, Db );
  587. goto Done;
  588. }
  589. if ( Wait && wcscmp( Wait, L"1" ) ) {
  590. Block = TRUE;
  591. }
  592. Win32Error = Promote( Dns, Flat, Site, Db, Log, SysVol, Parent,
  593. Replica, User, Password, Server, Options, Block );
  594. } else if (argc > 1 && ( _stricmp( argv[ 1 ], "-demote" ) == 0 || _stricmp( argv[ 1 ], "/demote" ) == 0 ) ) {
  595. for (i = 2; i < argc; i++ ) {
  596. Current = argv[i];
  597. if ( !( *Current == '-' || *Current == '/' ) ) {
  598. Win32Error = ERROR_INVALID_PARAMETER;
  599. break;
  600. }
  601. Current++;
  602. PARSE_CMD_VALUE_AND_CONTINUE( TAG_USER, Current, UserBuff, User );
  603. PARSE_CMD_VALUE_AND_CONTINUE( TAG_PASSWORD, Current, PasswordBuff, Password );
  604. PARSE_CMD_VALUE_AND_CONTINUE( TAG_ROLE, Current, RoleBuff, RoleScratch );
  605. PARSE_CMD_VALUE_AND_CONTINUE( TAG_OPTIONS, Current, ScratchBuff, Scratch );
  606. PARSE_CMD_VALUE_AND_CONTINUE( TAG_LASTDC, Current, LastDCBuff, LastDCScratch );
  607. printf("Unexpected command line value %s\n\n", argv[i] );
  608. Win32Error = ERROR_INVALID_PARAMETER;
  609. break;
  610. }
  611. if ( Scratch != NULL ) {
  612. Options = wcstoul( Scratch, &Scratch, 0 );
  613. }
  614. if ( RoleScratch == NULL ) {
  615. Win32Error = ERROR_INVALID_PARAMETER;
  616. } else {
  617. Role = wcstoul( RoleScratch, &RoleScratch, 0);
  618. }
  619. if ( LastDCScratch != NULL ) {
  620. LastDC = ( BOOL )wcstoul( LastDCScratch, &LastDCScratch, 0);
  621. }
  622. if( Win32Error == ERROR_INVALID_PARAMETER ) {
  623. Usage( Dns, Flat, Site, Db );
  624. goto Done;
  625. }
  626. Win32Error = Demote( User, Password, Role, Options, LastDC );
  627. } else if (argc > 1 && ( _stricmp( argv[ 1 ], "-save" ) == 0 || _stricmp( argv[ 1 ], "/save" ) == 0 ) ) {
  628. Win32Error = Save();
  629. } else if (argc > 1 && ( _stricmp( argv[ 1 ], "-abort" ) == 0 || _stricmp( argv[ 1 ], "/abort" ) == 0 ) ) {
  630. for (i = 2; i < argc; i++ ) {
  631. Current = argv[i];
  632. if ( !( *Current == '-' || *Current == '/' ) ) {
  633. Win32Error = ERROR_INVALID_PARAMETER;
  634. break;
  635. }
  636. Current++;
  637. PARSE_CMD_VALUE_AND_CONTINUE( TAG_ADMINPWD, Current, AdminPwdBuff, AdminPwd );
  638. printf("Unexpected command line value %s\n\n", argv[i] );
  639. Win32Error = ERROR_INVALID_PARAMETER;
  640. break;
  641. }
  642. Win32Error = Abort( AdminPwd );
  643. } else if (argc > 1 && ( _stricmp( argv[ 1 ], "-upgrade" ) == 0 || _stricmp( argv[ 1 ], "/upgrade" ) == 0) ) {
  644. if ( BuildDefaultsFailed ) {
  645. printf( "Failed to get the defaults: %lu\n", Win32Error );
  646. goto Done;
  647. }
  648. for (i = 2; i < argc; i++ ) {
  649. Current = argv[i];
  650. if ( !( *Current == '-' || *Current == '/' ) ) {
  651. Win32Error = ERROR_INVALID_PARAMETER;
  652. break;
  653. }
  654. Current++;
  655. PARSE_CMD_VALUE_AND_CONTINUE( TAG_DNS, Current, DnsBuff, Dns );
  656. PARSE_CMD_VALUE_AND_CONTINUE( TAG_SITE, Current, SiteBuff, Site );
  657. PARSE_CMD_VALUE_AND_CONTINUE( TAG_DB, Current, DbBuff, Db );
  658. PARSE_CMD_VALUE_AND_CONTINUE( TAG_LOG, Current, LogBuff, Log );
  659. PARSE_CMD_VALUE_AND_CONTINUE( TAG_SYSVOL, Current, SysVolBuff, SysVol );
  660. PARSE_CMD_VALUE_AND_CONTINUE( TAG_PARENT, Current, ParentBuff, Parent );
  661. PARSE_CMD_VALUE_AND_CONTINUE( TAG_USER, Current, UserBuff, User );
  662. PARSE_CMD_VALUE_AND_CONTINUE( TAG_PASSWORD, Current, PasswordBuff, Password );
  663. PARSE_CMD_VALUE_AND_CONTINUE( TAG_OPTIONS, Current, ScratchBuff, Scratch );
  664. printf("Unexpected command line value %s\n\n", argv[i] );
  665. Win32Error = ERROR_INVALID_PARAMETER;
  666. break;
  667. }
  668. if ( Scratch != NULL ) {
  669. Options = wcstoul( Scratch, &Scratch, 0 );
  670. }
  671. //
  672. // Validate the parameters
  673. //
  674. if ( Dns == NULL || Db == NULL || Log == NULL ) {
  675. Win32Error = ERROR_INVALID_PARAMETER;
  676. }
  677. if( Win32Error == ERROR_INVALID_PARAMETER ) {
  678. Usage( Dns, Flat, Site, Db );
  679. goto Done;
  680. }
  681. Win32Error = Upgrade( Dns, Site, Db, Log, SysVol, Parent, User,
  682. Password, Options );
  683. }
  684. Done:
  685. if( Win32Error == ERROR_SUCCESS ) {
  686. printf("The command completed successfully\n");
  687. } else {
  688. printf("The command failed with an error %lu\n", Win32Error );
  689. }
  690. return( Win32Error );
  691. }