/* 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));
    }
}
Exemple #3
0
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, &parameter);
    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;
}