MI_Result ValidateSchema()

in LCM/dsc/engine/ModuleLoader/ModuleLibrary/ModuleValidator.c [326:454]


MI_Result ValidateSchema(_In_ MI_ClassA *miClassArray,
                         _In_ MI_Uint32 classIndex,
                         _Inout_updates_(resSize) MI_Boolean *bResourceVisited,
                         _In_ MI_Uint32 resSize,
                         _In_ MI_Boolean bConfigurationResource,
                         _Outptr_result_maybenull_ MI_Instance **extendedError)
{
    MI_Result r = MI_RESULT_OK;
    MI_Uint32 xCount = 0, yCount = 0;
    const MI_ClassDecl *classToCheck = NULL;
    MI_Uint32 keyPropertyCount = 0;
    MI_Uint32 propertyBitMask = 0; // 1 = Read, 2 = Write, 4 = Key, 8 = Required
     if( extendedError )
        *extendedError = NULL;

    //PrintClass(miClassArray->data[classIndex]);

    if( classIndex >= miClassArray->size || NitsShouldFault(NitsHere(), NitsAutomatic))
    {
        return GetCimMIError(MI_RESULT_INVALID_PARAMETER, extendedError, ID_MODMAN_VALIDATE_SCHEMA_INVPARAM);
    }

    classToCheck = miClassArray->data[classIndex]->classDecl;
    // This Event does not produce any useful information and increasing log file size, disabling it. 
    // DSC_EventWriteValidatingSchema(classToCheck->name,classIndex,miClassArray->size);

    /*Test7*/
    if( classToCheck->numMethods != 0  || NitsShouldFault(NitsHere(), NitsAutomatic))
    {
        return GetCimMIError(MI_RESULT_INVALID_PARAMETER, extendedError, ID_MODMAN_VALIDATE_SCHEMA_NOMETHOD);
    }

    /*Test 4*/
    // validate class qualifiers
    for( xCount = 0 ; xCount < classToCheck->numQualifiers; xCount++)
    {
        if( Tcscasecmp(QUALIFIER_VERSION, classToCheck->qualifiers[xCount]->name) == 0 )
        {
            break;
        }
    }
    if( xCount == classToCheck->numQualifiers || NitsShouldFault(NitsHere(), NitsAutomatic))
    {
        return GetCimMIError(MI_RESULT_NOT_FOUND, extendedError, ID_MODMAN_VALIDATE_SCHEMA_VERSIONQUAL);
    }

    /*Test 2*/
    /*Rule1: Read and (Key or Required or Write) can't coexist*/
    /*Rule2: Write and (Read) can't coexist*/
    /*Rule3: Key and (Read) can't coexist*/
    /*Rule4: Required and (Read) can't coexist*/
    for( xCount = 0 ; xCount < classToCheck->numProperties; xCount++)
    {
        propertyBitMask = 0;
        /*Test5: Reference types are not supported.*/
        if( classToCheck->properties[xCount]->type == MI_REFERENCE ||
            classToCheck->properties[xCount]->type == MI_REFERENCEA  || NitsShouldFault(NitsHere(), NitsAutomatic))
        {
            return GetCimMIError(MI_RESULT_INVALID_PARAMETER, extendedError, ID_MODMAN_VALIDATE_SCHEMA_NOSUPP_REF);
        }
        if( classToCheck->properties[xCount]->flags & MI_FLAG_READONLY )
        {
            propertyBitMask |= PROPERTY_BITMASK_READ;
        }
        if( classToCheck->properties[xCount]->flags & MI_FLAG_KEY )
        {
            propertyBitMask |= PROPERTY_BITMASK_KEY;
            keyPropertyCount++;
        }
        if( classToCheck->properties[xCount]->flags & MI_FLAG_REQUIRED )
        {
            propertyBitMask |= PROPERTY_BITMASK_REQUIRED;
        }

        for( yCount = 0 ; yCount < classToCheck->properties[xCount]->numQualifiers; yCount++)
        {
            const MI_Qualifier *classQual = classToCheck->properties[xCount]->qualifiers[yCount];
            if( Tcscasecmp(classQual->name, QUALIFIER_WRITE) == 0 )
            {
                propertyBitMask |= PROPERTY_BITMASK_WRITE;
                break;
            }
        }

        // Do actual validation
        if( ((propertyBitMask & PROPERTY_BITMASK_READ) && ( (propertyBitMask & PROPERTY_BITMASK_ALL) & ~(PROPERTY_BITMASK_READ)))  || (NitsShouldFault(NitsHere(), NitsAutomatic)))
        {
            return GetCimMIError(MI_RESULT_INVALID_PARAMETER, extendedError, ID_MODMAN_VALIDATE_SCHEMA_NOMANDATORY_QUALIFIER);
        }

        /*Test6: Embedded object type support*/
        if( classToCheck->properties[xCount]->className != NULL)
        {
            // check for class in existing classes
            for( yCount = 0 ; yCount < miClassArray->size && yCount < resSize; yCount++)
            {
                if( Tcscasecmp(miClassArray->data[yCount]->classDecl->name, classToCheck->properties[xCount]->className) == 0 )
                {
                    if( bResourceVisited[yCount] == MI_TRUE) // Already processed
                    {
                        break;
                    }
                    else
                    {
                        bResourceVisited[yCount] = MI_TRUE;
                        r = ValidateSchema(miClassArray, yCount, bResourceVisited, resSize, MI_FALSE,extendedError);
                        if( r != MI_RESULT_OK)
                        {
                            return r;
                        }
                    }
                }
            }

        }
    }
    if( bConfigurationResource &&
        Tcscasecmp(miClassArray->data[classIndex]->classDecl->name, METACONFIG_CLASSNAME) != 0 &&
        Tcscasecmp(miClassArray->data[classIndex]->classDecl->name, MSFT_LOGRESOURCENAME) != 0)
    {
        if( keyPropertyCount < 1  || NitsShouldFault(NitsHere(), NitsAutomatic))
        {
            return GetCimMIError(MI_RESULT_INVALID_PARAMETER, extendedError, ID_MODMAN_VALIDATE_SCHEMA_NOKEY);
        }
    }

    return r;

}