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.
2232 lines
63 KiB
2232 lines
63 KiB
/*++
|
|
|
|
Copyright(c) 2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
NLB Manager
|
|
|
|
File Name:
|
|
|
|
NlbClient.cpp
|
|
|
|
Abstract:
|
|
|
|
Implementation of class NLBHost
|
|
|
|
NLBHost is responsible for connecting to an NLB host and getting/setting
|
|
its NLB-related configuration.
|
|
|
|
History:
|
|
|
|
03/31/01 JosephJ Created
|
|
07/27/01 JosephJ Moved to current location (used to be called
|
|
nlbhost.cpp under provider\tests).
|
|
|
|
NLB client-side WMI utility functions to configure
|
|
an NLB host.
|
|
|
|
--*/
|
|
|
|
#include "private.h"
|
|
#include "nlbclient.tmh"
|
|
|
|
extern BOOL g_Silent;
|
|
|
|
BOOL g_Fake; // If true, operate in "fake mode" -- see NlbHostFake()
|
|
|
|
|
|
WBEMSTATUS
|
|
extract_GetClusterConfiguration_output_params(
|
|
IN IWbemClassObjectPtr spWbemOutput,
|
|
OUT PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg
|
|
);
|
|
|
|
WBEMSTATUS
|
|
setup_GetClusterConfiguration_input_params(
|
|
IN LPCWSTR szNic,
|
|
IN IWbemClassObjectPtr spWbemInput
|
|
);
|
|
|
|
WBEMSTATUS
|
|
setup_UpdateClusterConfiguration_input_params(
|
|
IN LPCWSTR szClientDescription,
|
|
IN LPCWSTR szNic,
|
|
IN PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg,
|
|
IN IWbemClassObjectPtr spWbemInput
|
|
);
|
|
|
|
WBEMSTATUS
|
|
connect_to_server(
|
|
IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
|
|
OUT IWbemServicesPtr &spWbemService // Smart pointer
|
|
);
|
|
|
|
VOID
|
|
NlbHostFake(
|
|
VOID)
|
|
|
|
/*
|
|
Makes the NlbHostXXX apis operate in "fake mode", where they don't
|
|
actually connect to any real machines.
|
|
*/
|
|
{
|
|
g_Fake = TRUE;
|
|
FakeInitialize();
|
|
}
|
|
|
|
WBEMSTATUS
|
|
NlbHostGetConfiguration(
|
|
IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
|
|
IN LPCWSTR szNicGuid,
|
|
OUT PNLB_EXTENDED_CLUSTER_CONFIGURATION pCurrentCfg
|
|
)
|
|
{
|
|
WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
|
|
IWbemServicesPtr spWbemService = NULL; // Smart pointer
|
|
IWbemClassObjectPtr spWbemInput = NULL; // smart pointer
|
|
IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
|
|
LPWSTR pRelPath = NULL;
|
|
|
|
TRACE_INFO("->%!FUNC!(GUID=%ws)", szNicGuid);
|
|
|
|
if (g_Fake)
|
|
{
|
|
Status = FakeNlbHostGetConfiguration(pConnInfo, szNicGuid, pCurrentCfg);
|
|
goto end;
|
|
}
|
|
|
|
//
|
|
// Get interface to the NLB namespace on the specified machine
|
|
//
|
|
Status = connect_to_server(pConnInfo, REF spWbemService);
|
|
if (FAILED(Status))
|
|
{
|
|
goto end;
|
|
}
|
|
|
|
//
|
|
// Get wmi input instance to "GetClusterConfiguration" method
|
|
//
|
|
{
|
|
Status = CfgUtilGetWmiInputInstanceAndRelPath(
|
|
spWbemService,
|
|
L"NlbsNic", // szClassName
|
|
NULL, // szParameterName
|
|
NULL, // szPropertyValue
|
|
L"GetClusterConfiguration", // szMethodName,
|
|
spWbemInput, // smart pointer
|
|
&pRelPath // free using delete
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(
|
|
L"ERROR 0x%08lx trying to get instance of GetClusterConfiguration\n",
|
|
(UINT) Status
|
|
);
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Setup params for the "GetClusterConfiguration" method
|
|
// NOTE: spWbemInput could be NULL.
|
|
//
|
|
Status = setup_GetClusterConfiguration_input_params(
|
|
szNicGuid,
|
|
spWbemInput
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
goto end;
|
|
}
|
|
|
|
//
|
|
// Call the "GetClusterConfiguration" method
|
|
//
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (!g_Silent)
|
|
{
|
|
wprintf(L"Going to get GetClusterConfiguration...\n");
|
|
}
|
|
|
|
hr = spWbemService->ExecMethod(
|
|
_bstr_t(pRelPath),
|
|
L"GetClusterConfiguration",
|
|
0,
|
|
NULL,
|
|
spWbemInput,
|
|
&spWbemOutput,
|
|
NULL
|
|
);
|
|
|
|
if( FAILED( hr) )
|
|
{
|
|
wprintf(L"GetClusterConfiguration returns with failure 0x%8lx\n",
|
|
(UINT) hr);
|
|
Status = WBEM_E_CRITICAL_ERROR;
|
|
goto end;
|
|
}
|
|
else
|
|
{
|
|
if (!g_Silent)
|
|
{
|
|
wprintf(L"GetClusterConfiguration returns successfully\n");
|
|
}
|
|
}
|
|
|
|
if (spWbemOutput == NULL)
|
|
{
|
|
//
|
|
// Hmm --- no output ?!
|
|
//
|
|
printf("ExecMethod GetClusterConfiguration had no output");
|
|
Status = WBEM_E_NOT_FOUND;
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Extract params from the "GetClusterConfiguration" method
|
|
//
|
|
Status = extract_GetClusterConfiguration_output_params(
|
|
spWbemOutput,
|
|
pCurrentCfg
|
|
);
|
|
|
|
end:
|
|
|
|
if (pRelPath != NULL)
|
|
{
|
|
delete pRelPath;
|
|
}
|
|
|
|
spWbemService = NULL; // Smart pointer
|
|
spWbemInput = NULL; // smart pointer
|
|
spWbemOutput = NULL; // smart pointer.
|
|
|
|
TRACE_INFO("<-%!FUNC! returns 0x%08lx", Status);
|
|
return Status;
|
|
}
|
|
|
|
|
|
|
|
WBEMSTATUS
|
|
NlbHostDoUpdate(
|
|
IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
|
|
IN LPCWSTR szNicGuid,
|
|
IN LPCWSTR szClientDescription,
|
|
IN PNLB_EXTENDED_CLUSTER_CONFIGURATION pNewState,
|
|
OUT UINT *pGeneration,
|
|
OUT WCHAR **ppLog // free using delete operator.
|
|
)
|
|
{
|
|
|
|
WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
|
|
IWbemServicesPtr spWbemService = NULL; // Smart pointer
|
|
IWbemClassObjectPtr spWbemInput = NULL; // smart pointer
|
|
IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
|
|
LPWSTR pRelPath = NULL;
|
|
TRACE_INFO("->%!FUNC!(GUID=%ws)", szNicGuid);
|
|
|
|
*pGeneration = 0;
|
|
*ppLog = NULL;
|
|
|
|
if (g_Fake)
|
|
{
|
|
Status = FakeNlbHostDoUpdate(
|
|
pConnInfo,
|
|
szNicGuid,
|
|
szClientDescription,
|
|
pNewState,
|
|
pGeneration,
|
|
ppLog
|
|
);
|
|
goto end;
|
|
}
|
|
|
|
//
|
|
// Get interface to the NLB namespace on the specified machine
|
|
//
|
|
Status = connect_to_server(pConnInfo, REF spWbemService);
|
|
if (FAILED(Status))
|
|
{
|
|
goto end;
|
|
}
|
|
|
|
//
|
|
// Get wmi input instance to "UpdateClusterConfiguration" method
|
|
//
|
|
{
|
|
Status = CfgUtilGetWmiInputInstanceAndRelPath(
|
|
spWbemService,
|
|
L"NlbsNic", // szClassName
|
|
NULL, // szParameterName
|
|
NULL, // szPropertyValue
|
|
L"UpdateClusterConfiguration", // szMethodName,
|
|
spWbemInput, // smart pointer
|
|
&pRelPath // free using delete
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(
|
|
L"ERROR 0x%08lx trying to get instance of UpdateConfiguration\n",
|
|
(UINT) Status
|
|
);
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Setup params for the "UpdateClusterConfiguration" method
|
|
// NOTE: spWbemInput could be NULL.
|
|
//
|
|
Status = setup_UpdateClusterConfiguration_input_params(
|
|
szClientDescription,
|
|
szNicGuid,
|
|
pNewState,
|
|
spWbemInput
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
goto end;
|
|
}
|
|
|
|
//
|
|
// Call the "UpdateClusterConfiguration" method
|
|
//
|
|
{
|
|
HRESULT hr;
|
|
|
|
wprintf(L"Going get UpdateClusterConfiguration...\n");
|
|
|
|
hr = spWbemService->ExecMethod(
|
|
_bstr_t(pRelPath),
|
|
L"UpdateClusterConfiguration",
|
|
0,
|
|
NULL,
|
|
spWbemInput,
|
|
&spWbemOutput,
|
|
NULL
|
|
);
|
|
|
|
if( FAILED( hr) )
|
|
{
|
|
wprintf(L"UpdateConfiguration returns with failure 0x%8lx\n",
|
|
(UINT) hr);
|
|
goto end;
|
|
}
|
|
else
|
|
{
|
|
wprintf(L"UpdateConfiguration returns successfully\n");
|
|
}
|
|
|
|
if (spWbemOutput == NULL)
|
|
{
|
|
//
|
|
// Hmm --- no output ?!
|
|
//
|
|
printf("ExecMethod UpdateConfiguration had no output");
|
|
Status = WBEM_E_NOT_FOUND;
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Extract params from the "UpdateClusterConfiguration" method
|
|
//
|
|
{
|
|
DWORD dwReturnValue = 0;
|
|
|
|
Status = CfgUtilGetWmiDWORDParam(
|
|
spWbemOutput,
|
|
L"ReturnValue", // <--------------------------------
|
|
&dwReturnValue
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read ReturnValue failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
goto end;
|
|
}
|
|
|
|
|
|
LPWSTR szLog = NULL;
|
|
|
|
Status = CfgUtilGetWmiStringParam(
|
|
spWbemOutput,
|
|
L"Log", // <-------------------------
|
|
&szLog
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
szLog = NULL;
|
|
}
|
|
*ppLog = szLog;
|
|
|
|
DWORD dwGeneration = 0;
|
|
Status = CfgUtilGetWmiDWORDParam(
|
|
spWbemOutput,
|
|
L"NewGeneration", // <--------------------------------
|
|
&dwGeneration
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
//
|
|
// Generation should always be specified for pending operations.
|
|
// TODO: for successful operations also?
|
|
//
|
|
if ((WBEMSTATUS)dwReturnValue == WBEM_S_PENDING)
|
|
{
|
|
wprintf(L"Attempt to read NewGeneration for pending update failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
Status = WBEM_E_CRITICAL_ERROR;
|
|
goto end;
|
|
}
|
|
dwGeneration = 0; // we don't care if it's not set for non-pending
|
|
}
|
|
*pGeneration = (UINT) dwGeneration;
|
|
|
|
|
|
//
|
|
// Make the return status reflect the true status of the update
|
|
// operation.
|
|
//
|
|
Status = (WBEMSTATUS) dwReturnValue;
|
|
}
|
|
|
|
end:
|
|
|
|
if (pRelPath != NULL)
|
|
{
|
|
delete pRelPath;
|
|
}
|
|
|
|
spWbemService = NULL; // Smart pointer
|
|
spWbemInput = NULL; // smart pointer
|
|
spWbemOutput = NULL; // smart pointer.
|
|
|
|
TRACE_INFO("<-%!FUNC! returns 0x%08lx", Status);
|
|
return Status;
|
|
}
|
|
|
|
WBEMSTATUS
|
|
NlbHostControlCluster(
|
|
IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
|
|
IN LPCWSTR szNicGuid,
|
|
IN LPCWSTR szVip,
|
|
IN DWORD *pdwPortNum,
|
|
IN WLBS_OPERATION_CODES Operation,
|
|
OUT DWORD *pdwOperationStatus,
|
|
OUT DWORD *pdwClusterOrPortStatus,
|
|
OUT DWORD *pdwHostMap
|
|
)
|
|
{
|
|
|
|
WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
|
|
IWbemServicesPtr spWbemService = NULL; // Smart pointer
|
|
IWbemClassObjectPtr spWbemInput = NULL; // smart pointer
|
|
IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
|
|
LPWSTR pRelPath = NULL;
|
|
|
|
if (szVip && pdwPortNum)
|
|
TRACE_INFO("->%!FUNC!(GUID=%ws), szVip : %ls, Port : 0x%x, Operation : %d", szNicGuid, szVip, *pdwPortNum, Operation);
|
|
else
|
|
TRACE_INFO("->%!FUNC!(GUID=%ws), szVip : N/A, Port : N/A, Operation : %d", szNicGuid, Operation);
|
|
|
|
|
|
if (g_Fake)
|
|
{
|
|
Status = FakeNlbHostControlCluster(
|
|
pConnInfo,
|
|
szNicGuid,
|
|
szVip,
|
|
pdwPortNum,
|
|
Operation,
|
|
pdwOperationStatus,
|
|
pdwClusterOrPortStatus,
|
|
pdwHostMap
|
|
);
|
|
goto end;
|
|
}
|
|
|
|
// Initialize return variables to failure values
|
|
if (pdwOperationStatus)
|
|
*pdwOperationStatus = WLBS_FAILURE;
|
|
if (pdwClusterOrPortStatus)
|
|
*pdwClusterOrPortStatus = WLBS_FAILURE;
|
|
if (pdwHostMap)
|
|
*pdwHostMap = 0;
|
|
|
|
//
|
|
// Get interface to the NLB namespace on the specified machine
|
|
//
|
|
Status = connect_to_server(pConnInfo, REF spWbemService);
|
|
if (FAILED(Status))
|
|
{
|
|
goto end;
|
|
}
|
|
|
|
|
|
//
|
|
// Get wmi input instance to "ControlCluster" method
|
|
//
|
|
{
|
|
Status = CfgUtilGetWmiInputInstanceAndRelPath(
|
|
spWbemService,
|
|
L"NlbsNic", // szClassName
|
|
NULL, // szParameterName
|
|
NULL, // szPropertyValue
|
|
L"ControlCluster", // szMethodName,
|
|
spWbemInput, // smart pointer
|
|
&pRelPath // free using delete
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(
|
|
L"ERROR 0x%08lx trying to get instance of UpdateConfiguration\n",
|
|
(UINT) Status
|
|
);
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
// Setup input parameters
|
|
|
|
// Put in Adapter GUID
|
|
Status = CfgUtilSetWmiStringParam(
|
|
spWbemInput,
|
|
L"AdapterGuid",
|
|
szNicGuid
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
TRACE_CRIT(L"Error trying to set Adapter GUID : %ls",szNicGuid);
|
|
goto end;
|
|
}
|
|
|
|
// If passed, Put in Virtual IP Address
|
|
// Virtual IP Address will be passed only for port operations
|
|
if (szVip)
|
|
{
|
|
Status = CfgUtilSetWmiStringParam(
|
|
spWbemInput,
|
|
L"VirtualIpAddress",
|
|
szVip
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
TRACE_CRIT(L"Error trying to set Virtual IP Address : %ls",szVip);
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
// If passed, Put in Port Number
|
|
// Port number will be passed only for port operations
|
|
if (pdwPortNum)
|
|
{
|
|
CfgUtilSetWmiDWORDParam(
|
|
spWbemInput,
|
|
L"Port",
|
|
*pdwPortNum
|
|
);
|
|
}
|
|
|
|
// Put in Operation
|
|
CfgUtilSetWmiDWORDParam(
|
|
spWbemInput,
|
|
L"Operation",
|
|
(DWORD)Operation
|
|
);
|
|
|
|
//
|
|
// Call the "ControlCluster" method
|
|
//
|
|
{
|
|
HRESULT hr;
|
|
|
|
wprintf(L"Going get ControlCluster...\n");
|
|
|
|
hr = spWbemService->ExecMethod(
|
|
_bstr_t(pRelPath),
|
|
L"ControlCluster",
|
|
0,
|
|
NULL,
|
|
spWbemInput,
|
|
&spWbemOutput,
|
|
NULL
|
|
);
|
|
|
|
if( FAILED( hr) )
|
|
{
|
|
wprintf(L"ControlCluster returns with failure 0x%8lx\n",
|
|
(UINT) hr);
|
|
goto end;
|
|
}
|
|
//else
|
|
//{
|
|
// wprintf(L"ControlCluster returns successfully\n");
|
|
//}
|
|
|
|
if (spWbemOutput == NULL)
|
|
{
|
|
//
|
|
// Hmm --- no output ?!
|
|
//
|
|
printf("ExecMethod ControlCluster had no output");
|
|
Status = WBEM_E_NOT_FOUND;
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Extract output params from the "ControlCluster" method
|
|
//
|
|
{
|
|
DWORD dwTemp;
|
|
|
|
// Get return value
|
|
Status = CfgUtilGetWmiDWORDParam(
|
|
spWbemOutput,
|
|
L"ReturnValue",
|
|
&dwTemp
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read ReturnValue failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
goto end;
|
|
}
|
|
else
|
|
{
|
|
if (pdwOperationStatus)
|
|
*pdwOperationStatus = dwTemp;
|
|
}
|
|
|
|
// Get Cluster or Port Status
|
|
Status = CfgUtilGetWmiDWORDParam(
|
|
spWbemOutput,
|
|
L"CurrentState",
|
|
&dwTemp
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read CurrentState failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
goto end;
|
|
}
|
|
else
|
|
{
|
|
if (pdwClusterOrPortStatus)
|
|
*pdwClusterOrPortStatus = dwTemp;
|
|
}
|
|
|
|
// If present, Get Host Map
|
|
// For port operations, Host Map will not be returned
|
|
Status = CfgUtilGetWmiDWORDParam(
|
|
spWbemOutput,
|
|
L"HostMap",
|
|
&dwTemp
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
if ((Operation != WLBS_PORT_ENABLE)
|
|
&& (Operation != WLBS_PORT_DISABLE)
|
|
&& (Operation != WLBS_PORT_DRAIN)
|
|
&& (Operation != WLBS_QUERY_PORT_STATE)
|
|
)
|
|
{
|
|
wprintf(L"Attempt to read HostMap failed. Error=0x%08lx\n", (UINT) Status);
|
|
goto end;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pdwHostMap)
|
|
*pdwHostMap = dwTemp;
|
|
}
|
|
|
|
Status = WBEM_NO_ERROR;
|
|
}
|
|
|
|
end:
|
|
|
|
if (pRelPath != NULL)
|
|
{
|
|
delete pRelPath;
|
|
}
|
|
|
|
spWbemService = NULL; // Smart pointer
|
|
spWbemInput = NULL; // smart pointer
|
|
spWbemOutput = NULL; // smart pointer.
|
|
|
|
TRACE_INFO("<-%!FUNC! returns 0x%08lx", Status);
|
|
return Status;
|
|
}
|
|
|
|
|
|
WBEMSTATUS
|
|
NlbHostGetClusterMembers(
|
|
IN PWMI_CONNECTION_INFO pConnInfo,
|
|
IN LPCWSTR szNicGuid,
|
|
OUT DWORD *pNumMembers,
|
|
OUT NLB_CLUSTER_MEMBER_INFO **ppMembers // free using delete[]
|
|
)
|
|
{
|
|
|
|
WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
|
|
IWbemServicesPtr spWbemService = NULL; // Smart pointer
|
|
IWbemClassObjectPtr spWbemInput = NULL; // smart pointer
|
|
IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
|
|
LPWSTR pRelPath = NULL;
|
|
|
|
GUID AdapterGuid;
|
|
DWORD dwStatus;
|
|
LPWSTR *pszHostIdList = NULL;
|
|
LPWSTR *pszDedicatedIpAddressList = NULL;
|
|
LPWSTR *pszHostNameList = NULL;
|
|
UINT NumHostIds = 0;
|
|
UINT NumDips = 0;
|
|
UINT NumHostNames = 0;
|
|
|
|
TRACE_VERB(L"->(GUID=%ws)", szNicGuid);
|
|
|
|
ASSERT (pNumMembers != NULL);
|
|
ASSERT (ppMembers != NULL);
|
|
|
|
*pNumMembers = 0;
|
|
*ppMembers = NULL;
|
|
|
|
if (g_Fake)
|
|
{
|
|
TRACE_INFO(L"faking call");
|
|
Status = FakeNlbHostGetClusterMembers(
|
|
pConnInfo,
|
|
szNicGuid,
|
|
pNumMembers,
|
|
ppMembers
|
|
);
|
|
goto end;
|
|
}
|
|
|
|
//
|
|
// Get interface to the NLB namespace on the specified machine
|
|
//
|
|
Status = connect_to_server(pConnInfo, REF spWbemService);
|
|
if (FAILED(Status))
|
|
{
|
|
goto end;
|
|
}
|
|
|
|
|
|
//
|
|
// Get wmi input instance to "ControlCluster" method
|
|
//
|
|
{
|
|
Status = CfgUtilGetWmiInputInstanceAndRelPath(
|
|
spWbemService,
|
|
L"NlbsNic", // szClassName
|
|
NULL, // szParameterName
|
|
NULL, // szPropertyValue
|
|
L"GetClusterMembers", // szMethodName,
|
|
spWbemInput, // smart pointer
|
|
&pRelPath // free using delete
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(
|
|
L"ERROR 0x%08lx trying to get instance of UpdateConfiguration\n",
|
|
(UINT) Status
|
|
);
|
|
TRACE_CRIT(L"CfgUtilGetWmiInputInstanceAndRelPath failed with status 0x%x", Status);
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Setup input parameters
|
|
//
|
|
Status = CfgUtilSetWmiStringParam(
|
|
spWbemInput,
|
|
L"AdapterGuid",
|
|
szNicGuid
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
TRACE_CRIT(L"Error trying to set Adapter GUID : %ls", szNicGuid);
|
|
goto end;
|
|
}
|
|
|
|
{
|
|
HRESULT hr;
|
|
|
|
wprintf(L"Calling GetClusterMembers...\n");
|
|
|
|
hr = spWbemService->ExecMethod(
|
|
_bstr_t(pRelPath),
|
|
L"GetClusterMembers",
|
|
0,
|
|
NULL,
|
|
spWbemInput,
|
|
&spWbemOutput,
|
|
NULL
|
|
);
|
|
|
|
if( FAILED( hr) )
|
|
{
|
|
wprintf(L"GetClusterMembers returns with failure 0x%8lx\n",
|
|
(UINT) hr);
|
|
TRACE_CRIT(L"ExecMethod (GetClusterMembers) failed with hresult 0x%x", hr);
|
|
goto end;
|
|
}
|
|
|
|
if (spWbemOutput == NULL)
|
|
{
|
|
//
|
|
// Hmm --- no output ?!
|
|
//
|
|
printf("ExecMethod GetClusterMembers had no output");
|
|
Status = WBEM_E_NOT_FOUND;
|
|
TRACE_CRIT(L"ExecMethod (GetClusterMembers) failed with hresult 0x%x", hr);
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Extract output params from the "GetClusterMembers" method
|
|
//
|
|
{
|
|
DWORD dwTemp;
|
|
|
|
// Get return value
|
|
Status = CfgUtilGetWmiDWORDParam(
|
|
spWbemOutput,
|
|
L"ReturnValue",
|
|
&dwTemp
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read ReturnValue failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
TRACE_CRIT(L"Attempt to read ReturnValue failed. Error=0x%08lx", (UINT) Status);
|
|
goto end;
|
|
}
|
|
else
|
|
{
|
|
dwStatus = dwTemp;
|
|
}
|
|
|
|
if (dwStatus != WBEM_S_NO_ERROR)
|
|
{
|
|
TRACE_CRIT(L"GetClusterMembers failed return status = 0x%x", dwStatus);
|
|
Status = WBEM_NO_ERROR;
|
|
goto end;
|
|
}
|
|
|
|
// Get the array of host IDs
|
|
Status = CfgUtilGetWmiStringArrayParam(
|
|
spWbemOutput,
|
|
L"HostIds",
|
|
&pszHostIdList,
|
|
&NumHostIds
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
pszHostIdList = NULL;
|
|
NumHostIds = 0;
|
|
wprintf(L"Attempt to read HostIds failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
TRACE_CRIT(L"Attempt to read HostIds failed. Error=0x%08lx", (UINT) Status);
|
|
goto end;
|
|
}
|
|
|
|
// Get the array of Dedicated IPs
|
|
Status = CfgUtilGetWmiStringArrayParam(
|
|
spWbemOutput,
|
|
L"DedicatedIpAddresses",
|
|
&pszDedicatedIpAddressList,
|
|
&NumDips
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
pszDedicatedIpAddressList = NULL;
|
|
NumDips = 0;
|
|
wprintf(L"Attempt to read DedicatedIpAddresses failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
TRACE_CRIT(L"Attempt to read DedicatedIpAddresses failed. Error=0x%08lx", (UINT) Status);
|
|
goto end;
|
|
}
|
|
|
|
// Get the array of host IDs
|
|
Status = CfgUtilGetWmiStringArrayParam(
|
|
spWbemOutput,
|
|
L"HostNames",
|
|
&pszHostNameList,
|
|
&NumHostNames
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
pszHostNameList = NULL;
|
|
NumHostNames = 0;
|
|
wprintf(L"Attempt to read HostNames failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
TRACE_CRIT(L"Attempt to read HostNames failed. Error=0x%08lx", (UINT) Status);
|
|
goto end;
|
|
}
|
|
|
|
if (NumHostIds != NumDips || NumDips != NumHostNames)
|
|
{
|
|
TRACE_CRIT(L"Information arrays of host information are of different lengths. NumHostIds=%d, NumDips=%d, NumHostNames=%d", NumHostIds, NumDips, NumHostNames);
|
|
Status = WBEM_E_FAILED;
|
|
goto end;
|
|
}
|
|
|
|
*ppMembers = new NLB_CLUSTER_MEMBER_INFO[NumHostIds];
|
|
|
|
if (*ppMembers == NULL)
|
|
{
|
|
TRACE_CRIT(L"Memory allocation for NLB_CLUSTER_MEMBER_INFO array failed");
|
|
Status = WBEM_E_OUT_OF_MEMORY;
|
|
goto end;
|
|
}
|
|
|
|
*pNumMembers = NumHostIds;
|
|
|
|
//
|
|
// Copy the string information into buffers for output
|
|
//
|
|
for (int i=0; i< NumHostIds; i++)
|
|
{
|
|
(*ppMembers)[i].HostId = wcstoul(pszHostIdList[i], NULL, 0);
|
|
|
|
wcsncpy((*ppMembers)[i].DedicatedIpAddress, pszDedicatedIpAddressList[i], WLBS_MAX_CL_IP_ADDR);
|
|
(*ppMembers)[i].DedicatedIpAddress[WLBS_MAX_CL_IP_ADDR - 1] = L'\0';
|
|
|
|
wcsncpy((*ppMembers)[i].HostName, pszHostNameList[i], CVY_MAX_FQDN + 1);
|
|
(*ppMembers)[i].HostName[CVY_MAX_FQDN] = L'\0';
|
|
}
|
|
|
|
Status = WBEM_NO_ERROR;
|
|
}
|
|
|
|
end:
|
|
|
|
if (pRelPath != NULL)
|
|
{
|
|
delete pRelPath;
|
|
}
|
|
|
|
if (pszHostIdList != NULL)
|
|
{
|
|
delete [] pszHostIdList;
|
|
}
|
|
|
|
if (pszDedicatedIpAddressList != NULL)
|
|
{
|
|
delete [] pszDedicatedIpAddressList;
|
|
}
|
|
|
|
if (pszHostNameList != NULL)
|
|
{
|
|
delete [] pszHostNameList;
|
|
}
|
|
|
|
spWbemService = NULL; // Smart pointer
|
|
spWbemInput = NULL; // smart pointer
|
|
spWbemOutput = NULL; // smart pointer.
|
|
|
|
TRACE_VERB(L"<- returns 0x%08lx", Status);
|
|
return Status;
|
|
}
|
|
|
|
|
|
WBEMSTATUS
|
|
NlbHostGetUpdateStatus(
|
|
IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
|
|
IN LPCWSTR szNicGuid,
|
|
IN UINT Generation,
|
|
OUT WBEMSTATUS *pCompletionStatus,
|
|
OUT WCHAR **ppLog // free using delete operator.
|
|
)
|
|
{
|
|
WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
|
|
IWbemServicesPtr spWbemService = NULL; // Smart pointer
|
|
IWbemClassObjectPtr spWbemInput = NULL; // smart pointer
|
|
IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
|
|
LPWSTR pRelPath = NULL;
|
|
TRACE_INFO("->%!FUNC!(GUID=%ws)", szNicGuid);
|
|
|
|
*ppLog = NULL;
|
|
*pCompletionStatus = WBEM_E_CRITICAL_ERROR;
|
|
|
|
if (g_Fake)
|
|
{
|
|
Status = FakeNlbHostGetUpdateStatus(
|
|
pConnInfo,
|
|
szNicGuid,
|
|
Generation,
|
|
pCompletionStatus,
|
|
ppLog
|
|
);
|
|
goto end;
|
|
}
|
|
|
|
//
|
|
// Get interface to the NLB namespace on the specified machine
|
|
//
|
|
Status = connect_to_server(pConnInfo, REF spWbemService);
|
|
if (FAILED(Status))
|
|
{
|
|
goto end;
|
|
}
|
|
|
|
|
|
//
|
|
// Get wmi input instance to "QueryConfigurationUpdateStatus" method
|
|
//
|
|
{
|
|
Status = CfgUtilGetWmiInputInstanceAndRelPath(
|
|
spWbemService,
|
|
L"NlbsNic", // szClassName
|
|
NULL, // szParameterName
|
|
NULL, // szPropertyValue
|
|
L"QueryConfigurationUpdateStatus", // szMethodName,
|
|
spWbemInput, // smart pointer
|
|
&pRelPath // free using delete
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(
|
|
L"ERROR 0x%08lx trying to find instance to QueryUpdateStatus\n",
|
|
(UINT) Status
|
|
);
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Setup params for the "QueryConfigurationUpdateStatus" method
|
|
// NOTE: spWbemInput could be NULL.
|
|
//
|
|
{
|
|
Status = CfgUtilSetWmiStringParam(
|
|
spWbemInput,
|
|
L"AdapterGuid",
|
|
szNicGuid
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(
|
|
L"Couldn't set Adapter GUID parameter to QueryUpdateStatus\n");
|
|
goto end;
|
|
}
|
|
|
|
Status = CfgUtilSetWmiDWORDParam(
|
|
spWbemInput,
|
|
L"Generation",
|
|
Generation
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(
|
|
L"Couldn't set Generation parameter to QueryUpdateStatus\n");
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Call the "QueryConfigurationUpdateStatus" method
|
|
//
|
|
{
|
|
HRESULT hr;
|
|
|
|
// wprintf(L"Going call QueryConfigurationUpdateStatus...\n");
|
|
|
|
hr = spWbemService->ExecMethod(
|
|
_bstr_t(pRelPath),
|
|
L"QueryConfigurationUpdateStatus", // szMethodName,
|
|
0,
|
|
NULL,
|
|
spWbemInput,
|
|
&spWbemOutput,
|
|
NULL
|
|
);
|
|
|
|
if( FAILED( hr) )
|
|
{
|
|
wprintf(L"QueryConfigurationUpdateStatus returns with failure 0x%8lx\n",
|
|
(UINT) hr);
|
|
goto end;
|
|
}
|
|
else
|
|
{
|
|
// wprintf(L"QueryConfigurationUpdateStatus returns successfully\n");
|
|
}
|
|
|
|
if (spWbemOutput == NULL)
|
|
{
|
|
//
|
|
// Hmm --- no output ?!
|
|
//
|
|
printf("ExecMethod QueryConfigurationUpdateStatus had no output");
|
|
Status = WBEM_E_NOT_FOUND;
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Extract output params --- return code and log.
|
|
//
|
|
{
|
|
DWORD dwReturnValue = 0;
|
|
|
|
Status = CfgUtilGetWmiDWORDParam(
|
|
spWbemOutput,
|
|
L"ReturnValue", // <--------------------------------
|
|
&dwReturnValue
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read ReturnValue failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
goto end;
|
|
}
|
|
|
|
*pCompletionStatus = (WBEMSTATUS) dwReturnValue;
|
|
|
|
|
|
LPWSTR szLog = NULL;
|
|
|
|
Status = CfgUtilGetWmiStringParam(
|
|
spWbemOutput,
|
|
L"Log", // <-------------------------
|
|
&szLog
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
szLog = NULL;
|
|
}
|
|
|
|
*ppLog = szLog;
|
|
|
|
ASSERT(Status != WBEM_S_PENDING);
|
|
}
|
|
|
|
end:
|
|
|
|
if (pRelPath != NULL)
|
|
{
|
|
delete pRelPath;
|
|
}
|
|
|
|
spWbemService = NULL; // Smart pointer
|
|
spWbemInput = NULL; // smart pointer
|
|
spWbemOutput = NULL; // smart pointer.
|
|
|
|
TRACE_INFO("<-%!FUNC! returns 0x%08lx", Status);
|
|
return Status;
|
|
}
|
|
|
|
|
|
WBEMSTATUS
|
|
NlbHostPing(
|
|
LPCWSTR szBindString,
|
|
UINT Timeout, // In milliseconds.
|
|
OUT ULONG *pResolvedIpAddress // in network byte order.
|
|
)
|
|
{
|
|
WBEMSTATUS Status = WBEM_E_INVALID_PARAMETER;
|
|
TRACE_INFO("->%!FUNC!(GUID=%ws)", szBindString);
|
|
|
|
if (g_Fake)
|
|
{
|
|
Status = FakeNlbHostPing(szBindString, Timeout, pResolvedIpAddress);
|
|
}
|
|
else
|
|
{
|
|
Status = CfgUtilPing(szBindString, Timeout, pResolvedIpAddress);
|
|
}
|
|
|
|
TRACE_INFO("<-%!FUNC! returns 0x%08lx", Status);
|
|
return Status;
|
|
}
|
|
|
|
WBEMSTATUS
|
|
setup_GetClusterConfiguration_input_params(
|
|
IN LPCWSTR szNic,
|
|
IN IWbemClassObjectPtr spWbemInput
|
|
)
|
|
/*
|
|
Setup the input wmi parameters for the GetClusterConfiguration method
|
|
*/
|
|
{
|
|
WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
|
|
|
|
Status = CfgUtilSetWmiStringParam(
|
|
spWbemInput,
|
|
L"AdapterGuid",
|
|
szNic
|
|
);
|
|
return Status;
|
|
}
|
|
|
|
|
|
WBEMSTATUS
|
|
extract_GetClusterConfiguration_output_params(
|
|
IN IWbemClassObjectPtr spWbemOutput,
|
|
OUT PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg
|
|
)
|
|
{
|
|
WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
|
|
|
|
DWORD Generation = 0;
|
|
BOOL NlbBound = FALSE;
|
|
BOOL fDHCPEnabled = FALSE;
|
|
LPWSTR *pszNetworkAddresses= NULL;
|
|
UINT NumNetworkAddresses = 0;
|
|
BOOL ValidNlbCfg = FALSE;
|
|
LPWSTR szFriendlyName = NULL;
|
|
LPWSTR szClusterName = NULL;
|
|
LPWSTR szClusterNetworkAddress = NULL;
|
|
LPWSTR szTrafficMode = NULL;
|
|
NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE
|
|
TrafficMode
|
|
= NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_UNICAST;
|
|
LPWSTR *pszPortRules = NULL;
|
|
UINT NumPortRules = 0;
|
|
DWORD HostPriority = 0;
|
|
LPWSTR szDedicatedNetworkAddress = NULL;
|
|
/*
|
|
NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE
|
|
ClusterModeOnStart
|
|
= NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE_STOPPED;
|
|
*/
|
|
DWORD ClusterModeOnStart = CVY_HOST_STATE_STOPPED;
|
|
BOOL bPersistSuspendOnReboot = FALSE;
|
|
BOOL RemoteControlEnabled= FALSE;
|
|
DWORD dwHashedRemoteControlPassword = 0;
|
|
|
|
pCfg->Clear();
|
|
|
|
Status = CfgUtilGetWmiStringParam(
|
|
spWbemOutput,
|
|
L"FriendlyName", // <-------------------------
|
|
&szFriendlyName
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read Friendly Name failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
szFriendlyName = NULL;
|
|
// We don't treat this as a fatal error ...
|
|
}
|
|
|
|
Status = CfgUtilGetWmiDWORDParam(
|
|
spWbemOutput,
|
|
L"Generation", // <--------------------------------
|
|
&Generation
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read Generation failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
goto end;
|
|
}
|
|
|
|
Status = CfgUtilGetWmiStringArrayParam(
|
|
spWbemOutput,
|
|
L"NetworkAddresses", // <--------------------------------
|
|
&pszNetworkAddresses,
|
|
&NumNetworkAddresses
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read Network addresses failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
goto end;
|
|
}
|
|
|
|
Status = CfgUtilGetWmiBoolParam(
|
|
spWbemOutput,
|
|
L"DHCPEnabled", // <--------------------------------
|
|
&fDHCPEnabled
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
fDHCPEnabled = FALSE;
|
|
}
|
|
|
|
Status = CfgUtilGetWmiBoolParam(
|
|
spWbemOutput,
|
|
L"NLBBound", // <--------------------------------
|
|
&NlbBound
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read NLBBound failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
goto end;
|
|
}
|
|
|
|
|
|
do // while false -- just to allow us to break out
|
|
{
|
|
ValidNlbCfg = FALSE;
|
|
|
|
if (!NlbBound)
|
|
{
|
|
if (!g_Silent)
|
|
{
|
|
wprintf(L"NLB is UNBOUND\n");
|
|
}
|
|
break;
|
|
}
|
|
|
|
Status = CfgUtilGetWmiStringParam(
|
|
spWbemOutput,
|
|
L"ClusterNetworkAddress", // <-------------------------
|
|
&szClusterNetworkAddress
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read Cluster IP failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
break;
|
|
}
|
|
|
|
if (!g_Silent)
|
|
{
|
|
wprintf(L"NLB is BOUND, and the cluster address is %ws\n",
|
|
szClusterNetworkAddress);
|
|
}
|
|
|
|
Status = CfgUtilGetWmiStringParam(
|
|
spWbemOutput,
|
|
L"ClusterName", // <-------------------------
|
|
&szClusterName
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read Cluster Name failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Traffic mode
|
|
//
|
|
{
|
|
Status = CfgUtilGetWmiStringParam(
|
|
spWbemOutput,
|
|
L"TrafficMode", // <-------------------------
|
|
&szTrafficMode
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read Traffic Mode failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
break;
|
|
}
|
|
|
|
if (!_wcsicmp(szTrafficMode, L"UNICAST"))
|
|
{
|
|
TrafficMode =
|
|
NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_UNICAST;
|
|
}
|
|
else if (!_wcsicmp(szTrafficMode, L"MULTICAST"))
|
|
{
|
|
TrafficMode =
|
|
NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_MULTICAST;
|
|
}
|
|
else if (!_wcsicmp(szTrafficMode, L"IGMPMULTICAST"))
|
|
{
|
|
TrafficMode =
|
|
NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_IGMPMULTICAST;
|
|
}
|
|
}
|
|
|
|
// [OUT] String PortRules[],
|
|
Status = CfgUtilGetWmiStringArrayParam(
|
|
spWbemOutput,
|
|
L"PortRules", // <--------------------------------
|
|
&pszPortRules,
|
|
&NumPortRules
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read port rules failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
goto end;
|
|
}
|
|
|
|
Status = CfgUtilGetWmiDWORDParam(
|
|
spWbemOutput,
|
|
L"HostPriority", // <--------------------------------
|
|
&HostPriority
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read HostPriority failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
break;
|
|
}
|
|
|
|
Status = CfgUtilGetWmiStringParam(
|
|
spWbemOutput,
|
|
L"DedicatedNetworkAddress", // <-------------------------
|
|
&szDedicatedNetworkAddress
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read dedicated IP failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// StartMode
|
|
//
|
|
{
|
|
/*
|
|
BOOL StartMode = FALSE;
|
|
Status = CfgUtilGetWmiBoolParam(
|
|
spWbemOutput,
|
|
L"ClusterModeOnStart", // <-------------------------
|
|
&StartMode
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read ClusterModeOnStart failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
break;
|
|
}
|
|
if (StartMode)
|
|
{
|
|
ClusterModeOnStart =
|
|
NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE_STARTED;
|
|
}
|
|
else
|
|
{
|
|
ClusterModeOnStart =
|
|
NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE_STOPPED;
|
|
}
|
|
*/
|
|
|
|
Status = CfgUtilGetWmiDWORDParam(
|
|
spWbemOutput,
|
|
L"ClusterModeOnStart", // <--------------------------------
|
|
&ClusterModeOnStart
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read ClusterModeOnStart failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
Status = CfgUtilGetWmiBoolParam(
|
|
spWbemOutput,
|
|
L"PersistSuspendOnReboot", // <----------------------------
|
|
&bPersistSuspendOnReboot
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read PersistSuspendOnReboot failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
break;
|
|
}
|
|
|
|
Status = CfgUtilGetWmiBoolParam(
|
|
spWbemOutput,
|
|
L"RemoteControlEnabled", // <----------------------------
|
|
&RemoteControlEnabled
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read RemoteControlEnabled failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
break;
|
|
}
|
|
|
|
|
|
Status = CfgUtilGetWmiDWORDParam(
|
|
spWbemOutput,
|
|
L"HashedRemoteControlPassword", // <-----------
|
|
&dwHashedRemoteControlPassword
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to read dwHashedRemoteControlPassword failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
//
|
|
// we set this to 0 on failure, but go on.
|
|
//
|
|
dwHashedRemoteControlPassword = 0;
|
|
}
|
|
|
|
ValidNlbCfg = TRUE;
|
|
|
|
} while (FALSE) ;
|
|
|
|
//
|
|
// Now let's set all the the parameters in Cfg
|
|
//
|
|
{
|
|
(VOID) pCfg->SetFriendlyName(szFriendlyName); // OK if szFriendlyName is NULL.
|
|
pCfg->Generation = Generation;
|
|
pCfg->fDHCP = fDHCPEnabled;
|
|
pCfg->fBound = NlbBound;
|
|
Status = pCfg->SetNetworkAddresses(
|
|
(LPCWSTR*) pszNetworkAddresses,
|
|
NumNetworkAddresses
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to set NetworkAddresses failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
goto end;
|
|
}
|
|
pCfg->fValidNlbCfg = ValidNlbCfg;
|
|
pCfg->SetClusterName(szClusterName);
|
|
pCfg->SetClusterNetworkAddress(szClusterNetworkAddress);
|
|
pCfg->SetTrafficMode(TrafficMode);
|
|
Status = pCfg->SetPortRules((LPCWSTR*)pszPortRules, NumPortRules);
|
|
// Status = WBEM_NO_ERROR; // TODO -- change once port rules is done
|
|
if (FAILED(Status))
|
|
{
|
|
wprintf(L"Attempt to set PortRules failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
goto end;
|
|
}
|
|
pCfg->SetHostPriority(HostPriority);
|
|
pCfg->SetDedicatedNetworkAddress(szDedicatedNetworkAddress);
|
|
pCfg->SetClusterModeOnStart(ClusterModeOnStart);
|
|
pCfg->SetPersistSuspendOnReboot(bPersistSuspendOnReboot);
|
|
pCfg->SetRemoteControlEnabled(RemoteControlEnabled);
|
|
CfgUtilSetHashedRemoteControlPassword(
|
|
&pCfg->NlbParams,
|
|
dwHashedRemoteControlPassword
|
|
);
|
|
}
|
|
|
|
end:
|
|
|
|
delete szClusterNetworkAddress;
|
|
delete pszNetworkAddresses;
|
|
delete szFriendlyName;
|
|
delete szClusterName;
|
|
delete szTrafficMode;
|
|
delete pszPortRules;
|
|
delete szDedicatedNetworkAddress;
|
|
|
|
return Status;
|
|
}
|
|
|
|
WBEMSTATUS
|
|
setup_UpdateClusterConfiguration_input_params(
|
|
IN LPCWSTR szClientDescription,
|
|
IN LPCWSTR szNic,
|
|
IN PNLB_EXTENDED_CLUSTER_CONFIGURATION pCfg,
|
|
IN IWbemClassObjectPtr spWbemInput
|
|
)
|
|
/*
|
|
Setup the input wmi parameters for the UpdateGetClusterConfiguration method
|
|
|
|
[IN] String ClientDescription,
|
|
[IN] String AdapterGuid,
|
|
[IN] uint32 Generation,
|
|
[IN] Boolean PartialUpdate,
|
|
|
|
[IN] Boolean AddDedicatedIp,
|
|
[IN] Boolean AddClusterIps,
|
|
[IN] Boolean CheckForAddressConflicts,
|
|
|
|
[IN] String NetworkAddresses[], // "10.1.1.1/255.255.255.255"
|
|
[IN] Boolean NLBBound,
|
|
[IN] String ClusterNetworkAddress, // "10.1.1.1/255.0.0.0"
|
|
[IN] String ClusterName,
|
|
[IN] String TrafficMode, // UNICAST MULTICAST IGMPMULTICAST
|
|
[IN] String PortRules[],
|
|
[IN] uint32 HostPriority,
|
|
[IN] String DedicatedNetworkAddress, // "10.1.1.1/255.0.0.0"
|
|
[IN] uint32 ClusterModeOnStart, // 0 : STOPPED, 1 : STARTED, 2 : SUSPENDED
|
|
[IN] Boolean PersistSuspendOnReboot,
|
|
[IN] Boolean RemoteControlEnabled,
|
|
[IN] String RemoteControlPassword,
|
|
[IN] uint32 HashedRemoteControlPassword,
|
|
*/
|
|
{
|
|
WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
|
|
|
|
(VOID) CfgUtilSetWmiStringParam(
|
|
spWbemInput,
|
|
L"ClientDescription",
|
|
szClientDescription
|
|
);
|
|
|
|
Status = CfgUtilSetWmiStringParam(
|
|
spWbemInput,
|
|
L"AdapterGuid",
|
|
szNic
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
printf(
|
|
"Setup update params: Couldn't set adapter GUID"
|
|
" for NIC %ws\n",
|
|
szNic
|
|
);
|
|
goto end;
|
|
}
|
|
|
|
//
|
|
// Fill in NetworkAddresses[]
|
|
//
|
|
{
|
|
LPWSTR *pszAddresses = NULL;
|
|
UINT NumAddresses = 0;
|
|
Status = pCfg->GetNetworkAddresses(
|
|
&pszAddresses,
|
|
&NumAddresses
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
printf(
|
|
"Setup update params: couldn't extract network addresses from Cfg"
|
|
" for NIC %ws\n",
|
|
szNic
|
|
);
|
|
goto end;
|
|
}
|
|
|
|
//
|
|
// Note it's ok to not specify any IP addresses -- in which case
|
|
// the default ip addresses will be set up.
|
|
//
|
|
if (pszAddresses != NULL)
|
|
{
|
|
Status = CfgUtilSetWmiStringArrayParam(
|
|
spWbemInput,
|
|
L"NetworkAddresses",
|
|
(LPCWSTR *)pszAddresses,
|
|
NumAddresses
|
|
);
|
|
delete pszAddresses;
|
|
pszAddresses = NULL;
|
|
}
|
|
}
|
|
|
|
if (!pCfg->IsNlbBound())
|
|
{
|
|
//
|
|
// NLB is not bound
|
|
//
|
|
|
|
Status = CfgUtilSetWmiBoolParam(spWbemInput, L"NLBBound", FALSE);
|
|
goto end;
|
|
}
|
|
else if (!pCfg->IsValidNlbConfig())
|
|
{
|
|
printf(
|
|
"Setup update params: NLB-specific configuration on NIC %ws is invalid\n",
|
|
szNic
|
|
);
|
|
Status = WBEM_E_INVALID_PARAMETER;
|
|
goto end;
|
|
}
|
|
|
|
Status = CfgUtilSetWmiBoolParam(spWbemInput, L"NLBBound", TRUE);
|
|
if (FAILED(Status))
|
|
{
|
|
printf("Error trying to set NLBBound parameter\n");
|
|
goto end;
|
|
}
|
|
|
|
|
|
//
|
|
// NLB is bound
|
|
//
|
|
|
|
|
|
Status = CfgUtilSetWmiBoolParam(spWbemInput, L"AddDedicatedIp",
|
|
pCfg->fAddDedicatedIp);
|
|
if (FAILED(Status)) goto end;
|
|
|
|
Status = CfgUtilSetWmiBoolParam(spWbemInput, L"AddClusterIps",
|
|
pCfg->fAddClusterIps);
|
|
if (FAILED(Status)) goto end;
|
|
|
|
Status = CfgUtilSetWmiBoolParam(spWbemInput, L"CheckForAddressConflicts",
|
|
pCfg->fCheckForAddressConflicts);
|
|
if (FAILED(Status)) goto end;
|
|
|
|
|
|
//
|
|
// Cluster name
|
|
//
|
|
{
|
|
LPWSTR szName = NULL;
|
|
Status = pCfg->GetClusterName(&szName);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
printf(
|
|
"Setup update params: Could not extract cluster name for NIC %ws\n",
|
|
szNic
|
|
);
|
|
goto end;
|
|
}
|
|
CfgUtilSetWmiStringParam(spWbemInput, L"ClusterName", szName);
|
|
delete (szName);
|
|
szName = NULL;
|
|
}
|
|
|
|
//
|
|
// Cluster and dedicated network addresses
|
|
//
|
|
{
|
|
LPWSTR szAddress = NULL;
|
|
Status = pCfg->GetClusterNetworkAddress(&szAddress);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
printf(
|
|
"Setup update params: Could not extract cluster address for NIC %ws\n",
|
|
szNic
|
|
);
|
|
goto end;
|
|
}
|
|
CfgUtilSetWmiStringParam(
|
|
spWbemInput,
|
|
L"ClusterNetworkAddress",
|
|
szAddress
|
|
);
|
|
delete (szAddress);
|
|
szAddress = NULL;
|
|
|
|
Status = pCfg->GetDedicatedNetworkAddress(&szAddress);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
printf(
|
|
"Setup update params: Could not extract dedicated address for NIC %ws\n",
|
|
szNic
|
|
);
|
|
goto end;
|
|
}
|
|
CfgUtilSetWmiStringParam(
|
|
spWbemInput,
|
|
L"DedicatedNetworkAddress",
|
|
szAddress
|
|
);
|
|
delete (szAddress);
|
|
szAddress = NULL;
|
|
}
|
|
|
|
//
|
|
// TrafficMode
|
|
//
|
|
{
|
|
LPCWSTR szMode = NULL;
|
|
switch(pCfg->GetTrafficMode())
|
|
{
|
|
case NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_UNICAST:
|
|
szMode = L"UNICAST";
|
|
break;
|
|
case NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_MULTICAST:
|
|
szMode = L"MULTICAST";
|
|
break;
|
|
case NLB_EXTENDED_CLUSTER_CONFIGURATION::TRAFFIC_MODE_IGMPMULTICAST:
|
|
szMode = L"IGMPMULTICAST";
|
|
break;
|
|
default:
|
|
assert(FALSE);
|
|
Status = WBEM_E_CRITICAL_ERROR;
|
|
goto end;
|
|
}
|
|
CfgUtilSetWmiStringParam(spWbemInput, L"TrafficMode", szMode);
|
|
}
|
|
|
|
CfgUtilSetWmiDWORDParam(
|
|
spWbemInput,
|
|
L"HostPriority",
|
|
pCfg->GetHostPriority()
|
|
);
|
|
|
|
/*
|
|
if (pCfg->GetClusterModeOnStart() ==
|
|
NLB_EXTENDED_CLUSTER_CONFIGURATION::START_MODE_STARTED)
|
|
{
|
|
CfgUtilSetWmiBoolParam(spWbemInput, L"ClusterModeOnStart", TRUE);
|
|
}
|
|
else
|
|
{
|
|
CfgUtilSetWmiBoolParam(spWbemInput, L"ClusterModeOnStart", FALSE);
|
|
}
|
|
*/
|
|
|
|
CfgUtilSetWmiDWORDParam(
|
|
spWbemInput,
|
|
L"ClusterModeOnStart",
|
|
pCfg->GetClusterModeOnStart()
|
|
);
|
|
|
|
CfgUtilSetWmiBoolParam(
|
|
spWbemInput,
|
|
L"PersistSuspendOnReboot",
|
|
pCfg->GetPersistSuspendOnReboot()
|
|
);
|
|
|
|
CfgUtilSetWmiBoolParam(
|
|
spWbemInput,
|
|
L"RemoteControlEnabled",
|
|
pCfg->GetRemoteControlEnabled()
|
|
);
|
|
|
|
|
|
//
|
|
// Set the new password or hashed-password params, if specified.
|
|
//
|
|
{
|
|
// String RemoteControlPassword,
|
|
|
|
LPCWSTR szPwd = NULL;
|
|
szPwd = pCfg->GetNewRemoteControlPasswordRaw();
|
|
if (szPwd != NULL)
|
|
{
|
|
CfgUtilSetWmiStringParam(
|
|
spWbemInput,
|
|
L"RemoteControlPassword",
|
|
szPwd
|
|
);
|
|
}
|
|
else // only set the hashed pwd if szPwd is not specified.
|
|
{
|
|
DWORD dwHashedRemoteControlPassword;
|
|
BOOL fRet = FALSE;
|
|
|
|
fRet = pCfg->GetNewHashedRemoteControlPassword(
|
|
dwHashedRemoteControlPassword
|
|
);
|
|
|
|
if (fRet)
|
|
{
|
|
|
|
CfgUtilSetWmiDWORDParam(
|
|
spWbemInput,
|
|
L"HashedRemoteControlPassword",
|
|
dwHashedRemoteControlPassword
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// String PortRules[],
|
|
//
|
|
{
|
|
LPWSTR *pszPortRules = NULL;
|
|
UINT NumPortRules = 0;
|
|
Status = pCfg->GetPortRules(
|
|
&pszPortRules,
|
|
&NumPortRules
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
printf(
|
|
"Setup update params: couldn't extract port rules from Cfg"
|
|
" for NIC %ws\n",
|
|
szNic
|
|
);
|
|
goto end;
|
|
}
|
|
|
|
if (NumPortRules != 0)
|
|
{
|
|
Status = CfgUtilSetWmiStringArrayParam(
|
|
spWbemInput,
|
|
L"PortRules",
|
|
(LPCWSTR *)pszPortRules,
|
|
NumPortRules
|
|
);
|
|
delete pszPortRules;
|
|
pszPortRules = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
Status = WBEM_NO_ERROR;
|
|
|
|
end:
|
|
|
|
wprintf(L"<-Setup update params returns 0x%08lx\n", (UINT) Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
WBEMSTATUS
|
|
NlbHostGetCompatibleNics(
|
|
PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
|
|
OUT LPWSTR **ppszNics, // free using delete
|
|
OUT UINT *pNumNics, // free using delete
|
|
OUT UINT *pNumBoundToNlb
|
|
)
|
|
{
|
|
WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
|
|
IWbemServicesPtr spWbemService = NULL; // Smart pointer
|
|
IWbemClassObjectPtr spWbemInput = NULL; // smart pointer
|
|
IWbemClassObjectPtr spWbemOutput = NULL; // smart pointer.
|
|
LPWSTR pRelPath = NULL;
|
|
LPWSTR *pszNicList = NULL;
|
|
UINT NumNics = 0;
|
|
DWORD NumBoundToNlb = 0;
|
|
|
|
if (pConnInfo!=NULL)
|
|
{
|
|
TRACE_INFO("->%!FUNC!(Machine=%ws)", pConnInfo->szMachine);
|
|
}
|
|
else
|
|
{
|
|
TRACE_INFO("->%!FUNC! (Machine=<NULL>)");
|
|
}
|
|
|
|
|
|
if (g_Fake)
|
|
{
|
|
Status = FakeNlbHostGetCompatibleNics(
|
|
pConnInfo,
|
|
ppszNics,
|
|
pNumNics,
|
|
pNumBoundToNlb
|
|
);
|
|
goto end_fake;
|
|
}
|
|
|
|
*ppszNics = NULL;
|
|
*pNumNics = NULL;
|
|
*pNumBoundToNlb = NULL;
|
|
|
|
//
|
|
// Get interface to the NLB namespace on the specified machine
|
|
//
|
|
Status = connect_to_server(pConnInfo, REF spWbemService);
|
|
if (FAILED(Status))
|
|
{
|
|
goto end;
|
|
}
|
|
|
|
|
|
//
|
|
// Get wmi input instance to "GetCompatibleAdapterGuids" method
|
|
//
|
|
{
|
|
Status = CfgUtilGetWmiInputInstanceAndRelPath(
|
|
spWbemService,
|
|
L"NlbsNic", // szClassName
|
|
NULL, // L"AdapterGuid", // szParameterName
|
|
NULL, // szNicGuid, // szPropertyValue
|
|
L"GetCompatibleAdapterGuids", // szMethodName,
|
|
spWbemInput, // smart pointer
|
|
&pRelPath // free using delete
|
|
);
|
|
|
|
if (FAILED(Status))
|
|
{
|
|
TRACE_CRIT(
|
|
L"%!FUNC! ERROR 0x%08lx trying to get instance of GetCompatibleAdapterGuids",
|
|
(UINT) Status
|
|
);
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Setup params for the "GetClusterConfiguration" method
|
|
// NOTE: spWbemInput could be NULL.
|
|
//
|
|
{
|
|
// NOTHING TO DO HERE -- no input params...
|
|
}
|
|
|
|
//
|
|
// Call the "GetCompatibleAdapterGuids" method
|
|
//
|
|
{
|
|
HRESULT hr;
|
|
|
|
TRACE_VERB(L"%!FUNC! Going get GetCompatibleAdapterGuids...");
|
|
|
|
hr = spWbemService->ExecMethod(
|
|
_bstr_t(pRelPath),
|
|
L"GetCompatibleAdapterGuids",
|
|
0,
|
|
NULL,
|
|
spWbemInput,
|
|
&spWbemOutput,
|
|
NULL
|
|
);
|
|
|
|
if( FAILED( hr) )
|
|
{
|
|
TRACE_CRIT(L"%!FUNC! GetCompatibleAdapterGuids returns with failure 0x%8lx",
|
|
(UINT) hr);
|
|
Status = WBEM_E_CRITICAL_ERROR;
|
|
goto end;
|
|
}
|
|
else
|
|
{
|
|
TRACE_VERB(L"GetCompatibleAdapterGuids returns successfully");
|
|
}
|
|
|
|
if (spWbemOutput == NULL)
|
|
{
|
|
//
|
|
// Hmm --- no output ?!
|
|
//
|
|
TRACE_CRIT("%!FUNC! ExecMethod GetCompatibleAdapterGuids had no output");
|
|
Status = WBEM_E_NOT_FOUND;
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Extract params from the method
|
|
//
|
|
// [OUT] String AdapterGuids[],
|
|
// [OUT] uint32 NumBoundToNlb
|
|
//
|
|
|
|
Status = CfgUtilGetWmiDWORDParam(
|
|
spWbemOutput,
|
|
L"NumBoundToNlb", // <--------------------------------
|
|
&NumBoundToNlb
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
TRACE_CRIT(L"Attempt to read NumBoundToNlb failed. Error=0x%08lx\n",
|
|
(UINT) Status);
|
|
NumBoundToNlb = 0;
|
|
goto end;
|
|
}
|
|
|
|
Status = CfgUtilGetWmiStringArrayParam(
|
|
spWbemOutput,
|
|
L"AdapterGuids", // <--------------------------------
|
|
&pszNicList,
|
|
&NumNics
|
|
);
|
|
if (FAILED(Status))
|
|
{
|
|
TRACE_CRIT(L"%!FUNC! Attempt to read Adapter Guids failed. Error=0x%08lx",
|
|
(UINT) Status);
|
|
pszNicList = NULL;
|
|
NumNics = 0;
|
|
goto end;
|
|
}
|
|
|
|
|
|
end:
|
|
|
|
if (!FAILED(Status))
|
|
{
|
|
*ppszNics = pszNicList;
|
|
pszNicList = NULL;
|
|
*pNumNics = NumNics;
|
|
*pNumBoundToNlb = NumBoundToNlb;
|
|
}
|
|
|
|
delete pszNicList;
|
|
delete pRelPath;
|
|
|
|
end_fake:
|
|
|
|
spWbemService = NULL; // Smart pointer
|
|
spWbemInput = NULL; // smart pointer
|
|
spWbemOutput = NULL; // smart pointer.
|
|
|
|
TRACE_INFO("<-%!FUNC! returns 0x%08lx", Status);
|
|
return Status;
|
|
}
|
|
|
|
|
|
WBEMSTATUS
|
|
NlbHostGetMachineIdentification(
|
|
IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
|
|
OUT LPWSTR *pszMachineName, // free using delete
|
|
OUT LPWSTR *pszMachineGuid, // free using delete -- may be null
|
|
OUT BOOL *pfNlbMgrProviderInstalled // If nlb manager provider is installed.
|
|
)
|
|
{
|
|
WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
|
|
IWbemServicesPtr spWbemService = NULL; // Smart pointer
|
|
|
|
if (pConnInfo!=NULL)
|
|
{
|
|
TRACE_INFO("->%!FUNC!(Machine=%ws)", pConnInfo->szMachine);
|
|
}
|
|
else
|
|
{
|
|
TRACE_INFO("->%!FUNC! (Machine=<NULL>)");
|
|
}
|
|
|
|
|
|
if (g_Fake)
|
|
{
|
|
Status = FakeNlbHostGetMachineIdentification(
|
|
pConnInfo,
|
|
pszMachineName,
|
|
pszMachineGuid,
|
|
pfNlbMgrProviderInstalled
|
|
);
|
|
goto end;
|
|
}
|
|
|
|
*pszMachineName = NULL;
|
|
*pszMachineGuid = NULL;
|
|
*pfNlbMgrProviderInstalled = FALSE;
|
|
|
|
|
|
//
|
|
// Get interface to the NLB namespace on the specified machine
|
|
//
|
|
Status = connect_to_server(pConnInfo, REF spWbemService);
|
|
if (FAILED(Status))
|
|
{
|
|
goto end;
|
|
}
|
|
*pfNlbMgrProviderInstalled = TRUE;
|
|
|
|
|
|
Status = CfgUtilGetWmiMachineName(spWbemService, pszMachineName);
|
|
if (FAILED(Status))
|
|
{
|
|
*pszMachineName = NULL;
|
|
}
|
|
|
|
end:
|
|
|
|
spWbemService = NULL; // Smart pointer
|
|
|
|
TRACE_INFO("<-%!FUNC! returns 0x%08lx", Status);
|
|
return Status;
|
|
}
|
|
|
|
|
|
WBEMSTATUS
|
|
connect_to_server(
|
|
IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
|
|
OUT IWbemServicesPtr &spWbemService // Smart pointer
|
|
)
|
|
{
|
|
WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
|
|
#define _MaxLen 256
|
|
WCHAR NetworkResource[_MaxLen];
|
|
LPCWSTR szMachine = L".";
|
|
LPCWSTR szPassword = NULL;
|
|
LPCWSTR szUserName = NULL;
|
|
HRESULT hr;
|
|
WCHAR rgClearPassword[128];
|
|
|
|
//
|
|
// Get interface to the NLB namespace on the specified machine.
|
|
//
|
|
if (pConnInfo!=NULL)
|
|
{
|
|
szMachine = pConnInfo->szMachine;
|
|
szPassword = pConnInfo->szPassword;
|
|
szUserName = pConnInfo->szUserName;
|
|
}
|
|
|
|
hr = StringCbPrintf(
|
|
NetworkResource,
|
|
sizeof(NetworkResource),
|
|
L"\\\\%ws\\root\\microsoftnlb",
|
|
szMachine
|
|
);
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
TRACE_CRIT(L"%!FUNC! NetworkResource truncated - %ws",
|
|
NetworkResource);
|
|
Status = WBEM_E_INVALID_PARAMETER;
|
|
goto end;
|
|
}
|
|
|
|
if (szPassword != NULL && *szPassword != 0)
|
|
{
|
|
//
|
|
// A non-null, non-empty password was passed in...
|
|
// It's encrypted, so we temporarily decrypt it here...
|
|
// (We zero it out right before returning from this function)
|
|
//
|
|
BOOL fRet = CfgUtilDecryptPassword(
|
|
szPassword,
|
|
ASIZE(rgClearPassword),
|
|
rgClearPassword
|
|
);
|
|
if (!fRet)
|
|
{
|
|
TRACE_INFO("Attempt to decrypt failed -- bailing");
|
|
Status = WBEM_E_INVALID_PARAMETER;
|
|
goto end;
|
|
}
|
|
szPassword = rgClearPassword;
|
|
}
|
|
|
|
TRACE_INFO("%!FUNC! Connecting to NLB on %ws ...", szMachine);
|
|
|
|
Status = CfgUtilConnectToServer(
|
|
NetworkResource,
|
|
szUserName, // szUser
|
|
szPassword, // szPassword
|
|
NULL, // szAuthority (domain)
|
|
&spWbemService
|
|
);
|
|
|
|
//
|
|
// Security BUGBUG zero out decrypted password.
|
|
//
|
|
if (FAILED(Status))
|
|
{
|
|
TRACE_CRIT(
|
|
"%!FUNC! ERROR 0x%lx connectiong to NLB on %ws",
|
|
(UINT) Status,
|
|
szMachine
|
|
);
|
|
}
|
|
else
|
|
{
|
|
TRACE_INFO(L"Successfully connected to NLB on %ws...", szMachine);
|
|
}
|
|
|
|
end:
|
|
|
|
SecureZeroMemory(rgClearPassword, sizeof(rgClearPassword));
|
|
return Status;
|
|
}
|