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 }