|
|
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1999-2000 Microsoft Corporation
//
// Module Name:
// BaseClusterTest.cpp
//
// Description:
// Main file for the test harness executable.
// Initializes tracing, parses command line and actually call the
// BaseClusCfg functions.
//
// Documentation:
// No documention for the test harness.
//
// Maintained By:
// Vij Vasu (Vvasu) 08-MAR-2000
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Include Files
//////////////////////////////////////////////////////////////////////////////
#include "pch.h"
#include <stdio.h>
#include <objbase.h>
#include <limits.h>
#include <initguid.h>
#include "guids.h"
#include "CClusCfgCallback.h"
// Show help for this executable.
void ShowUsage() { wprintf( L"\nThe syntax of this command is:\n" ); wprintf( L"\nBaseClusterTest.exe [computer-name] {<options>}\n" ); wprintf( L"\n<options> =\n" ); wprintf( L" /FORM NAME= cluster-name DOMAIN= account-domain ACCOUNT= clussvc-account\n" ); wprintf( L" PASSWORD= account-password IPADDR= ip-address(hex)\n" ); wprintf( L" SUBNET= ip-subnet-mask(hex) NICNAME= ip-nic-name\n\n" ); wprintf( L" /JOIN NAME= cluster-name DOMAIN= account-domain ACCOUNT= clussvc-account\n" ); wprintf( L" PASSWORD= account-password\n\n" ); wprintf( L" /CLEANUP\n" ); wprintf( L"\nNotes:\n" ); wprintf( L"- A space is required after an '=' sign.\n" ); wprintf( L"- The order for the parameters has to be the same as shown above.\n" ); }
// Create the BaseCluster component.
HRESULT HrInitComponent( COSERVERINFO * pcoServerInfoPtrIn , CSmartIfacePtr< IClusCfgBaseCluster > & rspClusCfgBaseClusterIn ) { HRESULT hr = S_OK;
do { MULTI_QI mqiInterfaces[] = { { &IID_IClusCfgBaseCluster, NULL, S_OK }, { &IID_IClusCfgInitialize, NULL, S_OK } };
//
// Create and initialize the BaseClusterAction component
//
hr = CoCreateInstanceEx( CLSID_ClusCfgBaseCluster , NULL , CLSCTX_LOCAL_SERVER , pcoServerInfoPtrIn , sizeof( mqiInterfaces ) / sizeof( mqiInterfaces[0] ) , mqiInterfaces );
// Store the retrieved pointers in smart pointers for safe release.
rspClusCfgBaseClusterIn.Attach( reinterpret_cast< IClusCfgBaseCluster * >( mqiInterfaces[0].pItf ) );
CSmartIfacePtr< IClusCfgInitialize > spClusCfgInitialize; spClusCfgInitialize.Attach( reinterpret_cast< IClusCfgInitialize * >( mqiInterfaces[1].pItf ) );
// Check if CoCreateInstanceEx() worked.
if ( FAILED( hr ) && ( hr != CO_S_NOTALLINTERFACES ) ) { wprintf( L"Could not create the BaseCluster component. Error %#08x.\n", hr ); break; } // if: CoCreateInstanceEx() failed
// Check if we got the pointer to the IClusCfgBaseCluster interface.
hr = mqiInterfaces[0].hr; if ( FAILED( hr ) ) { // We cannot do anything without this pointer - bail.
wprintf( L"Could not get the IClusCfgBaseCluster pointer. Error %#08x.\n", hr ); break; } // if: we could not get a pointer to the IClusCfgBaseCluster interface
//
// Check if we got a pointer to the IClusCfgInitialize interface
hr = mqiInterfaces[1].hr; if ( hr == S_OK ) { // We got the pointer - initialize the component.
IUnknown * punk = NULL; IClusCfgCallback * pccb = NULL;
hr = CClusCfgCallback::S_HrCreateInstance( &punk ); if ( FAILED( hr ) ) { wprintf( L"Could not initalize callback component. Error %#08x.\n", hr ); break; }
hr = punk->QueryInterface< IClusCfgCallback >( &pccb ); punk->Release( ); if ( FAILED( hr ) ) { wprintf( L"Could not find IClusCfgCallback on CClusCfgCallback object. Error %#08x.\n", hr ); break; }
hr = spClusCfgInitialize->Initialize( pccb, LOCALE_SYSTEM_DEFAULT );
if ( pccb != NULL ) { pccb->Release(); } // if: we created a callback, release it.
if ( FAILED( hr ) ) { if ( hr == HRESULT_FROM_WIN32( ERROR_ACCESS_DENIED ) ) { 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" ); hr = ERROR_SUCCESS; } // if: the error was ERROR_ACCESS_DENIED
else { wprintf( L"Could not initialize the BaseCluster component. Error %#08x occurred. Configuration will be aborted.\n", hr ); break; } // else: some other error occurred.
} // if: something went wrong during initialization
} // if: we got a pointer to the IClusCfgInitialize interface
else { wprintf( L"The BaseCluster component does not provide notifications.\n" ); if ( hr != E_NOINTERFACE ) { break; } // if: the interface is supported, but something else went wrong.
//
// If the interface is not support, that is ok. It just means that
// initialization is not required.
//
hr = S_OK; } // if: we did not get a pointer to the IClusCfgInitialize interface
} while( false );
return hr; }
HRESULT HrFormCluster( int argc , WCHAR *argv[] , CSmartIfacePtr< IClusCfgBaseCluster > & rspClusCfgBaseClusterIn ) { HRESULT hr = S_OK; bool fSyntaxError = false;
do { if ( argc != 16 ) { wprintf( L"FORM: Incorrect number of parameters.\n" ); fSyntaxError = true; hr = E_INVALIDARG; break; }
wprintf( L"Trying to form a cluster...\n");
// Cluster name.
if ( ClRtlStrICmp( argv[2], L"NAME=" ) != 0 ) { wprintf( L"Expected 'NAME='. Got '%s'.\n", argv[2] ); fSyntaxError = true; hr = E_INVALIDARG; break; }
WCHAR * pszClusterName = argv[3]; wprintf( L" Cluster Name = '%s'\n", pszClusterName );
// Cluster account domain
if ( ClRtlStrICmp( argv[4], L"DOMAIN=" ) != 0 ) { wprintf( L"Expected 'DOMAIN='. Got '%s'.\n", argv[4] ); fSyntaxError = true; hr = E_INVALIDARG; break; } WCHAR * pszClusterAccountDomain = argv[5]; wprintf( L" Cluster Account Domain = '%s'\n", pszClusterAccountDomain );
// Cluster account name.
if ( ClRtlStrICmp( argv[6], L"ACCOUNT=" ) != 0 ) { wprintf( L"Expected 'ACCOUNT='. Got '%s'.\n", argv[6] ); fSyntaxError = true; hr = E_INVALIDARG; break; }
WCHAR * pszClusterAccountName = argv[7]; wprintf( L" Cluster Account Name = '%s'\n", pszClusterAccountName );
// Cluster account password.
if ( ClRtlStrICmp( argv[8], L"PASSWORD=" ) != 0 ) { wprintf( L"Expected 'PASSWORD='. Got '%s'.\n", argv[8] ); fSyntaxError = true; hr = E_INVALIDARG; break; }
WCHAR * pszClusterAccountPwd = argv[9]; wprintf( L" Cluster Account Password = '%s'\n", pszClusterAccountPwd );
// Cluster IP address.
if ( ClRtlStrICmp( argv[10], L"IPADDR=" ) != 0 ) { wprintf( L"Expected 'IPADDR='. Got '%s'.\n", argv[10] ); fSyntaxError = true; hr = E_INVALIDARG; break; }
WCHAR * pTemp;
ULONG ulClusterIPAddress = wcstoul( argv[11], &pTemp, 16 ); if ( ( ( argv[11] + wcslen( argv[11] ) ) != pTemp ) || ( ulClusterIPAddress == ULONG_MAX ) ) { wprintf( L"Could not convert '%s' to an IP address.\n", argv[11] ); fSyntaxError = true; hr = E_INVALIDARG; break; } wprintf( L" Cluster IP Address = %d.%d.%d.%d\n" , ( ulClusterIPAddress & 0xFF000000 ) >> 24 , ( ulClusterIPAddress & 0x00FF0000 ) >> 16 , ( ulClusterIPAddress & 0x0000FF00 ) >> 8 , ( ulClusterIPAddress & 0x000000FF ) );
// Cluster IP subnet mask.
if ( ClRtlStrICmp( argv[12], L"SUBNET=" ) != 0 ) { wprintf( L"Expected 'SUBNET='. Got '%s'.\n", argv[12] ); fSyntaxError = true; hr = E_INVALIDARG; break; }
ULONG ulClusterIPSubnetMask = wcstoul( argv[13], &pTemp, 16 ); if ( ( ( argv[13] + wcslen( argv[13] ) ) != pTemp ) || ( ulClusterIPAddress == ULONG_MAX ) ) { wprintf( L"Could not convert '%s' to a subnet mask.\n", argv[13] ); fSyntaxError = true; hr = E_INVALIDARG; break; } wprintf( L" Cluster IP subnet mask = %d.%d.%d.%d\n" , ( ulClusterIPSubnetMask & 0xFF000000 ) >> 24 , ( ulClusterIPSubnetMask & 0x00FF0000 ) >> 16 , ( ulClusterIPSubnetMask & 0x0000FF00 ) >> 8 , ( ulClusterIPSubnetMask & 0x000000FF ) );
// Cluster IP NIC name.
if ( ClRtlStrICmp( argv[14], L"NICNAME=" ) != 0 ) { wprintf( L"Expected 'NICNAME='. Got '%s'.\n", argv[14] ); fSyntaxError = true; hr = E_INVALIDARG; break; }
WCHAR * pszClusterIPNetwork = argv[15]; wprintf( L" Name of the NIC for the cluster IP address = '%s'\n", pszClusterIPNetwork );
// Indicate that a cluster should be formed when Commit() is called.
hr = rspClusCfgBaseClusterIn->SetCreate( pszClusterName , pszClusterAccountName , pszClusterAccountPwd , pszClusterAccountDomain , ulClusterIPAddress , ulClusterIPSubnetMask , pszClusterIPNetwork );
if ( FAILED( hr ) ) { wprintf( L"Error %#08x occurred trying to set cluster form parameters.\n", hr ); break; } // if: SetCreate() failed.
// Initiate a cluster create operation.
hr = rspClusCfgBaseClusterIn->Commit(); if ( hr != S_OK ) { wprintf( L"Error %#08x occurred trying to create the cluster.\n", hr ); break; } // if: Commit() failed.
wprintf( L"Cluster successfully created.\n" ); } while( false );
if ( fSyntaxError ) { ShowUsage(); }
return hr; }
HRESULT HrJoinCluster( int argc , WCHAR *argv[] , CSmartIfacePtr< IClusCfgBaseCluster > & rspClusCfgBaseClusterIn ) { HRESULT hr = S_OK; bool fSyntaxError = false;
do { if ( argc != 10 ) { wprintf( L"JOIN: Incorrect number of parameters.\n" ); fSyntaxError = true; hr = E_INVALIDARG; break; }
wprintf( L"Trying to join a cluster...\n");
// Cluster name.
if ( ClRtlStrICmp( argv[2], L"NAME=" ) != 0 ) { wprintf( L"Expected 'NAME='. Got '%s'.\n", argv[2] ); fSyntaxError = true; hr = E_INVALIDARG; break; }
WCHAR * pszClusterName = argv[3]; wprintf( L" Cluster Name = '%s'\n", pszClusterName );
// Cluster account domain
if ( ClRtlStrICmp( argv[4], L"DOMAIN=" ) != 0 ) { wprintf( L"Expected 'DOMAIN='. Got '%s'.\n", argv[4] ); fSyntaxError = true; hr = E_INVALIDARG; break; } WCHAR * pszClusterAccountDomain = argv[5]; wprintf( L" Cluster Account Domain = '%s'\n", pszClusterAccountDomain );
// Cluster account name.
if ( ClRtlStrICmp( argv[6], L"ACCOUNT=" ) != 0 ) { wprintf( L"Expected 'ACCOUNT='. Got '%s'.\n", argv[6] ); fSyntaxError = true; hr = E_INVALIDARG; break; }
WCHAR * pszClusterAccountName = argv[7]; wprintf( L" Cluster Account Name = '%s'\n", pszClusterAccountName );
// Cluster account password.
if ( ClRtlStrICmp( argv[8], L"PASSWORD=" ) != 0 ) { wprintf( L"Expected 'PASSWORD='. Got '%s'.\n", argv[8] ); fSyntaxError = true; hr = E_INVALIDARG; break; }
WCHAR * pszClusterAccountPwd = argv[9]; wprintf( L" Cluster Account Password = '%s'\n", pszClusterAccountPwd );
// Indicate that a cluster should be joined when Commit() is called.
hr = rspClusCfgBaseClusterIn->SetAdd( pszClusterName , pszClusterAccountName , pszClusterAccountPwd , pszClusterAccountDomain );
if ( FAILED( hr ) ) { wprintf( L"Error %#08x occurred trying to set cluster join parameters.\n", hr ); break; } // if: SetAdd() failed.
// Initiate cluster join.
hr = rspClusCfgBaseClusterIn->Commit(); if ( hr != S_OK ) { wprintf( L"Error %#08x occurred trying to join the cluster.\n", hr ); break; } // if: Commit() failed.
wprintf( L"Cluster join successful.\n" ); } while( false );
if ( fSyntaxError ) { ShowUsage(); }
return hr; }
HRESULT HrCleanupNode( int argc , WCHAR *argv[] , CSmartIfacePtr< IClusCfgBaseCluster > & rspClusCfgBaseClusterIn ) { HRESULT hr = S_OK; bool fSyntaxError = false;
do { if ( argc != 2 ) { wprintf( L"CLEANUP: Incorrect number of parameters.\n" ); fSyntaxError = true; hr = E_INVALIDARG; break; }
wprintf( L"Trying to cleanup node...\n");
// Indicate that the node should be cleaned up when Commit() is called.
hr = rspClusCfgBaseClusterIn->SetCleanup();
if ( FAILED( hr ) ) { wprintf( L"Error %#08x occurred trying to set node cleanup parameters.\n", hr ); break; } // if: SetCleanup() failed.
// Initiate node cleanup.
hr = rspClusCfgBaseClusterIn->Commit(); if ( hr != S_OK ) { wprintf( L"Error %#08x occurred trying to clean up the node.\n", hr ); break; } // if: Commit() failed.
wprintf( L"Node successfully cleaned up.\n" ); } while( false );
if ( fSyntaxError ) { ShowUsage(); }
return hr; }
// The main function for this program.
int __cdecl wmain( int argc, WCHAR *argv[] ) { HRESULT hr = S_OK;
// Initialize COM
CoInitializeEx( 0, COINIT_MULTITHREADED );
wprintf( L"\n" );
do { COSERVERINFO coServerInfo; COAUTHINFO coAuthInfo; COSERVERINFO * pcoServerInfoPtr = NULL; WCHAR ** pArgList = argv; int nArgc = argc;
CSmartIfacePtr< IClusCfgBaseCluster > spClusCfgBaseCluster;
if ( nArgc <= 1 ) { ShowUsage(); break; }
// Check if a computer name is specified.
if ( *pArgList[1] != '/' ) { coAuthInfo.dwAuthnSvc = RPC_C_AUTHN_WINNT; coAuthInfo.dwAuthzSvc = RPC_C_AUTHZ_NONE; coAuthInfo.pwszServerPrincName = NULL; coAuthInfo.dwAuthnLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY; coAuthInfo.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE; coAuthInfo.pAuthIdentityData = NULL; coAuthInfo.dwCapabilities = EOAC_NONE; coServerInfo.dwReserved1 = 0; coServerInfo.pwszName = pArgList[1]; coServerInfo.pAuthInfo = &coAuthInfo; coServerInfo.dwReserved2 = 0;
pcoServerInfoPtr = &coServerInfo;
wprintf( L"Attempting cluster configuration on computer '%s'.\n", pArgList[1] );
// Consume the arguments
++pArgList; --nArgc; } else { wprintf( L"Attempting cluster configuration on this computer.\n" ); }
// Initialize the BaseCluster component.
hr = HrInitComponent( pcoServerInfoPtr, spClusCfgBaseCluster ); if ( FAILED( hr ) ) { wprintf( L"HrInitComponent() failed. Cannot configure cluster. Error %#08x.\n", hr ); break; }
// Parse the command line for options
if ( ClRtlStrICmp( pArgList[1], L"/FORM" ) == 0 ) { hr = HrFormCluster( nArgc, pArgList, spClusCfgBaseCluster ); if ( FAILED( hr ) ) { wprintf( L"HrFormCluster() failed. Cannot form cluster. Error %#08x.\n", hr ); break; } } // if: form
else if ( ClRtlStrICmp( pArgList[1], L"/JOIN" ) == 0 ) { hr = HrJoinCluster( nArgc, pArgList, spClusCfgBaseCluster ); if ( FAILED( hr ) ) { wprintf( L"HrJoinCluster() failed. Cannot join cluster. Error %#08x.\n", hr ); break; } } // else if: join
else if ( ClRtlStrICmp( pArgList[1], L"/CLEANUP" ) == 0 ) { hr = HrCleanupNode( nArgc, pArgList, spClusCfgBaseCluster ); if ( FAILED( hr ) ) { wprintf( L"HrFormCluster() failed. Cannot clean up node. Error %#08x.\n", hr ); break; } } // else if: cleanup
else { wprintf( L"Invalid option '%s'.\n", pArgList[1] ); ShowUsage(); } // else: invalid option
} while( false ); // dummy do-while loop to avoid gotos.
CoUninitialize();
return hr; }
|