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.

616 lines
19 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // BaseClusterTest.cpp
  7. //
  8. // Description:
  9. // Main file for the test harness executable.
  10. // Initializes tracing, parses command line and actually call the
  11. // BaseClusCfg functions.
  12. //
  13. // Documentation:
  14. // No documention for the test harness.
  15. //
  16. // Maintained By:
  17. // Vij Vasu (Vvasu) 08-MAR-2000
  18. //
  19. //////////////////////////////////////////////////////////////////////////////
  20. //////////////////////////////////////////////////////////////////////////////
  21. // Include Files
  22. //////////////////////////////////////////////////////////////////////////////
  23. #include "pch.h"
  24. #include <stdio.h>
  25. #include <objbase.h>
  26. #include <limits.h>
  27. #include <initguid.h>
  28. #include "guids.h"
  29. #include "CClusCfgCallback.h"
  30. // Show help for this executable.
  31. void ShowUsage()
  32. {
  33. wprintf( L"\nThe syntax of this command is:\n" );
  34. wprintf( L"\nBaseClusterTest.exe [computer-name] {<options>}\n" );
  35. wprintf( L"\n<options> =\n" );
  36. wprintf( L" /FORM NAME= cluster-name DOMAIN= account-domain ACCOUNT= clussvc-account\n" );
  37. wprintf( L" PASSWORD= account-password IPADDR= ip-address(hex)\n" );
  38. wprintf( L" SUBNET= ip-subnet-mask(hex) NICNAME= ip-nic-name\n\n" );
  39. wprintf( L" /JOIN NAME= cluster-name DOMAIN= account-domain ACCOUNT= clussvc-account\n" );
  40. wprintf( L" PASSWORD= account-password\n\n" );
  41. wprintf( L" /CLEANUP\n" );
  42. wprintf( L"\nNotes:\n" );
  43. wprintf( L"- A space is required after an '=' sign.\n" );
  44. wprintf( L"- The order for the parameters has to be the same as shown above.\n" );
  45. }
  46. // Create the BaseCluster component.
  47. HRESULT HrInitComponent(
  48. COSERVERINFO * pcoServerInfoPtrIn
  49. , CSmartIfacePtr< IClusCfgBaseCluster > & rspClusCfgBaseClusterIn
  50. )
  51. {
  52. HRESULT hr = S_OK;
  53. do
  54. {
  55. MULTI_QI mqiInterfaces[] =
  56. {
  57. { &IID_IClusCfgBaseCluster, NULL, S_OK },
  58. { &IID_IClusCfgInitialize, NULL, S_OK }
  59. };
  60. //
  61. // Create and initialize the BaseClusterAction component
  62. //
  63. hr = CoCreateInstanceEx(
  64. CLSID_ClusCfgBaseCluster
  65. , NULL
  66. , CLSCTX_LOCAL_SERVER
  67. , pcoServerInfoPtrIn
  68. , sizeof( mqiInterfaces ) / sizeof( mqiInterfaces[0] )
  69. , mqiInterfaces
  70. );
  71. // Store the retrieved pointers in smart pointers for safe release.
  72. rspClusCfgBaseClusterIn.Attach(
  73. reinterpret_cast< IClusCfgBaseCluster * >( mqiInterfaces[0].pItf )
  74. );
  75. CSmartIfacePtr< IClusCfgInitialize > spClusCfgInitialize;
  76. spClusCfgInitialize.Attach( reinterpret_cast< IClusCfgInitialize * >( mqiInterfaces[1].pItf ) );
  77. // Check if CoCreateInstanceEx() worked.
  78. if ( FAILED( hr ) && ( hr != CO_S_NOTALLINTERFACES ) )
  79. {
  80. wprintf( L"Could not create the BaseCluster component. Error %#08x.\n", hr );
  81. break;
  82. } // if: CoCreateInstanceEx() failed
  83. // Check if we got the pointer to the IClusCfgBaseCluster interface.
  84. hr = mqiInterfaces[0].hr;
  85. if ( FAILED( hr ) )
  86. {
  87. // We cannot do anything without this pointer - bail.
  88. wprintf( L"Could not get the IClusCfgBaseCluster pointer. Error %#08x.\n", hr );
  89. break;
  90. } // if: we could not get a pointer to the IClusCfgBaseCluster interface
  91. //
  92. // Check if we got a pointer to the IClusCfgInitialize interface
  93. hr = mqiInterfaces[1].hr;
  94. if ( hr == S_OK )
  95. {
  96. // We got the pointer - initialize the component.
  97. IUnknown * punk = NULL;
  98. IClusCfgCallback * pccb = NULL;
  99. hr = CClusCfgCallback::S_HrCreateInstance( &punk );
  100. if ( FAILED( hr ) )
  101. {
  102. wprintf( L"Could not initalize callback component. Error %#08x.\n", hr );
  103. break;
  104. }
  105. hr = punk->QueryInterface< IClusCfgCallback >( &pccb );
  106. punk->Release( );
  107. if ( FAILED( hr ) )
  108. {
  109. wprintf( L"Could not find IClusCfgCallback on CClusCfgCallback object. Error %#08x.\n", hr );
  110. break;
  111. }
  112. hr = spClusCfgInitialize->Initialize( pccb, LOCALE_SYSTEM_DEFAULT );
  113. if ( pccb != NULL )
  114. {
  115. pccb->Release();
  116. } // if: we created a callback, release it.
  117. if ( FAILED( hr ) )
  118. {
  119. if ( hr == HRESULT_FROM_WIN32( ERROR_ACCESS_DENIED ) )
  120. {
  121. wprintf( L"Access was denied trying to initialize the BaseCluster component. This may be because remote callbacks are not supported. However, configuration will proceed.\n" );
  122. hr = ERROR_SUCCESS;
  123. } // if: the error was ERROR_ACCESS_DENIED
  124. else
  125. {
  126. wprintf( L"Could not initialize the BaseCluster component. Error %#08x occurred. Configuration will be aborted.\n", hr );
  127. break;
  128. } // else: some other error occurred.
  129. } // if: something went wrong during initialization
  130. } // if: we got a pointer to the IClusCfgInitialize interface
  131. else
  132. {
  133. wprintf( L"The BaseCluster component does not provide notifications.\n" );
  134. if ( hr != E_NOINTERFACE )
  135. {
  136. break;
  137. } // if: the interface is supported, but something else went wrong.
  138. //
  139. // If the interface is not support, that is ok. It just means that
  140. // initialization is not required.
  141. //
  142. hr = S_OK;
  143. } // if: we did not get a pointer to the IClusCfgInitialize interface
  144. }
  145. while( false );
  146. return hr;
  147. }
  148. HRESULT HrFormCluster(
  149. int argc
  150. , WCHAR *argv[]
  151. , CSmartIfacePtr< IClusCfgBaseCluster > & rspClusCfgBaseClusterIn
  152. )
  153. {
  154. HRESULT hr = S_OK;
  155. bool fSyntaxError = false;
  156. do
  157. {
  158. if ( argc != 16 )
  159. {
  160. wprintf( L"FORM: Incorrect number of parameters.\n" );
  161. fSyntaxError = true;
  162. hr = E_INVALIDARG;
  163. break;
  164. }
  165. wprintf( L"Trying to form a cluster...\n");
  166. // Cluster name.
  167. if ( ClRtlStrICmp( argv[2], L"NAME=" ) != 0 )
  168. {
  169. wprintf( L"Expected 'NAME='. Got '%s'.\n", argv[2] );
  170. fSyntaxError = true;
  171. hr = E_INVALIDARG;
  172. break;
  173. }
  174. WCHAR * pszClusterName = argv[3];
  175. wprintf( L" Cluster Name = '%s'\n", pszClusterName );
  176. // Cluster account domain
  177. if ( ClRtlStrICmp( argv[4], L"DOMAIN=" ) != 0 )
  178. {
  179. wprintf( L"Expected 'DOMAIN='. Got '%s'.\n", argv[4] );
  180. fSyntaxError = true;
  181. hr = E_INVALIDARG;
  182. break;
  183. }
  184. WCHAR * pszClusterAccountDomain = argv[5];
  185. wprintf( L" Cluster Account Domain = '%s'\n", pszClusterAccountDomain );
  186. // Cluster account name.
  187. if ( ClRtlStrICmp( argv[6], L"ACCOUNT=" ) != 0 )
  188. {
  189. wprintf( L"Expected 'ACCOUNT='. Got '%s'.\n", argv[6] );
  190. fSyntaxError = true;
  191. hr = E_INVALIDARG;
  192. break;
  193. }
  194. WCHAR * pszClusterAccountName = argv[7];
  195. wprintf( L" Cluster Account Name = '%s'\n", pszClusterAccountName );
  196. // Cluster account password.
  197. if ( ClRtlStrICmp( argv[8], L"PASSWORD=" ) != 0 )
  198. {
  199. wprintf( L"Expected 'PASSWORD='. Got '%s'.\n", argv[8] );
  200. fSyntaxError = true;
  201. hr = E_INVALIDARG;
  202. break;
  203. }
  204. WCHAR * pszClusterAccountPwd = argv[9];
  205. wprintf( L" Cluster Account Password = '%s'\n", pszClusterAccountPwd );
  206. // Cluster IP address.
  207. if ( ClRtlStrICmp( argv[10], L"IPADDR=" ) != 0 )
  208. {
  209. wprintf( L"Expected 'IPADDR='. Got '%s'.\n", argv[10] );
  210. fSyntaxError = true;
  211. hr = E_INVALIDARG;
  212. break;
  213. }
  214. WCHAR * pTemp;
  215. ULONG ulClusterIPAddress = wcstoul( argv[11], &pTemp, 16 );
  216. if ( ( ( argv[11] + wcslen( argv[11] ) ) != pTemp )
  217. || ( ulClusterIPAddress == ULONG_MAX ) )
  218. {
  219. wprintf( L"Could not convert '%s' to an IP address.\n", argv[11] );
  220. fSyntaxError = true;
  221. hr = E_INVALIDARG;
  222. break;
  223. }
  224. wprintf(
  225. L" Cluster IP Address = %d.%d.%d.%d\n"
  226. , ( ulClusterIPAddress & 0xFF000000 ) >> 24
  227. , ( ulClusterIPAddress & 0x00FF0000 ) >> 16
  228. , ( ulClusterIPAddress & 0x0000FF00 ) >> 8
  229. , ( ulClusterIPAddress & 0x000000FF )
  230. );
  231. // Cluster IP subnet mask.
  232. if ( ClRtlStrICmp( argv[12], L"SUBNET=" ) != 0 )
  233. {
  234. wprintf( L"Expected 'SUBNET='. Got '%s'.\n", argv[12] );
  235. fSyntaxError = true;
  236. hr = E_INVALIDARG;
  237. break;
  238. }
  239. ULONG ulClusterIPSubnetMask = wcstoul( argv[13], &pTemp, 16 );
  240. if ( ( ( argv[13] + wcslen( argv[13] ) ) != pTemp )
  241. || ( ulClusterIPAddress == ULONG_MAX ) )
  242. {
  243. wprintf( L"Could not convert '%s' to a subnet mask.\n", argv[13] );
  244. fSyntaxError = true;
  245. hr = E_INVALIDARG;
  246. break;
  247. }
  248. wprintf(
  249. L" Cluster IP subnet mask = %d.%d.%d.%d\n"
  250. , ( ulClusterIPSubnetMask & 0xFF000000 ) >> 24
  251. , ( ulClusterIPSubnetMask & 0x00FF0000 ) >> 16
  252. , ( ulClusterIPSubnetMask & 0x0000FF00 ) >> 8
  253. , ( ulClusterIPSubnetMask & 0x000000FF )
  254. );
  255. // Cluster IP NIC name.
  256. if ( ClRtlStrICmp( argv[14], L"NICNAME=" ) != 0 )
  257. {
  258. wprintf( L"Expected 'NICNAME='. Got '%s'.\n", argv[14] );
  259. fSyntaxError = true;
  260. hr = E_INVALIDARG;
  261. break;
  262. }
  263. WCHAR * pszClusterIPNetwork = argv[15];
  264. wprintf( L" Name of the NIC for the cluster IP address = '%s'\n", pszClusterIPNetwork );
  265. // Indicate that a cluster should be formed when Commit() is called.
  266. hr = rspClusCfgBaseClusterIn->SetCreate(
  267. pszClusterName
  268. , pszClusterAccountName
  269. , pszClusterAccountPwd
  270. , pszClusterAccountDomain
  271. , ulClusterIPAddress
  272. , ulClusterIPSubnetMask
  273. , pszClusterIPNetwork
  274. );
  275. if ( FAILED( hr ) )
  276. {
  277. wprintf( L"Error %#08x occurred trying to set cluster form parameters.\n", hr );
  278. break;
  279. } // if: SetCreate() failed.
  280. // Initiate a cluster create operation.
  281. hr = rspClusCfgBaseClusterIn->Commit();
  282. if ( hr != S_OK )
  283. {
  284. wprintf( L"Error %#08x occurred trying to create the cluster.\n", hr );
  285. break;
  286. } // if: Commit() failed.
  287. wprintf( L"Cluster successfully created.\n" );
  288. }
  289. while( false );
  290. if ( fSyntaxError )
  291. {
  292. ShowUsage();
  293. }
  294. return hr;
  295. }
  296. HRESULT HrJoinCluster(
  297. int argc
  298. , WCHAR *argv[]
  299. , CSmartIfacePtr< IClusCfgBaseCluster > & rspClusCfgBaseClusterIn
  300. )
  301. {
  302. HRESULT hr = S_OK;
  303. bool fSyntaxError = false;
  304. do
  305. {
  306. if ( argc != 10 )
  307. {
  308. wprintf( L"JOIN: Incorrect number of parameters.\n" );
  309. fSyntaxError = true;
  310. hr = E_INVALIDARG;
  311. break;
  312. }
  313. wprintf( L"Trying to join a cluster...\n");
  314. // Cluster name.
  315. if ( ClRtlStrICmp( argv[2], L"NAME=" ) != 0 )
  316. {
  317. wprintf( L"Expected 'NAME='. Got '%s'.\n", argv[2] );
  318. fSyntaxError = true;
  319. hr = E_INVALIDARG;
  320. break;
  321. }
  322. WCHAR * pszClusterName = argv[3];
  323. wprintf( L" Cluster Name = '%s'\n", pszClusterName );
  324. // Cluster account domain
  325. if ( ClRtlStrICmp( argv[4], L"DOMAIN=" ) != 0 )
  326. {
  327. wprintf( L"Expected 'DOMAIN='. Got '%s'.\n", argv[4] );
  328. fSyntaxError = true;
  329. hr = E_INVALIDARG;
  330. break;
  331. }
  332. WCHAR * pszClusterAccountDomain = argv[5];
  333. wprintf( L" Cluster Account Domain = '%s'\n", pszClusterAccountDomain );
  334. // Cluster account name.
  335. if ( ClRtlStrICmp( argv[6], L"ACCOUNT=" ) != 0 )
  336. {
  337. wprintf( L"Expected 'ACCOUNT='. Got '%s'.\n", argv[6] );
  338. fSyntaxError = true;
  339. hr = E_INVALIDARG;
  340. break;
  341. }
  342. WCHAR * pszClusterAccountName = argv[7];
  343. wprintf( L" Cluster Account Name = '%s'\n", pszClusterAccountName );
  344. // Cluster account password.
  345. if ( ClRtlStrICmp( argv[8], L"PASSWORD=" ) != 0 )
  346. {
  347. wprintf( L"Expected 'PASSWORD='. Got '%s'.\n", argv[8] );
  348. fSyntaxError = true;
  349. hr = E_INVALIDARG;
  350. break;
  351. }
  352. WCHAR * pszClusterAccountPwd = argv[9];
  353. wprintf( L" Cluster Account Password = '%s'\n", pszClusterAccountPwd );
  354. // Indicate that a cluster should be joined when Commit() is called.
  355. hr = rspClusCfgBaseClusterIn->SetAdd(
  356. pszClusterName
  357. , pszClusterAccountName
  358. , pszClusterAccountPwd
  359. , pszClusterAccountDomain
  360. );
  361. if ( FAILED( hr ) )
  362. {
  363. wprintf( L"Error %#08x occurred trying to set cluster join parameters.\n", hr );
  364. break;
  365. } // if: SetAdd() failed.
  366. // Initiate cluster join.
  367. hr = rspClusCfgBaseClusterIn->Commit();
  368. if ( hr != S_OK )
  369. {
  370. wprintf( L"Error %#08x occurred trying to join the cluster.\n", hr );
  371. break;
  372. } // if: Commit() failed.
  373. wprintf( L"Cluster join successful.\n" );
  374. }
  375. while( false );
  376. if ( fSyntaxError )
  377. {
  378. ShowUsage();
  379. }
  380. return hr;
  381. }
  382. HRESULT HrCleanupNode(
  383. int argc
  384. , WCHAR *argv[]
  385. , CSmartIfacePtr< IClusCfgBaseCluster > & rspClusCfgBaseClusterIn
  386. )
  387. {
  388. HRESULT hr = S_OK;
  389. bool fSyntaxError = false;
  390. do
  391. {
  392. if ( argc != 2 )
  393. {
  394. wprintf( L"CLEANUP: Incorrect number of parameters.\n" );
  395. fSyntaxError = true;
  396. hr = E_INVALIDARG;
  397. break;
  398. }
  399. wprintf( L"Trying to cleanup node...\n");
  400. // Indicate that the node should be cleaned up when Commit() is called.
  401. hr = rspClusCfgBaseClusterIn->SetCleanup();
  402. if ( FAILED( hr ) )
  403. {
  404. wprintf( L"Error %#08x occurred trying to set node cleanup parameters.\n", hr );
  405. break;
  406. } // if: SetCleanup() failed.
  407. // Initiate node cleanup.
  408. hr = rspClusCfgBaseClusterIn->Commit();
  409. if ( hr != S_OK )
  410. {
  411. wprintf( L"Error %#08x occurred trying to clean up the node.\n", hr );
  412. break;
  413. } // if: Commit() failed.
  414. wprintf( L"Node successfully cleaned up.\n" );
  415. }
  416. while( false );
  417. if ( fSyntaxError )
  418. {
  419. ShowUsage();
  420. }
  421. return hr;
  422. }
  423. // The main function for this program.
  424. int __cdecl wmain( int argc, WCHAR *argv[] )
  425. {
  426. HRESULT hr = S_OK;
  427. // Initialize COM
  428. CoInitializeEx( 0, COINIT_MULTITHREADED );
  429. wprintf( L"\n" );
  430. do
  431. {
  432. COSERVERINFO coServerInfo;
  433. COAUTHINFO coAuthInfo;
  434. COSERVERINFO * pcoServerInfoPtr = NULL;
  435. WCHAR ** pArgList = argv;
  436. int nArgc = argc;
  437. CSmartIfacePtr< IClusCfgBaseCluster > spClusCfgBaseCluster;
  438. if ( nArgc <= 1 )
  439. {
  440. ShowUsage();
  441. break;
  442. }
  443. // Check if a computer name is specified.
  444. if ( *pArgList[1] != '/' )
  445. {
  446. coAuthInfo.dwAuthnSvc = RPC_C_AUTHN_WINNT;
  447. coAuthInfo.dwAuthzSvc = RPC_C_AUTHZ_NONE;
  448. coAuthInfo.pwszServerPrincName = NULL;
  449. coAuthInfo.dwAuthnLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY;
  450. coAuthInfo.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
  451. coAuthInfo.pAuthIdentityData = NULL;
  452. coAuthInfo.dwCapabilities = EOAC_NONE;
  453. coServerInfo.dwReserved1 = 0;
  454. coServerInfo.pwszName = pArgList[1];
  455. coServerInfo.pAuthInfo = &coAuthInfo;
  456. coServerInfo.dwReserved2 = 0;
  457. pcoServerInfoPtr = &coServerInfo;
  458. wprintf( L"Attempting cluster configuration on computer '%s'.\n", pArgList[1] );
  459. // Consume the arguments
  460. ++pArgList;
  461. --nArgc;
  462. }
  463. else
  464. {
  465. wprintf( L"Attempting cluster configuration on this computer.\n" );
  466. }
  467. // Initialize the BaseCluster component.
  468. hr = HrInitComponent( pcoServerInfoPtr, spClusCfgBaseCluster );
  469. if ( FAILED( hr ) )
  470. {
  471. wprintf( L"HrInitComponent() failed. Cannot configure cluster. Error %#08x.\n", hr );
  472. break;
  473. }
  474. // Parse the command line for options
  475. if ( ClRtlStrICmp( pArgList[1], L"/FORM" ) == 0 )
  476. {
  477. hr = HrFormCluster( nArgc, pArgList, spClusCfgBaseCluster );
  478. if ( FAILED( hr ) )
  479. {
  480. wprintf( L"HrFormCluster() failed. Cannot form cluster. Error %#08x.\n", hr );
  481. break;
  482. }
  483. } // if: form
  484. else if ( ClRtlStrICmp( pArgList[1], L"/JOIN" ) == 0 )
  485. {
  486. hr = HrJoinCluster( nArgc, pArgList, spClusCfgBaseCluster );
  487. if ( FAILED( hr ) )
  488. {
  489. wprintf( L"HrJoinCluster() failed. Cannot join cluster. Error %#08x.\n", hr );
  490. break;
  491. }
  492. } // else if: join
  493. else if ( ClRtlStrICmp( pArgList[1], L"/CLEANUP" ) == 0 )
  494. {
  495. hr = HrCleanupNode( nArgc, pArgList, spClusCfgBaseCluster );
  496. if ( FAILED( hr ) )
  497. {
  498. wprintf( L"HrFormCluster() failed. Cannot clean up node. Error %#08x.\n", hr );
  499. break;
  500. }
  501. } // else if: cleanup
  502. else
  503. {
  504. wprintf( L"Invalid option '%s'.\n", pArgList[1] );
  505. ShowUsage();
  506. } // else: invalid option
  507. }
  508. while( false ); // dummy do-while loop to avoid gotos.
  509. CoUninitialize();
  510. return hr;
  511. }