Click here to Skip to main content
15,892,059 members

C++ WMI EnableStatic with multiple IPs Not Working

Aaron Manning asked:

Open original thread
G'Day All,

I have been trying to get the EnableStatic function to work with Multiple IP's/Netmasks and am having trouble. At NO point do I get any errors to any of the function calls, but none of my passed IP/Netmask pairs are actually being programmed. Hoping someone on here might have an idea as to what I am possibly doing wrong or missing.

The code to do the C++ EnableStatic was based off of this article in the posts section from "Brian Clow For God's Sake 10:38 30 May '06":

Making WMI Queries In C++[^]

I have changed the function to instead take a list of IP/Netmasks and build the EnableStatic parameters from those.

Here is the code (there is still some cleanup to do in the error returns for the function calls, but I have been first trying to get it to work):

C++
typedef struct IP_INFO
{
	char ip[40];
	char netmask[40];
} IP_INFO, *PIP_INFO;

bool AddIPAddressToAdapterPersistant(PIP_INFO &ipInfo, INT count, INT fIndex)
{
	HRESULT hr;
    IWbemLocator *pLocator = NULL;
    IWbemServices *pNamespace = NULL;
	BSTR path = SysAllocString(L"ROOT\\CIMV2");

    // Initialize COM and connect to WMI.
    hr = CoInitialize(0);
	if(FAILED(hr))
	{
		return (false);
	} // if

    hr  =  CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); 
	if(FAILED(hr))
	{
		CoUninitialize();
		return(false);
	} // if

    hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLocator);
	if (FAILED(hr))
	{
		CoUninitialize();
		return (false);
	} // if

    hr = pLocator->ConnectServer(path, NULL, NULL, NULL, 0, NULL, NULL, &pNamespace);
	if(FAILED(hr))
	{
		pLocator->Release();
		CoUninitialize();
		return(false);
	} // if

	// Grab class required to work on Win32_NetworkAdapterConfiguration
	IWbemClassObject *pClass = NULL;
	BSTR ClassPath = SysAllocString(L"Win32_NetworkAdapterConfiguration");
	hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
	SysFreeString(ClassPath);
	if( WBEM_S_NO_ERROR == hr )
	{
		// Grab pointer to the input parameter class of the method we are going to call
		BSTR MethodName_ES = SysAllocString(L"EnableStatic");
		IWbemClassObject *pInClass_ES = NULL;
		if(WBEM_S_NO_ERROR == pClass->GetMethod(MethodName_ES, 0, &pInClass_ES, NULL))
		{
			// Spawn instance of the input parameter class, so that we can stuff our parameters in
			IWbemClassObject *pInInst_ES = NULL;
 
			if(WBEM_S_NO_ERROR == pInClass_ES->SpawnInstance(0, &pInInst_ES))
			{
				//
				// (Step 3) - Pack desired parameters into the input class instances
				//
				// Convert from multibyte strings to wide character arrays
				wchar_t tmp_ip[_countof(ipInfo->ip)];
				SAFEARRAY *ip_list = SafeArrayCreateVector(VT_BSTR, 0, count);
				// Insert into safe arrays, allocating memory as we do so (destroying the safe array will destroy the allocated memory)
				long idx[] = {0};
				for(int i = 0; i < count; i++)
				{
					mbstowcs(tmp_ip, ipInfo[i].ip, _countof(ipInfo[i].ip));
					BSTR ip = SysAllocString(tmp_ip);
					idx[0] = i;
					if(FAILED(SafeArrayPutElement(ip_list, idx, ip)))
					{
						return (false);
					} // if
					// Destroy the BSTR pointer
					SysFreeString(ip);
				} // for

				// Convert from multibyte strings to wide character arrays
				wchar_t tmp_netmask[_countof(ipInfo->netmask)];
				SAFEARRAY *netmask_list = SafeArrayCreateVector(VT_BSTR, 0, count);
				// Insert into safe arrays, allocating memory as we do so (destroying the safe array will destroy the allocated memory)
				for(int i = 0; i < count; i++)
				{
					mbstowcs(tmp_netmask, ipInfo[i].netmask, _countof(ipInfo[i].netmask));
					BSTR netmask = SysAllocString(tmp_netmask);
					idx[0] = i;
					if(FAILED(SafeArrayPutElement(netmask_list, idx, netmask)))
					{
						return (false);
					} // if
					// Destroy the BSTR pointer
					SysFreeString(netmask);
				} // for

				// Now wrap each safe array in a VARIANT so that it can be passed to COM function
				VARIANT arg1_ES;
				VariantInit(&arg1_ES);
				arg1_ES.vt = VT_ARRAY|VT_BSTR;
				arg1_ES.parray = ip_list;
 
				VARIANT arg2_ES;
				VariantInit(&arg2_ES);
				arg2_ES.vt = VT_ARRAY|VT_BSTR; 
				arg2_ES.parray = netmask_list;
  
				if((WBEM_S_NO_ERROR == pInInst_ES->Put(L"IPAddress", 0, &arg1_ES, 0)) &&
			       (WBEM_S_NO_ERROR == pInInst_ES->Put(L"SubNetMask", 0, &arg2_ES, 0)))
				{
					//
					// (Step 4) - Call the methods
					//

					// First build the object path that specifies which network adapter we are executing a method on
					char indexString[10];
					itoa(fIndex, indexString, 10);
 
					char instanceString[100];
					wchar_t w_instanceString[100];
					strcpy(instanceString, "Win32_NetworkAdapterConfiguration.Index='");
					strcat(instanceString, indexString);
					strcat(instanceString, "'");
					mbstowcs(w_instanceString, instanceString, 100);
					BSTR InstancePath = SysAllocString(w_instanceString);
 
					// Now call the method
					IWbemClassObject * pOutInst = NULL;
					hr = pNamespace->ExecMethod(InstancePath, MethodName_ES, 0, NULL, pInInst_ES, &pOutInst, NULL);
					if(FAILED(hr))
					{
						// false
						return(false);
					} // if
					SysFreeString(InstancePath);
				} // if
 
				// Clear the variants - does this actually get ride of safearrays?
				VariantClear(&arg1_ES);
				VariantClear(&arg2_ES);

				// Destroy safe arrays, which destroys the objects stored inside them
				SafeArrayDestroy(ip_list); ip_list = NULL;
				SafeArrayDestroy(netmask_list); netmask_list = NULL;
 			}
			else
			{
				 // false
			} // if
 
			// Free up the instances that we spawned
			if(pInInst_ES)
			{
				pInInst_ES->Release();
				pInInst_ES = NULL;
			} // if
		}
		else
		{
			// false
		} // if
 
		// Free up methods input parameters class pointers
		if(pInClass_ES)
		{
			pInClass_ES->Release();
			pInClass_ES = NULL;
		} // if
		SysFreeString(MethodName_ES);
	}
	else
	{
		// false
	} // if
 
	// Variable cleanup
	if (pNamespace)
	{
		pNamespace->Release();
		pNamespace = NULL;
	}
	if (pLocator)
	{
		pLocator->Release();
		pLocator = NULL;
	} // if
	if(pClass)
	{
		pClass->Release();
		pClass = NULL;
	} //if
	CoUninitialize();

	return(true);
}


Thanks!
Tags: C++, WMI

Plain Text
ASM
ASP
ASP.NET
BASIC
BAT
C#
C++
COBOL
CoffeeScript
CSS
Dart
dbase
F#
FORTRAN
HTML
Java
Javascript
Kotlin
Lua
MIDL
MSIL
ObjectiveC
Pascal
PERL
PHP
PowerShell
Python
Razor
Ruby
Scala
Shell
SLN
SQL
Swift
T4
Terminal
TypeScript
VB
VBScript
XML
YAML

Preview



When answering a question please:
  1. Read the question carefully.
  2. Understand that English isn't everyone's first language so be lenient of bad spelling and grammar.
  3. If a question is poorly phrased then either ask for clarification, ignore it, or edit the question and fix the problem. Insults are not welcome.
  4. Don't tell someone to read the manual. Chances are they have and don't get it. Provide an answer or move on to the next question.
Let's work to help developers, not make them feel stupid.
Please note that all posts will be submitted under the http://www.codeproject.com/info/cpol10.aspx.



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900