Sunday, April 22, 2018

(WMI) ExecMethod out parameter - ResultingSnapshot is NULL irrespective of the result of the call, Why?

Leave a Comment

I am using WMI to create an RCT Checkpoint. Below is the code snippet. The problem is when I call the method Create Snapshot using ExecMethodthe checkpoint gets created but the ResultingSnapshot to still points to NULL.

Since the call is asynchronous (as the return value from pOutParameters is 4096) I have also waited till the job gets completed in WaitForJobCompletion but pOutParameters is not updated and still, the ResultingSnapshot is NULL.

Basically, I need this ResultingSnapshot for creating a reference point. If there is any other way to do it, I can write it, need guidance though.

I am new to WMI, any help or lead is appreciated.

HRESULT hr; CComPtr<IWbemClassObject> pInParams; CComPtr<IWbemClassObject> pOutParameters; IWbemCallResult *pResult = 0;  // Set Method Paramters this->GetMethodParams(L"Msvm_VirtualSystemSnapshotService", L"CreateSnapshot", &pInParams);  IWbemClassObject * pVirtualSystemSnaphotSettingData = NULL; hr = m_pWbemServices->GetObject(L"Msvm_VirtualSystemSnapshotSettingData", 0, NULL, &pVirtualSystemSnaphotSettingData, &pResult);  IWbemClassObject * pInpInstOfSnapshotSettingData = NULL; hr = pVirtualSystemSnaphotSettingData->SpawnInstance(0, &pInpInstOfSnapshotSettingData);  VARIANT consistencyLevel; VariantInit(&consistencyLevel); V_VT(&consistencyLevel) = VT_BSTR; V_BSTR(&consistencyLevel) = SysAllocString(L"1"); hr = pInpInstOfSnapshotSettingData->Put(L"ConsistencyLevel", 0, &consistencyLevel, 0); VariantClear(&consistencyLevel);  VARIANT elementName; VariantInit(&elementName); V_VT(&elementName) = VT_BSTR; V_BSTR(&elementName) = SysAllocString(L"rhel-1"); hr = pInpInstOfSnapshotSettingData->Put(L"ElementName", 0, &elementName, 0); VariantClear(&elementName);  hr = m_pWbemServices->PutInstance(pInpInstOfSnapshotSettingData, 0, NULL, &pResult);  BSTR objString = NULL; hr = pInpInstOfSnapshotSettingData->GetObjectText(0, &objString); BSTR ArgNameTwo = SysAllocString(L"SnapshotSettings"); VARIANT v; V_VT(&v) = VT_BSTR; V_BSTR(&v) = objString;   hr = pInParams->Put(ArgNameTwo, 0, &v, 0);  VARIANT vtProp; m_pVmWbemClassObject->Get(L"__Path", 0, &vtProp, 0, 0);  wprintf(L"Affected System : : %ls", (LPWSTR)vtProp.bstrVal); HRESULT hres = pInParams->Put(L"AffectedSystem", 0 , &vtProp, NULL);  VARIANT var; VariantInit(&var); V_VT(&var) = VT_BSTR; V_BSTR(&var) = SysAllocString(L"2");   CHK_HRES(pInParams->Put(L"SnapshotType", 0, &var, 0));   IEnumWbemClassObject* pEnumOb = NULL; hr = m_pWbemServices->ExecQuery( BSTR(L"WQL"), BSTR(L"select * from Msvm_VirtualSystemSnapshotService"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumOb); IWbemClassObject *pclsObj1 = NULL; ULONG uReturn1 = 0;  while (1) {     HRESULT hr = pEnumOb->Next(WBEM_INFINITE, 1, &pclsObj1, &uReturn1);      if (0 == uReturn1)     {         break;     }      IWbemCallResult *pCallResult = NULL;     IWbemClassObject *pResObj = NULL;      CComBSTR path(this->GetStrProperty(L"__PATH", pclsObj1));      hr = m_pWbemServices->ExecMethod(path, L"CreateSnapshot", 0, NULL, pInParams, &pOutParameters, &pCallResult);        /* cout << "check1 : " << hex << hr << endl;     hr = pCallResult->GetResultObject(0, &pResObj);     cout << "check2" << endl;*/      this->WaitForJobCompletion(pOutParameters);    }  cout << "\nSnpshot Complete" << endl; } 

EDIT I found that the SnapshotType Parameter is not set correctly it should be 32768 and I have used the following way to convert uint16 to Variant but no Success and I get 0x80070057 Incorrect Parameter Error.

VARIANT var; VariantInit(&var); V_VT(&var) = VT_BSTR; V_BSTR(&var) = SysAllocString(L"32768");  hr = pInParams->Put(L"SnapshotType", 0, &var, CIM_UINT16); 

1 Answers

Answers 1

You provide a ppCallResult parameter. From the documentation:

ppCallResult [out] If NULL, this is not used. If ppCallResult is specified, it must be set to point to NULL on entry. In this case, the call returns immediately with WBEM_S_NO_ERROR. The ppCallResult parameter receives a pointer to a new IWbemCallResult object, which must be polled to obtain the result of the method execution using the GetCallStatus method. The out parameters for the call are available by calling IWbemCallResult::GetResultObject.

Therefore you need to use GetCallStatus on pCallResult until the method has finished and then GetResultObject to get the out parameters:

LONG status; while ((hr = pCallResult->GetCallStatus(1000, &status)) == WBEM_S_TIMEDOUT); /* check hr and status here */ hr = pCallResult->GetResultObject(0, &pResObj); 

or use WBEM_INFINITE:

LONG status; hr = pCallResult->GetCallStatus(WBEM_INFINITE, &status); /* check hr and status here */ hr = pCallResult->GetResultObject(0, &pResObj); 

Alternatively provide NULL instead of pCallResult and it will be a synchronous call where pOutParameters will be set:

hr = m_pWbemServices->ExecMethod(path, L"CreateSnapshot", 0, NULL, pInParams, &pOutParameters, NULL); 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment