MI_Result AppendWMIError1Param(
    _Inout_ MI_Instance *cimErrorDetails,
    _In_z_ const MI_Char * pszFormat,
    _In_z_ const MI_Char * param1
)
{
    MI_Result r = MI_RESULT_OK;
    MI_Char *message = NULL;
    MI_Value value;

    r = DSC_MI_Instance_GetElement(cimErrorDetails, MSFT_WMIERROR_MESSAGE, &value, NULL, NULL, NULL);
    if( r == MI_RESULT_OK )
    {
        size_t msgLen = Tcslen(value.string) + Tcslen(param1) + Tcslen(pszFormat) + 1;
        message = (MI_Char*) DSC_malloc(sizeof(MI_Char) *msgLen, NitsMakeCallSite(-3, NULL, NULL, 0));
        if(message)
        {
            if( Stprintf(message, msgLen, pszFormat, value.string, param1))
            {
                value.string = message;
                r = MI_Instance_SetElement(cimErrorDetails, MSFT_WMIERROR_MESSAGE, &value, MI_STRING, 0);
            }

            DSC_free(message);
        }
    }
    return r;
}
/*Function to return true if registration needs to be done*/
MI_Boolean ShouldDoRegistration(
    _In_ RegistrationManager* self,
    _In_ RegistrationRequest* request,
    _Outptr_result_maybenull_ MI_Instance **cimErrorDetails)
{   
    MI_Result result = MI_RESULT_OK;
    MI_Uint32 i = 0;
    MI_Value value;
    MI_Char* url = NULL;    
    MI_Type type;
    MI_Uint32 flags;

    if (cimErrorDetails)
    {
        *cimErrorDetails = NULL;
    }

    MI_Instance *registrationDataInstance = request->registrationData;

    result = MI_Instance_GetElement(registrationDataInstance, MSFT_ServerURL_Name, &value, NULL, NULL, NULL);
    EH_CheckResult(result);
    url = value.string;
    
    result = DSC_MI_Instance_GetElement(registrationDataInstance, MSFT_RegistrationKey_Name, &value, &type, &flags, NULL);
    if (result == MI_RESULT_OK && type == MI_STRING && (!(flags & MI_FLAG_NULL)))
    {
        if (Tcscasecmp(value.string, MI_T("")) != 0)
        {
            // This means that a non-empty RegistrationKey is specified. Then, we always do registration. 
            // If RegistrationKey is not specified, then we check the cache and do/skip registration based on ServerURL
            DSC_EventWriteLCMAgentAttemptRegistration(g_ConfigurationDetails.jobGuidString, self->agentId, url);
            return MI_TRUE;
        }
    }

    for (i = 0; i < self->numberOfServerURLs; i++)
    {
        if (Tcscasecmp(self->serverURLs[i], url) == 0)
        {
            DSC_EventWriteLCMServerURLRegistered(g_ConfigurationDetails.jobGuidString, self->agentId, url);
            return MI_FALSE;
        }
    }
    
    EH_UNWIND:

    return MI_TRUE;
}
MI_Result GetRegisteredServerURLsFromCache(
    _Outptr_result_maybenull_z_ MI_Char** registeredServerURLs,
    _Outptr_result_maybenull_ MI_Instance **cimErrorDetails)
{
    MI_Value value;
    MI_Type  type;
    MI_Uint32 flags;
    size_t dwSize;
    int retValue;

    if (cimErrorDetails)
    {
        *cimErrorDetails = NULL;
    }

    memset(registeredServerURLs, 0, sizeof(MI_Char));

    if (g_DSCInternalCache)
    {
        if (DSC_MI_Instance_GetElement(g_DSCInternalCache, DSC_InternalStateCache_RegisteredServerURLs, &value, &type, &flags, NULL) == MI_RESULT_OK)
        {
            dwSize = Tcslen(value.string) + 1;
            *registeredServerURLs = (MI_Char*)DSC_malloc(dwSize*sizeof(MI_Char), NitsHere());
            if (*registeredServerURLs == NULL)
            {
                EH_Fail_(GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, cimErrorDetails, ID_LCMHELPER_MEMORY_ERROR));
            }
            memset(*registeredServerURLs, 0, dwSize);

            retValue = Stprintf(*registeredServerURLs, dwSize, MI_T("%T"), value.string);
            if (retValue == -1 || NitsShouldFault(NitsHere(), NitsAutomatic))
            {
                DSC_free(*registeredServerURLs);
                EH_Fail_(GetCimMIError(MI_RESULT_FAILED, cimErrorDetails, ID_LCMHELPER_PRINTF_ERROR));
            }
        }
    }

    EH_UNWIND:
        return MI_RESULT_OK;
}
MI_Result AppendWMIErrorWithResourceID(
    _Inout_ MI_Instance *cimErrorDetails,
    _In_z_ const MI_Char * resourceId
)
{
    MI_Result r = MI_RESULT_OK;
    Intlstr intlstr = Intlstr_Null;
    MI_Value value;

    r = DSC_MI_Instance_GetElement(cimErrorDetails, MSFT_WMIERROR_MESSAGE, &value, NULL, NULL, NULL);
    if( r == MI_RESULT_OK )
    {
        GetResourceString2Param(ID_CA_MOVETODESIREDSTATE_FAILED_APPEND_RESOURCEID, value.string, resourceId, &intlstr);
        if( intlstr.str)
        {
            value.string = (MI_Char*)intlstr.str;
            r = MI_Instance_SetElement(cimErrorDetails, MSFT_WMIERROR_MESSAGE, &value, MI_STRING, 0);
            Intlstr_Free(intlstr);
        }
    }
    return r;
}
MI_Boolean IsMatchedKeyProperties(
    _In_ MI_Instance* instance0,
    _In_ MI_Instance* instance1,
    _Outptr_result_maybenull_z_ MI_Char** keywords,
    _Out_ MI_Result* miResult,
    _Outptr_result_maybenull_ MI_Instance **extendedError)
{
    MI_Uint32 i, j;
    MI_Result result0, result1;
    MI_Value value0, value1;
    MI_Type type0, type1;
    Intlstr intlstr = Intlstr_Null;
    MI_Char* tempKeywords = NULL;
    MI_Char* tempKeywordsBackup = NULL;
    size_t length;
    MI_PropertyDecl** properties;

    if (extendedError == NULL)
    {        
        return MI_RESULT_INVALID_PARAMETER; 
    }
    *extendedError = NULL;	// Explicitly set *extendedError to NULL as _Outptr_ requires setting this at least once.	

    *miResult = MI_RESULT_OK;
    *keywords = NULL;
    properties = (MI_PropertyDecl**)instance0->classDecl->properties;
    for (i = 0; i < instance0->classDecl->numProperties; i++)
    {
        for (j = 0; j < properties[i]->numQualifiers; j++)
        {
            if (Tcscasecmp(properties[i]->qualifiers[j]->name, MI_T("Key")) == 0)
            {
                result0 = DSC_MI_Instance_GetElement(instance0, properties[i]->name, &value0, &type0, NULL, NULL);
                result1 = DSC_MI_Instance_GetElement(instance1, properties[i]->name, &value1, &type1, NULL, NULL);
                if (result0 == MI_RESULT_OK
                    && result1 == MI_RESULT_OK
                    && type0 == type1
                    && IsSameMiValue(&value0, &value1, type0))
                {
                    // key is the same, building keywords list.
                    length = Tcslen(properties[i]->name) + 1;
                    if (tempKeywords == NULL)
                    {
                        // the first keyword.
                        tempKeywords = (MI_Char*)DSC_malloc(length * sizeof (MI_Char), NitsHere());
                        if (tempKeywords == NULL)
                        {
                            *miResult = CreateMemoryError(extendedError);
                            return MI_TRUE;
                        }

                        memcpy(tempKeywords, properties[i]->name, length * sizeof(MI_Char) );
                    }
                    else
                    {
                        // the second or more keywords.
                        if (intlstr.str == NULL)
                        {
                            // create separator string once.
                            GetResourceString(ID_CA_COMMA_SEPARATOR, &intlstr);
                            if (intlstr.str == NULL)
                            {
                                *miResult = CreateMemoryError(extendedError);
                                DSC_free(tempKeywords);
                                return MI_TRUE;
                            }
                        }

                        length += Tcslen(tempKeywords) + Tcslen(intlstr.str);
                        tempKeywordsBackup = tempKeywords;
                        tempKeywords = (MI_Char*)DSC_realloc(tempKeywordsBackup, length * sizeof (MI_Char), NitsHere());
                        if (tempKeywords == NULL)
                        {
                            *miResult = CreateMemoryError(extendedError);
                            DSC_free(tempKeywordsBackup);
                            Intlstr_Free(intlstr);
                            return MI_TRUE;
                        }
                        Stprintf(tempKeywords, length, MI_T("%T%T"), intlstr.str, properties[i]->name);
                    }
                }
                else
                {
                    if (tempKeywords)
                    {
                        DSC_free(tempKeywords);
                    }
                    
                    if (intlstr.str)
                    {
                        Intlstr_Free(intlstr);
                    }
                    
                    if(result0 != MI_RESULT_OK)
                    {
                        *miResult = result0;
                    }
                    else if(result1 != MI_RESULT_OK)
                    {
                        *miResult = result1;
                    }

                    return MI_FALSE;
                }

                break;
            }
        }
    }

    if (intlstr.str)
    {
        Intlstr_Free(intlstr);
    }

    // at least one key was found, and all matched.
    if (tempKeywords)
    {
        *keywords = tempKeywords;
        return MI_TRUE;
    }

    return MI_FALSE;
}
Esempio n. 6
0
MI_Result ValidateProviderRegistrationAgainstSchema(_In_ MI_ClassA *miClassArray,
                                                    _In_ MI_InstanceA *miRegistrationArray,
                                                    _Outptr_result_maybenull_ MI_Instance **extendedError)

