G
Guest
I have a function to switch network from DHCP to static, the function works
fine in XP but not work in Vista, the return is 0 = no error, but there is
nothing changed in Vista, any help are welcome, I am using VS.net 2003 +
latest SDK
Thanks!
Eric
int SetStaticIP()
{
IWbemLocator *pLocator = NULL;
IWbemServices *pNamespace = 0;
IWbemClassObject *pClass = NULL;
IWbemClassObject *pMethod = NULL;
IWbemClassObject *pInInst = NULL;
IWbemClassObject *pOutInst = NULL;
// Strings needed later
BSTR className = SysAllocString(L"Win32_NetworkAdapterConfiguration");
BSTR methodName = SysAllocString(L"EnableStatic");
BSTR namespacePath = SysAllocString(L"root\\cimv2");
// Create WbemLocator Instance
HRESULT hr;
hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *) &pLocator);
// Using the WbemLocator, connect to the namespace
hr = pLocator->ConnectServer(namespacePath, NULL, NULL, NULL, 0,
NULL, NULL, &pNamespace);
hr = CoSetProxyBlanket(
pNamespace, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hr))
{
pNamespace->Release();
pLocator->Release();
CoUninitialize();
return 0; // Program has failed.
}
// Get the class object
hr = pNamespace->GetObject(className, 0, NULL, &pClass, NULL);
// Get the method we want to use in this class
hr = pClass->GetMethod(methodName, 0, &pMethod, NULL);
// Spawn an instance of the method so we can set it up (parameters)
hr = pMethod->SpawnInstance(0, &pInInst);
// EnableStatic() expects to receive the args in an array
BSTR ArgNameIP = SysAllocString(L"IPAddress");
BSTR ArgNameSM = SysAllocString(L"SubnetMask");
BSTR IP = SysAllocString(L"172.21.0.1");
BSTR SM = SysAllocString(L"255.255.0.0");
SAFEARRAYBOUND sab[1];
sab[0].cElements = 1;
sab[0].lLbound = 0;
LONG i = 0; // index needed for SafeArrayPutElement()
// var1 is the array that holds one element which is IP
VARIANT var1;
var1.vt = VT_ARRAY | VT_BSTR;
var1.parray = SafeArrayCreate(VT_BSTR, 1, sab); // create the array
SafeArrayPutElement(var1.parray, &i, IP); // put IP in the array
at pos 0
// var2 is the array that holds one element which is SM
VARIANT var2;
var2.vt = VT_ARRAY | VT_BSTR;
var2.parray = SafeArrayCreate(VT_BSTR, 1, sab); // create the array
SafeArrayPutElement(var2.parray, &i, SM); // put SM in the array
at pos 0
// put the ArgName and the Argument itself into the Method instance we
have
hr = pInInst->Put(ArgNameIP, 0, &var1, 0);
VariantClear(&var1);
hr = pInInst->Put(ArgNameSM, 0, &var2, 0);
VariantClear(&var2);
// Enumerate the instances of the NetworkAdapter to get at the __PATH
property
// to the one and only network card we really want to modify
IEnumWbemClassObject* pEnum;
hr = pNamespace->CreateInstanceEnum(className,
WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
NULL, &pEnum);
// Get the instance
ULONG numRet;
BSTR PropName;
VARIANT desc;
VARIANT dhcp;
VARIANT ipEnabled;
VARIANT pathVar;
IWbemClassObject *pInstance;
while ( hr != WBEM_S_FALSE)
{
hr = pEnum->Next(WBEM_INFINITE, (ULONG)1, &pInstance, &numRet);
if(0 == numRet)
break;
// we know that the one with DHCP is the one we want
PropName = SysAllocString(L"DHCPEnabled");
pInstance->Get(PropName, 0, &dhcp, 0, 0);
if (dhcp.bVal)
{
SysFreeString(PropName);
PropName = SysAllocString(L"IPEnabled");
pInstance->Get(PropName, 0, &ipEnabled, 0, 0);
SysFreeString(PropName);
if(ipEnabled.bVal)
{
// Print out the description just for us to see
SysFreeString(PropName);
PropName = SysAllocString(L"Description");
pInstance->Get(PropName, 0, &desc, 0, 0);
SysFreeString(PropName);
break;
}
}
SysFreeString(PropName);
}
// now we have the instance of the actual network card we want to modify
// let's query it's PATH property so that we can call the method on it.
PropName = SysAllocString(L"__PATH");
pInstance->Get(PropName, 0, &pathVar, 0, 0);
BSTR InstancePath = pathVar.bstrVal;
// finally we get to call the actuall method we want (EnableStatic())
hr = pNamespace->ExecMethod(InstancePath, methodName, 0, NULL,
pInInst, &pOutInst, NULL);
long ret = 0;
if(hr != WBEM_S_NO_ERROR)
{
BSTR Text;
hr = pOutInst->GetObjectText(0, &Text);
// CString strText = Text;
// MessageBox(strText);
}
else
{
// Get the EnableStatic method return value
VARIANT ret_value;
BSTR strReturnValue = SysAllocString(L"ReturnValue");
hr = pOutInst->Get(strReturnValue, 0, &ret_value, 0, 0);
long ret = V_I4(&ret_value);
}
// We're done!
// Free up resources
SysFreeString(className);
SysFreeString(methodName);
SysFreeString(namespacePath);
SysFreeString(ArgNameIP);
SysFreeString(ArgNameSM);
SysFreeString(IP);
SysFreeString(SM);
SysFreeString(PropName);
SysFreeString(InstancePath);
pLocator->Release();
pClass->Release();
pMethod->Release();
pNamespace->Release();
pInInst->Release();
pOutInst->Release();
pEnum->Release();
pInstance->Release();
CoUninitialize();
return ret;
}
fine in XP but not work in Vista, the return is 0 = no error, but there is
nothing changed in Vista, any help are welcome, I am using VS.net 2003 +
latest SDK
Thanks!
Eric
int SetStaticIP()
{
IWbemLocator *pLocator = NULL;
IWbemServices *pNamespace = 0;
IWbemClassObject *pClass = NULL;
IWbemClassObject *pMethod = NULL;
IWbemClassObject *pInInst = NULL;
IWbemClassObject *pOutInst = NULL;
// Strings needed later
BSTR className = SysAllocString(L"Win32_NetworkAdapterConfiguration");
BSTR methodName = SysAllocString(L"EnableStatic");
BSTR namespacePath = SysAllocString(L"root\\cimv2");
// Create WbemLocator Instance
HRESULT hr;
hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *) &pLocator);
// Using the WbemLocator, connect to the namespace
hr = pLocator->ConnectServer(namespacePath, NULL, NULL, NULL, 0,
NULL, NULL, &pNamespace);
hr = CoSetProxyBlanket(
pNamespace, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hr))
{
pNamespace->Release();
pLocator->Release();
CoUninitialize();
return 0; // Program has failed.
}
// Get the class object
hr = pNamespace->GetObject(className, 0, NULL, &pClass, NULL);
// Get the method we want to use in this class
hr = pClass->GetMethod(methodName, 0, &pMethod, NULL);
// Spawn an instance of the method so we can set it up (parameters)
hr = pMethod->SpawnInstance(0, &pInInst);
// EnableStatic() expects to receive the args in an array
BSTR ArgNameIP = SysAllocString(L"IPAddress");
BSTR ArgNameSM = SysAllocString(L"SubnetMask");
BSTR IP = SysAllocString(L"172.21.0.1");
BSTR SM = SysAllocString(L"255.255.0.0");
SAFEARRAYBOUND sab[1];
sab[0].cElements = 1;
sab[0].lLbound = 0;
LONG i = 0; // index needed for SafeArrayPutElement()
// var1 is the array that holds one element which is IP
VARIANT var1;
var1.vt = VT_ARRAY | VT_BSTR;
var1.parray = SafeArrayCreate(VT_BSTR, 1, sab); // create the array
SafeArrayPutElement(var1.parray, &i, IP); // put IP in the array
at pos 0
// var2 is the array that holds one element which is SM
VARIANT var2;
var2.vt = VT_ARRAY | VT_BSTR;
var2.parray = SafeArrayCreate(VT_BSTR, 1, sab); // create the array
SafeArrayPutElement(var2.parray, &i, SM); // put SM in the array
at pos 0
// put the ArgName and the Argument itself into the Method instance we
have
hr = pInInst->Put(ArgNameIP, 0, &var1, 0);
VariantClear(&var1);
hr = pInInst->Put(ArgNameSM, 0, &var2, 0);
VariantClear(&var2);
// Enumerate the instances of the NetworkAdapter to get at the __PATH
property
// to the one and only network card we really want to modify
IEnumWbemClassObject* pEnum;
hr = pNamespace->CreateInstanceEnum(className,
WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
NULL, &pEnum);
// Get the instance
ULONG numRet;
BSTR PropName;
VARIANT desc;
VARIANT dhcp;
VARIANT ipEnabled;
VARIANT pathVar;
IWbemClassObject *pInstance;
while ( hr != WBEM_S_FALSE)
{
hr = pEnum->Next(WBEM_INFINITE, (ULONG)1, &pInstance, &numRet);
if(0 == numRet)
break;
// we know that the one with DHCP is the one we want
PropName = SysAllocString(L"DHCPEnabled");
pInstance->Get(PropName, 0, &dhcp, 0, 0);
if (dhcp.bVal)
{
SysFreeString(PropName);
PropName = SysAllocString(L"IPEnabled");
pInstance->Get(PropName, 0, &ipEnabled, 0, 0);
SysFreeString(PropName);
if(ipEnabled.bVal)
{
// Print out the description just for us to see
SysFreeString(PropName);
PropName = SysAllocString(L"Description");
pInstance->Get(PropName, 0, &desc, 0, 0);
SysFreeString(PropName);
break;
}
}
SysFreeString(PropName);
}
// now we have the instance of the actual network card we want to modify
// let's query it's PATH property so that we can call the method on it.
PropName = SysAllocString(L"__PATH");
pInstance->Get(PropName, 0, &pathVar, 0, 0);
BSTR InstancePath = pathVar.bstrVal;
// finally we get to call the actuall method we want (EnableStatic())
hr = pNamespace->ExecMethod(InstancePath, methodName, 0, NULL,
pInInst, &pOutInst, NULL);
long ret = 0;
if(hr != WBEM_S_NO_ERROR)
{
BSTR Text;
hr = pOutInst->GetObjectText(0, &Text);
// CString strText = Text;
// MessageBox(strText);
}
else
{
// Get the EnableStatic method return value
VARIANT ret_value;
BSTR strReturnValue = SysAllocString(L"ReturnValue");
hr = pOutInst->Get(strReturnValue, 0, &ret_value, 0, 0);
long ret = V_I4(&ret_value);
}
// We're done!
// Free up resources
SysFreeString(className);
SysFreeString(methodName);
SysFreeString(namespacePath);
SysFreeString(ArgNameIP);
SysFreeString(ArgNameSM);
SysFreeString(IP);
SysFreeString(SM);
SysFreeString(PropName);
SysFreeString(InstancePath);
pLocator->Release();
pClass->Release();
pMethod->Release();
pNamespace->Release();
pInInst->Release();
pOutInst->Release();
pEnum->Release();
pInstance->Release();
CoUninitialize();
return ret;
}