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.
617 lines
19 KiB
617 lines
19 KiB
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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;
|
|
}
|