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.
 
 
 
 
 
 

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;
}