winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

DefaultSetGroupProcessor.cpp (7128B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #include "pch.h"
      4 #include "DefaultSetGroupProcessor.h"
      5 #include "ConfigurationSetApplyProcessor.h"
      6 #include "ExceptionResultHelpers.h"
      7 #include "TestGroupSettingsResult.h"
      8 #include "TestSettingsResult.h"
      9 
     10 #include <AppInstallerStrings.h>
     11 
     12 namespace winrt::Microsoft::Management::Configuration::implementation
     13 {
     14     namespace
     15     {
     16         // Determines whether a configuration unit should be tested.
     17         bool ShouldTestDuringTest(const Configuration::ConfigurationUnit& unit)
     18         {
     19             return unit.IsActive() && unit.Intent() != ConfigurationUnitIntent::Inform;
     20         }
     21     }
     22 
     23     void DefaultSetGroupProcessor::Initialize(const ConfigurationSet& set, const IConfigurationSetProcessor& setProcessor, ConfigThreadGlobals& threadGlobals, bool consistencyCheckOnly)
     24     {
     25         m_set = set;
     26         m_setProcessor = setProcessor;
     27         m_threadGlobals = &threadGlobals;
     28         m_consistencyCheckOnly = consistencyCheckOnly;
     29     }
     30 
     31     Windows::Foundation::IInspectable DefaultSetGroupProcessor::Group()
     32     {
     33         return m_set;
     34     }
     35 
     36     Windows::Foundation::IAsyncOperation<ITestGroupSettingsResult> DefaultSetGroupProcessor::TestGroupSettingsAsync(Windows::Foundation::EventHandler<ITestSettingsResult> progressHandler)
     37     {
     38         auto strongThis = get_strong();
     39         co_await resume_background();
     40 
     41         auto cancellation = co_await get_cancellation_token();
     42         cancellation.enable_propagation();
     43 
     44         auto result = make_self<wil::details::module_count_wrapper<implementation::TestGroupSettingsResult>>();
     45         result->Group(m_set);
     46 
     47         try
     48         {
     49             for (const auto& unit : m_set.Units())
     50             {
     51                 ThrowIf(cancellation());
     52 
     53                 AICLI_LOG_DIRECT(m_threadGlobals->GetDiagnosticLogger(), Config, Info, << "Testing configuration unit: `" << AppInstaller::Utility::ConvertToUTF8(unit.Identifier()) << "` [" << AppInstaller::Utility::ConvertToUTF8(unit.Type()) << ']');
     54 
     55                 ITestSettingsResult settingsResult;
     56                 ConfigurationTestResult testResult = ConfigurationTestResult::Unknown;
     57                 auto unitResult = make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>();
     58 
     59                 if (ShouldTestDuringTest(unit))
     60                 {
     61                     IConfigurationUnitProcessor unitProcessor;
     62 
     63                     try
     64                     {
     65                         unitProcessor = m_setProcessor.CreateUnitProcessor(unit);
     66                     }
     67                     catch (...)
     68                     {
     69                         ExtractUnitResultInformation(std::current_exception(), unitResult);
     70                     }
     71 
     72                     // Check again as creating the unit processor could take time
     73                     ThrowIf(cancellation());
     74 
     75                     if (unitProcessor)
     76                     {
     77                         IConfigurationGroupProcessor groupProcessor = unitProcessor.try_as<IConfigurationGroupProcessor>();
     78 
     79                         if (groupProcessor)
     80                         {
     81                             auto testOperation = groupProcessor.TestGroupSettingsAsync([&](const auto&, const ITestSettingsResult& unitResult)
     82                                 {
     83                                     progressHandler(nullptr, unitResult);
     84                                 });
     85 
     86                             ITestGroupSettingsResult groupResult = co_await testOperation;
     87 
     88                             // Put all of the group's unit results in our unit results
     89                             for (const auto& groupUnitResult : groupResult.UnitResults())
     90                             {
     91                                 result->AppendUnitResult(groupUnitResult);
     92                             }
     93 
     94                             // Convert group result into a unit result for the group
     95                             auto testSettingsResult = make_self<wil::details::module_count_wrapper<implementation::TestSettingsResult>>();
     96                             testSettingsResult->Unit(unit);
     97                             testSettingsResult->TestResult(groupResult.TestResult());
     98                             testSettingsResult->ResultInformation(groupResult.ResultInformation());
     99                             settingsResult = *testSettingsResult;
    100                         }
    101                         else
    102                         {
    103                             try
    104                             {
    105                                 settingsResult = unitProcessor.TestSettings();
    106                             }
    107                             catch (...)
    108                             {
    109                                 ExtractUnitResultInformation(std::current_exception(), unitResult);
    110                             }
    111                         }
    112                     }
    113                 }
    114                 else
    115                 {
    116                     testResult = ConfigurationTestResult::NotRun;
    117                 }
    118 
    119                 if (FAILED(unitResult->ResultCode()))
    120                 {
    121                     testResult = ConfigurationTestResult::Failed;
    122                 }
    123 
    124                 // Check if we need to construct our own result object
    125                 if (!settingsResult)
    126                 {
    127                     auto testSettingsResult = make_self<wil::details::module_count_wrapper<implementation::TestSettingsResult>>();
    128                     testSettingsResult->Unit(unit);
    129                     testSettingsResult->TestResult(testResult);
    130                     testSettingsResult->ResultInformation(*unitResult);
    131                     settingsResult = *testSettingsResult;
    132                 }
    133 
    134                 result->AppendUnitResult(settingsResult);
    135 
    136                 try
    137                 {
    138                     progressHandler(nullptr, settingsResult);
    139                 }
    140                 CATCH_LOG();
    141             }
    142 
    143             co_return *result;
    144         }
    145         catch (...)
    146         {
    147             ExtractUnitResultInformation(std::current_exception(), result->ResultInformationInternal());
    148             throw;
    149         }
    150     }
    151 
    152     Windows::Foundation::IAsyncOperation<IApplyGroupSettingsResult> DefaultSetGroupProcessor::ApplyGroupSettingsAsync(Windows::Foundation::EventHandler<IApplyGroupMemberSettingsResult> progressHandler)
    153     {
    154         auto strongThis = get_strong();
    155         co_await resume_background();
    156 
    157         ConfigurationSetApplyProcessor applyProcessor{ m_set, m_setProcessor, { std::move(progressHandler), co_await winrt::get_cancellation_token() } };
    158         applyProcessor.Process(m_consistencyCheckOnly);
    159 
    160         co_return applyProcessor.Result();
    161     }
    162 
    163     void DefaultSetGroupProcessor::ThrowIf(bool cancellation)
    164     {
    165         if (cancellation)
    166         {
    167             AICLI_LOG_DIRECT(m_threadGlobals->GetDiagnosticLogger(), Config, Warning, << "Operation cancelled");
    168             throw winrt::hresult_canceled();
    169         }
    170     }
    171 }