{
    MI_Result r = MI_RESULT_OK;
    MI_Uint32 xCount=0 , yCount = 0;
    MI_Uint32 registrationFoundCount = 0, schemaFoundCount = 0;
    MI_Value value;

    if (extendedError == NULL)
    {        
        return MI_RESULT_INVALID_PARAMETER; 
    }
    *extendedError = NULL;  // Explicitly set *extendedError to NULL as _Outptr_ requires setting this at least once.   

    DSC_EventWriteValidatingProviderRegistration(miClassArray->size,miRegistrationArray->size);

    //Test1 : only 1 registration per class
    //Test2 : no class left out without registration(except for meta config), also validates that registration not targeting more than 1 class.
    //Test3: no registration instance left out without class
    //Test4 : no two classes with same name    

    for (xCount = 0 ; xCount < miClassArray->size ; xCount++)
    {
        if (miClassArray->data[xCount]->classDecl->superClass &&
            Tcscasecmp(miClassArray->data[xCount]->classDecl->superClass, BASE_RESOURCE_CLASSNAME) == 0)
        {
            schemaFoundCount++;
        }

        //Test4
        for (yCount = xCount + 1 ; yCount <  miClassArray->size ; yCount++)
        {
            if (Tcscasecmp(miClassArray->data[yCount]->classDecl->name, miClassArray->data[xCount]->classDecl->name) == 0  || NitsShouldFault(NitsHere(), NitsAutomatic))
            {
                return GetCimMIError(MI_RESULT_INVALID_PARAMETER, extendedError, ID_MODMAN_VALIDATE_PROVREG_MULTI);  
            }
        }
    }

    for (xCount = 0 ; xCount < miRegistrationArray->size ; xCount++)
    {
        for (yCount = 0 ; yCount < miClassArray->size ; yCount++)
        {
            if ((miClassArray->data[yCount]->classDecl->superClass &&
                 Tcscasecmp(miClassArray->data[yCount]->classDecl->superClass, BASE_RESOURCE_CLASSNAME) == 0) ||
                 Tcscasecmp(miClassArray->data[xCount]->classDecl->name, METACONFIG_CLASSNAME) == 0)
            {
                r = DSC_MI_Instance_GetElement(miRegistrationArray->data[xCount], MSFT_BaseConfigurationProviderRegistration_ClassName, 
                    &value, NULL, NULL, NULL); 
                if (r != MI_RESULT_OK )
                {
                    return GetCimMIError(r, extendedError, ID_MODMAN_VALIDATE_PROVREG_MANDATORY);
                }

                if (Tcscasecmp(value.string, miClassArray->data[yCount]->classDecl->name) == 0 )
                {
                    // Test1
                    registrationFoundCount++;
                    break;
                }
            }
        }

        // Test3
        if (yCount == miClassArray->size  || NitsShouldFault(NitsHere(), NitsAutomatic))
        {
            return GetCimMIError(MI_RESULT_INVALID_PARAMETER, extendedError, ID_MODMAN_VALIDATE_PROVREG_NOCLASS);    
        }
    }

    // Test2
    if (registrationFoundCount != schemaFoundCount  || NitsShouldFault(NitsHere(), NitsAutomatic))
    {
        return GetCimMIError(MI_RESULT_INVALID_PARAMETER, extendedError, ID_MODMAN_VALIDATE_PROVREG_NOREG);
    }

    return r;
}