ConfigurationSet.cpp (10679B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #include "pch.h" 4 #include "ConfigurationSet.h" 5 #include "ConfigurationSet.g.cpp" 6 #include "ConfigurationSetParser.h" 7 #include "ConfigurationSetSerializer.h" 8 #include "Database/ConfigurationDatabase.h" 9 #include <AppInstallerLanguageUtilities.h> 10 11 namespace winrt::Microsoft::Management::Configuration::implementation 12 { 13 namespace impl 14 { 15 struct EnvironmentData 16 { 17 EnvironmentData(Configuration::ConfigurationEnvironment environment) : 18 Environment(environment), Context(environment.Context()), Identifier(environment.ProcessorIdentifier()), Properties(environment.ProcessorProperties()) 19 { 20 } 21 22 EnvironmentData(EnvironmentData&&) = default; 23 24 bool operator==(const EnvironmentData& other) const 25 { 26 return 27 Context == other.Context && 28 Identifier == other.Identifier && 29 ConfigurationEnvironment::AreEqual(Properties, other.Properties); 30 } 31 32 Configuration::ConfigurationEnvironment Environment; 33 SecurityContext Context; 34 hstring Identifier; 35 Windows::Foundation::Collections::IMap<hstring, hstring> Properties; 36 }; 37 38 bool ContainsEnvironment(const std::vector<EnvironmentData>& uniqueEnvironments, const EnvironmentData& data) 39 { 40 for (const EnvironmentData& item : uniqueEnvironments) 41 { 42 if (item == data) 43 { 44 return true; 45 } 46 } 47 48 return false; 49 } 50 51 void ComputeUniqueEnvironments(std::vector<EnvironmentData>& uniqueEnvironments, const Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit>& units) 52 { 53 for (const Configuration::ConfigurationUnit& unit : units) 54 { 55 if (unit.IsActive()) 56 { 57 EnvironmentData data{ unit.Environment() }; 58 if (!ContainsEnvironment(uniqueEnvironments, data)) 59 { 60 uniqueEnvironments.emplace_back(std::move(data)); 61 } 62 63 if (unit.IsGroup()) 64 { 65 ComputeUniqueEnvironments(uniqueEnvironments, unit.Units()); 66 } 67 } 68 } 69 } 70 } 71 72 ConfigurationSet::ConfigurationSet() 73 { 74 GUID instanceIdentifier; 75 THROW_IF_FAILED(CoCreateGuid(&instanceIdentifier)); 76 m_instanceIdentifier = instanceIdentifier; 77 std::tie(m_schemaVersion, m_schemaUri) = ConfigurationSetParser::LatestVersion(); 78 } 79 80 ConfigurationSet::ConfigurationSet(const guid& instanceIdentifier) : 81 m_instanceIdentifier(instanceIdentifier) 82 { 83 } 84 85 void ConfigurationSet::Units(std::vector<Configuration::ConfigurationUnit>&& units) 86 { 87 m_units = winrt::multi_threaded_vector<Configuration::ConfigurationUnit>(std::move(units)); 88 } 89 90 void ConfigurationSet::Parameters(std::vector<Configuration::ConfigurationParameter>&& value) 91 { 92 m_parameters = winrt::multi_threaded_vector<Configuration::ConfigurationParameter>(std::move(value)); 93 } 94 95 hstring ConfigurationSet::Name() 96 { 97 return m_name; 98 } 99 100 void ConfigurationSet::Name(const hstring& value) 101 { 102 m_name = value; 103 } 104 105 hstring ConfigurationSet::Origin() 106 { 107 return m_origin; 108 } 109 110 void ConfigurationSet::Origin(const hstring& value) 111 { 112 m_origin = value; 113 } 114 115 hstring ConfigurationSet::Path() 116 { 117 return m_path; 118 } 119 120 void ConfigurationSet::Path(const hstring& value) 121 { 122 m_path = value; 123 } 124 125 guid ConfigurationSet::InstanceIdentifier() const 126 { 127 return m_instanceIdentifier; 128 } 129 130 ConfigurationSetState ConfigurationSet::State() 131 { 132 auto status = ConfigurationStatus::Instance(); 133 return status->GetSetState(m_instanceIdentifier); 134 } 135 136 clock::time_point ConfigurationSet::FirstApply() 137 { 138 auto status = ConfigurationStatus::Instance(); 139 return status->GetSetFirstApply(m_instanceIdentifier); 140 } 141 142 clock::time_point ConfigurationSet::ApplyBegun() 143 { 144 auto status = ConfigurationStatus::Instance(); 145 return status->GetSetApplyBegun(m_instanceIdentifier); 146 } 147 148 clock::time_point ConfigurationSet::ApplyEnded() 149 { 150 auto status = ConfigurationStatus::Instance(); 151 return status->GetSetApplyEnded(m_instanceIdentifier); 152 } 153 154 Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit> ConfigurationSet::Units() 155 { 156 return m_units; 157 } 158 159 void ConfigurationSet::Units(const Windows::Foundation::Collections::IVector<ConfigurationUnit>& value) 160 { 161 THROW_HR_IF(E_POINTER, !value); 162 m_units = value; 163 } 164 165 hstring ConfigurationSet::SchemaVersion() 166 { 167 return m_schemaVersion; 168 } 169 170 void ConfigurationSet::SchemaVersion(const hstring& value) 171 { 172 THROW_HR_IF(E_INVALIDARG, !ConfigurationSetParser::IsRecognizedSchemaVersion(value)); 173 m_schemaUri = ConfigurationSetParser::GetSchemaUriForVersion(value); 174 m_schemaVersion = value; 175 } 176 177 void ConfigurationSet::ConfigurationSetChange(com_ptr<ConfigurationSetChangeData>& data, const std::optional<guid>& unitInstanceIdentifier) try 178 { 179 if (unitInstanceIdentifier) 180 { 181 Windows::Foundation::Collections::IVector<ConfigurationUnit> comUnits = m_units; 182 183 std::vector<ConfigurationUnit> units{ comUnits.Size() }; 184 units.resize(comUnits.GetMany(0, units)); 185 186 for (const ConfigurationUnit& unit : units) 187 { 188 if (unit.InstanceIdentifier() == unitInstanceIdentifier.value()) 189 { 190 data->Unit(unit); 191 break; 192 } 193 } 194 } 195 196 m_configurationSetChange(*get_strong(), *data); 197 } 198 CATCH_LOG(); 199 200 event_token ConfigurationSet::ConfigurationSetChange(const Windows::Foundation::TypedEventHandler<WinRT_Self, Configuration::ConfigurationSetChangeData>& handler) 201 { 202 if (!m_configurationSetChange) 203 { 204 auto status = ConfigurationStatus::Instance(); 205 std::atomic_store(&m_setChangeRegistration, status->RegisterForSetChange(*this)); 206 } 207 208 return m_configurationSetChange.add(handler); 209 } 210 211 void ConfigurationSet::ConfigurationSetChange(const event_token& token) noexcept 212 { 213 m_configurationSetChange.remove(token); 214 215 if (!m_configurationSetChange) 216 { 217 std::atomic_store(&m_setChangeRegistration, {}); 218 } 219 } 220 221 void ConfigurationSet::Serialize(const Windows::Storage::Streams::IOutputStream& stream) 222 { 223 std::unique_ptr<ConfigurationSetSerializer> serializer = ConfigurationSetSerializer::CreateSerializer(m_schemaVersion); 224 hstring result = serializer->Serialize(this); 225 auto resultUtf8 = winrt::to_string(result); 226 std::vector<uint8_t> bytes(resultUtf8.begin(), resultUtf8.end()); 227 228 Windows::Storage::Streams::DataWriter dataWriter{ stream }; 229 dataWriter.WriteBytes(bytes); 230 dataWriter.StoreAsync().get(); 231 dataWriter.DetachStream(); 232 } 233 234 void ConfigurationSet::Remove() 235 { 236 ConfigurationDatabase database; 237 database.EnsureOpened(false); 238 database.RemoveSetHistory(*get_strong()); 239 } 240 241 Windows::Foundation::Collections::ValueSet ConfigurationSet::Metadata() 242 { 243 return m_metadata; 244 } 245 246 void ConfigurationSet::Metadata(const Windows::Foundation::Collections::ValueSet& value) 247 { 248 THROW_HR_IF(E_POINTER, !value); 249 m_metadata = value; 250 } 251 252 Windows::Foundation::Collections::IVector<ConfigurationParameter> ConfigurationSet::Parameters() 253 { 254 return m_parameters; 255 } 256 257 void ConfigurationSet::Parameters(const Windows::Foundation::Collections::IVector<ConfigurationParameter>& value) 258 { 259 THROW_HR_IF(E_POINTER, !value); 260 m_parameters = value; 261 } 262 263 Windows::Foundation::Collections::ValueSet ConfigurationSet::Variables() 264 { 265 return m_variables; 266 } 267 268 void ConfigurationSet::Variables(const Windows::Foundation::Collections::ValueSet& value) 269 { 270 THROW_HR_IF(E_POINTER, !value); 271 m_variables = value; 272 } 273 274 Windows::Foundation::Uri ConfigurationSet::SchemaUri() 275 { 276 return m_schemaUri; 277 } 278 279 void ConfigurationSet::SchemaUri(const Windows::Foundation::Uri& value) 280 { 281 THROW_HR_IF(E_INVALIDARG, !ConfigurationSetParser::IsRecognizedSchemaUri(value)); 282 m_schemaVersion = ConfigurationSetParser::GetSchemaVersionForUri(value); 283 m_schemaUri = value; 284 } 285 286 Configuration::ConfigurationEnvironment ConfigurationSet::Environment() 287 { 288 return *m_environment; 289 } 290 291 implementation::ConfigurationEnvironment& ConfigurationSet::EnvironmentInternal() 292 { 293 return *m_environment; 294 } 295 296 std::vector<Configuration::ConfigurationEnvironment> ConfigurationSet::GetUnitEnvironmentsInternal() 297 { 298 std::vector<impl::EnvironmentData> uniqueEnvironments; 299 ComputeUniqueEnvironments(uniqueEnvironments, m_units); 300 301 std::vector<Configuration::ConfigurationEnvironment> result; 302 for (const impl::EnvironmentData& data : uniqueEnvironments) 303 { 304 result.emplace_back(*make_self<implementation::ConfigurationEnvironment>(data.Environment)); 305 } 306 return result; 307 } 308 309 Windows::Foundation::Collections::IVector<Configuration::ConfigurationEnvironment> ConfigurationSet::GetUnitEnvironments() 310 { 311 return single_threaded_vector(GetUnitEnvironmentsInternal()); 312 } 313 314 HRESULT STDMETHODCALLTYPE ConfigurationSet::SetLifetimeWatcher(IUnknown* watcher) 315 { 316 return AppInstaller::WinRT::LifetimeWatcherBase::SetLifetimeWatcher(watcher); 317 } 318 319 void ConfigurationSet::SetInputHash(std::string inputHash) 320 { 321 m_inputHash = std::move(inputHash); 322 } 323 324 const std::string& ConfigurationSet::GetInputHash() const 325 { 326 return m_inputHash; 327 } 328 }