in LCM/dsc/engine/ca/CAInfrastructure/CAEngine.c [1321:1631]
MI_Result Exec_WMIv2Provider(_In_ ProviderCallbackContext *provContext,
_In_ MI_Application *miApp,
_In_ MI_Session *miSession,
_In_ MI_Instance *instance,
_In_ const MI_Instance *regInstance,
_In_ MI_Uint32 flags,
_Inout_ MI_Uint32 *resultStatus,
_Inout_ MI_Boolean* canceled,
_Outptr_result_maybenull_ ResourceErrorList *resourceErrorList,
_Outptr_result_maybenull_ MI_Instance **extendedError)
{
MI_Result r = MI_RESULT_OK;
MI_Result result = MI_RESULT_OK;
const MI_Char *provNamespace = NULL;
MI_Operation operation = MI_OPERATION_NULL;
MI_Instance *params = NULL;
MI_Value value;
MI_Value valueOperationOptions;
MI_Boolean bTestResult = MI_TRUE;
MI_Uint64 outProviderContext = 0;
MI_Uint32 returnValue = 0;
MI_OperationCallbacks callbacks = MI_OPERATIONCALLBACKS_NULL;
MI_Real64 duration;
MI_OperationOptions sessionOptions;
const MI_Char * instanceNamespace;
ptrdiff_t start,finish;
//we don't have reginstance for meta configuration
if (Tcscasecmp(instance->classDecl->name, METACONFIG_CLASSNAME) == 0)
{
instanceNamespace = MI_T("");
}
else
{
instanceNamespace = regInstance->nameSpace;
}
//Debug Log
DSC_EventWriteEngineMethodParameters(__WFUNCTION__,
instance->classDecl->name,
provContext->resourceId,
flags,
provContext->lcmProviderContext->executionMode,
instanceNamespace);
DSC_EventWriteMessageExecutingWMI(instance->classDecl->name,provContext->resourceId);
callbacks.writeMessage = DoWriteMessage;
/* Sign up for progress only if we are in online mode*/
if ((LCM_EXECUTIONMODE_ONLINE & provContext->lcmProviderContext->executionMode) == LCM_EXECUTIONMODE_ONLINE)
{
callbacks.writeProgress = DoWriteProgress;
}
/* Sign up for promptuser only if we are asked to do so.*/
if ((LCM_SETFLAGS_ENABLEWHATIF & flags) == LCM_SETFLAGS_ENABLEWHATIF)
{
callbacks.promptUser = DoPromptUser;
}
callbacks.callbackContext = (void *)(provContext);
if (extendedError == NULL)
{
return MI_RESULT_INVALID_PARAMETER;
}
*extendedError = NULL; // Explicitly set *extendedError to NULL as _Outptr_ requires setting this at least once.
*canceled = MI_FALSE;
if (g_CancelConfiguration)
{
*canceled = MI_TRUE;
return MI_RESULT_FAILED;
}
// If the input MI_Instance is a MSFT_LogResource then directly log the message using LCM log API's
if (Tcscasecmp(instance->classDecl->name, LOGRESOURCE_CLASSNAME) == 0)
{
MI_Value value;
const MI_Char *message = NULL;
//Start timer for Set
start=CPU_GetTimeStamp();
//Starting Test
SetMessageInContext(ID_OUTPUT_OPERATION_START,ID_OUTPUT_ITEM_TEST,provContext->lcmProviderContext);
LogCAMessage(provContext->lcmProviderContext, ID_OUTPUT_EMPTYSTRING, provContext->resourceId);
r = MI_Instance_GetElement(instance, LOGRESOURCE_MESSAGEPROPERTYNAME, &value, NULL, NULL, NULL);
if (r != MI_RESULT_OK)
{
return GetCimMIError(r, extendedError,ID_CAINFRA_GET_LOGRESOURCE_FAILED);
}
message = value.string;
//Stop the timer for test
finish=CPU_GetTimeStamp();
duration = (MI_Real64)(finish- start) / TIME_PER_SECONND;
SetMessageInContext(ID_OUTPUT_OPERATION_END,ID_OUTPUT_ITEM_TEST,provContext->lcmProviderContext);
LogCAMessageTime(provContext->lcmProviderContext, ID_CA_TEST_TIMEMESSAGE, (const MI_Real64)duration,provContext->resourceId);
if (!(flags & LCM_EXECUTE_TESTONLY))
{
//Start timer for Set
start=CPU_GetTimeStamp();
SetMessageInContext(ID_OUTPUT_OPERATION_START,ID_OUTPUT_ITEM_SET,provContext->lcmProviderContext);
LogCAMessage(provContext->lcmProviderContext, ID_OUTPUT_EMPTYSTRING, provContext->resourceId);
LCM_WriteMessageFromProvider(provContext->lcmProviderContext, provContext->resourceId, MI_WRITEMESSAGE_CHANNEL_VERBOSE, message);
//Stop the timer for set
finish=CPU_GetTimeStamp();
duration = (MI_Real64)(finish- start) / TIME_PER_SECONND;
SetMessageInContext(ID_OUTPUT_OPERATION_END,ID_OUTPUT_ITEM_SET,provContext->lcmProviderContext);
LogCAMessageTime(provContext->lcmProviderContext, ID_CA_SET_TIMEMESSAGE, (const MI_Real64)duration,provContext->resourceId);
}
}
// If the input is a meta configuration then invoke LCM's API directly
else if (Tcscasecmp(instance->classDecl->name, METACONFIG_CLASSNAME) == 0 && !( flags & LCM_EXECUTE_TESTONLY ))
{
//Start timer for Set
start=CPU_GetTimeStamp();
//meta configuration is always explicitly get invoked so no need to test before set.
SetMessageInContext(ID_OUTPUT_OPERATION_START,ID_OUTPUT_ITEM_SET,provContext->lcmProviderContext);
LogCAMessage(provContext->lcmProviderContext, ID_OUTPUT_EMPTYSTRING, provContext->resourceId);
r = SetMetaConfig(instance, extendedError);
//Stop the timer for set
finish=CPU_GetTimeStamp();
duration = (MI_Real64)(finish- start) / TIME_PER_SECONND;
SetMessageInContext(ID_OUTPUT_OPERATION_END,ID_OUTPUT_ITEM_SET,provContext->lcmProviderContext);
LogCAMessageTime(provContext->lcmProviderContext, ID_CA_SET_TIMEMESSAGE, (const MI_Real64)duration,provContext->resourceId);
if(r == MI_RESULT_OK)
{
result = RegisterStandardTasks(extendedError);
}
}
else
{
/*Get target namespace*/
r = DSC_MI_Instance_GetElement(regInstance, MSFT_CimConfigurationProviderRegistration_Namespace, &value, NULL, NULL, NULL);
if (r != MI_RESULT_OK)
{
return GetCimMIError(r, extendedError,ID_CAINFRA_GET_NAMESPACE_FAILED);
}
provNamespace = value.string;
/*Set input parameters*/
r = DSC_MI_Application_NewInstance(miApp, MI_T("__Parameters"), NULL, ¶ms);
if (r != MI_RESULT_OK)
{
return GetCimMIError(r, extendedError,ID_CAINFRA_GET_NEWAPPLICATIONINSTANCE_FAILED);
}
value.instance = instance;
r = DSC_MI_Instance_AddElement(params, OMI_BaseResource_Method_InputResource, &value, MI_INSTANCE, 0 );
if (r != MI_RESULT_OK)
{
MI_Instance_Delete(params);
return GetCimMIError(r, extendedError,ID_CAINFRA_GET_ADDELEM_FAILED);
}
r = MI_Application_NewOperationOptions(miApp, MI_FALSE, &sessionOptions);
if( r != MI_RESULT_OK )
{
return GetCimMIError(r, extendedError,ID_CAINFRA_GET_NEWOPERATIONOPTIONS_FAILED);
}
valueOperationOptions.string=g_ConfigurationDetails.jobGuidString;
r =MI_OperationOptions_SetCustomOption(&sessionOptions,DSC_JOBIDSTRING,MI_STRING,&valueOperationOptions,MI_FALSE);
if( r != MI_RESULT_OK)
{
MI_OperationOptions_Delete(&sessionOptions);
return GetCimMIError(r, extendedError,ID_CAINFRA_GET_SETCUSTOMOPTION_FAILED);
}
if(r!=MI_RESULT_OK)
{
//INCHTODO: Say setcustomoptionfailed
return GetCimMIError(r, extendedError,ID_CAINFRA_GET_ADDELEM_FAILED);
}
/* Perform Test*/
//Start timer for test
start=CPU_GetTimeStamp();
DSC_EventWriteMessageInvokingSession(provNamespace,instance->classDecl->name,OMI_BaseResource_TestMethodName);
SetMessageInContext(ID_OUTPUT_OPERATION_START,ID_OUTPUT_ITEM_TEST,provContext->lcmProviderContext);
LogCAMessage(provContext->lcmProviderContext, ID_OUTPUT_EMPTYSTRING, provContext->resourceId);
RecursiveLock_Acquire(&g_cs_CurrentWmiv2Operation);
MI_Session_Invoke(miSession, 0, &sessionOptions, provNamespace,
instance->classDecl->name, OMI_BaseResource_TestMethodName,
NULL, params, &callbacks,&operation);
g_CurrentWmiv2Operation = &operation;
RecursiveLock_Release(&g_cs_CurrentWmiv2Operation);
r = GetTestMethodResult(&operation, &bTestResult, &outProviderContext, extendedError);
RecursiveLock_Acquire(&g_cs_CurrentWmiv2Operation);
g_CurrentWmiv2Operation = NULL;
MI_Operation_Close(&operation);
RecursiveLock_Release(&g_cs_CurrentWmiv2Operation);
if (r != MI_RESULT_OK)
{
MI_Instance_Delete(params);
MI_OperationOptions_Delete(&sessionOptions);
AddToResourceErrorList(resourceErrorList, provContext->resourceId);
Destroy_StatusReport_RNIDS(g_rnids);
g_rnids = Construct_StatusReport_RNIDS(GetSourceInfo(instance), GetModuleName(instance), "0", provContext->resourceId, "0", instance->classDecl->name, GetModuleVersion(instance), "False", provContext->resourceId, "", "False");
return r;
}
//Stop the timer for test
finish=CPU_GetTimeStamp();
duration = (MI_Real64)(finish- start) / TIME_PER_SECONND;
SetMessageInContext(ID_OUTPUT_OPERATION_END,ID_OUTPUT_ITEM_TEST,provContext->lcmProviderContext);
LogCAMessageTime(provContext->lcmProviderContext, ID_CA_TEST_TIMEMESSAGE, (const MI_Real64)duration,provContext->resourceId);
/* Skip rest of the operation if we were asked just to test.*/
if (flags & LCM_EXECUTE_TESTONLY)
{
if(bTestResult == MI_TRUE)
{
*resultStatus = 1;
}
else
{
*resultStatus = 0;
Destroy_StatusReport_RNIDS(g_rnids);
g_rnids = Construct_StatusReport_RNIDS(GetSourceInfo(instance), GetModuleName(instance), "0", provContext->resourceId, "0", instance->classDecl->name, GetModuleVersion(instance), "False", provContext->resourceId, "", "False");
}
MI_Instance_Delete(params);
MI_OperationOptions_Delete(&sessionOptions);
return MI_RESULT_OK;
}
/* Perform Set if value returned is FALSE*/
if( bTestResult == MI_TRUE)
{
SetMessageInContext(ID_OUTPUT_OPERATION_SKIP,ID_OUTPUT_ITEM_SET,provContext->lcmProviderContext);
LogCAMessage(provContext->lcmProviderContext, ID_OUTPUT_EMPTYSTRING, provContext->resourceId);
MI_Instance_Delete(params);
MI_OperationOptions_Delete(&sessionOptions);
return MI_RESULT_OK;
}
if (g_CancelConfiguration)
{
*canceled = MI_TRUE;
MI_Instance_Delete(params);
MI_OperationOptions_Delete(&sessionOptions);
return MI_RESULT_FAILED;
}
/* Add outProviderContext to the params*/
value.uint64 = outProviderContext;
r = DSC_MI_Instance_AddElement(params, OMI_BaseResource_Method_ProviderContext, &value, MI_UINT64, 0 );
if (r != MI_RESULT_OK)
{
MI_Instance_Delete(params);
MI_OperationOptions_Delete(&sessionOptions);
return GetCimMIError(r, extendedError,ID_CAINFRA_GET_ADDELEM_FAILED);
}
/* Perform Set*/
//Start timer for set
start=CPU_GetTimeStamp();
SetMessageInContext(ID_OUTPUT_OPERATION_START,ID_OUTPUT_ITEM_SET,provContext->lcmProviderContext);
LogCAMessage(provContext->lcmProviderContext, ID_OUTPUT_EMPTYSTRING, provContext->resourceId);
DSC_EventWriteMessageInvokingSession(provNamespace,instance->classDecl->name,OMI_BaseResource_SetMethodName);
RecursiveLock_Acquire(&g_cs_CurrentWmiv2Operation);
memset(&operation, 0, sizeof(MI_Operation));
MI_Session_Invoke(miSession, 0, &sessionOptions, provNamespace,
instance->classDecl->name, OMI_BaseResource_SetMethodName,
NULL, params, &callbacks,&operation);
g_CurrentWmiv2Operation = &operation;
RecursiveLock_Release(&g_cs_CurrentWmiv2Operation);
r = GetSetMethodResult(&operation, &returnValue, provContext->resourceId, extendedError);
MI_Instance_Delete(params);
RecursiveLock_Acquire(&g_cs_CurrentWmiv2Operation);
g_CurrentWmiv2Operation = NULL;
MI_Operation_Close(&operation);
RecursiveLock_Release(&g_cs_CurrentWmiv2Operation);
if (r != MI_RESULT_OK)
{
MI_OperationOptions_Delete(&sessionOptions);
AddToResourceErrorList(resourceErrorList, provContext->resourceId);
Destroy_StatusReport_RNIDS(g_rnids);
g_rnids = Construct_StatusReport_RNIDS(GetSourceInfo(instance), GetModuleName(instance), "0", provContext->resourceId, NULL, instance->classDecl->name, GetModuleVersion(instance), "False", provContext->resourceId, "", "False");
return r;
}
*resultStatus = returnValue;
if (returnValue != MI_TRUE)
{
Destroy_StatusReport_RNIDS(g_rnids);
g_rnids = Construct_StatusReport_RNIDS(GetSourceInfo(instance), GetModuleName(instance), "0", provContext->resourceId, NULL, instance->classDecl->name, GetModuleVersion(instance), "False", provContext->resourceId, "", "False");
}
//Stop the timer for set
finish=CPU_GetTimeStamp();
duration = (MI_Real64)(finish- start) / TIME_PER_SECONND;
SetMessageInContext(ID_OUTPUT_OPERATION_END,ID_OUTPUT_ITEM_SET,provContext->lcmProviderContext);
LogCAMessageTime(provContext->lcmProviderContext, ID_CA_SET_TIMEMESSAGE, (const MI_Real64)duration,provContext->resourceId);
MI_OperationOptions_Delete(&sessionOptions);
}
//Debug Log
DSC_EventWriteMethodEnd(__WFUNCTION__);
return r;
}