static MI_Result GetModuleNameVersionTable()

in LCM/dsc/engine/ca/CAInfrastructure/WebPullClient.c [2439:2614]


static MI_Result GetModuleNameVersionTable(MI_Char* mofFileLocation,
                                           ModuleTable* table,
                                           _Outptr_result_maybenull_ MI_Instance **extendedError)
{
    MI_Result r = MI_RESULT_OK;
    MI_InstanceA *miInstanceArray = NULL;
    MI_Uint8 *pbuffer = NULL;
    MI_Uint32 contentSize;
    MI_Uint32 readBytes;
    MI_ClassA miClassArray = {0};
    MI_Application *miApp = NULL;
    MI_Deserializer deserializer;
    MI_OperationOptions options;
    MI_Value moduleName;
    MI_Value moduleVersion;
    int i = 0;
    size_t tmpLength;
    ModuleTableEntry* current;
    ModuleTableEntry** foundEntry;
    ModuleClassList** foundClassEntry;

    miApp = (MI_Application *) DSC_malloc( sizeof(MI_Application), NitsHere());
    memset(miApp,  0, sizeof(MI_Application));
    r = DSC_MI_Application_Initialize(0, NULL, NULL, miApp);
    if( r != MI_RESULT_OK)
    {
        DSC_free(miApp);
        return GetCimMIError1Param(MI_RESULT_FAILED, extendedError, ID_PULL_INITIALIZEMODULETABLEFAILED, "App Init failed");
    }

    memset(&deserializer, 0, sizeof(MI_Deserializer));
    memset(&options, 0, sizeof(MI_OperationOptions));

    r = DSC_MI_Application_NewOperationOptions(miApp, MI_FALSE, &options);
    if (r != MI_RESULT_OK)
    {
        MI_Application_Close(miApp);
        DSC_free(miApp);
        return GetCimMIError1Param(MI_RESULT_FAILED, extendedError, ID_PULL_INITIALIZEMODULETABLEFAILED, "Setting NewOperationOptions failed");
    }

    r = DSC_MI_OperationOptions_SetString(&options, MOFCODEC_SCHEMA_VALIDATION_OPTION_NAME, MOFCODEC_SCHEMA_VALIDATION_IGNORE, 0);
    if (r!=MI_RESULT_OK )
    {
        MI_Application_Close(miApp);
        DSC_free(miApp);
        return GetCimMIError1Param(MI_RESULT_FAILED, extendedError, ID_PULL_INITIALIZEMODULETABLEFAILED, "Setting OperationOptions string Failed");
    }

    r = DSC_MI_Application_NewDeserializer_Mof(miApp, 0, MOFCODEC_FORMAT, &deserializer);
    if (r!=MI_RESULT_OK )
    {
        MI_Application_Close(miApp);
        DSC_free(miApp);
        return GetCimMIError1Param(MI_RESULT_FAILED, extendedError, ID_PULL_INITIALIZEMODULETABLEFAILED, "Creating New Deserializer Failed");
    }

    r = ReadFileContent(mofFileLocation, &pbuffer, &contentSize, extendedError);
    if(r != MI_RESULT_OK)
    {
        MI_Application_Close(miApp);
        DSC_free(miApp);
        return r;
    }
    miClassArray.size = 0;
    miClassArray.data = NULL;

    r = MI_Deserializer_DeserializeInstanceArray(&deserializer, 0, &options, 0, pbuffer, contentSize, &miClassArray, &readBytes, &miInstanceArray, extendedError);
    if (r != MI_RESULT_OK)
    {
        MI_Application_Close(miApp);
        DSC_free(miApp);
        return r;
    }

    if(pbuffer)
    {
        DSC_free(pbuffer);
        pbuffer = NULL;
    }

    for (i = 0; i < miInstanceArray->size; ++i)
    {
        // compare classname with BASE_DOCUMENT_CLASSNAME.  Skip if same
        if ( Tcscasecmp( miInstanceArray->data[i]->classDecl->name , BASE_DOCUMENT_CLASSNAME) != 0 )
        {

            r = DSC_MI_Instance_GetElement(miInstanceArray->data[i], MI_T("ModuleName"), &moduleName, NULL, NULL, NULL);
            if (r != MI_RESULT_OK )
            {
                continue;
            }

            r = DSC_MI_Instance_GetElement(miInstanceArray->data[i], MI_T("ModuleVersion"), &moduleVersion, NULL, NULL, NULL);
            if (r != MI_RESULT_OK )
            {
                continue;
            }

            if ( IsModuleVersionValidFormat(moduleVersion.string) == 1 )
            {

                // foundEntry will be a pointer to the "next" or "first" pointer that points to the ModuleTableEntry we want
                foundEntry = ModuleTableContainsKey(table, moduleName.string);
                if ( *foundEntry != NULL )
                {
                    // Find VersionClass tuple, append new class if necessary, update version if necessary

                    // compare version? Windows doesn't.
                    // current->moduleVersionClassTuple->moduleVersion

                    // See if class is in the class list.  If it isn't, add it. if it is, do nothing
                    foundClassEntry = ClassListContainsClass(&current->moduleVersionClassTuple->first, miInstanceArray->data[i]->classDecl->name );
                    if (*foundClassEntry == NULL)
                    {
                        *foundClassEntry = (ModuleClassList*) DSC_malloc(sizeof(ModuleClassList), NitsHere());
                        (*foundClassEntry)->next = NULL;

                        // Copy class name
                        tmpLength = Tcslen(miInstanceArray->data[i]->classDecl->name) + 1;
                        (*foundClassEntry)->moduleClass = (MI_Char*)DSC_malloc(sizeof(MI_Char) * tmpLength, NitsHere());
                        memcpy((*foundClassEntry)->moduleClass, miInstanceArray->data[i]->classDecl->name, tmpLength);
                    }
                }
                else
                {
                    *foundEntry = (ModuleTableEntry*) DSC_malloc(sizeof(ModuleTableEntry), NitsHere());
                    current = *foundEntry;
                    current->next = NULL;

                    // Copy module name
                    tmpLength = Tcslen(moduleName.string) + 1;
                    current->moduleName = (MI_Char*)DSC_malloc(sizeof(MI_Char) * tmpLength, NitsHere());
                    memcpy(current->moduleName, moduleName.string, tmpLength);

                    current->moduleVersionClassTuple = (ModuleVersionClassTuple*) DSC_malloc(sizeof(ModuleVersionClassTuple), NitsHere());

                    // Copy module version
                    tmpLength = Tcslen(moduleVersion.string) + 1;
                    current->moduleVersionClassTuple->moduleVersion = (MI_Char*)DSC_malloc(sizeof(MI_Char) * tmpLength, NitsHere());
                    memcpy(current->moduleVersionClassTuple->moduleVersion, moduleVersion.string, tmpLength);

                    current->moduleVersionClassTuple->first = (ModuleClassList*) DSC_malloc(sizeof(ModuleClassList), NitsHere());
                    current->moduleVersionClassTuple->first->next = NULL;

                    // Copy class name
                    tmpLength = Tcslen(miInstanceArray->data[i]->classDecl->name) + 1;
                    current->moduleVersionClassTuple->first->moduleClass = (MI_Char*)DSC_malloc(sizeof(MI_Char) * tmpLength, NitsHere());
                    memcpy(current->moduleVersionClassTuple->first->moduleClass, miInstanceArray->data[i]->classDecl->name, tmpLength);

                }
            }
            else
            {
                // Error: Invalid version for module.
                MI_Deserializer_Close(&deserializer);
                MI_OperationOptions_Delete(&options);
                CleanUpDeserializerInstanceCache(miInstanceArray);
                MI_Application_Close(miApp);
                DSC_free(miApp);
                return GetCimMIError2Params(MI_RESULT_FAILED, extendedError, ID_PULL_INVALIDMODULEVERSION, moduleVersion.string, moduleName.string);
            }
        }
    }

    r = FilterUsingCachedModules(table);

    MI_Deserializer_Close(&deserializer);
    MI_OperationOptions_Delete(&options);

    CleanUpDeserializerInstanceCache(miInstanceArray);
    MI_Application_Close(miApp);
    DSC_free(miApp);

    return MI_RESULT_OK;
}