/* Do_Association_Synchronous() carries out an instance association operation synchronously, retrieving all results * on the same thread. The results can be retrieved on any thread, but that would be unusual for a * synchronous operation. */ void Do_Association_Synchronous(MI_Session *miSession, _In_z_ const wchar_t *namespaceName, MI_Instance *keyInstance, MI_Boolean keysOnly, _In_opt_z_ MI_Char *associationClass, _In_opt_z_ MI_Char *resultClass, _In_opt_z_ MI_Char *roleProperty, _In_opt_z_ MI_Char *resultRoleProperty) { MI_Result miResult = MI_RESULT_OK; MI_Result _miResult; MI_Operation miOperation = MI_OPERATION_NULL; MI_Boolean moreResults; const MI_Char *errorString = NULL; const MI_Instance *errorDetails = NULL; MI_Uint32 instanceCount = 0; /* Note that the identity of the thread needs to be the same as the one the session was created on. */ /* Note, although this sample does not include the PowerShell callbacks for extended semantics, they are allowed * on synchronous operations. Allowable callbacks are: * MI_OperationCallbacks.writeError * MI_OperationCallbacks.writeMessage * MI_OperationCallbacks.writeProgress */ /* Initiate the associator operation. Synchronous results are always retrieved through a call MI_Operation_GetInstance(). * All operations must be closed with a call to MI_Operation_Close(), but all results must be processed before that. * The operation can be cancelled via MI_Operation_Cancel(), although even then all results must be consumed before the operation * is closed. */ MI_Session_AssociatorInstances(miSession, 0, NULL, namespaceName, keyInstance, associationClass, resultClass, roleProperty, resultRoleProperty, keysOnly, NULL, &miOperation); /* Must loop through all results until moreResults == MI_FALSE */ do { MI_Instance *miInstance; /* Retrieve a single instance result */ _miResult = MI_Operation_GetInstance(&miOperation, &miInstance, &moreResults, &miResult, &errorString, &errorDetails); if (_miResult != MI_RESULT_OK) { /* If this function returns a failure it means that an invalid parameter was passed in, or the identity of the thread * is different from the identity the operation was created with. Both imply programming error. */ wprintf(L"MI_Operation_GetInstance failed, error = %s\n", MI_Result_To_String(_miResult)); break; } if (miInstance) { /* Dump the instance result */ wprintf(L"------------------------------------------\n"); Dump_MI_Instance(miInstance, keysOnly, 0); instanceCount++; } } while (miResult == MI_RESULT_OK && moreResults == MI_TRUE); /* moreResults == MI_FALSE, dump the final outcome of the operation */ wprintf(L"------------------------------------------\n"); if (miResult != MI_RESULT_OK) { wprintf(L"Operation failed, MI_Result=%s, errorString=%s, errorDetails=\n", MI_Result_To_String(miResult), errorString); Dump_MI_Instance(errorDetails, MI_FALSE, 0); } else { wprintf(L"Operation succeeded, number of instances=%u\n", instanceCount); } wprintf(L"------------------------------------------\n"); /* All operations must be closed. If an operation is not closed the owning session will hang until the operations * are closed fully. MI_Operation_Close will cancel an operation if it is still running, however results must be * consumed before the close can complete fully. * For synchronous operations the MI_Operation_Close() method is synchronous until the final result has been consumed * (moreResults == MI_FALSE). */ _miResult = MI_Operation_Close(&miOperation); if (_miResult != MI_RESULT_OK) { /* This API is likely to fail with invalid parameter, out of memory errors or access denied. * When an out of memory error happens, the operation will shut down as best it can. * Invalid parameter means a programming error happened. * Access denied means the security context while calling into the Close() is different from * when the operation was created. This will be a programming error and could happen if closing * from a different thread and forgetting to impersonate. */ wprintf(L"MI_Operation_Close failed, error %s\n", MI_Result_To_String(_miResult)); } }
/* Do_Create_Synchronous() carries out an instance Create operation synchronously, retrieving the result * on the same thread. The result can be retrieved on any thread, but that would be unusual for a * synchronous operation. */ void Do_Create_Synchronous(MI_Session *miSession, _In_z_ const wchar_t *namespaceName, MI_Instance *createInstance) { MI_Result miResult; MI_Result _miResult; MI_Operation miOperation = MI_OPERATION_NULL; MI_Instance *miInstance = NULL; MI_Boolean moreResults; MI_Char *errorMessage = NULL; MI_Instance *completionDetails = NULL; /* Note that the identity of the thread needs to be the same as the one the session was created on. */ /* Note, although this sample does not include the PowerShell callbacks for extended semantics, they are allowed * on synchronous operations. Allowable callbacks are: * MI_OperationCallbacks.writeError * MI_OperationCallbacks.writeMessage * MI_OperationCallbacks.writeProgress */ /* Initiate the CreateInstance operation. Synchronous results are always retrieved through a call MI_Operation_GetInstance(). * All operations must be closed with a call to MI_Operation_Close(), but all results must be processed before that. * The operation can be cancelled via MI_Operation_Cancel(), although even then all results must be consumed before the operation * is closed. */ MI_Session_CreateInstance(miSession, 0, NULL, namespaceName, createInstance, NULL, &miOperation); /* We always need to look through results until moreResults == MI_FALSE. For synchronous operations without * PowerShell callbacks it is not very likely to get more than one result from MI_Operation_GetInstance, * but it is always best to be sure, especially if you choose to add the PowerShell callbacks at a later data * and forget to update the retrieval to a loop. */ do { /* Retrieve the single instance result. remember, we need to call this API until moreResults == MI_FALSE */ _miResult = MI_Operation_GetInstance(&miOperation, &miInstance, &moreResults, &miResult, &errorMessage, &completionDetails); if (_miResult != MI_RESULT_OK) { /* If this function returns a failure it means that an invalid parameter was passed in, or the identity of the thread * is different from the identity the operation was created with. Both imply programming error. */ wprintf(L"MI_Operation_GetInstance failed, errorString=%s\n", MI_Result_To_String(_miResult)); } else { /* A result (success or failure) has been received. */ wprintf(L"------------------------------------------\n"); if (miResult != MI_RESULT_OK) { wprintf(L"Operation failed, MI_Result=%s, errorString=%s, errorDetails=\n", MI_Result_To_String(miResult), errorMessage); Dump_MI_Instance(completionDetails, MI_FALSE, 0); } else if (miInstance) { Dump_MI_Instance(miInstance, MI_FALSE, 0); } else if (moreResults == MI_TRUE) { wprintf(L"More results are due and we have no instance, we will keep trying!\n"); } wprintf(L"------------------------------------------\n"); } } while (moreResults == MI_TRUE); /* All operations must be closed. If an operation is not closed the owning session will hang until the operations * are closed fully. MI_Operation_Close will cancel an operation if it is still running, however results must be * consumed before the close can complete fully. * For synchronous operations the MI_Operation_Close() method is synchronous until the final result has been consumed * (moreResults == MI_FALSE). */ _miResult = MI_Operation_Close(&miOperation); if (_miResult != MI_RESULT_OK) { /* This API is likely to fail with invalid parameter, out of memory errors or access denied. * When an out of memory error happens, the operation will shut down as best it can. * Invalid parameter means a programming error happened. * Access denied means the security context while calling into the Close() is different from * when the operation was created. This will be a programming error and could happen if closing * from a different thread and forgetting to impersonate. */ wprintf(L"MI_Operation_Close failed, error %s\n", MI_Result_To_String(_miResult)); } }
int main(int argc, char *argv[]) { MI_Application miApp = MI_APPLICATION_NULL; MI_Session miSess = MI_SESSION_NULL; MI_Operation miOperation = MI_OPERATION_NULL; MI_Instance *parameter = NULL; MI_Result r = MI_RESULT_OK; MI_Value value; const MI_Instance *result; MI_Boolean moreResults; MI_Result resultCode; const MI_Char *errorMessage; MI_Instance *cimErrorDetails = NULL; MI_Uint32 argValue = TASK_REGULAR; // if( argc >= 2 ) { // the argument is the value of the parameter passed to function PerformRequiredConfigurationChecks argValue = atoi(argv[1]); if( argValue == 0 || !(argValue == TASK_REGULAR || argValue== TASK_REBOOT || argValue == TASK_BOOTSTRAP)) argValue = TASK_REGULAR; } r = DSC_MI_Application_Initialize(0, NULL, NULL, &miApp); if( r != MI_RESULT_OK) { return r; } r = DSC_MI_Application_NewSession(&miApp, NULL, NULL, NULL, NULL, NULL, &miSess); if (r != MI_RESULT_OK) { MI_Application_Close(&miApp); return r; } r = DSC_MI_Application_NewInstance(&miApp, MI_T("__Parameter"), NULL, ¶meter); if (r != MI_RESULT_OK) { MI_Session_Close(&miSess, NULL, NULL); MI_Application_Close(&miApp); return r; } value.uint32 = TASK_REGULAR; r = DSC_MI_Instance_AddElement(parameter, PerformRequiredConfigurationChecks_PARAMETER_NAME, &value, MI_UINT32, 0); if (r != MI_RESULT_OK) { MI_Instance_Delete(parameter); MI_Session_Close(&miSess, NULL, NULL); MI_Application_Close(&miApp); return r; } MI_Session_Invoke(&miSess, 0, 0, DSCENGINE_NAMESPACE, MSFT_DSCLocalConfigManager_CLASSNAME, MSFT_DSCLocalConfigManager_PerformRequiredConfigurationChecks, NULL, parameter, NULL, &miOperation); r = MI_Operation_GetInstance(&miOperation, &result, &moreResults, &resultCode, &errorMessage, (const MI_Instance **)&cimErrorDetails); if (resultCode != MI_RESULT_OK) { //write error message r = MI_RESULT_FAILED; } // Free resources MI_Instance_Delete(parameter); MI_Operation_Close(&miOperation); MI_Session_Close(&miSess, NULL, NULL); MI_Application_Close(&miApp); return r; }