in LCM/dsc/engine/ConfigurationManager/LocalConfigManagerHelper.c [1775:2062]
MI_Result SetConfiguration(
_In_reads_bytes_(dataSize) const MI_Uint8* ConfigData,
MI_Uint32 dataSize,
MI_Boolean force,
_In_ LCMProviderContext *lcmContext,
MI_Uint32 dwFlags,
_Outptr_result_maybenull_ MI_Instance **cimErrorDetails)
{
MI_Result result = MI_RESULT_OK;
MI_Result deleteResult = MI_RESULT_OK;
ModuleManager *moduleManager = NULL;
MSFT_DSCMetaConfiguration *metaConfigInstance = NULL;
MI_Value value;
MI_Uint32 flags;
MI_Uint32 resultStatus = 0;
MI_Char *partialConfigFileDataStoreLocation = NULL;
//Debug Log
DSC_EventWriteLocalConfigMethodParameters(__WFUNCTION__,dataSize,dwFlags,lcmContext->executionMode);
if (cimErrorDetails == NULL)
{
return MI_RESULT_INVALID_PARAMETER;
}
*cimErrorDetails = NULL; // Explicitly set *cimErrorDetails to NULL as _Outptr_ requires setting this at least once.
result = ValidateConfigurationDirectory(cimErrorDetails);
if (result != MI_RESULT_OK)
{
if (cimErrorDetails && *cimErrorDetails)
{
return result;
}
return GetCimMIError(result, cimErrorDetails, ID_LCMHELPER_VALIDATE_CONFGDIR_FAILED);
}
result = InitializeModuleManager(0, cimErrorDetails, &moduleManager);
if (result != MI_RESULT_OK)
{
return result;
}
if (moduleManager == NULL)
{
return GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, cimErrorDetails, ID_ENGINEHELPER_MEMORY_ERROR);
}
result = GetMetaConfig((MSFT_DSCMetaConfiguration **)&metaConfigInstance);
if (result != MI_RESULT_OK)
{
moduleManager->ft->Close(moduleManager, NULL);
return GetCimMIError(result, cimErrorDetails, ID_LCM_FAILED_TO_GET_METACONFIGURATION);
}
result = MI_Instance_GetElement((MI_Instance*)metaConfigInstance, MSFT_DSCMetaConfiguration_RefreshMode, &value, NULL, &flags, NULL);
if (result != MI_RESULT_OK)
{
MI_Instance_Delete((MI_Instance *)metaConfigInstance);
moduleManager->ft->Close(moduleManager, NULL);
return GetCimMIError(result, cimErrorDetails, ID_LCM_FAILED_TO_GET_METACONFIGURATION);
}
if (flags & MI_FLAG_NULL)
{
value.string = METADATA_REFRESHMODE_PUSH;
}
if (Tcscasecmp(value.string , METADATA_REFRESHMODE_PULL) == 0)
{
/* Force converts the PULL to a PUSH otherwise PULL cannot convert to PUSH */
if (force == MI_TRUE)
{
value.string = METADATA_REFRESHMODE_PUSH;
result = MI_Instance_SetElement((MI_Instance*)metaConfigInstance, MSFT_DSCMetaConfiguration_RefreshMode, &value, MI_STRING, 0);
if (result != MI_RESULT_OK)
{
MI_Instance_Delete((MI_Instance *)metaConfigInstance);
moduleManager->ft->Close(moduleManager, NULL);
return result;
}
result = SetMetaConfig((MI_Instance*)metaConfigInstance, cimErrorDetails);
if (result != MI_RESULT_OK)
{
MI_Instance_Delete((MI_Instance *)metaConfigInstance);
moduleManager->ft->Close(moduleManager, NULL);
return result;
}
}
else
{
MI_Instance_Delete((MI_Instance *)metaConfigInstance);
moduleManager->ft->Close(moduleManager, NULL);
return GetCimMIError(MI_RESULT_INVALID_PARAMETER, cimErrorDetails, ID_LCM_PUSH_REQUESTED_ON_PULL_WO_FORCE);
}
}
if (dwFlags & LCM_SET_METACONFIG)
{
MI_Instance_Delete((MI_Instance *)metaConfigInstance);
result = SaveFile(GetMetaConfigTmpFileName(), ConfigData, dataSize, cimErrorDetails);
if (result != MI_RESULT_OK)
{
moduleManager->ft->Close(moduleManager, NULL);
if (cimErrorDetails && *cimErrorDetails)
{
return result;
}
return GetCimMIError(MI_RESULT_ALREADY_EXISTS, cimErrorDetails, ID_LCMHELPER_SAVE_METATMP_ERROR);
}
dwFlags |= VALIDATE_METACONFIG_INSTANCE;
result = ApplyMetaConfig(lcmContext, moduleManager, dwFlags, &resultStatus, cimErrorDetails);
moduleManager->ft->Close(moduleManager, NULL);
deleteResult = RetryDeleteFile(GetMetaConfigTmpFileName());
if (result != MI_RESULT_OK)
{
return result;
}
if (deleteResult != MI_RESULT_OK)
{
return GetCimMIError(deleteResult, cimErrorDetails, ID_LCMHELPER_DEL_METATMPFILEAFTER_FAILED);
}
}
else
{
//If there's a partial configuration in the metaconfig, do not save as pending, save in data store instead.
if (ShouldUsePartialConfigurations((MI_Instance*)metaConfigInstance, MI_FALSE)) //Don't need to check if there are files in the partial config directory
{
//If it isn't a publishonly command, then this is not supported. Throw an error
if (!(dwFlags & LCM_SETFLAGS_SAVETOPENDINGONLY))
{
result = GetCimMIError(MI_RESULT_NOT_SUPPORTED, cimErrorDetails, ID_LCM_CANNOTUSE_PARTIALCONFIG_PUSHMODE_WITHOUTPUBLISH);
goto Cleanup;
}
DSC_EventWriteLCMIdentifiedModePartial();
//Save the partial config file into the data store.
result = GetPartialConfigStoreLocation(moduleManager, ConfigData, dataSize, cimErrorDetails, &partialConfigFileDataStoreLocation);
GOTO_CLEANUP_IF_FAILED(result, Cleanup);
//Store configFileName as path c:\windows\system32\configuration\partialconfigurations +_+ value.string + .mof
result = CheckAndSaveConfigDataIntoFile(partialConfigFileDataStoreLocation, ConfigData, dataSize, MI_TRUE, cimErrorDetails, ID_LCMHELPER_OLDCONFPENDING_ERROR, ID_LCMHELPER_SAVE_PENDING_ERROR);
//Note, you're passing force as true over here always because you want to delete the old existing partial configs no matter what. Check if this is okay , for now we go with this
GOTO_CLEANUP_IF_FAILED(result, Cleanup);
result = ValidatePartialConfiguration(moduleManager, partialConfigFileDataStoreLocation, (MI_Instance*) metaConfigInstance, cimErrorDetails);
GOTO_CLEANUP_IF_FAILED(result, Cleanup);
SetMessageInContext(ID_OUTPUT_OPERATION_END, ID_OUTPUT_ITEM_SET, lcmContext);
LCM_BuildMessage(lcmContext, ID_LCM_WRITEMESSAGE_SAVETOPARTIAL, EMPTY_STRING, MI_WRITEMESSAGE_CHANNEL_VERBOSE);
Cleanup:
moduleManager->ft->Close(moduleManager, NULL);
//If there was a failure, ensure the partial config file(if exists) is deleted.
if (result != MI_RESULT_OK && partialConfigFileDataStoreLocation != NULL)
{
RetryDeleteFile(partialConfigFileDataStoreLocation);
}
DSCFREE_IF_NOT_NULL(partialConfigFileDataStoreLocation);
}
else //Only in the case of no partial configuration should you save it in pending.mof and do pushdependency check.
{
// If Current.mof exists, move Current.mof to Previous.mof
if (File_ExistT(GetCurrentConfigFileName()) == 0)
{
result = CopyConfigAndRemoveSource(CONFIGURATION_LOCATION_CURRENT, CONFIGURATION_LOCATION_PREVIOUS, cimErrorDetails);
if (result != MI_RESULT_OK)
{
MI_Instance_Delete((MI_Instance *)metaConfigInstance);
moduleManager->ft->Close(moduleManager, NULL);
return result;
}
}
// If Pending.mof exists, throw an error if Force was not specified
if (File_ExistT(GetPendingConfigFileName()) != -1)
{
if (force == MI_TRUE)
{
deleteResult = RetryDeleteFile(GetPendingConfigFileName());
if (deleteResult != MI_RESULT_OK)
{
MI_Instance_Delete((MI_Instance *)metaConfigInstance);
moduleManager->ft->Close(moduleManager, NULL);
return GetCimMIError(deleteResult, cimErrorDetails, ID_LCMHELPER_OLDCONFPENDING_ERROR);
}
}
else
{
MI_Instance_Delete((MI_Instance *)metaConfigInstance);
moduleManager->ft->Close(moduleManager, NULL);
return GetCimMIError(MI_RESULT_ALREADY_EXISTS, cimErrorDetails, ID_LCMHELPER_OLDCONFPENDING_ERROR);
}
}
// Save the new configuration to Pending.mof
result = SaveFile(GetPendingConfigFileName(), ConfigData, dataSize, cimErrorDetails);
if ( result != MI_RESULT_OK)
{
MI_Instance_Delete((MI_Instance *)metaConfigInstance);
moduleManager->ft->Close(moduleManager, NULL);
if (cimErrorDetails && *cimErrorDetails)
{
return result;
}
return GetCimMIError(MI_RESULT_ALREADY_EXISTS, cimErrorDetails, ID_LCMHELPER_SAVE_PENDING_ERROR);
}
if (dwFlags & LCM_SETFLAGS_SAVETOPENDINGONLY )
{
LCM_BuildMessage(lcmContext, ID_LCM_WRITEMESSAGE_SAVETOPENDING, EMPTY_STRING, MI_WRITEMESSAGE_CHANNEL_VERBOSE);
MI_Instance_Delete((MI_Instance *)metaConfigInstance);
moduleManager->ft->Close(moduleManager, NULL);
return MI_RESULT_OK;
}
result = ApplyPendingConfig(lcmContext, moduleManager, dwFlags, &resultStatus, cimErrorDetails);
if (result != MI_RESULT_OK)
{
MI_Instance_Delete((MI_Instance *)metaConfigInstance);
moduleManager->ft->Close(moduleManager, NULL);
return result;
}
if (File_ExistT(g_MetaConfigFileName) == -1)
{
// If there is no meta config file, create the one which is default meta config, and creates new task.
// The operation must be done before reboot operation to avoid possible incomplete update.
result = SetMetaConfig((MI_Instance *)metaConfigInstance, cimErrorDetails);
if (result != MI_RESULT_OK)
{
MI_Instance_Delete((MI_Instance *)metaConfigInstance);
moduleManager->ft->Close(moduleManager, NULL);
return result;
}
}
if (resultStatus & DSC_RESTART_SYSTEM_FLAG)
{
SetLCMStatusReboot();
}
MI_Instance_Delete((MI_Instance *)metaConfigInstance);
moduleManager->ft->Close(moduleManager, NULL);
}
}
DSC_EventWriteMethodEnd(__WFUNCTION__);
if(overWroteUserSpecifiedRefreshFreqMins != NULL)
{
MI_Context* mi_context = (MI_Context*) lcmContext->context;
Intlstr pTempStr = Intlstr_Null;
GetResourceString1Param(ID_LCMHELPER_OVERWROTE_USER_SPECIFIED_REFRESH_FREQUENCY, overWroteUserSpecifiedRefreshFreqMins , &pTempStr);
#if defined(BUILD_OMS)
DSC_LOG_WARNING("%s", pTempStr.str);
#else
MI_Context_WriteWarning(mi_context, pTempStr.str);
#endif
if(pTempStr.str)
{
Intlstr_Free(pTempStr);
}
overWroteUserSpecifiedRefreshFreqMins = NULL;
}
if (overWroteUserSpecifiedConfModeFreqMins != NULL)
{
MI_Context* mi_context = (MI_Context*) lcmContext->context;
Intlstr pTempStr = Intlstr_Null;
GetResourceString1Param(ID_LCMHELPER_OVERWROTE_USER_SPECIFIED_CONFMODE_FREQUENCY, overWroteUserSpecifiedConfModeFreqMins, &pTempStr);
#if defined(BUILD_OMS)
DSC_LOG_WARNING("%s", pTempStr.str);
#else
MI_Context_WriteWarning(mi_context, pTempStr.str);
#endif
if (pTempStr.str)
{
Intlstr_Free(pTempStr);
}
overWroteUserSpecifiedConfModeFreqMins = NULL;
}
return result;
}