SetIP,SetDns和SetGate三个成员函除均是通过C++调用WMI组件中对应的方法实现的,其实现基本类似,这里仅以SetIP作简要说明,源码如下:
void CWMI::SetIP(LPWSTR IPAddress,LPWSTR SubnetMask){
setIndexByAdapterName();
EnableStatic(IPAddress,SubnetMask);
}
setIndexByAdapterName是CWMI类实现的成员函数,实现了对当前主机的网络适配器的选择操作。
EnableStatic成员函数是对WMI中Win32_NetworkAdapterConfiguration类中EnanleStatic方法的封装,源代码如下:
HRESULT CWMI::EnableStatic(LPWSTR IPAddress,LPWSTR SubnetMask){
ULONG Status=0;
NetWorkResource = SysAllocString(L"root\\cimv2");
WCHAR AdapterIndex[128];
wsprintf(AdapterIndex,
L"Win32_NetworkAdapterConfiguration=%ld",index);
InstancePath = SysAllocString(AdapterIndex);
ClassPath = SysAllocString(L"Win32_NetworkAdapterConfiguration");
MethodName = SysAllocString(L"EnableStatic");
LPCWSTR Arg1Name = L"IPAddress";
VARIANT var1;
LPCWSTR Arg2Name = L"SubnetMask";
VARIANT var2;
hr = CoInitializeEx(NULL,COINIT_MULTITHREADED);
if(FAILED(hr)){
MessageBox(NULL,L"CoInitializeEx",L"Error",MB_OK);
Clean();
return hr;
}
CreateOneElementBstrArray(&var1,IPAddress);
CreateOneElementBstrArray(&var2,SubnetMask);
CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (void**)&pLocator);
hr = pLocator->ConnectServer(NetWorkResource,NULL, NULL, NULL, 0, NULL, NULL,
&pNamespace);
hr = CoSetProxyBlanket(pNamespace,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE);
if(FAILED(hr)) { Clean();MessageBox(NULL,L"CoSetProxyBlanket",L"Error",MB_OK); return hr; }
else
hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
if(FAILED(hr)){Clean();MessageBox(NULL,L"GetObject",L"Error",MB_OK);return hr; }
else
hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
if(FAILED(hr)){ Clean();MessageBox(NULL,L"GetMethod",L"Error",MB_OK);return hr; }
else
hr = pInClass->SpawnInstance(0, &pInInst);
if(FAILED(hr)) { Clean();MessageBox(NULL,L"SpawnInstance",L"Error",MB_OK);return hr; }
else
hr = pInInst->Put(Arg1Name, 0, &var1, 0);
if(FAILED(hr)){ Clean();MessageBox(NULL,L"Put",L"Error",MB_OK);return hr; }
else
hr = pInInst->Put(Arg2Name, 0, &var2, 0);
if(FAILED(hr)){ Clean();return hr; }
else{
VARIANT resultParameter;
ULONG Status;
hr = pNamespace->ExecMethod(InstancePath, MethodName, 0, NULL,
pInInst, &pOutInst, NULL);
if(SUCCEEDED(pOutInst->Get(L"ReturnValue",0,&resultParameter,NULL,NULL))){
Status = resultParameter.ulVal;
VariantClear(&resultParameter);
TRACE1("返回值:%lu\n",Status);
}
else{
TRACE0("参数未能获得");
MessageBox(NULL,L"ExecMethod",L"Error",MB_OK);
}
}
VariantClear(&var1);
VariantClear(&var2);
Clean();
return Status;
}
其中CreateOneElementBstrArray是CWMI类的成员函数,实现了封装一个BSTR数组,代码如下:
void CWMI::CreateOneElementBstrArray(VARIANT* v, LPCWSTR s){
SAFEARRAYBOUND bound[1];
SAFEARRAY* array;
bound[0].lLbound = 0;
bound[0].cElements = 1;
array = SafeArrayCreate(VT_BSTR, 1, bound);
long Index = 0;
BSTR bstr = SysAllocString(s);
SafeArrayPutElement(array, &Index, bstr);
SysFreeString(bstr);
VariantInit(v);
v->vt = VT_BSTR | VT_ARRAY;
v->parray = array;
}
3.设计技巧
使用WMI测试程序进行WMI测试,Windows Management Instrumentation(WMI)测试程序,也叫做WBEMTest,是一个在Windows Management Instrumentation(WMI)服务程序和WMI应用程序开发期间,用于查看和更改公共信息模型(Common Information Model,CIM)类、实例和方法的常规工具。
|