in LCM/dsc/engine/ca/CAInfrastructure/CAEngine.c [2546:2707]
MI_Result MI_CALL PerformInventory( _In_ LCMProviderContext *lcmContext,
_In_ MI_Uint32 flags,
_In_ MI_InstanceA *instanceA,
_In_ ModuleManager *moduleManager,
_In_ MI_Instance *documentIns,
_Out_ MI_InstanceA *outInstances,
_Outptr_result_maybenull_ MI_Instance **extendedError)
{
MI_Result r = MI_RESULT_OK;
MI_Instance *filteredInstance = NULL;
MI_Instance *regInstance = NULL;
ModuleLoaderObject *moduleLoader = NULL;
MI_InstanceA inventoryInstancesResult;
MI_Session miSession = MI_SESSION_NULL;
ProviderCallbackContext providerContext = {0};
MI_InstanceA * inventoryInstancesResultArray = NULL;
MI_Char *certificateid = NULL;
MI_Boolean bEncryptionEnabled = MI_FALSE;
MI_Uint32 xCount = 0;
MI_Uint32 index = 0;
MI_Instance * tempInstance;
MI_Instance ** tempInstanceArray;
MI_Uint32 i = 0;
MI_Uint32 j = 0;
MI_Uint32 totalInstanceCount = 0;
if( outInstances == NULL || NitsShouldFault(NitsHere(), NitsAutomatic))
{
return GetCimMIError(MI_RESULT_INVALID_PARAMETER, extendedError,ID_CAINFRA_INVENTORY_NULLPARAM);
}
memset(outInstances, 0, sizeof(MI_InstanceA));
if( instanceA == 0 || moduleManager == 0 || instanceA->size == 0 || NitsShouldFault(NitsHere(), NitsAutomatic))
{
return GetCimMIError(MI_RESULT_INVALID_PARAMETER, extendedError,ID_CAINFRA_DEPENDCY_NULLPARAM);
}
if (extendedError == NULL)
{
return MI_RESULT_INVALID_PARAMETER;
}
*extendedError = NULL; // Explicitly set *extendedError to NULL as _Outptr_ requires setting this at least once.
providerContext.lcmProviderContext = lcmContext;
r = GetDocumentEncryptionSetting(documentIns, &bEncryptionEnabled, &certificateid, extendedError);
if( r != MI_RESULT_OK )
{
return r;
}
outInstances->data = NULL;
outInstances->size = 0;
inventoryInstancesResult.data = NULL;
inventoryInstancesResult.size = 0;
inventoryInstancesResultArray = (MI_InstanceA*)DSC_malloc(sizeof(MI_InstanceA) * instanceA->size, NitsHere());
moduleLoader = (ModuleLoaderObject*) moduleManager->reserved2;
/*Create MI session*/
r = DSC_MI_Application_NewSession(moduleLoader->application, NULL, NULL, NULL, NULL, NULL, &miSession);
if( r != MI_RESULT_OK)
{
return GetCimMIError(r, extendedError,ID_CAINFRA_NEWSESSION_FAILED);
}
// Instantiate native resource manager, responsible to load/unload native resource provider.
r = NativeResourceManager_New(&providerContext, &(providerContext.nativeResourceManager));
if( r != MI_RESULT_OK)
{
return r;
}
/*Assuming the dependencies is implicit (the order in which instances are specified in instance document). */
/*Get the instance compatible with the provider.*/
for (xCount = 0 ; xCount < instanceA->size ; xCount++)
{
/* Get Registration Instance to find registration information.*/
r = moduleManager->ft->GetRegistrationInstance(moduleManager, instanceA->data[xCount]->classDecl->name, (const MI_Instance **)®Instance, extendedError);
if( r != MI_RESULT_OK)
{
MI_Session_Close(&miSession, NULL, NULL);
return r;
}
/*Get provider compatible instance*/
r = moduleManager->ft->GetProviderCompatibleInstance(moduleManager, instanceA->data[xCount], &filteredInstance, extendedError);
if( r != MI_RESULT_OK)
{
MI_Session_Close(&miSession, NULL, NULL);
return r;
}
providerContext.resourceId = GetResourceId(instanceA->data[xCount]);
/* Get the inventory.*/
r = PerformInventoryState(&providerContext, moduleLoader->application, &miSession, filteredInstance, regInstance, &inventoryInstancesResult, extendedError);
MI_Instance_Delete(filteredInstance);
filteredInstance = NULL;
if( r != MI_RESULT_OK)
{
Intlstr intlstr = Intlstr_Null;
GetResourceString(ID_LCMHELPER_GETINVENTORY_ERROR, &intlstr);
DSC_EventWriteLCMSendConfigurationError(CA_ACTIVITY_NAME,
r,
(MI_Char*)intlstr.str,
providerContext.resourceId,
GetSourceInfo(instanceA->data[xCount]),
(MI_Char*)GetErrorDetail(*extendedError));
if( intlstr.str)
Intlstr_Free(intlstr);
MI_Session_Close(&miSession, NULL, NULL);
return r;
}
inventoryInstancesResultArray[xCount].data = inventoryInstancesResult.data;
inventoryInstancesResultArray[xCount].size = inventoryInstancesResult.size;
totalInstanceCount += inventoryInstancesResult.size;
}
if (totalInstanceCount > 0)
{
outInstances->data = (MI_Instance**)DSC_malloc(sizeof(MI_Instance*) * totalInstanceCount, NitsHere());
outInstances->size = totalInstanceCount;
xCount = 0;
for (i = 0; i < instanceA->size; ++i)
{
for (j = 0; j < inventoryInstancesResultArray[i].size; ++j)
{
outInstances->data[xCount] = inventoryInstancesResultArray[i].data[j];
xCount += 1;
}
}
}
else
{
outInstances->data = NULL;
outInstances->size = 0;
}
MI_Session_Close(&miSession, NULL, NULL);
// Ignore this call and do not delete the native resource manager instance. It will be cleaned up when the host process goes away.
NativeResourceManager_Delete(providerContext.nativeResourceManager);
#if defined(BUILD_OMS)
struct sigaction sa;
sa.sa_handler = &handleSIGCHLDSignal;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
sigaction(SIGCHLD, &sa, 0);
DSC_EventWriteMessageRegisterProcessHandler();
#endif
return r;
}