Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

WMI Methods in C++

314 views
Skip to first unread message

luke_21

unread,
Mar 1, 2007, 4:08:44 AM3/1/07
to
Hi,

I'd like to remotely set a value in Registry, using WMI methods as
StdRegProv:SetStringValue for example.
I tried using MSDN example, Method execution is correct, but
SetStringValue return me code errors I can't analyse or understand. Is
somebody could help me to understand what i am doing wrong ?

IWbemLocator *ppiWmiLoc = NULL;

hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *) &ppiWmiLoc);


IWbemServices *pSvc = NULL;
CComBSTR bstrserv(L"\\\\RemoteComputer\\root\\default");
CComBSTR bstrUsername(m_csUserName), bstrPassword(m_csPassword);

hres = ppiWmiLoc->ConnectServer(bstrserv, NULL, NULL,0, NULL, 0, 0,
&pSvc);
//AfficheErreur(hres);

BSTR MethodName = SysAllocString(L"SetStringValue");
BSTR ClassName = SysAllocString(L"StdRegProv");

IWbemClassObject* pClass = NULL;
hres = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL);

IWbemClassObject* pInParamsDefinition = NULL;
hres = pClass->GetMethod(MethodName, 0,
&pInParamsDefinition, NULL);

IWbemClassObject* pClassInstance = NULL;
hres = pInParamsDefinition->SpawnInstance(0, &pClassInstance);


// Create the values for the in parameters
VARIANT varCommand;
varCommand.vt = VT_BSTR;
varCommand.bstrVal = L"SOFTWARE\\Computer\\Luke";

// Store the value for the in parameters
hres = pClassInstance->Put(L"sSubKeyName", 0,
&varCommand, 0);

// Create the values for the in parameters

varCommand.vt = VT_BSTR;
varCommand.bstrVal = L"str";

// Store the value for the in parameters
hres = pClassInstance->Put(L"sValueName", 0,
&varCommand, 0);

// Create the values for the in parameters

varCommand.vt = VT_BSTR;
varCommand.bstrVal = L"toto";

// Store the value for the in parameters
hres = pClassInstance->Put(L"sValue", 0,
&varCommand, 0);

// Execute Method
IWbemClassObject* pOutParams = NULL;
hres = pSvc->ExecMethod(ClassName, MethodName, 0,
NULL, pClassInstance, &pOutParams, NULL);

if (FAILED(hres))
{
MessageBox("Command Failed","SetStringValue",MB_OK);
/* VariantClear(&varCommand);
SysFreeString(ClassName);
SysFreeString(MethodName);
pClass->Release();
pInParamsDefinition->Release();
pOutParams->Release();
pSvc->Release();*/
}
else
{
VARIANT varReturnValue;
CComBSTR bstrret(L"ReturnValue");
BSTR ret;
hres = pOutParams->GetObjectText(0, &ret);
char mess[MAX_PATH];
wsprintf(mess,"%S",ret);
MessageBox(mess,"Error message",MB_OK);
/*hres = pOutParams->Get(bstrret, 0, &varReturnValue, NULL, 0);
SHORT toto = varReturnValue.iVal;*/

luke_21

unread,
Mar 1, 2007, 4:19:29 AM3/1/07
to
For example for that code, I have no error about the execution of
Method, but I have Error code 1346 as Returned Value from
SetStringValue function.
It says that : Either a required impersonation level was not provided,
or the provided impersonation level is invalid. But can't understand
what that could say ....

Chris Richards

unread,
Mar 4, 2007, 7:00:42 PM3/4/07
to
You have to set your impersonation level before you can make calls to
WMI. After you call:

hres = ppiWmiLoc->ConnectServer(bstrserv, NULL, NULL, 0, NULL, 0, 0, &pSvc)

You need to call:

hRes = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);

That should get you fixed up (I hope).

Later,
Chris

luke_21

unread,
Mar 5, 2007, 3:32:41 AM3/5/07
to
> > what that could say ....- Masquer le texte des messages précédents -
>
> - Afficher le texte des messages précédents -

That works perfectly !!!!
Thank you very much.
I found no code that describe that, very few examples in C++.

luke_21

unread,
Mar 5, 2007, 5:58:26 AM3/5/07
to
Well,

I have another problem, using SetDWORDValue method.

As I had :

// Create the values for the in parameters


varCommand.vt = VT_BSTR;
varCommand.bstrVal = L"toto";


// Store the value for the in parameters
hres = pClassInstance->Put(L"sValue", 0,
&varCommand, 0);

I'd like to set "lValue" of SetDWORDValue method to 0 or 1. But can't
find type of variant to set it ... I tried VT_UINT, VT_I8 and so
on ... but I got always same -2147217403 error ....


varCommand.vt = VT_UINT;
varCommand.uintVal = 1;


// Store the value for the in parameters

hres = pClassInstance->Put(L"lValue", 0,
&varCommand, 0);


Need some help again...


On 5 mar, 01:00, Chris Richards <g...@aoaforums.com> wrote:

Chris Richards

unread,
Mar 5, 2007, 9:26:21 AM3/5/07
to
I haven't played with this, but I suspect that if you call the
SetDWORDValue method, you need to actually pass a DWORD, not a variant.

Later,
Chris

luke_21

unread,
Mar 5, 2007, 9:56:36 AM3/5/07
to
Yes, you're right but pClassInstance->Put function needs a Variant. So
I have to pass a dword, but by the variant. As I passed my string
value by Variant : var.vt = VT_BSTR and then var.bstrval =
L"MyVariant"; Do you know what I mean ? I have to find the exact type
I have to use and the exact format I have to use for my DWORD value.

IWbemClassObject* pClassInstance;

HRESULT Put(
LPCWSTR wszName,
LONG lFlags,
VARIANT* pVal,
CIMTYPE vtType
);

> >> - Afficher le texte des messages précédents -- Masquer le texte des messages précédents -

Chris Richards

unread,
Mar 8, 2007, 5:21:36 PM3/8/07
to
Ah, I think I understand now.

Have you tried setting the value into the variant as a BSTR? I've
noticed that some of the WMI classes are documented as returning int32
or something like that, but in fact return an int32 value EXPRESS AS A
STRING.

That being the case, it is not beyond the realm of reason that it might
be expecting the DWORD value expressed as a string in the BSTR element.

Just a thought.

Later,
Chris

0 new messages