From 99c17146caaa6a46fd62bf40ad11cb9fe49dc5e5 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Thu, 15 Dec 2022 11:45:56 -0800 Subject: [PATCH 01/31] Commit before moving to internal --- src/AppInstallerCLI.sln | 42 ++ .../Microsoft.Management.Configuration.idl | 443 ++++++++++++++++++ ...Microsoft.Management.Configuration.vcxproj | 162 +++++++ ...t.Management.Configuration.vcxproj.filters | 18 + .../Microsoft_Management_Configuration.def | 3 + .../PropertySheet.props | 16 + .../packages.config | 5 + src/Microsoft.Management.Configuration/pch.h | 8 + 8 files changed, 697 insertions(+) create mode 100644 src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl create mode 100644 src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj create mode 100644 src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters create mode 100644 src/Microsoft.Management.Configuration/Microsoft_Management_Configuration.def create mode 100644 src/Microsoft.Management.Configuration/PropertySheet.props create mode 100644 src/Microsoft.Management.Configuration/packages.config create mode 100644 src/Microsoft.Management.Configuration/pch.h diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index 7b0c805c38..63e8fa4b77 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -142,6 +142,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "templates", "templates", "{ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PureLib", "PureLib\PureLib.vcxproj", "{BB14D603-F44E-4415-8770-BF3E13F4C17F}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Configuration", "Microsoft.Management.Configuration\Microsoft.Management.Configuration.vcxproj", "{CA460806-5E41-4E97-9A3D-1D74B433B663}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1061,6 +1063,46 @@ Global {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|x64.Build.0 = Release|x64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|x86.ActiveCfg = Release|Win32 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|x86.Build.0 = Release|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|Any CPU.ActiveCfg = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|Any CPU.Build.0 = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM.ActiveCfg = Debug|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM.Build.0 = Debug|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM64.Build.0 = Debug|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x64.ActiveCfg = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x64.Build.0 = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x86.ActiveCfg = Debug|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x86.Build.0 = Debug|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|Any CPU.ActiveCfg = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|Any CPU.Build.0 = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM.ActiveCfg = Debug|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM.Build.0 = Debug|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM64.Build.0 = Debug|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x64.ActiveCfg = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x64.Build.0 = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x86.ActiveCfg = Debug|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x86.Build.0 = Debug|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|Any CPU.ActiveCfg = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|Any CPU.Build.0 = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM.ActiveCfg = Release|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM.Build.0 = Release|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM64.ActiveCfg = Release|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM64.Build.0 = Release|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x64.ActiveCfg = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x64.Build.0 = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x86.ActiveCfg = Release|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x86.Build.0 = Release|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|Any CPU.ActiveCfg = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|Any CPU.Build.0 = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM.ActiveCfg = Release|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM.Build.0 = Release|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM64.Build.0 = Release|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x64.ActiveCfg = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x64.Build.0 = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x86.ActiveCfg = Release|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl new file mode 100644 index 0000000000..4b681cfc00 --- /dev/null +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -0,0 +1,443 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +namespace Microsoft.Management.Configuration +{ + [contractversion(1)] + apicontract Contract{}; + + // The current state of a configuration set. + [contract(Microsoft.Management.Configuration.Contract, 1)] + enum ConfigurationSetState + { + Unknown, + ApplicationPending, + ApplicationBegun, + ApplicationFailed, + ApplicationSucceeded, + }; + + // The current state of a configuration unit. + [contract(Microsoft.Management.Configuration.Contract, 1)] + enum ConfigurationUnitState + { + Unknown, + ApplicationPending, + ApplicationBegun, + ApplicationFailed, + ApplicationSucceeded, + SkippedManually, + SkippedDueToDependencies, + }; + + // Defines the level of detail that is desired about a configuration unit. + [contract(Microsoft.Management.Configuration.Contract, 1)] + enum ConfigurationUnitDetailLevel + { + // Only reads details from local data. + Local, + // Will query the catalog information for details, but will not download any modules. + Catalog, + // Will download modules, but not load them. + Download, + // Will download and load modules for details. + Load, + }; + + // Information on a failure for a single unit of configuration. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass ConfigurationUnitFailureInformation + { + // The error code of the failure. + HRESULT ResultCode{ get; }; + + // The description of the failure. + String Description{ get; }; + } + + // This interface provides information and access for a specific configuration unit within the runtime. + [contract(Microsoft.Management.Configuration.Contract, 1)] + interface IConfigurationUnitSettingDetails + { + // The name of the setting. + String Name{ get; }; + // The description of the setting. + String Description{ get; }; + // Whether the setting is a key. This is used to determine if different settings are in conflict. + Boolean IsKey{ get; }; + // Whether a non-empty value for the setting is required. + Boolean IsRequired{ get; }; + // Whether the setting should be serialized in order to be applied on another system. + // When the current settings are retrieved from the system, this can be used to exclude settings that are not relevant to a future application of the unit of configuration. + Boolean IsInformational{ get; }; + // The data type for the value of this setting. + Windows.Foundation.PropertyType Type{ get; }; + // The semantics to be used for this setting. + // The goal is to enable richer conflict detection and authoring scenarios by having a deeper understanding of this value than "String". + // TODO: Create the actual semantics of the semantics value... + String Semantics{ get; }; + } + + // This interface provides information about a specific configuration unit processor within the runtime. + [contract(Microsoft.Management.Configuration.Contract, 1)] + interface IConfigurationUnitProcessorDetails + { + // The name of the unit of configuration. + String UnitName{ get; }; + // A description of the unit of configuration. + String UnitDescription{ get; }; + // The URI of the documentation for the unit of configuration. + Windows.Foundation.Uri UnitDocumentationUri{ get; }; + // The URI of the icon for the unit of configuration. + Windows.Foundation.Uri UnitIconUri{ get; }; + // The name of the module containing the unit of configuration. + String ModuleName{ get; }; + // The type of the module containing the unit of configuration. + String ModuleType{ get; }; + // The source of the module containing the unit of configuration. + String ModuleSource{ get; }; + // The description of the module containing the unit of configuration. + String ModuleDescription{ get; }; + // The URI of the documentation for the module containing the unit of configuration. + Windows.Foundation.Uri ModuleDocumentationUri{ get; }; + // The URI for the published module containing the unit of configuration. + Windows.Foundation.Uri PublishedModuleUri{ get; }; + // The version of the module containing the unit of configuration. + String Version{ get; }; + // The publishing date of the module containing the unit of configuration. + Windows.Foundation.DateTime PublishedDate{ get; }; + // Whether the module is already present on the system. + Boolean IsLocal{ get; }; + // The author of the module containing the unit of configuration. + String Author{ get; }; + // The publisher of the module containing the unit of configuration. + String Publisher{ get; }; + // The signing certificate chain of the module containing the unit of configuration. + Windows.Security.Cryptography.Certificates.CertificateChain SigningCertificateChain{ get; }; + // The settings information for the unit of configuration. + Windows.Foundation.Collections.IVectorView Settings{ get; }; + } + + // A single unit of configuration. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass ConfigurationUnit + { + // Creates an empty configuration unit for authoring purposes. + ConfigurationUnit(); + + // The name of the unit being configured; not a name for this instance. + // Can be changed if a mutable unit. + String UnitName; + + // An identifier used to uniquely identify the instance of a configuration unit on the system. + // Immutable, although the unit can be removed and an identical unit applied later with a different identifier. + Guid InstanceIdentifier{ get; }; + + // The identifier name of this instance within the set. + // Can be changed if a mutable unit. + String Identifier; + + // The configuration units that this unit depends on. + // Can be set on a mutable configuration unit; this will copy the items into the internal storage. + Windows.Foundation.Collections.IVectorView Dependencies; + + // Contains the values that are for use by the configuration system, related to this unit. + Windows.Foundation.Collections.ValueSet Directives{ get; }; + + // Contains the values that are for use by the configuration unit itself. + Windows.Foundation.Collections.ValueSet Settings; + + // Contains information on the origin of the configuration unit. + // May be null if ConfigurationProcessor.GetDetailsAsync has not been called yet. + IConfigurationUnitProcessorDetails Details{ get; }; + + // The current state of the configuration unit. + ConfigurationUnitState State{ get; }; + + // If the State is ApplicationFailed, this object should exist with additional details on the latest failure. + ConfigurationUnitFailureInformation FailureInformation{ get; }; + + // Allows for control over whether this unit should be applied when the set containing it is applied. + Boolean ShouldApply; + } + + // The change event type that has occurred. + [contract(Microsoft.Management.Configuration.Contract, 1)] + enum ConfigurationSetChangeEventType + { + Unknown, + SetStateChanged, + UnitStateChanged, + }; + + // The change data sent about changes to a specific set. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass ConfigurationSetChangeData + { + // The change event type that occurred. + ConfigurationSetChangeEventType Change{ get; }; + + // The state of the configuration set for this event (the ConfigurationSet can be used to get the current state, which may be different). + ConfigurationSetState SetState{ get; }; + + // The state of the configuration unit for this event (the ConfigurationUnit can be used to get the current state, which may be different). + ConfigurationUnitState UnitState{ get; }; + + // If the UnitState is ApplicationFailed, this object should exist with additional details on the failure. + ConfigurationUnitFailureInformation FailureInformation{ get; }; + + // The configuration unit whose state changed. + ConfigurationUnit Unit{ get; }; + } + + // A configuration set contains a collection of configuration units and details about the set. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass ConfigurationSet + { + // Creates an empty, mutable configuration set for authoring purposes. + ConfigurationSet(); + + // Loads a mutable configuration set from the given stream. + ConfigurationSet(Windows.Storage.Streams.IInputStream stream); + + // The name of the set; if from a file this could be the file name. + // Can be changed if a mutable set. + String Name; + // The origin of the set; if it came from a repository it could be the remote URL (ex. https://github.com/microsoft/winget-cli.git). + // Can be changed if a mutable set. + String Origin; + + // An identifier used to uniquely identify the instance of a configuration set on the system. + // Immutable, although the set can be removed and an identical set applied later with a different identifier. + Guid InstanceIdentifier{ get; }; + // The state that the set is in. + ConfigurationSetState State{ get; }; + // The time that this set was recorded with intent to apply. + Windows.Foundation.DateTime InitialIntent{ get; }; + // The time that this set was last started to be applied. + Windows.Foundation.DateTime ApplyBegun{ get; }; + // The time that this set was last finished being applied (does not indicate success). + Windows.Foundation.DateTime ApplyEnded{ get; }; + + // The configuration units that are part of this set. + // Can be set on a mutable configuration set; this will copy the items into the internal storage. + Windows.Foundation.Collections.IVectorView ConfigurationUnits; + + // Only changes for this set are sent to this event. + // This includes things like: start/stop of the entire set for application or test, start/stop of a unit for application or test. + event Windows.Foundation.TypedEventHandler ConfigurationSetChange; + + // Writes the configuration set to the given stream. + void Serialize(Windows.Storage.Streams.IOutputStream stream); + + // Removes a configuration set from the system history. Only usable on a set that came from `Statics.GetConfigurationHistory`. + void Remove(); + } + + // This interface provides information and access for a specific configuration unit within the runtime. + [contract(Microsoft.Management.Configuration.Contract, 1)] + interface IConfigurationUnitProcessor + { + // The configuration unit that the processor was created for. + ConfigurationUnit Unit{ get; }; + + // The directives overlay that the processor was created with. + Windows.Foundation.Collections.ValueSet DirectivesOverlay{ get; }; + + // Determines if the system is already in the state described by the configuration unit. + Boolean TestSettings(); + + // Gets the current system state for the configuration unit. + Windows.Foundation.Collections.ValueSet GetSettings(); + + // Applies the state described in the configuration unit. + void ApplySettings(); + } + + // This interface allows different runtimes to provide specialized handling of configuration processing. + [contract(Microsoft.Management.Configuration.Contract, 1)] + interface IConfigurationProcessorFactory + { + // Gets the configuration unit processor details for the given unit. + IConfigurationUnitProcessorDetails GetUnitProcessorGetails(ConfigurationUnit unit); + + // Creates a configuration unit processor for the given unit. + // The optional `directivesOverlay` parameter allows for the `ConfigurationProcessor` to alter behavior without needing to change the unit itself. + // The overlay is searched first; any value not present there will then fall back to the unit's directives. + IConfigurationUnitProcessor CreateUnitProcessor(ConfigurationUnit unit, Windows.Foundation.Collections.ValueSet directivesOverlay); + } + + // The type of conflict that occurred. + [contract(Microsoft.Management.Configuration.Contract, 1)] + enum ConfigurationConflictType + { + Unknown, + // Indicates that the first configuration set has a matching name and origin to the second, which has already been applied. + // This is likely an update to the existing set, and should be applied as such, rather than an entirely new set. + MatchingOrigin, + // Indicates that the first configuration set is identical to the second, that has already been applied. + // This is based solely on the configuration unit settings. + IdenticalSetApplied, + // Indicates a conflict between the settings of two configuration units. + SettingsConflict, + }; + + // Describes a conflict between a setting of two configuration units. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass ConfigurationConflictSetting + { + // The name of the setting. + String Name{ get; }; + + // The value from the first configuration unit. + // These are the values from a `ValueSet`, and are thus required to be a `PopertyValue` or a 'ValueSet`. + Object FirstValue{ get; }; + + // The value from the second configuration unit. + // These are the values from a `ValueSet`, and are thus required to be a `PopertyValue` or a 'ValueSet`. + Object SecondValue{ get; }; + } + + // Describes a conflict between two configurations. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass ConfigurationConflict + { + // The type of conflict detected. + ConfigurationConflictType Conflict{ get; }; + + // The first of the configuration sets involved in the conflict. + ConfigurationSet FirstSet{ get; }; + + // The second of the configuration sets involved in the conflict. + ConfigurationSet SecondSet{ get; }; + + // The first of the configuration units involved in the conflict. + ConfigurationUnit FirstUnit{ get; }; + + // The second of the configuration units involved in the conflict. + ConfigurationUnit SecondUnit{ get; }; + + // Contains information about the particular settings that are conflicting. + Windows.Foundation.Collections.IVectorView Settings{ get; }; + } + + // Flags to control how a configuration set should be applied to the system. + [contract(Microsoft.Management.Configuration.Contract, 1)] + enum ApplyConfigurationSetFlags + { + None = 0x0, + // Forces a new configuration set instance to be recorded when the set being applied matches a previous set's origin. + // The default behavior is to assume that the incoming set is an update to the existing set and overwrite it. + DoNotOverwriteMatchingOriginSet = 0x1, + }; + + // The result of applying the settings for a configuration unit. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass ApplyConfigurationUnitResult + { + // The result from applying the configuration unit. + HRESULT ResultCode{ get; }; + } + + // The result of applying the settings for a configuration set. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass ApplyConfigurationSetResult + { + // Results for each configuration unit in the set. + Windows.Foundation.Collections.IVectorView UnitResults{ get; }; + + // The overall result from applying the configuration set. + HRESULT ResultCode{ get; }; + } + + // The result of testing the settings for a configuration unit. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass TestConfigurationUnitResult + { + // The configuration unit that was tested. + ConfigurationUnit Unit{ get; }; + + // Will be true if the system is in the state described by the configuration unit; false otherwise. + Boolean TestResult{ get; }; + } + + // The result of testing the settings for a configuration set. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass TestConfigurationSetResult + { + // Results for each configuration unit in the set. + Windows.Foundation.Collections.IVectorView UnitResults{ get; }; + + // Will be true if the system is in the state described by the entire configuration set; false otherwise (if any unit is not in the described state). + Boolean TestResult{ get; }; + } + + // The result of getting the settings for a configuration unit. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass GetConfigurationUnitSettingsResult + { + // The current state of the system for the configuration unit. + Windows.Foundation.Collections.ValueSet Settings { get; }; + } + + // The configuration processor is responsible for the interactions with the system. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass ConfigurationProcessor + { + ConfigurationProcessor(IConfigurationProcessorFactory factory); + + // Checks for conflicts amongst the configuration sets provided, optionally including the configuration sets already applied to the system. + Windows.Foundation.IAsyncOperation< Windows.Foundation.Collections.IVectorView > CheckForConflictsAsync(Windows.Foundation.Collections.IVectorView configurationSets, Boolean includeConfigurationHistory); + + // Gets the details for all configuration units in a set. + Windows.Foundation.IAsyncAction GetSetDetailsAsync(ConfigurationSet configurationSet, ConfigurationUnitDetailLevel detailLevel); + + // Gets the details for a configuration unit. + Windows.Foundation.IAsyncAction GetUnitDetailsAsync(ConfigurationUnit unit, ConfigurationUnitDetailLevel detailLevel); + + // Applies the configuration set state; to get progress, attach a delegate to the ConfigurationSetChange before calling this method. + Windows.Foundation.IAsyncOperation ApplyAsync(ConfigurationSet configurationSet, ApplyConfigurationSetFlags flags); + + // Tests the configuration set state; to get progress, attach a delegate to the ConfigurationSetChange before calling this method. + Windows.Foundation.IAsyncOperation TestAsync(ConfigurationSet configurationSet); + + // Gets the current configuration unit settings. + Windows.Foundation.IAsyncOperation GetSettingsAsync(ConfigurationUnit unit); + } + + // The change event type that has occurred. + [contract(Microsoft.Management.Configuration.Contract, 1)] + enum ConfigurationChangeEventType + { + Unknown, + SetAdded, + SetStateChanged, + SetRemoved, + }; + + // The change data sent about changes to sets. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass ConfigurationChangeData + { + // The change event type that occurred. + ConfigurationChangeEventType Change{ get; }; + + // The identifier used to uniquely identify the instance of a configuration set on the system. + Guid InstanceIdentifier{ get; }; + + // The state of the configuration set for this event (the ConfigurationSet can be used to get the current state, which may be different). + ConfigurationSetState State{ get; }; + } + + // Statics of Microsoft.Management.Configuration + [contract(Microsoft.Management.Configuration.Contract, 1)] + static runtimeclass Statics + { + // Only top level configuration changes are sent to this event. + // This includes things like: creation of a new set for intent to run, start/stop of a set for application or test, deletion of a not started set. + static event Windows.Foundation.TypedEventHandler ConfigurationChange; + + // Gets the configuration sets that have already been applied or the intent to be applied (this may include in progress sets or those that are waiting on others). + // These configuration sets will be marked as immutable. + static Windows.Foundation.Collections.IVectorView GetConfigurationHistory(); + } +} diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj new file mode 100644 index 0000000000..934131f2d6 --- /dev/null +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -0,0 +1,162 @@ + + + + + true + true + true + true + {CA460806-5E41-4E97-9A3D-1D74B433B663} + Microsoft.Management.Configuration + Microsoft.Management.Configuration + en-US + 14.0 + 10.0 + 10.0.22000.0 + 10.0.17763.0 + true + true + -library Microsoft_Management_Configuration + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + StaticLibrary + v140 + v141 + v142 + v143 + Unicode + false + + + true + true + + + false + true + false + Spectre + + + + + + + + + + + + + $(VC_IncludePath);$(WindowsSDK_IncludePath); + $(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\ + $(PlatformTarget)\$(Configuration)\ + $(RootNamespace).Server + true + false + ..\CodeAnalysis.ruleset + + + + Use + pch.h + $(IntDir)pch.pch + Level4 + %(AdditionalOptions) /bigobj + true + true + _WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) + $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) + %(AdditionalIncludeDirectories) + + + Console + false + Microsoft_Management_Configuration.def + $(OutDir)$(ProjectName).winmd + %(AdditionalDependencies) + + + + + _DEBUG;%(PreprocessorDefinitions) + $(OutDir)$(TargetName)Debug.pdb + + + + + NDEBUG;%(PreprocessorDefinitions) + + + true + true + + + + + + + + Create + + + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters new file mode 100644 index 0000000000..7c520a610f --- /dev/null +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.Management.Configuration/Microsoft_Management_Configuration.def b/src/Microsoft.Management.Configuration/Microsoft_Management_Configuration.def new file mode 100644 index 0000000000..8c1a02932d --- /dev/null +++ b/src/Microsoft.Management.Configuration/Microsoft_Management_Configuration.def @@ -0,0 +1,3 @@ +EXPORTS +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/src/Microsoft.Management.Configuration/PropertySheet.props b/src/Microsoft.Management.Configuration/PropertySheet.props new file mode 100644 index 0000000000..e34141b019 --- /dev/null +++ b/src/Microsoft.Management.Configuration/PropertySheet.props @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.Management.Configuration/packages.config b/src/Microsoft.Management.Configuration/packages.config new file mode 100644 index 0000000000..5e899619db --- /dev/null +++ b/src/Microsoft.Management.Configuration/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/Microsoft.Management.Configuration/pch.h b/src/Microsoft.Management.Configuration/pch.h new file mode 100644 index 0000000000..a12993ff40 --- /dev/null +++ b/src/Microsoft.Management.Configuration/pch.h @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include +#include +#include + +#include \ No newline at end of file From e55bd0840c9ab0574443000514c2a2a9d81c4758 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Fri, 16 Dec 2022 15:20:58 -0800 Subject: [PATCH 02/31] Add API review doc and minor IDL changes --- doc/specs/Configuration-COM-API.md | 663 ++++++++++++++++++ .../Microsoft.Management.Configuration.idl | 60 +- 2 files changed, 700 insertions(+), 23 deletions(-) create mode 100644 doc/specs/Configuration-COM-API.md diff --git a/doc/specs/Configuration-COM-API.md b/doc/specs/Configuration-COM-API.md new file mode 100644 index 0000000000..233d1a6106 --- /dev/null +++ b/doc/specs/Configuration-COM-API.md @@ -0,0 +1,663 @@ + + +Microsoft.Management.Configuration API +=== + +# Background +This API is being added to enable the Developer+ configuration scenarios. It enables interacting with +configuration sets in three contexts: + +1. Loading an existing configuration set from a stream +2. Loading previously applied configuration sets from the local history +3. Authoring a new/editing an existing configuration + +These configuration sets are composed of configuration units, which describe the individual configurable +items and the values to configure. + +Configuration actions consist of: + +1. Test :: Determining whether the system state matches the described state +2. Get :: Extracting the current system state with respect to the configuration scope +3. Set :: Applying the described state to the system + +This API is also intended to support multiple processes watching for state changes, both for the +configuration set lifetimes and the individual configuration unit states. + +# Conceptual pages (How To) + +_(Add conceptual documentation that will go to docs.microsoft.com "how to" page if needed)_ + +# API Pages + + + +## ConfigurationSetState enumeration + +The state of a configuration set in the configuration history. + +| Name | Description | +|-|-| +| Unknown | Primarily used for a configuration set that has not been applied. | +| ApplicationPending | The configuration set has been recorded into the history, but has not yet begun applying. | +| ApplicationBegun | The configuration set has begun being applied to the system. | +| ApplicationFailed | The configuration set has completed being applied, and one or more configuration units failed to apply. | +| ApplicationSucceeded | The configuration set has completed being applied successfully. | + +## ConfigurationUnitState enumeration + +The state of a configuration unit in the configuration history. + +| Name | Description | +|-|-| +| Unknown | Primarily used for a configuration unit that has not been applied. | +| ApplicationPending | The configuration unit has been recorded into the history, but has not yet begun applying. | +| ApplicationBegun | The configuration unit has begun being applied to the system. | +| ApplicationFailed | The configuration unit has completed being applied, but it failed. | +| ApplicationSucceeded | The configuration unit has completed being applied successfully. | +| SkippedManually | The configuration unit was skipped by the user. | +| SkippedDueToDependencies | The configuration unit was skipped due to a dependency not having been successfully applied. | +| TestBegun | The configuration unit has begun testing the system state. This state is only sent locally to the set being tested. | +| TestFailed | The configuration unit testing has failed. This state is only sent locally to the set being tested. | +| TestSucceeded | The configuration unit testing has succeeded. This state is only sent locally to the set being tested. | + +## ConfigurationUnitDetailLevel enumeration + +Defines the level of detail probing that is allowed about a configuration unit. + +| Name | Description | +|-|-| +| Local | Only reads details from local data. | +| Catalog | Will query the catalog information for details, but will not download any modules. | +| Download | Will download modules, but not load them. | +| Load | Will download and load modules for details. | + +## ConfigurationUnitResultInformation class + +Information on a result for a single unit of configuration. + +The class is used both in reporting results through the `ConfigurationSet.ConfigurationSetChange` event as they occur +and in viewing past results via the `ConfigurationUnit.ResultInformation` property on a historical record. + +## IConfigurationUnitSettingDetails interface + +Provides information for a specific configuration unit setting. + +The properties on this interface are useful for creating a rich authoring experience. + +## IConfigurationUnitSettingDetails.Semantics schema + +> _TODO: Define the meaning/schema for this value_ + +## IConfigurationUnitProcessorDetails interface + +Provides information for a specific configuration unit within the runtime. + +The properties on this interface are useful for informing the user about the provenance of the code that is +responsible for processing the configuration unit. + +## ConfigurationUnit class + +A single unit of configuration. + +Represents the smallest actionable configuration element. + +## ConfigurationUnit constructor + +Creates an empty configuration unit for authoring purposes. + +```C# +ConfigurationUnit(); +``` + +## ConfigurationUnit properties + +| Name | Description | +|-|-| +| UnitName | The name of the unit being configured; not a name for this instance. | +| InstanceIdentifier | An identifier used to uniquely identify the instance of a configuration unit on the system. | +| Identifier | The identifier name of this instance within the set. This value is referenced by other unit's `Dependencies`. | +| Dependencies | The identifiers of the configuration units that this unit depends on. | +| Directives | Contains the values that are for use by the configuration system, related to this unit. | +| Settings | Contains the values that are for use by the configuration unit itself. | +| Details | Contains information on the origin of the configuration unit. You must call `ConfigurationProcessor.Get*DetailsAsync` to populate this value. | +| State | The current state of the configuration unit. | +| ResultInformation | Contains information on the result of the latest attempt to apply the configuration unit. | +| ShouldApply | Allows for control over whether this unit should be applied when the set containing it is applied. | + +## ConfigurationUnit.Directives known values + +> _TODO: List of well known directives_ + +## ConfigurationSetChangeEventType enumeration + +The change event type that has occurred for a configuration set change. + +| Name | Description | +|-|-| +| Unknown | For future use if the caller is not aware of newer change types. | +| SetStateChanged | The state of the configuration set has changed. | +| UnitStateChanged | The state of a configuration unit has changed. | + +## ConfigurationSetChangeData class + +The change data sent about changes to a specific set. + +This class is sent to subscribers of the `ConfigurationSet.ConfigurationSetChange` event, containing information +about the specific change that occurred. + +## ConfigurationSet class + +A configuration set contains a collection of configuration units and details about the set. + +Represents a self contained group of configuration units that are operated on together. + +## ConfigurationSet constructors + +Creates an empty configuration set for authoring purposes. + +```C# +ConfigurationSet(); +``` + +Loads a configuration set from the given stream. + +```C# +ConfigurationSet(Windows.Storage.Streams.IInputStream stream); +``` + +## ConfigurationSet.ConfigurationSetChange event + +State changes for this set and it's units are sent to subscribers of this event. + +```C# +event Windows.Foundation.TypedEventHandler ConfigurationSetChange; +``` + +## ConfigurationSet.Serialize method + +Serializes the configuration set to the given output stream. + +```C# +void Serialize(Windows.Storage.Streams.IOutputStream stream); +``` + +## ConfigurationSet.Remove method + +Removes the configuration set from the recorded history, if present. + +```C# +void Remove(); +``` + +You can use this method to remove a configuration set that is no longer relevant. For example, it may have been for +a repository that is no longer being used by the user and future conflicts with it's configuration are not important. + +## ConfigurationSet properties + +| Name | Description | +|-|-| +| Name | The name of the set; if from a file this could be the file name. | +| Origin | The origin of the set; if it came from a repository it could be the remote URL (ex. https://github.com/microsoft/winget-cli.git). | +| InstanceIdentifier | An identifier used to uniquely identify the instance of a configuration set on the system. | +| State | The state that the set is in. | +| InitialIntent | The time that this set was recorded with intent to apply. | +| ApplyBegun | The time that this set was last started to be applied. | +| ApplyEnded | The time that this set was last finished being applied (does not indicate success). | +| ConfigurationUnits | The configuration units that are part of this set. | + +## IConfigurationUnitProcessor interface + +Provides access to a specific configuration unit within the runtime. + +This interface is the primary mechanism used to actually read and write configuration to the system, +but it is not expected that you would use this directly as a consumer of Microsoft.Management.Configuration. + +## IConfigurationProcessorFactory interface + +Allows different runtimes to provide specialized handling of configuration processing. + +It is not expected that you would use this interface directly, but rather the `ConfigurationProcessor` class. + +_Spec note: A separate binary (written by us) will contain the implementation(s) of this interface._ + +## ConfigurationConflictType enumeration + +The type of conflict between configuration sets that was detected. + +| Name | Description | +|-|-| +| Unknown | For future use if the caller is not aware of newer conflict types. | +| MatchingOrigin | Indicates that the first configuration set has a matching name and origin to the second, which has already been applied. | +| IdenticalSetApplied | Indicates that the first configuration set is identical to the second, which has already been applied. | +| SettingsConflict | Indicates a conflict between the settings of two configuration units. | + +## ConfigurationConflictSetting class + +Describes a conflict between a setting of two configuration units. + +## ConfigurationConflict class + +Describes a conflict between two configuration sets. + +## ApplyConfigurationSetFlags enumeration + +Flags to control how a configuration set should be applied to the system. + +| Name | Description | +|-|-| +| None | The configuration set should be applied in the default manner. | +| DoNotOverwriteMatchingOriginSet | Forces a new configuration set instance to be recorded when the set being applied matches a previous set's origin. The default behavior is to assume that the incoming set is an update to the existing set and overwrite it. | + +## ConfigurationProcessor class + +The configuration processor is responsible for the interactions with the system. + +You must use this class to do anything beyond reading configuration sets. It is the entrypoint for all actions that +will interact with the actual system configuration. + +## ConfigurationProcessor constructor + +Creates a configuration processor using the given configuration factory. + +```C# +ConfigurationProcessor(IConfigurationProcessorFactory factory); +``` + +> _TODO: Add details on the mechanics of creating the `IConfigurationProcessorFactory` objects that we provide._ + +## ConfigurationProcessor.CheckForConflictsAsync method + +Checks for conflicts amongst the configuration sets provided, optionally including the configuration sets already applied to the system. + +```C# +Windows.Foundation.IAsyncOperation< Windows.Foundation.Collections.IVectorView > CheckForConflictsAsync(Windows.Foundation.Collections.IVectorView configurationSets, Boolean includeConfigurationHistory); +``` + +This method should be used on any configuration set that is opened in order to determine if it would cause a conflict +with previously applied configurations. It should be called *after* setting the `Name` and `Origin` in order to determine +if it is a potential update. + +## ConfigurationProcessor.GetSetDetailsAsync method + +Gets the details for all configuration units in a set. + +```C# +Windows.Foundation.IAsyncAction GetSetDetailsAsync(ConfigurationSet configurationSet, ConfigurationUnitDetailLevel detailLevel); +``` + +This is a convenience/optimization method that will do the same thing as calling `GetUnitDetailsAsync` on each +configuration unit in the set. See `GetUnitDetailsAsync` for more information on what it will do. + +## ConfigurationProcessor.GetUnitDetailsAsync method + +Gets the details for all configuration units in a set. + +```C# +Windows.Foundation.IAsyncAction GetUnitDetailsAsync(ConfigurationUnit unit, ConfigurationUnitDetailLevel detailLevel); +``` + +This method will get the details about a specific configuration unit and make them available via `ConfigurationUnit.Details`. +The `detailLevel` parameter allows control over how deeply to probe for details. It is an analog for the amount of +trust to place in the configuration unit processor. + +## ConfigurationProcessor.ApplyAsync method + +Applies the configuration set state to the system. + +```C# +Windows.Foundation.IAsyncOperation ApplyAsync(ConfigurationSet configurationSet, ApplyConfigurationSetFlags flags); +``` + +To get progress, subscribe to the `ConfigurationSetChange` before calling this method. + +## ConfigurationProcessor.TestAsync method + +Tests if the system state matches the state described by the configuration set. + +```C# +Windows.Foundation.IAsyncOperation TestAsync(ConfigurationSet configurationSet); +``` + +To get progress, subscribe to the `ConfigurationSetChange` before calling this method. + +## ConfigurationProcessor.GetSettingsAsync method + +Gets the current configuration unit settings from the system state. + +```C# +Windows.Foundation.IAsyncOperation GetSettingsAsync(ConfigurationUnit unit); +``` + +## ConfigurationChangeEventType enumeration + +The configuration set change event type that has occurred. + +| Name | Description | +|-|-| +| Unknown | For future use if the caller is not aware of newer change types. | +| SetAdded | A new configuration set was recorded in the history with the intent to be applied. | +| SetStateChanged | A configuration set has changed state. | +| SetRemoved | A configuration set has been removed from the history. | + +## ConfigurationChangeEventType class + +The change data sent about changes to sets. + +## Statics.ConfigurationChange event + +Signals changes to the set of configuration sets in the history, as well as changes to the state of configuration sets in the history. + +## Statics.GetConfigurationHistory method + +Gets the configuration sets from the recorded history. + +```C# +static Windows.Foundation.Collections.IVectorView GetConfigurationHistory(); +``` + +Gets the configuration sets that have already been applied or those recorded with the intent to be applied. This may include in progress sets or those that are waiting to be applied. + +# API Details + +[Link to the MIDL3 file.](../../src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl) + +# Appendix + + + +# Sample + +This sample illustrates some of the expected usage patterns. + +```C# +using System; +using System.Collections.Generic; +using System.IO; +using Microsoft.Management.Configuration; +using Windows.Storage; +using Windows.Storage.Streams; + +namespace ConfigurationSample +{ + internal class Helpers + { + internal static IConfigurationProcessorFactory CreateIConfigurationProcessorFactory() + { + // While we will also implement these factories, that will be part of a separate binary. + throw new NotImplementedException(); + } + + internal static void SetWatcher(ConfigurationSet set, ConfigurationSetChangeData data) + { + Console.WriteLine($" - Set: {set.Name} [{set.InstanceIdentifier}]"); + Console.WriteLine($" Change: {data.Change}"); + Console.WriteLine($" Set State: {data.SetState}"); + switch (data.Change) + { + case ConfigurationSetChangeEventType.UnitStateChanged: + Console.WriteLine($" Unit: {data.Unit.UnitName} [{data.Unit.InstanceIdentifier}]"); + Console.WriteLine($" Unit State: {data.UnitState}"); + if (data.UnitState == ConfigurationUnitState.ApplicationFailed) + { + Console.WriteLine($" Failure: {data.ResultInformation.Description} [{data.ResultInformation.ResultCode.HResult}]"); + } + break; + } + } + } + + internal class Program + { + static void LoadAndOutput(string[] args) + { + // Open the given configuration file and load into a set + var file = FileRandomAccessStream.OpenAsync(args[2], FileAccessMode.Read).GetResults(); + ConfigurationSet configSet = new ConfigurationSet(file); + + // Create the factory and processor, then get more information on the configuration unit processors + ConfigurationProcessor processor = new ConfigurationProcessor(Helpers.CreateIConfigurationProcessorFactory()); + processor.GetSetDetailsAsync(configSet, ConfigurationUnitDetailLevel.Catalog).GetResults(); + + // Output some of the information from the set + Console.WriteLine($"Configuration Set: {args[2]}"); + + foreach (var unit in configSet.ConfigurationUnits) + { + Console.WriteLine($" - Configuration Unit: {unit.UnitName}"); + Console.WriteLine($" Module: {unit.Details.ModuleName}"); + Console.WriteLine( " Settings:"); + foreach (var setting in unit.Settings) + { + Console.WriteLine($" {setting.Key}: {setting.Value}"); + } + } + } + + static void LoadAndCheckConflicts(string[] args) + { + // Open the given configuration file and load into a set + var file = FileRandomAccessStream.OpenAsync(args[2], FileAccessMode.Read).GetResults(); + ConfigurationSet configSet = new ConfigurationSet(file); + + // Set a name and origin for this set so that we can see it in the conflict info + configSet.Name = Path.GetFileName(args[2]); + configSet.Origin = args[2]; + + // Create the factory and processor, then check for conflicts with existing configurations + ConfigurationProcessor processor = new ConfigurationProcessor(Helpers.CreateIConfigurationProcessorFactory()); + List configSets = new List(); + configSets.Add(configSet); + var conflicts = processor.CheckForConflictsAsync(configSets, true).GetResults(); + + Console.WriteLine($"Conflicts with Configuration Set: {args[2]}"); + + foreach (var conflict in conflicts) + { + Console.WriteLine($" - Conflict: {conflict.Conflict}"); + Console.WriteLine($" First Set: {conflict.FirstSet.Name} [{conflict.FirstSet.Origin}]"); + Console.WriteLine($" Second Set: {conflict.SecondSet.Name} [{conflict.SecondSet.Origin}]"); + if (conflict.Conflict == ConfigurationConflictType.SettingsConflict) + { + Console.WriteLine($" First Unit: {conflict.FirstUnit.UnitName} [{conflict.FirstUnit.InstanceIdentifier}]"); + Console.WriteLine($" Second Unit: {conflict.SecondUnit.UnitName} [{conflict.SecondUnit.InstanceIdentifier}]"); + foreach (var setting in conflict.Settings) + { + Console.WriteLine($" - Setting: {setting.Name}"); + Console.WriteLine($" First Value: {setting.FirstValue}"); + Console.WriteLine($" Second Value: {setting.SecondValue}"); + } + } + } + } + + static void LoadAndApply(string[] args) + { + // Open the given configuration file and load into a set + var file = FileRandomAccessStream.OpenAsync(args[2], FileAccessMode.Read).GetResults(); + ConfigurationSet configSet = new ConfigurationSet(file); + + // Create the factory and processor + ConfigurationProcessor processor = new ConfigurationProcessor(Helpers.CreateIConfigurationProcessorFactory()); + + // Attach event handler on set change + configSet.ConfigurationSetChange += Helpers.SetWatcher; + + Console.WriteLine($"Applying Configuration Set: {args[2]}"); + + var result = processor.ApplyAsync(configSet, ApplyConfigurationSetFlags.None).GetResults(); + + Console.WriteLine($" - Done: {result.ResultCode.HResult}"); + } + + static void GetHistoryAndWatchEverything(string[] args) + { + Console.WriteLine("Watching all configuration [press Enter to stop]:"); + + List list = new List(); + + // Attach to the top level change event + Statics.ConfigurationChange += (ConfigurationSet incomingSet, ConfigurationChangeData data) => + { + int existingSetIndex = -1; + + lock (list) + { + for (int i = 0; i < list.Count; ++i) + { + if (list[i].InstanceIdentifier == data.InstanceIdentifier) + { + existingSetIndex = i; + break; + } + } + + if (data.Change == ConfigurationChangeEventType.SetAdded || data.Change == ConfigurationChangeEventType.SetStateChanged) + { + if (existingSetIndex == -1) + { + incomingSet.ConfigurationSetChange += Helpers.SetWatcher; + list.Add(incomingSet); + } + } + else // Removed + { + if (existingSetIndex != -1) + { + list[existingSetIndex].ConfigurationSetChange -= Helpers.SetWatcher; + list.RemoveAt(existingSetIndex); + } + } + } + + Console.WriteLine($" - Set: {data.InstanceIdentifier}"); + Console.WriteLine($" Change: {data.Change}"); + }; + + foreach (var set in Statics.GetConfigurationHistory()) + { + int existingSetIndex = -1; + + lock (list) + { + for (int i = 0; i < list.Count; ++i) + { + if (list[i].InstanceIdentifier == set.InstanceIdentifier) + { + existingSetIndex = i; + break; + } + } + + if (existingSetIndex == -1) + { + set.ConfigurationSetChange += Helpers.SetWatcher; + list.Add(set); + } + } + + if (existingSetIndex == -1) + { + Console.WriteLine($" - Set: {set.Name} [{set.InstanceIdentifier}]"); + Console.WriteLine($" State: {set.State}"); + } + } + + // Wait for user to press enter + Console.ReadLine(); + } + + static void Main(string[] args) + { + var method = typeof(Program).GetMethod(args[1]); + + if (method != null) + { + method.Invoke(null, new object[]{ args }); + } + else + { + Console.WriteLine($"{args[1]} is not a sample"); + } + } + } +} + +``` \ No newline at end of file diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl index 4b681cfc00..3565e14f1b 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -27,9 +27,12 @@ namespace Microsoft.Management.Configuration ApplicationSucceeded, SkippedManually, SkippedDueToDependencies, + TestBegun, + TestFailed, + TestSucceeded, }; - // Defines the level of detail that is desired about a configuration unit. + // Defines the level of detail probing that is allowed about a configuration unit. [contract(Microsoft.Management.Configuration.Contract, 1)] enum ConfigurationUnitDetailLevel { @@ -43,9 +46,9 @@ namespace Microsoft.Management.Configuration Load, }; - // Information on a failure for a single unit of configuration. + // Information on a result for a single unit of configuration. [contract(Microsoft.Management.Configuration.Contract, 1)] - runtimeclass ConfigurationUnitFailureInformation + runtimeclass ConfigurationUnitResultInformation { // The error code of the failure. HRESULT ResultCode{ get; }; @@ -54,7 +57,7 @@ namespace Microsoft.Management.Configuration String Description{ get; }; } - // This interface provides information and access for a specific configuration unit within the runtime. + // Provides information for a specific configuration unit setting. [contract(Microsoft.Management.Configuration.Contract, 1)] interface IConfigurationUnitSettingDetails { @@ -77,7 +80,7 @@ namespace Microsoft.Management.Configuration String Semantics{ get; }; } - // This interface provides information about a specific configuration unit processor within the runtime. + // Provides information for a specific configuration unit within the runtime. [contract(Microsoft.Management.Configuration.Contract, 1)] interface IConfigurationUnitProcessorDetails { @@ -153,14 +156,14 @@ namespace Microsoft.Management.Configuration // The current state of the configuration unit. ConfigurationUnitState State{ get; }; - // If the State is ApplicationFailed, this object should exist with additional details on the latest failure. - ConfigurationUnitFailureInformation FailureInformation{ get; }; + // Contains information on the result of the latest attempt to apply the configuration unit. + ConfigurationUnitResultInformation ResultInformation{ get; }; // Allows for control over whether this unit should be applied when the set containing it is applied. Boolean ShouldApply; } - // The change event type that has occurred. + // The change event type that has occurred for a configuration set change. [contract(Microsoft.Management.Configuration.Contract, 1)] enum ConfigurationSetChangeEventType { @@ -182,8 +185,8 @@ namespace Microsoft.Management.Configuration // The state of the configuration unit for this event (the ConfigurationUnit can be used to get the current state, which may be different). ConfigurationUnitState UnitState{ get; }; - // If the UnitState is ApplicationFailed, this object should exist with additional details on the failure. - ConfigurationUnitFailureInformation FailureInformation{ get; }; + // Contains information on the result of the attempt to apply the configuration unit. + ConfigurationUnitResultInformation ResultInformation{ get; }; // The configuration unit whose state changed. ConfigurationUnit Unit{ get; }; @@ -229,11 +232,11 @@ namespace Microsoft.Management.Configuration // Writes the configuration set to the given stream. void Serialize(Windows.Storage.Streams.IOutputStream stream); - // Removes a configuration set from the system history. Only usable on a set that came from `Statics.GetConfigurationHistory`. + // Removes the configuration set from the recorded history, if present. void Remove(); } - // This interface provides information and access for a specific configuration unit within the runtime. + // Provides access to a specific configuration unit within the runtime. [contract(Microsoft.Management.Configuration.Contract, 1)] interface IConfigurationUnitProcessor { @@ -253,12 +256,12 @@ namespace Microsoft.Management.Configuration void ApplySettings(); } - // This interface allows different runtimes to provide specialized handling of configuration processing. + // Allows different runtimes to provide specialized handling of configuration processing. [contract(Microsoft.Management.Configuration.Contract, 1)] interface IConfigurationProcessorFactory { // Gets the configuration unit processor details for the given unit. - IConfigurationUnitProcessorDetails GetUnitProcessorGetails(ConfigurationUnit unit); + IConfigurationUnitProcessorDetails GetUnitProcessorDetails(ConfigurationUnit unit); // Creates a configuration unit processor for the given unit. // The optional `directivesOverlay` parameter allows for the `ConfigurationProcessor` to alter behavior without needing to change the unit itself. @@ -266,7 +269,7 @@ namespace Microsoft.Management.Configuration IConfigurationUnitProcessor CreateUnitProcessor(ConfigurationUnit unit, Windows.Foundation.Collections.ValueSet directivesOverlay); } - // The type of conflict that occurred. + // The type of conflict between configuration sets that was detected. [contract(Microsoft.Management.Configuration.Contract, 1)] enum ConfigurationConflictType { @@ -274,7 +277,7 @@ namespace Microsoft.Management.Configuration // Indicates that the first configuration set has a matching name and origin to the second, which has already been applied. // This is likely an update to the existing set, and should be applied as such, rather than an entirely new set. MatchingOrigin, - // Indicates that the first configuration set is identical to the second, that has already been applied. + // Indicates that the first configuration set is identical to the second, which has already been applied. // This is based solely on the configuration unit settings. IdenticalSetApplied, // Indicates a conflict between the settings of two configuration units. @@ -289,15 +292,15 @@ namespace Microsoft.Management.Configuration String Name{ get; }; // The value from the first configuration unit. - // These are the values from a `ValueSet`, and are thus required to be a `PopertyValue` or a 'ValueSet`. + // These are the values from a `ValueSet`, and are thus required to be a `PropertyValue` or a 'ValueSet`. Object FirstValue{ get; }; // The value from the second configuration unit. - // These are the values from a `ValueSet`, and are thus required to be a `PopertyValue` or a 'ValueSet`. + // These are the values from a `ValueSet`, and are thus required to be a `PropertyValue` or a 'ValueSet`. Object SecondValue{ get; }; } - // Describes a conflict between two configurations. + // Describes a conflict between two configuration sets. [contract(Microsoft.Management.Configuration.Contract, 1)] runtimeclass ConfigurationConflict { @@ -334,8 +337,11 @@ namespace Microsoft.Management.Configuration [contract(Microsoft.Management.Configuration.Contract, 1)] runtimeclass ApplyConfigurationUnitResult { - // The result from applying the configuration unit. - HRESULT ResultCode{ get; }; + // The configuration unit that was applied. + ConfigurationUnit Unit{ get; }; + + // The result of applying the configuration unit. + ConfigurationUnitResultInformation ResultInformation{ get; }; } // The result of applying the settings for a configuration set. @@ -356,6 +362,10 @@ namespace Microsoft.Management.Configuration // The configuration unit that was tested. ConfigurationUnit Unit{ get; }; + // The result of testing the configuration unit. + // This is not the response for the test, but rather contains information about the actual attempt to run the test. + ConfigurationUnitResultInformation ResultInformation{ get; }; + // Will be true if the system is in the state described by the configuration unit; false otherwise. Boolean TestResult{ get; }; } @@ -375,6 +385,10 @@ namespace Microsoft.Management.Configuration [contract(Microsoft.Management.Configuration.Contract, 1)] runtimeclass GetConfigurationUnitSettingsResult { + // The result of getting the configuration unit settings. + // This is not the response for the retrieval, but rather contains information about the actual attempt to retrieve the settings. + ConfigurationUnitResultInformation ResultInformation{ get; }; + // The current state of the system for the configuration unit. Windows.Foundation.Collections.ValueSet Settings { get; }; } @@ -394,10 +408,10 @@ namespace Microsoft.Management.Configuration // Gets the details for a configuration unit. Windows.Foundation.IAsyncAction GetUnitDetailsAsync(ConfigurationUnit unit, ConfigurationUnitDetailLevel detailLevel); - // Applies the configuration set state; to get progress, attach a delegate to the ConfigurationSetChange before calling this method. + // Applies the configuration set state; to get progress, subscribe to the ConfigurationSetChange before calling this method. Windows.Foundation.IAsyncOperation ApplyAsync(ConfigurationSet configurationSet, ApplyConfigurationSetFlags flags); - // Tests the configuration set state; to get progress, attach a delegate to the ConfigurationSetChange before calling this method. + // Tests the configuration set state; to get progress, subscribe to the ConfigurationSetChange before calling this method. Windows.Foundation.IAsyncOperation TestAsync(ConfigurationSet configurationSet); // Gets the current configuration unit settings. From e2ca3190211ef56498ff20a0c1ea9b7656809be9 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Fri, 6 Jan 2023 12:01:21 -0800 Subject: [PATCH 03/31] Minor update to API: remove Statics and add diagnostics functionality. --- doc/specs/Configuration-COM-API.md | 51 +++++++--- .../Microsoft.Management.Configuration.idl | 96 +++++++++++-------- 2 files changed, 94 insertions(+), 53 deletions(-) diff --git a/doc/specs/Configuration-COM-API.md b/doc/specs/Configuration-COM-API.md index 233d1a6106..dec5749bb7 100644 --- a/doc/specs/Configuration-COM-API.md +++ b/doc/specs/Configuration-COM-API.md @@ -292,6 +292,23 @@ It is not expected that you would use this interface directly, but rather the `C _Spec note: A separate binary (written by us) will contain the implementation(s) of this interface._ +## DiagnosticLevel enumeration + +Indicates the importance of diagnostic information. + +| Name | Description | +|-|-| +| Verbose | Most useful for debugging scenarios; likely too much for general use. | +| Informational | Details that can be useful for understanding what is happening. | +| Warning | Indicates some abnormal condition, but that is not expected to impact functionality. | +| Error | An error has occurred, but this does not necessarily mean that it will halt the operation. | +| Critical | A serious, fatal condition has been encountered. | + +## DiagnosticInformation class + +Contains diagnostic information from the configuration system that can be passed along to the user or log files. +This is not intended as primary information, and is thus not localized. + ## ConfigurationConflictType enumeration The type of conflict between configuration sets that was detected. @@ -320,6 +337,21 @@ Flags to control how a configuration set should be applied to the system. | None | The configuration set should be applied in the default manner. | | DoNotOverwriteMatchingOriginSet | Forces a new configuration set instance to be recorded when the set being applied matches a previous set's origin. The default behavior is to assume that the incoming set is an update to the existing set and overwrite it. | +## ConfigurationChangeEventType enumeration + +The configuration set change event type that has occurred. + +| Name | Description | +|-|-| +| Unknown | For future use if the caller is not aware of newer change types. | +| SetAdded | A new configuration set was recorded in the history with the intent to be applied. | +| SetStateChanged | A configuration set has changed state. | +| SetRemoved | A configuration set has been removed from the history. | + +## ConfigurationChangeEventType class + +The change data sent about changes to sets. + ## ConfigurationProcessor class The configuration processor is responsible for the interactions with the system. @@ -400,26 +432,15 @@ Gets the current configuration unit settings from the system state. Windows.Foundation.IAsyncOperation GetSettingsAsync(ConfigurationUnit unit); ``` -## ConfigurationChangeEventType enumeration +## ConfigurationProcessor.Diagnostics event -The configuration set change event type that has occurred. - -| Name | Description | -|-|-| -| Unknown | For future use if the caller is not aware of newer change types. | -| SetAdded | A new configuration set was recorded in the history with the intent to be applied. | -| SetStateChanged | A configuration set has changed state. | -| SetRemoved | A configuration set has been removed from the history. | - -## ConfigurationChangeEventType class - -The change data sent about changes to sets. +Enables listening to internal diagnostics events for logging purposes. -## Statics.ConfigurationChange event +## ConfigurationProcessor.ConfigurationChange event Signals changes to the set of configuration sets in the history, as well as changes to the state of configuration sets in the history. -## Statics.GetConfigurationHistory method +## ConfigurationProcessor.GetConfigurationHistory method Gets the configuration sets from the recorded history. diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl index 3565e14f1b..1ae7993013 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -261,7 +261,7 @@ namespace Microsoft.Management.Configuration interface IConfigurationProcessorFactory { // Gets the configuration unit processor details for the given unit. - IConfigurationUnitProcessorDetails GetUnitProcessorDetails(ConfigurationUnit unit); + IConfigurationUnitProcessorDetails GetUnitProcessorDetails(ConfigurationUnit unit, ConfigurationUnitDetailLevel detailLevel); // Creates a configuration unit processor for the given unit. // The optional `directivesOverlay` parameter allows for the `ConfigurationProcessor` to alter behavior without needing to change the unit itself. @@ -269,6 +269,52 @@ namespace Microsoft.Management.Configuration IConfigurationUnitProcessor CreateUnitProcessor(ConfigurationUnit unit, Windows.Foundation.Collections.ValueSet directivesOverlay); } + // The level of the diagnostic information. + [contract(Microsoft.Management.Configuration.Contract, 1)] + enum DiagnosticLevel + { + Verbose, + Informational, + Warning, + Error, + Critical, + }; + + // Enables diagnostic information from the configuration system to be inspected/stored by callers. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass DiagnosticInformation + { + // Indicates the importance of the diagnostic information. + DiagnosticLevel Level{ get; }; + + // The diagnostic message. + String Message{ get; }; + } + + // The change event type that has occurred. + [contract(Microsoft.Management.Configuration.Contract, 1)] + enum ConfigurationChangeEventType + { + Unknown, + SetAdded, + SetStateChanged, + SetRemoved, + }; + + // The change data sent about changes to sets. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass ConfigurationChangeData + { + // The change event type that occurred. + ConfigurationChangeEventType Change{ get; }; + + // The identifier used to uniquely identify the instance of a configuration set on the system. + Guid InstanceIdentifier{ get; }; + + // The state of the configuration set for this event (the ConfigurationSet can be used to get the current state, which may be different). + ConfigurationSetState State{ get; }; + } + // The type of conflict between configuration sets that was detected. [contract(Microsoft.Management.Configuration.Contract, 1)] enum ConfigurationConflictType @@ -399,6 +445,17 @@ namespace Microsoft.Management.Configuration { ConfigurationProcessor(IConfigurationProcessorFactory factory); + // Diagnostics event; useful for logging and/or verbose output. + event Windows.Foundation.EventHandler Diagnostics; + + // Only top level configuration changes are sent to this event. + // This includes things like: creation of a new set for intent to run, start/stop of a set for application or test, deletion of a not started set. + event Windows.Foundation.TypedEventHandler ConfigurationChange; + + // Gets the configuration sets that have already been applied or the intent to be applied (this may include in progress sets or those that are waiting on others). + // These configuration sets will be marked as immutable. + Windows.Foundation.Collections.IVectorView GetConfigurationHistory(); + // Checks for conflicts amongst the configuration sets provided, optionally including the configuration sets already applied to the system. Windows.Foundation.IAsyncOperation< Windows.Foundation.Collections.IVectorView > CheckForConflictsAsync(Windows.Foundation.Collections.IVectorView configurationSets, Boolean includeConfigurationHistory); @@ -417,41 +474,4 @@ namespace Microsoft.Management.Configuration // Gets the current configuration unit settings. Windows.Foundation.IAsyncOperation GetSettingsAsync(ConfigurationUnit unit); } - - // The change event type that has occurred. - [contract(Microsoft.Management.Configuration.Contract, 1)] - enum ConfigurationChangeEventType - { - Unknown, - SetAdded, - SetStateChanged, - SetRemoved, - }; - - // The change data sent about changes to sets. - [contract(Microsoft.Management.Configuration.Contract, 1)] - runtimeclass ConfigurationChangeData - { - // The change event type that occurred. - ConfigurationChangeEventType Change{ get; }; - - // The identifier used to uniquely identify the instance of a configuration set on the system. - Guid InstanceIdentifier{ get; }; - - // The state of the configuration set for this event (the ConfigurationSet can be used to get the current state, which may be different). - ConfigurationSetState State{ get; }; - } - - // Statics of Microsoft.Management.Configuration - [contract(Microsoft.Management.Configuration.Contract, 1)] - static runtimeclass Statics - { - // Only top level configuration changes are sent to this event. - // This includes things like: creation of a new set for intent to run, start/stop of a set for application or test, deletion of a not started set. - static event Windows.Foundation.TypedEventHandler ConfigurationChange; - - // Gets the configuration sets that have already been applied or the intent to be applied (this may include in progress sets or those that are waiting on others). - // These configuration sets will be marked as immutable. - static Windows.Foundation.Collections.IVectorView GetConfigurationHistory(); - } } From 6326c05816ade3e79fc462cacfd9127560ac69f2 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Fri, 6 Jan 2023 16:45:59 -0800 Subject: [PATCH 04/31] Checkpoint --- .../ConfigurationUnit.cpp | 98 +++++++++++++++++++ .../ConfigurationUnit.h | 57 +++++++++++ .../ConfigurationUnitResultInformation.cpp | 24 +++++ .../ConfigurationUnitResultInformation.h | 25 +++++ ...Microsoft.Management.Configuration.vcxproj | 6 ++ ...t.Management.Configuration.vcxproj.filters | 6 ++ .../MutableFlag.cpp | 12 +++ .../MutableFlag.h | 22 +++++ .../pch.cpp | 3 + src/Microsoft.Management.Configuration/pch.h | 9 ++ 10 files changed, 262 insertions(+) create mode 100644 src/Microsoft.Management.Configuration/ConfigurationUnit.cpp create mode 100644 src/Microsoft.Management.Configuration/ConfigurationUnit.h create mode 100644 src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp create mode 100644 src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h create mode 100644 src/Microsoft.Management.Configuration/MutableFlag.cpp create mode 100644 src/Microsoft.Management.Configuration/MutableFlag.h create mode 100644 src/Microsoft.Management.Configuration/pch.cpp diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp b/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp new file mode 100644 index 0000000000..60e5ff21da --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp @@ -0,0 +1,98 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ConfigurationUnit.h" +#include "ConfigurationUnit.g.cpp" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + ConfigurationUnit::ConfigurationUnit() + { + GUID instanceIdentifier; + THROW_IF_FAILED(CoCreateGuid(&instanceIdentifier)); + m_InstanceIdentifier = instanceIdentifier; + } + + ConfigurationUnit::ConfigurationUnit(guid instanceIdentifier) : + m_InstanceIdentifier(instanceIdentifier), m_mutableFlag(false) + { + } + + hstring ConfigurationUnit::UnitName() + { + return m_unitName; + } + + void ConfigurationUnit::UnitName(hstring value) + { + m_mutableFlag.RequireMutable(); + m_unitName = value; + } + + guid ConfigurationUnit::InstanceIdentifier() + { + return m_InstanceIdentifier; + } + + hstring ConfigurationUnit::Identifier() + { + return m_identifier; + } + + void ConfigurationUnit::Identifier(hstring value) + { + m_mutableFlag.RequireMutable(); + m_identifier = value; + } + + Windows::Foundation::Collections::IVectorView ConfigurationUnit::Dependencies() + { + return m_dependencies.GetView(); + } + + void ConfigurationUnit::Dependencies(Windows::Foundation::Collections::IVectorView value) + { + m_mutableFlag.RequireMutable(); + m_dependencies = winrt::single_threaded_vector(value); + } + + Windows::Foundation::Collections::ValueSet ConfigurationUnit::Directives() + { + m_directives.get + } + + Windows::Foundation::Collections::ValueSet ConfigurationUnit::Settings() + { + + } + + void ConfigurationUnit::Settings(Windows::Foundation::Collections::ValueSet value) + { + + } + + IConfigurationUnitProcessorDetails ConfigurationUnit::Details() + { + + } + + ConfigurationUnitState ConfigurationUnit::State() + { + + } + + ConfigurationUnitResultInformation ConfigurationUnit::ResultInformation() + { + + } + + bool ConfigurationUnit::ShouldApply() + { + + } + + void ConfigurationUnit::ShouldApply(bool value) + { + + } +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnit.h b/src/Microsoft.Management.Configuration/ConfigurationUnit.h new file mode 100644 index 0000000000..8a92ddedfe --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationUnit.h @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ConfigurationUnit.g.h" +#include "MutableFlag.h" +#include + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct ConfigurationUnit : ConfigurationUnitT + { + ConfigurationUnit(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + ConfigurationUnit(guid instanceIdentifier); +#endif + + hstring UnitName(); + void UnitName(hstring value); + + guid InstanceIdentifier(); + + hstring Identifier(); + void Identifier(hstring value); + + Windows::Foundation::Collections::IVectorView Dependencies(); + void Dependencies(Windows::Foundation::Collections::IVectorView value); + + Windows::Foundation::Collections::ValueSet Directives(); + + Windows::Foundation::Collections::ValueSet Settings(); + void Settings(Windows::Foundation::Collections::ValueSet value); + + IConfigurationUnitProcessorDetails Details(); + + ConfigurationUnitState State(); + + ConfigurationUnitResultInformation ResultInformation(); + + bool ShouldApply(); + void ShouldApply(bool value); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + hstring m_unitName; + guid m_InstanceIdentifier; + hstring m_identifier; + Windows::Foundation::Collections::IVector m_dependencies{ winrt::single_threaded_vector() }; + Windows::Foundation::Collections::ValueSet m_directives; + Windows::Foundation::Collections::ValueSet m_settings; + IConfigurationUnitProcessorDetails m_details{ nullptr }; + bool m_shouldApply = true; + + MutableFlag m_mutableFlag; +#endif + }; +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp new file mode 100644 index 0000000000..6b6fa5411a --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ConfigurationUnitResultInformation.h" +#include "ConfigurationUnitResultInformation.g.cpp" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + void ConfigurationUnitResultInformation::Initialize(hresult resultCode, std::wstring_view description) + { + m_resultCode = resultCode; + m_description = description; + } + + hresult ConfigurationUnitResultInformation::ResultCode() + { + return m_resultCode; + } + + hstring ConfigurationUnitResultInformation::Description() + { + return m_description; + } +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h new file mode 100644 index 0000000000..89cac7bc29 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ConfigurationUnitResultInformation.g.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct ConfigurationUnitResultInformation : ConfigurationUnitResultInformationT + { + ConfigurationUnitResultInformation() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void Initialize(hresult resultCode, std::wstring_view description); +#endif + + hresult ResultCode(); + hstring Description(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + hresult m_resultCode; + hstring m_description; +#endif + }; +} diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj index 934131f2d6..758cb150f1 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -128,9 +128,15 @@ + + + + + + Create diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters index 7c520a610f..3b881d27db 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters @@ -3,9 +3,15 @@ + + + + + + diff --git a/src/Microsoft.Management.Configuration/MutableFlag.cpp b/src/Microsoft.Management.Configuration/MutableFlag.cpp new file mode 100644 index 0000000000..c095a89229 --- /dev/null +++ b/src/Microsoft.Management.Configuration/MutableFlag.cpp @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "MutableFlag.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + void MutableFlag::RequireMutable() const + { + THROW_HR_IF(E_NOT_VALID_STATE, !m_isMutable); + } +} diff --git a/src/Microsoft.Management.Configuration/MutableFlag.h b/src/Microsoft.Management.Configuration/MutableFlag.h new file mode 100644 index 0000000000..a3c5be7be0 --- /dev/null +++ b/src/Microsoft.Management.Configuration/MutableFlag.h @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + // Helper to enable objects to enforce being immutable. + struct MutableFlag + { + MutableFlag(bool isMutable = true) : m_isMutable(isMutable) {} + MutableFlag(const MutableFlag&) = default; + MutableFlag& operator=(const MutableFlag&) = default; + MutableFlag(MutableFlag&&) = default; + MutableFlag& operator=(MutableFlag&&) = default; + + // If the state is not mutable, throws. + void RequireMutable() const; + + private: + bool m_isMutable; + }; +} diff --git a/src/Microsoft.Management.Configuration/pch.cpp b/src/Microsoft.Management.Configuration/pch.cpp new file mode 100644 index 0000000000..147dc1b6e0 --- /dev/null +++ b/src/Microsoft.Management.Configuration/pch.cpp @@ -0,0 +1,3 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" diff --git a/src/Microsoft.Management.Configuration/pch.h b/src/Microsoft.Management.Configuration/pch.h index a12993ff40..12b524b84e 100644 --- a/src/Microsoft.Management.Configuration/pch.h +++ b/src/Microsoft.Management.Configuration/pch.h @@ -5,4 +5,13 @@ #include #include +// TODO: Is this needed? + +#pragma warning( push ) +#pragma warning ( disable : 4467 6388) +// 4467 Allow use of uuid attribute for com object creation. +// 6388 Allow CreateInstance. +#include +#pragma warning( pop ) + #include \ No newline at end of file From 1ffbc8712c5099df5db933d98743678acb2e79f2 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Mon, 9 Jan 2023 17:45:48 -0800 Subject: [PATCH 05/31] Checkpoint --- .../ConfigurationSet.cpp | 108 +++++++++++++++++ .../ConfigurationSet.h | 65 ++++++++++ .../ConfigurationSetChangeData.cpp | 38 ++++++ .../ConfigurationSetChangeData.h | 31 +++++ .../ConfigurationUnit.cpp | 112 +++++++++--------- .../ConfigurationUnit.h | 20 +++- .../Microsoft.Management.Configuration.idl | 6 +- ...Microsoft.Management.Configuration.vcxproj | 4 + ...t.Management.Configuration.vcxproj.filters | 4 + src/Microsoft.Management.Configuration/pch.h | 1 + 10 files changed, 323 insertions(+), 66 deletions(-) create mode 100644 src/Microsoft.Management.Configuration/ConfigurationSet.cpp create mode 100644 src/Microsoft.Management.Configuration/ConfigurationSet.h create mode 100644 src/Microsoft.Management.Configuration/ConfigurationSetChangeData.cpp create mode 100644 src/Microsoft.Management.Configuration/ConfigurationSetChangeData.h diff --git a/src/Microsoft.Management.Configuration/ConfigurationSet.cpp b/src/Microsoft.Management.Configuration/ConfigurationSet.cpp new file mode 100644 index 0000000000..7e4728dfcd --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationSet.cpp @@ -0,0 +1,108 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ConfigurationSet.h" +#include "ConfigurationSet.g.cpp" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + ConfigurationSet::ConfigurationSet() + { + GUID instanceIdentifier; + THROW_IF_FAILED(CoCreateGuid(&instanceIdentifier)); + m_instanceIdentifier = instanceIdentifier; + } + + ConfigurationSet::ConfigurationSet(const Windows::Storage::Streams::IInputStream& stream) + { + UNREFERENCED_PARAMETER(stream); + THROW_HR(E_NOTIMPL); + } + + ConfigurationSet::ConfigurationSet(const guid& instanceIdentifier) : + m_instanceIdentifier(instanceIdentifier), m_mutableFlag(false) + { + } + + hstring ConfigurationSet::Name() + { + return m_name; + } + + void ConfigurationSet::Name(const hstring& value) + { + m_mutableFlag.RequireMutable(); + m_name = value; + } + + hstring ConfigurationSet::Origin() + { + return m_origin; + } + + void ConfigurationSet::Origin(const hstring& value) + { + m_mutableFlag.RequireMutable(); + m_origin = value; + } + + guid ConfigurationSet::InstanceIdentifier() + { + return m_instanceIdentifier; + } + + ConfigurationSetState ConfigurationSet::State() + { + return ConfigurationSetState::Unknown; + } + + clock::time_point ConfigurationSet::InitialIntent() + { + return clock::time_point{}; + } + + clock::time_point ConfigurationSet::ApplyBegun() + { + return clock::time_point{}; + } + + clock::time_point ConfigurationSet::ApplyEnded() + { + return clock::time_point{}; + } + + Windows::Foundation::Collections::IVectorView ConfigurationSet::ConfigurationUnits() + { + return m_configurationUnits.GetView(); + } + + void ConfigurationSet::ConfigurationUnits(const Windows::Foundation::Collections::IVectorView& value) + { + m_mutableFlag.RequireMutable(); + + std::vector temp{ value.Size() }; + value.GetMany(0, temp); + m_configurationUnits = winrt::single_threaded_vector(std::move(temp)); + } + + event_token ConfigurationSet::ConfigurationSetChange(const Windows::Foundation::TypedEventHandler& value) + { + return m_configurationSetChange.add(value); + } + + void ConfigurationSet::ConfigurationSetChange(const event_token& token) + { + m_configurationSetChange.remove(token); + } + + void ConfigurationSet::Serialize(const Windows::Storage::Streams::IOutputStream& stream) + { + UNREFERENCED_PARAMETER(stream); + THROW_HR(E_NOTIMPL); + } + + void ConfigurationSet::Remove() + { + THROW_HR(E_NOTIMPL); + } +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationSet.h b/src/Microsoft.Management.Configuration/ConfigurationSet.h new file mode 100644 index 0000000000..9300d43379 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationSet.h @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ConfigurationSet.g.h" +#include "MutableFlag.h" +#include +#include + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct ConfigurationSet : ConfigurationSetT + { + using WinRT_Self = ::winrt::Microsoft::Management::Configuration::ConfigurationSet; + + ConfigurationSet(); + ConfigurationSet(const Windows::Storage::Streams::IInputStream& stream); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + ConfigurationSet(const guid& instanceIdentifier); +#endif + + hstring Name(); + void Name(const hstring& value); + + hstring Origin(); + void Origin(const hstring& value); + + guid InstanceIdentifier(); + ConfigurationSetState State(); + clock::time_point InitialIntent(); + clock::time_point ApplyBegun(); + clock::time_point ApplyEnded(); + + Windows::Foundation::Collections::IVectorView ConfigurationUnits(); + void ConfigurationUnits(const Windows::Foundation::Collections::IVectorView& value); + + event_token ConfigurationSetChange(const Windows::Foundation::TypedEventHandler& value); + void ConfigurationSetChange(const event_token& token); + + void Serialize(const Windows::Storage::Streams::IOutputStream& stream); + + void Remove(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + hstring m_name; + hstring m_origin; + guid m_instanceIdentifier; + clock::time_point m_initialIntent; + Windows::Foundation::Collections::IVector m_configurationUnits{ winrt::single_threaded_vector() }; + winrt::event> m_configurationSetChange; + + MutableFlag m_mutableFlag; +#endif + }; +} + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) +namespace winrt::Microsoft::Management::Configuration::factory_implementation +{ + struct ConfigurationSet : ConfigurationSetT + { + }; +} +#endif diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.cpp new file mode 100644 index 0000000000..2e582f2b06 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.cpp @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ConfigurationSetChangeData.h" +#include "ConfigurationSetChangeData.g.cpp" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + void ConfigurationSetChangeData::Initialize(ConfigurationSetChangeEventType change) + { + m_change = change; + } + + ConfigurationSetChangeEventType ConfigurationSetChangeData::Change() + { + return m_change; + } + + ConfigurationSetState ConfigurationSetChangeData::SetState() + { + return m_setState; + } + + ConfigurationUnitState ConfigurationSetChangeData::UnitState() + { + return m_unitState; + } + + ConfigurationUnitResultInformation ConfigurationSetChangeData::ResultInformation() + { + return m_resultInformation; + } + + ConfigurationUnit ConfigurationSetChangeData::Unit() + { + return m_unit; + } +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.h b/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.h new file mode 100644 index 0000000000..c0ec719888 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.h @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ConfigurationSetChangeData.g.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct ConfigurationSetChangeData : ConfigurationSetChangeDataT + { + ConfigurationSetChangeData() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void Initialize(ConfigurationSetChangeEventType change); +#endif + + ConfigurationSetChangeEventType Change(); + ConfigurationSetState SetState(); + ConfigurationUnitState UnitState(); + ConfigurationUnitResultInformation ResultInformation(); + ConfigurationUnit Unit(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + ConfigurationSetChangeEventType m_change; + ConfigurationSetState m_setState; + ConfigurationUnitState m_unitState; + ConfigurationUnitResultInformation m_resultInformation; + ConfigurationUnit m_unit; +#endif + }; +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp b/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp index 60e5ff21da..8b0e2ceebb 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp @@ -6,93 +6,91 @@ namespace winrt::Microsoft::Management::Configuration::implementation { - ConfigurationUnit::ConfigurationUnit() - { - GUID instanceIdentifier; - THROW_IF_FAILED(CoCreateGuid(&instanceIdentifier)); - m_InstanceIdentifier = instanceIdentifier; + ConfigurationUnit::ConfigurationUnit() + { + GUID instanceIdentifier; + THROW_IF_FAILED(CoCreateGuid(&instanceIdentifier)); + m_instanceIdentifier = instanceIdentifier; } - ConfigurationUnit::ConfigurationUnit(guid instanceIdentifier) : - m_InstanceIdentifier(instanceIdentifier), m_mutableFlag(false) - { + ConfigurationUnit::ConfigurationUnit(const guid& instanceIdentifier) : + m_instanceIdentifier(instanceIdentifier), m_mutableFlag(false) + { } - hstring ConfigurationUnit::UnitName() - { - return m_unitName; + hstring ConfigurationUnit::UnitName() + { + return m_unitName; } - void ConfigurationUnit::UnitName(hstring value) - { - m_mutableFlag.RequireMutable(); - m_unitName = value; + void ConfigurationUnit::UnitName(const hstring& value) + { + m_mutableFlag.RequireMutable(); + m_unitName = value; } - guid ConfigurationUnit::InstanceIdentifier() - { - return m_InstanceIdentifier; + guid ConfigurationUnit::InstanceIdentifier() + { + return m_instanceIdentifier; } - hstring ConfigurationUnit::Identifier() - { - return m_identifier; + hstring ConfigurationUnit::Identifier() + { + return m_identifier; } - void ConfigurationUnit::Identifier(hstring value) - { - m_mutableFlag.RequireMutable(); - m_identifier = value; + void ConfigurationUnit::Identifier(const hstring& value) + { + m_mutableFlag.RequireMutable(); + m_identifier = value; } - Windows::Foundation::Collections::IVectorView ConfigurationUnit::Dependencies() - { - return m_dependencies.GetView(); + Windows::Foundation::Collections::IVectorView ConfigurationUnit::Dependencies() + { + return m_dependencies.GetView(); } - void ConfigurationUnit::Dependencies(Windows::Foundation::Collections::IVectorView value) - { - m_mutableFlag.RequireMutable(); - m_dependencies = winrt::single_threaded_vector(value); - } + void ConfigurationUnit::Dependencies(const Windows::Foundation::Collections::IVectorView& value) + { + m_mutableFlag.RequireMutable(); - Windows::Foundation::Collections::ValueSet ConfigurationUnit::Directives() - { - m_directives.get + std::vector temp{ value.Size() }; + value.GetMany(0, temp); + m_dependencies = winrt::single_threaded_vector(std::move(temp)); } - Windows::Foundation::Collections::ValueSet ConfigurationUnit::Settings() - { - + Windows::Foundation::Collections::ValueSet ConfigurationUnit::Directives() + { + return m_directives; } - void ConfigurationUnit::Settings(Windows::Foundation::Collections::ValueSet value) - { - + Windows::Foundation::Collections::ValueSet ConfigurationUnit::Settings() + { + return m_settings; } - IConfigurationUnitProcessorDetails ConfigurationUnit::Details() - { - + IConfigurationUnitProcessorDetails ConfigurationUnit::Details() + { + return m_details; } - ConfigurationUnitState ConfigurationUnit::State() - { - + ConfigurationUnitState ConfigurationUnit::State() + { + return ConfigurationUnitState::Unknown; } - ConfigurationUnitResultInformation ConfigurationUnit::ResultInformation() - { - + ConfigurationUnitResultInformation ConfigurationUnit::ResultInformation() + { + return nullptr; } - bool ConfigurationUnit::ShouldApply() - { - + bool ConfigurationUnit::ShouldApply() + { + return m_shouldApply; } - void ConfigurationUnit::ShouldApply(bool value) - { - + void ConfigurationUnit::ShouldApply(bool value) + { + m_shouldApply = value; } } diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnit.h b/src/Microsoft.Management.Configuration/ConfigurationUnit.h index 8a92ddedfe..e04b6a45aa 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationUnit.h +++ b/src/Microsoft.Management.Configuration/ConfigurationUnit.h @@ -12,24 +12,23 @@ namespace winrt::Microsoft::Management::Configuration::implementation ConfigurationUnit(); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) - ConfigurationUnit(guid instanceIdentifier); + ConfigurationUnit(const guid& instanceIdentifier); #endif hstring UnitName(); - void UnitName(hstring value); + void UnitName(const hstring& value); guid InstanceIdentifier(); hstring Identifier(); - void Identifier(hstring value); + void Identifier(const hstring& value); Windows::Foundation::Collections::IVectorView Dependencies(); - void Dependencies(Windows::Foundation::Collections::IVectorView value); + void Dependencies(const Windows::Foundation::Collections::IVectorView& value); Windows::Foundation::Collections::ValueSet Directives(); Windows::Foundation::Collections::ValueSet Settings(); - void Settings(Windows::Foundation::Collections::ValueSet value); IConfigurationUnitProcessorDetails Details(); @@ -43,7 +42,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: hstring m_unitName; - guid m_InstanceIdentifier; + guid m_instanceIdentifier; hstring m_identifier; Windows::Foundation::Collections::IVector m_dependencies{ winrt::single_threaded_vector() }; Windows::Foundation::Collections::ValueSet m_directives; @@ -55,3 +54,12 @@ namespace winrt::Microsoft::Management::Configuration::implementation #endif }; } + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) +namespace winrt::Microsoft::Management::Configuration::factory_implementation +{ + struct ConfigurationUnit : ConfigurationUnitT + { + }; +} +#endif \ No newline at end of file diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl index 1ae7993013..85834a3342 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -147,7 +147,7 @@ namespace Microsoft.Management.Configuration Windows.Foundation.Collections.ValueSet Directives{ get; }; // Contains the values that are for use by the configuration unit itself. - Windows.Foundation.Collections.ValueSet Settings; + Windows.Foundation.Collections.ValueSet Settings{ get; }; // Contains information on the origin of the configuration unit. // May be null if ConfigurationProcessor.GetDetailsAsync has not been called yet. @@ -244,7 +244,7 @@ namespace Microsoft.Management.Configuration ConfigurationUnit Unit{ get; }; // The directives overlay that the processor was created with. - Windows.Foundation.Collections.ValueSet DirectivesOverlay{ get; }; + Windows.Foundation.Collections.IMapView DirectivesOverlay{ get; }; // Determines if the system is already in the state described by the configuration unit. Boolean TestSettings(); @@ -266,7 +266,7 @@ namespace Microsoft.Management.Configuration // Creates a configuration unit processor for the given unit. // The optional `directivesOverlay` parameter allows for the `ConfigurationProcessor` to alter behavior without needing to change the unit itself. // The overlay is searched first; any value not present there will then fall back to the unit's directives. - IConfigurationUnitProcessor CreateUnitProcessor(ConfigurationUnit unit, Windows.Foundation.Collections.ValueSet directivesOverlay); + IConfigurationUnitProcessor CreateUnitProcessor(ConfigurationUnit unit, Windows.Foundation.Collections.IMapView directivesOverlay); } // The level of the diagnostic information. diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj index 758cb150f1..4bcb641513 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -128,12 +128,16 @@ + + + + diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters index 3b881d27db..52a50067f1 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters @@ -6,12 +6,16 @@ + + + + diff --git a/src/Microsoft.Management.Configuration/pch.h b/src/Microsoft.Management.Configuration/pch.h index 12b524b84e..5250675513 100644 --- a/src/Microsoft.Management.Configuration/pch.h +++ b/src/Microsoft.Management.Configuration/pch.h @@ -4,6 +4,7 @@ #include #include #include +#include // TODO: Is this needed? From 50700b19a20e2f0b8bc52724c626bc1fc0e1377b Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Tue, 10 Jan 2023 15:07:49 -0800 Subject: [PATCH 06/31] Skeleton complete --- .../ApplyConfigurationSetResult.cpp | 24 +++ .../ApplyConfigurationSetResult.h | 26 ++++ .../ApplyConfigurationUnitResult.cpp | 24 +++ .../ApplyConfigurationUnitResult.h | 25 +++ .../ConfigurationChangeData.cpp | 30 ++++ .../ConfigurationChangeData.h | 27 ++++ .../ConfigurationConflict.cpp | 50 ++++++ .../ConfigurationConflict.h | 34 +++++ .../ConfigurationConflictSetting.cpp | 30 ++++ .../ConfigurationConflictSetting.h | 27 ++++ .../ConfigurationProcessor.cpp | 84 ++++++++++ .../ConfigurationProcessor.h | 56 +++++++ .../ConfigurationSet.cpp | 144 +++++++++--------- .../ConfigurationSet.h | 5 +- .../DiagnosticInformation.cpp | 24 +++ .../DiagnosticInformation.h | 25 +++ .../GetConfigurationUnitSettingsResult.cpp | 23 +++ .../GetConfigurationUnitSettingsResult.h | 26 ++++ .../Microsoft.Management.Configuration.idl | 2 +- ...Microsoft.Management.Configuration.vcxproj | 20 +++ ...t.Management.Configuration.vcxproj.filters | 111 ++++++++++++-- .../TestConfigurationSetResult.cpp | 23 +++ .../TestConfigurationSetResult.h | 26 ++++ .../TestConfigurationUnitResult.cpp | 30 ++++ .../TestConfigurationUnitResult.h | 27 ++++ src/Microsoft.Management.Configuration/pch.h | 3 +- 26 files changed, 840 insertions(+), 86 deletions(-) create mode 100644 src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.cpp create mode 100644 src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.h create mode 100644 src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp create mode 100644 src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h create mode 100644 src/Microsoft.Management.Configuration/ConfigurationChangeData.cpp create mode 100644 src/Microsoft.Management.Configuration/ConfigurationChangeData.h create mode 100644 src/Microsoft.Management.Configuration/ConfigurationConflict.cpp create mode 100644 src/Microsoft.Management.Configuration/ConfigurationConflict.h create mode 100644 src/Microsoft.Management.Configuration/ConfigurationConflictSetting.cpp create mode 100644 src/Microsoft.Management.Configuration/ConfigurationConflictSetting.h create mode 100644 src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp create mode 100644 src/Microsoft.Management.Configuration/ConfigurationProcessor.h create mode 100644 src/Microsoft.Management.Configuration/DiagnosticInformation.cpp create mode 100644 src/Microsoft.Management.Configuration/DiagnosticInformation.h create mode 100644 src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp create mode 100644 src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h create mode 100644 src/Microsoft.Management.Configuration/TestConfigurationSetResult.cpp create mode 100644 src/Microsoft.Management.Configuration/TestConfigurationSetResult.h create mode 100644 src/Microsoft.Management.Configuration/TestConfigurationUnitResult.cpp create mode 100644 src/Microsoft.Management.Configuration/TestConfigurationUnitResult.h diff --git a/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.cpp b/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.cpp new file mode 100644 index 0000000000..e49fb0c502 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.cpp @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ApplyConfigurationSetResult.h" +#include "ApplyConfigurationSetResult.g.cpp" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + void ApplyConfigurationSetResult::Initialize(std::vector&& unitResults, hresult resultCode) + { + m_unitResults = winrt::single_threaded_vector(std::move(unitResults)); + m_resultCode = resultCode; + } + + Windows::Foundation::Collections::IVectorView ApplyConfigurationSetResult::UnitResults() + { + return m_unitResults.GetView(); + } + + hresult ApplyConfigurationSetResult::ResultCode() + { + return m_resultCode; + } +} diff --git a/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.h b/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.h new file mode 100644 index 0000000000..8c5ab7142c --- /dev/null +++ b/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.h @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ApplyConfigurationSetResult.g.h" +#include + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct ApplyConfigurationSetResult : ApplyConfigurationSetResultT + { + ApplyConfigurationSetResult() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void Initialize(std::vector&& unitResults, hresult resultCode); +#endif + + Windows::Foundation::Collections::IVectorView UnitResults(); + hresult ResultCode(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + Windows::Foundation::Collections::IVector m_unitResults = nullptr; + hresult m_resultCode; +#endif + }; +} diff --git a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp new file mode 100644 index 0000000000..627c40a3f4 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ApplyConfigurationUnitResult.h" +#include "ApplyConfigurationUnitResult.g.cpp" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + void ApplyConfigurationUnitResult::Initialize(const ConfigurationUnit& unit, const ConfigurationUnitResultInformation& resultInformation) + { + m_unit = unit; + m_resultInformation = resultInformation; + } + + ConfigurationUnit ApplyConfigurationUnitResult::Unit() + { + return m_unit; + } + + ConfigurationUnitResultInformation ApplyConfigurationUnitResult::ResultInformation() + { + return m_resultInformation; + } +} diff --git a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h new file mode 100644 index 0000000000..52c5f30d76 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ApplyConfigurationUnitResult.g.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct ApplyConfigurationUnitResult : ApplyConfigurationUnitResultT + { + ApplyConfigurationUnitResult() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void Initialize(const ConfigurationUnit& unit, const ConfigurationUnitResultInformation& resultInformation); +#endif + + ConfigurationUnit Unit(); + ConfigurationUnitResultInformation ResultInformation(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + ConfigurationUnit m_unit = nullptr; + ConfigurationUnitResultInformation m_resultInformation = nullptr; +#endif + }; +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationChangeData.cpp b/src/Microsoft.Management.Configuration/ConfigurationChangeData.cpp new file mode 100644 index 0000000000..b4b020e693 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationChangeData.cpp @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ConfigurationChangeData.h" +#include "ConfigurationChangeData.g.cpp" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + void ConfigurationChangeData::Initialize(ConfigurationChangeEventType change, guid instanceIdentifier, ConfigurationSetState state) + { + m_change = change; + m_instanceIdentifier = instanceIdentifier; + m_state = state; + } + + ConfigurationChangeEventType ConfigurationChangeData::Change() + { + return m_change; + } + + guid ConfigurationChangeData::InstanceIdentifier() + { + return m_instanceIdentifier; + } + + ConfigurationSetState ConfigurationChangeData::State() + { + return m_state; + } +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationChangeData.h b/src/Microsoft.Management.Configuration/ConfigurationChangeData.h new file mode 100644 index 0000000000..8e6fab6d96 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationChangeData.h @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ConfigurationChangeData.g.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct ConfigurationChangeData : ConfigurationChangeDataT + { + ConfigurationChangeData() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void Initialize(ConfigurationChangeEventType change, guid instanceIdentifier, ConfigurationSetState state); +#endif + + ConfigurationChangeEventType Change(); + guid InstanceIdentifier(); + ConfigurationSetState State(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + ConfigurationChangeEventType m_change{}; + guid m_instanceIdentifier; + ConfigurationSetState m_state{}; +#endif + }; +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationConflict.cpp b/src/Microsoft.Management.Configuration/ConfigurationConflict.cpp new file mode 100644 index 0000000000..6d945ba068 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationConflict.cpp @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ConfigurationConflict.h" +#include "ConfigurationConflict.g.cpp" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + void ConfigurationConflict::Initialize(ConfigurationConflictType conflict) + { + m_conflict = conflict; + } + + ConfigurationConflictType ConfigurationConflict::Conflict() + { + return m_conflict; + } + + ConfigurationSet ConfigurationConflict::FirstSet() + { + return m_firstSet; + } + + ConfigurationSet ConfigurationConflict::SecondSet() + { + return m_secondSet; + } + + ConfigurationUnit ConfigurationConflict::FirstUnit() + { + return m_firstUnit; + } + + ConfigurationUnit ConfigurationConflict::SecondUnit() + { + return m_secondUnit; + } + + Windows::Foundation::Collections::IVectorView ConfigurationConflict::Settings() + { + if (m_settings) + { + return m_settings.GetView(); + } + else + { + return nullptr; + } + } +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationConflict.h b/src/Microsoft.Management.Configuration/ConfigurationConflict.h new file mode 100644 index 0000000000..6956916df5 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationConflict.h @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ConfigurationConflict.g.h" +#include + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct ConfigurationConflict : ConfigurationConflictT + { + ConfigurationConflict() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void Initialize(ConfigurationConflictType conflict); +#endif + + ConfigurationConflictType Conflict(); + ConfigurationSet FirstSet(); + ConfigurationSet SecondSet(); + ConfigurationUnit FirstUnit(); + ConfigurationUnit SecondUnit(); + Windows::Foundation::Collections::IVectorView Settings(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + ConfigurationConflictType m_conflict{}; + ConfigurationSet m_firstSet = nullptr; + ConfigurationSet m_secondSet = nullptr; + ConfigurationUnit m_firstUnit = nullptr; + ConfigurationUnit m_secondUnit = nullptr; + Windows::Foundation::Collections::IVector m_settings = nullptr; +#endif + }; +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationConflictSetting.cpp b/src/Microsoft.Management.Configuration/ConfigurationConflictSetting.cpp new file mode 100644 index 0000000000..a68546d625 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationConflictSetting.cpp @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ConfigurationConflictSetting.h" +#include "ConfigurationConflictSetting.g.cpp" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + void ConfigurationConflictSetting::Initialize(std::wstring_view name, const IInspectable& firstValue, const IInspectable& secondValue) + { + m_name = name; + m_firstValue = firstValue; + m_secondValue = secondValue; + } + + hstring ConfigurationConflictSetting::Name() + { + return m_name; + } + + ConfigurationConflictSetting::IInspectable ConfigurationConflictSetting::FirstValue() + { + return m_firstValue; + } + + ConfigurationConflictSetting::IInspectable ConfigurationConflictSetting::SecondValue() + { + return m_secondValue; + } +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationConflictSetting.h b/src/Microsoft.Management.Configuration/ConfigurationConflictSetting.h new file mode 100644 index 0000000000..bf790906fc --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationConflictSetting.h @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ConfigurationConflictSetting.g.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct ConfigurationConflictSetting : ConfigurationConflictSettingT + { + ConfigurationConflictSetting() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void Initialize(std::wstring_view name, const IInspectable& firstValue, const IInspectable& secondValue); +#endif + + hstring Name(); + IInspectable FirstValue(); + IInspectable SecondValue(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + hstring m_name; + IInspectable m_firstValue = nullptr; + IInspectable m_secondValue = nullptr; +#endif + }; +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp new file mode 100644 index 0000000000..766093f98f --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp @@ -0,0 +1,84 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ConfigurationProcessor.h" +#include "ConfigurationProcessor.g.cpp" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + ConfigurationProcessor::ConfigurationProcessor(const IConfigurationProcessorFactory& factory) : m_factory(factory) + { + } + + void ConfigurationProcessor::Initialize() + { + + } + + event_token ConfigurationProcessor::Diagnostics(const Windows::Foundation::EventHandler& handler) + { + return m_diagnostics.add(handler); + } + + void ConfigurationProcessor::Diagnostics(const event_token& token) noexcept + { + m_diagnostics.remove(token); + } + + event_token ConfigurationProcessor::ConfigurationChange(const Windows::Foundation::TypedEventHandler& handler) + { + return m_configurationChange.add(handler); + } + + void ConfigurationProcessor::ConfigurationChange(const event_token& token) noexcept + { + m_configurationChange.remove(token); + } + + Windows::Foundation::Collections::IVector ConfigurationProcessor::GetConfigurationHistory() + { + THROW_HR(E_NOTIMPL); + } + + Windows::Foundation::IAsyncOperation> ConfigurationProcessor::CheckForConflictsAsync( + const Windows::Foundation::Collections::IVectorView& configurationSets, + bool includeConfigurationHistory) + { + UNREFERENCED_PARAMETER(configurationSets); + UNREFERENCED_PARAMETER(includeConfigurationHistory); + THROW_HR(E_NOTIMPL); + } + + Windows::Foundation::IAsyncAction ConfigurationProcessor::GetSetDetailsAsync(const ConfigurationSet& configurationSet, const ConfigurationUnitDetailLevel& detailLevel) + { + UNREFERENCED_PARAMETER(configurationSet); + UNREFERENCED_PARAMETER(detailLevel); + THROW_HR(E_NOTIMPL); + } + + Windows::Foundation::IAsyncAction ConfigurationProcessor::GetUnitDetailsAsync(const ConfigurationUnit& unit, const ConfigurationUnitDetailLevel& detailLevel) + { + UNREFERENCED_PARAMETER(unit); + UNREFERENCED_PARAMETER(detailLevel); + THROW_HR(E_NOTIMPL); + } + + Windows::Foundation::IAsyncOperation ConfigurationProcessor::ApplyAsync(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags) + { + UNREFERENCED_PARAMETER(configurationSet); + UNREFERENCED_PARAMETER(flags); + THROW_HR(E_NOTIMPL); + } + + Windows::Foundation::IAsyncOperation ConfigurationProcessor::TestAsync(const ConfigurationSet& configurationSet) + { + UNREFERENCED_PARAMETER(configurationSet); + THROW_HR(E_NOTIMPL); + } + + Windows::Foundation::IAsyncOperation ConfigurationProcessor::GetSettingsAsync(const ConfigurationUnit& unit) + { + UNREFERENCED_PARAMETER(unit); + THROW_HR(E_NOTIMPL); + } +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.h b/src/Microsoft.Management.Configuration/ConfigurationProcessor.h new file mode 100644 index 0000000000..09d600f8ca --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationProcessor.h @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ConfigurationProcessor.g.h" +#include +#include + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct ConfigurationProcessor : ConfigurationProcessorT + { + ConfigurationProcessor(const IConfigurationProcessorFactory& factory); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void Initialize(); +#endif + + event_token Diagnostics(const Windows::Foundation::EventHandler& handler); + void Diagnostics(const event_token& token) noexcept; + + event_token ConfigurationChange(const Windows::Foundation::TypedEventHandler& handler); + void ConfigurationChange(const event_token& token) noexcept; + + Windows::Foundation::Collections::IVector GetConfigurationHistory(); + + Windows::Foundation::IAsyncOperation> CheckForConflictsAsync( + const Windows::Foundation::Collections::IVectorView& configurationSets, + bool includeConfigurationHistory); + + Windows::Foundation::IAsyncAction GetSetDetailsAsync(const ConfigurationSet& configurationSet, const ConfigurationUnitDetailLevel& detailLevel); + + Windows::Foundation::IAsyncAction GetUnitDetailsAsync(const ConfigurationUnit& unit, const ConfigurationUnitDetailLevel& detailLevel); + + Windows::Foundation::IAsyncOperation ApplyAsync(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags); + + Windows::Foundation::IAsyncOperation TestAsync(const ConfigurationSet& configurationSet); + + Windows::Foundation::IAsyncOperation GetSettingsAsync(const ConfigurationUnit& unit); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + IConfigurationProcessorFactory m_factory = nullptr; + event> m_diagnostics; + event> m_configurationChange; +#endif + }; +} + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) +namespace winrt::Microsoft::Management::Configuration::factory_implementation +{ + struct ConfigurationProcessor : ConfigurationProcessorT + { + }; +} +#endif diff --git a/src/Microsoft.Management.Configuration/ConfigurationSet.cpp b/src/Microsoft.Management.Configuration/ConfigurationSet.cpp index 7e4728dfcd..535b309397 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSet.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSet.cpp @@ -6,103 +6,103 @@ namespace winrt::Microsoft::Management::Configuration::implementation { - ConfigurationSet::ConfigurationSet() + ConfigurationSet::ConfigurationSet() { GUID instanceIdentifier; THROW_IF_FAILED(CoCreateGuid(&instanceIdentifier)); - m_instanceIdentifier = instanceIdentifier; - } + m_instanceIdentifier = instanceIdentifier; + } - ConfigurationSet::ConfigurationSet(const Windows::Storage::Streams::IInputStream& stream) - { - UNREFERENCED_PARAMETER(stream); - THROW_HR(E_NOTIMPL); - } + ConfigurationSet::ConfigurationSet(const Windows::Storage::Streams::IInputStream& stream) + { + UNREFERENCED_PARAMETER(stream); + THROW_HR(E_NOTIMPL); + } ConfigurationSet::ConfigurationSet(const guid& instanceIdentifier) : - m_instanceIdentifier(instanceIdentifier), m_mutableFlag(false) - { - } + m_instanceIdentifier(instanceIdentifier), m_mutableFlag(false) + { + } - hstring ConfigurationSet::Name() - { - return m_name; - } + hstring ConfigurationSet::Name() + { + return m_name; + } - void ConfigurationSet::Name(const hstring& value) + void ConfigurationSet::Name(const hstring& value) { m_mutableFlag.RequireMutable(); - m_name = value; - } + m_name = value; + } - hstring ConfigurationSet::Origin() - { - return m_origin; - } + hstring ConfigurationSet::Origin() + { + return m_origin; + } - void ConfigurationSet::Origin(const hstring& value) + void ConfigurationSet::Origin(const hstring& value) { m_mutableFlag.RequireMutable(); - m_origin = value; - } + m_origin = value; + } - guid ConfigurationSet::InstanceIdentifier() - { - return m_instanceIdentifier; - } + guid ConfigurationSet::InstanceIdentifier() + { + return m_instanceIdentifier; + } - ConfigurationSetState ConfigurationSet::State() - { - return ConfigurationSetState::Unknown; - } + ConfigurationSetState ConfigurationSet::State() + { + return ConfigurationSetState::Unknown; + } - clock::time_point ConfigurationSet::InitialIntent() - { - return clock::time_point{}; - } + clock::time_point ConfigurationSet::InitialIntent() + { + return clock::time_point{}; + } - clock::time_point ConfigurationSet::ApplyBegun() - { - return clock::time_point{}; - } + clock::time_point ConfigurationSet::ApplyBegun() + { + return clock::time_point{}; + } - clock::time_point ConfigurationSet::ApplyEnded() - { - return clock::time_point{}; - } + clock::time_point ConfigurationSet::ApplyEnded() + { + return clock::time_point{}; + } - Windows::Foundation::Collections::IVectorView ConfigurationSet::ConfigurationUnits() - { - return m_configurationUnits.GetView(); - } + Windows::Foundation::Collections::IVectorView ConfigurationSet::ConfigurationUnits() + { + return m_configurationUnits.GetView(); + } - void ConfigurationSet::ConfigurationUnits(const Windows::Foundation::Collections::IVectorView& value) + void ConfigurationSet::ConfigurationUnits(const Windows::Foundation::Collections::IVectorView& value) { m_mutableFlag.RequireMutable(); std::vector temp{ value.Size() }; value.GetMany(0, temp); - m_configurationUnits = winrt::single_threaded_vector(std::move(temp)); - } - - event_token ConfigurationSet::ConfigurationSetChange(const Windows::Foundation::TypedEventHandler& value) - { - return m_configurationSetChange.add(value); - } - - void ConfigurationSet::ConfigurationSetChange(const event_token& token) - { - m_configurationSetChange.remove(token); - } - - void ConfigurationSet::Serialize(const Windows::Storage::Streams::IOutputStream& stream) - { - UNREFERENCED_PARAMETER(stream); - THROW_HR(E_NOTIMPL); - } - - void ConfigurationSet::Remove() - { - THROW_HR(E_NOTIMPL); + m_configurationUnits = winrt::single_threaded_vector(std::move(temp)); + } + + event_token ConfigurationSet::ConfigurationSetChange(const Windows::Foundation::TypedEventHandler& handler) + { + return m_configurationSetChange.add(handler); + } + + void ConfigurationSet::ConfigurationSetChange(const event_token& token) noexcept + { + m_configurationSetChange.remove(token); + } + + void ConfigurationSet::Serialize(const Windows::Storage::Streams::IOutputStream& stream) + { + UNREFERENCED_PARAMETER(stream); + THROW_HR(E_NOTIMPL); + } + + void ConfigurationSet::Remove() + { + THROW_HR(E_NOTIMPL); } } diff --git a/src/Microsoft.Management.Configuration/ConfigurationSet.h b/src/Microsoft.Management.Configuration/ConfigurationSet.h index 9300d43379..ac9667bacc 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSet.h +++ b/src/Microsoft.Management.Configuration/ConfigurationSet.h @@ -3,6 +3,7 @@ #pragma once #include "ConfigurationSet.g.h" #include "MutableFlag.h" +#include #include #include @@ -34,8 +35,8 @@ namespace winrt::Microsoft::Management::Configuration::implementation Windows::Foundation::Collections::IVectorView ConfigurationUnits(); void ConfigurationUnits(const Windows::Foundation::Collections::IVectorView& value); - event_token ConfigurationSetChange(const Windows::Foundation::TypedEventHandler& value); - void ConfigurationSetChange(const event_token& token); + event_token ConfigurationSetChange(const Windows::Foundation::TypedEventHandler& handler); + void ConfigurationSetChange(const event_token& token) noexcept; void Serialize(const Windows::Storage::Streams::IOutputStream& stream); diff --git a/src/Microsoft.Management.Configuration/DiagnosticInformation.cpp b/src/Microsoft.Management.Configuration/DiagnosticInformation.cpp new file mode 100644 index 0000000000..0877e4910f --- /dev/null +++ b/src/Microsoft.Management.Configuration/DiagnosticInformation.cpp @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "DiagnosticInformation.h" +#include "DiagnosticInformation.g.cpp" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + void DiagnosticInformation::Initialize(DiagnosticLevel level, std::wstring_view message) + { + m_level = level; + m_message = message; + } + + DiagnosticLevel DiagnosticInformation::Level() + { + return m_level; + } + + hstring DiagnosticInformation::Message() + { + return m_message; + } +} diff --git a/src/Microsoft.Management.Configuration/DiagnosticInformation.h b/src/Microsoft.Management.Configuration/DiagnosticInformation.h new file mode 100644 index 0000000000..78f6020e9b --- /dev/null +++ b/src/Microsoft.Management.Configuration/DiagnosticInformation.h @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "DiagnosticInformation.g.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct DiagnosticInformation : DiagnosticInformationT + { + DiagnosticInformation() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void Initialize(DiagnosticLevel level, std::wstring_view message); +#endif + + DiagnosticLevel Level(); + hstring Message(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + DiagnosticLevel m_level; + hstring m_message; +#endif + }; +} diff --git a/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp new file mode 100644 index 0000000000..04f037c6c5 --- /dev/null +++ b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "GetConfigurationUnitSettingsResult.h" +#include "GetConfigurationUnitSettingsResult.g.cpp" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + void GetConfigurationUnitSettingsResult::Initialize() + { + + } + + ConfigurationUnitResultInformation GetConfigurationUnitSettingsResult::ResultInformation() + { + return m_resultInformation; + } + + Windows::Foundation::Collections::ValueSet GetConfigurationUnitSettingsResult::Settings() + { + return m_settings; + } +} diff --git a/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h new file mode 100644 index 0000000000..f428b2e7de --- /dev/null +++ b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "GetConfigurationUnitSettingsResult.g.h" +#include + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct GetConfigurationUnitSettingsResult : GetConfigurationUnitSettingsResultT + { + GetConfigurationUnitSettingsResult() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void Initialize(); +#endif + + ConfigurationUnitResultInformation ResultInformation(); + Windows::Foundation::Collections::ValueSet Settings(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + ConfigurationUnitResultInformation m_resultInformation = nullptr; + Windows::Foundation::Collections::ValueSet m_settings = nullptr; +#endif + }; +} diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl index 85834a3342..fb9cce66ff 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -454,7 +454,7 @@ namespace Microsoft.Management.Configuration // Gets the configuration sets that have already been applied or the intent to be applied (this may include in progress sets or those that are waiting on others). // These configuration sets will be marked as immutable. - Windows.Foundation.Collections.IVectorView GetConfigurationHistory(); + Windows.Foundation.Collections.IVector GetConfigurationHistory(); // Checks for conflicts amongst the configuration sets provided, optionally including the configuration sets already applied to the system. Windows.Foundation.IAsyncOperation< Windows.Foundation.Collections.IVectorView > CheckForConflictsAsync(Windows.Foundation.Collections.IVectorView configurationSets, Boolean includeConfigurationHistory); diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj index 4bcb641513..2e2eea0e00 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -128,23 +128,43 @@ + + + + + + + + + + + + + + + + + + Create + + diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters index 52a50067f1..4d944b5654 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters @@ -3,19 +3,99 @@ - - - - - + + API Source + + + API Source + + + API Source + + + API Source + + + API Source + + + API Source + + + API Source + + + API Source + + + API Source + + + API Source + + + API Source + + + Internals + + + API Source + + + API Source + + + API Source + - - - - - + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + Internals + + + API Headers + + + API Headers + + + API Headers + @@ -25,4 +105,15 @@ + + + {0826fc0e-120c-4e31-bde7-ce0a1278b1b1} + + + {6dbfe76d-646d-43b0-b162-e1dedad10ab8} + + + {c5f2f74e-de80-4235-abbd-bacd6771eaf2} + + \ No newline at end of file diff --git a/src/Microsoft.Management.Configuration/TestConfigurationSetResult.cpp b/src/Microsoft.Management.Configuration/TestConfigurationSetResult.cpp new file mode 100644 index 0000000000..ffe0f5da98 --- /dev/null +++ b/src/Microsoft.Management.Configuration/TestConfigurationSetResult.cpp @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "TestConfigurationSetResult.h" +#include "TestConfigurationSetResult.g.cpp" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + void TestConfigurationSetResult::Initialize() + { + + } + + Windows::Foundation::Collections::IVectorView TestConfigurationSetResult::UnitResults() + { + return m_unitResults.GetView(); + } + + bool TestConfigurationSetResult::TestResult() + { + return m_testResult; + } +} diff --git a/src/Microsoft.Management.Configuration/TestConfigurationSetResult.h b/src/Microsoft.Management.Configuration/TestConfigurationSetResult.h new file mode 100644 index 0000000000..5a9624c68f --- /dev/null +++ b/src/Microsoft.Management.Configuration/TestConfigurationSetResult.h @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "TestConfigurationSetResult.g.h" +#include + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct TestConfigurationSetResult : TestConfigurationSetResultT + { + TestConfigurationSetResult() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void Initialize(); +#endif + + Windows::Foundation::Collections::IVectorView UnitResults(); + bool TestResult(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + Windows::Foundation::Collections::IVector m_unitResults = nullptr; + bool m_testResult; +#endif + }; +} diff --git a/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.cpp b/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.cpp new file mode 100644 index 0000000000..7ede81d198 --- /dev/null +++ b/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.cpp @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "TestConfigurationUnitResult.h" +#include "TestConfigurationUnitResult.g.cpp" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + void TestConfigurationUnitResult::Initialize(ConfigurationUnit unit, ConfigurationUnitResultInformation resultInformation, bool testResult) + { + m_unit = unit; + m_resultInformation = resultInformation; + m_testResult = testResult; + } + + ConfigurationUnit TestConfigurationUnitResult::Unit() + { + return m_unit; + } + + ConfigurationUnitResultInformation TestConfigurationUnitResult::ResultInformation() + { + return m_resultInformation; + } + + bool TestConfigurationUnitResult::TestResult() + { + return m_testResult; + } +} diff --git a/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.h b/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.h new file mode 100644 index 0000000000..1657da531c --- /dev/null +++ b/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.h @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "TestConfigurationUnitResult.g.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct TestConfigurationUnitResult : TestConfigurationUnitResultT + { + TestConfigurationUnitResult() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void Initialize(ConfigurationUnit unit, ConfigurationUnitResultInformation resultInformation, bool testResult); +#endif + + ConfigurationUnit Unit(); + ConfigurationUnitResultInformation ResultInformation(); + bool TestResult(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + ConfigurationUnit m_unit = nullptr; + ConfigurationUnitResultInformation m_resultInformation = nullptr; + bool m_testResult; +#endif + }; +} diff --git a/src/Microsoft.Management.Configuration/pch.h b/src/Microsoft.Management.Configuration/pch.h index 5250675513..d308521cc2 100644 --- a/src/Microsoft.Management.Configuration/pch.h +++ b/src/Microsoft.Management.Configuration/pch.h @@ -15,4 +15,5 @@ #include #pragma warning( pop ) -#include \ No newline at end of file +#include +#include From d3cc1ceed1ed1217f61adf1c73fc1f113aecb510 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Tue, 10 Jan 2023 17:52:49 -0800 Subject: [PATCH 07/31] Convert to project to DLL --- .../Microsoft.Management.Configuration.vcxproj | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj index 2e2eea0e00..e0f0f85e8b 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -16,7 +16,6 @@ 10.0.17763.0 true true - -library Microsoft_Management_Configuration @@ -54,7 +53,7 @@ - StaticLibrary + DynamicLibrary v140 v141 v142 @@ -86,7 +85,7 @@ $(VC_IncludePath);$(WindowsSDK_IncludePath); $(SolutionDir)$(PlatformTarget)\$(Configuration)\$(ProjectName)\ $(PlatformTarget)\$(Configuration)\ - $(RootNamespace).Server + $(RootNamespace) true false ..\CodeAnalysis.ruleset From 5c0633aa130985dfdc48bd423ccdf9eb191e1fa3 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Wed, 11 Jan 2023 17:39:59 -0800 Subject: [PATCH 08/31] Begin YAML parsing --- .../ConfigurationSet.cpp | 35 +++++++++++++++++-- ...Microsoft.Management.Configuration.vcxproj | 9 +++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.Management.Configuration/ConfigurationSet.cpp b/src/Microsoft.Management.Configuration/ConfigurationSet.cpp index 535b309397..81e482a9bf 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSet.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSet.cpp @@ -4,8 +4,39 @@ #include "ConfigurationSet.h" #include "ConfigurationSet.g.cpp" +#include + namespace winrt::Microsoft::Management::Configuration::implementation { + namespace + { + std::string StreamToString(const Windows::Storage::Streams::IInputStream& stream) + { + uint32_t bufferSize = 1 << 20; + Windows::Storage::Streams::Buffer buffer(bufferSize); + Windows::Storage::Streams::InputStreamOptions readOptions = Windows::Storage::Streams::InputStreamOptions::Partial | Windows::Storage::Streams::InputStreamOptions::ReadAhead; + std::string result; + + for (;;) + { + Windows::Storage::Streams::IBuffer readBuffer = stream.ReadAsync(buffer, bufferSize, readOptions).GetResults(); + + size_t readSize = static_cast(readBuffer.Length()); + if (readSize) + { + static_assert(sizeof(char) == sizeof(*readBuffer.data())); + result.append(reinterpret_cast(readBuffer.data()), readSize); + } + else + { + break; + } + } + + return result; + } + } + ConfigurationSet::ConfigurationSet() { GUID instanceIdentifier; @@ -15,8 +46,8 @@ namespace winrt::Microsoft::Management::Configuration::implementation ConfigurationSet::ConfigurationSet(const Windows::Storage::Streams::IInputStream& stream) { - UNREFERENCED_PARAMETER(stream); - THROW_HR(E_NOTIMPL); + std::string input = StreamToString(stream); + AppInstaller::YAML::Node yaml = AppInstaller::YAML::Load(input); } ConfigurationSet::ConfigurationSet(const guid& instanceIdentifier) : diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj index e0f0f85e8b..d864df153f 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -101,14 +101,14 @@ true _WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) - %(AdditionalIncludeDirectories) + $(ProjectDir)..\AppInstallerCommonCore\Public;%(AdditionalIncludeDirectories) Console false Microsoft_Management_Configuration.def $(OutDir)$(ProjectName).winmd - %(AdditionalDependencies) + Advapi32.lib;%(AdditionalDependencies) @@ -175,6 +175,11 @@ + + + {5890d6ed-7c3b-40f3-b436-b54f640d9e65} + + From 372f02d301af23f4e88a81d6c8e63e2f0dbd4c65 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Fri, 13 Jan 2023 17:05:28 -0800 Subject: [PATCH 09/31] build fix and API updates --- .../Public/AppInstallerSHA256.h | 2 +- .../ConfigurationSet.cpp | 15 ++++++++++++- .../ConfigurationSet.h | 4 ++++ .../ConfigurationUnit.cpp | 11 ++++++++++ .../ConfigurationUnit.h | 4 ++++ .../Microsoft.Management.Configuration.idl | 21 +++++++++++++++++++ ...Microsoft.Management.Configuration.vcxproj | 2 +- src/Microsoft.Management.Configuration/pch.h | 9 ++++++++ 8 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/AppInstallerSharedLib/Public/AppInstallerSHA256.h b/src/AppInstallerSharedLib/Public/AppInstallerSHA256.h index 959231abe2..472e1700e3 100644 --- a/src/AppInstallerSharedLib/Public/AppInstallerSHA256.h +++ b/src/AppInstallerSharedLib/Public/AppInstallerSHA256.h @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #pragma once - +#include #include #include #include diff --git a/src/Microsoft.Management.Configuration/ConfigurationSet.cpp b/src/Microsoft.Management.Configuration/ConfigurationSet.cpp index 81e482a9bf..47900336fb 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSet.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSet.cpp @@ -44,10 +44,12 @@ namespace winrt::Microsoft::Management::Configuration::implementation m_instanceIdentifier = instanceIdentifier; } - ConfigurationSet::ConfigurationSet(const Windows::Storage::Streams::IInputStream& stream) + ConfigurationSet::ConfigurationSet(const Windows::Storage::Streams::IInputStream& stream) : ConfigurationSet() { std::string input = StreamToString(stream); AppInstaller::YAML::Node yaml = AppInstaller::YAML::Load(input); + + } ConfigurationSet::ConfigurationSet(const guid& instanceIdentifier) : @@ -77,6 +79,17 @@ namespace winrt::Microsoft::Management::Configuration::implementation m_origin = value; } + hstring ConfigurationSet::Path() + { + return m_path; + } + + void ConfigurationSet::Path(const hstring& value) + { + m_mutableFlag.RequireMutable(); + m_path = value; + } + guid ConfigurationSet::InstanceIdentifier() { return m_instanceIdentifier; diff --git a/src/Microsoft.Management.Configuration/ConfigurationSet.h b/src/Microsoft.Management.Configuration/ConfigurationSet.h index ac9667bacc..4533691ce5 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSet.h +++ b/src/Microsoft.Management.Configuration/ConfigurationSet.h @@ -26,6 +26,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation hstring Origin(); void Origin(const hstring& value); + hstring Path(); + void Path(const hstring& value); + guid InstanceIdentifier(); ConfigurationSetState State(); clock::time_point InitialIntent(); @@ -46,6 +49,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation private: hstring m_name; hstring m_origin; + hstring m_path; guid m_instanceIdentifier; clock::time_point m_initialIntent; Windows::Foundation::Collections::IVector m_configurationUnits{ winrt::single_threaded_vector() }; diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp b/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp index 8b0e2ceebb..0b991f5c15 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp @@ -45,6 +45,17 @@ namespace winrt::Microsoft::Management::Configuration::implementation m_identifier = value; } + ConfigurationUnitIntent ConfigurationUnit::Intent() + { + return m_intent; + } + + void ConfigurationUnit::Intent(ConfigurationUnitIntent value) + { + m_mutableFlag.RequireMutable(); + m_intent = value; + } + Windows::Foundation::Collections::IVectorView ConfigurationUnit::Dependencies() { return m_dependencies.GetView(); diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnit.h b/src/Microsoft.Management.Configuration/ConfigurationUnit.h index e04b6a45aa..20c8ab0eed 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationUnit.h +++ b/src/Microsoft.Management.Configuration/ConfigurationUnit.h @@ -23,6 +23,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation hstring Identifier(); void Identifier(const hstring& value); + ConfigurationUnitIntent Intent(); + void Intent(ConfigurationUnitIntent value); + Windows::Foundation::Collections::IVectorView Dependencies(); void Dependencies(const Windows::Foundation::Collections::IVectorView& value); @@ -44,6 +47,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation hstring m_unitName; guid m_instanceIdentifier; hstring m_identifier; + ConfigurationUnitIntent m_intent = ConfigurationUnitIntent::Apply; Windows::Foundation::Collections::IVector m_dependencies{ winrt::single_threaded_vector() }; Windows::Foundation::Collections::ValueSet m_directives; Windows::Foundation::Collections::ValueSet m_settings; diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl index fb9cce66ff..f52725b762 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -120,6 +120,19 @@ namespace Microsoft.Management.Configuration Windows.Foundation.Collections.IVectorView Settings{ get; }; } + // Defines how the configuration unit is to be used within the configuration system. + [contract(Microsoft.Management.Configuration.Contract, 1)] + enum ConfigurationUnitIntent + { + // The configuration unit will only be used to Test the current system state. + Assert, + // The configuration unit will only be used to Get the current system state. + Inform, + // The configuration unit will be used to Set the current system state. + // The configuration unit will be used to Test and Get the current system state as part of that process. + Apply, + }; + // A single unit of configuration. [contract(Microsoft.Management.Configuration.Contract, 1)] runtimeclass ConfigurationUnit @@ -139,6 +152,10 @@ namespace Microsoft.Management.Configuration // Can be changed if a mutable unit. String Identifier; + // Describes how this configuration unit will be used. + // Can be changed if a mutable unit. + ConfigurationUnitIntent Intent; + // The configuration units that this unit depends on. // Can be set on a mutable configuration unit; this will copy the items into the internal storage. Windows.Foundation.Collections.IVectorView Dependencies; @@ -208,6 +225,10 @@ namespace Microsoft.Management.Configuration // The origin of the set; if it came from a repository it could be the remote URL (ex. https://github.com/microsoft/winget-cli.git). // Can be changed if a mutable set. String Origin; + // The location of the configuration set on the local filesystem. + // If this set is from history, the file may no longer exist or it's contents may have been changed. + // Can be changed if a mutable set. + String Path; // An identifier used to uniquely identify the instance of a configuration set on the system. // Immutable, although the set can be removed and an identical set applied later with a different identifier. diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj index d864df153f..baf38c6c7f 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -101,7 +101,7 @@ true _WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) - $(ProjectDir)..\AppInstallerCommonCore\Public;%(AdditionalIncludeDirectories) + $(ProjectDir)..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) Console diff --git a/src/Microsoft.Management.Configuration/pch.h b/src/Microsoft.Management.Configuration/pch.h index d308521cc2..f3fa3208c6 100644 --- a/src/Microsoft.Management.Configuration/pch.h +++ b/src/Microsoft.Management.Configuration/pch.h @@ -15,5 +15,14 @@ #include #pragma warning( pop ) +#include +#include +#include +#include #include +#include +#include +#include +#include #include +#include From 00383c327aa7ba005c673ee460d842525fd94aba Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Thu, 19 Jan 2023 12:07:08 -0800 Subject: [PATCH 10/31] Basic parser working --- src/AppInstallerCLITests/Versions.cpp | 32 ++++ .../AppInstallerCommonCore.vcxproj | 2 - .../AppInstallerCommonCore.vcxproj.filters | 6 - .../AppInstallerLogging.cpp | 17 +- .../AppInstallerSharedLib.vcxproj | 2 + .../AppInstallerSharedLib.vcxproj.filters | 6 + .../Public/AppInstallerErrors.h | 3 + .../Public/AppInstallerLogging.h | 1 + .../Public/AppInstallerVersions.h | 26 +++ .../Public/winget/Yaml.h | 2 + .../Versions.cpp | 73 ++++++++ src/AppInstallerSharedLib/Yaml.cpp | 5 + .../ConfigurationSet.cpp | 48 ++--- .../ConfigurationSet.h | 1 + .../ConfigurationSetParser.cpp | 82 ++++++++ .../ConfigurationSetParser.h | 38 ++++ .../ConfigurationSetParser_0_1.cpp | 176 ++++++++++++++++++ .../ConfigurationSetParser_0_1.h | 28 +++ .../ConfigurationUnit.cpp | 5 + .../ConfigurationUnit.h | 2 + ...Microsoft.Management.Configuration.vcxproj | 6 +- ...t.Management.Configuration.vcxproj.filters | 15 ++ src/Microsoft.Management.Configuration/pch.h | 1 + 23 files changed, 527 insertions(+), 50 deletions(-) rename src/{AppInstallerCommonCore => AppInstallerSharedLib}/Public/AppInstallerVersions.h (87%) rename src/{AppInstallerCommonCore => AppInstallerSharedLib}/Versions.cpp (83%) create mode 100644 src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp create mode 100644 src/Microsoft.Management.Configuration/ConfigurationSetParser.h create mode 100644 src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.cpp create mode 100644 src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.h diff --git a/src/AppInstallerCLITests/Versions.cpp b/src/AppInstallerCLITests/Versions.cpp index 32a6b36d68..4e07519fda 100644 --- a/src/AppInstallerCLITests/Versions.cpp +++ b/src/AppInstallerCLITests/Versions.cpp @@ -317,3 +317,35 @@ TEST_CASE("VersionRange", "[versions]") REQUIRE(VersionRange{ Version{ "0.5" }, Version{ "1.0" } } < VersionRange{ Version{ "1.5" }, Version{ "2.0" } }); REQUIRE_FALSE(VersionRange{ Version{ "1.5" }, Version{ "2.0" } } < VersionRange{ Version{ "0.5" }, Version{ "1.0" } }); } + +TEST_CASE("SemanticVersion", "[versions]") +{ + REQUIRE_THROWS_HR(SemanticVersion("1.2.3.4"), E_INVALIDARG); + REQUIRE_THROWS_HR(SemanticVersion("1.2abc.3"), E_INVALIDARG); + + SemanticVersion version = SemanticVersion("1.2.3-alpha"); + REQUIRE(version.IsPrerelease()); + REQUIRE(version.PrereleaseVersion() == Version("alpha")); + REQUIRE(!version.HasBuildMetadata()); + REQUIRE(version.PartAt(2).Other == "-alpha"); + + version = SemanticVersion("1.2.3-4.5.6"); + REQUIRE(version.IsPrerelease()); + REQUIRE(version.PrereleaseVersion() == Version("4.5.6")); + REQUIRE(!version.HasBuildMetadata()); + REQUIRE(version.PartAt(2).Other == "-4.5.6"); + + // Really shouldn't be allowed, but we are loose here + version = SemanticVersion("1.2+build"); + REQUIRE(!version.IsPrerelease()); + REQUIRE(version.HasBuildMetadata()); + REQUIRE(version.BuildMetadata() == Version("build")); + REQUIRE(version.PartAt(2).Other == "+build"); + + version = SemanticVersion("1.2.3-beta+4.5.6"); + REQUIRE(version.IsPrerelease()); + REQUIRE(version.PrereleaseVersion() == Version("beta")); + REQUIRE(version.HasBuildMetadata()); + REQUIRE(version.BuildMetadata() == Version("4.5.6")); + REQUIRE(version.PartAt(2).Other == "-beta+4.5.6"); +} diff --git a/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj b/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj index 7ab3ba750c..ac786715f2 100644 --- a/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj +++ b/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj @@ -299,7 +299,6 @@ - @@ -398,7 +397,6 @@ - diff --git a/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj.filters b/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj.filters index 963f635427..ca0cef8615 100644 --- a/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj.filters +++ b/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj.filters @@ -78,9 +78,6 @@ Public - - Public - Public\winget @@ -233,9 +230,6 @@ Source Files - - Source Files - Source Files diff --git a/src/AppInstallerSharedLib/AppInstallerLogging.cpp b/src/AppInstallerSharedLib/AppInstallerLogging.cpp index 3fdc26e160..9e0d3044d9 100644 --- a/src/AppInstallerSharedLib/AppInstallerLogging.cpp +++ b/src/AppInstallerSharedLib/AppInstallerLogging.cpp @@ -33,14 +33,15 @@ namespace AppInstaller::Logging { switch(channel) { - case Channel::Fail: return "FAIL"; - case Channel::CLI: return "CLI"; - case Channel::SQL: return "SQL"; - case Channel::Repo: return "REPO"; - case Channel::YAML: return "YAML"; - case Channel::Core: return "CORE"; - case Channel::Test: return "TEST"; - default: return "NONE"; + case Channel::Fail: return "FAIL"; + case Channel::CLI: return "CLI"; + case Channel::SQL: return "SQL"; + case Channel::Repo: return "REPO"; + case Channel::YAML: return "YAML"; + case Channel::Core: return "CORE"; + case Channel::Test: return "TEST"; + case Channel::Config: return "CONF"; + default: return "NONE"; } } diff --git a/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj b/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj index ff24a2281c..03d0948b82 100644 --- a/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj +++ b/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj @@ -281,6 +281,7 @@ + @@ -300,6 +301,7 @@ + diff --git a/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj.filters b/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj.filters index 808d17d410..1aca372677 100644 --- a/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj.filters +++ b/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj.filters @@ -56,6 +56,9 @@ Public + + Public + @@ -91,6 +94,9 @@ Source Files + + Source Files + diff --git a/src/AppInstallerSharedLib/Public/AppInstallerErrors.h b/src/AppInstallerSharedLib/Public/AppInstallerErrors.h index f7864f751a..6f03f374ca 100644 --- a/src/AppInstallerSharedLib/Public/AppInstallerErrors.h +++ b/src/AppInstallerSharedLib/Public/AppInstallerErrors.h @@ -148,6 +148,9 @@ #define WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK ((HRESULT)0x0A150206) #define WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR ((HRESULT)0x8A150207) +// Configuration Errors +#define WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE ((HRESULT)0x8A15C001) + namespace AppInstaller { diff --git a/src/AppInstallerSharedLib/Public/AppInstallerLogging.h b/src/AppInstallerSharedLib/Public/AppInstallerLogging.h index 59382240c6..e62ca8c2a4 100644 --- a/src/AppInstallerSharedLib/Public/AppInstallerLogging.h +++ b/src/AppInstallerSharedLib/Public/AppInstallerLogging.h @@ -53,6 +53,7 @@ namespace AppInstaller::Logging YAML, Core, Test, + Config, All, }; diff --git a/src/AppInstallerCommonCore/Public/AppInstallerVersions.h b/src/AppInstallerSharedLib/Public/AppInstallerVersions.h similarity index 87% rename from src/AppInstallerCommonCore/Public/AppInstallerVersions.h rename to src/AppInstallerSharedLib/Public/AppInstallerVersions.h index 6b4a01cd0c..4de56ed535 100644 --- a/src/AppInstallerCommonCore/Public/AppInstallerVersions.h +++ b/src/AppInstallerSharedLib/Public/AppInstallerVersions.h @@ -140,6 +140,32 @@ namespace AppInstaller::Utility UINT64 Revision() const { return m_parts.size() > 3 ? m_parts[3].Integer : 0; } }; + // A semantic version as defined by semver.org + // This is currently fairly loose in its restrictions on a version, and is largely to separate out the prelease and build metadata portions. + struct SemanticVersion : public Version + { + SemanticVersion() = default; + SemanticVersion(std::string&& version); + SemanticVersion(const std::string& version) : + SemanticVersion(std::string(version)) {} + + void Assign(std::string version, std::string_view splitChars = DefaultSplitChars) override; + + // Indicates that the version is pre-release + bool IsPrerelease() const; + // The pre-release version + const Version& PrereleaseVersion() const; + + // Indicates that the version has build metadata + bool HasBuildMetadata() const; + // The build metadata version + const Version& BuildMetadata() const; + + private: + Version m_prerelease; + Version m_buildMetadata; + }; + // Version range represented by a min version and max version, both inclusive. struct VersionRange { diff --git a/src/AppInstallerSharedLib/Public/winget/Yaml.h b/src/AppInstallerSharedLib/Public/winget/Yaml.h index 9c8e0d5007..18c11cb4c3 100644 --- a/src/AppInstallerSharedLib/Public/winget/Yaml.h +++ b/src/AppInstallerSharedLib/Public/winget/Yaml.h @@ -99,6 +99,7 @@ namespace AppInstaller::YAML bool IsScalar() const { return m_type == Type::Scalar; } bool IsSequence() const { return m_type == Type::Sequence; } bool IsMap() const { return m_type == Type::Mapping; } + Type GetType() const { return m_type; } explicit operator bool() const { return IsDefined(); } @@ -141,6 +142,7 @@ namespace AppInstaller::YAML // The workers for the as function. std::string as_dispatch(std::string*) const; + std::wstring as_dispatch(std::wstring*) const; int64_t as_dispatch(int64_t*) const; int as_dispatch(int*) const; bool as_dispatch(bool*) const; diff --git a/src/AppInstallerCommonCore/Versions.cpp b/src/AppInstallerSharedLib/Versions.cpp similarity index 83% rename from src/AppInstallerCommonCore/Versions.cpp rename to src/AppInstallerSharedLib/Versions.cpp index a300e8cdcc..468c5fe310 100644 --- a/src/AppInstallerCommonCore/Versions.cpp +++ b/src/AppInstallerSharedLib/Versions.cpp @@ -440,6 +440,79 @@ namespace AppInstaller::Utility THROW_HR_IF(E_INVALIDARG, part.Integer >> 16 != 0); } } + + SemanticVersion::SemanticVersion(std::string&& version) + { + Assign(std::move(version), DefaultSplitChars); + } + + void SemanticVersion::Assign(std::string version, std::string_view splitChars) + { + // Semantic versions require using the default split character + THROW_HR_IF(E_INVALIDARG, splitChars != DefaultSplitChars); + + // First split off any trailing build metadata + std::string interimVersion = version; + size_t buildMetadataPos = interimVersion.find('+', 0); + + if (buildMetadataPos != std::string::npos) + { + m_buildMetadata.Assign(interimVersion.substr(buildMetadataPos + 1)); + interimVersion.resize(buildMetadataPos); + } + + // Now split off the prerelease data + size_t prereleasePos = interimVersion.find('-', 0); + + if (prereleasePos != std::string::npos) + { + m_prerelease.Assign(interimVersion.substr(prereleasePos + 1)); + interimVersion.resize(prereleasePos); + } + + // Parse main version + Version::Assign(std::move(interimVersion), splitChars); + THROW_HR_IF(E_INVALIDARG, IsApproximate()); + THROW_HR_IF(E_INVALIDARG, m_parts.size() > 3); + for (size_t i = 0; i < 3; ++i) + { + THROW_HR_IF(E_INVALIDARG, !PartAt(i).Other.empty()); + } + + // Put rest of version back onto Other of last part + size_t otherSplit = (prereleasePos != std::string::npos ? prereleasePos : buildMetadataPos); + if (otherSplit != std::string::npos) + { + while (m_parts.size() < 3) + { + m_parts.emplace_back(); + } + m_parts[2].Other = version.substr(otherSplit); + } + + // Overwrite the whole version string with our whole version string + m_version = std::move(version); + } + + bool SemanticVersion::IsPrerelease() const + { + return !m_prerelease.IsEmpty(); + } + + const Version& SemanticVersion::PrereleaseVersion() const + { + return m_prerelease; + } + + bool SemanticVersion::HasBuildMetadata() const + { + return !m_buildMetadata.IsEmpty(); + } + + const Version& SemanticVersion::BuildMetadata() const + { + return m_buildMetadata; + } VersionRange::VersionRange(Version minVersion, Version maxVersion) { diff --git a/src/AppInstallerSharedLib/Yaml.cpp b/src/AppInstallerSharedLib/Yaml.cpp index 023bba7c15..fe0d5b7036 100644 --- a/src/AppInstallerSharedLib/Yaml.cpp +++ b/src/AppInstallerSharedLib/Yaml.cpp @@ -238,6 +238,11 @@ namespace AppInstaller::YAML return m_scalar; } + std::wstring Node::as_dispatch(std::wstring*) const + { + return Utility::ConvertToUTF16(m_scalar); + } + int64_t Node::as_dispatch(int64_t*) const { return std::stoll(m_scalar); diff --git a/src/Microsoft.Management.Configuration/ConfigurationSet.cpp b/src/Microsoft.Management.Configuration/ConfigurationSet.cpp index 47900336fb..f502da33fc 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSet.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSet.cpp @@ -3,40 +3,12 @@ #include "pch.h" #include "ConfigurationSet.h" #include "ConfigurationSet.g.cpp" +#include "ConfigurationSetParser.h" -#include +#include namespace winrt::Microsoft::Management::Configuration::implementation { - namespace - { - std::string StreamToString(const Windows::Storage::Streams::IInputStream& stream) - { - uint32_t bufferSize = 1 << 20; - Windows::Storage::Streams::Buffer buffer(bufferSize); - Windows::Storage::Streams::InputStreamOptions readOptions = Windows::Storage::Streams::InputStreamOptions::Partial | Windows::Storage::Streams::InputStreamOptions::ReadAhead; - std::string result; - - for (;;) - { - Windows::Storage::Streams::IBuffer readBuffer = stream.ReadAsync(buffer, bufferSize, readOptions).GetResults(); - - size_t readSize = static_cast(readBuffer.Length()); - if (readSize) - { - static_assert(sizeof(char) == sizeof(*readBuffer.data())); - result.append(reinterpret_cast(readBuffer.data()), readSize); - } - else - { - break; - } - } - - return result; - } - } - ConfigurationSet::ConfigurationSet() { GUID instanceIdentifier; @@ -46,10 +18,20 @@ namespace winrt::Microsoft::Management::Configuration::implementation ConfigurationSet::ConfigurationSet(const Windows::Storage::Streams::IInputStream& stream) : ConfigurationSet() { - std::string input = StreamToString(stream); - AppInstaller::YAML::Node yaml = AppInstaller::YAML::Load(input); + bool throwException = true; + try + { + std::unique_ptr parser = ConfigurationSetParser::Create(stream); + if (parser) + { + m_configurationUnits = winrt::single_threaded_vector(parser->GetConfigurationUnits()); + throwException = false; + } + } + CATCH_LOG(); + THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, throwException); } ConfigurationSet::ConfigurationSet(const guid& instanceIdentifier) : @@ -115,7 +97,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation return clock::time_point{}; } - Windows::Foundation::Collections::IVectorView ConfigurationSet::ConfigurationUnits() + Windows::Foundation::Collections::IVectorView ConfigurationSet::ConfigurationUnits() { return m_configurationUnits.GetView(); } diff --git a/src/Microsoft.Management.Configuration/ConfigurationSet.h b/src/Microsoft.Management.Configuration/ConfigurationSet.h index 4533691ce5..99744a059c 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSet.h +++ b/src/Microsoft.Management.Configuration/ConfigurationSet.h @@ -12,6 +12,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation struct ConfigurationSet : ConfigurationSetT { using WinRT_Self = ::winrt::Microsoft::Management::Configuration::ConfigurationSet; + using ConfigurationUnit = ::winrt::Microsoft::Management::Configuration::ConfigurationUnit; ConfigurationSet(); ConfigurationSet(const Windows::Storage::Streams::IInputStream& stream); diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp new file mode 100644 index 0000000000..a10239bb95 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp @@ -0,0 +1,82 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include + +#include +#include +#include +#include + +#include "ConfigurationSetParser_0_1.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + namespace + { + std::string StreamToString(const Windows::Storage::Streams::IInputStream& stream) + { + uint32_t bufferSize = 1 << 20; + Windows::Storage::Streams::Buffer buffer(bufferSize); + Windows::Storage::Streams::InputStreamOptions readOptions = Windows::Storage::Streams::InputStreamOptions::Partial | Windows::Storage::Streams::InputStreamOptions::ReadAhead; + std::string result; + + for (;;) + { + Windows::Storage::Streams::IBuffer readBuffer = stream.ReadAsync(buffer, bufferSize, readOptions).get(); + + size_t readSize = static_cast(readBuffer.Length()); + if (readSize) + { + static_assert(sizeof(char) == sizeof(*readBuffer.data())); + result.append(reinterpret_cast(readBuffer.data()), readSize); + } + else + { + break; + } + } + + return result; + } + } + + std::unique_ptr ConfigurationSetParser::Create(const Windows::Storage::Streams::IInputStream& stream) + { + return Create(StreamToString(stream)); + } + + std::unique_ptr ConfigurationSetParser::Create(std::string_view input) + { + AppInstaller::YAML::Node document = AppInstaller::YAML::Load(input); + if (!document.IsMap()) + { + AICLI_LOG(Config, Info, << "Invalid YAML"); + return {}; + } + + AppInstaller::YAML::Node& popertiesNode = document[NodeName_Properties]; + if (!popertiesNode.IsMap()) + { + AICLI_LOG(Config, Info, << "Invalid properties"); + return {}; + } + + AppInstaller::YAML::Node& versionNode = popertiesNode[NodeName_ConfigurationVersion]; + if (!versionNode.IsScalar()) + { + AICLI_LOG(Config, Info, << "Invalid configuration version"); + return {}; + } + + AppInstaller::Utility::SemanticVersion schemaVersion(versionNode.as()); + + if (schemaVersion.PartAt(0).Integer == 0 && schemaVersion.PartAt(1).Integer == 1) + { + return std::make_unique(std::move(document)); + } + + AICLI_LOG(Config, Info, << "Unknown configuration version: " << schemaVersion.ToString()); + return {}; + } +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetParser.h b/src/Microsoft.Management.Configuration/ConfigurationSetParser.h new file mode 100644 index 0000000000..0439268da2 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationSetParser.h @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include +#include +#include +#include + +using namespace std::string_view_literals; + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + // Interface for parsing a configuration set stream. + struct ConfigurationSetParser + { + static constexpr std::string_view NodeName_Properties = "properties"sv; + static constexpr std::string_view NodeName_ConfigurationVersion = "configurationVersion"sv; + + // Create a parser from the given stream. + static std::unique_ptr Create(const Windows::Storage::Streams::IInputStream& stream); + + // Create a parser from the given bytes (the encoding is detected). + static std::unique_ptr Create(std::string_view input); + + virtual ~ConfigurationSetParser() noexcept = default; + + ConfigurationSetParser(const ConfigurationSetParser&) = delete; + ConfigurationSetParser& operator=(const ConfigurationSetParser&) = delete; + ConfigurationSetParser(ConfigurationSetParser&&) = default; + ConfigurationSetParser& operator=(ConfigurationSetParser&&) = default; + + // Retrieve the configuration units from the parser. + virtual std::vector GetConfigurationUnits() = 0; + + protected: + ConfigurationSetParser() = default; + }; +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.cpp new file mode 100644 index 0000000000..d8440172d7 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.cpp @@ -0,0 +1,176 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ConfigurationSetParser_0_1.h" + +#include +#include + +#include + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + namespace + { + using namespace AppInstaller::YAML; + + void GetStringValueForUnit(const Node& item, std::string_view valueName, bool required, ConfigurationUnit* unit, void(ConfigurationUnit::* propertyFunction)(const hstring& value)) + { + const Node& valueNode = item[valueName]; + + if (valueNode) + { + THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, !valueNode.IsScalar()); + } + else + { + THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, required); + return; + } + + (unit->*propertyFunction)(hstring{ valueNode.as() }); + } + + void GetStringArrayForUnit(const Node& item, std::string_view arrayName, ConfigurationUnit* unit, void(ConfigurationUnit::* propertyFunction)(std::vector&& value)) + { + const Node& arrayNode = item[arrayName]; + + if (!arrayNode) + { + return; + } + + THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, !arrayNode.IsSequence()); + + std::vector arrayValue; + + for (const Node& arrayItem : arrayNode.Sequence()) + { + THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, !arrayItem.IsScalar()); + arrayValue.emplace_back(arrayItem.as()); + } + + (unit->*propertyFunction)(std::move(arrayValue)); + } + + Windows::Foundation::IInspectable GetIInspectableFromNode(const Node& node); + + // Returns the appropriate IPropertyValue for the given node, which is assumed to be a scalar. + Windows::Foundation::IInspectable GetPropertyValueFromScalar(const Node& node) + { + // TODO: Use the tag to determine the type of property to create. + return Windows::Foundation::PropertyValue::CreateString(node.as()); + } + + // Returns the appropriate IPropertyValue for the given node, which is assumed to be a scalar. + Windows::Foundation::IInspectable GetPropertyValueFromSequence(const Node& sequenceNode) + { + Windows::Foundation::Collections::ValueSet result; + size_t index = 0; + + for (const Node& sequenceItem : sequenceNode.Sequence()) + { + std::wostringstream strstr; + strstr << index++; + result.Insert(strstr.str(), GetIInspectableFromNode(sequenceItem)); + } + + result.Insert(L"treatAsArray", Windows::Foundation::PropertyValue::CreateBoolean(true)); + return result; + } + + // Fills the ValueSet from the given node, which is assumed to be a map. + void FillValueSetFromMap(const Node& mapNode, const Windows::Foundation::Collections::ValueSet& valueSet) + { + for (const auto& mapItem : mapNode.Mapping()) + { + // Insert returns true if it replaces an existing key, and that indicates an invalid map. + THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, valueSet.Insert(mapItem.first.as(), GetIInspectableFromNode(mapItem.second))); + } + } + + // Returns the appropriate IInspectable for the given node. + Windows::Foundation::IInspectable GetIInspectableFromNode(const Node& node) + { + ::winrt::Windows::Foundation::IInspectable result; + + switch (node.GetType()) + { + case Node::Type::Invalid: + case Node::Type::None: + // Leave value as null + break; + case Node::Type::Scalar: + result = GetPropertyValueFromScalar(node); + break; + case Node::Type::Sequence: + result = GetPropertyValueFromSequence(node); + break; + case Node::Type::Mapping: + { + Windows::Foundation::Collections::ValueSet subset; + FillValueSetFromMap(node, subset); + result = std::move(subset); + } + break; + default: + THROW_HR(E_UNEXPECTED); + } + + return result; + } + + void GetValueSet(const Node& mapNode, bool required, const Windows::Foundation::Collections::ValueSet& valueSet) + { + if (mapNode) + { + THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, !mapNode.IsMap()); + } + else + { + THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, required); + return; + } + + FillValueSetFromMap(mapNode, valueSet); + } + + void ParseConfigurationUnitsFromSubsection(const Node& document, std::string_view subsection, ConfigurationUnitIntent intent, std::vector& result) + { + Node subsectionNode = document[subsection]; + + if (!subsectionNode.IsDefined()) + { + return; + } + + THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, !subsectionNode.IsSequence()); + + for (const Node& item : subsectionNode.Sequence()) + { + THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, !item.IsMap()); + + auto configurationUnit = make_self>(); + + GetStringValueForUnit(item, "resource", true, configurationUnit.get(), &ConfigurationUnit::UnitName); + GetStringValueForUnit(item, "id", false, configurationUnit.get(), &ConfigurationUnit::Identifier); + configurationUnit->Intent(intent); + GetStringArrayForUnit(item, "dependsOn", configurationUnit.get(), &ConfigurationUnit::Dependencies); + GetValueSet(item["directives"], false, configurationUnit->Directives()); + GetValueSet(item["settings"], false, configurationUnit->Settings()); + + result.emplace_back(*configurationUnit); + } + } + } + + std::vector ConfigurationSetParser_0_1::GetConfigurationUnits() + { + std::vector result; + const Node& properties = m_document[NodeName_Properties]; + ParseConfigurationUnitsFromSubsection(properties, "assertions", ConfigurationUnitIntent::Assert, result); + ParseConfigurationUnitsFromSubsection(properties, "parameters", ConfigurationUnitIntent::Inform, result); + ParseConfigurationUnitsFromSubsection(properties, "resources", ConfigurationUnitIntent::Apply, result); + return result; + } +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.h b/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.h new file mode 100644 index 0000000000..169bd5a316 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.h @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ConfigurationSetParser.h" + +#include + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + // Interface for parsing a configuration set stream. + struct ConfigurationSetParser_0_1 : public ConfigurationSetParser + { + ConfigurationSetParser_0_1(AppInstaller::YAML::Node&& document) : m_document(std::move(document)) {} + + virtual ~ConfigurationSetParser_0_1() noexcept = default; + + ConfigurationSetParser_0_1(const ConfigurationSetParser_0_1&) = delete; + ConfigurationSetParser_0_1& operator=(const ConfigurationSetParser_0_1&) = delete; + ConfigurationSetParser_0_1(ConfigurationSetParser_0_1&&) = default; + ConfigurationSetParser_0_1& operator=(ConfigurationSetParser_0_1&&) = default; + + // Retrieve the configuration units from the parser. + std::vector GetConfigurationUnits() override; + + protected: + AppInstaller::YAML::Node m_document; + }; +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp b/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp index 0b991f5c15..e9c2dab7bc 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp @@ -70,6 +70,11 @@ namespace winrt::Microsoft::Management::Configuration::implementation m_dependencies = winrt::single_threaded_vector(std::move(temp)); } + void ConfigurationUnit::Dependencies(std::vector&& value) + { + m_dependencies = winrt::single_threaded_vector(std::move(value)); + } + Windows::Foundation::Collections::ValueSet ConfigurationUnit::Directives() { return m_directives; diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnit.h b/src/Microsoft.Management.Configuration/ConfigurationUnit.h index 20c8ab0eed..0ba1f7f018 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationUnit.h +++ b/src/Microsoft.Management.Configuration/ConfigurationUnit.h @@ -4,6 +4,7 @@ #include "ConfigurationUnit.g.h" #include "MutableFlag.h" #include +#include namespace winrt::Microsoft::Management::Configuration::implementation { @@ -13,6 +14,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) ConfigurationUnit(const guid& instanceIdentifier); + void Dependencies(std::vector&& value); #endif hstring UnitName(); diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj index baf38c6c7f..347179b809 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -101,7 +101,7 @@ true _WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) - $(ProjectDir)..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerSharedLib\Public;%(AdditionalIncludeDirectories) Console @@ -135,6 +135,8 @@ + + @@ -153,6 +155,8 @@ + + diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters index 4d944b5654..0daec38b5f 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters @@ -48,6 +48,12 @@ API Source + + Parser + + + Parser + @@ -96,6 +102,12 @@ API Headers + + Parser + + + Parser + @@ -115,5 +127,8 @@ {c5f2f74e-de80-4235-abbd-bacd6771eaf2} + + {b31f8336-b4d8-4c05-b08d-6b82c550a30b} + \ No newline at end of file diff --git a/src/Microsoft.Management.Configuration/pch.h b/src/Microsoft.Management.Configuration/pch.h index f3fa3208c6..c827de4ea8 100644 --- a/src/Microsoft.Management.Configuration/pch.h +++ b/src/Microsoft.Management.Configuration/pch.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include From 2de91fef286f131e99cbad529e4ac7af00912dd7 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Fri, 20 Jan 2023 14:46:51 -0800 Subject: [PATCH 11/31] Add additional processor interface, move stream loading to enable diagnostics --- .../Public/AppInstallerErrors.h | 3 + .../ConfigurationProcessor.cpp | 43 ++++- .../ConfigurationProcessor.h | 6 + .../ConfigurationSet.cpp | 24 +-- .../ConfigurationSet.h | 4 +- .../ConfigurationSetParser.cpp | 25 ++- .../ConfigurationSetParser.h | 13 ++ .../ConfigurationSetParserError.h | 19 ++ .../ConfigurationSetParser_0_1.cpp | 180 ++++++++++-------- .../ConfigurationSetParser_0_1.h | 7 +- .../Microsoft.Management.Configuration.idl | 32 +++- ...Microsoft.Management.Configuration.vcxproj | 3 + ...t.Management.Configuration.vcxproj.filters | 9 + .../OpenConfigurationSetResult.cpp | 34 ++++ .../OpenConfigurationSetResult.h | 29 +++ 15 files changed, 322 insertions(+), 109 deletions(-) create mode 100644 src/Microsoft.Management.Configuration/ConfigurationSetParserError.h create mode 100644 src/Microsoft.Management.Configuration/OpenConfigurationSetResult.cpp create mode 100644 src/Microsoft.Management.Configuration/OpenConfigurationSetResult.h diff --git a/src/AppInstallerSharedLib/Public/AppInstallerErrors.h b/src/AppInstallerSharedLib/Public/AppInstallerErrors.h index 6f03f374ca..c2cfb201aa 100644 --- a/src/AppInstallerSharedLib/Public/AppInstallerErrors.h +++ b/src/AppInstallerSharedLib/Public/AppInstallerErrors.h @@ -150,6 +150,9 @@ // Configuration Errors #define WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE ((HRESULT)0x8A15C001) +#define WINGET_CONFIG_ERROR_INVALID_YAML ((HRESULT)0x8A15C002) +#define WINGET_CONFIG_ERROR_INVALID_FIELD ((HRESULT)0x8A15C003) +#define WINGET_CONFIG_ERROR_UKNOWN_CONFIGURATION_FILE_VERSION ((HRESULT)0x8A15C004) namespace AppInstaller diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp index 766093f98f..19713626d6 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp @@ -3,6 +3,11 @@ #include "pch.h" #include "ConfigurationProcessor.h" #include "ConfigurationProcessor.g.cpp" +#include "ConfigurationSet.h" +#include "OpenConfigurationSetResult.h" +#include "ConfigurationSetParser.h" + +#include namespace winrt::Microsoft::Management::Configuration::implementation { @@ -35,11 +40,47 @@ namespace winrt::Microsoft::Management::Configuration::implementation m_configurationChange.remove(token); } - Windows::Foundation::Collections::IVector ConfigurationProcessor::GetConfigurationHistory() + Windows::Foundation::Collections::IVector ConfigurationProcessor::GetConfigurationHistory() { THROW_HR(E_NOTIMPL); } + Configuration::OpenConfigurationSetResult ConfigurationProcessor::OpenConfigurationSet(Windows::Storage::Streams::IInputStream stream) + { + auto result = make_self>(); + + try + { + std::unique_ptr parser = ConfigurationSetParser::Create(stream); + if (FAILED(parser->Result())) + { + result->Initialize(parser->Result(), parser->Field()); + return *result; + } + + auto configurationSet = make_self>(); + configurationSet->Initialize(parser->GetConfigurationUnits()); + if (FAILED(parser->Result())) + { + result->Initialize(parser->Result(), parser->Field()); + return *result; + } + + result->Initialize(*configurationSet); + } + catch(const wil::ResultException& resultException) + { + result->Initialize(resultException.GetErrorCode()); + } + catch (...) + { + result->Initialize(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE); + LOG_CAUGHT_EXCEPTION(); + } + + return *result; + } + Windows::Foundation::IAsyncOperation> ConfigurationProcessor::CheckForConflictsAsync( const Windows::Foundation::Collections::IVectorView& configurationSets, bool includeConfigurationHistory) diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.h b/src/Microsoft.Management.Configuration/ConfigurationProcessor.h index 09d600f8ca..66078ee396 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationProcessor.h +++ b/src/Microsoft.Management.Configuration/ConfigurationProcessor.h @@ -4,11 +4,15 @@ #include "ConfigurationProcessor.g.h" #include #include +#include namespace winrt::Microsoft::Management::Configuration::implementation { struct ConfigurationProcessor : ConfigurationProcessorT { + using ConfigurationSet = Configuration::ConfigurationSet; + using ConfigurationUnit = Configuration::ConfigurationUnit; + ConfigurationProcessor(const IConfigurationProcessorFactory& factory); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) @@ -23,6 +27,8 @@ namespace winrt::Microsoft::Management::Configuration::implementation Windows::Foundation::Collections::IVector GetConfigurationHistory(); + Configuration::OpenConfigurationSetResult OpenConfigurationSet(Windows::Storage::Streams::IInputStream stream); + Windows::Foundation::IAsyncOperation> CheckForConflictsAsync( const Windows::Foundation::Collections::IVectorView& configurationSets, bool includeConfigurationHistory); diff --git a/src/Microsoft.Management.Configuration/ConfigurationSet.cpp b/src/Microsoft.Management.Configuration/ConfigurationSet.cpp index f502da33fc..fc2f52153b 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSet.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSet.cpp @@ -3,9 +3,6 @@ #include "pch.h" #include "ConfigurationSet.h" #include "ConfigurationSet.g.cpp" -#include "ConfigurationSetParser.h" - -#include namespace winrt::Microsoft::Management::Configuration::implementation { @@ -16,27 +13,14 @@ namespace winrt::Microsoft::Management::Configuration::implementation m_instanceIdentifier = instanceIdentifier; } - ConfigurationSet::ConfigurationSet(const Windows::Storage::Streams::IInputStream& stream) : ConfigurationSet() + ConfigurationSet::ConfigurationSet(const guid& instanceIdentifier) : + m_instanceIdentifier(instanceIdentifier), m_mutableFlag(false) { - bool throwException = true; - - try - { - std::unique_ptr parser = ConfigurationSetParser::Create(stream); - if (parser) - { - m_configurationUnits = winrt::single_threaded_vector(parser->GetConfigurationUnits()); - throwException = false; - } - } - CATCH_LOG(); - - THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, throwException); } - ConfigurationSet::ConfigurationSet(const guid& instanceIdentifier) : - m_instanceIdentifier(instanceIdentifier), m_mutableFlag(false) + void ConfigurationSet::Initialize(std::vector&& units) { + m_configurationUnits = winrt::single_threaded_vector(std::move(units)); } hstring ConfigurationSet::Name() diff --git a/src/Microsoft.Management.Configuration/ConfigurationSet.h b/src/Microsoft.Management.Configuration/ConfigurationSet.h index 99744a059c..f7940a68ca 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSet.h +++ b/src/Microsoft.Management.Configuration/ConfigurationSet.h @@ -5,7 +5,7 @@ #include "MutableFlag.h" #include #include -#include +#include namespace winrt::Microsoft::Management::Configuration::implementation { @@ -15,10 +15,10 @@ namespace winrt::Microsoft::Management::Configuration::implementation using ConfigurationUnit = ::winrt::Microsoft::Management::Configuration::ConfigurationUnit; ConfigurationSet(); - ConfigurationSet(const Windows::Storage::Streams::IInputStream& stream); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) ConfigurationSet(const guid& instanceIdentifier); + void Initialize(std::vector&& units); #endif hstring Name(); diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp index a10239bb95..ce244a346b 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp @@ -5,9 +5,11 @@ #include #include +#include #include #include +#include "ConfigurationSetParserError.h" #include "ConfigurationSetParser_0_1.h" namespace winrt::Microsoft::Management::Configuration::implementation @@ -48,25 +50,32 @@ namespace winrt::Microsoft::Management::Configuration::implementation std::unique_ptr ConfigurationSetParser::Create(std::string_view input) { - AppInstaller::YAML::Node document = AppInstaller::YAML::Load(input); + AppInstaller::YAML::Node document; + + try + { + document = AppInstaller::YAML::Load(input); + } + CATCH_LOG(); + if (!document.IsMap()) { AICLI_LOG(Config, Info, << "Invalid YAML"); - return {}; + return std::make_unique(WINGET_CONFIG_ERROR_INVALID_YAML); } AppInstaller::YAML::Node& popertiesNode = document[NodeName_Properties]; if (!popertiesNode.IsMap()) { AICLI_LOG(Config, Info, << "Invalid properties"); - return {}; + return std::make_unique(WINGET_CONFIG_ERROR_INVALID_FIELD, NodeName_Properties); } AppInstaller::YAML::Node& versionNode = popertiesNode[NodeName_ConfigurationVersion]; if (!versionNode.IsScalar()) { AICLI_LOG(Config, Info, << "Invalid configuration version"); - return {}; + return std::make_unique(WINGET_CONFIG_ERROR_INVALID_FIELD, NodeName_ConfigurationVersion); } AppInstaller::Utility::SemanticVersion schemaVersion(versionNode.as()); @@ -77,6 +86,12 @@ namespace winrt::Microsoft::Management::Configuration::implementation } AICLI_LOG(Config, Info, << "Unknown configuration version: " << schemaVersion.ToString()); - return {}; + return std::make_unique(WINGET_CONFIG_ERROR_UKNOWN_CONFIGURATION_FILE_VERSION); + } + + void ConfigurationSetParser::SetError(hresult result, std::string_view field) + { + m_result = result; + m_field = AppInstaller::Utility::ConvertToUTF16(field); } } diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetParser.h b/src/Microsoft.Management.Configuration/ConfigurationSetParser.h index 0439268da2..1bc2229942 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetParser.h +++ b/src/Microsoft.Management.Configuration/ConfigurationSetParser.h @@ -4,6 +4,7 @@ #include #include #include +#include #include using namespace std::string_view_literals; @@ -32,7 +33,19 @@ namespace winrt::Microsoft::Management::Configuration::implementation // Retrieve the configuration units from the parser. virtual std::vector GetConfigurationUnits() = 0; + // The latest result code from the parser. + hresult Result() const { return m_result; } + + // The field related to the result code. + hstring Field() const { return m_field; } + protected: ConfigurationSetParser() = default; + + // Set the error state + void SetError(hresult result, std::string_view field = {}); + + hresult m_result; + hstring m_field; }; } diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetParserError.h b/src/Microsoft.Management.Configuration/ConfigurationSetParserError.h new file mode 100644 index 0000000000..20c6b37272 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationSetParserError.h @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ConfigurationSetParser.h" +#include + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + // Parser object that only indicates an error occurred. + struct ConfigurationSetParserError : public ConfigurationSetParser + { + ConfigurationSetParserError(hresult result, std::string_view field = {}) + { + SetError(result, field); + } + + std::vector GetConfigurationUnits() override { return {}; } + }; +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.cpp index d8440172d7..4769eac779 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.cpp @@ -10,49 +10,14 @@ namespace winrt::Microsoft::Management::Configuration::implementation { - namespace - { - using namespace AppInstaller::YAML; - - void GetStringValueForUnit(const Node& item, std::string_view valueName, bool required, ConfigurationUnit* unit, void(ConfigurationUnit::* propertyFunction)(const hstring& value)) - { - const Node& valueNode = item[valueName]; - - if (valueNode) - { - THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, !valueNode.IsScalar()); - } - else - { - THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, required); - return; - } - - (unit->*propertyFunction)(hstring{ valueNode.as() }); - } - - void GetStringArrayForUnit(const Node& item, std::string_view arrayName, ConfigurationUnit* unit, void(ConfigurationUnit::* propertyFunction)(std::vector&& value)) - { - const Node& arrayNode = item[arrayName]; - - if (!arrayNode) - { - return; - } - - THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, !arrayNode.IsSequence()); - - std::vector arrayValue; - - for (const Node& arrayItem : arrayNode.Sequence()) - { - THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, !arrayItem.IsScalar()); - arrayValue.emplace_back(arrayItem.as()); - } + using namespace AppInstaller::YAML; - (unit->*propertyFunction)(std::move(arrayValue)); - } +#define CHECK_ERROR(_op_) (_op_); if (FAILED(m_result)) { return; } +#define FIELD_ERROR(_field_) SetError(WINGET_CONFIG_ERROR_INVALID_FIELD, (_field_)); return +#define FIELD_ERROR_IF(_condition_,_field_) if (_condition_) { FIELD_ERROR(_field_); } + namespace + { Windows::Foundation::IInspectable GetIInspectableFromNode(const Node& node); // Returns the appropriate IPropertyValue for the given node, which is assumed to be a scalar. @@ -119,58 +84,123 @@ namespace winrt::Microsoft::Management::Configuration::implementation return result; } + } + + std::vector ConfigurationSetParser_0_1::GetConfigurationUnits() + { + std::vector result; + const Node& properties = m_document[NodeName_Properties]; + ParseConfigurationUnitsFromSubsection(properties, "assertions", ConfigurationUnitIntent::Assert, result); + ParseConfigurationUnitsFromSubsection(properties, "parameters", ConfigurationUnitIntent::Inform, result); + ParseConfigurationUnitsFromSubsection(properties, "resources", ConfigurationUnitIntent::Apply, result); + return result; + } - void GetValueSet(const Node& mapNode, bool required, const Windows::Foundation::Collections::ValueSet& valueSet) + void ConfigurationSetParser_0_1::ParseConfigurationUnitsFromSubsection(const Node& document, std::string_view subsection, ConfigurationUnitIntent intent, std::vector& result) + { + if (FAILED(m_result)) { - if (mapNode) - { - THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, !mapNode.IsMap()); - } - else + return; + } + + Node subsectionNode = document[subsection]; + + if (!subsectionNode.IsDefined()) + { + return; + } + + FIELD_ERROR_IF(!subsectionNode.IsSequence(), subsection); + + std::ostringstream strstr; + strstr << subsection; + size_t index = 0; + + for (const Node& item : subsectionNode.Sequence()) + { + if (!item.IsMap()) { - THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, required); - return; + strstr << '[' << index << ']'; + FIELD_ERROR(strstr.str()); } + index++; + + auto configurationUnit = make_self>(); - FillValueSetFromMap(mapNode, valueSet); + CHECK_ERROR(GetStringValueForUnit(item, "resource", true, configurationUnit.get(), &ConfigurationUnit::UnitName)); + CHECK_ERROR(GetStringValueForUnit(item, "id", false, configurationUnit.get(), &ConfigurationUnit::Identifier)); + configurationUnit->Intent(intent); + CHECK_ERROR(GetStringArrayForUnit(item, "dependsOn", configurationUnit.get(), &ConfigurationUnit::Dependencies)); + CHECK_ERROR(GetValueSet(item, "directives", false, configurationUnit->Directives())); + CHECK_ERROR(GetValueSet(item, "settings", false, configurationUnit->Settings())); + + result.emplace_back(*configurationUnit); } + } - void ParseConfigurationUnitsFromSubsection(const Node& document, std::string_view subsection, ConfigurationUnitIntent intent, std::vector& result) + void ConfigurationSetParser_0_1::GetStringValueForUnit(const Node& item, std::string_view valueName, bool required, ConfigurationUnit* unit, void(ConfigurationUnit::* propertyFunction)(const hstring& value)) + { + const Node& valueNode = item[valueName]; + + if (valueNode) { - Node subsectionNode = document[subsection]; + FIELD_ERROR_IF(!valueNode.IsScalar(), valueName); + } + else + { + FIELD_ERROR_IF(required, valueName); + return; + } - if (!subsectionNode.IsDefined()) - { - return; - } + (unit->*propertyFunction)(hstring{ valueNode.as() }); + } - THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, !subsectionNode.IsSequence()); + void ConfigurationSetParser_0_1::GetStringArrayForUnit(const Node& item, std::string_view arrayName, ConfigurationUnit* unit, void(ConfigurationUnit::* propertyFunction)(std::vector&& value)) + { + const Node& arrayNode = item[arrayName]; - for (const Node& item : subsectionNode.Sequence()) - { - THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, !item.IsMap()); + if (!arrayNode) + { + return; + } + + FIELD_ERROR_IF(!arrayNode.IsSequence(), arrayName); - auto configurationUnit = make_self>(); + std::vector arrayValue; - GetStringValueForUnit(item, "resource", true, configurationUnit.get(), &ConfigurationUnit::UnitName); - GetStringValueForUnit(item, "id", false, configurationUnit.get(), &ConfigurationUnit::Identifier); - configurationUnit->Intent(intent); - GetStringArrayForUnit(item, "dependsOn", configurationUnit.get(), &ConfigurationUnit::Dependencies); - GetValueSet(item["directives"], false, configurationUnit->Directives()); - GetValueSet(item["settings"], false, configurationUnit->Settings()); + std::ostringstream strstr; + strstr << arrayName; + size_t index = 0; - result.emplace_back(*configurationUnit); + for (const Node& arrayItem : arrayNode.Sequence()) + { + if (!arrayItem.IsScalar()) + { + strstr << '[' << index << ']'; + FIELD_ERROR(strstr.str()); } + index++; + + arrayValue.emplace_back(arrayItem.as()); } + + (unit->*propertyFunction)(std::move(arrayValue)); } - std::vector ConfigurationSetParser_0_1::GetConfigurationUnits() + void ConfigurationSetParser_0_1::GetValueSet(const Node& item, std::string_view mapName, bool required, const Windows::Foundation::Collections::ValueSet& valueSet) { - std::vector result; - const Node& properties = m_document[NodeName_Properties]; - ParseConfigurationUnitsFromSubsection(properties, "assertions", ConfigurationUnitIntent::Assert, result); - ParseConfigurationUnitsFromSubsection(properties, "parameters", ConfigurationUnitIntent::Inform, result); - ParseConfigurationUnitsFromSubsection(properties, "resources", ConfigurationUnitIntent::Apply, result); - return result; + const Node& mapNode = item[mapName]; + + if (mapNode) + { + FIELD_ERROR_IF(!mapNode.IsMap(), mapName); + } + else + { + FIELD_ERROR_IF(required, mapName); + return; + } + + FillValueSetFromMap(mapNode, valueSet); } } diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.h b/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.h index 169bd5a316..4870272b3f 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.h +++ b/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.h @@ -7,7 +7,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation { - // Interface for parsing a configuration set stream. + // Parser for schema version 0.1 struct ConfigurationSetParser_0_1 : public ConfigurationSetParser { ConfigurationSetParser_0_1(AppInstaller::YAML::Node&& document) : m_document(std::move(document)) {} @@ -23,6 +23,11 @@ namespace winrt::Microsoft::Management::Configuration::implementation std::vector GetConfigurationUnits() override; protected: + void ParseConfigurationUnitsFromSubsection(const AppInstaller::YAML::Node& document, std::string_view subsection, ConfigurationUnitIntent intent, std::vector& result); + void GetStringValueForUnit(const AppInstaller::YAML::Node& item, std::string_view valueName, bool required, ConfigurationUnit* unit, void(ConfigurationUnit::* propertyFunction)(const hstring& value)); + void GetStringArrayForUnit(const AppInstaller::YAML::Node& item, std::string_view arrayName, ConfigurationUnit* unit, void(ConfigurationUnit::* propertyFunction)(std::vector&& value)); + void GetValueSet(const AppInstaller::YAML::Node& item, std::string_view mapName, bool required, const Windows::Foundation::Collections::ValueSet& valueSet); + AppInstaller::YAML::Node m_document; }; } diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl index f52725b762..0880e36c92 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -215,9 +215,6 @@ namespace Microsoft.Management.Configuration { // Creates an empty, mutable configuration set for authoring purposes. ConfigurationSet(); - - // Loads a mutable configuration set from the given stream. - ConfigurationSet(Windows.Storage.Streams.IInputStream stream); // The name of the set; if from a file this could be the file name. // Can be changed if a mutable set. @@ -277,9 +274,9 @@ namespace Microsoft.Management.Configuration void ApplySettings(); } - // Allows different runtimes to provide specialized handling of configuration processing. + // Controls the lifetime of operations for a single configuration set. [contract(Microsoft.Management.Configuration.Contract, 1)] - interface IConfigurationProcessorFactory + interface IConfigurationSetProcessor { // Gets the configuration unit processor details for the given unit. IConfigurationUnitProcessorDetails GetUnitProcessorDetails(ConfigurationUnit unit, ConfigurationUnitDetailLevel detailLevel); @@ -290,6 +287,14 @@ namespace Microsoft.Management.Configuration IConfigurationUnitProcessor CreateUnitProcessor(ConfigurationUnit unit, Windows.Foundation.Collections.IMapView directivesOverlay); } + // Allows different runtimes to provide specialized handling of configuration processing. + [contract(Microsoft.Management.Configuration.Contract, 1)] + interface IConfigurationProcessorFactory + { + // Creates a configuration set processor for the given set. + IConfigurationSetProcessor CreateSetProcessor(ConfigurationSet configurationSet); + } + // The level of the diagnostic information. [contract(Microsoft.Management.Configuration.Contract, 1)] enum DiagnosticLevel @@ -336,6 +341,20 @@ namespace Microsoft.Management.Configuration ConfigurationSetState State{ get; }; } + // The result of calling OpenConfigurationSet, containing either the set or details about the failure. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass OpenConfigurationSetResult + { + // The configuration set if successful; null otherwise. + ConfigurationSet Set{ get; }; + + // The result from opening the set. + HRESULT ResultCode{ get; }; + + // The field that is missing/invalid, if appropriate for the specific ResultCode. + String Field{ get; }; + } + // The type of conflict between configuration sets that was detected. [contract(Microsoft.Management.Configuration.Contract, 1)] enum ConfigurationConflictType @@ -477,6 +496,9 @@ namespace Microsoft.Management.Configuration // These configuration sets will be marked as immutable. Windows.Foundation.Collections.IVector GetConfigurationHistory(); + // Loads a mutable configuration set from the given stream. + OpenConfigurationSetResult OpenConfigurationSet(Windows.Storage.Streams.IInputStream stream); + // Checks for conflicts amongst the configuration sets provided, optionally including the configuration sets already applied to the system. Windows.Foundation.IAsyncOperation< Windows.Foundation.Collections.IVectorView > CheckForConflictsAsync(Windows.Foundation.Collections.IVectorView configurationSets, Boolean includeConfigurationHistory); diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj index 347179b809..326da818cd 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -136,12 +136,14 @@ + + @@ -162,6 +164,7 @@ + Create diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters index 0daec38b5f..f0e7ca32d5 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters @@ -54,6 +54,9 @@ Parser + + API Source + @@ -108,6 +111,12 @@ Parser + + API Headers + + + Parser + diff --git a/src/Microsoft.Management.Configuration/OpenConfigurationSetResult.cpp b/src/Microsoft.Management.Configuration/OpenConfigurationSetResult.cpp new file mode 100644 index 0000000000..1b58013609 --- /dev/null +++ b/src/Microsoft.Management.Configuration/OpenConfigurationSetResult.cpp @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "OpenConfigurationSetResult.h" +#include "OpenConfigurationSetResult.g.cpp" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + void OpenConfigurationSetResult::Initialize(Configuration::ConfigurationSet configurationSet) + { + m_set = std::move(configurationSet); + } + + void OpenConfigurationSetResult::Initialize(hresult resultCode, hstring field) + { + m_resultCode = resultCode; + m_field = field; + } + + Configuration::ConfigurationSet OpenConfigurationSetResult::Set() + { + return m_set; + } + + hresult OpenConfigurationSetResult::ResultCode() + { + return m_resultCode; + } + + hstring OpenConfigurationSetResult::Field() + { + return m_field; + } +} diff --git a/src/Microsoft.Management.Configuration/OpenConfigurationSetResult.h b/src/Microsoft.Management.Configuration/OpenConfigurationSetResult.h new file mode 100644 index 0000000000..bfaa8b487a --- /dev/null +++ b/src/Microsoft.Management.Configuration/OpenConfigurationSetResult.h @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "OpenConfigurationSetResult.g.h" +#include "ConfigurationSet.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct OpenConfigurationSetResult : OpenConfigurationSetResultT + { + OpenConfigurationSetResult() = default; + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void Initialize(Configuration::ConfigurationSet configurationSet); + void Initialize(hresult resultCode, hstring field = {}); +#endif + + Configuration::ConfigurationSet Set(); + hresult ResultCode(); + hstring Field(); + +#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + private: + Configuration::ConfigurationSet m_set = nullptr; + hresult m_resultCode; + hstring m_field; +#endif + }; +} From a8e26fa4885f6a0ad92bf77f63f804b055eae649 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Tue, 24 Jan 2023 17:44:56 -0800 Subject: [PATCH 12/31] Basic actions building but untested --- .../Public/AppInstallerErrors.h | 7 +- .../Public/winget/SharedThreadGlobals.h | 2 +- .../ApplyConfigurationSetResult.cpp | 24 +- .../ApplyConfigurationSetResult.h | 2 + .../ApplyConfigurationUnitResult.h | 3 + .../ConfigThreadGlobals.cpp | 17 + .../ConfigThreadGlobals.h | 21 ++ .../ConfigurationProcessor.cpp | 242 +++++++++++-- .../ConfigurationProcessor.h | 33 +- .../ConfigurationSetApplyProcessor.cpp | 340 ++++++++++++++++++ .../ConfigurationSetApplyProcessor.h | 92 +++++ .../ConfigurationSetParser.cpp | 2 +- .../ConfigurationSetParser_0_1.cpp | 1 + .../ConfigurationUnit.cpp | 5 + .../ConfigurationUnit.h | 4 +- .../ConfigurationUnitResultInformation.cpp | 11 + .../ConfigurationUnitResultInformation.h | 2 + .../ExceptionResultHelpers.h | 24 ++ .../GetConfigurationUnitSettingsResult.cpp | 27 +- .../GetConfigurationUnitSettingsResult.h | 5 +- .../Microsoft.Management.Configuration.idl | 7 + ...Microsoft.Management.Configuration.vcxproj | 5 + ...t.Management.Configuration.vcxproj.filters | 15 + .../TestConfigurationSetResult.cpp | 31 +- .../TestConfigurationSetResult.h | 5 +- .../TestConfigurationUnitResult.cpp | 8 +- .../TestConfigurationUnitResult.h | 6 +- 27 files changed, 871 insertions(+), 70 deletions(-) create mode 100644 src/Microsoft.Management.Configuration/ConfigThreadGlobals.cpp create mode 100644 src/Microsoft.Management.Configuration/ConfigThreadGlobals.h create mode 100644 src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp create mode 100644 src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h create mode 100644 src/Microsoft.Management.Configuration/ExceptionResultHelpers.h diff --git a/src/AppInstallerSharedLib/Public/AppInstallerErrors.h b/src/AppInstallerSharedLib/Public/AppInstallerErrors.h index c2cfb201aa..f149049b8a 100644 --- a/src/AppInstallerSharedLib/Public/AppInstallerErrors.h +++ b/src/AppInstallerSharedLib/Public/AppInstallerErrors.h @@ -152,7 +152,12 @@ #define WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE ((HRESULT)0x8A15C001) #define WINGET_CONFIG_ERROR_INVALID_YAML ((HRESULT)0x8A15C002) #define WINGET_CONFIG_ERROR_INVALID_FIELD ((HRESULT)0x8A15C003) -#define WINGET_CONFIG_ERROR_UKNOWN_CONFIGURATION_FILE_VERSION ((HRESULT)0x8A15C004) +#define WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION ((HRESULT)0x8A15C004) +#define WINGET_CONFIG_ERROR_SET_APPLY_FAILED ((HRESULT)0x8A15C005) +#define WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER ((HRESULT)0x8A15C006) +#define WINGET_CONFIG_ERROR_MISSING_DEPENDENCY ((HRESULT)0x8A15C007) +#define WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED ((HRESULT)0x8A15C008) +#define WINGET_CONFIG_ERROR_ASSERTION_FAILED ((HRESULT)0x8A15C009) namespace AppInstaller diff --git a/src/AppInstallerSharedLib/Public/winget/SharedThreadGlobals.h b/src/AppInstallerSharedLib/Public/winget/SharedThreadGlobals.h index ffa22f77a6..812568b700 100644 --- a/src/AppInstallerSharedLib/Public/winget/SharedThreadGlobals.h +++ b/src/AppInstallerSharedLib/Public/winget/SharedThreadGlobals.h @@ -30,7 +30,7 @@ namespace AppInstaller::ThreadLocalStorage static ThreadGlobals* GetForCurrentThread(); }; - // RAII object used to + // RAII object used to enable reverting back to the previous thread globals object. struct PreviousThreadGlobals { ~PreviousThreadGlobals(); diff --git a/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.cpp b/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.cpp index e49fb0c502..1708c9a538 100644 --- a/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.cpp +++ b/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.cpp @@ -6,19 +6,19 @@ namespace winrt::Microsoft::Management::Configuration::implementation { - void ApplyConfigurationSetResult::Initialize(std::vector&& unitResults, hresult resultCode) - { - m_unitResults = winrt::single_threaded_vector(std::move(unitResults)); - m_resultCode = resultCode; - } + void ApplyConfigurationSetResult::Initialize(std::vector&& unitResults, hresult resultCode) + { + m_unitResults = single_threaded_vector(std::move(unitResults)); + m_resultCode = resultCode; + } - Windows::Foundation::Collections::IVectorView ApplyConfigurationSetResult::UnitResults() - { - return m_unitResults.GetView(); - } + Windows::Foundation::Collections::IVectorView ApplyConfigurationSetResult::UnitResults() + { + return m_unitResults.GetView(); + } - hresult ApplyConfigurationSetResult::ResultCode() - { - return m_resultCode; + hresult ApplyConfigurationSetResult::ResultCode() + { + return m_resultCode; } } diff --git a/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.h b/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.h index 8c5ab7142c..9ae4af5421 100644 --- a/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.h +++ b/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.h @@ -8,6 +8,8 @@ namespace winrt::Microsoft::Management::Configuration::implementation { struct ApplyConfigurationSetResult : ApplyConfigurationSetResultT { + using ApplyConfigurationUnitResult = Configuration::ApplyConfigurationUnitResult; + ApplyConfigurationSetResult() = default; #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) diff --git a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h index 52c5f30d76..509c8301b3 100644 --- a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h +++ b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h @@ -7,6 +7,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation { struct ApplyConfigurationUnitResult : ApplyConfigurationUnitResultT { + using ConfigurationUnit = Configuration::ConfigurationUnit; + using ConfigurationUnitResultInformation = Configuration::ConfigurationUnitResultInformation; + ApplyConfigurationUnitResult() = default; #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) diff --git a/src/Microsoft.Management.Configuration/ConfigThreadGlobals.cpp b/src/Microsoft.Management.Configuration/ConfigThreadGlobals.cpp new file mode 100644 index 0000000000..9ea21eb54f --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigThreadGlobals.cpp @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ConfigThreadGlobals.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + AppInstaller::Logging::DiagnosticLogger& ConfigThreadGlobals::GetDiagnosticLogger() + { + return m_logger; + } + + AppInstaller::Logging::TelemetryTraceLogger& ConfigThreadGlobals::GetTelemetryLogger() + { + THROW_HR(E_NOTIMPL); + } +} diff --git a/src/Microsoft.Management.Configuration/ConfigThreadGlobals.h b/src/Microsoft.Management.Configuration/ConfigThreadGlobals.h new file mode 100644 index 0000000000..c0f322e947 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigThreadGlobals.h @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + // Interface for access to values that are stored on a per-thread object. + struct ConfigThreadGlobals : public AppInstaller::ThreadLocalStorage::ThreadGlobals + { + ConfigThreadGlobals() = default; + virtual ~ConfigThreadGlobals() = default; + + AppInstaller::Logging::DiagnosticLogger& GetDiagnosticLogger() override; + + AppInstaller::Logging::TelemetryTraceLogger& GetTelemetryLogger() override; + + protected: + AppInstaller::Logging::DiagnosticLogger m_logger; + }; +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp index 19713626d6..5de837ddb6 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp @@ -6,18 +6,75 @@ #include "ConfigurationSet.h" #include "OpenConfigurationSetResult.h" #include "ConfigurationSetParser.h" +#include "DiagnosticInformation.h" +#include "ApplyConfigurationSetResult.h" +#include "ConfigurationSetApplyProcessor.h" +#include "TestConfigurationSetResult.h" +#include "TestConfigurationUnitResult.h" +#include "ConfigurationUnitResultInformation.h" +#include "GetConfigurationUnitSettingsResult.h" +#include "ExceptionResultHelpers.h" #include +#include namespace winrt::Microsoft::Management::Configuration::implementation { - ConfigurationProcessor::ConfigurationProcessor(const IConfigurationProcessorFactory& factory) : m_factory(factory) + namespace { + // ILogger that sends data back to the Diagnostics event of the ConfigurationProcessor. + struct ConfigurationProcessorDiagnosticsLogger : public AppInstaller::Logging::ILogger + { + ConfigurationProcessorDiagnosticsLogger(ConfigurationProcessor& processor) : m_processor(processor) {} + + std::string GetName() const override + { + return "ConfigurationProcessorDiagnosticsLogger"; + } + + void Write(AppInstaller::Logging::Channel channel, AppInstaller::Logging::Level level, std::string_view message) noexcept override try + { + std::ostringstream strstr; + strstr << '[' << AppInstaller::Logging::GetChannelName(channel) << "] " << message; + m_processor.Diagnostics(ConvertLevel(level), strstr.str()); + } + catch (...) {} + + void WriteDirect(std::string_view message) noexcept override try + { + m_processor.Diagnostics(DiagnosticLevel::Informational, message); + } + catch (...) {} + + private: + DiagnosticLevel ConvertLevel(AppInstaller::Logging::Level level) + { + switch (level) + { + case AppInstaller::Logging::Level::Verbose: return DiagnosticLevel::Verbose; + case AppInstaller::Logging::Level::Info: return DiagnosticLevel::Informational; + case AppInstaller::Logging::Level::Warning: return DiagnosticLevel::Warning; + case AppInstaller::Logging::Level::Error: return DiagnosticLevel::Error; + case AppInstaller::Logging::Level::Crit: return DiagnosticLevel::Critical; + default: return DiagnosticLevel::Warning; + } + } + + ConfigurationProcessor& m_processor; + }; + + bool ShouldTestDuringTest(ConfigurationUnitIntent intent) + { + return (intent == ConfigurationUnitIntent::Assert || intent == ConfigurationUnitIntent::Apply); + } } - void ConfigurationProcessor::Initialize() + ConfigurationProcessor::ConfigurationProcessor(const IConfigurationProcessorFactory& factory) : m_factory(factory) { - + AppInstaller::Logging::DiagnosticLogger& logger = m_threadGlobals.GetDiagnosticLogger(); + logger.EnableChannel(AppInstaller::Logging::Channel::All); + logger.SetLevel(AppInstaller::Logging::Level::Verbose); + logger.AddLogger(std::make_unique(*this)); } event_token ConfigurationProcessor::Diagnostics(const Windows::Foundation::EventHandler& handler) @@ -47,6 +104,8 @@ namespace winrt::Microsoft::Management::Configuration::implementation Configuration::OpenConfigurationSetResult ConfigurationProcessor::OpenConfigurationSet(Windows::Storage::Streams::IInputStream stream) { + auto threadGlobals = m_threadGlobals.SetForCurrentThread(); + auto result = make_self>(); try @@ -84,42 +143,185 @@ namespace winrt::Microsoft::Management::Configuration::implementation Windows::Foundation::IAsyncOperation> ConfigurationProcessor::CheckForConflictsAsync( const Windows::Foundation::Collections::IVectorView& configurationSets, bool includeConfigurationHistory) + { + co_return CheckForConflicts(configurationSets, includeConfigurationHistory); + } + + Windows::Foundation::IAsyncAction ConfigurationProcessor::GetSetDetailsAsync(const ConfigurationSet& configurationSet, ConfigurationUnitDetailLevel detailLevel) + { + co_return GetSetDetails(configurationSet, detailLevel); + } + + Windows::Foundation::IAsyncAction ConfigurationProcessor::GetUnitDetailsAsync(const ConfigurationUnit& unit, ConfigurationUnitDetailLevel detailLevel) + { + co_return GetUnitDetails(unit, detailLevel); + } + + Windows::Foundation::IAsyncOperation ConfigurationProcessor::ApplyAsync(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags) + { + co_return Apply(configurationSet, flags); + } + + Windows::Foundation::IAsyncOperation ConfigurationProcessor::TestAsync(const ConfigurationSet& configurationSet) + { + co_return Test(configurationSet); + } + + Windows::Foundation::IAsyncOperation ConfigurationProcessor::GetSettingsAsync(const ConfigurationUnit& unit) + { + co_return GetSettings(unit); + } + + void ConfigurationProcessor::Diagnostics(DiagnosticLevel level, std::string_view message) + { + auto diagnostics = make_self>(); + diagnostics->Initialize(level, AppInstaller::Utility::ConvertToUTF16(message)); + m_diagnostics(*this, *diagnostics); + } + + Windows::Foundation::Collections::IVectorView ConfigurationProcessor::CheckForConflicts( + const Windows::Foundation::Collections::IVectorView& configurationSets, + bool includeConfigurationHistory) { UNREFERENCED_PARAMETER(configurationSets); UNREFERENCED_PARAMETER(includeConfigurationHistory); THROW_HR(E_NOTIMPL); } - Windows::Foundation::IAsyncAction ConfigurationProcessor::GetSetDetailsAsync(const ConfigurationSet& configurationSet, const ConfigurationUnitDetailLevel& detailLevel) + void ConfigurationProcessor::GetSetDetails(const ConfigurationSet& configurationSet, ConfigurationUnitDetailLevel detailLevel) { - UNREFERENCED_PARAMETER(configurationSet); - UNREFERENCED_PARAMETER(detailLevel); - THROW_HR(E_NOTIMPL); + auto threadGlobals = m_threadGlobals.SetForCurrentThread(); + + THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); + + IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(configurationSet); + + for (const auto& unit : configurationSet.ConfigurationUnits()) + { + IConfigurationUnitProcessorDetails details = setProcessor.GetUnitProcessorDetails(unit, detailLevel); + get_self(unit)->Details(std::move(details)); + } } - Windows::Foundation::IAsyncAction ConfigurationProcessor::GetUnitDetailsAsync(const ConfigurationUnit& unit, const ConfigurationUnitDetailLevel& detailLevel) + void ConfigurationProcessor::GetUnitDetails(const ConfigurationUnit& unit, ConfigurationUnitDetailLevel detailLevel) { - UNREFERENCED_PARAMETER(unit); - UNREFERENCED_PARAMETER(detailLevel); - THROW_HR(E_NOTIMPL); + auto threadGlobals = m_threadGlobals.SetForCurrentThread(); + + THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); + + IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr); + IConfigurationUnitProcessorDetails details = setProcessor.GetUnitProcessorDetails(unit, detailLevel); + get_self(unit)->Details(std::move(details)); } - Windows::Foundation::IAsyncOperation ConfigurationProcessor::ApplyAsync(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags) + Configuration::ApplyConfigurationSetResult ConfigurationProcessor::Apply(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags) { - UNREFERENCED_PARAMETER(configurationSet); + // TODO: Not needed until we have history implemented UNREFERENCED_PARAMETER(flags); - THROW_HR(E_NOTIMPL); + + auto threadGlobals = m_threadGlobals.SetForCurrentThread(); + + THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); + + ConfigurationSetApplyProcessor applyProcessor{ configurationSet, m_factory.CreateSetProcessor(configurationSet) }; + applyProcessor.Process(); + + auto result = make_self>(); + result->Initialize(applyProcessor.GetUnitResults(), applyProcessor.ResultCode()); + return *result; } - Windows::Foundation::IAsyncOperation ConfigurationProcessor::TestAsync(const ConfigurationSet& configurationSet) + Configuration::TestConfigurationSetResult ConfigurationProcessor::Test(const ConfigurationSet& configurationSet) { - UNREFERENCED_PARAMETER(configurationSet); - THROW_HR(E_NOTIMPL); + auto threadGlobals = m_threadGlobals.SetForCurrentThread(); + + THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); + + IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(configurationSet); + auto result = make_self>(); + bool overallResult = true; + + for (const auto& unit : configurationSet.ConfigurationUnits()) + { + auto testResult = make_self>(); + auto unitResult = make_self>(); + testResult->Initialize(unit, *unitResult); + + if (ShouldTestDuringTest(unit.Intent())) + { + IConfigurationUnitProcessor unitProcessor; + + try + { + // TODO: Directives overlay to prevent running elevated for test + unitProcessor = setProcessor.CreateUnitProcessor(unit, {}); + } + catch (...) + { + ExtractUnitResultInformation(std::current_exception(), unitResult, setProcessor); + } + + if (unitProcessor) + { + try + { + bool unitTestResult = unitProcessor.TestSettings(); + overallResult = overallResult && unitTestResult; + testResult->TestResult(unitTestResult); + } + catch (...) + { + ExtractUnitResultInformation(std::current_exception(), unitResult, unitProcessor); + } + } + } + else + { + unitResult->ResultCode(S_FALSE); + } + + result->AppendUnitResult(*testResult); + } + + result->TestResult(overallResult); + return *result; } - Windows::Foundation::IAsyncOperation ConfigurationProcessor::GetSettingsAsync(const ConfigurationUnit& unit) + Configuration::GetConfigurationUnitSettingsResult ConfigurationProcessor::GetSettings(const ConfigurationUnit& unit) { - UNREFERENCED_PARAMETER(unit); - THROW_HR(E_NOTIMPL); + auto threadGlobals = m_threadGlobals.SetForCurrentThread(); + + THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); + + IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr); + auto result = make_self>(); + auto unitResult = make_self>(); + result->Initialize(*unitResult); + + IConfigurationUnitProcessor unitProcessor; + + try + { + // TODO: Directives overlay to prevent running elevated for get + unitProcessor = setProcessor.CreateUnitProcessor(unit, {}); + } + catch (...) + { + ExtractUnitResultInformation(std::current_exception(), unitResult, setProcessor); + } + + if (unitProcessor) + { + try + { + result->Settings(unitProcessor.GetSettings()); + } + catch (...) + { + ExtractUnitResultInformation(std::current_exception(), unitResult, unitProcessor); + } + } + + return *result; } } diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.h b/src/Microsoft.Management.Configuration/ConfigurationProcessor.h index 66078ee396..7765e2319c 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationProcessor.h +++ b/src/Microsoft.Management.Configuration/ConfigurationProcessor.h @@ -5,6 +5,9 @@ #include #include #include +#include "ConfigThreadGlobals.h" + +#include namespace winrt::Microsoft::Management::Configuration::implementation { @@ -12,13 +15,13 @@ namespace winrt::Microsoft::Management::Configuration::implementation { using ConfigurationSet = Configuration::ConfigurationSet; using ConfigurationUnit = Configuration::ConfigurationUnit; + using DiagnosticInformation = Configuration::DiagnosticInformation; + using ApplyConfigurationSetResult = Configuration::ApplyConfigurationSetResult; + using TestConfigurationSetResult = Configuration::TestConfigurationSetResult; + using GetConfigurationUnitSettingsResult = Configuration::GetConfigurationUnitSettingsResult; ConfigurationProcessor(const IConfigurationProcessorFactory& factory); -#if !defined(INCLUDE_ONLY_INTERFACE_METHODS) - void Initialize(); -#endif - event_token Diagnostics(const Windows::Foundation::EventHandler& handler); void Diagnostics(const event_token& token) noexcept; @@ -33,9 +36,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation const Windows::Foundation::Collections::IVectorView& configurationSets, bool includeConfigurationHistory); - Windows::Foundation::IAsyncAction GetSetDetailsAsync(const ConfigurationSet& configurationSet, const ConfigurationUnitDetailLevel& detailLevel); + Windows::Foundation::IAsyncAction GetSetDetailsAsync(const ConfigurationSet& configurationSet, ConfigurationUnitDetailLevel detailLevel); - Windows::Foundation::IAsyncAction GetUnitDetailsAsync(const ConfigurationUnit& unit, const ConfigurationUnitDetailLevel& detailLevel); + Windows::Foundation::IAsyncAction GetUnitDetailsAsync(const ConfigurationUnit& unit, ConfigurationUnitDetailLevel detailLevel); Windows::Foundation::IAsyncOperation ApplyAsync(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags); @@ -44,10 +47,28 @@ namespace winrt::Microsoft::Management::Configuration::implementation Windows::Foundation::IAsyncOperation GetSettingsAsync(const ConfigurationUnit& unit); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + // Sends diagnostics objects to the event. + void Diagnostics(DiagnosticLevel level, std::string_view message); + + Windows::Foundation::Collections::IVectorView CheckForConflicts( + const Windows::Foundation::Collections::IVectorView& configurationSets, + bool includeConfigurationHistory); + + void GetSetDetails(const ConfigurationSet& configurationSet, ConfigurationUnitDetailLevel detailLevel); + + void GetUnitDetails(const ConfigurationUnit& unit, ConfigurationUnitDetailLevel detailLevel); + + ApplyConfigurationSetResult Apply(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags); + + TestConfigurationSetResult Test(const ConfigurationSet& configurationSet); + + GetConfigurationUnitSettingsResult GetSettings(const ConfigurationUnit& unit); + private: IConfigurationProcessorFactory m_factory = nullptr; event> m_diagnostics; event> m_configurationChange; + ConfigThreadGlobals m_threadGlobals; #endif }; } diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp new file mode 100644 index 0000000000..f6cb3cf766 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp @@ -0,0 +1,340 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ConfigurationSetApplyProcessor.h" +#include "ExceptionResultHelpers.h" + +#include +#include +#include + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + namespace + { + std::string GetNormalizedIdentifier(hstring identifier) + { + using namespace AppInstaller::Utility; + return FoldCase(NormalizedString{ identifier }); + } + } + + ConfigurationSetApplyProcessor::ConfigurationSetApplyProcessor(const Configuration::ConfigurationSet& configurationSet, IConfigurationSetProcessor&& setProcessor) : + m_setProcessor(std::move(setProcessor)) + { + // Create a copy of the set of configuration units + auto unitsView = configurationSet.ConfigurationUnits(); + std::vector unitsToProcess{ unitsView.Size() }; + unitsView.GetMany(0, unitsToProcess); + + // Create the unit info vector from these units + for (const auto& unit : unitsToProcess) + { + m_unitInfo.emplace_back(unit); + } + } + + void ConfigurationSetApplyProcessor::Process() + { + if (!PreProcess()) + { + return; + } + + ProcessInternal(HasProcessedSuccessfully, &ConfigurationSetApplyProcessor::ProcessUnit); + } + + std::vector ConfigurationSetApplyProcessor::GetUnitResults() const + { + THROW_HR(E_NOTIMPL); + } + + hresult ConfigurationSetApplyProcessor::ResultCode() const + { + return m_resultCode; + } + + ConfigurationSetApplyProcessor::UnitInfo::UnitInfo(const Configuration::ConfigurationUnit& unit) : + Unit(unit), Result(make_self>()) + { + } + + bool ConfigurationSetApplyProcessor::PreProcess() + { + bool result = true; + + for (size_t i = 0; i < m_unitInfo.size(); ++i) + { + if (!AddUnitToMap(m_unitInfo[i], i)) + { + result = false; + } + } + + if (!result) + { + // This is the only error that adding to the map can produce + m_resultCode = WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER; + return false; + } + + for (UnitInfo& unitInfo : m_unitInfo) + { + for (hstring dependencyHstring : unitInfo.Unit.Dependencies()) + { + std::string dependency = GetNormalizedIdentifier(dependencyHstring); + auto itr = m_idToUnitInfoIndex.find(dependency); + if (itr == m_idToUnitInfoIndex.end()) + { + AICLI_LOG(Config, Error, << "Found missing dependency: " << dependency); + unitInfo.Result->ResultCode(WINGET_CONFIG_ERROR_MISSING_DEPENDENCY); + result = false; + } + else + { + unitInfo.DependencyIndices.emplace_back(itr->second); + } + } + } + + if (!result) + { + // This is the only error that adding to the map can produce + m_resultCode = WINGET_CONFIG_ERROR_MISSING_DEPENDENCY; + return false; + } + + return ProcessInternal(HasPreprocessed, &ConfigurationSetApplyProcessor::MarkPreprocessed); + } + + bool ConfigurationSetApplyProcessor::AddUnitToMap(UnitInfo& unitInfo, size_t unitInfoIndex) + { + std::string identifier = GetNormalizedIdentifier(unitInfo.Unit.Identifier()); + + auto itr = m_idToUnitInfoIndex.find(identifier); + if (itr != m_idToUnitInfoIndex.end()) + { + AICLI_LOG(Config, Error, << "Found duplicate identifier: " << identifier); + // Found a duplicate identifier, mark both as such + unitInfo.Result->ResultCode(WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER); + m_unitInfo[itr->second].Result->ResultCode(WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER); + return false; + } + else + { + m_idToUnitInfoIndex.emplace(std::move(identifier), unitInfoIndex); + return true; + } + } + + bool ConfigurationSetApplyProcessor::ProcessInternal(CheckDependencyPtr checkDependencyFunction, ProcessUnitPtr processUnitFunction) + { + // Create the set of units that need to be processed + std::vector unitsToProcess; + for (size_t i = 0, size = m_unitInfo.size(); i > size; ++i) + { + unitsToProcess.emplace_back(i); + } + + // Always process all ConfigurationUnitIntent::Assert first + if (!ProcessIntentInternal( + unitsToProcess, + checkDependencyFunction, + processUnitFunction, + ConfigurationUnitIntent::Assert, + WINGET_CONFIG_ERROR_ASSERTION_FAILED, + WINGET_CONFIG_ERROR_ASSERTION_FAILED)) + { + return false; + } + + // Then all ConfigurationUnitIntent::Inform + if (!ProcessIntentInternal( + unitsToProcess, + checkDependencyFunction, + processUnitFunction, + ConfigurationUnitIntent::Inform, + WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED, + WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED)) + { + return false; + } + + // Then all ConfigurationUnitIntent::Apply + return ProcessIntentInternal( + unitsToProcess, + checkDependencyFunction, + processUnitFunction, + ConfigurationUnitIntent::Apply, + E_FAIL, // This should not happen as there are no other intents left + WINGET_CONFIG_ERROR_SET_APPLY_FAILED); + } + + bool ConfigurationSetApplyProcessor::ProcessIntentInternal( + std::vector unitsToProcess, + CheckDependencyPtr checkDependencyFunction, + ProcessUnitPtr processUnitFunction, + ConfigurationUnitIntent intent, + hresult errorForOtherIntents, + hresult errorForFailures) + { + // Always process the first item in the list that is available to be processed + bool hasProcessed = true; + bool hasFailure = false; + while (hasProcessed) + { + hasProcessed = false; + for (auto itr = unitsToProcess.begin(), end = unitsToProcess.end(); itr != end; ++itr) + { + UnitInfo& unitInfo = m_unitInfo[*itr]; + if (HasIntentAndSatisfiedDependencies(unitInfo, intent, checkDependencyFunction)) + { + if (!(this->*processUnitFunction)(unitInfo)) + { + hasFailure = true; + } + unitsToProcess.erase(itr); + hasProcessed = true; + break; + } + } + } + + // Mark all remaining items with intent as failed due to dependency + bool hasRemainingDependencies = false; + for (size_t index : unitsToProcess) + { + UnitInfo& unitInfo = m_unitInfo[index]; + if (unitInfo.Unit.Intent() == intent) + { + hasRemainingDependencies = true; + unitInfo.Result->ResultCode(WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED); + } + } + + // Any failures are fatal, mark all other units as failed due to that + if (hasFailure || hasRemainingDependencies) + { + for (size_t index : unitsToProcess) + { + UnitInfo& unitInfo = m_unitInfo[index]; + if (unitInfo.Unit.Intent() != intent) + { + unitInfo.Result->ResultCode(errorForOtherIntents); + } + } + + if (hasFailure) + { + m_resultCode = errorForFailures; + } + else // hasRemainingDependencies + { + m_resultCode = WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED; + } + return false; + } + + return true; + } + + bool ConfigurationSetApplyProcessor::HasIntentAndSatisfiedDependencies( + const UnitInfo& unitInfo, + ConfigurationUnitIntent intent, + CheckDependencyPtr checkDependencyFunction) const + { + bool result = false; + + if (unitInfo.Unit.Intent() == intent) + { + result = true; + for (size_t dependencyIndex : unitInfo.DependencyIndices) + { + if (!checkDependencyFunction(m_unitInfo[dependencyIndex])) + { + result = false; + break; + } + } + } + + return result; + } + + bool ConfigurationSetApplyProcessor::HasPreprocessed(const UnitInfo& unitInfo) + { + return unitInfo.PreProcessed; + } + + bool ConfigurationSetApplyProcessor::MarkPreprocessed(UnitInfo& unitInfo) + { + unitInfo.PreProcessed = true; + return true; + } + + bool ConfigurationSetApplyProcessor::HasProcessedSuccessfully(const UnitInfo& unitInfo) + { + return unitInfo.Processed && SUCCEEDED(unitInfo.Result->ResultCode()); + } + + bool ConfigurationSetApplyProcessor::ProcessUnit(UnitInfo& unitInfo) + { + IConfigurationUnitProcessor unitProcessor; + + try + { + unitProcessor = m_setProcessor.CreateUnitProcessor(unitInfo.Unit, {}); + } + catch (...) + { + ExtractUnitResultInformation(std::current_exception(), unitInfo.Result, m_setProcessor); + return false; + } + + try + { + switch (unitInfo.Unit.Intent()) + { + case ConfigurationUnitIntent::Assert: + { + if (unitProcessor.TestSettings()) + { + return true; + } + else + { + unitInfo.Result->ResultCode(WINGET_CONFIG_ERROR_ASSERTION_FAILED); + return false; + } + } + case ConfigurationUnitIntent::Inform: + { + // Force the processor to retrieve the settings + std::ignore = unitProcessor.GetSettings(); + return true; + } + case ConfigurationUnitIntent::Apply: + { + if (unitProcessor.TestSettings()) + { + unitInfo.Result->ResultCode(S_FALSE); + return true; + } + else + { + unitProcessor.ApplySettings(); + return true; + } + } + default: + unitInfo.Result->ResultCode(E_UNEXPECTED); + return false; + } + } + catch (...) + { + ExtractUnitResultInformation(std::current_exception(), unitInfo.Result, unitProcessor); + return false; + } + } +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h new file mode 100644 index 0000000000..193c28ed8c --- /dev/null +++ b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h @@ -0,0 +1,92 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ConfigurationSet.h" +#include "ConfigurationUnit.h" +#include "ApplyConfigurationUnitResult.h" +#include "ConfigurationUnitResultInformation.h" + +#include +#include +#include + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + // A helper to better organize the configuration set Apply. + struct ConfigurationSetApplyProcessor + { + using ConfigurationSet = Configuration::ConfigurationSet; + using ConfigurationUnit = Configuration::ConfigurationUnit; + + ConfigurationSetApplyProcessor(const ConfigurationSet& configurationSet, IConfigurationSetProcessor&& setProcessor); + + // Processes the apply for the configuration set. + void Process(); + + // Gets the unit results from the processing. + std::vector GetUnitResults() const; + + // Gets the overall result code from the processing. + hresult ResultCode() const; + + private: + // Contains all of the relevant data for a configuration unit. + struct UnitInfo + { + UnitInfo(const ConfigurationUnit& unit); + + ConfigurationUnit Unit; + std::vector DependencyIndices; + decltype(make_self>()) Result; + bool PreProcessed = false; + bool Processed = false; + }; + + // Builds out some data used during processing and validates the set along the way. + bool PreProcess(); + + // Adds the given unit to the identifier to unit info index map. + bool AddUnitToMap(UnitInfo& unitInfo, size_t unitInfoIndex); + + // Checks the dependency; returns true to indicate that the dependency is satisfied, false if not. + using CheckDependencyPtr = bool (*)(const UnitInfo&); + + // Processes the unit; returns true if successful, false if not. + using ProcessUnitPtr = bool (ConfigurationSetApplyProcessor::*)(UnitInfo&); + + // Runs the processing using the given functions. + bool ProcessInternal(CheckDependencyPtr checkDependencyFunction, ProcessUnitPtr processUnitFunction); + + // Processes one of the non-writing intent types, which are fatal if not all successful + bool ProcessIntentInternal( + std::vector unitsToProcess, + CheckDependencyPtr checkDependencyFunction, + ProcessUnitPtr processUnitFunction, + ConfigurationUnitIntent intent, + hresult errorForOtherIntents, + hresult errorForFailures); + + // Determines if the given unit has the given intent and all of its dependencies are satisfied + bool HasIntentAndSatisfiedDependencies( + const UnitInfo& unitInfo, + ConfigurationUnitIntent intent, + CheckDependencyPtr checkDependencyFunction) const; + + // Checks a dependency for preprocessing. + static bool HasPreprocessed(const UnitInfo& unitInfo); + + // Marks a unit as preprocessed. + bool MarkPreprocessed(UnitInfo& unitInfo); + + // Checks a dependency for having processed successfully. + static bool HasProcessedSuccessfully(const UnitInfo& unitInfo); + + // Processes a configuration unit per its intent. + bool ProcessUnit(UnitInfo& unitInfo); + + IConfigurationSetProcessor m_setProcessor; + std::vector m_unitInfo; + std::map m_idToUnitInfoIndex; + hresult m_resultCode; + }; +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp index ce244a346b..132aa06697 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp @@ -86,7 +86,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation } AICLI_LOG(Config, Info, << "Unknown configuration version: " << schemaVersion.ToString()); - return std::make_unique(WINGET_CONFIG_ERROR_UKNOWN_CONFIGURATION_FILE_VERSION); + return std::make_unique(WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION); } void ConfigurationSetParser::SetError(hresult result, std::string_view field) diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.cpp index 4769eac779..30aa43beab 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.cpp @@ -93,6 +93,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation ParseConfigurationUnitsFromSubsection(properties, "assertions", ConfigurationUnitIntent::Assert, result); ParseConfigurationUnitsFromSubsection(properties, "parameters", ConfigurationUnitIntent::Inform, result); ParseConfigurationUnitsFromSubsection(properties, "resources", ConfigurationUnitIntent::Apply, result); + // TODO: Additional semantic validation? return result; } diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp b/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp index e9c2dab7bc..78bd18f146 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationUnit.cpp @@ -90,6 +90,11 @@ namespace winrt::Microsoft::Management::Configuration::implementation return m_details; } + void ConfigurationUnit::Details(IConfigurationUnitProcessorDetails&& details) + { + m_details = std::move(details); + } + ConfigurationUnitState ConfigurationUnit::State() { return ConfigurationUnitState::Unknown; diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnit.h b/src/Microsoft.Management.Configuration/ConfigurationUnit.h index 0ba1f7f018..0c26182c21 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationUnit.h +++ b/src/Microsoft.Management.Configuration/ConfigurationUnit.h @@ -14,7 +14,6 @@ namespace winrt::Microsoft::Management::Configuration::implementation #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) ConfigurationUnit(const guid& instanceIdentifier); - void Dependencies(std::vector&& value); #endif hstring UnitName(); @@ -45,6 +44,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation void ShouldApply(bool value); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void Dependencies(std::vector&& value); + void Details(IConfigurationUnitProcessorDetails&& details); + private: hstring m_unitName; guid m_instanceIdentifier; diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp index 6b6fa5411a..255129565d 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp @@ -12,11 +12,22 @@ namespace winrt::Microsoft::Management::Configuration::implementation m_description = description; } + void ConfigurationUnitResultInformation::Initialize(hresult resultCode, hstring description) + { + m_resultCode = resultCode; + m_description = description; + } + hresult ConfigurationUnitResultInformation::ResultCode() { return m_resultCode; } + void ConfigurationUnitResultInformation::ResultCode(hresult resultCode) + { + m_resultCode = resultCode; + } + hstring ConfigurationUnitResultInformation::Description() { return m_description; diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h index 89cac7bc29..dd15c0cacf 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h +++ b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h @@ -11,6 +11,8 @@ namespace winrt::Microsoft::Management::Configuration::implementation #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void Initialize(hresult resultCode, std::wstring_view description); + void Initialize(hresult resultCode, hstring description); + void ResultCode(hresult resultCode); #endif hresult ResultCode(); diff --git a/src/Microsoft.Management.Configuration/ExceptionResultHelpers.h b/src/Microsoft.Management.Configuration/ExceptionResultHelpers.h new file mode 100644 index 0000000000..a89f73b228 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ExceptionResultHelpers.h @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + template + void ExtractUnitResultInformation(std::exception_ptr exc, const UnitResult& unitResult, const Processor& processor) + { + try + { + std::rethrow_exception(exc); + } + catch (const winrt::hresult_error& hre) + { + unitResult->Initialize(hre.code(), processor.GetLastErrorMessage()); + } + catch (...) + { + unitResult->Initialize(E_FAIL, hstring{}); + } + } +} diff --git a/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp index 04f037c6c5..211ee96a49 100644 --- a/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp +++ b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp @@ -6,18 +6,23 @@ namespace winrt::Microsoft::Management::Configuration::implementation { - void GetConfigurationUnitSettingsResult::Initialize() - { - - } + void GetConfigurationUnitSettingsResult::Initialize(const ConfigurationUnitResultInformation& resultInformation) + { + m_resultInformation = resultInformation; + } + + ConfigurationUnitResultInformation GetConfigurationUnitSettingsResult::ResultInformation() + { + return m_resultInformation; + } - ConfigurationUnitResultInformation GetConfigurationUnitSettingsResult::ResultInformation() - { - return m_resultInformation; - } + Windows::Foundation::Collections::ValueSet GetConfigurationUnitSettingsResult::Settings() + { + return m_settings; + } - Windows::Foundation::Collections::ValueSet GetConfigurationUnitSettingsResult::Settings() - { - return m_settings; + void GetConfigurationUnitSettingsResult::Settings(Windows::Foundation::Collections::ValueSet&& value) + { + m_settings = std::move(value); } } diff --git a/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h index f428b2e7de..8604ea230d 100644 --- a/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h +++ b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h @@ -8,10 +8,13 @@ namespace winrt::Microsoft::Management::Configuration::implementation { struct GetConfigurationUnitSettingsResult : GetConfigurationUnitSettingsResultT { + using ConfigurationUnitResultInformation = Configuration::ConfigurationUnitResultInformation; + GetConfigurationUnitSettingsResult() = default; #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) - void Initialize(); + void Initialize(const ConfigurationUnitResultInformation& resultInformation); + void Settings(Windows::Foundation::Collections::ValueSet&& value); #endif ConfigurationUnitResultInformation ResultInformation(); diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl index 0880e36c92..6c5bc34da1 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -26,6 +26,7 @@ namespace Microsoft.Management.Configuration ApplicationFailed, ApplicationSucceeded, SkippedManually, + SkippedDueToAssertions, SkippedDueToDependencies, TestBegun, TestFailed, @@ -272,6 +273,9 @@ namespace Microsoft.Management.Configuration // Applies the state described in the configuration unit. void ApplySettings(); + + // Gets the error message from the last attempt to run a command. + String GetLastErrorMessage(); } // Controls the lifetime of operations for a single configuration set. @@ -285,6 +289,9 @@ namespace Microsoft.Management.Configuration // The optional `directivesOverlay` parameter allows for the `ConfigurationProcessor` to alter behavior without needing to change the unit itself. // The overlay is searched first; any value not present there will then fall back to the unit's directives. IConfigurationUnitProcessor CreateUnitProcessor(ConfigurationUnit unit, Windows.Foundation.Collections.IMapView directivesOverlay); + + // Gets the error message from the last attempt to run a command. + String GetLastErrorMessage(); } // Allows different runtimes to provide specialized handling of configuration processing. diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj index 326da818cd..f01e5506bd 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -129,11 +129,13 @@ + + @@ -141,6 +143,7 @@ + @@ -151,11 +154,13 @@ + + diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters index f0e7ca32d5..716dd6fc2e 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters @@ -57,6 +57,12 @@ API Source + + Internals + + + Internals + @@ -117,6 +123,15 @@ Parser + + Internals + + + Internals + + + Internals + diff --git a/src/Microsoft.Management.Configuration/TestConfigurationSetResult.cpp b/src/Microsoft.Management.Configuration/TestConfigurationSetResult.cpp index ffe0f5da98..9d0f1f101c 100644 --- a/src/Microsoft.Management.Configuration/TestConfigurationSetResult.cpp +++ b/src/Microsoft.Management.Configuration/TestConfigurationSetResult.cpp @@ -6,18 +6,27 @@ namespace winrt::Microsoft::Management::Configuration::implementation { - void TestConfigurationSetResult::Initialize() - { - - } + TestConfigurationSetResult::TestConfigurationSetResult() : m_unitResults(single_threaded_vector()) + { + } + + void TestConfigurationSetResult::AppendUnitResult(const TestConfigurationUnitResult& unitResult) + { + m_unitResults.Append(unitResult); + } - Windows::Foundation::Collections::IVectorView TestConfigurationSetResult::UnitResults() - { - return m_unitResults.GetView(); - } + Windows::Foundation::Collections::IVectorView TestConfigurationSetResult::UnitResults() + { + return m_unitResults.GetView(); + } + + bool TestConfigurationSetResult::TestResult() + { + return m_testResult; + } - bool TestConfigurationSetResult::TestResult() - { - return m_testResult; + void TestConfigurationSetResult::TestResult(bool value) + { + m_testResult = value; } } diff --git a/src/Microsoft.Management.Configuration/TestConfigurationSetResult.h b/src/Microsoft.Management.Configuration/TestConfigurationSetResult.h index 5a9624c68f..0b74b89e23 100644 --- a/src/Microsoft.Management.Configuration/TestConfigurationSetResult.h +++ b/src/Microsoft.Management.Configuration/TestConfigurationSetResult.h @@ -8,10 +8,11 @@ namespace winrt::Microsoft::Management::Configuration::implementation { struct TestConfigurationSetResult : TestConfigurationSetResultT { - TestConfigurationSetResult() = default; + TestConfigurationSetResult(); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) - void Initialize(); + void AppendUnitResult(const TestConfigurationUnitResult& unitResult); + void TestResult(bool value); #endif Windows::Foundation::Collections::IVectorView UnitResults(); diff --git a/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.cpp b/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.cpp index 7ede81d198..05e3cc1f2d 100644 --- a/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.cpp +++ b/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.cpp @@ -6,11 +6,10 @@ namespace winrt::Microsoft::Management::Configuration::implementation { - void TestConfigurationUnitResult::Initialize(ConfigurationUnit unit, ConfigurationUnitResultInformation resultInformation, bool testResult) + void TestConfigurationUnitResult::Initialize(ConfigurationUnit unit, ConfigurationUnitResultInformation resultInformation) { m_unit = unit; m_resultInformation = resultInformation; - m_testResult = testResult; } ConfigurationUnit TestConfigurationUnitResult::Unit() @@ -27,4 +26,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation { return m_testResult; } + + void TestConfigurationUnitResult::TestResult(bool value) + { + m_testResult = value; + } } diff --git a/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.h b/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.h index 1657da531c..3e1da45e2b 100644 --- a/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.h +++ b/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.h @@ -7,10 +7,14 @@ namespace winrt::Microsoft::Management::Configuration::implementation { struct TestConfigurationUnitResult : TestConfigurationUnitResultT { + using ConfigurationUnit = Configuration::ConfigurationUnit; + using ConfigurationUnitResultInformation = Configuration::ConfigurationUnitResultInformation; + TestConfigurationUnitResult() = default; #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) - void Initialize(ConfigurationUnit unit, ConfigurationUnitResultInformation resultInformation, bool testResult); + void Initialize(ConfigurationUnit unit, ConfigurationUnitResultInformation resultInformation); + void TestResult(bool value); #endif ConfigurationUnit Unit(); From be5b279be23c317cd87756f9d5245745bb0a49be Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Tue, 31 Jan 2023 17:52:47 -0800 Subject: [PATCH 13/31] Some logic fixes and the initial test infrastructure --- src/AppInstallerCLI.sln | 164 +++++++++++++----- .../Public/AppInstallerErrors.h | 1 + ...Management.Configuration.Projection.csproj | 36 ++++ .../Fixtures/UnitTestCollection.cs | 21 +++ .../Fixtures/UnitTestFixture.cs | 30 ++++ .../Helpers/ConfigurationProcessorTestBase.cs | 53 ++++++ .../Helpers/DiagnosticsEventSink.cs | 49 ++++++ ....Management.Configuration.UnitTests.csproj | 37 ++++ .../Tests/ConfigurationSetAuthoringTests.cs | 111 ++++++++++++ .../Tests/OpenConfigurationSetTests.cs | 46 +++++ .../ApplyConfigurationUnitResult.cpp | 8 +- .../ApplyConfigurationUnitResult.h | 4 +- .../ConfigurationProcessor.cpp | 6 + .../ConfigurationSetApplyProcessor.cpp | 46 ++++- .../ConfigurationSetApplyProcessor.h | 1 + .../DiagnosticInformation.h | 2 +- .../Microsoft.Management.Configuration.idl | 3 + ...Microsoft.Management.Configuration.vcxproj | 1 + 18 files changed, 569 insertions(+), 50 deletions(-) create mode 100644 src/Microsoft.Management.Configuration.Projection/Microsoft.Management.Configuration.Projection.csproj create mode 100644 src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestCollection.cs create mode 100644 src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs create mode 100644 src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs create mode 100644 src/Microsoft.Management.Configuration.UnitTests/Helpers/DiagnosticsEventSink.cs create mode 100644 src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj create mode 100644 src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationSetAuthoringTests.cs create mode 100644 src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index a91476cebb..41f57410f6 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -151,6 +151,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AppInstallerSharedLib", "Ap EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Configuration", "Microsoft.Management.Configuration\Microsoft.Management.Configuration.vcxproj", "{CA460806-5E41-4E97-9A3D-1D74B433B663}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Management.Configuration.Projection", "Microsoft.Management.Configuration.Projection\Microsoft.Management.Configuration.Projection.csproj", "{E8454BF1-2068-4513-A525-ABF55CC8742C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Management.Configuration.UnitTests", "Microsoft.Management.Configuration.UnitTests\Microsoft.Management.Configuration.UnitTests.csproj", "{EE43C990-7789-4A60-B077-BF0ED3D093A1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1080,46 +1084,6 @@ Global {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|x64.Build.0 = Release|x64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|x86.ActiveCfg = Release|Win32 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|x86.Build.0 = Release|Win32 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|Any CPU.ActiveCfg = Debug|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|Any CPU.Build.0 = Debug|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM.ActiveCfg = Debug|ARM - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM.Build.0 = Debug|ARM - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM64.Build.0 = Debug|ARM64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x64.ActiveCfg = Debug|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x64.Build.0 = Debug|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x86.ActiveCfg = Debug|Win32 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x86.Build.0 = Debug|Win32 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|Any CPU.ActiveCfg = Debug|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|Any CPU.Build.0 = Debug|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM.ActiveCfg = Debug|ARM - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM.Build.0 = Debug|ARM - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM64.Build.0 = Debug|ARM64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x64.ActiveCfg = Debug|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x64.Build.0 = Debug|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x86.ActiveCfg = Debug|Win32 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x86.Build.0 = Debug|Win32 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|Any CPU.ActiveCfg = Release|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|Any CPU.Build.0 = Release|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM.ActiveCfg = Release|ARM - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM.Build.0 = Release|ARM - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM64.ActiveCfg = Release|ARM64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM64.Build.0 = Release|ARM64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x64.ActiveCfg = Release|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x64.Build.0 = Release|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x86.ActiveCfg = Release|Win32 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x86.Build.0 = Release|Win32 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|Any CPU.ActiveCfg = Release|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|Any CPU.Build.0 = Release|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM.ActiveCfg = Release|ARM - {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM.Build.0 = Release|ARM - {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM64.ActiveCfg = Release|ARM64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM64.Build.0 = Release|ARM64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x64.ActiveCfg = Release|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x64.Build.0 = Release|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x86.ActiveCfg = Release|Win32 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x86.Build.0 = Release|Win32 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|Any CPU.ActiveCfg = Debug|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|Any CPU.Build.0 = Debug|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|ARM.ActiveCfg = Debug|ARM @@ -1160,6 +1124,126 @@ Global {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.TestRelease|x64.Build.0 = Release|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.TestRelease|x86.ActiveCfg = Release|Win32 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.TestRelease|x86.Build.0 = Release|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|Any CPU.ActiveCfg = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|Any CPU.Build.0 = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM.ActiveCfg = Debug|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM.Build.0 = Debug|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM64.Build.0 = Debug|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x64.ActiveCfg = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x64.Build.0 = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x86.ActiveCfg = Debug|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x86.Build.0 = Debug|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|Any CPU.ActiveCfg = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|Any CPU.Build.0 = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM.ActiveCfg = Debug|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM.Build.0 = Debug|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM64.Build.0 = Debug|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x64.ActiveCfg = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x64.Build.0 = Debug|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x86.ActiveCfg = Debug|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x86.Build.0 = Debug|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|Any CPU.ActiveCfg = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|Any CPU.Build.0 = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM.ActiveCfg = Release|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM.Build.0 = Release|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM64.ActiveCfg = Release|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM64.Build.0 = Release|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x64.ActiveCfg = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x64.Build.0 = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x86.ActiveCfg = Release|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x86.Build.0 = Release|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|Any CPU.ActiveCfg = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|Any CPU.Build.0 = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM.ActiveCfg = Release|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM.Build.0 = Release|ARM + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM64.ActiveCfg = Release|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM64.Build.0 = Release|ARM64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x64.ActiveCfg = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x64.Build.0 = Release|x64 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x86.ActiveCfg = Release|Win32 + {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x86.Build.0 = Release|Win32 + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM.ActiveCfg = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM.Build.0 = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM64.Build.0 = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x64.ActiveCfg = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x64.Build.0 = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x86.ActiveCfg = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x86.Build.0 = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|Any CPU.ActiveCfg = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|Any CPU.Build.0 = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|ARM.ActiveCfg = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|ARM.Build.0 = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|ARM64.ActiveCfg = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|ARM64.Build.0 = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|x64.ActiveCfg = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|x64.Build.0 = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|x86.ActiveCfg = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|x86.Build.0 = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|Any CPU.Build.0 = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|ARM.ActiveCfg = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|ARM.Build.0 = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|ARM64.ActiveCfg = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|ARM64.Build.0 = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|x64.ActiveCfg = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|x64.Build.0 = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|x86.ActiveCfg = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|x86.Build.0 = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|Any CPU.ActiveCfg = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|Any CPU.Build.0 = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|ARM.ActiveCfg = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|ARM.Build.0 = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|ARM64.ActiveCfg = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|ARM64.Build.0 = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|x64.ActiveCfg = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|x64.Build.0 = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|x86.ActiveCfg = Release|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|x86.Build.0 = Release|Any CPU + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|Any CPU.ActiveCfg = Debug|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|Any CPU.Build.0 = Debug|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|ARM.ActiveCfg = Debug|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|ARM.Build.0 = Debug|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|ARM64.ActiveCfg = Debug|arm64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|ARM64.Build.0 = Debug|arm64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|x64.ActiveCfg = Debug|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|x64.Build.0 = Debug|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|x86.ActiveCfg = Debug|x86 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|x86.Build.0 = Debug|x86 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|Any CPU.ActiveCfg = Debug|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|Any CPU.Build.0 = Debug|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|ARM.ActiveCfg = Debug|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|ARM.Build.0 = Debug|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|ARM64.ActiveCfg = Debug|arm64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|ARM64.Build.0 = Debug|arm64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|x64.ActiveCfg = Debug|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|x64.Build.0 = Debug|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|x86.ActiveCfg = Debug|x86 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|x86.Build.0 = Debug|x86 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|Any CPU.ActiveCfg = Release|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|Any CPU.Build.0 = Release|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|ARM.ActiveCfg = Release|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|ARM.Build.0 = Release|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|ARM64.ActiveCfg = Release|arm64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|ARM64.Build.0 = Release|arm64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|x64.ActiveCfg = Release|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|x64.Build.0 = Release|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|x86.ActiveCfg = Release|x86 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|x86.Build.0 = Release|x86 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|Any CPU.ActiveCfg = Release|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|Any CPU.Build.0 = Release|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|ARM.ActiveCfg = Release|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|ARM.Build.0 = Release|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|ARM64.ActiveCfg = Release|arm64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|ARM64.Build.0 = Release|arm64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|x64.ActiveCfg = Release|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|x64.Build.0 = Release|x64 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|x86.ActiveCfg = Release|x86 + {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/AppInstallerSharedLib/Public/AppInstallerErrors.h b/src/AppInstallerSharedLib/Public/AppInstallerErrors.h index f149049b8a..1fe45f0ebd 100644 --- a/src/AppInstallerSharedLib/Public/AppInstallerErrors.h +++ b/src/AppInstallerSharedLib/Public/AppInstallerErrors.h @@ -158,6 +158,7 @@ #define WINGET_CONFIG_ERROR_MISSING_DEPENDENCY ((HRESULT)0x8A15C007) #define WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED ((HRESULT)0x8A15C008) #define WINGET_CONFIG_ERROR_ASSERTION_FAILED ((HRESULT)0x8A15C009) +#define WINGET_CONFIG_ERROR_MANUALLY_SKIPPED ((HRESULT)0x8A15C00A) namespace AppInstaller diff --git a/src/Microsoft.Management.Configuration.Projection/Microsoft.Management.Configuration.Projection.csproj b/src/Microsoft.Management.Configuration.Projection/Microsoft.Management.Configuration.Projection.csproj new file mode 100644 index 0000000000..66a5ef6422 --- /dev/null +++ b/src/Microsoft.Management.Configuration.Projection/Microsoft.Management.Configuration.Projection.csproj @@ -0,0 +1,36 @@ + + + + net6.0-windows10.0.22000.0 + AnyCPU + enable + enable + $(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)\ + + + + Microsoft.Management.Configuration + $(OutDir) + 10.0.22000.0 + + 10.0.17763.0 + + + + + None + + + + + + + + + Content + PreserveNewest + True + + + + diff --git a/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestCollection.cs b/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestCollection.cs new file mode 100644 index 0000000000..69f74968e6 --- /dev/null +++ b/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestCollection.cs @@ -0,0 +1,21 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Fixtures +{ + using Xunit; + + /// + /// Unit test collection. + /// + [CollectionDefinition("UnitTestCollection")] + public class UnitTestCollection : ICollectionFixture + { + // This class has no code, and is never created. Its purpose is simply + // to be the place to apply [CollectionDefinition] and all the + // ICollectionFixture<> interfaces. + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs b/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs new file mode 100644 index 0000000000..420ba392dd --- /dev/null +++ b/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs @@ -0,0 +1,30 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Fixtures +{ + using Xunit.Abstractions; + + /// + /// Unit test fixture. + /// + public class UnitTestFixture + { + /// + /// Initializes a new instance of the class. + /// + /// The message sink for the fixture. + public UnitTestFixture(IMessageSink messageSink) + { + this.MessageSink = messageSink; + } + + /// + /// Gets the message sink for the fixture. + /// + public IMessageSink MessageSink { get; private set; } + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs new file mode 100644 index 0000000000..5b8e1df86e --- /dev/null +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs @@ -0,0 +1,53 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Helpers +{ + using Microsoft.Management.Configuration.UnitTests.Fixtures; + using Xunit.Abstractions; + + /// + /// Test base that provides helpers for dealing with . + /// + public class ConfigurationProcessorTestBase + { + private readonly DiagnosticsEventSink diagnosticsEventSink; + + /// + /// Initializes a new instance of the class. + /// + /// Unit test fixture. + /// Log helper. + protected ConfigurationProcessorTestBase(UnitTestFixture fixture, ITestOutputHelper log) + { + this.Fixture = fixture; + this.Log = log; + this.diagnosticsEventSink = new DiagnosticsEventSink(fixture, log); + } + + /// + /// Gets the test fixture. + /// + protected UnitTestFixture Fixture { get; private set; } + + /// + /// Gets the output helper. + /// + protected ITestOutputHelper Log { get; private set; } + + /// + /// Createa a new with the diagnostics event hooked up. + /// + /// The factory to use. + /// The new object. + protected ConfigurationProcessor CreateConfigurationProcessorWithDiagnostics(IConfigurationProcessorFactory? factory = null) + { + ConfigurationProcessor result = new ConfigurationProcessor(factory); + result.Diagnostics += this.diagnosticsEventSink.DiagnosticsHandler; + return result; + } + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/DiagnosticsEventSink.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/DiagnosticsEventSink.cs new file mode 100644 index 0000000000..6dc1a42cdf --- /dev/null +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/DiagnosticsEventSink.cs @@ -0,0 +1,49 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Helpers +{ + using Microsoft.Management.Configuration.UnitTests.Fixtures; + using Xunit.Abstractions; + using Xunit.Sdk; + + /// + /// This class aids in getting diagnostics data from the out to the xUnit infrastructure. + /// + internal class DiagnosticsEventSink + { + private readonly UnitTestFixture fixture; + private readonly ITestOutputHelper log; + + /// + /// Initializes a new instance of the class. + /// + /// Unit test fixture. + /// Log helper. + public DiagnosticsEventSink(UnitTestFixture fixture, ITestOutputHelper log) + { + this.fixture = fixture; + this.log = log; + } + + /// + /// Handles diagnostic information from a . + /// + /// The object sending the information. + /// The diagnostic information. + public void DiagnosticsHandler(object? sender, DiagnosticInformation e) + { + if (e.Level == DiagnosticLevel.Verbose) + { + this.fixture.MessageSink.OnMessage(new DiagnosticMessage(e.Message)); + } + else + { + this.log.WriteLine(e.Message); + } + } + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj b/src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj new file mode 100644 index 0000000000..d9f8cc85ff --- /dev/null +++ b/src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj @@ -0,0 +1,37 @@ + + + + net6.0-windows10.0.22000.0 + enable + 10.0.17763.0 + x64;x86;arm64 + $(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)\ + + + + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationSetAuthoringTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationSetAuthoringTests.cs new file mode 100644 index 0000000000..84ddeb4603 --- /dev/null +++ b/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationSetAuthoringTests.cs @@ -0,0 +1,111 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Tests +{ + using System; + using Microsoft.Management.Configuration.UnitTests.Fixtures; + using Microsoft.VisualBasic; + using Xunit; + using Xunit.Abstractions; + + /// + /// Unit tests for configuration set authoring (creating objects). + /// + [Collection("UnitTestCollection")] + public class ConfigurationSetAuthoringTests + { + private readonly UnitTestFixture fixture; + private readonly ITestOutputHelper log; + + /// + /// Initializes a new instance of the class. + /// + /// Unit test fixture. + /// Log helper. + public ConfigurationSetAuthoringTests(UnitTestFixture fixture, ITestOutputHelper log) + { + this.fixture = fixture; + this.log = log; + } + + /// + /// Creates a configuration set and sets all available properties. + /// + [Fact] + public void ConfigurationSetAndProperties() + { + string testName = "Test Name"; + string testOrigin = "Test Origin"; + string testPath = "TestPath.ext"; + + ConfigurationSet testSet = new ConfigurationSet(); + + testSet.Name = testName; + Assert.Equal(testName, testSet.Name); + testSet.Origin = testOrigin; + Assert.Equal(testOrigin, testSet.Origin); + testSet.Path = testPath; + Assert.Equal(testPath, testSet.Path); + + Assert.NotEqual(Guid.Empty, testSet.InstanceIdentifier); + Assert.Equal(ConfigurationSetState.Unknown, testSet.State); + + Assert.Empty(testSet.ConfigurationUnits); + testSet.ConfigurationUnits = new ConfigurationUnit[] { new ConfigurationUnit() }; + Assert.Equal(1, testSet.ConfigurationUnits.Count); + } + + /// + /// Creates a configuration unit and sets all available properties. + /// + [Fact] + public void ConfigurationUnitAndProperties() + { + string testName = "Test Name"; + string testIdentifier = "Test Identifier"; + ConfigurationUnitIntent testIntent = ConfigurationUnitIntent.Assert; + + ConfigurationUnit testUnit = new ConfigurationUnit(); + + testUnit.UnitName = testName; + Assert.Equal(testName, testUnit.UnitName); + testUnit.Identifier = testIdentifier; + Assert.Equal(testIdentifier, testUnit.Identifier); + + Assert.NotEqual(Guid.Empty, testUnit.InstanceIdentifier); + + Assert.Equal(ConfigurationUnitIntent.Apply, testUnit.Intent); + testUnit.Intent = testIntent; + Assert.Equal(testIntent, testUnit.Intent); + + Assert.Empty(testUnit.Dependencies); + testUnit.Dependencies = new string[] { "dependency1", "dependency2" }; + Assert.Equal(2, testUnit.Dependencies.Count); + + Assert.Empty(testUnit.Directives); + Assert.Empty(testUnit.Settings); + Assert.Null(testUnit.Details); + + Assert.Equal(ConfigurationUnitState.Unknown, testUnit.State); + + Assert.Null(testUnit.ResultInformation); + + Assert.True(testUnit.ShouldApply); + testUnit.ShouldApply = false; + Assert.False(testUnit.ShouldApply); + } + + /// + /// This test is to ensure that real tests are added when Serialize is implemented. + /// + [Fact] + public void ConfigurationSetSerializeNotImplemented() + { + Assert.Throws(() => new ConfigurationSet().Serialize(null)); + } + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs new file mode 100644 index 0000000000..f688560d49 --- /dev/null +++ b/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs @@ -0,0 +1,46 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Tests +{ + using System; + using Microsoft.Management.Configuration.UnitTests.Fixtures; + using Microsoft.Management.Configuration.UnitTests.Helpers; + using Microsoft.VisualBasic; + using Xunit; + using Xunit.Abstractions; + + /// + /// Unit tests for configuration set authoring (creating objects). + /// + [Collection("UnitTestCollection")] + public class OpenConfigurationSetTests : ConfigurationProcessorTestBase + { + /// + /// Initializes a new instance of the class. + /// + /// Unit test fixture. + /// Log helper. + public OpenConfigurationSetTests(UnitTestFixture fixture, ITestOutputHelper log) + : base(fixture, log) + { + } + + /// + /// Passes a null stream as input. + /// + [Fact] + public void NullStream() + { + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(); + + OpenConfigurationSetResult result = processor.OpenConfigurationSet(null); + Assert.Null(result.Set); + Assert.IsType(result.ResultCode); + Assert.Equal(string.Empty, result.Field); + } + } +} diff --git a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp index 627c40a3f4..0dd9d10a6b 100644 --- a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp +++ b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp @@ -6,9 +6,10 @@ namespace winrt::Microsoft::Management::Configuration::implementation { - void ApplyConfigurationUnitResult::Initialize(const ConfigurationUnit& unit, const ConfigurationUnitResultInformation& resultInformation) + void ApplyConfigurationUnitResult::Initialize(const ConfigurationUnit& unit, bool previouslyInDesiredState, const ConfigurationUnitResultInformation& resultInformation) { m_unit = unit; + m_previouslyInDesiredState = previouslyInDesiredState; m_resultInformation = resultInformation; } @@ -17,6 +18,11 @@ namespace winrt::Microsoft::Management::Configuration::implementation return m_unit; } + bool ApplyConfigurationUnitResult::PreviouslyInDesiredState() const + { + return m_previouslyInDesiredState; + } + ConfigurationUnitResultInformation ApplyConfigurationUnitResult::ResultInformation() { return m_resultInformation; diff --git a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h index 509c8301b3..2f14471ae7 100644 --- a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h +++ b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h @@ -13,15 +13,17 @@ namespace winrt::Microsoft::Management::Configuration::implementation ApplyConfigurationUnitResult() = default; #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) - void Initialize(const ConfigurationUnit& unit, const ConfigurationUnitResultInformation& resultInformation); + void Initialize(const ConfigurationUnit& unit, bool previouslyInDesiredState, const ConfigurationUnitResultInformation& resultInformation); #endif ConfigurationUnit Unit(); + bool PreviouslyInDesiredState() const; ConfigurationUnitResultInformation ResultInformation(); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: ConfigurationUnit m_unit = nullptr; + bool m_previouslyInDesiredState = false; ConfigurationUnitResultInformation m_resultInformation = nullptr; #endif }; diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp index 5de837ddb6..cf047ca7ec 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp @@ -108,6 +108,12 @@ namespace winrt::Microsoft::Management::Configuration::implementation auto result = make_self>(); + if (!stream) + { + result->Initialize(E_POINTER, {}); + return *result; + } + try { std::unique_ptr parser = ConfigurationSetParser::Create(stream); diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp index f6cb3cf766..e93e8c3b9e 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp @@ -46,7 +46,16 @@ namespace winrt::Microsoft::Management::Configuration::implementation std::vector ConfigurationSetApplyProcessor::GetUnitResults() const { - THROW_HR(E_NOTIMPL); + std::vector unitResults; + + for (const auto& unitInfo : m_unitInfo) + { + auto result = make_self>(); + result->Initialize(unitInfo.Unit, unitInfo.PreviouslyInDesiredState, *unitInfo.Result); + unitResults.emplace_back(*result); + } + + return unitResults; } hresult ConfigurationSetApplyProcessor::ResultCode() const @@ -82,6 +91,12 @@ namespace winrt::Microsoft::Management::Configuration::implementation { for (hstring dependencyHstring : unitInfo.Unit.Dependencies()) { + // Throw out empty dependency strings + if (dependencyHstring.empty()) + { + continue; + } + std::string dependency = GetNormalizedIdentifier(dependencyHstring); auto itr = m_idToUnitInfoIndex.find(dependency); if (itr == m_idToUnitInfoIndex.end()) @@ -109,7 +124,13 @@ namespace winrt::Microsoft::Management::Configuration::implementation bool ConfigurationSetApplyProcessor::AddUnitToMap(UnitInfo& unitInfo, size_t unitInfoIndex) { - std::string identifier = GetNormalizedIdentifier(unitInfo.Unit.Identifier()); + hstring originalIdentifier = unitInfo.Unit.Identifier(); + if (originalIdentifier.empty()) + { + return true; + } + + std::string identifier = GetNormalizedIdentifier(originalIdentifier); auto itr = m_idToUnitInfoIndex.find(identifier); if (itr != m_idToUnitInfoIndex.end()) @@ -131,7 +152,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation { // Create the set of units that need to be processed std::vector unitsToProcess; - for (size_t i = 0, size = m_unitInfo.size(); i > size; ++i) + for (size_t i = 0, size = m_unitInfo.size(); i < size; ++i) { unitsToProcess.emplace_back(i); } @@ -281,6 +302,17 @@ namespace winrt::Microsoft::Management::Configuration::implementation { IConfigurationUnitProcessor unitProcessor; + // Once we get this far, consider the unit processed even if we fail to create the actual processor. + unitInfo.Processed = true; + + if (!unitInfo.Unit.ShouldApply()) + { + // If the unit is requested to be skipped, we mark it with a failure to prevent any dependency from running. + // But we return true from this function to indicate a successful "processing". + unitInfo.Result->ResultCode(WINGET_CONFIG_ERROR_MANUALLY_SKIPPED); + return true; + } + try { unitProcessor = m_setProcessor.CreateUnitProcessor(unitInfo.Unit, {}); @@ -302,7 +334,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation return true; } else - { + { unitInfo.Result->ResultCode(WINGET_CONFIG_ERROR_ASSERTION_FAILED); return false; } @@ -316,8 +348,8 @@ namespace winrt::Microsoft::Management::Configuration::implementation case ConfigurationUnitIntent::Apply: { if (unitProcessor.TestSettings()) - { - unitInfo.Result->ResultCode(S_FALSE); + { + unitInfo.PreviouslyInDesiredState = true; return true; } else @@ -326,7 +358,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation return true; } } - default: + default: unitInfo.Result->ResultCode(E_UNEXPECTED); return false; } diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h index 193c28ed8c..2e1e50c9f5 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h +++ b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h @@ -38,6 +38,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation ConfigurationUnit Unit; std::vector DependencyIndices; decltype(make_self>()) Result; + bool PreviouslyInDesiredState = false; bool PreProcessed = false; bool Processed = false; }; diff --git a/src/Microsoft.Management.Configuration/DiagnosticInformation.h b/src/Microsoft.Management.Configuration/DiagnosticInformation.h index 78f6020e9b..0aa1fabb4e 100644 --- a/src/Microsoft.Management.Configuration/DiagnosticInformation.h +++ b/src/Microsoft.Management.Configuration/DiagnosticInformation.h @@ -18,7 +18,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: - DiagnosticLevel m_level; + DiagnosticLevel m_level = DiagnosticLevel::Verbose; hstring m_message; #endif }; diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl index 6c5bc34da1..a74559c6fa 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -433,6 +433,9 @@ namespace Microsoft.Management.Configuration // The configuration unit that was applied. ConfigurationUnit Unit{ get; }; + // Will be true if the configuration unit was in the desired state (Test returns true) prior to the apply action. + Boolean PreviouslyInDesiredState{ get; }; + // The result of applying the configuration unit. ConfigurationUnitResultInformation ResultInformation{ get; }; } diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj index f01e5506bd..aecc286c0f 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -60,6 +60,7 @@ v143 Unicode false + true true From 8c9b00dc1a2d5f06125a886d88ff684e161fa8ca Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Wed, 1 Feb 2023 14:23:05 -0800 Subject: [PATCH 14/31] checkpoint work on tests --- .../Helpers/ConfigurationProcessorTestBase.cs | 17 +- .../Helpers/Errors.cs | 33 ++++ .../Tests/OpenConfigurationSetTests.cs | 164 ++++++++++++++++++ .../ConfigurationProcessor.cpp | 21 +++ .../ConfigurationSetParser.cpp | 1 + 5 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 src/Microsoft.Management.Configuration.UnitTests/Helpers/Errors.cs diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs index 5b8e1df86e..a39a58efb6 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs @@ -1,5 +1,5 @@ // ----------------------------------------------------------------------------- -// +// // Copyright (c) Microsoft Corporation. Licensed under the MIT License. // // ----------------------------------------------------------------------------- @@ -7,6 +7,7 @@ namespace Microsoft.Management.Configuration.UnitTests.Helpers { using Microsoft.Management.Configuration.UnitTests.Fixtures; + using Windows.Storage.Streams; using Xunit.Abstractions; /// @@ -49,5 +50,19 @@ protected ConfigurationProcessor CreateConfigurationProcessorWithDiagnostics(ICo result.Diagnostics += this.diagnosticsEventSink.DiagnosticsHandler; return result; } + + /// + /// Creates an input stream from the given string. + /// + /// The contents that the stream should contain. + /// The created stream. + protected IInputStream CreateStream(string contents) + { + InMemoryRandomAccessStream result = new InMemoryRandomAccessStream(); + DataWriter writer = new DataWriter(result); + writer.WriteString(contents); + result.Seek(0); + return result; + } } } diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/Errors.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/Errors.cs new file mode 100644 index 0000000000..d4d7cd7746 --- /dev/null +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/Errors.cs @@ -0,0 +1,33 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Helpers +{ + /// + /// Contains the error codes used by Microsoft.Management.Configuration + /// + internal static class Errors + { +#pragma warning disable SA1310 // Field names should not contain underscore +#pragma warning disable SA1600 // Elements should be documented +#pragma warning disable SA1025 // Code should not contain multiple whitespace in a row + + public static readonly int WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE = unchecked((int)0x8A15C001); + public static readonly int WINGET_CONFIG_ERROR_INVALID_YAML = unchecked((int)0x8A15C002); + public static readonly int WINGET_CONFIG_ERROR_INVALID_FIELD = unchecked((int)0x8A15C003); + public static readonly int WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION = unchecked((int)0x8A15C004); + public static readonly int WINGET_CONFIG_ERROR_SET_APPLY_FAILED = unchecked((int)0x8A15C005); + public static readonly int WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER = unchecked((int)0x8A15C006); + public static readonly int WINGET_CONFIG_ERROR_MISSING_DEPENDENCY = unchecked((int)0x8A15C007); + public static readonly int WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED = unchecked((int)0x8A15C008); + public static readonly int WINGET_CONFIG_ERROR_ASSERTION_FAILED = unchecked((int)0x8A15C009); + public static readonly int WINGET_CONFIG_ERROR_MANUALLY_SKIPPED = unchecked((int)0x8A15C00A); + +#pragma warning restore SA1025 // Code should not contain multiple whitespace in a row +#pragma warning restore SA1600 // Elements should be documented +#pragma warning restore SA1310 // Field names should not contain underscore + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs index f688560d49..339a9bfab8 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs @@ -7,6 +7,7 @@ namespace Microsoft.Management.Configuration.UnitTests.Tests { using System; + using System.Runtime.InteropServices; using Microsoft.Management.Configuration.UnitTests.Fixtures; using Microsoft.Management.Configuration.UnitTests.Helpers; using Microsoft.VisualBasic; @@ -42,5 +43,168 @@ public void NullStream() Assert.IsType(result.ResultCode); Assert.Equal(string.Empty, result.Field); } + + /// + /// Passes an empty stream as input. + /// + [Fact] + public void EmptyStream() + { + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(); + + OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(string.Empty)); + Assert.Null(result.Set); + Assert.NotNull(result.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_INVALID_YAML, result.ResultCode.HResult); + Assert.Equal(string.Empty, result.Field); + } + + /// + /// Passes a stream with a single null byte in it. + /// + [Fact] + public void NullByteStream() + { + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(); + + OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream("\0")); + Assert.Null(result.Set); + Assert.NotNull(result.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_INVALID_YAML, result.ResultCode.HResult); + Assert.Equal(string.Empty, result.Field); + } + + /// + /// Passes YAML, but it isn't anything like a configuration file. + /// + [Fact] + public void NotConfigYAML() + { + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(); + + OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream("yaml: yep")); + Assert.Null(result.Set); + Assert.NotNull(result.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_INVALID_FIELD, result.ResultCode.HResult); + Assert.NotEqual(string.Empty, result.Field); + } + + /// + /// Passes YAML without a schema version. + /// + [Fact] + public void NoConfigVersion() + { + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(); + + OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@" +properties: + thing: 1 +")); + Assert.Null(result.Set); + Assert.NotNull(result.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_INVALID_FIELD, result.ResultCode.HResult); + Assert.NotEqual(string.Empty, result.Field); + } + + /// + /// Passes YAML that appears to be from the distant future. + /// + [Fact] + public void UnknownConfigVersion() + { + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(); + + OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@" +properties: + configurationVersion: 99999999 +")); + Assert.Null(result.Set); + Assert.NotNull(result.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION, result.ResultCode.HResult); + Assert.Equal(string.Empty, result.Field); + } + + /// + /// Has one of each type of intent to ensure that it is set properly. + /// + [Fact] + public void EnsureIntent() + { + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(); + + OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@" +properties: + assertions: + - resource: Assert + parameters: + - resource: Inform + resources: + - resource: Apply +")); + + Assert.NotNull(result.Set); + Assert.Null(result.ResultCode); + Assert.Equal(string.Empty, result.Field); + + var units = result.Set.ConfigurationUnits; + Assert.Equal(3, units.Count); + bool sawAssert = false; + bool sawInform = false; + bool sawApply = false; + + foreach (var unit in units) + { + Assert.Equal(unit.UnitName, unit.Intent.ToString()); + switch (unit.Intent) + { + case ConfigurationUnitIntent.Assert: sawAssert = true; break; + case ConfigurationUnitIntent.Inform: sawInform = true; break; + case ConfigurationUnitIntent.Apply: sawApply = true; break; + default: Assert.Fail("Unknown intent"); break; + } + } + + Assert.True(sawAssert); + Assert.True(sawInform); + Assert.True(sawApply); + } + + /// + /// Passes YAML with resources being something other than a sequence. + /// + [Fact] + public void NonSequenceUnits() + { + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(); + + OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@" +properties: + resources: 1 +")); + Assert.Null(result.Set); + Assert.NotNull(result.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_INVALID_FIELD, result.ResultCode.HResult); + Assert.NotEqual(string.Empty, result.Field); + } + + /// + /// Passes YAML with a resource being something other than a map. + /// + [Fact] + public void NonMapSequenceUnits() + { + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(); + + OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@" +properties: + resources: + - string +")); + Assert.Null(result.Set); + Assert.NotNull(result.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_INVALID_FIELD, result.ResultCode.HResult); + Assert.NotEqual(string.Empty, result.Field); + } } } diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp index cf047ca7ec..8ccdfa42a3 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp @@ -63,6 +63,26 @@ namespace winrt::Microsoft::Management::Configuration::implementation ConfigurationProcessor& m_processor; }; + // Helper to ensure a one-time callback attach + struct AttachWilFailureCallback + { + AttachWilFailureCallback() + { + wil::SetResultLoggingCallback(wilResultLoggingCallback); + } + + ~AttachWilFailureCallback() = default; + + static void __stdcall wilResultLoggingCallback(const wil::FailureInfo& info) noexcept + { + AICLI_LOG(Fail, Error, << [&]() { + wchar_t message[2048]; + GetFailureLogString(message, ARRAYSIZE(message), info); + return AppInstaller::Utility::ConvertToUTF8(message); + }()); + } + }; + bool ShouldTestDuringTest(ConfigurationUnitIntent intent) { return (intent == ConfigurationUnitIntent::Assert || intent == ConfigurationUnitIntent::Apply); @@ -79,6 +99,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation event_token ConfigurationProcessor::Diagnostics(const Windows::Foundation::EventHandler& handler) { + static AttachWilFailureCallback s_callbackAttach; return m_diagnostics.add(handler); } diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp index 132aa06697..2d237e75e5 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp @@ -91,6 +91,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation void ConfigurationSetParser::SetError(hresult result, std::string_view field) { + AICLI_LOG(Config, Error, << "ConfigurationSetParser error: " << AppInstaller::Logging::SetHRFormat << result << " [" << field << "]"); m_result = result; m_field = AppInstaller::Utility::ConvertToUTF16(field); } From e62961a284f8d79d38cbfef276b40d6de4f4ecc3 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Wed, 1 Feb 2023 17:25:19 -0800 Subject: [PATCH 15/31] Add sync/async functions so as to have both for all processor functionality; add progress to apply and test to enable direct feedback --- .../ConfigurationProcessor.cpp | 170 ++++++++++-------- .../ConfigurationProcessor.h | 37 ++-- .../ConfigurationSetChangeData.h | 3 + .../Microsoft.Management.Configuration.idl | 20 ++- src/Microsoft.Management.Configuration/pch.h | 1 + 5 files changed, 136 insertions(+), 95 deletions(-) diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp index 8ccdfa42a3..505e888ed3 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp @@ -14,6 +14,7 @@ #include "ConfigurationUnitResultInformation.h" #include "GetConfigurationUnitSettingsResult.h" #include "ExceptionResultHelpers.h" +#include "ConfigurationSetChangeData.h" #include #include @@ -123,6 +124,11 @@ namespace winrt::Microsoft::Management::Configuration::implementation THROW_HR(E_NOTIMPL); } + Windows::Foundation::IAsyncOperation> ConfigurationProcessor::GetConfigurationHistoryAsync() + { + co_return GetConfigurationHistory(); + } + Configuration::OpenConfigurationSetResult ConfigurationProcessor::OpenConfigurationSet(Windows::Storage::Streams::IInputStream stream) { auto threadGlobals = m_threadGlobals.SetForCurrentThread(); @@ -167,81 +173,136 @@ namespace winrt::Microsoft::Management::Configuration::implementation return *result; } - Windows::Foundation::IAsyncOperation> ConfigurationProcessor::CheckForConflictsAsync( + Windows::Foundation::IAsyncOperation ConfigurationProcessor::OpenConfigurationSetAsync(Windows::Storage::Streams::IInputStream stream) + { + co_return OpenConfigurationSet(stream); + } + + Windows::Foundation::Collections::IVector ConfigurationProcessor::CheckForConflicts( + const Windows::Foundation::Collections::IVectorView& configurationSets, + bool includeConfigurationHistory) + { + UNREFERENCED_PARAMETER(configurationSets); + UNREFERENCED_PARAMETER(includeConfigurationHistory); + THROW_HR(E_NOTIMPL); + } + + Windows::Foundation::IAsyncOperation> ConfigurationProcessor::CheckForConflictsAsync( const Windows::Foundation::Collections::IVectorView& configurationSets, bool includeConfigurationHistory) { co_return CheckForConflicts(configurationSets, includeConfigurationHistory); } + void ConfigurationProcessor::GetSetDetails(const ConfigurationSet& configurationSet, ConfigurationUnitDetailLevel detailLevel) + { + auto threadGlobals = m_threadGlobals.SetForCurrentThread(); + + THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); + + IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(configurationSet); + + for (const auto& unit : configurationSet.ConfigurationUnits()) + { + IConfigurationUnitProcessorDetails details = setProcessor.GetUnitProcessorDetails(unit, detailLevel); + get_self(unit)->Details(std::move(details)); + } + } + Windows::Foundation::IAsyncAction ConfigurationProcessor::GetSetDetailsAsync(const ConfigurationSet& configurationSet, ConfigurationUnitDetailLevel detailLevel) { co_return GetSetDetails(configurationSet, detailLevel); } - Windows::Foundation::IAsyncAction ConfigurationProcessor::GetUnitDetailsAsync(const ConfigurationUnit& unit, ConfigurationUnitDetailLevel detailLevel) + void ConfigurationProcessor::GetUnitDetails(const ConfigurationUnit& unit, ConfigurationUnitDetailLevel detailLevel) { - co_return GetUnitDetails(unit, detailLevel); + auto threadGlobals = m_threadGlobals.SetForCurrentThread(); + + THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); + + IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr); + IConfigurationUnitProcessorDetails details = setProcessor.GetUnitProcessorDetails(unit, detailLevel); + get_self(unit)->Details(std::move(details)); } - Windows::Foundation::IAsyncOperation ConfigurationProcessor::ApplyAsync(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags) + Windows::Foundation::IAsyncAction ConfigurationProcessor::GetUnitDetailsAsync(const ConfigurationUnit& unit, ConfigurationUnitDetailLevel detailLevel) { - co_return Apply(configurationSet, flags); + co_return GetUnitDetails(unit, detailLevel); } - Windows::Foundation::IAsyncOperation ConfigurationProcessor::TestAsync(const ConfigurationSet& configurationSet) + Configuration::ApplyConfigurationSetResult ConfigurationProcessor::ApplySet(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags) { - co_return Test(configurationSet); + return ApplySetInternal(configurationSet, flags, {}); } - Windows::Foundation::IAsyncOperation ConfigurationProcessor::GetSettingsAsync(const ConfigurationUnit& unit) + Windows::Foundation::IAsyncOperationWithProgress ConfigurationProcessor::ApplySetAsync(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags) { - co_return GetSettings(unit); + auto progress = co_await winrt::get_progress_token(); + co_return ApplySetInternal(configurationSet, flags, progress); } - void ConfigurationProcessor::Diagnostics(DiagnosticLevel level, std::string_view message) + Configuration::TestConfigurationSetResult ConfigurationProcessor::TestSet(const ConfigurationSet& configurationSet) { - auto diagnostics = make_self>(); - diagnostics->Initialize(level, AppInstaller::Utility::ConvertToUTF16(message)); - m_diagnostics(*this, *diagnostics); + return TestSetInternal(configurationSet, {}); } - Windows::Foundation::Collections::IVectorView ConfigurationProcessor::CheckForConflicts( - const Windows::Foundation::Collections::IVectorView& configurationSets, - bool includeConfigurationHistory) + Windows::Foundation::IAsyncOperationWithProgress ConfigurationProcessor::TestSetAsync(const ConfigurationSet& configurationSet) { - UNREFERENCED_PARAMETER(configurationSets); - UNREFERENCED_PARAMETER(includeConfigurationHistory); - THROW_HR(E_NOTIMPL); + auto progress = co_await winrt::get_progress_token(); + co_return TestSetInternal(configurationSet, progress); } - void ConfigurationProcessor::GetSetDetails(const ConfigurationSet& configurationSet, ConfigurationUnitDetailLevel detailLevel) + Configuration::GetConfigurationUnitSettingsResult ConfigurationProcessor::GetUnitSettings(const ConfigurationUnit& unit) { auto threadGlobals = m_threadGlobals.SetForCurrentThread(); THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); - IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(configurationSet); + IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr); + auto result = make_self>(); + auto unitResult = make_self>(); + result->Initialize(*unitResult); - for (const auto& unit : configurationSet.ConfigurationUnits()) + IConfigurationUnitProcessor unitProcessor; + + try { - IConfigurationUnitProcessorDetails details = setProcessor.GetUnitProcessorDetails(unit, detailLevel); - get_self(unit)->Details(std::move(details)); + // TODO: Directives overlay to prevent running elevated for get + unitProcessor = setProcessor.CreateUnitProcessor(unit, {}); } + catch (...) + { + ExtractUnitResultInformation(std::current_exception(), unitResult, setProcessor); + } + + if (unitProcessor) + { + try + { + result->Settings(unitProcessor.GetSettings()); + } + catch (...) + { + ExtractUnitResultInformation(std::current_exception(), unitResult, unitProcessor); + } + } + + return *result; } - void ConfigurationProcessor::GetUnitDetails(const ConfigurationUnit& unit, ConfigurationUnitDetailLevel detailLevel) + Windows::Foundation::IAsyncOperation ConfigurationProcessor::GetUnitSettingsAsync(const ConfigurationUnit& unit) { - auto threadGlobals = m_threadGlobals.SetForCurrentThread(); - - THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); + co_return GetUnitSettings(unit); + } - IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr); - IConfigurationUnitProcessorDetails details = setProcessor.GetUnitProcessorDetails(unit, detailLevel); - get_self(unit)->Details(std::move(details)); + void ConfigurationProcessor::Diagnostics(DiagnosticLevel level, std::string_view message) + { + auto diagnostics = make_self>(); + diagnostics->Initialize(level, AppInstaller::Utility::ConvertToUTF16(message)); + m_diagnostics(*this, *diagnostics); } - Configuration::ApplyConfigurationSetResult ConfigurationProcessor::Apply(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags) + Configuration::ApplyConfigurationSetResult ConfigurationProcessor::ApplySetInternal(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags, const std::function& progress) { // TODO: Not needed until we have history implemented UNREFERENCED_PARAMETER(flags); @@ -250,6 +311,8 @@ namespace winrt::Microsoft::Management::Configuration::implementation THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); + // TODO: progress passed in here and used + UNREFERENCED_PARAMETER(progress); ConfigurationSetApplyProcessor applyProcessor{ configurationSet, m_factory.CreateSetProcessor(configurationSet) }; applyProcessor.Process(); @@ -258,7 +321,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation return *result; } - Configuration::TestConfigurationSetResult ConfigurationProcessor::Test(const ConfigurationSet& configurationSet) + Configuration::TestConfigurationSetResult ConfigurationProcessor::TestSetInternal(const ConfigurationSet& configurationSet, const std::function& progress) { auto threadGlobals = m_threadGlobals.SetForCurrentThread(); @@ -268,6 +331,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation auto result = make_self>(); bool overallResult = true; + // TODO: Use progress here and below + UNREFERENCED_PARAMETER(progress); + for (const auto& unit : configurationSet.ConfigurationUnits()) { auto testResult = make_self>(); @@ -313,42 +379,4 @@ namespace winrt::Microsoft::Management::Configuration::implementation result->TestResult(overallResult); return *result; } - - Configuration::GetConfigurationUnitSettingsResult ConfigurationProcessor::GetSettings(const ConfigurationUnit& unit) - { - auto threadGlobals = m_threadGlobals.SetForCurrentThread(); - - THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); - - IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr); - auto result = make_self>(); - auto unitResult = make_self>(); - result->Initialize(*unitResult); - - IConfigurationUnitProcessor unitProcessor; - - try - { - // TODO: Directives overlay to prevent running elevated for get - unitProcessor = setProcessor.CreateUnitProcessor(unit, {}); - } - catch (...) - { - ExtractUnitResultInformation(std::current_exception(), unitResult, setProcessor); - } - - if (unitProcessor) - { - try - { - result->Settings(unitProcessor.GetSettings()); - } - catch (...) - { - ExtractUnitResultInformation(std::current_exception(), unitResult, unitProcessor); - } - } - - return *result; - } } diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.h b/src/Microsoft.Management.Configuration/ConfigurationProcessor.h index 7765e2319c..3dda64d915 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationProcessor.h +++ b/src/Microsoft.Management.Configuration/ConfigurationProcessor.h @@ -8,12 +8,14 @@ #include "ConfigThreadGlobals.h" #include +#include namespace winrt::Microsoft::Management::Configuration::implementation { struct ConfigurationProcessor : ConfigurationProcessorT { using ConfigurationSet = Configuration::ConfigurationSet; + using ConfigurationSetChangeData = Configuration::ConfigurationSetChangeData; using ConfigurationUnit = Configuration::ConfigurationUnit; using DiagnosticInformation = Configuration::DiagnosticInformation; using ApplyConfigurationSetResult = Configuration::ApplyConfigurationSetResult; @@ -29,42 +31,41 @@ namespace winrt::Microsoft::Management::Configuration::implementation void ConfigurationChange(const event_token& token) noexcept; Windows::Foundation::Collections::IVector GetConfigurationHistory(); + Windows::Foundation::IAsyncOperation> GetConfigurationHistoryAsync(); Configuration::OpenConfigurationSetResult OpenConfigurationSet(Windows::Storage::Streams::IInputStream stream); + Windows::Foundation::IAsyncOperation OpenConfigurationSetAsync(Windows::Storage::Streams::IInputStream stream); - Windows::Foundation::IAsyncOperation> CheckForConflictsAsync( + Windows::Foundation::Collections::IVector CheckForConflicts( + const Windows::Foundation::Collections::IVectorView& configurationSets, + bool includeConfigurationHistory); + Windows::Foundation::IAsyncOperation> CheckForConflictsAsync( const Windows::Foundation::Collections::IVectorView& configurationSets, bool includeConfigurationHistory); + void GetSetDetails(const ConfigurationSet& configurationSet, ConfigurationUnitDetailLevel detailLevel); Windows::Foundation::IAsyncAction GetSetDetailsAsync(const ConfigurationSet& configurationSet, ConfigurationUnitDetailLevel detailLevel); + void GetUnitDetails(const ConfigurationUnit& unit, ConfigurationUnitDetailLevel detailLevel); Windows::Foundation::IAsyncAction GetUnitDetailsAsync(const ConfigurationUnit& unit, ConfigurationUnitDetailLevel detailLevel); - Windows::Foundation::IAsyncOperation ApplyAsync(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags); + ApplyConfigurationSetResult ApplySet(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags); + Windows::Foundation::IAsyncOperationWithProgress ApplySetAsync(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags); - Windows::Foundation::IAsyncOperation TestAsync(const ConfigurationSet& configurationSet); + TestConfigurationSetResult TestSet(const ConfigurationSet& configurationSet); + Windows::Foundation::IAsyncOperationWithProgress TestSetAsync(const ConfigurationSet& configurationSet); - Windows::Foundation::IAsyncOperation GetSettingsAsync(const ConfigurationUnit& unit); + GetConfigurationUnitSettingsResult GetUnitSettings(const ConfigurationUnit& unit); + Windows::Foundation::IAsyncOperation GetUnitSettingsAsync(const ConfigurationUnit& unit); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) // Sends diagnostics objects to the event. void Diagnostics(DiagnosticLevel level, std::string_view message); - Windows::Foundation::Collections::IVectorView CheckForConflicts( - const Windows::Foundation::Collections::IVectorView& configurationSets, - bool includeConfigurationHistory); - - void GetSetDetails(const ConfigurationSet& configurationSet, ConfigurationUnitDetailLevel detailLevel); - - void GetUnitDetails(const ConfigurationUnit& unit, ConfigurationUnitDetailLevel detailLevel); - - ApplyConfigurationSetResult Apply(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags); - - TestConfigurationSetResult Test(const ConfigurationSet& configurationSet); - - GetConfigurationUnitSettingsResult GetSettings(const ConfigurationUnit& unit); - private: + ApplyConfigurationSetResult ApplySetInternal(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags, const std::function& progress); + TestConfigurationSetResult TestSetInternal(const ConfigurationSet& configurationSet, const std::function& progress); + IConfigurationProcessorFactory m_factory = nullptr; event> m_diagnostics; event> m_configurationChange; diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.h b/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.h index c0ec719888..b4a2480429 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.h +++ b/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.h @@ -7,6 +7,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation { struct ConfigurationSetChangeData : ConfigurationSetChangeDataT { + using ConfigurationUnit = Configuration::ConfigurationUnit; + using ConfigurationUnitResultInformation = Configuration::ConfigurationUnitResultInformation; + ConfigurationSetChangeData() = default; #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl index a74559c6fa..48812d66fe 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -505,26 +505,34 @@ namespace Microsoft.Management.Configuration // Gets the configuration sets that have already been applied or the intent to be applied (this may include in progress sets or those that are waiting on others). // These configuration sets will be marked as immutable. Windows.Foundation.Collections.IVector GetConfigurationHistory(); + Windows.Foundation.IAsyncOperation< Windows.Foundation.Collections.IVector > GetConfigurationHistoryAsync(); // Loads a mutable configuration set from the given stream. OpenConfigurationSetResult OpenConfigurationSet(Windows.Storage.Streams.IInputStream stream); + Windows.Foundation.IAsyncOperation OpenConfigurationSetAsync(Windows.Storage.Streams.IInputStream stream); // Checks for conflicts amongst the configuration sets provided, optionally including the configuration sets already applied to the system. - Windows.Foundation.IAsyncOperation< Windows.Foundation.Collections.IVectorView > CheckForConflictsAsync(Windows.Foundation.Collections.IVectorView configurationSets, Boolean includeConfigurationHistory); + Windows.Foundation.Collections.IVector CheckForConflicts(Windows.Foundation.Collections.IVectorView configurationSets, Boolean includeConfigurationHistory); + Windows.Foundation.IAsyncOperation< Windows.Foundation.Collections.IVector > CheckForConflictsAsync(Windows.Foundation.Collections.IVectorView configurationSets, Boolean includeConfigurationHistory); // Gets the details for all configuration units in a set. + void GetSetDetails(ConfigurationSet configurationSet, ConfigurationUnitDetailLevel detailLevel); Windows.Foundation.IAsyncAction GetSetDetailsAsync(ConfigurationSet configurationSet, ConfigurationUnitDetailLevel detailLevel); // Gets the details for a configuration unit. + void GetUnitDetails(ConfigurationUnit unit, ConfigurationUnitDetailLevel detailLevel); Windows.Foundation.IAsyncAction GetUnitDetailsAsync(ConfigurationUnit unit, ConfigurationUnitDetailLevel detailLevel); - // Applies the configuration set state; to get progress, subscribe to the ConfigurationSetChange before calling this method. - Windows.Foundation.IAsyncOperation ApplyAsync(ConfigurationSet configurationSet, ApplyConfigurationSetFlags flags); + // Applies the configuration set state. + ApplyConfigurationSetResult ApplySet(ConfigurationSet configurationSet, ApplyConfigurationSetFlags flags); + Windows.Foundation.IAsyncOperationWithProgress ApplySetAsync(ConfigurationSet configurationSet, ApplyConfigurationSetFlags flags); - // Tests the configuration set state; to get progress, subscribe to the ConfigurationSetChange before calling this method. - Windows.Foundation.IAsyncOperation TestAsync(ConfigurationSet configurationSet); + // Tests the configuration set state. + TestConfigurationSetResult TestSet(ConfigurationSet configurationSet); + Windows.Foundation.IAsyncOperationWithProgress TestSetAsync(ConfigurationSet configurationSet); // Gets the current configuration unit settings. - Windows.Foundation.IAsyncOperation GetSettingsAsync(ConfigurationUnit unit); + GetConfigurationUnitSettingsResult GetUnitSettings(ConfigurationUnit unit); + Windows.Foundation.IAsyncOperation GetUnitSettingsAsync(ConfigurationUnit unit); } } diff --git a/src/Microsoft.Management.Configuration/pch.h b/src/Microsoft.Management.Configuration/pch.h index c827de4ea8..7044cf6098 100644 --- a/src/Microsoft.Management.Configuration/pch.h +++ b/src/Microsoft.Management.Configuration/pch.h @@ -17,6 +17,7 @@ #include #include +#include #include #include #include From 3ab4b03a38b8bb3ce674f828cc9ece1b9eef1f1c Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Thu, 2 Feb 2023 17:52:29 -0800 Subject: [PATCH 16/31] Change unit processor output to enable differentiating errors from unit processor infra and processor itself. Implement progress callbacks --- .../ApplySettingsResult.cpp | 19 +++ .../ApplySettingsResult.h | 24 ++++ .../ConfigurationProcessor.cpp | 49 ++++--- .../ConfigurationProcessor.h | 5 +- .../ConfigurationSetApplyProcessor.cpp | 131 +++++++++++++++--- .../ConfigurationSetApplyProcessor.h | 18 ++- .../ConfigurationSetChangeData.cpp | 79 +++++++---- .../ConfigurationSetChangeData.h | 16 ++- .../ConfigurationUnitResultInformation.cpp | 5 + .../ConfigurationUnitResultInformation.h | 4 +- .../ExceptionResultHelpers.h | 9 +- .../GetConfigurationUnitSettingsResult.cpp | 2 +- .../GetConfigurationUnitSettingsResult.h | 2 +- .../GetSettingsResult.cpp | 24 ++++ .../GetSettingsResult.h | 26 ++++ .../Microsoft.Management.Configuration.idl | 101 ++++++++++---- ...Microsoft.Management.Configuration.vcxproj | 8 +- ...t.Management.Configuration.vcxproj.filters | 18 +++ .../TestConfigurationSetResult.cpp | 33 ++++- .../TestConfigurationSetResult.h | 6 +- .../TestConfigurationUnitResult.cpp | 9 +- .../TestConfigurationUnitResult.h | 7 +- .../TestSettingsResult.cpp | 29 ++++ .../TestSettingsResult.h | 28 ++++ src/Microsoft.Management.Configuration/pch.h | 4 +- 25 files changed, 533 insertions(+), 123 deletions(-) create mode 100644 src/Microsoft.Management.Configuration/ApplySettingsResult.cpp create mode 100644 src/Microsoft.Management.Configuration/ApplySettingsResult.h create mode 100644 src/Microsoft.Management.Configuration/GetSettingsResult.cpp create mode 100644 src/Microsoft.Management.Configuration/GetSettingsResult.h create mode 100644 src/Microsoft.Management.Configuration/TestSettingsResult.cpp create mode 100644 src/Microsoft.Management.Configuration/TestSettingsResult.h diff --git a/src/Microsoft.Management.Configuration/ApplySettingsResult.cpp b/src/Microsoft.Management.Configuration/ApplySettingsResult.cpp new file mode 100644 index 0000000000..3e1b8fbc97 --- /dev/null +++ b/src/Microsoft.Management.Configuration/ApplySettingsResult.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ApplySettingsResult.h" +#include "ApplySettingsResult.g.cpp" +#include "ConfigurationUnitResultInformation.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + ApplySettingsResult::ApplySettingsResult() : + m_resultInformation(*make_self>()) + { + } + + Configuration::ConfigurationUnitResultInformation ApplySettingsResult::ResultInformation() + { + return m_resultInformation; + } +} diff --git a/src/Microsoft.Management.Configuration/ApplySettingsResult.h b/src/Microsoft.Management.Configuration/ApplySettingsResult.h new file mode 100644 index 0000000000..baa08d50da --- /dev/null +++ b/src/Microsoft.Management.Configuration/ApplySettingsResult.h @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "ApplySettingsResult.g.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct ApplySettingsResult : ApplySettingsResultT + { + ApplySettingsResult(); + + Configuration::ConfigurationUnitResultInformation ResultInformation(); + + private: + Configuration::ConfigurationUnitResultInformation m_resultInformation; + }; +} + +namespace winrt::Microsoft::Management::Configuration::factory_implementation +{ + struct ApplySettingsResult : ApplySettingsResultT + { + }; +} diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp index 505e888ed3..1819456b2f 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp @@ -84,6 +84,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation } }; + // Specifies the set of intents that should execute during a Test request bool ShouldTestDuringTest(ConfigurationUnitIntent intent) { return (intent == ConfigurationUnitIntent::Assert || intent == ConfigurationUnitIntent::Apply); @@ -246,7 +247,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation return TestSetInternal(configurationSet, {}); } - Windows::Foundation::IAsyncOperationWithProgress ConfigurationProcessor::TestSetAsync(const ConfigurationSet& configurationSet) + Windows::Foundation::IAsyncOperationWithProgress ConfigurationProcessor::TestSetAsync(const ConfigurationSet& configurationSet) { auto progress = co_await winrt::get_progress_token(); co_return TestSetInternal(configurationSet, progress); @@ -261,7 +262,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr); auto result = make_self>(); auto unitResult = make_self>(); - result->Initialize(*unitResult); + result->ResultInformation(*unitResult); IConfigurationUnitProcessor unitProcessor; @@ -272,18 +273,20 @@ namespace winrt::Microsoft::Management::Configuration::implementation } catch (...) { - ExtractUnitResultInformation(std::current_exception(), unitResult, setProcessor); + ExtractUnitResultInformation(std::current_exception(), unitResult); } if (unitProcessor) { try { - result->Settings(unitProcessor.GetSettings()); + GetSettingsResult settingsResult = unitProcessor.GetSettings(); + result->Settings(settingsResult.Settings()); + result->ResultInformation(settingsResult.ResultInformation()); } catch (...) { - ExtractUnitResultInformation(std::current_exception(), unitResult, unitProcessor); + ExtractUnitResultInformation(std::current_exception(), unitResult); } } @@ -311,9 +314,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); - // TODO: progress passed in here and used - UNREFERENCED_PARAMETER(progress); - ConfigurationSetApplyProcessor applyProcessor{ configurationSet, m_factory.CreateSetProcessor(configurationSet) }; + ConfigurationSetApplyProcessor applyProcessor{ configurationSet, m_factory.CreateSetProcessor(configurationSet), progress }; applyProcessor.Process(); auto result = make_self>(); @@ -321,7 +322,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation return *result; } - Configuration::TestConfigurationSetResult ConfigurationProcessor::TestSetInternal(const ConfigurationSet& configurationSet, const std::function& progress) + Configuration::TestConfigurationSetResult ConfigurationProcessor::TestSetInternal(const ConfigurationSet& configurationSet, const std::function& progress) { auto threadGlobals = m_threadGlobals.SetForCurrentThread(); @@ -329,13 +330,12 @@ namespace winrt::Microsoft::Management::Configuration::implementation IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(configurationSet); auto result = make_self>(); - bool overallResult = true; - - // TODO: Use progress here and below - UNREFERENCED_PARAMETER(progress); + result->TestResult(ConfigurationTestResult::NotRun); for (const auto& unit : configurationSet.ConfigurationUnits()) { + AICLI_LOG(Config, Info, << "Testing configuration unit: " << AppInstaller::Utility::ConvertToUTF8(unit.UnitName())); + auto testResult = make_self>(); auto unitResult = make_self>(); testResult->Initialize(unit, *unitResult); @@ -351,32 +351,41 @@ namespace winrt::Microsoft::Management::Configuration::implementation } catch (...) { - ExtractUnitResultInformation(std::current_exception(), unitResult, setProcessor); + ExtractUnitResultInformation(std::current_exception(), unitResult); } if (unitProcessor) { try { - bool unitTestResult = unitProcessor.TestSettings(); - overallResult = overallResult && unitTestResult; - testResult->TestResult(unitTestResult); + TestSettingsResult settingsResult = unitProcessor.TestSettings(); + testResult->TestResult(settingsResult.TestResult()); + testResult->ResultInformation(settingsResult.ResultInformation()); } catch (...) { - ExtractUnitResultInformation(std::current_exception(), unitResult, unitProcessor); + ExtractUnitResultInformation(std::current_exception(), unitResult); } } } else { - unitResult->ResultCode(S_FALSE); + testResult->TestResult(ConfigurationTestResult::NotRun); + } + + if (FAILED(unitResult->ResultCode())) + { + testResult->TestResult(ConfigurationTestResult::Failed); + } + + if (progress) + { + progress(*testResult); } result->AppendUnitResult(*testResult); } - result->TestResult(overallResult); return *result; } } diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.h b/src/Microsoft.Management.Configuration/ConfigurationProcessor.h index 3dda64d915..1aabfcf4f3 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationProcessor.h +++ b/src/Microsoft.Management.Configuration/ConfigurationProcessor.h @@ -20,6 +20,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation using DiagnosticInformation = Configuration::DiagnosticInformation; using ApplyConfigurationSetResult = Configuration::ApplyConfigurationSetResult; using TestConfigurationSetResult = Configuration::TestConfigurationSetResult; + using TestConfigurationUnitResult = Configuration::TestConfigurationUnitResult; using GetConfigurationUnitSettingsResult = Configuration::GetConfigurationUnitSettingsResult; ConfigurationProcessor(const IConfigurationProcessorFactory& factory); @@ -53,7 +54,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation Windows::Foundation::IAsyncOperationWithProgress ApplySetAsync(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags); TestConfigurationSetResult TestSet(const ConfigurationSet& configurationSet); - Windows::Foundation::IAsyncOperationWithProgress TestSetAsync(const ConfigurationSet& configurationSet); + Windows::Foundation::IAsyncOperationWithProgress TestSetAsync(const ConfigurationSet& configurationSet); GetConfigurationUnitSettingsResult GetUnitSettings(const ConfigurationUnit& unit); Windows::Foundation::IAsyncOperation GetUnitSettingsAsync(const ConfigurationUnit& unit); @@ -64,7 +65,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation private: ApplyConfigurationSetResult ApplySetInternal(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags, const std::function& progress); - TestConfigurationSetResult TestSetInternal(const ConfigurationSet& configurationSet, const std::function& progress); + TestConfigurationSetResult TestSetInternal(const ConfigurationSet& configurationSet, const std::function& progress); IConfigurationProcessorFactory m_factory = nullptr; event> m_diagnostics; diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp index e93e8c3b9e..e6c0a7044e 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp @@ -2,6 +2,7 @@ // Licensed under the MIT License. #include "pch.h" #include "ConfigurationSetApplyProcessor.h" +#include "ConfigurationSetChangeData.h" #include "ExceptionResultHelpers.h" #include @@ -19,8 +20,8 @@ namespace winrt::Microsoft::Management::Configuration::implementation } } - ConfigurationSetApplyProcessor::ConfigurationSetApplyProcessor(const Configuration::ConfigurationSet& configurationSet, IConfigurationSetProcessor&& setProcessor) : - m_setProcessor(std::move(setProcessor)) + ConfigurationSetApplyProcessor::ConfigurationSetApplyProcessor(const Configuration::ConfigurationSet& configurationSet, IConfigurationSetProcessor&& setProcessor, const std::function& progress) : + m_setProcessor(std::move(setProcessor)), m_progress(progress) { // Create a copy of the set of configuration units auto unitsView = configurationSet.ConfigurationUnits(); @@ -41,7 +42,12 @@ namespace winrt::Microsoft::Management::Configuration::implementation return; } - ProcessInternal(HasProcessedSuccessfully, &ConfigurationSetApplyProcessor::ProcessUnit); + // TODO: When cross process is implemented, send Pending until we actually start + SendProgress(ConfigurationSetState::InProgress); + + ProcessInternal(HasProcessedSuccessfully, &ConfigurationSetApplyProcessor::ProcessUnit, true); + + SendProgress(ConfigurationSetState::Completed); } std::vector ConfigurationSetApplyProcessor::GetUnitResults() const @@ -64,7 +70,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation } ConfigurationSetApplyProcessor::UnitInfo::UnitInfo(const Configuration::ConfigurationUnit& unit) : - Unit(unit), Result(make_self>()) + Unit(unit), Result(make_self>()) { } @@ -148,7 +154,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation } } - bool ConfigurationSetApplyProcessor::ProcessInternal(CheckDependencyPtr checkDependencyFunction, ProcessUnitPtr processUnitFunction) + bool ConfigurationSetApplyProcessor::ProcessInternal(CheckDependencyPtr checkDependencyFunction, ProcessUnitPtr processUnitFunction, bool sendProgress) { // Create the set of units that need to be processed std::vector unitsToProcess; @@ -164,7 +170,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation processUnitFunction, ConfigurationUnitIntent::Assert, WINGET_CONFIG_ERROR_ASSERTION_FAILED, - WINGET_CONFIG_ERROR_ASSERTION_FAILED)) + ConfigurationUnitState::SkippedDueToAssertions, + WINGET_CONFIG_ERROR_ASSERTION_FAILED, + sendProgress)) { return false; } @@ -176,7 +184,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation processUnitFunction, ConfigurationUnitIntent::Inform, WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED, - WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED)) + ConfigurationUnitState::SkippedDueToDependencies, + WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED, + sendProgress)) { return false; } @@ -188,7 +198,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation processUnitFunction, ConfigurationUnitIntent::Apply, E_FAIL, // This should not happen as there are no other intents left - WINGET_CONFIG_ERROR_SET_APPLY_FAILED); + ConfigurationUnitState::Unknown, + WINGET_CONFIG_ERROR_SET_APPLY_FAILED, + sendProgress); } bool ConfigurationSetApplyProcessor::ProcessIntentInternal( @@ -197,7 +209,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation ProcessUnitPtr processUnitFunction, ConfigurationUnitIntent intent, hresult errorForOtherIntents, - hresult errorForFailures) + ConfigurationUnitState progressForOtherIntents, + hresult errorForFailures, + bool sendProgress) { // Always process the first item in the list that is available to be processed bool hasProcessed = true; @@ -230,6 +244,10 @@ namespace winrt::Microsoft::Management::Configuration::implementation { hasRemainingDependencies = true; unitInfo.Result->ResultCode(WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED); + if (sendProgress) + { + SendProgress(ConfigurationUnitState::SkippedDueToDependencies, unitInfo); + } } } @@ -242,6 +260,10 @@ namespace winrt::Microsoft::Management::Configuration::implementation if (unitInfo.Unit.Intent() != intent) { unitInfo.Result->ResultCode(errorForOtherIntents); + if (sendProgress) + { + SendProgress(progressForOtherIntents, unitInfo); + } } } @@ -310,16 +332,21 @@ namespace winrt::Microsoft::Management::Configuration::implementation // If the unit is requested to be skipped, we mark it with a failure to prevent any dependency from running. // But we return true from this function to indicate a successful "processing". unitInfo.Result->ResultCode(WINGET_CONFIG_ERROR_MANUALLY_SKIPPED); + SendProgress(ConfigurationUnitState::SkippedManually, unitInfo); return true; } + // Send a progress event that we are starting, and prepare one for completion when we exit the function + SendProgress(ConfigurationUnitState::InProgress, unitInfo); + auto sendCompletedProgress = wil::scope_exit([this, &unitInfo]() { SendProgress(ConfigurationUnitState::Completed, unitInfo); }); + try { unitProcessor = m_setProcessor.CreateUnitProcessor(unitInfo.Unit, {}); } catch (...) { - ExtractUnitResultInformation(std::current_exception(), unitInfo.Result, m_setProcessor); + ExtractUnitResultInformation(std::current_exception(), unitInfo.Result); return false; } @@ -329,33 +356,77 @@ namespace winrt::Microsoft::Management::Configuration::implementation { case ConfigurationUnitIntent::Assert: { - if (unitProcessor.TestSettings()) + TestSettingsResult settingsResult = unitProcessor.TestSettings(); + + if (settingsResult.TestResult() == ConfigurationTestResult::Positive) { return true; } - else + else if (settingsResult.TestResult() == ConfigurationTestResult::Negative) { unitInfo.Result->ResultCode(WINGET_CONFIG_ERROR_ASSERTION_FAILED); return false; } + else if (settingsResult.TestResult() == ConfigurationTestResult::Failed) + { + unitInfo.Result->ResultCode(settingsResult.ResultInformation().ResultCode()); + unitInfo.Result->Description(settingsResult.ResultInformation().Description()); + return false; + } + else + { + unitInfo.Result->ResultCode(E_UNEXPECTED); + return false; + } } case ConfigurationUnitIntent::Inform: { // Force the processor to retrieve the settings - std::ignore = unitProcessor.GetSettings(); - return true; + GetSettingsResult settingsResult = unitProcessor.GetSettings(); + if (SUCCEEDED(settingsResult.ResultInformation().ResultCode())) + { + return true; + } + else + { + unitInfo.Result->ResultCode(settingsResult.ResultInformation().ResultCode()); + unitInfo.Result->Description(settingsResult.ResultInformation().Description()); + return false; + } } case ConfigurationUnitIntent::Apply: { - if (unitProcessor.TestSettings()) + TestSettingsResult testSettingsResult = unitProcessor.TestSettings(); + + if (testSettingsResult.TestResult() == ConfigurationTestResult::Positive) { unitInfo.PreviouslyInDesiredState = true; return true; } + else if (testSettingsResult.TestResult() == ConfigurationTestResult::Negative) + { + ApplySettingsResult applySettingsResult = unitProcessor.ApplySettings(); + if (SUCCEEDED(applySettingsResult.ResultInformation().ResultCode())) + { + return true; + } + else + { + unitInfo.Result->ResultCode(applySettingsResult.ResultInformation().ResultCode()); + unitInfo.Result->Description(applySettingsResult.ResultInformation().Description()); + return false; + } + } + else if (testSettingsResult.TestResult() == ConfigurationTestResult::Failed) + { + unitInfo.Result->ResultCode(testSettingsResult.ResultInformation().ResultCode()); + unitInfo.Result->Description(testSettingsResult.ResultInformation().Description()); + return false; + } else { - unitProcessor.ApplySettings(); - return true; + unitInfo.Result->ResultCode(E_UNEXPECTED); + return false; } } default: @@ -365,8 +436,32 @@ namespace winrt::Microsoft::Management::Configuration::implementation } catch (...) { - ExtractUnitResultInformation(std::current_exception(), unitInfo.Result, unitProcessor); + ExtractUnitResultInformation(std::current_exception(), unitInfo.Result); return false; } } + + void ConfigurationSetApplyProcessor::SendProgress(ConfigurationSetState state) + { + if (m_progress) + { + try + { + m_progress(implementation::ConfigurationSetChangeData::Create(state)); + } + CATCH_LOG(); + } + } + + void ConfigurationSetApplyProcessor::SendProgress(ConfigurationUnitState state, const UnitInfo& unitInfo) + { + if (m_progress) + { + try + { + m_progress(implementation::ConfigurationSetChangeData::Create(state, *unitInfo.Result, unitInfo.Unit)); + } + CATCH_LOG(); + } + } } diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h index 2e1e50c9f5..4f20751f0c 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h +++ b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h @@ -17,8 +17,10 @@ namespace winrt::Microsoft::Management::Configuration::implementation { using ConfigurationSet = Configuration::ConfigurationSet; using ConfigurationUnit = Configuration::ConfigurationUnit; + using ConfigurationUnitResultInformation = Configuration::ConfigurationUnitResultInformation; + using ConfigurationSetChangeData = Configuration::ConfigurationSetChangeData; - ConfigurationSetApplyProcessor(const ConfigurationSet& configurationSet, IConfigurationSetProcessor&& setProcessor); + ConfigurationSetApplyProcessor(const ConfigurationSet& configurationSet, IConfigurationSetProcessor&& setProcessor, const std::function& progress); // Processes the apply for the configuration set. void Process(); @@ -37,7 +39,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation ConfigurationUnit Unit; std::vector DependencyIndices; - decltype(make_self>()) Result; + decltype(make_self>()) Result; bool PreviouslyInDesiredState = false; bool PreProcessed = false; bool Processed = false; @@ -56,7 +58,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation using ProcessUnitPtr = bool (ConfigurationSetApplyProcessor::*)(UnitInfo&); // Runs the processing using the given functions. - bool ProcessInternal(CheckDependencyPtr checkDependencyFunction, ProcessUnitPtr processUnitFunction); + bool ProcessInternal(CheckDependencyPtr checkDependencyFunction, ProcessUnitPtr processUnitFunction, bool sendProgress = false); // Processes one of the non-writing intent types, which are fatal if not all successful bool ProcessIntentInternal( @@ -65,7 +67,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation ProcessUnitPtr processUnitFunction, ConfigurationUnitIntent intent, hresult errorForOtherIntents, - hresult errorForFailures); + ConfigurationUnitState progressForOtherIntents, + hresult errorForFailures, + bool sendProgress); // Determines if the given unit has the given intent and all of its dependencies are satisfied bool HasIntentAndSatisfiedDependencies( @@ -85,7 +89,13 @@ namespace winrt::Microsoft::Management::Configuration::implementation // Processes a configuration unit per its intent. bool ProcessUnit(UnitInfo& unitInfo); + // Sends progress + // TODO: Eventually these functions/call sites will be used for history + void SendProgress(ConfigurationSetState state); + void SendProgress(ConfigurationUnitState state, const UnitInfo& unitInfo); + IConfigurationSetProcessor m_setProcessor; + std::function m_progress; std::vector m_unitInfo; std::map m_idToUnitInfoIndex; hresult m_resultCode; diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.cpp index 2e582f2b06..48d0d5cc07 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.cpp @@ -6,33 +6,56 @@ namespace winrt::Microsoft::Management::Configuration::implementation { - void ConfigurationSetChangeData::Initialize(ConfigurationSetChangeEventType change) - { - m_change = change; - } - - ConfigurationSetChangeEventType ConfigurationSetChangeData::Change() - { - return m_change; - } - - ConfigurationSetState ConfigurationSetChangeData::SetState() - { - return m_setState; - } - - ConfigurationUnitState ConfigurationSetChangeData::UnitState() - { - return m_unitState; - } - - ConfigurationUnitResultInformation ConfigurationSetChangeData::ResultInformation() - { - return m_resultInformation; - } - - ConfigurationUnit ConfigurationSetChangeData::Unit() - { - return m_unit; + Configuration::ConfigurationSetChangeData ConfigurationSetChangeData::Create(ConfigurationSetState state) + { + auto result = make_self>(); + result->Initialize(state); + return *result; + } + + Configuration::ConfigurationSetChangeData ConfigurationSetChangeData::Create(ConfigurationUnitState state, ConfigurationUnitResultInformation resultInformation, ConfigurationUnit unit) + { + auto result = make_self>(); + result->Initialize(state, resultInformation, unit); + return *result; + } + + void ConfigurationSetChangeData::Initialize(ConfigurationSetState state) + { + m_change = ConfigurationSetChangeEventType::SetStateChanged; + m_setState = state; + } + + void ConfigurationSetChangeData::Initialize(ConfigurationUnitState state, ConfigurationUnitResultInformation resultInformation, ConfigurationUnit unit) + { + m_change = ConfigurationSetChangeEventType::UnitStateChanged; + m_unitState = state; + m_resultInformation = resultInformation; + m_unit = unit; + } + + ConfigurationSetChangeEventType ConfigurationSetChangeData::Change() + { + return m_change; + } + + ConfigurationSetState ConfigurationSetChangeData::SetState() + { + return m_setState; + } + + ConfigurationUnitState ConfigurationSetChangeData::UnitState() + { + return m_unitState; + } + + ConfigurationUnitResultInformation ConfigurationSetChangeData::ResultInformation() + { + return m_resultInformation; + } + + ConfigurationUnit ConfigurationSetChangeData::Unit() + { + return m_unit; } } diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.h b/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.h index b4a2480429..743763cc43 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.h +++ b/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.h @@ -13,7 +13,11 @@ namespace winrt::Microsoft::Management::Configuration::implementation ConfigurationSetChangeData() = default; #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) - void Initialize(ConfigurationSetChangeEventType change); + static Configuration::ConfigurationSetChangeData Create(ConfigurationSetState state); + static Configuration::ConfigurationSetChangeData Create(ConfigurationUnitState state, ConfigurationUnitResultInformation resultInformation, ConfigurationUnit unit); + + void Initialize(ConfigurationSetState state); + void Initialize(ConfigurationUnitState state, ConfigurationUnitResultInformation resultInformation, ConfigurationUnit unit); #endif ConfigurationSetChangeEventType Change(); @@ -24,11 +28,11 @@ namespace winrt::Microsoft::Management::Configuration::implementation #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: - ConfigurationSetChangeEventType m_change; - ConfigurationSetState m_setState; - ConfigurationUnitState m_unitState; - ConfigurationUnitResultInformation m_resultInformation; - ConfigurationUnit m_unit; + ConfigurationSetChangeEventType m_change = ConfigurationSetChangeEventType::Unknown; + ConfigurationSetState m_setState = ConfigurationSetState::Unknown; + ConfigurationUnitState m_unitState = ConfigurationUnitState::Unknown; + ConfigurationUnitResultInformation m_resultInformation = nullptr; + ConfigurationUnit m_unit = nullptr; #endif }; } diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp index 255129565d..926ef9d5cd 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp @@ -32,4 +32,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation { return m_description; } + + void ConfigurationUnitResultInformation::Description(hstring value) + { + m_description = value; + } } diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h index dd15c0cacf..c2e6079d05 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h +++ b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h @@ -12,11 +12,13 @@ namespace winrt::Microsoft::Management::Configuration::implementation #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void Initialize(hresult resultCode, std::wstring_view description); void Initialize(hresult resultCode, hstring description); - void ResultCode(hresult resultCode); #endif hresult ResultCode(); + void ResultCode(hresult resultCode); + hstring Description(); + void Description(hstring value); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: diff --git a/src/Microsoft.Management.Configuration/ExceptionResultHelpers.h b/src/Microsoft.Management.Configuration/ExceptionResultHelpers.h index a89f73b228..fdea24bd72 100644 --- a/src/Microsoft.Management.Configuration/ExceptionResultHelpers.h +++ b/src/Microsoft.Management.Configuration/ExceptionResultHelpers.h @@ -2,11 +2,12 @@ // Licensed under the MIT License. #pragma once #include +#include namespace winrt::Microsoft::Management::Configuration::implementation { - template - void ExtractUnitResultInformation(std::exception_ptr exc, const UnitResult& unitResult, const Processor& processor) + template + void ExtractUnitResultInformation(std::exception_ptr exc, const UnitResult& unitResult) { try { @@ -14,11 +15,13 @@ namespace winrt::Microsoft::Management::Configuration::implementation } catch (const winrt::hresult_error& hre) { - unitResult->Initialize(hre.code(), processor.GetLastErrorMessage()); + unitResult->Initialize(hre.code(), hre.message()); } catch (...) { unitResult->Initialize(E_FAIL, hstring{}); } + + AICLI_LOG(Config, Error, << "Unit Processor exception: " << AppInstaller::Logging::SetHRFormat << unitResult->ResultCode() << " [" << AppInstaller::Utility::ConvertToUTF8(unitResult->Description()) << "]"); } } diff --git a/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp index 211ee96a49..8fd3194e80 100644 --- a/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp +++ b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp @@ -6,7 +6,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation { - void GetConfigurationUnitSettingsResult::Initialize(const ConfigurationUnitResultInformation& resultInformation) + void GetConfigurationUnitSettingsResult::ResultInformation(const ConfigurationUnitResultInformation& resultInformation) { m_resultInformation = resultInformation; } diff --git a/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h index 8604ea230d..2a76333778 100644 --- a/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h +++ b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h @@ -13,7 +13,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation GetConfigurationUnitSettingsResult() = default; #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) - void Initialize(const ConfigurationUnitResultInformation& resultInformation); + void ResultInformation(const ConfigurationUnitResultInformation& resultInformation); void Settings(Windows::Foundation::Collections::ValueSet&& value); #endif diff --git a/src/Microsoft.Management.Configuration/GetSettingsResult.cpp b/src/Microsoft.Management.Configuration/GetSettingsResult.cpp new file mode 100644 index 0000000000..fd530bfb09 --- /dev/null +++ b/src/Microsoft.Management.Configuration/GetSettingsResult.cpp @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "GetSettingsResult.h" +#include "GetSettingsResult.g.cpp" +#include "ConfigurationUnitResultInformation.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + GetSettingsResult::GetSettingsResult() : + m_resultInformation(*make_self>()) + { + } + + Windows::Foundation::Collections::ValueSet GetSettingsResult::Settings() + { + return m_settings; + } + + Configuration::ConfigurationUnitResultInformation GetSettingsResult::ResultInformation() + { + return m_resultInformation; + } +} diff --git a/src/Microsoft.Management.Configuration/GetSettingsResult.h b/src/Microsoft.Management.Configuration/GetSettingsResult.h new file mode 100644 index 0000000000..6259970c80 --- /dev/null +++ b/src/Microsoft.Management.Configuration/GetSettingsResult.h @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "GetSettingsResult.g.h" +#include "winrt/Windows.Foundation.Collections.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct GetSettingsResult : GetSettingsResultT + { + GetSettingsResult(); + + Windows::Foundation::Collections::ValueSet Settings(); + Configuration::ConfigurationUnitResultInformation ResultInformation(); + + private: + Windows::Foundation::Collections::ValueSet m_settings; + Configuration::ConfigurationUnitResultInformation m_resultInformation; + }; +} +namespace winrt::Microsoft::Management::Configuration::factory_implementation +{ + struct GetSettingsResult : GetSettingsResultT + { + }; +} diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl index 48812d66fe..816eebe8a0 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -10,10 +10,9 @@ namespace Microsoft.Management.Configuration enum ConfigurationSetState { Unknown, - ApplicationPending, - ApplicationBegun, - ApplicationFailed, - ApplicationSucceeded, + Pending, + InProgress, + Completed, }; // The current state of a configuration unit. @@ -21,16 +20,12 @@ namespace Microsoft.Management.Configuration enum ConfigurationUnitState { Unknown, - ApplicationPending, - ApplicationBegun, - ApplicationFailed, - ApplicationSucceeded, + Pending, + InProgress, + Completed, SkippedManually, SkippedDueToAssertions, SkippedDueToDependencies, - TestBegun, - TestFailed, - TestSucceeded, }; // Defines the level of detail probing that is allowed about a configuration unit. @@ -52,10 +47,10 @@ namespace Microsoft.Management.Configuration runtimeclass ConfigurationUnitResultInformation { // The error code of the failure. - HRESULT ResultCode{ get; }; + HRESULT ResultCode; // The description of the failure. - String Description{ get; }; + String Description; } // Provides information for a specific configuration unit setting. @@ -255,6 +250,60 @@ namespace Microsoft.Management.Configuration void Remove(); } + // The result of applying the settings with an IConfigurationUnitProcessor. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass ApplySettingsResult + { + ApplySettingsResult(); + + // The result of applying the configuration unit. + ConfigurationUnitResultInformation ResultInformation{ get; }; + } + + // Informs the caller of the result of running a Test. + [contract(Microsoft.Management.Configuration.Contract, 1)] + enum ConfigurationTestResult + { + // The result is unknown. + Unknown, + // The system is in the state described by the configuration. + Positive, + // The system is not in the state described by the configuration. + Negative, + // Running the test failed. + Failed, + // The test was not run because it was not applicable. + NotRun, + }; + + // The result of testing the settings with an IConfigurationUnitProcessor. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass TestSettingsResult + { + TestSettingsResult(); + + // The result (if any) of running Test on the configuration unit. + ConfigurationTestResult TestResult; + + // The result of testing the configuration unit. + // This is not the response for the test, but rather contains information about the actual attempt to run the test. + ConfigurationUnitResultInformation ResultInformation{ get; }; + } + + // The result of getting the settings with an IConfigurationUnitProcessor. + [contract(Microsoft.Management.Configuration.Contract, 1)] + runtimeclass GetSettingsResult + { + GetSettingsResult(); + + // The current state of the system for the configuration unit. + Windows.Foundation.Collections.ValueSet Settings { get; }; + + // The result of getting the configuration unit settings. + // This is not the response for the retrieval, but rather contains information about the actual attempt to retrieve the settings. + ConfigurationUnitResultInformation ResultInformation{ get; }; + } + // Provides access to a specific configuration unit within the runtime. [contract(Microsoft.Management.Configuration.Contract, 1)] interface IConfigurationUnitProcessor @@ -266,16 +315,13 @@ namespace Microsoft.Management.Configuration Windows.Foundation.Collections.IMapView DirectivesOverlay{ get; }; // Determines if the system is already in the state described by the configuration unit. - Boolean TestSettings(); + TestSettingsResult TestSettings(); // Gets the current system state for the configuration unit. - Windows.Foundation.Collections.ValueSet GetSettings(); + GetSettingsResult GetSettings(); // Applies the state described in the configuration unit. - void ApplySettings(); - - // Gets the error message from the last attempt to run a command. - String GetLastErrorMessage(); + ApplySettingsResult ApplySettings(); } // Controls the lifetime of operations for a single configuration set. @@ -289,9 +335,6 @@ namespace Microsoft.Management.Configuration // The optional `directivesOverlay` parameter allows for the `ConfigurationProcessor` to alter behavior without needing to change the unit itself. // The overlay is searched first; any value not present there will then fall back to the unit's directives. IConfigurationUnitProcessor CreateUnitProcessor(ConfigurationUnit unit, Windows.Foundation.Collections.IMapView directivesOverlay); - - // Gets the error message from the last attempt to run a command. - String GetLastErrorMessage(); } // Allows different runtimes to provide specialized handling of configuration processing. @@ -462,8 +505,8 @@ namespace Microsoft.Management.Configuration // This is not the response for the test, but rather contains information about the actual attempt to run the test. ConfigurationUnitResultInformation ResultInformation{ get; }; - // Will be true if the system is in the state described by the configuration unit; false otherwise. - Boolean TestResult{ get; }; + // The result (if any) of running Test on the configuration unit. + ConfigurationTestResult TestResult{ get; }; } // The result of testing the settings for a configuration set. @@ -473,8 +516,12 @@ namespace Microsoft.Management.Configuration // Results for each configuration unit in the set. Windows.Foundation.Collections.IVectorView UnitResults{ get; }; - // Will be true if the system is in the state described by the entire configuration set; false otherwise (if any unit is not in the described state). - Boolean TestResult{ get; }; + // The result (if any) of running Test on the configuration set. + // If this value is NotRun, every unit result will be NotRun. + // If this value is Positive, every unit result will be Positive (or NotRun with at least one being Positive). + // Any Negative result for a unit will result in this value being Negative. + // Any Failed result for a unit will result in this value being Failed (overriding the Negative statement above). + ConfigurationTestResult TestResult{ get; }; } // The result of getting the settings for a configuration unit. @@ -529,7 +576,7 @@ namespace Microsoft.Management.Configuration // Tests the configuration set state. TestConfigurationSetResult TestSet(ConfigurationSet configurationSet); - Windows.Foundation.IAsyncOperationWithProgress TestSetAsync(ConfigurationSet configurationSet); + Windows.Foundation.IAsyncOperationWithProgress TestSetAsync(ConfigurationSet configurationSet); // Gets the current configuration unit settings. GetConfigurationUnitSettingsResult GetUnitSettings(ConfigurationUnit unit); diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj index aecc286c0f..54e8ca7d2d 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -60,7 +60,7 @@ v143 Unicode false - true + true true @@ -130,6 +130,7 @@ + @@ -146,15 +147,18 @@ + + + @@ -169,6 +173,7 @@ + @@ -177,6 +182,7 @@ + diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters index 716dd6fc2e..c35d4de8c5 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters @@ -63,6 +63,15 @@ Internals + + API Source + + + API Source + + + API Source + @@ -132,6 +141,15 @@ Internals + + API Headers + + + API Headers + + + API Headers + diff --git a/src/Microsoft.Management.Configuration/TestConfigurationSetResult.cpp b/src/Microsoft.Management.Configuration/TestConfigurationSetResult.cpp index 9d0f1f101c..8a8820ac84 100644 --- a/src/Microsoft.Management.Configuration/TestConfigurationSetResult.cpp +++ b/src/Microsoft.Management.Configuration/TestConfigurationSetResult.cpp @@ -13,6 +13,35 @@ namespace winrt::Microsoft::Management::Configuration::implementation void TestConfigurationSetResult::AppendUnitResult(const TestConfigurationUnitResult& unitResult) { m_unitResults.Append(unitResult); + + ConfigurationTestResult unitValue = unitResult.TestResult(); + + // Also aggregate the result of this incoming test into the overall result + switch (m_testResult) + { + case ConfigurationTestResult::Unknown: + case ConfigurationTestResult::NotRun: + // In these "default" cases, just take the unit result + m_testResult = unitValue; + break; + case ConfigurationTestResult::Positive: + if (unitValue == ConfigurationTestResult::Negative || unitValue == ConfigurationTestResult::Failed) + { + m_testResult = unitValue; + } + break; + case ConfigurationTestResult::Negative: + if (unitValue == ConfigurationTestResult::Failed) + { + m_testResult = unitValue; + } + break; + case ConfigurationTestResult::Failed: + // If a unit failed, the set failed + break; + default: + THROW_HR(E_UNEXPECTED); + } } Windows::Foundation::Collections::IVectorView TestConfigurationSetResult::UnitResults() @@ -20,12 +49,12 @@ namespace winrt::Microsoft::Management::Configuration::implementation return m_unitResults.GetView(); } - bool TestConfigurationSetResult::TestResult() + ConfigurationTestResult TestConfigurationSetResult::TestResult() { return m_testResult; } - void TestConfigurationSetResult::TestResult(bool value) + void TestConfigurationSetResult::TestResult(ConfigurationTestResult value) { m_testResult = value; } diff --git a/src/Microsoft.Management.Configuration/TestConfigurationSetResult.h b/src/Microsoft.Management.Configuration/TestConfigurationSetResult.h index 0b74b89e23..629ffc56e0 100644 --- a/src/Microsoft.Management.Configuration/TestConfigurationSetResult.h +++ b/src/Microsoft.Management.Configuration/TestConfigurationSetResult.h @@ -12,16 +12,16 @@ namespace winrt::Microsoft::Management::Configuration::implementation #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void AppendUnitResult(const TestConfigurationUnitResult& unitResult); - void TestResult(bool value); + void TestResult(ConfigurationTestResult value); #endif Windows::Foundation::Collections::IVectorView UnitResults(); - bool TestResult(); + ConfigurationTestResult TestResult(); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: Windows::Foundation::Collections::IVector m_unitResults = nullptr; - bool m_testResult; + ConfigurationTestResult m_testResult = ConfigurationTestResult::Unknown; #endif }; } diff --git a/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.cpp b/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.cpp index 05e3cc1f2d..e824b0aae3 100644 --- a/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.cpp +++ b/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.cpp @@ -21,13 +21,18 @@ namespace winrt::Microsoft::Management::Configuration::implementation { return m_resultInformation; } + + void TestConfigurationUnitResult::ResultInformation(const ConfigurationUnitResultInformation& value) + { + m_resultInformation = value; + } - bool TestConfigurationUnitResult::TestResult() + ConfigurationTestResult TestConfigurationUnitResult::TestResult() { return m_testResult; } - void TestConfigurationUnitResult::TestResult(bool value) + void TestConfigurationUnitResult::TestResult(ConfigurationTestResult value) { m_testResult = value; } diff --git a/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.h b/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.h index 3e1da45e2b..d827d088d7 100644 --- a/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.h +++ b/src/Microsoft.Management.Configuration/TestConfigurationUnitResult.h @@ -14,18 +14,19 @@ namespace winrt::Microsoft::Management::Configuration::implementation #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void Initialize(ConfigurationUnit unit, ConfigurationUnitResultInformation resultInformation); - void TestResult(bool value); + void ResultInformation(const ConfigurationUnitResultInformation& value); + void TestResult(ConfigurationTestResult value); #endif ConfigurationUnit Unit(); ConfigurationUnitResultInformation ResultInformation(); - bool TestResult(); + ConfigurationTestResult TestResult(); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: ConfigurationUnit m_unit = nullptr; ConfigurationUnitResultInformation m_resultInformation = nullptr; - bool m_testResult; + ConfigurationTestResult m_testResult = ConfigurationTestResult::Unknown; #endif }; } diff --git a/src/Microsoft.Management.Configuration/TestSettingsResult.cpp b/src/Microsoft.Management.Configuration/TestSettingsResult.cpp new file mode 100644 index 0000000000..465c6de1eb --- /dev/null +++ b/src/Microsoft.Management.Configuration/TestSettingsResult.cpp @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "TestSettingsResult.h" +#include "TestSettingsResult.g.cpp" +#include "ConfigurationUnitResultInformation.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + TestSettingsResult::TestSettingsResult() : + m_resultInformation(*make_self>()) + { + } + + ConfigurationTestResult TestSettingsResult::TestResult() + { + return m_testResult; + } + + void TestSettingsResult::TestResult(ConfigurationTestResult const& value) + { + m_testResult = value; + } + + Configuration::ConfigurationUnitResultInformation TestSettingsResult::ResultInformation() + { + return m_resultInformation; + } +} diff --git a/src/Microsoft.Management.Configuration/TestSettingsResult.h b/src/Microsoft.Management.Configuration/TestSettingsResult.h new file mode 100644 index 0000000000..e28ef5451f --- /dev/null +++ b/src/Microsoft.Management.Configuration/TestSettingsResult.h @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "TestSettingsResult.g.h" + +namespace winrt::Microsoft::Management::Configuration::implementation +{ + struct TestSettingsResult : TestSettingsResultT + { + TestSettingsResult(); + + ConfigurationTestResult TestResult(); + void TestResult(ConfigurationTestResult const& value); + + Configuration::ConfigurationUnitResultInformation ResultInformation(); + + private: + ConfigurationTestResult m_testResult = ConfigurationTestResult::Unknown; + Configuration::ConfigurationUnitResultInformation m_resultInformation; + }; +} + +namespace winrt::Microsoft::Management::Configuration::factory_implementation +{ + struct TestSettingsResult : TestSettingsResultT + { + }; +} diff --git a/src/Microsoft.Management.Configuration/pch.h b/src/Microsoft.Management.Configuration/pch.h index 7044cf6098..736f4ecafa 100644 --- a/src/Microsoft.Management.Configuration/pch.h +++ b/src/Microsoft.Management.Configuration/pch.h @@ -12,7 +12,8 @@ #pragma warning ( disable : 4467 6388) // 4467 Allow use of uuid attribute for com object creation. // 6388 Allow CreateInstance. -#include +#include +#include #pragma warning( pop ) #include @@ -27,4 +28,5 @@ #include #include #include +#include #include From 579b12942f5472a6be3bbca550290d9163771e48 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Fri, 3 Feb 2023 17:24:23 -0800 Subject: [PATCH 17/31] Test fixes --- .../Helpers/ConfigurationProcessorTestBase.cs | 12 ++++++++++-- .../Tests/OpenConfigurationSetTests.cs | 3 +++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs index a39a58efb6..aa43b3574f 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs @@ -7,6 +7,7 @@ namespace Microsoft.Management.Configuration.UnitTests.Helpers { using Microsoft.Management.Configuration.UnitTests.Fixtures; + using System; using Windows.Storage.Streams; using Xunit.Abstractions; @@ -59,8 +60,15 @@ protected ConfigurationProcessor CreateConfigurationProcessorWithDiagnostics(ICo protected IInputStream CreateStream(string contents) { InMemoryRandomAccessStream result = new InMemoryRandomAccessStream(); - DataWriter writer = new DataWriter(result); - writer.WriteString(contents); + + using (DataWriter writer = new DataWriter(result)) + { + writer.UnicodeEncoding = UnicodeEncoding.Utf8; + writer.WriteString(contents); + writer.StoreAsync().AsTask().Wait(); + writer.DetachStream(); + } + result.Seek(0); return result; } diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs index 339a9bfab8..8672e42418 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs @@ -135,6 +135,7 @@ public void EnsureIntent() OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@" properties: + configurationVersion: 0.1 assertions: - resource: Assert parameters: @@ -180,6 +181,7 @@ public void NonSequenceUnits() OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@" properties: + configurationVersion: 0.1 resources: 1 ")); Assert.Null(result.Set); @@ -198,6 +200,7 @@ public void NonMapSequenceUnits() OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@" properties: + configurationVersion: 0.1 resources: - string ")); From dcdb01445cd8afcaec27759ef62a66cff9c196df Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Mon, 6 Feb 2023 10:59:54 -0800 Subject: [PATCH 18/31] Checkpoint; test factory interfaces in progress --- .../Helpers/ConfigurationProcessorTestBase.cs | 2 +- .../TestConfigurationProcessorFactory.cs | 49 ++++++++++ .../Helpers/TestConfigurationSetProcessor.cs | 89 +++++++++++++++++++ .../Helpers/TestConfigurationUnitProcessor.cs | 50 +++++++++++ .../TestConfigurationUnitProcessorDetails.cs | 52 +++++++++++ .../Tests/OpenConfigurationSetTests.cs | 70 +++++++++++++++ .../Microsoft.Management.Configuration.idl | 13 +++ 7 files changed, 324 insertions(+), 1 deletion(-) create mode 100644 src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs create mode 100644 src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationSetProcessor.cs create mode 100644 src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs create mode 100644 src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessorDetails.cs diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs index aa43b3574f..c72da96d1e 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs @@ -6,8 +6,8 @@ namespace Microsoft.Management.Configuration.UnitTests.Helpers { - using Microsoft.Management.Configuration.UnitTests.Fixtures; using System; + using Microsoft.Management.Configuration.UnitTests.Fixtures; using Windows.Storage.Streams; using Xunit.Abstractions; diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs new file mode 100644 index 0000000000..956e2c0a20 --- /dev/null +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs @@ -0,0 +1,49 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Helpers +{ + using System; + using System.Collections.Generic; + + /// + /// A test implementation of IConfigurationProcessorFactory. + /// + internal class TestConfigurationProcessorFactory : IConfigurationProcessorFactory + { + /// + /// Gets or sets the processors to be used by this factory. + /// + internal Dictionary Processors { get; set; } = + new Dictionary(); + + /// + /// Gets or sets the exceptions to be used by this factory. + /// + internal Dictionary Exceptions { get; set; } = + new Dictionary(); + + /// + /// Creates a new TestConfigurationSetProcessor for the set. + /// + /// The set. + /// A new TestConfigurationSetProcessor for the set. + public IConfigurationSetProcessor CreateSetProcessor(ConfigurationSet configurationSet) + { + if (this.Exceptions.ContainsKey(configurationSet)) + { + throw this.Exceptions[configurationSet]; + } + + if (!this.Processors.ContainsKey(configurationSet)) + { + this.Processors.Add(configurationSet, new TestConfigurationSetProcessor(configurationSet)); + } + + return this.Processors[configurationSet]; + } + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationSetProcessor.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationSetProcessor.cs new file mode 100644 index 0000000000..97c94ab51f --- /dev/null +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationSetProcessor.cs @@ -0,0 +1,89 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Helpers +{ + using ABI.Microsoft.Management.Configuration; + using System; + using System.Collections.Generic; + + /// + /// A test implementation of IConfigurationSetProcessor. + /// + internal class TestConfigurationSetProcessor : IConfigurationSetProcessor + { + private ConfigurationSet set; + + /// + /// Initializes a new instance of the class. + /// + /// The set that this processor is for. + internal TestConfigurationSetProcessor(ConfigurationSet set) + { + this.set = set; + } + + /// + /// Gets or sets the processors to be used by this factory. + /// + internal Dictionary Processors { get; set; } = + new Dictionary(); + + /// + /// Gets or sets the details to be used by this factory. + /// + internal Dictionary Details { get; set; } = + new Dictionary(); + + /// + /// Gets or sets the exceptions to be used by this factory. + /// + internal Dictionary Exceptions { get; set; } = + new Dictionary(); + + /// + /// Creates a new unit processor for the given unit. + /// + /// The unit. + /// Directives to override those in the unit. + /// The configuration unit processor. + public IConfigurationUnitProcessor CreateUnitProcessor(ConfigurationUnit unit, IReadOnlyDictionary directivesOverlay) + { + if (this.Exceptions.ContainsKey(unit)) + { + throw this.Exceptions[unit]; + } + + if (!this.Processors.ContainsKey(unit)) + { + this.Processors.Add(unit, new TestConfigurationUnitProcessor(unit, directivesOverlay)); + } + + return this.Processors[unit]; + } + + /// + /// Gets the unit processor details for the given unit. + /// + /// The unit. + /// The detail level requested. + /// The details requested. + public IConfigurationUnitProcessorDetails GetUnitProcessorDetails(ConfigurationUnit unit, ConfigurationUnitDetailLevel detailLevel) + { + if (this.Exceptions.ContainsKey(unit)) + { + throw this.Exceptions[unit]; + } + + if (!this.Details.ContainsKey(unit)) + { + this.Details.Add(unit, new TestConfigurationUnitProcessorDetails(unit, detailLevel)); + } + + return this.Details[unit]; + } + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs new file mode 100644 index 0000000000..3cc21f4314 --- /dev/null +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs @@ -0,0 +1,50 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Helpers +{ + using System; + using System.Collections.Generic; + + /// + /// A test implementation of IConfigurationProcessorFactory. + /// + internal class TestConfigurationUnitProcessor : IConfigurationUnitProcessor + { + private ConfigurationUnit unit; + private IReadOnlyDictionary directivesOverlay; + + /// + /// Initializes a new instance of the class. + /// + /// The unit. + /// The directives overlay. + internal TestConfigurationUnitProcessor(ConfigurationUnit unit, IReadOnlyDictionary directivesOverlay) + { + this.unit = unit; + this.directivesOverlay = directivesOverlay; + } + + public IReadOnlyDictionary DirectivesOverlay => throw new NotImplementedException(); + + public ConfigurationUnit Unit => throw new NotImplementedException(); + + public ApplySettingsResult ApplySettings() + { + throw new NotImplementedException(); + } + + public GetSettingsResult GetSettings() + { + throw new NotImplementedException(); + } + + public TestSettingsResult TestSettings() + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessorDetails.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessorDetails.cs new file mode 100644 index 0000000000..4a07f902a6 --- /dev/null +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessorDetails.cs @@ -0,0 +1,52 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Helpers +{ + using System; + using System.Collections.Generic; + using Windows.Security.Cryptography.Certificates; + + /// + /// A test implementation of IConfigurationProcessorFactory. + /// + internal class TestConfigurationUnitProcessorDetails : IConfigurationUnitProcessorDetails + { + public string Author => throw new NotImplementedException(); + + public bool IsLocal => throw new NotImplementedException(); + + public string ModuleDescription => throw new NotImplementedException(); + + public Uri ModuleDocumentationUri => throw new NotImplementedException(); + + public string ModuleName => throw new NotImplementedException(); + + public string ModuleSource => throw new NotImplementedException(); + + public string ModuleType => throw new NotImplementedException(); + + public DateTimeOffset PublishedDate => throw new NotImplementedException(); + + public Uri PublishedModuleUri => throw new NotImplementedException(); + + public string Publisher => throw new NotImplementedException(); + + public IReadOnlyList Settings => throw new NotImplementedException(); + + public CertificateChain SigningCertificateChain => throw new NotImplementedException(); + + public string UnitDescription => throw new NotImplementedException(); + + public Uri UnitDocumentationUri => throw new NotImplementedException(); + + public Uri UnitIconUri => throw new NotImplementedException(); + + public string UnitName => throw new NotImplementedException(); + + public string Version => throw new NotImplementedException(); + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs index 8672e42418..25d707696d 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs @@ -7,6 +7,7 @@ namespace Microsoft.Management.Configuration.UnitTests.Tests { using System; + using System.Linq; using System.Runtime.InteropServices; using Microsoft.Management.Configuration.UnitTests.Fixtures; using Microsoft.Management.Configuration.UnitTests.Helpers; @@ -209,5 +210,74 @@ public void NonMapSequenceUnits() Assert.Equal(Errors.WINGET_CONFIG_ERROR_INVALID_FIELD, result.ResultCode.HResult); Assert.NotEqual(string.Empty, result.Field); } + + /// + /// Passes YAML with all values present. + /// + [Fact] + public void CheckAllUnitProperties() + { + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(); + + OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@" +properties: + configurationVersion: 0.1 + resources: + - resource: Resource + id: Identifier + dependsOn: + - Dependency1 + - Dependency2 + directives: + Directive1: A + Directive2: B + settings: + Setting1: 1 + Setting2: 2 +")); + Assert.NotNull(result.Set); + Assert.Null(result.ResultCode); + Assert.Equal(string.Empty, result.Field); + + Assert.NotEqual(Guid.Empty, result.Set.InstanceIdentifier); + + var units = result.Set.ConfigurationUnits; + Assert.NotNull(units); + Assert.Equal(1, units.Count); + + ConfigurationUnit unit = units[0]; + Assert.NotNull(unit); + Assert.Equal("Resource", unit.UnitName); + Assert.NotEqual(Guid.Empty, unit.InstanceIdentifier); + Assert.Equal("Identifier", unit.Identifier); + Assert.Equal(ConfigurationUnitIntent.Apply, unit.Intent); + + var dependencies = unit.Dependencies; + Assert.NotNull(dependencies); + Assert.Equal(2, dependencies.Count); + Assert.Contains("Dependency1", dependencies); + Assert.Contains("Dependency2", dependencies); + + var directives = unit.Directives; + Assert.NotNull(directives); + Assert.Equal(2, directives.Count); + Assert.Contains("Directive1", directives); + Assert.Equal("A", directives["Directive1"]); + Assert.Contains("Directive2", directives); + Assert.Equal("B", directives["Directive2"]); + + var settings = unit.Settings; + Assert.NotNull(settings); + Assert.Equal(2, settings.Count); + Assert.Contains("Setting1", settings); + Assert.Equal("1", settings["Setting1"]); + Assert.Contains("Setting2", settings); + Assert.Equal("2", settings["Setting2"]); + + Assert.Null(unit.Details); + Assert.Equal(ConfigurationUnitState.Unknown, unit.State); + Assert.Null(unit.ResultInformation); + Assert.True(unit.ShouldApply); + } } } diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl index 816eebe8a0..407c7d784b 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -582,4 +582,17 @@ namespace Microsoft.Management.Configuration GetConfigurationUnitSettingsResult GetUnitSettings(ConfigurationUnit unit); Windows.Foundation.IAsyncOperation GetUnitSettingsAsync(ConfigurationUnit unit); } + + /// Force midl3 to generate vector marshalling info. + declare + { + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVector; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVectorView; + interface Windows.Foundation.Collections.IVectorView; + } } From b5f07b5739f4d3a8e0a0ea427f9cc7e31439c83c Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Mon, 6 Feb 2023 20:35:12 -0800 Subject: [PATCH 19/31] Fix not creating get settings result members; add many tests --- .../TestConfigurationProcessorFactory.cs | 36 +++ .../Helpers/TestConfigurationSetProcessor.cs | 16 +- .../Helpers/TestConfigurationUnitProcessor.cs | 96 +++++- .../TestConfigurationUnitProcessorDetails.cs | 50 +-- .../Tests/ConfigurationProcessorTestTests.cs | 285 ++++++++++++++++++ .../Tests/OpenConfigurationSetTests.cs | 2 +- .../Tests/ProcessorGetTests.cs | 188 ++++++++++++ .../GetConfigurationUnitSettingsResult.cpp | 8 +- .../GetConfigurationUnitSettingsResult.h | 6 +- 9 files changed, 653 insertions(+), 34 deletions(-) create mode 100644 src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorTestTests.cs create mode 100644 src/Microsoft.Management.Configuration.UnitTests/Tests/ProcessorGetTests.cs diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs index 956e2c0a20..6bc42c2a39 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs @@ -14,12 +14,22 @@ namespace Microsoft.Management.Configuration.UnitTests.Helpers /// internal class TestConfigurationProcessorFactory : IConfigurationProcessorFactory { + /// + /// Gets or sets the processor used when the incoming configuration set is null. + /// + internal TestConfigurationSetProcessor? NullProcessor { get; set; } + /// /// Gets or sets the processors to be used by this factory. /// internal Dictionary Processors { get; set; } = new Dictionary(); + /// + /// Gets or sets the exception used when the incoming configuration set is null. + /// + internal Exception? NullException { get; set; } + /// /// Gets or sets the exceptions to be used by this factory. /// @@ -33,6 +43,21 @@ internal class TestConfigurationProcessorFactory : IConfigurationProcessorFactor /// A new TestConfigurationSetProcessor for the set. public IConfigurationSetProcessor CreateSetProcessor(ConfigurationSet configurationSet) { + if (configurationSet == null) + { + if (this.NullException != null) + { + throw this.NullException; + } + + if (this.NullProcessor == null) + { + this.NullProcessor = new TestConfigurationSetProcessor(null); + } + + return this.NullProcessor; + } + if (this.Exceptions.ContainsKey(configurationSet)) { throw this.Exceptions[configurationSet]; @@ -45,5 +70,16 @@ public IConfigurationSetProcessor CreateSetProcessor(ConfigurationSet configurat return this.Processors[configurationSet]; } + + /// + /// A convenience function to create a new processor for the given set and store it in the dictionary for use in the test. + /// + /// The set. + /// A new TestConfigurationSetProcessor for the set. + internal TestConfigurationSetProcessor CreateTestProcessor(ConfigurationSet configurationSet) + { + this.Processors[configurationSet] = new TestConfigurationSetProcessor(configurationSet); + return this.Processors[configurationSet]; + } } } diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationSetProcessor.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationSetProcessor.cs index 97c94ab51f..48b751a1c6 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationSetProcessor.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationSetProcessor.cs @@ -6,7 +6,6 @@ namespace Microsoft.Management.Configuration.UnitTests.Helpers { - using ABI.Microsoft.Management.Configuration; using System; using System.Collections.Generic; @@ -15,13 +14,13 @@ namespace Microsoft.Management.Configuration.UnitTests.Helpers /// internal class TestConfigurationSetProcessor : IConfigurationSetProcessor { - private ConfigurationSet set; + private ConfigurationSet? set; /// /// Initializes a new instance of the class. /// /// The set that this processor is for. - internal TestConfigurationSetProcessor(ConfigurationSet set) + internal TestConfigurationSetProcessor(ConfigurationSet? set) { this.set = set; } @@ -85,5 +84,16 @@ public IConfigurationUnitProcessorDetails GetUnitProcessorDetails(ConfigurationU return this.Details[unit]; } + + /// + /// Creates a new test processor for the given unit. + /// + /// The unit. + /// The configuration unit processor. + internal TestConfigurationUnitProcessor CreateTestProcessor(ConfigurationUnit unit) + { + this.Processors[unit] = new TestConfigurationUnitProcessor(unit); + return this.Processors[unit]; + } } } diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs index 3cc21f4314..36003e5699 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs @@ -14,8 +14,14 @@ namespace Microsoft.Management.Configuration.UnitTests.Helpers /// internal class TestConfigurationUnitProcessor : IConfigurationUnitProcessor { - private ConfigurationUnit unit; - private IReadOnlyDictionary directivesOverlay; + /// + /// Initializes a new instance of the class. + /// + /// The unit. + internal TestConfigurationUnitProcessor(ConfigurationUnit unit) + { + this.Unit = unit; + } /// /// Initializes a new instance of the class. @@ -24,27 +30,99 @@ internal class TestConfigurationUnitProcessor : IConfigurationUnitProcessor /// The directives overlay. internal TestConfigurationUnitProcessor(ConfigurationUnit unit, IReadOnlyDictionary directivesOverlay) { - this.unit = unit; - this.directivesOverlay = directivesOverlay; + this.Unit = unit; + this.DirectivesOverlay = directivesOverlay; } - public IReadOnlyDictionary DirectivesOverlay => throw new NotImplementedException(); + /// + /// The delegate for ApplySettings. + /// + /// The result. + internal delegate ApplySettingsResult ApplySettingsDelegateType(); + + /// + /// The delegate for GetSettings. + /// + /// The result. + internal delegate GetSettingsResult GetSettingsDelegateType(); + + /// + /// The delegate for TestSettings. + /// + /// The result. + internal delegate TestSettingsResult TestSettingsDelegateType(); + + /// + /// Gets or sets the directives overlay. + /// + public IReadOnlyDictionary? DirectivesOverlay { get; set; } + + /// + /// Gets the configuration unit. + /// + public ConfigurationUnit Unit { get; private set; } - public ConfigurationUnit Unit => throw new NotImplementedException(); + /// + /// Gets or sets the delegate object for ApplySettings. + /// + internal ApplySettingsDelegateType? ApplySettingsDelegate { get; set; } + /// + /// Gets or sets the delegate object for GetSettings. + /// + internal GetSettingsDelegateType? GetSettingsDelegate { get; set; } + + /// + /// Gets or sets the delegate object for TestSettings. + /// + internal TestSettingsDelegateType? TestSettingsDelegate { get; set; } + + /// + /// Calls the ApplySettingsDelegate if one is provided; returns success if not. + /// + /// The result. public ApplySettingsResult ApplySettings() { - throw new NotImplementedException(); + if (this.ApplySettingsDelegate != null) + { + return this.ApplySettingsDelegate(); + } + else + { + return new ApplySettingsResult(); + } } + /// + /// Calls the GetSettingsDelegate if one is provided; returns success if not (with no settings values). + /// + /// The result. public GetSettingsResult GetSettings() { - throw new NotImplementedException(); + if (this.GetSettingsDelegate != null) + { + return this.GetSettingsDelegate(); + } + else + { + return new GetSettingsResult(); + } } + /// + /// Calls the TestSettingsDelegate if one is provided; returns success if not (with a positive test result). + /// + /// The result. public TestSettingsResult TestSettings() { - throw new NotImplementedException(); + if (this.TestSettingsDelegate != null) + { + return this.TestSettingsDelegate(); + } + else + { + return new TestSettingsResult { TestResult = ConfigurationTestResult.Positive }; + } } } } diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessorDetails.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessorDetails.cs index 4a07f902a6..ea15a71226 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessorDetails.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessorDetails.cs @@ -15,38 +15,54 @@ namespace Microsoft.Management.Configuration.UnitTests.Helpers /// internal class TestConfigurationUnitProcessorDetails : IConfigurationUnitProcessorDetails { - public string Author => throw new NotImplementedException(); + private ConfigurationUnit unit; + private ConfigurationUnitDetailLevel detailLevel; - public bool IsLocal => throw new NotImplementedException(); + /// + /// Initializes a new instance of the class. + /// + /// The unit. + /// The level of the details. + internal TestConfigurationUnitProcessorDetails(ConfigurationUnit unit, ConfigurationUnitDetailLevel detailLevel) + { + this.unit = unit; + this.detailLevel = detailLevel; + } - public string ModuleDescription => throw new NotImplementedException(); +#pragma warning disable SA1600 // Elements should be documented + public string? Author { get; internal set; } - public Uri ModuleDocumentationUri => throw new NotImplementedException(); + public bool IsLocal { get; internal set; } - public string ModuleName => throw new NotImplementedException(); + public string? ModuleDescription { get; internal set; } - public string ModuleSource => throw new NotImplementedException(); + public Uri? ModuleDocumentationUri { get; internal set; } - public string ModuleType => throw new NotImplementedException(); + public string? ModuleName { get; internal set; } - public DateTimeOffset PublishedDate => throw new NotImplementedException(); + public string? ModuleSource { get; internal set; } - public Uri PublishedModuleUri => throw new NotImplementedException(); + public string? ModuleType { get; internal set; } - public string Publisher => throw new NotImplementedException(); + public DateTimeOffset PublishedDate { get; internal set; } - public IReadOnlyList Settings => throw new NotImplementedException(); + public Uri? PublishedModuleUri { get; internal set; } - public CertificateChain SigningCertificateChain => throw new NotImplementedException(); + public string? Publisher { get; internal set; } - public string UnitDescription => throw new NotImplementedException(); + public IReadOnlyList? Settings { get; internal set; } - public Uri UnitDocumentationUri => throw new NotImplementedException(); + public CertificateChain? SigningCertificateChain { get; internal set; } - public Uri UnitIconUri => throw new NotImplementedException(); + public string? UnitDescription { get; internal set; } - public string UnitName => throw new NotImplementedException(); + public Uri? UnitDocumentationUri { get; internal set; } - public string Version => throw new NotImplementedException(); + public Uri? UnitIconUri { get; internal set; } + + public string? UnitName { get; internal set; } + + public string? Version { get; internal set; } +#pragma warning restore SA1600 // Elements should be documented } } diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorTestTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorTestTests.cs new file mode 100644 index 0000000000..6af37df61a --- /dev/null +++ b/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorTestTests.cs @@ -0,0 +1,285 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Tests +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Runtime.InteropServices; + using Microsoft.Management.Configuration.UnitTests.Fixtures; + using Microsoft.Management.Configuration.UnitTests.Helpers; + using Microsoft.VisualBasic; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Xunit; + using Xunit.Abstractions; + + /// + /// Unit tests for running test on the processor. + /// + [Collection("UnitTestCollection")] + public class ConfigurationProcessorTestTests : ConfigurationProcessorTestBase + { + /// + /// Initializes a new instance of the class. + /// + /// Unit test fixture. + /// Log helper. + public ConfigurationProcessorTestTests(UnitTestFixture fixture, ITestOutputHelper log) + : base(fixture, log) + { + } + + /// + /// An error creating the set processor results in an error for the function. + /// + [Fact] + public void TestSet_SetProcessorError() + { + ConfigurationSet configurationSet = new ConfigurationSet(); + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + factory.Exceptions.Add(configurationSet, new FileNotFoundException()); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + Assert.Throws(() => processor.TestSet(configurationSet)); + } + + /// + /// An error creating a unit processor results in an error for that unit. + /// + [Fact] + public void TestSet_UnitProcessorCreationError() + { + ConfigurationSet configurationSet = new ConfigurationSet(); + ConfigurationUnit configurationUnitThrows = new ConfigurationUnit(); + ConfigurationUnit configurationUnitWorks = new ConfigurationUnit(); + configurationSet.ConfigurationUnits = new ConfigurationUnit[] { configurationUnitThrows, configurationUnitWorks }; + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet); + setProcessor.Exceptions.Add(configurationUnitThrows, new NullReferenceException()); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + TestConfigurationSetResult result = processor.TestSet(configurationSet); + + Assert.NotNull(result); + Assert.Equal(ConfigurationTestResult.Failed, result.TestResult); + Assert.NotNull(result.UnitResults); + Assert.Equal(2, result.UnitResults.Count); + + TestConfigurationUnitResult throwsResult = result.UnitResults.First(x => x.Unit == configurationUnitThrows); + Assert.NotNull(throwsResult); + Assert.Equal(ConfigurationTestResult.Failed, throwsResult.TestResult); + Assert.NotNull(throwsResult.ResultInformation); + Assert.NotNull(throwsResult.ResultInformation.ResultCode); + Assert.IsType(throwsResult.ResultInformation.ResultCode); + + TestConfigurationUnitResult worksResult = result.UnitResults.First(x => x.Unit == configurationUnitWorks); + Assert.NotNull(worksResult); + Assert.Equal(ConfigurationTestResult.Positive, worksResult.TestResult); + Assert.NotNull(worksResult.ResultInformation); + Assert.Null(worksResult.ResultInformation.ResultCode); + } + + /// + /// An error running a unit processor results in an error for that unit. + /// + [Fact] + public void TestSet_UnitProcessorExecutionError() + { + ConfigurationSet configurationSet = new ConfigurationSet(); + ConfigurationUnit configurationUnitThrows = new ConfigurationUnit(); + ConfigurationUnit configurationUnitWorks = new ConfigurationUnit(); + configurationSet.ConfigurationUnits = new ConfigurationUnit[] { configurationUnitWorks, configurationUnitThrows }; + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet); + TestConfigurationUnitProcessor unitProcessor = setProcessor.CreateTestProcessor(configurationUnitThrows); + unitProcessor.TestSettingsDelegate = () => throw new NullReferenceException(); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + TestConfigurationSetResult result = processor.TestSet(configurationSet); + + Assert.NotNull(result); + Assert.Equal(ConfigurationTestResult.Failed, result.TestResult); + Assert.NotNull(result.UnitResults); + Assert.Equal(2, result.UnitResults.Count); + + TestConfigurationUnitResult throwsResult = result.UnitResults.First(x => x.Unit == configurationUnitThrows); + Assert.NotNull(throwsResult); + Assert.Equal(ConfigurationTestResult.Failed, throwsResult.TestResult); + Assert.NotNull(throwsResult.ResultInformation); + Assert.NotNull(throwsResult.ResultInformation.ResultCode); + Assert.IsType(throwsResult.ResultInformation.ResultCode); + + TestConfigurationUnitResult worksResult = result.UnitResults.First(x => x.Unit == configurationUnitWorks); + Assert.NotNull(worksResult); + Assert.Equal(ConfigurationTestResult.Positive, worksResult.TestResult); + Assert.NotNull(worksResult.ResultInformation); + Assert.Null(worksResult.ResultInformation.ResultCode); + } + + /// + /// An error running a unit processor results in an error for that unit. + /// + [Fact] + public void TestSet_UnitProcessorResultError() + { + ConfigurationSet configurationSet = new ConfigurationSet(); + ConfigurationUnit configurationUnitThrows = new ConfigurationUnit(); + ConfigurationUnit configurationUnitWorks = new ConfigurationUnit(); + configurationSet.ConfigurationUnits = new ConfigurationUnit[] { configurationUnitWorks, configurationUnitThrows }; + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet); + TestConfigurationUnitProcessor unitProcessor = setProcessor.CreateTestProcessor(configurationUnitThrows); + TestSettingsResult testResult = new TestSettingsResult(); + testResult.TestResult = ConfigurationTestResult.Failed; + testResult.ResultInformation.ResultCode = new NullReferenceException(); + testResult.ResultInformation.Description = "Failed again"; + unitProcessor.TestSettingsDelegate = () => testResult; + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + TestConfigurationSetResult result = processor.TestSet(configurationSet); + + Assert.NotNull(result); + Assert.Equal(ConfigurationTestResult.Failed, result.TestResult); + Assert.NotNull(result.UnitResults); + Assert.Equal(2, result.UnitResults.Count); + + TestConfigurationUnitResult throwsResult = result.UnitResults.First(x => x.Unit == configurationUnitThrows); + Assert.NotNull(throwsResult); + Assert.Equal(ConfigurationTestResult.Failed, throwsResult.TestResult); + Assert.NotNull(throwsResult.ResultInformation); + Assert.NotNull(throwsResult.ResultInformation.ResultCode); + Assert.IsType(throwsResult.ResultInformation.ResultCode); + Assert.Equal(testResult.ResultInformation.Description, throwsResult.ResultInformation.Description); + + TestConfigurationUnitResult worksResult = result.UnitResults.First(x => x.Unit == configurationUnitWorks); + Assert.NotNull(worksResult); + Assert.Equal(ConfigurationTestResult.Positive, worksResult.TestResult); + Assert.NotNull(worksResult.ResultInformation); + Assert.Null(worksResult.ResultInformation.ResultCode); + } + + /// + /// Ensures that the expected TestResult comes back for all types. + /// + [Fact] + public void TestSet_ResultTypes() + { + this.RunTestSetTestForResultTypes(new ConfigurationTestResult[] { ConfigurationTestResult.Positive, ConfigurationTestResult.Negative, ConfigurationTestResult.Failed, ConfigurationTestResult.NotRun }, ConfigurationTestResult.Failed); + } + + /// + /// Ensures that a single negative makes the overall result negative. + /// + [Fact] + public void TestSet_Negative() + { + this.RunTestSetTestForResultTypes(new ConfigurationTestResult[] { ConfigurationTestResult.Positive, ConfigurationTestResult.Negative, ConfigurationTestResult.Positive, ConfigurationTestResult.NotRun }, ConfigurationTestResult.Negative); + } + + /// + /// Ensures that a single not run test does not impact the positive result. + /// + [Fact] + public void TestSet_Positive() + { + this.RunTestSetTestForResultTypes(new ConfigurationTestResult[] { ConfigurationTestResult.Positive, ConfigurationTestResult.Positive, ConfigurationTestResult.Positive, ConfigurationTestResult.NotRun }, ConfigurationTestResult.Positive); + } + + /// + /// Creates a test scenario where the units produce the given test results. + /// + /// The result types for each unit. + /// The expected overall test result. + private void RunTestSetTestForResultTypes(ConfigurationTestResult[] resultTypes, ConfigurationTestResult overallResult) + { + ConfigurationSet configurationSet = new ConfigurationSet(); + ConfigurationUnit[] configurationUnits = new ConfigurationUnit[resultTypes.Length]; + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet); + + TestSettingsResult positiveResult = new TestSettingsResult(); + positiveResult.TestResult = ConfigurationTestResult.Positive; + + TestSettingsResult negativeResult = new TestSettingsResult(); + negativeResult.TestResult = ConfigurationTestResult.Negative; + + TestSettingsResult failedResult = new TestSettingsResult(); + failedResult.TestResult = ConfigurationTestResult.Failed; + failedResult.ResultInformation.ResultCode = new NullReferenceException(); + failedResult.ResultInformation.Description = "Failed again"; + + for (int i = 0; i < resultTypes.Length; ++i) + { + configurationUnits[i] = new ConfigurationUnit(); + configurationUnits[i].UnitName = $"Unit {i}"; + TestConfigurationUnitProcessor unitProcessor = setProcessor.CreateTestProcessor(configurationUnits[i]); + + switch (resultTypes[i]) + { + case ConfigurationTestResult.Positive: + unitProcessor.TestSettingsDelegate = () => positiveResult; + break; + case ConfigurationTestResult.Negative: + unitProcessor.TestSettingsDelegate = () => negativeResult; + break; + case ConfigurationTestResult.NotRun: + configurationUnits[i].Intent = ConfigurationUnitIntent.Inform; + break; + case ConfigurationTestResult.Failed: + unitProcessor.TestSettingsDelegate = () => failedResult; + break; + } + } + + configurationSet.ConfigurationUnits = configurationUnits; + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + TestConfigurationSetResult result = processor.TestSet(configurationSet); + + Assert.NotNull(result); + Assert.Equal(overallResult, result.TestResult); + Assert.NotNull(result.UnitResults); + Assert.Equal(resultTypes.Length, result.UnitResults.Count); + + for (int i = 0; i < resultTypes.Length; ++i) + { + TestConfigurationUnitResult unitResult = result.UnitResults.First(x => x.Unit == configurationUnits[i]); + + Assert.NotNull(unitResult); + Assert.Equal(resultTypes[i], unitResult.TestResult); + Assert.NotNull(unitResult.ResultInformation); + + switch (resultTypes[i]) + { + case ConfigurationTestResult.Positive: + case ConfigurationTestResult.Negative: + case ConfigurationTestResult.NotRun: + Assert.Null(unitResult.ResultInformation.ResultCode); + Assert.Empty(unitResult.ResultInformation.Description); + break; + case ConfigurationTestResult.Failed: + Assert.NotNull(unitResult.ResultInformation.ResultCode); + Assert.IsType(unitResult.ResultInformation.ResultCode); + Assert.Equal(failedResult.ResultInformation.Description, unitResult.ResultInformation.Description); + break; + } + } + } + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs index 25d707696d..c3e25138e0 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs @@ -16,7 +16,7 @@ namespace Microsoft.Management.Configuration.UnitTests.Tests using Xunit.Abstractions; /// - /// Unit tests for configuration set authoring (creating objects). + /// Unit tests for parsing configuration sets from streams. /// [Collection("UnitTestCollection")] public class OpenConfigurationSetTests : ConfigurationProcessorTestBase diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/ProcessorGetTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/ProcessorGetTests.cs new file mode 100644 index 0000000000..ba5ad2227f --- /dev/null +++ b/src/Microsoft.Management.Configuration.UnitTests/Tests/ProcessorGetTests.cs @@ -0,0 +1,188 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Tests +{ + using System.IO; + using System.Runtime.InteropServices; + using Microsoft.Management.Configuration.UnitTests.Fixtures; + using Microsoft.Management.Configuration.UnitTests.Helpers; + using Microsoft.VisualBasic; + using Xunit; + using Xunit.Abstractions; + + /// + /// Unit tests for getting details on processors. + /// + [Collection("UnitTestCollection")] + public class ProcessorGetTests : ConfigurationProcessorTestBase + { + /// + /// Initializes a new instance of the class. + /// + /// Unit test fixture. + /// Log helper. + public ProcessorGetTests(UnitTestFixture fixture, ITestOutputHelper log) + : base(fixture, log) + { + } + + /// + /// Getting unit details throws an error. + /// + [Fact] + public void GetUnitDetailsError() + { + ConfigurationUnit configurationUnitThrows = new ConfigurationUnit(); + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + factory.NullProcessor = new TestConfigurationSetProcessor(null); + factory.NullProcessor.Exceptions.Add(configurationUnitThrows, new FileNotFoundException()); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + Assert.Throws(() => processor.GetUnitDetails(configurationUnitThrows, ConfigurationUnitDetailLevel.Local)); + } + + /// + /// Getting unit details retrieves a value. + /// + [Fact] + public void GetUnitDetailsSuccess() + { + ConfigurationUnit configurationUnit = new ConfigurationUnit(); + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + Assert.Null(configurationUnit.Details); + processor.GetUnitDetails(configurationUnit, ConfigurationUnitDetailLevel.Local); + Assert.NotNull(configurationUnit.Details); + } + + /// + /// Getting set details throws an error. + /// + [Fact] + public void GetSetDetailsError() + { + ConfigurationSet configurationSet = new ConfigurationSet(); + ConfigurationUnit configurationUnitWorks = new ConfigurationUnit(); + ConfigurationUnit configurationUnitThrows = new ConfigurationUnit(); + configurationSet.ConfigurationUnits = new ConfigurationUnit[] { configurationUnitWorks, configurationUnitThrows }; + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet); + setProcessor.Exceptions.Add(configurationUnitThrows, new InvalidDataException()); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + Assert.Throws(() => processor.GetSetDetails(configurationSet, ConfigurationUnitDetailLevel.Local)); + Assert.NotNull(configurationUnitWorks.Details); + } + + /// + /// Getting set details retrieves all values. + /// + [Fact] + public void GetSetDetailsSuccess() + { + ConfigurationSet configurationSet = new ConfigurationSet(); + ConfigurationUnit configurationUnit1 = new ConfigurationUnit(); + ConfigurationUnit configurationUnit2 = new ConfigurationUnit(); + configurationSet.ConfigurationUnits = new ConfigurationUnit[] { configurationUnit1, configurationUnit2 }; + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + processor.GetSetDetails(configurationSet, ConfigurationUnitDetailLevel.Local); + Assert.NotNull(configurationUnit1.Details); + Assert.NotNull(configurationUnit2.Details); + } + + /// + /// The unit settings processor returns an error HRESULT. + /// + [Fact] + public void GetSettings_ProcessorSettingsError() + { + ConfigurationUnit configurationUnit = new ConfigurationUnit(); + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + factory.NullProcessor = new TestConfigurationSetProcessor(null); + TestConfigurationUnitProcessor unitProcessor = factory.NullProcessor.CreateTestProcessor(configurationUnit); + unitProcessor.GetSettingsDelegate = () => throw new FileNotFoundException(); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + GetConfigurationUnitSettingsResult result = processor.GetUnitSettings(configurationUnit); + + Assert.NotNull(result); + Assert.NotNull(result.Settings); + Assert.NotNull(result.ResultInformation); + Assert.NotNull(result.ResultInformation.ResultCode); + Assert.IsType(result.ResultInformation.ResultCode); + } + + /// + /// The unit settings processor returns an error in it's result. + /// + [Fact] + public void GetSettings_ProcessorSettingsFailedResult() + { + ConfigurationUnit configurationUnit = new ConfigurationUnit(); + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + factory.NullProcessor = new TestConfigurationSetProcessor(null); + TestConfigurationUnitProcessor unitProcessor = factory.NullProcessor.CreateTestProcessor(configurationUnit); + GetSettingsResult getSettingsResult = new GetSettingsResult(); + getSettingsResult.ResultInformation.ResultCode = new InvalidDataException(); + getSettingsResult.ResultInformation.Description = "We fail because we must"; + unitProcessor.GetSettingsDelegate = () => getSettingsResult; + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + GetConfigurationUnitSettingsResult result = processor.GetUnitSettings(configurationUnit); + + Assert.NotNull(result); + Assert.NotNull(result.Settings); + Assert.NotNull(result.ResultInformation); + Assert.Equal(getSettingsResult.ResultInformation.ResultCode.HResult, result.ResultInformation.ResultCode.HResult); + Assert.Equal(getSettingsResult.ResultInformation.Description, result.ResultInformation.Description); + } + + /// + /// The unit settings processor returns good settings. + /// + [Fact] + public void GetSettings_ProcessorSettingsSuccess() + { + ConfigurationUnit configurationUnit = new ConfigurationUnit(); + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + factory.NullProcessor = new TestConfigurationSetProcessor(null); + TestConfigurationUnitProcessor unitProcessor = factory.NullProcessor.CreateTestProcessor(configurationUnit); + GetSettingsResult getSettingsResult = new GetSettingsResult(); + getSettingsResult.Settings.Add("key", "value"); + unitProcessor.GetSettingsDelegate = () => getSettingsResult; + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + GetConfigurationUnitSettingsResult result = processor.GetUnitSettings(configurationUnit); + + Assert.NotNull(result); + Assert.NotNull(result.ResultInformation); + Assert.Null(result.ResultInformation.ResultCode); + Assert.Empty(result.ResultInformation.Description); + Assert.NotNull(result.Settings); + Assert.NotEmpty(result.Settings); + Assert.Contains("key", result.Settings); + Assert.IsType(result.Settings["key"]); + Assert.Equal("value", (string)result.Settings["key"]); + } + } +} diff --git a/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp index 8fd3194e80..ae663b147c 100644 --- a/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp +++ b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp @@ -3,15 +3,21 @@ #include "pch.h" #include "GetConfigurationUnitSettingsResult.h" #include "GetConfigurationUnitSettingsResult.g.cpp" +#include "ConfigurationUnitResultInformation.h" namespace winrt::Microsoft::Management::Configuration::implementation { + GetConfigurationUnitSettingsResult::GetConfigurationUnitSettingsResult() : + m_resultInformation(*make_self>()) + { + } + void GetConfigurationUnitSettingsResult::ResultInformation(const ConfigurationUnitResultInformation& resultInformation) { m_resultInformation = resultInformation; } - ConfigurationUnitResultInformation GetConfigurationUnitSettingsResult::ResultInformation() + Configuration::ConfigurationUnitResultInformation GetConfigurationUnitSettingsResult::ResultInformation() { return m_resultInformation; } diff --git a/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h index 2a76333778..0798679e57 100644 --- a/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h +++ b/src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h @@ -10,7 +10,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation { using ConfigurationUnitResultInformation = Configuration::ConfigurationUnitResultInformation; - GetConfigurationUnitSettingsResult() = default; + GetConfigurationUnitSettingsResult(); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void ResultInformation(const ConfigurationUnitResultInformation& resultInformation); @@ -22,8 +22,8 @@ namespace winrt::Microsoft::Management::Configuration::implementation #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: - ConfigurationUnitResultInformation m_resultInformation = nullptr; - Windows::Foundation::Collections::ValueSet m_settings = nullptr; + ConfigurationUnitResultInformation m_resultInformation; + Windows::Foundation::Collections::ValueSet m_settings; #endif }; } From 677b7ed3c596020e98f7b0f007b76bd0b5ffcfb2 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Tue, 7 Feb 2023 17:35:40 -0800 Subject: [PATCH 20/31] Changes to API and apply processing, more tests --- .../Helpers/TestConfigurationUnitProcessor.cs | 18 ++ .../Tests/ConfigurationProcessorApplyTests.cs | 256 ++++++++++++++++++ .../Tests/ProcessorGetTests.cs | 3 +- .../ApplyConfigurationUnitResult.cpp | 33 ++- .../ApplyConfigurationUnitResult.h | 7 +- .../ApplySettingsResult.cpp | 10 + .../ApplySettingsResult.h | 4 + .../ConfigurationSetApplyProcessor.cpp | 52 ++-- .../ConfigurationSetApplyProcessor.h | 4 +- .../ConfigurationUnitResultInformation.cpp | 6 + .../ConfigurationUnitResultInformation.h | 1 + .../GetSettingsResult.cpp | 5 + .../GetSettingsResult.h | 4 +- .../Microsoft.Management.Configuration.idl | 8 +- 14 files changed, 371 insertions(+), 40 deletions(-) create mode 100644 src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs index 36003e5699..5db7261bac 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs @@ -67,22 +67,38 @@ internal TestConfigurationUnitProcessor(ConfigurationUnit unit, IReadOnlyDiction /// internal ApplySettingsDelegateType? ApplySettingsDelegate { get; set; } + /// + /// Gets the number of times ApplySettings is called. + /// + internal int ApplySettingsCalls { get; private set; } = 0; + /// /// Gets or sets the delegate object for GetSettings. /// internal GetSettingsDelegateType? GetSettingsDelegate { get; set; } + /// + /// Gets the number of times GetSettings is called. + /// + internal int GetSettingsCalls { get; private set; } = 0; + /// /// Gets or sets the delegate object for TestSettings. /// internal TestSettingsDelegateType? TestSettingsDelegate { get; set; } + /// + /// Gets the number of times TestSettings is called. + /// + internal int TestSettingsCalls { get; private set; } = 0; + /// /// Calls the ApplySettingsDelegate if one is provided; returns success if not. /// /// The result. public ApplySettingsResult ApplySettings() { + ++this.ApplySettingsCalls; if (this.ApplySettingsDelegate != null) { return this.ApplySettingsDelegate(); @@ -99,6 +115,7 @@ public ApplySettingsResult ApplySettings() /// The result. public GetSettingsResult GetSettings() { + ++this.GetSettingsCalls; if (this.GetSettingsDelegate != null) { return this.GetSettingsDelegate(); @@ -115,6 +132,7 @@ public GetSettingsResult GetSettings() /// The result. public TestSettingsResult TestSettings() { + ++this.TestSettingsCalls; if (this.TestSettingsDelegate != null) { return this.TestSettingsDelegate(); diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs new file mode 100644 index 0000000000..5b01637699 --- /dev/null +++ b/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs @@ -0,0 +1,256 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Configuration.UnitTests.Tests +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Runtime.InteropServices; + using Microsoft.Management.Configuration.UnitTests.Fixtures; + using Microsoft.Management.Configuration.UnitTests.Helpers; + using Microsoft.VisualBasic; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; + using Xunit; + using Xunit.Abstractions; + + /// + /// Unit tests for running test on the processor. + /// + [Collection("UnitTestCollection")] + public class ConfigurationProcessorApplyTests : ConfigurationProcessorTestBase + { + /// + /// Initializes a new instance of the class. + /// + /// Unit test fixture. + /// Log helper. + public ConfigurationProcessorApplyTests(UnitTestFixture fixture, ITestOutputHelper log) + : base(fixture, log) + { + } + + /// + /// An error creating the set processor results in an error for the function. + /// + [Fact] + public void ApplySet_SetProcessorError() + { + ConfigurationSet configurationSet = new ConfigurationSet(); + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + factory.Exceptions.Add(configurationSet, new FileNotFoundException()); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + Assert.Throws(() => processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None)); + } + + /// + /// Multiple configuration units with the same identifier. + /// + [Fact] + public void ApplySet_DuplicateIdentifiers() + { + ConfigurationSet configurationSet = new ConfigurationSet(); + ConfigurationUnit configurationUnit1 = new ConfigurationUnit(); + ConfigurationUnit configurationUnit2 = new ConfigurationUnit(); + ConfigurationUnit configurationUnitDifferentIdentifier = new ConfigurationUnit(); + string sharedIdentifier = "SameIdentifier"; + configurationUnit1.Identifier = sharedIdentifier; + configurationUnit2.Identifier = sharedIdentifier; + configurationSet.ConfigurationUnits = new ConfigurationUnit[] { configurationUnit1, configurationUnit2, configurationUnitDifferentIdentifier }; + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None); + Assert.NotNull(result); + Assert.NotNull(result.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER, result.ResultCode.HResult); + Assert.Equal(3, result.UnitResults.Count); + + foreach (var configurationUnit in new ConfigurationUnit[] { configurationUnit1, configurationUnit2 }) + { + ApplyConfigurationUnitResult unitResult = result.UnitResults.First(x => x.Unit == configurationUnit); + Assert.NotNull(unitResult); + Assert.False(unitResult.PreviouslyInDesiredState); + Assert.False(unitResult.RebootRequired); + Assert.NotNull(unitResult.ResultInformation); + Assert.NotNull(unitResult.ResultInformation.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER, unitResult.ResultInformation.ResultCode.HResult); + } + + ApplyConfigurationUnitResult unitResultDifferentIdentifier = result.UnitResults.First(x => x.Unit == configurationUnitDifferentIdentifier); + Assert.NotNull(unitResultDifferentIdentifier); + Assert.False(unitResultDifferentIdentifier.PreviouslyInDesiredState); + Assert.False(unitResultDifferentIdentifier.RebootRequired); + Assert.NotNull(unitResultDifferentIdentifier.ResultInformation); + Assert.Null(unitResultDifferentIdentifier.ResultInformation.ResultCode); + } + + /// + /// A configuration unit has a dependency that is not in the set. + /// + [Fact] + public void ApplySet_MissingDependency() + { + ConfigurationSet configurationSet = new ConfigurationSet(); + ConfigurationUnit configurationUnit = new ConfigurationUnit(); + ConfigurationUnit configurationUnitMissingDependency = new ConfigurationUnit(); + configurationUnit.Identifier = "Identifier"; + configurationUnitMissingDependency.Dependencies = new string[] { "Dependency" }; + configurationSet.ConfigurationUnits = new ConfigurationUnit[] { configurationUnit, configurationUnitMissingDependency }; + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None); + Assert.NotNull(result); + Assert.NotNull(result.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_MISSING_DEPENDENCY, result.ResultCode.HResult); + Assert.Equal(2, result.UnitResults.Count); + + ApplyConfigurationUnitResult unitResult = result.UnitResults.First(x => x.Unit == configurationUnit); + Assert.NotNull(unitResult); + Assert.False(unitResult.PreviouslyInDesiredState); + Assert.False(unitResult.RebootRequired); + Assert.NotNull(unitResult.ResultInformation); + Assert.Null(unitResult.ResultInformation.ResultCode); + + unitResult = result.UnitResults.First(x => x.Unit == configurationUnitMissingDependency); + Assert.NotNull(unitResult); + Assert.False(unitResult.PreviouslyInDesiredState); + Assert.False(unitResult.RebootRequired); + Assert.NotNull(unitResult.ResultInformation); + Assert.NotNull(unitResult.ResultInformation.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_MISSING_DEPENDENCY, unitResult.ResultInformation.ResultCode.HResult); + } + + /// + /// The configuration set has a dependency cycle. + /// + [Fact] + public void ApplySet_DependencyCycle() + { + ConfigurationSet configurationSet = new ConfigurationSet(); + ConfigurationUnit configurationUnit1 = new ConfigurationUnit(); + ConfigurationUnit configurationUnit2 = new ConfigurationUnit(); + ConfigurationUnit configurationUnit3 = new ConfigurationUnit(); + configurationUnit1.Identifier = "Identifier1"; + configurationUnit2.Identifier = "Identifier2"; + configurationUnit3.Identifier = "Identifier3"; + configurationUnit1.Dependencies = new string[] { "Identifier3" }; + configurationUnit2.Dependencies = new string[] { "Identifier1" }; + configurationUnit3.Dependencies = new string[] { "Identifier2" }; + configurationSet.ConfigurationUnits = new ConfigurationUnit[] { configurationUnit1, configurationUnit2, configurationUnit3 }; + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None); + Assert.NotNull(result); + Assert.NotNull(result.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED, result.ResultCode.HResult); + Assert.Equal(3, result.UnitResults.Count); + + foreach (var unitResult in result.UnitResults) + { + Assert.NotNull(unitResult); + Assert.False(unitResult.PreviouslyInDesiredState); + Assert.False(unitResult.RebootRequired); + Assert.NotNull(unitResult.ResultInformation); + Assert.NotNull(unitResult.ResultInformation.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED, unitResult.ResultInformation.ResultCode.HResult); + } + } + + /// + /// Checks that the intent for configuration units is handled properly. + /// + [Fact] + public void ApplySet_IntentRespected() + { + ConfigurationSet configurationSet = new ConfigurationSet(); + ConfigurationUnit configurationUnitAssert = new ConfigurationUnit { Intent = ConfigurationUnitIntent.Assert }; + ConfigurationUnit configurationUnitInform = new ConfigurationUnit { Intent = ConfigurationUnitIntent.Inform }; + ConfigurationUnit configurationUnitApply = new ConfigurationUnit { Intent = ConfigurationUnitIntent.Apply }; + configurationSet.ConfigurationUnits = new ConfigurationUnit[] { configurationUnitInform, configurationUnitApply, configurationUnitAssert }; + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet); + TestConfigurationUnitProcessor unitProcessorAssert = setProcessor.CreateTestProcessor(configurationUnitAssert); + TestConfigurationUnitProcessor unitProcessorInform = setProcessor.CreateTestProcessor(configurationUnitInform); + TestConfigurationUnitProcessor unitProcessorApply = setProcessor.CreateTestProcessor(configurationUnitApply); + unitProcessorApply.TestSettingsDelegate = () => new TestSettingsResult { TestResult = ConfigurationTestResult.Negative }; + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None); + Assert.NotNull(result); + Assert.Null(result.ResultCode); + Assert.Equal(3, result.UnitResults.Count); + + foreach (var unitResult in result.UnitResults) + { + Assert.NotNull(unitResult); + Assert.False(unitResult.PreviouslyInDesiredState); + Assert.False(unitResult.RebootRequired); + Assert.NotNull(unitResult.ResultInformation); + Assert.Null(unitResult.ResultInformation.ResultCode); + } + + Assert.Equal(1, unitProcessorAssert.TestSettingsCalls); + Assert.Equal(0, unitProcessorAssert.GetSettingsCalls); + Assert.Equal(0, unitProcessorAssert.ApplySettingsCalls); + + Assert.Equal(0, unitProcessorInform.TestSettingsCalls); + Assert.Equal(1, unitProcessorInform.GetSettingsCalls); + Assert.Equal(0, unitProcessorInform.ApplySettingsCalls); + + Assert.Equal(1, unitProcessorApply.TestSettingsCalls); + Assert.Equal(0, unitProcessorApply.GetSettingsCalls); + Assert.Equal(1, unitProcessorApply.ApplySettingsCalls); + } + + /// + /// An assertion fails to run. + /// + [Fact] + public void ApplySet_AssertionFailure() + { + } + + /// + /// An assertion is found to be false. + /// + [Fact] + public void ApplySet_AssertionNegative() + { + } + + /// + /// A unit in the correct state is not applied again. + /// + [Fact] + public void ApplySet_UnitAlreadyInCorrectState() + { + } + + /// + /// Checks the progress reporting. + /// + [Fact] + public void ApplySet_Progress() + { + } + } +} diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/ProcessorGetTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/ProcessorGetTests.cs index ba5ad2227f..a7e94f9bf5 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Tests/ProcessorGetTests.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Tests/ProcessorGetTests.cs @@ -149,7 +149,7 @@ public void GetSettings_ProcessorSettingsFailedResult() GetConfigurationUnitSettingsResult result = processor.GetUnitSettings(configurationUnit); Assert.NotNull(result); - Assert.NotNull(result.Settings); + Assert.Null(result.Settings); Assert.NotNull(result.ResultInformation); Assert.Equal(getSettingsResult.ResultInformation.ResultCode.HResult, result.ResultInformation.ResultCode.HResult); Assert.Equal(getSettingsResult.ResultInformation.Description, result.ResultInformation.Description); @@ -167,6 +167,7 @@ public void GetSettings_ProcessorSettingsSuccess() factory.NullProcessor = new TestConfigurationSetProcessor(null); TestConfigurationUnitProcessor unitProcessor = factory.NullProcessor.CreateTestProcessor(configurationUnit); GetSettingsResult getSettingsResult = new GetSettingsResult(); + getSettingsResult.Settings = new Windows.Foundation.Collections.ValueSet(); getSettingsResult.Settings.Add("key", "value"); unitProcessor.GetSettingsDelegate = () => getSettingsResult; diff --git a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp index 0dd9d10a6b..c8032abf42 100644 --- a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp +++ b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp @@ -3,19 +3,18 @@ #include "pch.h" #include "ApplyConfigurationUnitResult.h" #include "ApplyConfigurationUnitResult.g.cpp" +#include "ConfigurationUnitResultInformation.h" namespace winrt::Microsoft::Management::Configuration::implementation { - void ApplyConfigurationUnitResult::Initialize(const ConfigurationUnit& unit, bool previouslyInDesiredState, const ConfigurationUnitResultInformation& resultInformation) + ConfigurationUnit ApplyConfigurationUnitResult::Unit() { - m_unit = unit; - m_previouslyInDesiredState = previouslyInDesiredState; - m_resultInformation = resultInformation; + return m_unit; } - ConfigurationUnit ApplyConfigurationUnitResult::Unit() + void ApplyConfigurationUnitResult::Unit(ConfigurationUnit value) { - return m_unit; + m_unit = std::move(value); } bool ApplyConfigurationUnitResult::PreviouslyInDesiredState() const @@ -23,8 +22,28 @@ namespace winrt::Microsoft::Management::Configuration::implementation return m_previouslyInDesiredState; } - ConfigurationUnitResultInformation ApplyConfigurationUnitResult::ResultInformation() + void ApplyConfigurationUnitResult::PreviouslyInDesiredState(bool value) + { + m_previouslyInDesiredState = value; + } + + bool ApplyConfigurationUnitResult::RebootRequired() const + { + return m_rebootRequired; + } + + void ApplyConfigurationUnitResult::RebootRequired(bool value) + { + m_rebootRequired = value; + } + + Configuration::ConfigurationUnitResultInformation ApplyConfigurationUnitResult::ResultInformation() { return m_resultInformation; } + + void ApplyConfigurationUnitResult::ResultInformation(ConfigurationUnitResultInformation value) + { + m_resultInformation = std::move(value); + } } diff --git a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h index 2f14471ae7..a0ba725fdd 100644 --- a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h +++ b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h @@ -13,17 +13,22 @@ namespace winrt::Microsoft::Management::Configuration::implementation ApplyConfigurationUnitResult() = default; #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) - void Initialize(const ConfigurationUnit& unit, bool previouslyInDesiredState, const ConfigurationUnitResultInformation& resultInformation); + void Unit(ConfigurationUnit value); + void PreviouslyInDesiredState(bool value); + void RebootRequired(bool value); + void ResultInformation(ConfigurationUnitResultInformation value); #endif ConfigurationUnit Unit(); bool PreviouslyInDesiredState() const; + bool RebootRequired() const; ConfigurationUnitResultInformation ResultInformation(); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: ConfigurationUnit m_unit = nullptr; bool m_previouslyInDesiredState = false; + bool m_rebootRequired = false; ConfigurationUnitResultInformation m_resultInformation = nullptr; #endif }; diff --git a/src/Microsoft.Management.Configuration/ApplySettingsResult.cpp b/src/Microsoft.Management.Configuration/ApplySettingsResult.cpp index 3e1b8fbc97..8c6a398921 100644 --- a/src/Microsoft.Management.Configuration/ApplySettingsResult.cpp +++ b/src/Microsoft.Management.Configuration/ApplySettingsResult.cpp @@ -12,6 +12,16 @@ namespace winrt::Microsoft::Management::Configuration::implementation { } + bool ApplySettingsResult::RebootRequired() const + { + return m_rebootRequired; + } + + void ApplySettingsResult::RebootRequired(bool value) + { + m_rebootRequired = value; + } + Configuration::ConfigurationUnitResultInformation ApplySettingsResult::ResultInformation() { return m_resultInformation; diff --git a/src/Microsoft.Management.Configuration/ApplySettingsResult.h b/src/Microsoft.Management.Configuration/ApplySettingsResult.h index baa08d50da..ed42a9627c 100644 --- a/src/Microsoft.Management.Configuration/ApplySettingsResult.h +++ b/src/Microsoft.Management.Configuration/ApplySettingsResult.h @@ -9,9 +9,13 @@ namespace winrt::Microsoft::Management::Configuration::implementation { ApplySettingsResult(); + bool RebootRequired() const; + void RebootRequired(bool value); + Configuration::ConfigurationUnitResultInformation ResultInformation(); private: + bool m_rebootRequired = false; Configuration::ConfigurationUnitResultInformation m_resultInformation; }; } diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp index e6c0a7044e..9c214cdbfd 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp @@ -56,9 +56,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation for (const auto& unitInfo : m_unitInfo) { - auto result = make_self>(); - result->Initialize(unitInfo.Unit, unitInfo.PreviouslyInDesiredState, *unitInfo.Result); - unitResults.emplace_back(*result); + unitResults.emplace_back(*unitInfo.Result); } return unitResults; @@ -70,8 +68,11 @@ namespace winrt::Microsoft::Management::Configuration::implementation } ConfigurationSetApplyProcessor::UnitInfo::UnitInfo(const Configuration::ConfigurationUnit& unit) : - Unit(unit), Result(make_self>()) + Unit(unit), Result(make_self>()), + ResultInformation(make_self>()) { + Result->Unit(unit); + Result->ResultInformation(*ResultInformation); } bool ConfigurationSetApplyProcessor::PreProcess() @@ -108,7 +109,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation if (itr == m_idToUnitInfoIndex.end()) { AICLI_LOG(Config, Error, << "Found missing dependency: " << dependency); - unitInfo.Result->ResultCode(WINGET_CONFIG_ERROR_MISSING_DEPENDENCY); + unitInfo.ResultInformation->ResultCode(WINGET_CONFIG_ERROR_MISSING_DEPENDENCY); result = false; } else @@ -143,8 +144,8 @@ namespace winrt::Microsoft::Management::Configuration::implementation { AICLI_LOG(Config, Error, << "Found duplicate identifier: " << identifier); // Found a duplicate identifier, mark both as such - unitInfo.Result->ResultCode(WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER); - m_unitInfo[itr->second].Result->ResultCode(WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER); + unitInfo.ResultInformation->ResultCode(WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER); + m_unitInfo[itr->second].ResultInformation->ResultCode(WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER); return false; } else @@ -243,7 +244,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation if (unitInfo.Unit.Intent() == intent) { hasRemainingDependencies = true; - unitInfo.Result->ResultCode(WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED); + unitInfo.ResultInformation->ResultCode(WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED); if (sendProgress) { SendProgress(ConfigurationUnitState::SkippedDueToDependencies, unitInfo); @@ -259,7 +260,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation UnitInfo& unitInfo = m_unitInfo[index]; if (unitInfo.Unit.Intent() != intent) { - unitInfo.Result->ResultCode(errorForOtherIntents); + unitInfo.ResultInformation->ResultCode(errorForOtherIntents); if (sendProgress) { SendProgress(progressForOtherIntents, unitInfo); @@ -317,7 +318,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation bool ConfigurationSetApplyProcessor::HasProcessedSuccessfully(const UnitInfo& unitInfo) { - return unitInfo.Processed && SUCCEEDED(unitInfo.Result->ResultCode()); + return unitInfo.Processed && SUCCEEDED(unitInfo.ResultInformation->ResultCode()); } bool ConfigurationSetApplyProcessor::ProcessUnit(UnitInfo& unitInfo) @@ -331,7 +332,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation { // If the unit is requested to be skipped, we mark it with a failure to prevent any dependency from running. // But we return true from this function to indicate a successful "processing". - unitInfo.Result->ResultCode(WINGET_CONFIG_ERROR_MANUALLY_SKIPPED); + unitInfo.ResultInformation->ResultCode(WINGET_CONFIG_ERROR_MANUALLY_SKIPPED); SendProgress(ConfigurationUnitState::SkippedManually, unitInfo); return true; } @@ -346,7 +347,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation } catch (...) { - ExtractUnitResultInformation(std::current_exception(), unitInfo.Result); + ExtractUnitResultInformation(std::current_exception(), unitInfo.ResultInformation); return false; } @@ -364,18 +365,17 @@ namespace winrt::Microsoft::Management::Configuration::implementation } else if (settingsResult.TestResult() == ConfigurationTestResult::Negative) { - unitInfo.Result->ResultCode(WINGET_CONFIG_ERROR_ASSERTION_FAILED); + unitInfo.ResultInformation->ResultCode(WINGET_CONFIG_ERROR_ASSERTION_FAILED); return false; } else if (settingsResult.TestResult() == ConfigurationTestResult::Failed) { - unitInfo.Result->ResultCode(settingsResult.ResultInformation().ResultCode()); - unitInfo.Result->Description(settingsResult.ResultInformation().Description()); + unitInfo.ResultInformation->Initialize(settingsResult.ResultInformation()); return false; } else { - unitInfo.Result->ResultCode(E_UNEXPECTED); + unitInfo.ResultInformation->ResultCode(E_UNEXPECTED); return false; } } @@ -389,8 +389,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation } else { - unitInfo.Result->ResultCode(settingsResult.ResultInformation().ResultCode()); - unitInfo.Result->Description(settingsResult.ResultInformation().Description()); + unitInfo.ResultInformation->Initialize(settingsResult.ResultInformation()); return false; } } @@ -400,7 +399,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation if (testSettingsResult.TestResult() == ConfigurationTestResult::Positive) { - unitInfo.PreviouslyInDesiredState = true; + unitInfo.Result->PreviouslyInDesiredState(true); return true; } else if (testSettingsResult.TestResult() == ConfigurationTestResult::Negative) @@ -408,35 +407,34 @@ namespace winrt::Microsoft::Management::Configuration::implementation ApplySettingsResult applySettingsResult = unitProcessor.ApplySettings(); if (SUCCEEDED(applySettingsResult.ResultInformation().ResultCode())) { + unitInfo.Result->RebootRequired(applySettingsResult.RebootRequired()); return true; } else { - unitInfo.Result->ResultCode(applySettingsResult.ResultInformation().ResultCode()); - unitInfo.Result->Description(applySettingsResult.ResultInformation().Description()); + unitInfo.ResultInformation->Initialize(applySettingsResult.ResultInformation()); return false; } } else if (testSettingsResult.TestResult() == ConfigurationTestResult::Failed) { - unitInfo.Result->ResultCode(testSettingsResult.ResultInformation().ResultCode()); - unitInfo.Result->Description(testSettingsResult.ResultInformation().Description()); + unitInfo.ResultInformation->Initialize(testSettingsResult.ResultInformation()); return false; } else { - unitInfo.Result->ResultCode(E_UNEXPECTED); + unitInfo.ResultInformation->ResultCode(E_UNEXPECTED); return false; } } default: - unitInfo.Result->ResultCode(E_UNEXPECTED); + unitInfo.ResultInformation->ResultCode(E_UNEXPECTED); return false; } } catch (...) { - ExtractUnitResultInformation(std::current_exception(), unitInfo.Result); + ExtractUnitResultInformation(std::current_exception(), unitInfo.ResultInformation); return false; } } @@ -459,7 +457,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation { try { - m_progress(implementation::ConfigurationSetChangeData::Create(state, *unitInfo.Result, unitInfo.Unit)); + m_progress(implementation::ConfigurationSetChangeData::Create(state, *unitInfo.ResultInformation, unitInfo.Unit)); } CATCH_LOG(); } diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h index 4f20751f0c..278b828088 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h +++ b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h @@ -39,8 +39,8 @@ namespace winrt::Microsoft::Management::Configuration::implementation ConfigurationUnit Unit; std::vector DependencyIndices; - decltype(make_self>()) Result; - bool PreviouslyInDesiredState = false; + decltype(make_self>()) Result; + decltype(make_self>()) ResultInformation; bool PreProcessed = false; bool Processed = false; }; diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp index 926ef9d5cd..fc7de5509e 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp @@ -6,6 +6,12 @@ namespace winrt::Microsoft::Management::Configuration::implementation { + void ConfigurationUnitResultInformation::Initialize(const Configuration::ConfigurationUnitResultInformation& other) + { + m_resultCode = other.ResultCode(); + m_description = other.Description(); + } + void ConfigurationUnitResultInformation::Initialize(hresult resultCode, std::wstring_view description) { m_resultCode = resultCode; diff --git a/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h index c2e6079d05..087bd4359a 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h +++ b/src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h @@ -10,6 +10,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation ConfigurationUnitResultInformation() = default; #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) + void Initialize(const Configuration::ConfigurationUnitResultInformation& other); void Initialize(hresult resultCode, std::wstring_view description); void Initialize(hresult resultCode, hstring description); #endif diff --git a/src/Microsoft.Management.Configuration/GetSettingsResult.cpp b/src/Microsoft.Management.Configuration/GetSettingsResult.cpp index fd530bfb09..c3c4c1b230 100644 --- a/src/Microsoft.Management.Configuration/GetSettingsResult.cpp +++ b/src/Microsoft.Management.Configuration/GetSettingsResult.cpp @@ -17,6 +17,11 @@ namespace winrt::Microsoft::Management::Configuration::implementation return m_settings; } + void GetSettingsResult::Settings(Windows::Foundation::Collections::ValueSet value) + { + m_settings = std::move(value); + } + Configuration::ConfigurationUnitResultInformation GetSettingsResult::ResultInformation() { return m_resultInformation; diff --git a/src/Microsoft.Management.Configuration/GetSettingsResult.h b/src/Microsoft.Management.Configuration/GetSettingsResult.h index 6259970c80..c2f3f8369b 100644 --- a/src/Microsoft.Management.Configuration/GetSettingsResult.h +++ b/src/Microsoft.Management.Configuration/GetSettingsResult.h @@ -11,10 +11,12 @@ namespace winrt::Microsoft::Management::Configuration::implementation GetSettingsResult(); Windows::Foundation::Collections::ValueSet Settings(); + void Settings(Windows::Foundation::Collections::ValueSet value); + Configuration::ConfigurationUnitResultInformation ResultInformation(); private: - Windows::Foundation::Collections::ValueSet m_settings; + Windows::Foundation::Collections::ValueSet m_settings = nullptr; Configuration::ConfigurationUnitResultInformation m_resultInformation; }; } diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl index 407c7d784b..6847c590ff 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -256,6 +256,9 @@ namespace Microsoft.Management.Configuration { ApplySettingsResult(); + // Indicates whether a reboot is required after the settings were applied. + Boolean RebootRequired; + // The result of applying the configuration unit. ConfigurationUnitResultInformation ResultInformation{ get; }; } @@ -297,7 +300,7 @@ namespace Microsoft.Management.Configuration GetSettingsResult(); // The current state of the system for the configuration unit. - Windows.Foundation.Collections.ValueSet Settings { get; }; + Windows.Foundation.Collections.ValueSet Settings; // The result of getting the configuration unit settings. // This is not the response for the retrieval, but rather contains information about the actual attempt to retrieve the settings. @@ -479,6 +482,9 @@ namespace Microsoft.Management.Configuration // Will be true if the configuration unit was in the desired state (Test returns true) prior to the apply action. Boolean PreviouslyInDesiredState{ get; }; + // Indicates whether a reboot is required after the configuration unit was applied. + Boolean RebootRequired{ get; }; + // The result of applying the configuration unit. ConfigurationUnitResultInformation ResultInformation{ get; }; } From 37fe8327da9f9bde9874eac62793779b6b0db5bc Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Wed, 8 Feb 2023 16:04:05 -0800 Subject: [PATCH 21/31] Code complete? --- .../TestConfigurationProcessorFactory.cs | 28 +++ .../Tests/ConfigurationProcessorApplyTests.cs | 183 +++++++++++++++ .../ApplyConfigurationSetResult.cpp | 18 +- .../ApplyConfigurationSetResult.h | 7 +- .../ConfigurationProcessor.cpp | 222 +++++++++--------- .../ConfigurationProcessor.h | 7 +- .../ConfigurationSetApplyProcessor.cpp | 42 ++-- .../ConfigurationSetApplyProcessor.h | 14 +- 8 files changed, 368 insertions(+), 153 deletions(-) diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs index 6bc42c2a39..37628e2513 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs @@ -14,6 +14,14 @@ namespace Microsoft.Management.Configuration.UnitTests.Helpers /// internal class TestConfigurationProcessorFactory : IConfigurationProcessorFactory { + /// + /// Delegate type for CreateSetProcessor. + /// + /// The TestConfigurationProcessorFactory that is calling this function. + /// The set. + /// A new TestConfigurationSetProcessor for the set. + internal delegate IConfigurationSetProcessor CreateSetProcessorDelegateType(TestConfigurationProcessorFactory factory, ConfigurationSet configurationSet); + /// /// Gets or sets the processor used when the incoming configuration set is null. /// @@ -36,12 +44,32 @@ internal class TestConfigurationProcessorFactory : IConfigurationProcessorFactor internal Dictionary Exceptions { get; set; } = new Dictionary(); + /// + /// Gets or sets the delegate use to replace the default CreateSetProcessor functionality. + /// + internal CreateSetProcessorDelegateType? CreateSetProcessorDelegate { get; set; } + /// /// Creates a new TestConfigurationSetProcessor for the set. /// /// The set. /// A new TestConfigurationSetProcessor for the set. public IConfigurationSetProcessor CreateSetProcessor(ConfigurationSet configurationSet) + { + if (this.CreateSetProcessorDelegate != null) + { + return this.CreateSetProcessorDelegate(this, configurationSet); + } + + return this.DefaultCreateSetProcessor(configurationSet); + } + + /// + /// The default test implementation that creates a new TestConfigurationSetProcessor for the set. + /// + /// The set. + /// A new TestConfigurationSetProcessor for the set. + internal IConfigurationSetProcessor DefaultCreateSetProcessor(ConfigurationSet configurationSet) { if (configurationSet == null) { diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs index 5b01637699..054b1c58a6 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs @@ -12,6 +12,7 @@ namespace Microsoft.Management.Configuration.UnitTests.Tests using System.IO; using System.Linq; using System.Runtime.InteropServices; + using System.Threading; using Microsoft.Management.Configuration.UnitTests.Fixtures; using Microsoft.Management.Configuration.UnitTests.Helpers; using Microsoft.VisualBasic; @@ -227,6 +228,41 @@ public void ApplySet_IntentRespected() [Fact] public void ApplySet_AssertionFailure() { + ConfigurationSet configurationSet = new ConfigurationSet(); + ConfigurationUnit configurationUnitAssert = new ConfigurationUnit { Intent = ConfigurationUnitIntent.Assert }; + ConfigurationUnit configurationUnitApply = new ConfigurationUnit { Intent = ConfigurationUnitIntent.Apply }; + configurationSet.ConfigurationUnits = new ConfigurationUnit[] { configurationUnitApply, configurationUnitAssert }; + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet); + TestConfigurationUnitProcessor unitProcessorAssert = setProcessor.CreateTestProcessor(configurationUnitAssert); + unitProcessorAssert.TestSettingsDelegate = () => throw new NullReferenceException(); + TestConfigurationUnitProcessor unitProcessorApply = setProcessor.CreateTestProcessor(configurationUnitApply); + unitProcessorApply.TestSettingsDelegate = () => new TestSettingsResult { TestResult = ConfigurationTestResult.Negative }; + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None); + Assert.NotNull(result); + Assert.NotNull(result.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_ASSERTION_FAILED, result.ResultCode.HResult); + Assert.Equal(2, result.UnitResults.Count); + + ApplyConfigurationUnitResult unitResult = result.UnitResults.First(x => x.Unit == configurationUnitAssert); + Assert.NotNull(unitResult); + Assert.False(unitResult.PreviouslyInDesiredState); + Assert.False(unitResult.RebootRequired); + Assert.NotNull(unitResult.ResultInformation); + Assert.NotNull(unitResult.ResultInformation.ResultCode); + Assert.IsType(unitResult.ResultInformation.ResultCode); + + unitResult = result.UnitResults.First(x => x.Unit == configurationUnitApply); + Assert.NotNull(unitResult); + Assert.False(unitResult.PreviouslyInDesiredState); + Assert.False(unitResult.RebootRequired); + Assert.NotNull(unitResult.ResultInformation); + Assert.NotNull(unitResult.ResultInformation.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_ASSERTION_FAILED, unitResult.ResultInformation.ResultCode.HResult); } /// @@ -235,6 +271,35 @@ public void ApplySet_AssertionFailure() [Fact] public void ApplySet_AssertionNegative() { + ConfigurationSet configurationSet = new ConfigurationSet(); + ConfigurationUnit configurationUnitAssert = new ConfigurationUnit { Intent = ConfigurationUnitIntent.Assert }; + ConfigurationUnit configurationUnitApply = new ConfigurationUnit { Intent = ConfigurationUnitIntent.Apply }; + configurationSet.ConfigurationUnits = new ConfigurationUnit[] { configurationUnitApply, configurationUnitAssert }; + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet); + TestConfigurationUnitProcessor unitProcessorAssert = setProcessor.CreateTestProcessor(configurationUnitAssert); + unitProcessorAssert.TestSettingsDelegate = () => new TestSettingsResult { TestResult = ConfigurationTestResult.Negative }; + TestConfigurationUnitProcessor unitProcessorApply = setProcessor.CreateTestProcessor(configurationUnitApply); + unitProcessorApply.TestSettingsDelegate = () => new TestSettingsResult { TestResult = ConfigurationTestResult.Negative }; + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None); + Assert.NotNull(result); + Assert.NotNull(result.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_ASSERTION_FAILED, result.ResultCode.HResult); + Assert.Equal(2, result.UnitResults.Count); + + foreach (var unitResult in result.UnitResults) + { + Assert.NotNull(unitResult); + Assert.False(unitResult.PreviouslyInDesiredState); + Assert.False(unitResult.RebootRequired); + Assert.NotNull(unitResult.ResultInformation); + Assert.NotNull(unitResult.ResultInformation.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_ASSERTION_FAILED, unitResult.ResultInformation.ResultCode.HResult); + } } /// @@ -243,6 +308,28 @@ public void ApplySet_AssertionNegative() [Fact] public void ApplySet_UnitAlreadyInCorrectState() { + ConfigurationSet configurationSet = new ConfigurationSet(); + ConfigurationUnit configurationUnit = new ConfigurationUnit { Intent = ConfigurationUnitIntent.Apply }; + configurationSet.ConfigurationUnits = new ConfigurationUnit[] { configurationUnit }; + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet); + TestConfigurationUnitProcessor unitProcessor = setProcessor.CreateTestProcessor(configurationUnit); + unitProcessor.TestSettingsDelegate = () => new TestSettingsResult { TestResult = ConfigurationTestResult.Positive }; + + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + + ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None); + Assert.NotNull(result); + Assert.Null(result.ResultCode); + Assert.Equal(1, result.UnitResults.Count); + + ApplyConfigurationUnitResult unitResult = result.UnitResults.First(); + Assert.NotNull(unitResult); + Assert.True(unitResult.PreviouslyInDesiredState); + Assert.False(unitResult.RebootRequired); + Assert.NotNull(unitResult.ResultInformation); + Assert.Null(unitResult.ResultInformation.ResultCode); } /// @@ -251,6 +338,102 @@ public void ApplySet_UnitAlreadyInCorrectState() [Fact] public void ApplySet_Progress() { + ConfigurationSet configurationSet = new ConfigurationSet(); + ConfigurationUnit assert1 = new ConfigurationUnit() { Intent = ConfigurationUnitIntent.Assert, Identifier = "Assert1" }; + ConfigurationUnit assert2 = new ConfigurationUnit() { Intent = ConfigurationUnitIntent.Assert, Identifier = "Assert2", Dependencies = new string[] { assert1.Identifier } }; + ConfigurationUnit inform1 = new ConfigurationUnit() { Intent = ConfigurationUnitIntent.Inform, Identifier = "Inform1" }; + ConfigurationUnit apply1 = new ConfigurationUnit() { Intent = ConfigurationUnitIntent.Apply, Identifier = "Apply1" }; + ConfigurationUnit apply2 = new ConfigurationUnit() { Intent = ConfigurationUnitIntent.Apply, Identifier = "Apply2" }; + ConfigurationUnit apply3 = new ConfigurationUnit() { Intent = ConfigurationUnitIntent.Apply, Identifier = "Apply3", Dependencies = new string[] { apply1.Identifier, apply2.Identifier } }; + ConfigurationUnit apply4 = new ConfigurationUnit() { Intent = ConfigurationUnitIntent.Apply, Identifier = "Apply4", ShouldApply = false }; + ConfigurationUnit apply5 = new ConfigurationUnit() { Intent = ConfigurationUnitIntent.Apply, Identifier = "Apply5", Dependencies = new string[] { apply4.Identifier } }; + configurationSet.ConfigurationUnits = new ConfigurationUnit[] { assert2, assert1, inform1, apply1, apply3, apply4, apply2, apply5 }; + + ManualResetEvent startProcessing = new ManualResetEvent(false); + + TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory(); + factory.CreateSetProcessorDelegate = (f, c) => + { + startProcessing.WaitOne(); + return f.DefaultCreateSetProcessor(c); + }; + ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory); + List progressEvents = new List(); + + var operation = processor.ApplySetAsync(configurationSet, ApplyConfigurationSetFlags.None); + operation.Progress = (asyncInfo, progress) => progressEvents.Add(progress); + startProcessing.Set(); + operation.AsTask().Wait(); + ApplyConfigurationSetResult result = operation.GetResults(); + + Assert.NotNull(result); + Assert.NotNull(result.ResultCode); + Assert.Equal(Errors.WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED, result.ResultCode.HResult); + Assert.NotNull(result.UnitResults); + Assert.Equal(configurationSet.ConfigurationUnits.Count, result.UnitResults.Count); + + // Verify that progress events match the expected + ExpectedConfigurationChangeData[] expectedProgress = new ExpectedConfigurationChangeData[] + { + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.SetStateChanged, SetState = ConfigurationSetState.InProgress }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.InProgress, Unit = assert1 }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = assert1 }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.InProgress, Unit = assert2 }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = assert2 }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.InProgress, Unit = inform1 }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = inform1 }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.InProgress, Unit = apply1 }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = apply1 }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.SkippedManually, Unit = apply4, HResult = Errors.WINGET_CONFIG_ERROR_MANUALLY_SKIPPED }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.InProgress, Unit = apply2 }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = apply2 }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.InProgress, Unit = apply3 }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = apply3 }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.SkippedDueToDependencies, Unit = apply5, HResult = Errors.WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.SetStateChanged, SetState = ConfigurationSetState.Completed }, + }; + + Assert.Equal(expectedProgress.Count(), progressEvents.Count); + + for (int i = 0; i < progressEvents.Count; ++i) + { + this.Log.WriteLine($"Comparing event {i}"); + Assert.Equal(expectedProgress[i].Change, progressEvents[i].Change); + switch (expectedProgress[i].Change) + { + case ConfigurationSetChangeEventType.SetStateChanged: + Assert.Equal(expectedProgress[i].SetState, progressEvents[i].SetState); + break; + case ConfigurationSetChangeEventType.UnitStateChanged: + Assert.Equal(expectedProgress[i].UnitState, progressEvents[i].UnitState); + Assert.Same(expectedProgress[i].Unit, progressEvents[i].Unit); + + Assert.NotNull(progressEvents[i].ResultInformation); + if (expectedProgress[i].HResult == 0) + { + Assert.Null(progressEvents[i].ResultInformation.ResultCode); + } + else + { + Assert.NotNull(progressEvents[i].ResultInformation.ResultCode); + Assert.Equal(expectedProgress[i].HResult, progressEvents[i].ResultInformation.ResultCode.HResult); + } + + break; + default: + Assert.Fail("Unexpected ConfigurationSetChangeEventType value"); + break; + } + } + } + + private struct ExpectedConfigurationChangeData + { + public ConfigurationSetChangeEventType Change; + public ConfigurationSetState SetState; + public ConfigurationUnitState UnitState; + public int HResult; + public ConfigurationUnit Unit; } } } diff --git a/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.cpp b/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.cpp index 1708c9a538..e73b0bc07a 100644 --- a/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.cpp +++ b/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.cpp @@ -6,19 +6,27 @@ namespace winrt::Microsoft::Management::Configuration::implementation { - void ApplyConfigurationSetResult::Initialize(std::vector&& unitResults, hresult resultCode) - { - m_unitResults = single_threaded_vector(std::move(unitResults)); - m_resultCode = resultCode; - } + ApplyConfigurationSetResult::ApplyConfigurationSetResult() : + m_unitResults(single_threaded_vector()) + {} Windows::Foundation::Collections::IVectorView ApplyConfigurationSetResult::UnitResults() { return m_unitResults.GetView(); } + const Windows::Foundation::Collections::IVector& ApplyConfigurationSetResult::UnitResultsVector() + { + return m_unitResults; + } + hresult ApplyConfigurationSetResult::ResultCode() { return m_resultCode; } + + void ApplyConfigurationSetResult::ResultCode(hresult value) + { + m_resultCode = value; + } } diff --git a/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.h b/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.h index 9ae4af5421..d3546dc6e4 100644 --- a/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.h +++ b/src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.h @@ -10,10 +10,11 @@ namespace winrt::Microsoft::Management::Configuration::implementation { using ApplyConfigurationUnitResult = Configuration::ApplyConfigurationUnitResult; - ApplyConfigurationSetResult() = default; + ApplyConfigurationSetResult(); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) - void Initialize(std::vector&& unitResults, hresult resultCode); + const Windows::Foundation::Collections::IVector& UnitResultsVector(); + void ResultCode(hresult value); #endif Windows::Foundation::Collections::IVectorView UnitResults(); @@ -21,7 +22,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: - Windows::Foundation::Collections::IVector m_unitResults = nullptr; + Windows::Foundation::Collections::IVector m_unitResults; hresult m_resultCode; #endif }; diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp index 1819456b2f..c78f915e9f 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp @@ -130,25 +130,32 @@ namespace winrt::Microsoft::Management::Configuration::implementation co_return GetConfigurationHistory(); } - Configuration::OpenConfigurationSetResult ConfigurationProcessor::OpenConfigurationSet(Windows::Storage::Streams::IInputStream stream) + Configuration::OpenConfigurationSetResult ConfigurationProcessor::OpenConfigurationSet(const Windows::Storage::Streams::IInputStream& stream) { - auto threadGlobals = m_threadGlobals.SetForCurrentThread(); + return OpenConfigurationSetAsync(stream).get(); + } + Windows::Foundation::IAsyncOperation ConfigurationProcessor::OpenConfigurationSetAsync(const Windows::Storage::Streams::IInputStream& stream) + { + Windows::Storage::Streams::IInputStream localStream = stream; + co_await winrt::resume_background(); + + auto threadGlobals = m_threadGlobals.SetForCurrentThread(); auto result = make_self>(); if (!stream) { result->Initialize(E_POINTER, {}); - return *result; + co_return *result; } try { - std::unique_ptr parser = ConfigurationSetParser::Create(stream); + std::unique_ptr parser = ConfigurationSetParser::Create(localStream); if (FAILED(parser->Result())) { result->Initialize(parser->Result(), parser->Field()); - return *result; + co_return *result; } auto configurationSet = make_self>(); @@ -156,12 +163,12 @@ namespace winrt::Microsoft::Management::Configuration::implementation if (FAILED(parser->Result())) { result->Initialize(parser->Result(), parser->Field()); - return *result; + co_return *result; } result->Initialize(*configurationSet); } - catch(const wil::ResultException& resultException) + catch (const wil::ResultException& resultException) { result->Initialize(resultException.GetErrorCode()); } @@ -171,12 +178,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation LOG_CAUGHT_EXCEPTION(); } - return *result; - } - - Windows::Foundation::IAsyncOperation ConfigurationProcessor::OpenConfigurationSetAsync(Windows::Storage::Streams::IInputStream stream) - { - co_return OpenConfigurationSet(stream); + co_return *result; } Windows::Foundation::Collections::IVector ConfigurationProcessor::CheckForConflicts( @@ -197,142 +199,94 @@ namespace winrt::Microsoft::Management::Configuration::implementation void ConfigurationProcessor::GetSetDetails(const ConfigurationSet& configurationSet, ConfigurationUnitDetailLevel detailLevel) { - auto threadGlobals = m_threadGlobals.SetForCurrentThread(); + return GetSetDetailsAsync(configurationSet, detailLevel).get(); + } + Windows::Foundation::IAsyncAction ConfigurationProcessor::GetSetDetailsAsync(const ConfigurationSet& configurationSet, ConfigurationUnitDetailLevel detailLevel) + { THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); - IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(configurationSet); + ConfigurationSet localSet = configurationSet; + co_await winrt::resume_background(); + + auto threadGlobals = m_threadGlobals.SetForCurrentThread(); + + IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(localSet); - for (const auto& unit : configurationSet.ConfigurationUnits()) + for (const auto& unit : localSet.ConfigurationUnits()) { IConfigurationUnitProcessorDetails details = setProcessor.GetUnitProcessorDetails(unit, detailLevel); get_self(unit)->Details(std::move(details)); } } - Windows::Foundation::IAsyncAction ConfigurationProcessor::GetSetDetailsAsync(const ConfigurationSet& configurationSet, ConfigurationUnitDetailLevel detailLevel) - { - co_return GetSetDetails(configurationSet, detailLevel); - } - void ConfigurationProcessor::GetUnitDetails(const ConfigurationUnit& unit, ConfigurationUnitDetailLevel detailLevel) { - auto threadGlobals = m_threadGlobals.SetForCurrentThread(); - - THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); - - IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr); - IConfigurationUnitProcessorDetails details = setProcessor.GetUnitProcessorDetails(unit, detailLevel); - get_self(unit)->Details(std::move(details)); + return GetUnitDetailsAsync(unit, detailLevel).get(); } Windows::Foundation::IAsyncAction ConfigurationProcessor::GetUnitDetailsAsync(const ConfigurationUnit& unit, ConfigurationUnitDetailLevel detailLevel) { - co_return GetUnitDetails(unit, detailLevel); - } + THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); - Configuration::ApplyConfigurationSetResult ConfigurationProcessor::ApplySet(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags) - { - return ApplySetInternal(configurationSet, flags, {}); - } + ConfigurationUnit localUnit = unit; + co_await winrt::resume_background(); - Windows::Foundation::IAsyncOperationWithProgress ConfigurationProcessor::ApplySetAsync(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags) - { - auto progress = co_await winrt::get_progress_token(); - co_return ApplySetInternal(configurationSet, flags, progress); - } + auto threadGlobals = m_threadGlobals.SetForCurrentThread(); - Configuration::TestConfigurationSetResult ConfigurationProcessor::TestSet(const ConfigurationSet& configurationSet) - { - return TestSetInternal(configurationSet, {}); + IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr); + IConfigurationUnitProcessorDetails details = setProcessor.GetUnitProcessorDetails(localUnit, detailLevel); + get_self(localUnit)->Details(std::move(details)); } - Windows::Foundation::IAsyncOperationWithProgress ConfigurationProcessor::TestSetAsync(const ConfigurationSet& configurationSet) + Configuration::ApplyConfigurationSetResult ConfigurationProcessor::ApplySet(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags) { - auto progress = co_await winrt::get_progress_token(); - co_return TestSetInternal(configurationSet, progress); + return ApplySetAsync(configurationSet, flags).get(); } - Configuration::GetConfigurationUnitSettingsResult ConfigurationProcessor::GetUnitSettings(const ConfigurationUnit& unit) + Windows::Foundation::IAsyncOperationWithProgress ConfigurationProcessor::ApplySetAsync(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags) { - auto threadGlobals = m_threadGlobals.SetForCurrentThread(); - THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); - IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr); - auto result = make_self>(); - auto unitResult = make_self>(); - result->ResultInformation(*unitResult); + ConfigurationSet localSet = configurationSet; + co_await winrt::resume_background(); + auto progress = co_await winrt::get_progress_token(); - IConfigurationUnitProcessor unitProcessor; + // TODO: Not needed until we have history implemented + UNREFERENCED_PARAMETER(flags); - try - { - // TODO: Directives overlay to prevent running elevated for get - unitProcessor = setProcessor.CreateUnitProcessor(unit, {}); - } - catch (...) - { - ExtractUnitResultInformation(std::current_exception(), unitResult); - } + auto threadGlobals = m_threadGlobals.SetForCurrentThread(); - if (unitProcessor) - { - try - { - GetSettingsResult settingsResult = unitProcessor.GetSettings(); - result->Settings(settingsResult.Settings()); - result->ResultInformation(settingsResult.ResultInformation()); - } - catch (...) - { - ExtractUnitResultInformation(std::current_exception(), unitResult); - } - } + auto result = make_self>(); + ConfigurationSetApplyProcessor applyProcessor{ localSet, m_factory.CreateSetProcessor(localSet), result, progress }; + progress.set_result(*result); - return *result; - } + applyProcessor.Process(); - Windows::Foundation::IAsyncOperation ConfigurationProcessor::GetUnitSettingsAsync(const ConfigurationUnit& unit) - { - co_return GetUnitSettings(unit); + co_return *result; } - void ConfigurationProcessor::Diagnostics(DiagnosticLevel level, std::string_view message) + Configuration::TestConfigurationSetResult ConfigurationProcessor::TestSet(const ConfigurationSet& configurationSet) { - auto diagnostics = make_self>(); - diagnostics->Initialize(level, AppInstaller::Utility::ConvertToUTF16(message)); - m_diagnostics(*this, *diagnostics); + return TestSetAsync(configurationSet).get(); } - Configuration::ApplyConfigurationSetResult ConfigurationProcessor::ApplySetInternal(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags, const std::function& progress) + Windows::Foundation::IAsyncOperationWithProgress ConfigurationProcessor::TestSetAsync(const ConfigurationSet& configurationSet) { - // TODO: Not needed until we have history implemented - UNREFERENCED_PARAMETER(flags); - - auto threadGlobals = m_threadGlobals.SetForCurrentThread(); - THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); - ConfigurationSetApplyProcessor applyProcessor{ configurationSet, m_factory.CreateSetProcessor(configurationSet), progress }; - applyProcessor.Process(); - - auto result = make_self>(); - result->Initialize(applyProcessor.GetUnitResults(), applyProcessor.ResultCode()); - return *result; - } + ConfigurationSet localSet = configurationSet; + co_await winrt::resume_background(); + auto progress = co_await winrt::get_progress_token(); - Configuration::TestConfigurationSetResult ConfigurationProcessor::TestSetInternal(const ConfigurationSet& configurationSet, const std::function& progress) - { auto threadGlobals = m_threadGlobals.SetForCurrentThread(); - THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); - - IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(configurationSet); + IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(localSet); auto result = make_self>(); result->TestResult(ConfigurationTestResult::NotRun); + progress.set_result(*result); - for (const auto& unit : configurationSet.ConfigurationUnits()) + for (const auto& unit : localSet.ConfigurationUnits()) { AICLI_LOG(Config, Info, << "Testing configuration unit: " << AppInstaller::Utility::ConvertToUTF8(unit.UnitName())); @@ -378,14 +332,66 @@ namespace winrt::Microsoft::Management::Configuration::implementation testResult->TestResult(ConfigurationTestResult::Failed); } - if (progress) + result->AppendUnitResult(*testResult); + + progress(*testResult); + } + + co_return *result; + } + + Configuration::GetConfigurationUnitSettingsResult ConfigurationProcessor::GetUnitSettings(const ConfigurationUnit& unit) + { + return GetUnitSettingsAsync(unit).get(); + } + + Windows::Foundation::IAsyncOperation ConfigurationProcessor::GetUnitSettingsAsync(const ConfigurationUnit& unit) + { + THROW_HR_IF(E_NOT_VALID_STATE, !m_factory); + + ConfigurationUnit localUnit = unit; + co_await winrt::resume_background(); + + auto threadGlobals = m_threadGlobals.SetForCurrentThread(); + + IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr); + auto result = make_self>(); + auto unitResult = make_self>(); + result->ResultInformation(*unitResult); + + IConfigurationUnitProcessor unitProcessor; + + try + { + // TODO: Directives overlay to prevent running elevated for get + unitProcessor = setProcessor.CreateUnitProcessor(localUnit, {}); + } + catch (...) + { + ExtractUnitResultInformation(std::current_exception(), unitResult); + } + + if (unitProcessor) + { + try { - progress(*testResult); + GetSettingsResult settingsResult = unitProcessor.GetSettings(); + result->Settings(settingsResult.Settings()); + result->ResultInformation(settingsResult.ResultInformation()); + } + catch (...) + { + ExtractUnitResultInformation(std::current_exception(), unitResult); } - - result->AppendUnitResult(*testResult); } - return *result; + co_return *result; + } + + void ConfigurationProcessor::Diagnostics(DiagnosticLevel level, std::string_view message) + { + auto diagnostics = make_self>(); + diagnostics->Initialize(level, AppInstaller::Utility::ConvertToUTF16(message)); + m_diagnostics(*this, *diagnostics); } } diff --git a/src/Microsoft.Management.Configuration/ConfigurationProcessor.h b/src/Microsoft.Management.Configuration/ConfigurationProcessor.h index 1aabfcf4f3..50580e7b43 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationProcessor.h +++ b/src/Microsoft.Management.Configuration/ConfigurationProcessor.h @@ -34,8 +34,8 @@ namespace winrt::Microsoft::Management::Configuration::implementation Windows::Foundation::Collections::IVector GetConfigurationHistory(); Windows::Foundation::IAsyncOperation> GetConfigurationHistoryAsync(); - Configuration::OpenConfigurationSetResult OpenConfigurationSet(Windows::Storage::Streams::IInputStream stream); - Windows::Foundation::IAsyncOperation OpenConfigurationSetAsync(Windows::Storage::Streams::IInputStream stream); + Configuration::OpenConfigurationSetResult OpenConfigurationSet(const Windows::Storage::Streams::IInputStream& stream); + Windows::Foundation::IAsyncOperation OpenConfigurationSetAsync(const Windows::Storage::Streams::IInputStream& stream); Windows::Foundation::Collections::IVector CheckForConflicts( const Windows::Foundation::Collections::IVectorView& configurationSets, @@ -64,9 +64,6 @@ namespace winrt::Microsoft::Management::Configuration::implementation void Diagnostics(DiagnosticLevel level, std::string_view message); private: - ApplyConfigurationSetResult ApplySetInternal(const ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags, const std::function& progress); - TestConfigurationSetResult TestSetInternal(const ConfigurationSet& configurationSet, const std::function& progress); - IConfigurationProcessorFactory m_factory = nullptr; event> m_diagnostics; event> m_configurationChange; diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp index 9c214cdbfd..469468b9b4 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp @@ -20,8 +20,8 @@ namespace winrt::Microsoft::Management::Configuration::implementation } } - ConfigurationSetApplyProcessor::ConfigurationSetApplyProcessor(const Configuration::ConfigurationSet& configurationSet, IConfigurationSetProcessor&& setProcessor, const std::function& progress) : - m_setProcessor(std::move(setProcessor)), m_progress(progress) + ConfigurationSetApplyProcessor::ConfigurationSetApplyProcessor(const Configuration::ConfigurationSet& configurationSet, IConfigurationSetProcessor&& setProcessor, result_type result, const std::function& progress) : + m_setProcessor(std::move(setProcessor)), m_result(std::move(result)), m_progress(progress) { // Create a copy of the set of configuration units auto unitsView = configurationSet.ConfigurationUnits(); @@ -39,6 +39,12 @@ namespace winrt::Microsoft::Management::Configuration::implementation { if (!PreProcess()) { + // If preprocessing fails, copy all unit results over + for (const UnitInfo& unitInfo : m_unitInfo) + { + m_result->UnitResultsVector().Append(*unitInfo.Result); + } + return; } @@ -50,23 +56,6 @@ namespace winrt::Microsoft::Management::Configuration::implementation SendProgress(ConfigurationSetState::Completed); } - std::vector ConfigurationSetApplyProcessor::GetUnitResults() const - { - std::vector unitResults; - - for (const auto& unitInfo : m_unitInfo) - { - unitResults.emplace_back(*unitInfo.Result); - } - - return unitResults; - } - - hresult ConfigurationSetApplyProcessor::ResultCode() const - { - return m_resultCode; - } - ConfigurationSetApplyProcessor::UnitInfo::UnitInfo(const Configuration::ConfigurationUnit& unit) : Unit(unit), Result(make_self>()), ResultInformation(make_self>()) @@ -90,7 +79,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation if (!result) { // This is the only error that adding to the map can produce - m_resultCode = WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER; + m_result->ResultCode(WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER); return false; } @@ -122,7 +111,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation if (!result) { // This is the only error that adding to the map can produce - m_resultCode = WINGET_CONFIG_ERROR_MISSING_DEPENDENCY; + m_result->ResultCode(WINGET_CONFIG_ERROR_MISSING_DEPENDENCY); return false; } @@ -205,7 +194,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation } bool ConfigurationSetApplyProcessor::ProcessIntentInternal( - std::vector unitsToProcess, + std::vector& unitsToProcess, CheckDependencyPtr checkDependencyFunction, ProcessUnitPtr processUnitFunction, ConfigurationUnitIntent intent, @@ -270,11 +259,11 @@ namespace winrt::Microsoft::Management::Configuration::implementation if (hasFailure) { - m_resultCode = errorForFailures; + m_result->ResultCode(errorForFailures); } else // hasRemainingDependencies { - m_resultCode = WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED; + m_result->ResultCode(WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED); } return false; } @@ -453,6 +442,11 @@ namespace winrt::Microsoft::Management::Configuration::implementation void ConfigurationSetApplyProcessor::SendProgress(ConfigurationUnitState state, const UnitInfo& unitInfo) { + if (state != ConfigurationUnitState::InProgress) + { + m_result->UnitResultsVector().Append(*unitInfo.Result); + } + if (m_progress) { try diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h index 278b828088..f0299b4ef9 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h +++ b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h @@ -3,6 +3,7 @@ #pragma once #include "ConfigurationSet.h" #include "ConfigurationUnit.h" +#include "ApplyConfigurationSetResult.h" #include "ApplyConfigurationUnitResult.h" #include "ConfigurationUnitResultInformation.h" @@ -20,17 +21,13 @@ namespace winrt::Microsoft::Management::Configuration::implementation using ConfigurationUnitResultInformation = Configuration::ConfigurationUnitResultInformation; using ConfigurationSetChangeData = Configuration::ConfigurationSetChangeData; - ConfigurationSetApplyProcessor(const ConfigurationSet& configurationSet, IConfigurationSetProcessor&& setProcessor, const std::function& progress); + using result_type = decltype(make_self>()); + + ConfigurationSetApplyProcessor(const ConfigurationSet& configurationSet, IConfigurationSetProcessor&& setProcessor, result_type result, const std::function& progress); // Processes the apply for the configuration set. void Process(); - // Gets the unit results from the processing. - std::vector GetUnitResults() const; - - // Gets the overall result code from the processing. - hresult ResultCode() const; - private: // Contains all of the relevant data for a configuration unit. struct UnitInfo @@ -62,7 +59,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation // Processes one of the non-writing intent types, which are fatal if not all successful bool ProcessIntentInternal( - std::vector unitsToProcess, + std::vector& unitsToProcess, CheckDependencyPtr checkDependencyFunction, ProcessUnitPtr processUnitFunction, ConfigurationUnitIntent intent, @@ -95,6 +92,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation void SendProgress(ConfigurationUnitState state, const UnitInfo& unitInfo); IConfigurationSetProcessor m_setProcessor; + result_type m_result; std::function m_progress; std::vector m_unitInfo; std::map m_idToUnitInfoIndex; From 02d24b4e1b1a03b09b11aec75437dbc8f652a590 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Wed, 8 Feb 2023 18:46:45 -0800 Subject: [PATCH 22/31] Some minor changes after fixing up sample, docs, pipeline update for tests --- azure-pipelines.yml | 9 + doc/specs/Configuration-COM-API.md | 257 +++++++++++++----- .../Tests/ConfigurationProcessorApplyTests.cs | 4 +- .../ApplyConfigurationUnitResult.cpp | 10 + .../ApplyConfigurationUnitResult.h | 4 + .../ConfigurationSetApplyProcessor.cpp | 22 +- .../ConfigurationSetApplyProcessor.h | 1 - .../ConfigurationSetChangeData.cpp | 1 + .../Microsoft.Management.Configuration.idl | 7 +- src/Microsoft.Management.Configuration/pch.h | 1 + 10 files changed, 225 insertions(+), 91 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index ec5edba4d8..a08ab214ca 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -290,6 +290,15 @@ jobs: codeCoverageEnabled: true platform: 'Any CPU' configuration: '$(BuildConfiguration)' + + - task: VSTest@2 + displayName: 'Run tests: Microsoft.Management.Configuration.UnitTests' + inputs: + testSelector: 'testAssemblies' + testAssemblyVer2: 'Microsoft.Management.Configuration.UnitTests.dll' + searchFolder: '$(Build.ArtifactStagingDirectory)\Microsoft.Management.Configuration.UnitTests' + codeCoverageEnabled: true + platform: 'x64' - task: CopyFiles@2 displayName: 'Copy Util to artifacts folder' diff --git a/doc/specs/Configuration-COM-API.md b/doc/specs/Configuration-COM-API.md index dec5749bb7..7b47ac5f93 100644 --- a/doc/specs/Configuration-COM-API.md +++ b/doc/specs/Configuration-COM-API.md @@ -110,10 +110,9 @@ The state of a configuration set in the configuration history. | Name | Description | |-|-| | Unknown | Primarily used for a configuration set that has not been applied. | -| ApplicationPending | The configuration set has been recorded into the history, but has not yet begun applying. | -| ApplicationBegun | The configuration set has begun being applied to the system. | -| ApplicationFailed | The configuration set has completed being applied, and one or more configuration units failed to apply. | -| ApplicationSucceeded | The configuration set has completed being applied successfully. | +| Pending | The configuration set has been recorded into the history, but has not yet begun applying. | +| InProgress | The configuration set has begun being applied to the system. | +| Completed | The configuration set has completed being applied. | ## ConfigurationUnitState enumeration @@ -122,15 +121,10 @@ The state of a configuration unit in the configuration history. | Name | Description | |-|-| | Unknown | Primarily used for a configuration unit that has not been applied. | -| ApplicationPending | The configuration unit has been recorded into the history, but has not yet begun applying. | -| ApplicationBegun | The configuration unit has begun being applied to the system. | -| ApplicationFailed | The configuration unit has completed being applied, but it failed. | -| ApplicationSucceeded | The configuration unit has completed being applied successfully. | -| SkippedManually | The configuration unit was skipped by the user. | -| SkippedDueToDependencies | The configuration unit was skipped due to a dependency not having been successfully applied. | -| TestBegun | The configuration unit has begun testing the system state. This state is only sent locally to the set being tested. | -| TestFailed | The configuration unit testing has failed. This state is only sent locally to the set being tested. | -| TestSucceeded | The configuration unit testing has succeeded. This state is only sent locally to the set being tested. | +| Pending | The configuration unit has been recorded into the history, but has not yet begun applying. | +| InProgress | The configuration unit has begun being applied to the system. | +| Completed | The configuration unit has completed being applied; the result information will contain additional details. | +| Skipped | The configuration unit was skipped; the result information will contain additional details on the reason. | ## ConfigurationUnitDetailLevel enumeration @@ -284,6 +278,13 @@ Provides access to a specific configuration unit within the runtime. This interface is the primary mechanism used to actually read and write configuration to the system, but it is not expected that you would use this directly as a consumer of Microsoft.Management.Configuration. +## IConfigurationSetProcessor interface + +Contains the lifetime of the processing action for a configuration set. + +This interface is used to contain the lifetime of a processing action, +but it is not expected that you would use this directly as a consumer of Microsoft.Management.Configuration. + ## IConfigurationProcessorFactory interface Allows different runtimes to provide specialized handling of configuration processing. @@ -369,11 +370,13 @@ ConfigurationProcessor(IConfigurationProcessorFactory factory); > _TODO: Add details on the mechanics of creating the `IConfigurationProcessorFactory` objects that we provide._ -## ConfigurationProcessor.CheckForConflictsAsync method +## ConfigurationProcessor.CheckForConflicts(Async) method Checks for conflicts amongst the configuration sets provided, optionally including the configuration sets already applied to the system. ```C# +Windows.Foundation.Collections.IVectorView CheckForConflicts(Windows.Foundation.Collections.IVectorView configurationSets, Boolean includeConfigurationHistory); + Windows.Foundation.IAsyncOperation< Windows.Foundation.Collections.IVectorView > CheckForConflictsAsync(Windows.Foundation.Collections.IVectorView configurationSets, Boolean includeConfigurationHistory); ``` @@ -381,22 +384,26 @@ This method should be used on any configuration set that is opened in order to d with previously applied configurations. It should be called *after* setting the `Name` and `Origin` in order to determine if it is a potential update. -## ConfigurationProcessor.GetSetDetailsAsync method +## ConfigurationProcessor.GetSetDetails(Async) method Gets the details for all configuration units in a set. ```C# +void GetSetDetails(ConfigurationSet configurationSet, ConfigurationUnitDetailLevel detailLevel); + Windows.Foundation.IAsyncAction GetSetDetailsAsync(ConfigurationSet configurationSet, ConfigurationUnitDetailLevel detailLevel); ``` -This is a convenience/optimization method that will do the same thing as calling `GetUnitDetailsAsync` on each -configuration unit in the set. See `GetUnitDetailsAsync` for more information on what it will do. +This is a convenience/optimization method that will do the same thing as calling `GetUnitDetails(Async)` on each +configuration unit in the set. See `GetUnitDetails(Async)` for more information on what it will do. -## ConfigurationProcessor.GetUnitDetailsAsync method +## ConfigurationProcessor.GetUnitDetails(Async) method Gets the details for all configuration units in a set. ```C# +void GetUnitDetails(ConfigurationUnit unit, ConfigurationUnitDetailLevel detailLevel); + Windows.Foundation.IAsyncAction GetUnitDetailsAsync(ConfigurationUnit unit, ConfigurationUnitDetailLevel detailLevel); ``` @@ -404,31 +411,35 @@ This method will get the details about a specific configuration unit and make th The `detailLevel` parameter allows control over how deeply to probe for details. It is an analog for the amount of trust to place in the configuration unit processor. -## ConfigurationProcessor.ApplyAsync method +## ConfigurationProcessor.ApplySet(Async) method Applies the configuration set state to the system. ```C# -Windows.Foundation.IAsyncOperation ApplyAsync(ConfigurationSet configurationSet, ApplyConfigurationSetFlags flags); +ApplyConfigurationSetResult ApplySet(ConfigurationSet configurationSet, ApplyConfigurationSetFlags flags); + +Windows.Foundation.IAsyncOperationWithProgress ApplySetAsync(ConfigurationSet configurationSet, ApplyConfigurationSetFlags flags); ``` -To get progress, subscribe to the `ConfigurationSetChange` before calling this method. +Using the async method and it's progress is more efficient than subscribing to the `ConfigurationSetChange` event before calling this method. -## ConfigurationProcessor.TestAsync method +## ConfigurationProcessor.TestSet(Async) method Tests if the system state matches the state described by the configuration set. ```C# -Windows.Foundation.IAsyncOperation TestAsync(ConfigurationSet configurationSet); -``` +TestConfigurationSetResult TestSet(ConfigurationSet configurationSet); -To get progress, subscribe to the `ConfigurationSetChange` before calling this method. +Windows.Foundation.IAsyncOperationWithProgress TestSetAsync(ConfigurationSet configurationSet); +``` -## ConfigurationProcessor.GetSettingsAsync method +## ConfigurationProcessor.GetSettings(Async) method Gets the current configuration unit settings from the system state. ```C# +GetConfigurationUnitSettingsResult GetSettings(ConfigurationUnit unit); + Windows.Foundation.IAsyncOperation GetSettingsAsync(ConfigurationUnit unit); ``` @@ -445,7 +456,7 @@ Signals changes to the set of configuration sets in the history, as well as chan Gets the configuration sets from the recorded history. ```C# -static Windows.Foundation.Collections.IVectorView GetConfigurationHistory(); +Windows.Foundation.Collections.IVectorView GetConfigurationHistory(); ``` Gets the configuration sets that have already been applied or those recorded with the intent to be applied. This may include in progress sets or those that are waiting to be applied. @@ -469,23 +480,41 @@ Gets the configuration sets that have already been applied or those recorded wit This sample illustrates some of the expected usage patterns. ```C# +using Microsoft.Management.Configuration; using System; using System.Collections.Generic; using System.IO; -using Microsoft.Management.Configuration; +using System.Reflection; +using Windows.Foundation; +using Windows.Foundation.Collections; using Windows.Storage; using Windows.Storage.Streams; namespace ConfigurationSample { - internal class Helpers + internal static class Helpers { internal static IConfigurationProcessorFactory CreateIConfigurationProcessorFactory() { - // While we will also implement these factories, that will be part of a separate binary. throw new NotImplementedException(); } + internal static ConfigurationSet OpenConfigurationSet(string filePath, ConfigurationProcessor processor) + { + var fileOperation = FileRandomAccessStream.OpenAsync(filePath, FileAccessMode.Read); + fileOperation.AsTask().Wait(); + var file = fileOperation.GetResults(); + OpenConfigurationSetResult result = processor.OpenConfigurationSet(file); + + if (result.Set != null) + { + return result.Set; + } + + Console.WriteLine($"Failed opening configuration set: 0x{result.ResultCode:X} at {result.Field}"); + return null; + } + internal static void SetWatcher(ConfigurationSet set, ConfigurationSetChangeData data) { Console.WriteLine($" - Set: {set.Name} [{set.InstanceIdentifier}]"); @@ -496,7 +525,7 @@ namespace ConfigurationSample case ConfigurationSetChangeEventType.UnitStateChanged: Console.WriteLine($" Unit: {data.Unit.UnitName} [{data.Unit.InstanceIdentifier}]"); Console.WriteLine($" Unit State: {data.UnitState}"); - if (data.UnitState == ConfigurationUnitState.ApplicationFailed) + if (data.UnitState == ConfigurationUnitState.Completed && data.ResultInformation.ResultCode != null) { Console.WriteLine($" Failure: {data.ResultInformation.Description} [{data.ResultInformation.ResultCode.HResult}]"); } @@ -505,52 +534,136 @@ namespace ConfigurationSample } } + internal class ApplyProgressWatcher + { + private bool isFirstProgress = true; + + internal void Watcher(IAsyncOperationWithProgress operation, ConfigurationSetChangeData data) + { + if (isFirstProgress) + { + isFirstProgress = false; + + // If our first progress callback contains partial results, output them as if they had been called through progress + ApplyConfigurationSetResult partialResult = operation.GetResults(); + + foreach (ApplyConfigurationUnitResult unitResult in partialResult.UnitResults) + { + HandleUnitProgress(unitResult.Unit, unitResult.State, unitResult.ResultInformation); + } + } + + switch (data.Change) + { + case ConfigurationSetChangeEventType.SetStateChanged: + Console.WriteLine($" - Set State: {data.SetState}"); + break; + case ConfigurationSetChangeEventType.UnitStateChanged: + HandleUnitProgress(data.Unit, data.UnitState, data.ResultInformation); + break; + } + } + + private void HandleUnitProgress(ConfigurationUnit unit, ConfigurationUnitState state, ConfigurationUnitResultInformation resultInformation) + { + switch (state) + { + case ConfigurationUnitState.Pending: + break; + case ConfigurationUnitState.InProgress: + case ConfigurationUnitState.Completed: + case ConfigurationUnitState.Skipped: + Console.WriteLine($" - Unit: {unit.UnitName} [{unit.InstanceIdentifier}]"); + Console.WriteLine($" Unit State: {state}"); + if (resultInformation.ResultCode != null) + { + Console.WriteLine($" HRESULT: [0x{resultInformation.ResultCode.HResult:X8}]"); + Console.WriteLine($" Reason: {resultInformation.Description}"); + } + break; + case ConfigurationUnitState.Unknown: + break; + } + } + } + internal class Program { static void LoadAndOutput(string[] args) { - // Open the given configuration file and load into a set - var file = FileRandomAccessStream.OpenAsync(args[2], FileAccessMode.Read).GetResults(); - ConfigurationSet configSet = new ConfigurationSet(file); - - // Create the factory and processor, then get more information on the configuration unit processors ConfigurationProcessor processor = new ConfigurationProcessor(Helpers.CreateIConfigurationProcessorFactory()); - processor.GetSetDetailsAsync(configSet, ConfigurationUnitDetailLevel.Catalog).GetResults(); + + // Open the given configuration file + ConfigurationSet configSet = Helpers.OpenConfigurationSet(args[1], processor); + if (configSet == null) + { + return; + } // Output some of the information from the set - Console.WriteLine($"Configuration Set: {args[2]}"); + Console.WriteLine($"Configuration Set: {args[1]}"); - foreach (var unit in configSet.ConfigurationUnits) + foreach (ConfigurationUnit unit in configSet.ConfigurationUnits) { Console.WriteLine($" - Configuration Unit: {unit.UnitName}"); - Console.WriteLine($" Module: {unit.Details.ModuleName}"); - Console.WriteLine( " Settings:"); - foreach (var setting in unit.Settings) + if (!string.IsNullOrEmpty(unit.Identifier)) + { + Console.WriteLine($" Identifier: {unit.Identifier}"); + } + Console.WriteLine($" Intent: {unit.Intent}"); + IReadOnlyList dependencies = unit.Dependencies; + if (dependencies.Count > 0) + { + Console.WriteLine(" Dependencies:"); + foreach (string dependency in dependencies) + { + Console.WriteLine($" {dependency}"); + } + } + ValueSet directives = unit.Directives; + if (directives.Count > 0) { - Console.WriteLine($" {setting.Key}: {setting.Value}"); + Console.WriteLine(" Directives:"); + foreach (var directive in unit.Directives) + { + Console.WriteLine($" {directive.Key}: {directive.Value}"); + } + } + ValueSet settings = unit.Settings; + if (settings.Count > 0) + { + Console.WriteLine(" Settings:"); + foreach (var setting in unit.Settings) + { + Console.WriteLine($" {setting.Key}: {setting.Value}"); + } } } } static void LoadAndCheckConflicts(string[] args) { - // Open the given configuration file and load into a set - var file = FileRandomAccessStream.OpenAsync(args[2], FileAccessMode.Read).GetResults(); - ConfigurationSet configSet = new ConfigurationSet(file); + // Create the factory and processor + ConfigurationProcessor processor = new ConfigurationProcessor(Helpers.CreateIConfigurationProcessorFactory()); + + // Open the given configuration file + ConfigurationSet configSet = Helpers.OpenConfigurationSet(args[1], processor); + if (configSet == null) + { + return; + } // Set a name and origin for this set so that we can see it in the conflict info - configSet.Name = Path.GetFileName(args[2]); - configSet.Origin = args[2]; + configSet.Name = Path.GetFileName(args[1]); + configSet.Origin = args[1]; - // Create the factory and processor, then check for conflicts with existing configurations - ConfigurationProcessor processor = new ConfigurationProcessor(Helpers.CreateIConfigurationProcessorFactory()); - List configSets = new List(); - configSets.Add(configSet); - var conflicts = processor.CheckForConflictsAsync(configSets, true).GetResults(); + // Check for conflicts with existing configurations + List configSets = new List() { configSet }; + IList conflicts = processor.CheckForConflicts(configSets, true); - Console.WriteLine($"Conflicts with Configuration Set: {args[2]}"); + Console.WriteLine($"Conflicts with Configuration Set: {args[1]}"); - foreach (var conflict in conflicts) + foreach (ConfigurationConflict conflict in conflicts) { Console.WriteLine($" - Conflict: {conflict.Conflict}"); Console.WriteLine($" First Set: {conflict.FirstSet.Name} [{conflict.FirstSet.Origin}]"); @@ -559,7 +672,7 @@ namespace ConfigurationSample { Console.WriteLine($" First Unit: {conflict.FirstUnit.UnitName} [{conflict.FirstUnit.InstanceIdentifier}]"); Console.WriteLine($" Second Unit: {conflict.SecondUnit.UnitName} [{conflict.SecondUnit.InstanceIdentifier}]"); - foreach (var setting in conflict.Settings) + foreach (ConfigurationConflictSetting setting in conflict.Settings) { Console.WriteLine($" - Setting: {setting.Name}"); Console.WriteLine($" First Value: {setting.FirstValue}"); @@ -571,19 +684,24 @@ namespace ConfigurationSample static void LoadAndApply(string[] args) { - // Open the given configuration file and load into a set - var file = FileRandomAccessStream.OpenAsync(args[2], FileAccessMode.Read).GetResults(); - ConfigurationSet configSet = new ConfigurationSet(file); - // Create the factory and processor ConfigurationProcessor processor = new ConfigurationProcessor(Helpers.CreateIConfigurationProcessorFactory()); - // Attach event handler on set change - configSet.ConfigurationSetChange += Helpers.SetWatcher; + // Open the given configuration file + ConfigurationSet configSet = Helpers.OpenConfigurationSet(args[1], processor); + if (configSet == null) + { + return; + } - Console.WriteLine($"Applying Configuration Set: {args[2]}"); + Console.WriteLine($"Applying Configuration Set: {args[1]}"); - var result = processor.ApplyAsync(configSet, ApplyConfigurationSetFlags.None).GetResults(); + ApplyProgressWatcher watcher = new ApplyProgressWatcher(); + + var operation = processor.ApplySetAsync(configSet, ApplyConfigurationSetFlags.None); + operation.Progress = watcher.Watcher; + operation.AsTask().Wait(); + ApplyConfigurationSetResult result = operation.GetResults(); Console.WriteLine($" - Done: {result.ResultCode.HResult}"); } @@ -592,10 +710,13 @@ namespace ConfigurationSample { Console.WriteLine("Watching all configuration [press Enter to stop]:"); + // Create the factory and processor + ConfigurationProcessor processor = new ConfigurationProcessor(Helpers.CreateIConfigurationProcessorFactory()); + List list = new List(); // Attach to the top level change event - Statics.ConfigurationChange += (ConfigurationSet incomingSet, ConfigurationChangeData data) => + processor.ConfigurationChange += (ConfigurationSet incomingSet, ConfigurationChangeData data) => { int existingSetIndex = -1; @@ -632,7 +753,7 @@ namespace ConfigurationSample Console.WriteLine($" Change: {data.Change}"); }; - foreach (var set in Statics.GetConfigurationHistory()) + foreach (ConfigurationSet set in processor.GetConfigurationHistory()) { int existingSetIndex = -1; @@ -667,7 +788,7 @@ namespace ConfigurationSample static void Main(string[] args) { - var method = typeof(Program).GetMethod(args[1]); + var method = typeof(Program).GetMethod(args[0], BindingFlags.NonPublic | BindingFlags.Static); if (method != null) { @@ -675,7 +796,7 @@ namespace ConfigurationSample } else { - Console.WriteLine($"{args[1]} is not a sample"); + Console.WriteLine($"{args[0]} is not a sample"); } } } diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs index 054b1c58a6..70bc0142f6 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs @@ -384,12 +384,12 @@ public void ApplySet_Progress() new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = inform1 }, new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.InProgress, Unit = apply1 }, new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = apply1 }, - new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.SkippedManually, Unit = apply4, HResult = Errors.WINGET_CONFIG_ERROR_MANUALLY_SKIPPED }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Skipped, Unit = apply4, HResult = Errors.WINGET_CONFIG_ERROR_MANUALLY_SKIPPED }, new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.InProgress, Unit = apply2 }, new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = apply2 }, new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.InProgress, Unit = apply3 }, new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = apply3 }, - new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.SkippedDueToDependencies, Unit = apply5, HResult = Errors.WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED }, + new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Skipped, Unit = apply5, HResult = Errors.WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED }, new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.SetStateChanged, SetState = ConfigurationSetState.Completed }, }; diff --git a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp index c8032abf42..489c25e9a6 100644 --- a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp +++ b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp @@ -17,6 +17,16 @@ namespace winrt::Microsoft::Management::Configuration::implementation m_unit = std::move(value); } + ConfigurationUnitState ApplyConfigurationUnitResult::State() const + { + return m_state.load(); + } + + void ApplyConfigurationUnitResult::State(ConfigurationUnitState value) + { + m_state.store(value); + } + bool ApplyConfigurationUnitResult::PreviouslyInDesiredState() const { return m_previouslyInDesiredState; diff --git a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h index a0ba725fdd..407ccaf3b8 100644 --- a/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h +++ b/src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h @@ -2,6 +2,7 @@ // Licensed under the MIT License. #pragma once #include "ApplyConfigurationUnitResult.g.h" +#include namespace winrt::Microsoft::Management::Configuration::implementation { @@ -14,12 +15,14 @@ namespace winrt::Microsoft::Management::Configuration::implementation #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) void Unit(ConfigurationUnit value); + void State(ConfigurationUnitState value); void PreviouslyInDesiredState(bool value); void RebootRequired(bool value); void ResultInformation(ConfigurationUnitResultInformation value); #endif ConfigurationUnit Unit(); + ConfigurationUnitState State() const; bool PreviouslyInDesiredState() const; bool RebootRequired() const; ConfigurationUnitResultInformation ResultInformation(); @@ -27,6 +30,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: ConfigurationUnit m_unit = nullptr; + std::atomic m_state = ConfigurationUnitState::Pending; bool m_previouslyInDesiredState = false; bool m_rebootRequired = false; ConfigurationUnitResultInformation m_resultInformation = nullptr; diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp index 469468b9b4..5b8c77a52b 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp @@ -32,6 +32,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation for (const auto& unit : unitsToProcess) { m_unitInfo.emplace_back(unit); + m_result->UnitResultsVector().Append(*m_unitInfo.back().Result); } } @@ -39,12 +40,6 @@ namespace winrt::Microsoft::Management::Configuration::implementation { if (!PreProcess()) { - // If preprocessing fails, copy all unit results over - for (const UnitInfo& unitInfo : m_unitInfo) - { - m_result->UnitResultsVector().Append(*unitInfo.Result); - } - return; } @@ -160,7 +155,6 @@ namespace winrt::Microsoft::Management::Configuration::implementation processUnitFunction, ConfigurationUnitIntent::Assert, WINGET_CONFIG_ERROR_ASSERTION_FAILED, - ConfigurationUnitState::SkippedDueToAssertions, WINGET_CONFIG_ERROR_ASSERTION_FAILED, sendProgress)) { @@ -174,7 +168,6 @@ namespace winrt::Microsoft::Management::Configuration::implementation processUnitFunction, ConfigurationUnitIntent::Inform, WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED, - ConfigurationUnitState::SkippedDueToDependencies, WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED, sendProgress)) { @@ -188,7 +181,6 @@ namespace winrt::Microsoft::Management::Configuration::implementation processUnitFunction, ConfigurationUnitIntent::Apply, E_FAIL, // This should not happen as there are no other intents left - ConfigurationUnitState::Unknown, WINGET_CONFIG_ERROR_SET_APPLY_FAILED, sendProgress); } @@ -199,7 +191,6 @@ namespace winrt::Microsoft::Management::Configuration::implementation ProcessUnitPtr processUnitFunction, ConfigurationUnitIntent intent, hresult errorForOtherIntents, - ConfigurationUnitState progressForOtherIntents, hresult errorForFailures, bool sendProgress) { @@ -236,7 +227,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation unitInfo.ResultInformation->ResultCode(WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED); if (sendProgress) { - SendProgress(ConfigurationUnitState::SkippedDueToDependencies, unitInfo); + SendProgress(ConfigurationUnitState::Skipped, unitInfo); } } } @@ -252,7 +243,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation unitInfo.ResultInformation->ResultCode(errorForOtherIntents); if (sendProgress) { - SendProgress(progressForOtherIntents, unitInfo); + SendProgress(ConfigurationUnitState::Skipped, unitInfo); } } } @@ -322,7 +313,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation // If the unit is requested to be skipped, we mark it with a failure to prevent any dependency from running. // But we return true from this function to indicate a successful "processing". unitInfo.ResultInformation->ResultCode(WINGET_CONFIG_ERROR_MANUALLY_SKIPPED); - SendProgress(ConfigurationUnitState::SkippedManually, unitInfo); + SendProgress(ConfigurationUnitState::Skipped, unitInfo); return true; } @@ -442,10 +433,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation void ConfigurationSetApplyProcessor::SendProgress(ConfigurationUnitState state, const UnitInfo& unitInfo) { - if (state != ConfigurationUnitState::InProgress) - { - m_result->UnitResultsVector().Append(*unitInfo.Result); - } + unitInfo.Result->State(state); if (m_progress) { diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h index f0299b4ef9..16a2deb8b8 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h +++ b/src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h @@ -64,7 +64,6 @@ namespace winrt::Microsoft::Management::Configuration::implementation ProcessUnitPtr processUnitFunction, ConfigurationUnitIntent intent, hresult errorForOtherIntents, - ConfigurationUnitState progressForOtherIntents, hresult errorForFailures, bool sendProgress); diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.cpp index 48d0d5cc07..49aab2660c 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSetChangeData.cpp @@ -29,6 +29,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation void ConfigurationSetChangeData::Initialize(ConfigurationUnitState state, ConfigurationUnitResultInformation resultInformation, ConfigurationUnit unit) { m_change = ConfigurationSetChangeEventType::UnitStateChanged; + m_setState = ConfigurationSetState::InProgress; m_unitState = state; m_resultInformation = resultInformation; m_unit = unit; diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl index 6847c590ff..836e90a0e2 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -23,9 +23,7 @@ namespace Microsoft.Management.Configuration Pending, InProgress, Completed, - SkippedManually, - SkippedDueToAssertions, - SkippedDueToDependencies, + Skipped, }; // Defines the level of detail probing that is allowed about a configuration unit. @@ -479,6 +477,9 @@ namespace Microsoft.Management.Configuration // The configuration unit that was applied. ConfigurationUnit Unit{ get; }; + // The state of the configuration unit with regards to the current execution of ApplySet. + ConfigurationUnitState State{ get; }; + // Will be true if the configuration unit was in the desired state (Test returns true) prior to the apply action. Boolean PreviouslyInDesiredState{ get; }; diff --git a/src/Microsoft.Management.Configuration/pch.h b/src/Microsoft.Management.Configuration/pch.h index 736f4ecafa..930db9788e 100644 --- a/src/Microsoft.Management.Configuration/pch.h +++ b/src/Microsoft.Management.Configuration/pch.h @@ -16,6 +16,7 @@ #include #pragma warning( pop ) +#include #include #include #include From 4cc990db1204d9b2d0a81c10713d2d7b7aef532f Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Thu, 9 Feb 2023 10:43:38 -0800 Subject: [PATCH 23/31] Fix spelling and pipeline task for test --- .github/actions/spelling/allow.txt | 3 +++ azure-pipelines.yml | 2 +- .../Helpers/ConfigurationProcessorTestBase.cs | 2 +- .../ConfigurationSetParser.cpp | 6 +++--- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index 7231a00be5..51ab30ac91 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -133,6 +133,7 @@ dll dllexport dllmain Dlls +DMC docx dotnet downlevel @@ -228,6 +229,7 @@ https HWND Hyperlink IAppx +IConfiguration icu IDX IFACEMETHOD @@ -235,6 +237,7 @@ ifdef ifndef ifspec ifstream +IInspectable IIS impl inapplicabilities diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a08ab214ca..168b08743f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -296,7 +296,7 @@ jobs: inputs: testSelector: 'testAssemblies' testAssemblyVer2: 'Microsoft.Management.Configuration.UnitTests.dll' - searchFolder: '$(Build.ArtifactStagingDirectory)\Microsoft.Management.Configuration.UnitTests' + searchFolder: '$(buildOutDir)\Microsoft.Management.Configuration.UnitTests' codeCoverageEnabled: true platform: 'x64' diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs index c72da96d1e..fdcc115a97 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs @@ -41,7 +41,7 @@ protected ConfigurationProcessorTestBase(UnitTestFixture fixture, ITestOutputHel protected ITestOutputHelper Log { get; private set; } /// - /// Createa a new with the diagnostics event hooked up. + /// Create a new with the diagnostics event hooked up. /// /// The factory to use. /// The new object. diff --git a/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp b/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp index 2d237e75e5..47d8bb40ce 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp @@ -64,14 +64,14 @@ namespace winrt::Microsoft::Management::Configuration::implementation return std::make_unique(WINGET_CONFIG_ERROR_INVALID_YAML); } - AppInstaller::YAML::Node& popertiesNode = document[NodeName_Properties]; - if (!popertiesNode.IsMap()) + AppInstaller::YAML::Node& propertiesNode = document[NodeName_Properties]; + if (!propertiesNode.IsMap()) { AICLI_LOG(Config, Info, << "Invalid properties"); return std::make_unique(WINGET_CONFIG_ERROR_INVALID_FIELD, NodeName_Properties); } - AppInstaller::YAML::Node& versionNode = popertiesNode[NodeName_ConfigurationVersion]; + AppInstaller::YAML::Node& versionNode = propertiesNode[NodeName_ConfigurationVersion]; if (!versionNode.IsScalar()) { AICLI_LOG(Config, Info, << "Invalid configuration version"); From c7963c9187f488beae2fcc063b5ec2be05544a6c Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Thu, 9 Feb 2023 12:11:46 -0800 Subject: [PATCH 24/31] Better file match pattern for tests? --- azure-pipelines.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 168b08743f..5dd28e8bbd 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -295,10 +295,11 @@ jobs: displayName: 'Run tests: Microsoft.Management.Configuration.UnitTests' inputs: testSelector: 'testAssemblies' - testAssemblyVer2: 'Microsoft.Management.Configuration.UnitTests.dll' + testAssemblyVer2: '**\Microsoft.Management.Configuration.UnitTests.dll' searchFolder: '$(buildOutDir)\Microsoft.Management.Configuration.UnitTests' codeCoverageEnabled: true platform: 'x64' + configuration: '$(BuildConfiguration)' - task: CopyFiles@2 displayName: 'Copy Util to artifacts folder' From 3996176f2ce081d66be723caeb9a3d81d2ad65ef Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Thu, 9 Feb 2023 13:49:36 -0800 Subject: [PATCH 25/31] Update pipeline to check why the configuration types are not activating correctly --- azure-pipelines.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5dd28e8bbd..388f3331e8 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -290,6 +290,14 @@ jobs: codeCoverageEnabled: true platform: 'Any CPU' configuration: '$(BuildConfiguration)' + + - task: PowerShell@2 + displayName: TEMP - Diagnose filesystem for unit tests + inputs: + targetType: 'inline' + script: | + Get-ChildItem -Recurse + workingDirectory: '$(buildOutDir)\Microsoft.Management.Configuration.UnitTests' - task: VSTest@2 displayName: 'Run tests: Microsoft.Management.Configuration.UnitTests' From b1c25fc97006af69e72d28706d0aa02426181a7f Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Thu, 9 Feb 2023 15:08:40 -0800 Subject: [PATCH 26/31] Explicitly force the projection (and hopefully the real module) to be copied over --- .../Microsoft.Management.Configuration.Projection.csproj | 2 +- .../Microsoft.Management.Configuration.UnitTests.csproj | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.Management.Configuration.Projection/Microsoft.Management.Configuration.Projection.csproj b/src/Microsoft.Management.Configuration.Projection/Microsoft.Management.Configuration.Projection.csproj index 66a5ef6422..7af8ddd0e6 100644 --- a/src/Microsoft.Management.Configuration.Projection/Microsoft.Management.Configuration.Projection.csproj +++ b/src/Microsoft.Management.Configuration.Projection/Microsoft.Management.Configuration.Projection.csproj @@ -2,7 +2,7 @@ net6.0-windows10.0.22000.0 - AnyCPU + x64;x86;arm64 enable enable $(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)\ diff --git a/src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj b/src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj index d9f8cc85ff..5f2b805ba7 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj +++ b/src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj @@ -1,4 +1,4 @@ - + net6.0-windows10.0.22000.0 @@ -31,7 +31,10 @@ - + + True + True + From d6807e1297ad3b1b679da70a8744308686ca0478 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Thu, 9 Feb 2023 18:14:33 -0800 Subject: [PATCH 27/31] PR feedback and yet another attempt at getting the module to copy --- src/AppInstallerCLI.sln | 18 +++++++----------- .../Fixtures/UnitTestFixture.cs | 2 +- .../Helpers/ConfigurationProcessorTestBase.cs | 4 ++-- ...t.Management.Configuration.UnitTests.csproj | 5 +++-- .../ConfigurationSet.cpp | 4 ++-- .../ConfigurationSet.h | 4 ++-- .../Microsoft.Management.Configuration.idl | 15 +++++++++++++-- .../Microsoft.Management.Configuration.vcxproj | 4 ++-- src/Microsoft.Management.Configuration/pch.h | 2 -- 9 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index 41f57410f6..cf0318e5f7 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -1085,7 +1085,6 @@ Global {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|x86.ActiveCfg = Release|Win32 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|x86.Build.0 = Release|Win32 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|Any CPU.ActiveCfg = Debug|x64 - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|Any CPU.Build.0 = Debug|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|ARM.ActiveCfg = Debug|ARM {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|ARM.Build.0 = Debug|ARM {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -1125,7 +1124,6 @@ Global {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.TestRelease|x86.ActiveCfg = Release|Win32 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.TestRelease|x86.Build.0 = Release|Win32 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|Any CPU.ActiveCfg = Debug|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|Any CPU.Build.0 = Debug|x64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM.ActiveCfg = Debug|ARM {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM.Build.0 = Debug|ARM {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -1164,16 +1162,15 @@ Global {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x64.Build.0 = Release|x64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x86.ActiveCfg = Release|Win32 {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x86.Build.0 = Release|Win32 - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|Any CPU.ActiveCfg = Debug|x64 {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM.ActiveCfg = Debug|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM.Build.0 = Debug|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM64.Build.0 = Debug|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x64.ActiveCfg = Debug|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x64.Build.0 = Debug|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x86.ActiveCfg = Debug|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x86.Build.0 = Debug|Any CPU + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM64.ActiveCfg = Debug|arm64 + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM64.Build.0 = Debug|arm64 + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x64.ActiveCfg = Debug|x64 + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x64.Build.0 = Debug|x64 + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x86.ActiveCfg = Debug|x86 + {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x86.Build.0 = Debug|x86 {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|Any CPU.ActiveCfg = Debug|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|Any CPU.Build.0 = Debug|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|ARM.ActiveCfg = Debug|Any CPU @@ -1205,7 +1202,6 @@ Global {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|x86.ActiveCfg = Release|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|x86.Build.0 = Release|Any CPU {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|Any CPU.ActiveCfg = Debug|x64 - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|Any CPU.Build.0 = Debug|x64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|ARM.ActiveCfg = Debug|x64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|ARM.Build.0 = Debug|x64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|ARM64.ActiveCfg = Debug|arm64 diff --git a/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs b/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs index 420ba392dd..6d124f7e1b 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs @@ -25,6 +25,6 @@ public UnitTestFixture(IMessageSink messageSink) /// /// Gets the message sink for the fixture. /// - public IMessageSink MessageSink { get; private set; } + public IMessageSink MessageSink { get; private init; } } } diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs index fdcc115a97..2e7d56e5d0 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs +++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs @@ -33,12 +33,12 @@ protected ConfigurationProcessorTestBase(UnitTestFixture fixture, ITestOutputHel /// /// Gets the test fixture. /// - protected UnitTestFixture Fixture { get; private set; } + protected UnitTestFixture Fixture { get; private init; } /// /// Gets the output helper. /// - protected ITestOutputHelper Log { get; private set; } + protected ITestOutputHelper Log { get; private init; } /// /// Create a new with the diagnostics event hooked up. diff --git a/src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj b/src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj index 5f2b805ba7..73af0be80a 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj +++ b/src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj @@ -32,8 +32,9 @@ - True - True + Content + PreserveNewest + True diff --git a/src/Microsoft.Management.Configuration/ConfigurationSet.cpp b/src/Microsoft.Management.Configuration/ConfigurationSet.cpp index fc2f52153b..5fea20bed7 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSet.cpp +++ b/src/Microsoft.Management.Configuration/ConfigurationSet.cpp @@ -66,9 +66,9 @@ namespace winrt::Microsoft::Management::Configuration::implementation return ConfigurationSetState::Unknown; } - clock::time_point ConfigurationSet::InitialIntent() + clock::time_point ConfigurationSet::FirstApply() { - return clock::time_point{}; + return m_firstApply; } clock::time_point ConfigurationSet::ApplyBegun() diff --git a/src/Microsoft.Management.Configuration/ConfigurationSet.h b/src/Microsoft.Management.Configuration/ConfigurationSet.h index f7940a68ca..ae6c749161 100644 --- a/src/Microsoft.Management.Configuration/ConfigurationSet.h +++ b/src/Microsoft.Management.Configuration/ConfigurationSet.h @@ -32,7 +32,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation guid InstanceIdentifier(); ConfigurationSetState State(); - clock::time_point InitialIntent(); + clock::time_point FirstApply(); clock::time_point ApplyBegun(); clock::time_point ApplyEnded(); @@ -52,7 +52,7 @@ namespace winrt::Microsoft::Management::Configuration::implementation hstring m_origin; hstring m_path; guid m_instanceIdentifier; - clock::time_point m_initialIntent; + clock::time_point m_firstApply{}; Windows::Foundation::Collections::IVector m_configurationUnits{ winrt::single_threaded_vector() }; winrt::event> m_configurationSetChange; diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl index 836e90a0e2..63ed4c9bd2 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl @@ -9,9 +9,13 @@ namespace Microsoft.Management.Configuration [contract(Microsoft.Management.Configuration.Contract, 1)] enum ConfigurationSetState { + // The state of the configuration set is unknown. Unknown, + // The configuration set is in the queue to be applied. Pending, + // The configuration set is actively being applied. InProgress, + // The configuration set has completed being applied. Completed, }; @@ -19,10 +23,15 @@ namespace Microsoft.Management.Configuration [contract(Microsoft.Management.Configuration.Contract, 1)] enum ConfigurationUnitState { + // The state of the configuration unit is unknown. Unknown, + // The configuration unit is in the queue to be applied. Pending, + // The configuration unit is actively being applied. InProgress, + // The configuration unit has completed being applied. Completed, + // The configuration unit was not applied due to external factors. Skipped, }; @@ -122,7 +131,7 @@ namespace Microsoft.Management.Configuration Assert, // The configuration unit will only be used to Get the current system state. Inform, - // The configuration unit will be used to Set the current system state. + // The configuration unit will be used to Apply the current system state. // The configuration unit will be used to Test and Get the current system state as part of that process. Apply, }; @@ -179,7 +188,9 @@ namespace Microsoft.Management.Configuration enum ConfigurationSetChangeEventType { Unknown, + // The change event was for the set state. Only ConfigurationSetChangeData.SetState is valid. SetStateChanged, + // The change event was for the unit state. All ConfigurationSetChangeData properties are valid. UnitStateChanged, }; @@ -227,7 +238,7 @@ namespace Microsoft.Management.Configuration // The state that the set is in. ConfigurationSetState State{ get; }; // The time that this set was recorded with intent to apply. - Windows.Foundation.DateTime InitialIntent{ get; }; + Windows.Foundation.DateTime FirstApply{ get; }; // The time that this set was last started to be applied. Windows.Foundation.DateTime ApplyBegun{ get; }; // The time that this set was last finished being applied (does not indicate success). diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj index 54e8ca7d2d..369559eead 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -195,8 +195,8 @@ - - {5890d6ed-7c3b-40f3-b436-b54f640d9e65} + + {f3f6e699-bc5d-4950-8a05-e49dd9eb0d51} diff --git a/src/Microsoft.Management.Configuration/pch.h b/src/Microsoft.Management.Configuration/pch.h index 930db9788e..6ad465fc7a 100644 --- a/src/Microsoft.Management.Configuration/pch.h +++ b/src/Microsoft.Management.Configuration/pch.h @@ -6,8 +6,6 @@ #include #include -// TODO: Is this needed? - #pragma warning( push ) #pragma warning ( disable : 4467 6388) // 4467 Allow use of uuid attribute for com object creation. From c20dddeabca2580d88f9cdf60d85db921ec4c878 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Fri, 10 Feb 2023 12:33:13 -0800 Subject: [PATCH 28/31] Break down and directly reference the module project rather than relying on it to come through the dependency --- .../Microsoft.Management.Configuration.UnitTests.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj b/src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj index 73af0be80a..c610bdc4c0 100644 --- a/src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj +++ b/src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj @@ -36,6 +36,9 @@ PreserveNewest True + + True + From 959dbb3fdf254bf3b43d2bb7fed05ef0c674bdc9 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Fri, 10 Feb 2023 13:37:48 -0800 Subject: [PATCH 29/31] Remove test task and fix platform for test publishing --- azure-pipelines.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 388f3331e8..a813fb3abe 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -290,14 +290,6 @@ jobs: codeCoverageEnabled: true platform: 'Any CPU' configuration: '$(BuildConfiguration)' - - - task: PowerShell@2 - displayName: TEMP - Diagnose filesystem for unit tests - inputs: - targetType: 'inline' - script: | - Get-ChildItem -Recurse - workingDirectory: '$(buildOutDir)\Microsoft.Management.Configuration.UnitTests' - task: VSTest@2 displayName: 'Run tests: Microsoft.Management.Configuration.UnitTests' @@ -306,7 +298,7 @@ jobs: testAssemblyVer2: '**\Microsoft.Management.Configuration.UnitTests.dll' searchFolder: '$(buildOutDir)\Microsoft.Management.Configuration.UnitTests' codeCoverageEnabled: true - platform: 'x64' + platform: '$(buildPlatform)' configuration: '$(BuildConfiguration)' - task: CopyFiles@2 From f197d90b55df85ae60f9b31a441bf1ef5d78868d Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Fri, 10 Feb 2023 14:43:23 -0800 Subject: [PATCH 30/31] Remove RTTI from configuration and dependencies --- .../AppInstallerSharedLib.vcxproj | 12 +++++++++++ src/JsonCppLib/JsonCppLib.vcxproj | 20 +++++++++++++++---- ...Microsoft.Management.Configuration.vcxproj | 8 ++++++++ src/YamlCppLib/YamlCppLib.vcxproj | 12 +++++++++++ 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj b/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj index 03d0948b82..4fdc39cbc8 100644 --- a/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj +++ b/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj @@ -186,6 +186,11 @@ true true true + false + false + false + false + false false @@ -201,6 +206,8 @@ true true true + false + false Windows @@ -228,6 +235,10 @@ false false false + false + false + false + false true @@ -250,6 +261,7 @@ stdcpp17 MultiThreaded %(AdditionalOptions) /fsanitize-coverage=inline-8bit-counters /fsanitize-coverage=edge /fsanitize-coverage=trace-cmp /fsanitize-coverage=trace-div + false true diff --git a/src/JsonCppLib/JsonCppLib.vcxproj b/src/JsonCppLib/JsonCppLib.vcxproj index be733bfbe8..2f42499f8e 100644 --- a/src/JsonCppLib/JsonCppLib.vcxproj +++ b/src/JsonCppLib/JsonCppLib.vcxproj @@ -84,13 +84,13 @@ false v142 v143 - Spectre + Spectre StaticLibrary false - v142 - v143 + v142 + v143 true @@ -104,7 +104,7 @@ false v142 v143 - Spectre + Spectre @@ -177,6 +177,8 @@ Disabled stdcpp17 json + false + false MachineX86 @@ -192,6 +194,7 @@ ProgramDatabase stdcpp17 json + false MachineX86 @@ -206,6 +209,7 @@ stdcpp17 json Level3 + false @@ -215,6 +219,7 @@ Level3 /fsanitize-coverage=inline-8bit-counters /fsanitize-coverage=edge /fsanitize-coverage=trace-cmp /fsanitize-coverage=trace-div %(AdditionalOptions) MultiThreaded + false @@ -222,6 +227,7 @@ stdcpp17 json Level3 + false @@ -229,6 +235,7 @@ stdcpp17 json Level3 + false @@ -236,6 +243,8 @@ stdcpp17 json Level3 + false + false @@ -243,6 +252,8 @@ stdcpp17 json Level3 + false + false @@ -250,6 +261,7 @@ stdcpp17 json Level3 + false diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj index 369559eead..bcf9f79ce1 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -116,11 +116,19 @@ _DEBUG;%(PreprocessorDefinitions) $(OutDir)$(TargetName)Debug.pdb + false + false + false + false NDEBUG;%(PreprocessorDefinitions) + false + false + false + false true diff --git a/src/YamlCppLib/YamlCppLib.vcxproj b/src/YamlCppLib/YamlCppLib.vcxproj index a42bda6a31..dc52d59ad8 100644 --- a/src/YamlCppLib/YamlCppLib.vcxproj +++ b/src/YamlCppLib/YamlCppLib.vcxproj @@ -172,6 +172,7 @@ stdcpp17 Level3 /D YAML_DECLARE_STATIC /D HAVE_CONFIG_H %(AdditionalOptions) + false @@ -180,6 +181,7 @@ stdcpp17 Level3 /D YAML_DECLARE_STATIC /D HAVE_CONFIG_H %(AdditionalOptions) + false @@ -188,6 +190,7 @@ stdcpp17 Level3 /D YAML_DECLARE_STATIC /D HAVE_CONFIG_H %(AdditionalOptions) + false @@ -196,6 +199,7 @@ stdcpp17 Level3 /D YAML_DECLARE_STATIC /D HAVE_CONFIG_H %(AdditionalOptions) + false @@ -204,6 +208,7 @@ stdcpp17 Level3 /D YAML_DECLARE_STATIC /D HAVE_CONFIG_H %(AdditionalOptions) + false @@ -212,6 +217,7 @@ stdcpp17 Level3 /D YAML_DECLARE_STATIC /D HAVE_CONFIG_H %(AdditionalOptions) + false @@ -220,6 +226,7 @@ stdcpp17 Level3 /D YAML_DECLARE_STATIC /D HAVE_CONFIG_H %(AdditionalOptions) + false @@ -228,6 +235,7 @@ stdcpp17 Level3 /D YAML_DECLARE_STATIC /D HAVE_CONFIG_H %(AdditionalOptions) + false @@ -236,6 +244,7 @@ stdcpp17 Level3 /D YAML_DECLARE_STATIC /D HAVE_CONFIG_H %(AdditionalOptions) + false @@ -244,6 +253,7 @@ stdcpp17 Level3 /D YAML_DECLARE_STATIC /D HAVE_CONFIG_H %(AdditionalOptions) + false @@ -252,6 +262,7 @@ stdcpp17 Level3 /D YAML_DECLARE_STATIC /D HAVE_CONFIG_H %(AdditionalOptions) + false @@ -261,6 +272,7 @@ Level3 /D YAML_DECLARE_STATIC /D HAVE_CONFIG_H /fsanitize-coverage=inline-8bit-counters /fsanitize-coverage=edge /fsanitize-coverage=trace-cmp /fsanitize-coverage=trace-div %(AdditionalOptions) MultiThreaded + false From 3e4f1bafba2600114ad371d44400117f4551cfb9 Mon Sep 17 00:00:00 2001 From: JohnMcPMS Date: Tue, 14 Feb 2023 11:32:52 -0800 Subject: [PATCH 31/31] PR feedback: Remove Any CPU and ARM solution configurations since we don't need them --- src/AppInstallerCLI.sln | 420 ------------------ ...Microsoft.Management.Configuration.vcxproj | 2 +- 2 files changed, 1 insertion(+), 421 deletions(-) diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index cf0318e5f7..8b2317e081 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -157,34 +157,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Management.Config EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|ARM = Debug|ARM Debug|ARM64 = Debug|ARM64 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 - Fuzzing|Any CPU = Fuzzing|Any CPU - Fuzzing|ARM = Fuzzing|ARM Fuzzing|ARM64 = Fuzzing|ARM64 Fuzzing|x64 = Fuzzing|x64 Fuzzing|x86 = Fuzzing|x86 - Release|Any CPU = Release|Any CPU - Release|ARM = Release|ARM Release|ARM64 = Release|ARM64 Release|x64 = Release|x64 Release|x86 = Release|x86 - TestRelease|Any CPU = TestRelease|Any CPU - TestRelease|ARM = TestRelease|ARM TestRelease|ARM64 = TestRelease|ARM64 TestRelease|x64 = TestRelease|x64 TestRelease|x86 = TestRelease|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM.ActiveCfg = Debug|ARM - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM.Build.0 = Debug|ARM - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM.Deploy.0 = Debug|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM64.ActiveCfg = Debug|ARM64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM64.Build.0 = Debug|ARM64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM64.Deploy.0 = Debug|ARM64 @@ -194,19 +180,9 @@ Global {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x86.ActiveCfg = Debug|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x86.Build.0 = Debug|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x86.Deploy.0 = Debug|x86 - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|Any CPU.ActiveCfg = Release|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|Any CPU.Build.0 = Release|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|Any CPU.Deploy.0 = Release|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|ARM.ActiveCfg = Release|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|x64.ActiveCfg = Release|x64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|x86.ActiveCfg = Release|x86 - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|Any CPU.Build.0 = Release|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|Any CPU.Deploy.0 = Release|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM.ActiveCfg = Release|ARM - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM.Build.0 = Release|ARM - {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM.Deploy.0 = Release|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM64.ActiveCfg = Release|ARM64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM64.Build.0 = Release|ARM64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM64.Deploy.0 = Release|ARM64 @@ -216,297 +192,181 @@ Global {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.ActiveCfg = Release|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.Build.0 = Release|x86 {6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.Deploy.0 = Release|x86 - {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|Any CPU.ActiveCfg = Release|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|Any CPU.Build.0 = Release|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|Any CPU.Deploy.0 = Release|Any CPU - {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|ARM.ActiveCfg = Release|ARM {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|x64.ActiveCfg = Release|x64 {6AA3791A-0713-4548-A357-87A323E7AC3A}.TestRelease|x86.ActiveCfg = Release|x86 - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM.ActiveCfg = Debug|ARM - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM.Build.0 = Debug|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM64.ActiveCfg = Debug|ARM64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM64.Build.0 = Debug|ARM64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x64.ActiveCfg = Debug|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x64.Build.0 = Debug|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x86.ActiveCfg = Debug|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x86.Build.0 = Debug|Win32 - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|Any CPU.Build.0 = Release|Win32 - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|ARM.ActiveCfg = Release|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|x64.ActiveCfg = Release|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|x86.ActiveCfg = Release|Win32 - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|Any CPU.ActiveCfg = Release|Win32 - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|ARM.ActiveCfg = Release|ARM - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|ARM.Build.0 = Release|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|ARM64.ActiveCfg = Release|ARM64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|ARM64.Build.0 = Release|ARM64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x64.ActiveCfg = Release|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x64.Build.0 = Release|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x86.ActiveCfg = Release|Win32 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x86.Build.0 = Release|Win32 - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|Any CPU.ActiveCfg = Release|Win32 - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|Any CPU.Build.0 = Release|Win32 - {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|ARM.ActiveCfg = Release|ARM {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|x64.ActiveCfg = Release|x64 {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.TestRelease|x86.ActiveCfg = Release|Win32 - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM.ActiveCfg = Debug|ARM - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM.Build.0 = Debug|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM64.ActiveCfg = Debug|ARM64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM64.Build.0 = Debug|ARM64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x64.ActiveCfg = Debug|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x64.Build.0 = Debug|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x86.ActiveCfg = Debug|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x86.Build.0 = Debug|Win32 - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|Any CPU.Build.0 = Release|Win32 - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|ARM.ActiveCfg = Release|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|x64.ActiveCfg = Release|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|x86.ActiveCfg = Release|Win32 - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|Any CPU.ActiveCfg = Release|Win32 - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|ARM.ActiveCfg = Release|ARM - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|ARM.Build.0 = Release|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|ARM64.ActiveCfg = Release|ARM64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|ARM64.Build.0 = Release|ARM64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x64.ActiveCfg = Release|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x64.Build.0 = Release|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x86.ActiveCfg = Release|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x86.Build.0 = Release|Win32 - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|Any CPU.ActiveCfg = Release|Win32 - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|Any CPU.Build.0 = Release|Win32 - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|ARM.ActiveCfg = Release|ARM - {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|ARM.Build.0 = Release|ARM {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|ARM64.Build.0 = Release|ARM64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|x64.ActiveCfg = Release|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|x64.Build.0 = Release|x64 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|x86.ActiveCfg = Release|Win32 {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.TestRelease|x86.Build.0 = Release|Win32 - {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|ARM.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|ARM64.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x64.ActiveCfg = Debug|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x64.Build.0 = Debug|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x86.ActiveCfg = Debug|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x86.Build.0 = Debug|Win32 - {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|Any CPU.ActiveCfg = Release|x64 - {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|Any CPU.Build.0 = Release|x64 - {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|ARM.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|ARM64.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|x64.ActiveCfg = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|x86.ActiveCfg = Release|Win32 - {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|Any CPU.ActiveCfg = Release|Win32 - {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|ARM.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|ARM64.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x64.ActiveCfg = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x64.Build.0 = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x86.ActiveCfg = Release|Win32 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x86.Build.0 = Release|Win32 - {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|Any CPU.ActiveCfg = Release|x64 - {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|Any CPU.Build.0 = Release|x64 - {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|ARM.ActiveCfg = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|ARM64.ActiveCfg = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|x64.ActiveCfg = Release|x64 {89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.TestRelease|x86.ActiveCfg = Release|Win32 - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM.ActiveCfg = Debug|ARM - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM.Build.0 = Debug|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM64.ActiveCfg = Debug|ARM64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM64.Build.0 = Debug|ARM64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x64.ActiveCfg = Debug|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x64.Build.0 = Debug|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x86.ActiveCfg = Debug|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x86.Build.0 = Debug|Win32 - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|Any CPU.Build.0 = Release|Win32 - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|ARM.ActiveCfg = Release|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|x64.ActiveCfg = Release|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|x86.ActiveCfg = Release|Win32 - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|Any CPU.ActiveCfg = Release|Win32 - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|ARM.ActiveCfg = Release|ARM - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|ARM.Build.0 = Release|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|ARM64.ActiveCfg = Release|ARM64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|ARM64.Build.0 = Release|ARM64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x64.ActiveCfg = Release|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x64.Build.0 = Release|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x86.ActiveCfg = Release|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x86.Build.0 = Release|Win32 - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|Any CPU.ActiveCfg = Release|Win32 - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|Any CPU.Build.0 = Release|Win32 - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|ARM.ActiveCfg = Release|ARM - {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|ARM.Build.0 = Release|ARM {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|ARM64.Build.0 = Release|ARM64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|x64.ActiveCfg = Release|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|x64.Build.0 = Release|x64 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|x86.ActiveCfg = Release|Win32 {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.TestRelease|x86.Build.0 = Release|Win32 - {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM.ActiveCfg = Debug|ARM - {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM.Build.0 = Debug|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM64.ActiveCfg = Debug|ARM64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|ARM64.Build.0 = Debug|ARM64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|x64.ActiveCfg = Debug|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|x64.Build.0 = Debug|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|x86.ActiveCfg = Debug|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Debug|x86.Build.0 = Debug|Win32 - {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|Win32 - {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|ARM.ActiveCfg = Release|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|x64.Build.0 = Fuzzing|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Fuzzing|x86.ActiveCfg = Release|Win32 - {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|Any CPU.ActiveCfg = Release|Win32 - {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|ARM.ActiveCfg = Release|ARM - {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|ARM.Build.0 = Release|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|ARM64.ActiveCfg = Release|ARM64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|ARM64.Build.0 = Release|ARM64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x64.ActiveCfg = Release|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x64.Build.0 = Release|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x86.ActiveCfg = Release|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.Release|x86.Build.0 = Release|Win32 - {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|Any CPU.ActiveCfg = Fuzzing|ARM - {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|Any CPU.Build.0 = Fuzzing|ARM - {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|ARM.ActiveCfg = Release|ARM - {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|ARM.Build.0 = Release|ARM {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|ARM64.Build.0 = Release|ARM64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|x64.ActiveCfg = Release|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|x64.Build.0 = Release|x64 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|x86.ActiveCfg = Release|Win32 {8BB94BB8-374F-4294-BCA1-C7811514A6B7}.TestRelease|x86.Build.0 = Release|Win32 - {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM.ActiveCfg = Debug|ARM - {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM.Build.0 = Debug|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM64.ActiveCfg = Debug|ARM64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM64.Build.0 = Debug|ARM64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x64.ActiveCfg = Debug|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x64.Build.0 = Debug|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x86.ActiveCfg = Debug|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x86.Build.0 = Debug|Win32 - {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64 - {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|ARM.ActiveCfg = Release|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x64.Build.0 = Fuzzing|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x86.ActiveCfg = Release|Win32 - {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|Any CPU.ActiveCfg = Release|Win32 - {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|ARM.ActiveCfg = Release|ARM - {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|ARM.Build.0 = Release|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|ARM64.ActiveCfg = Release|ARM64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|ARM64.Build.0 = Release|ARM64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x64.ActiveCfg = Release|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x64.Build.0 = Release|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x86.ActiveCfg = Release|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x86.Build.0 = Release|Win32 - {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|Any CPU.ActiveCfg = Release|x64 - {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|Any CPU.Build.0 = Release|x64 - {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|ARM.ActiveCfg = Release|ARM - {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|ARM.Build.0 = Release|ARM {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|ARM64.Build.0 = Release|ARM64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|x64.ActiveCfg = Release|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|x64.Build.0 = Release|x64 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|x86.ActiveCfg = Release|Win32 {5890D6ED-7C3B-40F3-B436-B54F640D9E65}.TestRelease|x86.Build.0 = Release|Win32 - {FB313532-38B0-4676-9303-AB200AA13576}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM.ActiveCfg = Debug|ARM - {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM.Build.0 = Debug|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM64.ActiveCfg = Debug|ARM64 {FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM64.Build.0 = Debug|ARM64 {FB313532-38B0-4676-9303-AB200AA13576}.Debug|x64.ActiveCfg = Debug|x64 {FB313532-38B0-4676-9303-AB200AA13576}.Debug|x64.Build.0 = Debug|x64 {FB313532-38B0-4676-9303-AB200AA13576}.Debug|x86.ActiveCfg = Debug|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Debug|x86.Build.0 = Debug|Win32 - {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|Any CPU.Build.0 = Release|Win32 - {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|ARM.ActiveCfg = Release|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|x64.ActiveCfg = Release|x64 {FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|x86.ActiveCfg = Release|Win32 - {FB313532-38B0-4676-9303-AB200AA13576}.Release|Any CPU.ActiveCfg = Release|Win32 - {FB313532-38B0-4676-9303-AB200AA13576}.Release|ARM.ActiveCfg = Release|ARM - {FB313532-38B0-4676-9303-AB200AA13576}.Release|ARM.Build.0 = Release|ARM {FB313532-38B0-4676-9303-AB200AA13576}.Release|ARM64.ActiveCfg = Release|ARM64 {FB313532-38B0-4676-9303-AB200AA13576}.Release|ARM64.Build.0 = Release|ARM64 {FB313532-38B0-4676-9303-AB200AA13576}.Release|x64.ActiveCfg = Release|x64 {FB313532-38B0-4676-9303-AB200AA13576}.Release|x64.Build.0 = Release|x64 {FB313532-38B0-4676-9303-AB200AA13576}.Release|x86.ActiveCfg = Release|Win32 {FB313532-38B0-4676-9303-AB200AA13576}.Release|x86.Build.0 = Release|Win32 - {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|Any CPU.ActiveCfg = Release|Win32 - {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|Any CPU.Build.0 = Release|Win32 - {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|ARM.ActiveCfg = Release|ARM {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|x64.ActiveCfg = Release|x64 {FB313532-38B0-4676-9303-AB200AA13576}.TestRelease|x86.ActiveCfg = Release|Win32 - {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM.ActiveCfg = Debug|ARM - {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM.Build.0 = Debug|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM64.ActiveCfg = Debug|ARM64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM64.Build.0 = Debug|ARM64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x64.ActiveCfg = Debug|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x64.Build.0 = Debug|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x86.ActiveCfg = Debug|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x86.Build.0 = Debug|Win32 - {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|Any CPU.Build.0 = Release|Win32 - {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|ARM.ActiveCfg = Release|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|x64.ActiveCfg = Release|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|x86.ActiveCfg = Release|Win32 - {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|Any CPU.ActiveCfg = Release|Win32 - {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|ARM.ActiveCfg = Release|ARM - {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|ARM.Build.0 = Release|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|ARM64.ActiveCfg = Release|ARM64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|ARM64.Build.0 = Release|ARM64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x64.ActiveCfg = Release|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x64.Build.0 = Release|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x86.ActiveCfg = Release|Win32 {6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x86.Build.0 = Release|Win32 - {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|Any CPU.ActiveCfg = Release|Win32 - {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|Any CPU.Build.0 = Release|Win32 - {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|ARM.ActiveCfg = Release|ARM {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|x64.ActiveCfg = Release|x64 {6CB84692-5994-407D-B9BD-9216AF77FE83}.TestRelease|x86.ActiveCfg = Release|Win32 - {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|Any CPU.ActiveCfg = Debug|x86 - {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|ARM.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|ARM64.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x64.ActiveCfg = Debug|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x64.Build.0 = Debug|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x86.ActiveCfg = Debug|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x86.Build.0 = Debug|x86 - {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|Any CPU.ActiveCfg = TestOnly|x64 - {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|Any CPU.Build.0 = TestOnly|x64 - {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|ARM.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|ARM64.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|x64.ActiveCfg = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|x86.ActiveCfg = Release|x86 - {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|Any CPU.ActiveCfg = Release|x86 - {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|ARM.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|ARM64.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x64.ActiveCfg = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x64.Build.0 = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x86.ActiveCfg = Release|x86 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x86.Build.0 = Release|x86 - {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|Any CPU.ActiveCfg = TestOnly|x64 - {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|Any CPU.Build.0 = TestOnly|x64 - {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|ARM.ActiveCfg = TestOnly|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|ARM64.ActiveCfg = TestOnly|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|x64.ActiveCfg = Release|x64 {3C0269FA-E582-4CA7-9E33-3881A005CA0C}.TestRelease|x86.ActiveCfg = Release|x86 - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM.ActiveCfg = Debug|ARM - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM.Build.0 = Debug|ARM - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM.Deploy.0 = Debug|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM64.ActiveCfg = Debug|ARM64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM64.Build.0 = Debug|ARM64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM64.Deploy.0 = Debug|ARM64 @@ -516,19 +376,9 @@ Global {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x86.ActiveCfg = Debug|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x86.Build.0 = Debug|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x86.Deploy.0 = Debug|x86 - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|Any CPU.ActiveCfg = Release|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|Any CPU.Build.0 = Release|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|Any CPU.Deploy.0 = Release|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|ARM.ActiveCfg = Release|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|x64.ActiveCfg = Release|x64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|x86.ActiveCfg = Release|x86 - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|Any CPU.Build.0 = Release|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|Any CPU.Deploy.0 = Release|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM.ActiveCfg = Release|ARM - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM.Build.0 = Release|ARM - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM.Deploy.0 = Release|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM64.ActiveCfg = Release|ARM64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM64.Build.0 = Release|ARM64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM64.Deploy.0 = Release|ARM64 @@ -538,702 +388,432 @@ Global {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.ActiveCfg = Release|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.Build.0 = Release|x86 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.Deploy.0 = Release|x86 - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|Any CPU.ActiveCfg = Release|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|Any CPU.Build.0 = Release|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|Any CPU.Deploy.0 = Release|Any CPU - {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|ARM.ActiveCfg = Release|ARM {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|x64.ActiveCfg = Release|x64 {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.TestRelease|x86.ActiveCfg = Release|x86 - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|Any CPU.ActiveCfg = Debug - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|Any CPU.Build.0 = Debug - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|ARM.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|ARM64.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|x64.ActiveCfg = Debug {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|x86.ActiveCfg = Debug - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|Any CPU.ActiveCfg = Release - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|Any CPU.Build.0 = Release - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|ARM.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|ARM64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|x64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|x86.ActiveCfg = Release - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|Any CPU.ActiveCfg = Release - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|Any CPU.Build.0 = Release - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|ARM.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|ARM64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|x64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|x86.ActiveCfg = Release - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|Any CPU.ActiveCfg = Release - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|Any CPU.Build.0 = Release - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|ARM.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|ARM64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|x64.ActiveCfg = Release {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.TestRelease|x86.ActiveCfg = Release - {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|Any CPU.ActiveCfg = Debug|x86 - {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|ARM.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|ARM64.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x64.ActiveCfg = Debug|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x64.Build.0 = Debug|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x86.ActiveCfg = Debug|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x86.Build.0 = Debug|x86 - {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|Any CPU.ActiveCfg = Release|x64 - {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|Any CPU.Build.0 = Release|x64 - {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|ARM.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|ARM64.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|x64.ActiveCfg = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|x86.ActiveCfg = Release|x86 - {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|Any CPU.ActiveCfg = Release|x86 - {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|ARM.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|ARM64.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x64.ActiveCfg = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x64.Build.0 = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x86.ActiveCfg = Release|x86 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x86.Build.0 = Release|x86 - {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|Any CPU.ActiveCfg = Release|x64 - {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|Any CPU.Build.0 = Release|x64 - {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|ARM.ActiveCfg = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|ARM64.ActiveCfg = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|x64.ActiveCfg = Release|x64 {3B8466CF-4FDD-4329-9C80-91321C4AAC99}.TestRelease|x86.ActiveCfg = Release|x86 - {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM.ActiveCfg = Debug|ARM - {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM.Build.0 = Debug|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM64.ActiveCfg = Debug|ARM64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|ARM64.Build.0 = Debug|ARM64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|x64.ActiveCfg = Debug|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|x64.Build.0 = Debug|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|x86.ActiveCfg = Debug|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Debug|x86.Build.0 = Debug|Win32 - {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64 - {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|ARM.ActiveCfg = Release|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|x64.Build.0 = Fuzzing|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Fuzzing|x86.ActiveCfg = Release|Win32 - {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|Any CPU.ActiveCfg = Release|Win32 - {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|ARM.ActiveCfg = Release|ARM - {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|ARM.Build.0 = Release|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|ARM64.ActiveCfg = Release|ARM64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|ARM64.Build.0 = Release|ARM64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x64.ActiveCfg = Release|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x64.Build.0 = Release|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x86.ActiveCfg = Release|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.Release|x86.Build.0 = Release|Win32 - {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|Any CPU.ActiveCfg = Release|x64 - {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|Any CPU.Build.0 = Release|x64 - {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|ARM.ActiveCfg = Release|ARM - {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|ARM.Build.0 = Release|ARM {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|ARM64.Build.0 = Release|ARM64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|x64.ActiveCfg = Release|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|x64.Build.0 = Release|x64 {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|x86.ActiveCfg = Release|Win32 {82B39FDA-E86B-4713-A873-9D56DE00247A}.TestRelease|x86.Build.0 = Release|Win32 - {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|Any CPU.ActiveCfg = Debug|x64 - {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|ARM.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|ARM64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|x64.ActiveCfg = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|x86.ActiveCfg = Fuzzing|x64 - {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64 - {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|ARM.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|ARM64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x64.Build.0 = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x86.ActiveCfg = Fuzzing|x64 - {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|Any CPU.ActiveCfg = Debug|x64 - {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|Any CPU.Build.0 = Debug|x64 - {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|ARM.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|ARM64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|x64.ActiveCfg = Fuzzing|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.Release|x86.ActiveCfg = Fuzzing|x64 - {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|Any CPU.ActiveCfg = Debug|x64 - {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|Any CPU.Build.0 = Debug|x64 - {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|ARM.ActiveCfg = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|ARM64.ActiveCfg = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|x64.ActiveCfg = Debug|x64 {1622DA16-914F-4F57-A259-D5169003CC8C}.TestRelease|x86.ActiveCfg = Debug|x64 - {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|Any CPU.ActiveCfg = Debug|x86 - {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|ARM.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|ARM64.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x64.ActiveCfg = Debug|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x64.Build.0 = Debug|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x86.ActiveCfg = Debug|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x86.Build.0 = Debug|x86 - {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|Any CPU.ActiveCfg = Release|x64 - {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|Any CPU.Build.0 = Release|x64 - {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|ARM.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|ARM64.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|x64.ActiveCfg = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|x86.ActiveCfg = Release|x86 - {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|Any CPU.ActiveCfg = Release|x86 - {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|ARM.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|ARM64.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x64.ActiveCfg = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x64.Build.0 = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x86.ActiveCfg = Release|x86 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x86.Build.0 = Release|x86 - {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|Any CPU.ActiveCfg = Release|x64 - {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|Any CPU.Build.0 = Release|x64 - {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|ARM.ActiveCfg = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|ARM64.ActiveCfg = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|x64.ActiveCfg = Release|x64 {3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.TestRelease|x86.ActiveCfg = Release|x86 - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM.ActiveCfg = Debug|ARM - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM.Build.0 = Debug|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM64.ActiveCfg = Debug|ARM64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|ARM64.Build.0 = Debug|ARM64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|x64.ActiveCfg = Debug|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|x64.Build.0 = Debug|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|x86.ActiveCfg = Debug|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Debug|x86.Build.0 = Debug|Win32 - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|Any CPU.Build.0 = Release|Win32 - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|ARM.ActiveCfg = Release|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|ARM64.ActiveCfg = Release|ARM64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|x64.ActiveCfg = Release|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Fuzzing|x86.ActiveCfg = Release|Win32 - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|Any CPU.ActiveCfg = Release|Win32 - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|ARM.ActiveCfg = Release|ARM - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|ARM.Build.0 = Release|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|ARM64.ActiveCfg = Release|ARM64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|ARM64.Build.0 = Release|ARM64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x64.ActiveCfg = Release|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x64.Build.0 = Release|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x86.ActiveCfg = Release|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.Release|x86.Build.0 = Release|Win32 - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|Any CPU.ActiveCfg = Release|Win32 - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|Any CPU.Build.0 = Release|Win32 - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|ARM.ActiveCfg = Release|ARM - {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|ARM.Build.0 = Release|ARM {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|ARM64.Build.0 = Release|ARM64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|x64.ActiveCfg = Release|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|x64.Build.0 = Release|x64 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|x86.ActiveCfg = Release|Win32 {866C3F06-636F-4BE8-BC24-5F86ECC606A1}.TestRelease|x86.Build.0 = Release|Win32 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM.ActiveCfg = Debug|ARM - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM.Build.0 = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM64.ActiveCfg = Debug|ARM64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM64.Build.0 = Debug|ARM64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x64.ActiveCfg = Debug|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x64.Build.0 = Debug|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x86.ActiveCfg = Debug|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x86.Build.0 = Debug|Win32 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|Any CPU.Build.0 = Release|Win32 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|ARM.ActiveCfg = Debug|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x64.ActiveCfg = Debug|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x86.ActiveCfg = Debug|Win32 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|Any CPU.ActiveCfg = Release|Win32 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM.ActiveCfg = Release|ARM - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM.Build.0 = Release|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM64.ActiveCfg = Release|ARM64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM64.Build.0 = Release|ARM64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x64.ActiveCfg = Release|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x64.Build.0 = Release|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x86.ActiveCfg = Release|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x86.Build.0 = Release|Win32 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|Any CPU.ActiveCfg = Release|Win32 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|Any CPU.Build.0 = Release|Win32 - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|ARM.ActiveCfg = Release|ARM - {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|ARM.Build.0 = Release|ARM {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|ARM64.Build.0 = Release|ARM64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|x64.ActiveCfg = Release|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|x64.Build.0 = Release|x64 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|x86.ActiveCfg = Release|Win32 {1CC41A9A-AE66-459D-9210-1E572DD7BE69}.TestRelease|x86.Build.0 = Release|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM.ActiveCfg = Debug|ARM - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM.Build.0 = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM64.ActiveCfg = Debug|ARM64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM64.Build.0 = Debug|ARM64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x64.ActiveCfg = Debug|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x64.Build.0 = Debug|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.ActiveCfg = Debug|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.Build.0 = Debug|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|Any CPU.ActiveCfg = Release|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|Any CPU.Build.0 = Release|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|ARM.ActiveCfg = Debug|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x64.ActiveCfg = Debug|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x86.ActiveCfg = Debug|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|Any CPU.ActiveCfg = Release|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM.ActiveCfg = Release|ARM - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM.Build.0 = Release|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM64.ActiveCfg = Release|ARM64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM64.Build.0 = Release|ARM64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x64.ActiveCfg = Release|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x64.Build.0 = Release|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.ActiveCfg = Release|Win32 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.Build.0 = Release|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|Any CPU.ActiveCfg = Release|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|Any CPU.Build.0 = Release|Win32 - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|ARM.ActiveCfg = Release|ARM {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|x64.ActiveCfg = Release|x64 {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.TestRelease|x86.ActiveCfg = Release|Win32 - {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|Any CPU.Build.0 = Debug|Any CPU - {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|ARM.ActiveCfg = Debug|Any CPU - {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|ARM.Build.0 = Debug|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|ARM64.ActiveCfg = Debug|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|ARM64.Build.0 = Debug|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|x64.ActiveCfg = Debug|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|x64.Build.0 = Debug|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|x86.ActiveCfg = Debug|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|x86.Build.0 = Debug|Any CPU - {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|Any CPU.ActiveCfg = Debug|Any CPU - {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|Any CPU.Build.0 = Debug|Any CPU - {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|ARM.ActiveCfg = Debug|Any CPU - {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|ARM.Build.0 = Debug|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|ARM64.ActiveCfg = Debug|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|ARM64.Build.0 = Debug|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|x64.ActiveCfg = Debug|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|x64.Build.0 = Debug|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|x86.ActiveCfg = Debug|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|x86.Build.0 = Debug|Any CPU - {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|Any CPU.ActiveCfg = Release|Any CPU - {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|Any CPU.Build.0 = Release|Any CPU - {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|ARM.ActiveCfg = Release|Any CPU - {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|ARM.Build.0 = Release|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|ARM64.ActiveCfg = Release|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|ARM64.Build.0 = Release|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|x64.ActiveCfg = Release|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|x64.Build.0 = Release|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|x86.ActiveCfg = Release|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|x86.Build.0 = Release|Any CPU - {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|Any CPU.ActiveCfg = Release|Any CPU - {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|Any CPU.Build.0 = Release|Any CPU - {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|ARM.ActiveCfg = Release|Any CPU - {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|ARM.Build.0 = Release|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|ARM64.ActiveCfg = Release|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|ARM64.Build.0 = Release|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|x64.ActiveCfg = Release|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|x64.Build.0 = Release|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|x86.ActiveCfg = Release|Any CPU {846FB88B-BF1B-4F33-9883-E589CEC99739}.TestRelease|x86.Build.0 = Release|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|ARM.ActiveCfg = Debug|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|ARM.Build.0 = Debug|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|ARM64.ActiveCfg = Debug|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|ARM64.Build.0 = Debug|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|x64.ActiveCfg = Debug|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|x64.Build.0 = Debug|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|x86.ActiveCfg = Debug|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|x86.Build.0 = Debug|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|Any CPU.ActiveCfg = Debug|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|Any CPU.Build.0 = Debug|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|ARM.ActiveCfg = Debug|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|ARM.Build.0 = Debug|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|ARM64.ActiveCfg = Debug|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|ARM64.Build.0 = Debug|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|x64.ActiveCfg = Debug|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|x64.Build.0 = Debug|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|x86.ActiveCfg = Debug|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|x86.Build.0 = Debug|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|Any CPU.Build.0 = Release|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|ARM.ActiveCfg = Release|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|ARM.Build.0 = Release|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|ARM64.ActiveCfg = Release|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|ARM64.Build.0 = Release|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|x64.ActiveCfg = Release|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|x64.Build.0 = Release|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|x86.ActiveCfg = Release|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.Release|x86.Build.0 = Release|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|Any CPU.ActiveCfg = Release|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|Any CPU.Build.0 = Release|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|ARM.ActiveCfg = Release|Any CPU - {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|ARM.Build.0 = Release|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|ARM64.ActiveCfg = Release|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|ARM64.Build.0 = Release|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|x64.ActiveCfg = Release|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|x64.Build.0 = Release|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|x86.ActiveCfg = Release|Any CPU {68808357-902B-406C-8C19-E8E26A69DE8A}.TestRelease|x86.Build.0 = Release|Any CPU - {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Debug|ARM.ActiveCfg = Debug|ARM - {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Debug|ARM.Build.0 = Debug|ARM {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Debug|ARM64.ActiveCfg = Debug|ARM64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Debug|ARM64.Build.0 = Debug|ARM64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Debug|x64.ActiveCfg = Debug|x64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Debug|x64.Build.0 = Debug|x64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Debug|x86.ActiveCfg = Debug|Win32 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Debug|x86.Build.0 = Debug|Win32 - {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Fuzzing|Any CPU.ActiveCfg = Debug|Win32 - {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Fuzzing|Any CPU.Build.0 = Debug|Win32 - {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Fuzzing|ARM.ActiveCfg = Debug|ARM - {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Fuzzing|ARM.Build.0 = Debug|ARM {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Fuzzing|ARM64.Build.0 = Debug|ARM64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Fuzzing|x64.ActiveCfg = Debug|x64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Fuzzing|x64.Build.0 = Debug|x64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Fuzzing|x86.ActiveCfg = Debug|Win32 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Fuzzing|x86.Build.0 = Debug|Win32 - {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Release|Any CPU.ActiveCfg = Release|Win32 - {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Release|ARM.ActiveCfg = Release|ARM - {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Release|ARM.Build.0 = Release|ARM {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Release|ARM64.ActiveCfg = Release|ARM64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Release|ARM64.Build.0 = Release|ARM64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Release|x64.ActiveCfg = Release|x64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Release|x64.Build.0 = Release|x64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Release|x86.ActiveCfg = Release|Win32 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Release|x86.Build.0 = Release|Win32 - {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.TestRelease|Any CPU.ActiveCfg = Debug|Win32 - {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.TestRelease|Any CPU.Build.0 = Debug|Win32 - {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.TestRelease|ARM.ActiveCfg = Release|ARM - {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.TestRelease|ARM.Build.0 = Release|ARM {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.TestRelease|ARM64.Build.0 = Release|ARM64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.TestRelease|x64.ActiveCfg = Release|x64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.TestRelease|x64.Build.0 = Release|x64 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.TestRelease|x86.ActiveCfg = Release|Win32 {2046B5AF-666D-4CE8-8D3E-C32C57908A56}.TestRelease|x86.Build.0 = Release|Win32 - {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Debug|ARM.ActiveCfg = Debug|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Debug|ARM64.ActiveCfg = Debug|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Debug|x64.ActiveCfg = Debug|x64 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Debug|x64.Build.0 = Debug|x64 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Debug|x86.ActiveCfg = Debug|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Debug|x86.Build.0 = Debug|Win32 - {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Fuzzing|Any CPU.ActiveCfg = Debug|Win32 - {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Fuzzing|Any CPU.Build.0 = Debug|Win32 - {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Fuzzing|ARM.ActiveCfg = Debug|Win32 - {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Fuzzing|ARM.Build.0 = Debug|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Fuzzing|ARM64.ActiveCfg = Debug|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Fuzzing|ARM64.Build.0 = Debug|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Fuzzing|x64.ActiveCfg = Debug|x64 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Fuzzing|x64.Build.0 = Debug|x64 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Fuzzing|x86.ActiveCfg = Debug|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Fuzzing|x86.Build.0 = Debug|Win32 - {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Release|Any CPU.ActiveCfg = Release|Win32 - {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Release|ARM.ActiveCfg = Release|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Release|ARM64.ActiveCfg = Release|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Release|x64.ActiveCfg = Release|x64 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Release|x64.Build.0 = Release|x64 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Release|x86.ActiveCfg = Release|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Release|x86.Build.0 = Release|Win32 - {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|Any CPU.ActiveCfg = Debug|Win32 - {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|Any CPU.Build.0 = Debug|Win32 - {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|ARM.ActiveCfg = Debug|Win32 - {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|ARM.Build.0 = Debug|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|ARM64.ActiveCfg = Debug|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|ARM64.Build.0 = Debug|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|x64.ActiveCfg = Release|x64 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|x64.Build.0 = Release|x64 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|x86.ActiveCfg = Release|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|x86.Build.0 = Release|Win32 - {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|Any CPU.ActiveCfg = Debug|x64 - {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|ARM.ActiveCfg = Debug|ARM - {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|ARM.Build.0 = Debug|ARM {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|ARM64.ActiveCfg = Debug|ARM64 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|ARM64.Build.0 = Debug|ARM64 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|x64.ActiveCfg = Debug|x64 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|x64.Build.0 = Debug|x64 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|x86.ActiveCfg = Debug|x86 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|x86.Build.0 = Debug|x86 - {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|Any CPU.ActiveCfg = Debug|x64 - {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|ARM.ActiveCfg = Debug|ARM {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|ARM64.Build.0 = Debug|ARM64 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|x64.ActiveCfg = Debug|x64 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|x86.ActiveCfg = Debug|x86 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|x86.Build.0 = Debug|x86 - {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|Any CPU.ActiveCfg = Release|x64 - {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|ARM.ActiveCfg = Release|ARM - {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|ARM.Build.0 = Release|ARM {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|ARM64.ActiveCfg = Release|ARM64 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|ARM64.Build.0 = Release|ARM64 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|x64.ActiveCfg = Release|x64 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|x64.Build.0 = Release|x64 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|x86.ActiveCfg = Release|x86 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|x86.Build.0 = Release|x86 - {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|Any CPU.ActiveCfg = Debug|x64 - {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|ARM.ActiveCfg = Debug|ARM {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|ARM64.Build.0 = Release|ARM64 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|x64.ActiveCfg = Release|x64 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|x64.Build.0 = Release|x64 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|x86.ActiveCfg = Release|x86 {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|x86.Build.0 = Release|x86 - {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Debug|Any CPU.ActiveCfg = Debug|x86 - {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Debug|ARM.ActiveCfg = Debug|x86 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Debug|ARM64.ActiveCfg = Debug|x86 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Debug|x64.ActiveCfg = Debug|x64 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Debug|x64.Build.0 = Debug|x64 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Debug|x86.ActiveCfg = Debug|x86 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Debug|x86.Build.0 = Debug|x86 - {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Fuzzing|Any CPU.ActiveCfg = TestOnly|x64 - {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Fuzzing|Any CPU.Build.0 = TestOnly|x64 - {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Fuzzing|ARM.ActiveCfg = Release|x86 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Fuzzing|ARM64.ActiveCfg = Release|x86 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Fuzzing|x64.ActiveCfg = Release|x64 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Fuzzing|x86.ActiveCfg = Release|x86 - {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Release|Any CPU.ActiveCfg = Release|x86 - {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Release|ARM.ActiveCfg = Release|x86 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Release|ARM64.ActiveCfg = Release|x86 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Release|x64.ActiveCfg = Release|x64 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Release|x64.Build.0 = Release|x64 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Release|x86.ActiveCfg = Release|x86 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Release|x86.Build.0 = Release|x86 - {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.TestRelease|Any CPU.ActiveCfg = TestOnly|x64 - {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.TestRelease|Any CPU.Build.0 = TestOnly|x64 - {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.TestRelease|ARM.ActiveCfg = TestOnly|x64 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.TestRelease|ARM64.ActiveCfg = TestOnly|x64 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.TestRelease|x64.ActiveCfg = Release|x64 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.TestRelease|x86.ActiveCfg = Release|x86 - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|Any CPU.ActiveCfg = Debug|x64 - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|ARM.ActiveCfg = Debug|ARM - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|ARM.Build.0 = Debug|ARM {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|ARM64.ActiveCfg = Debug|ARM64 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|ARM64.Build.0 = Debug|ARM64 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|x64.ActiveCfg = Debug|x64 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|x64.Build.0 = Debug|x64 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|x86.ActiveCfg = Debug|Win32 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|x86.Build.0 = Debug|Win32 - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Fuzzing|Any CPU.ActiveCfg = Debug|x64 - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Fuzzing|Any CPU.Build.0 = Debug|x64 - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Fuzzing|ARM.ActiveCfg = Debug|ARM {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Fuzzing|x64.ActiveCfg = Debug|x64 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Fuzzing|x86.ActiveCfg = Debug|Win32 - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|Any CPU.ActiveCfg = Release|x64 - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|ARM.ActiveCfg = Release|ARM - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|ARM.Build.0 = Release|ARM {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|ARM64.ActiveCfg = Release|ARM64 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|ARM64.Build.0 = Release|ARM64 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x64.ActiveCfg = Release|x64 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x64.Build.0 = Release|x64 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x86.ActiveCfg = Release|Win32 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x86.Build.0 = Release|Win32 - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|Any CPU.ActiveCfg = Release|x64 - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|Any CPU.Build.0 = Release|x64 - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|ARM.ActiveCfg = Release|ARM {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|x64.ActiveCfg = Release|x64 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|x64.Build.0 = Release|x64 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|x86.ActiveCfg = Release|Win32 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|x86.Build.0 = Release|Win32 - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|Any CPU.ActiveCfg = Debug|x64 - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|ARM.ActiveCfg = Debug|ARM - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|ARM.Build.0 = Debug|ARM {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|ARM64.ActiveCfg = Debug|ARM64 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|ARM64.Build.0 = Debug|ARM64 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|x64.ActiveCfg = Debug|x64 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|x64.Build.0 = Debug|x64 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|x86.ActiveCfg = Debug|Win32 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|x86.Build.0 = Debug|Win32 - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Fuzzing|Any CPU.ActiveCfg = Debug|x64 - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Fuzzing|Any CPU.Build.0 = Debug|x64 - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Fuzzing|ARM.ActiveCfg = Debug|ARM {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Fuzzing|x64.ActiveCfg = Debug|x64 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Fuzzing|x86.ActiveCfg = Debug|Win32 - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|Any CPU.ActiveCfg = Release|x64 - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|ARM.ActiveCfg = Release|ARM - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|ARM.Build.0 = Release|ARM {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|ARM64.ActiveCfg = Release|ARM64 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|ARM64.Build.0 = Release|ARM64 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|x64.ActiveCfg = Release|x64 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|x64.Build.0 = Release|x64 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|x86.ActiveCfg = Release|Win32 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|x86.Build.0 = Release|Win32 - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|Any CPU.ActiveCfg = Release|x64 - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|Any CPU.Build.0 = Release|x64 - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|ARM.ActiveCfg = Release|ARM {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|x64.ActiveCfg = Release|x64 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|x64.Build.0 = Release|x64 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|x86.ActiveCfg = Release|Win32 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|x86.Build.0 = Release|Win32 - {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Debug|Any CPU.ActiveCfg = Debug|x64 - {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Debug|ARM.ActiveCfg = Debug|ARM - {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Debug|ARM.Build.0 = Debug|ARM {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Debug|ARM64.ActiveCfg = Debug|ARM64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Debug|ARM64.Build.0 = Debug|ARM64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Debug|x64.ActiveCfg = Debug|x64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Debug|x64.Build.0 = Debug|x64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Debug|x86.ActiveCfg = Debug|Win32 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Debug|x86.Build.0 = Debug|Win32 - {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Fuzzing|Any CPU.ActiveCfg = Debug|x64 - {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Fuzzing|ARM.ActiveCfg = Debug|ARM {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Fuzzing|x64.ActiveCfg = Debug|x64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Fuzzing|x86.ActiveCfg = Debug|Win32 - {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Release|Any CPU.ActiveCfg = Release|x64 - {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Release|ARM.ActiveCfg = Release|ARM - {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Release|ARM.Build.0 = Release|ARM {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Release|ARM64.ActiveCfg = Release|ARM64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Release|ARM64.Build.0 = Release|ARM64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Release|x64.ActiveCfg = Release|x64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Release|x64.Build.0 = Release|x64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Release|x86.ActiveCfg = Release|Win32 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.Release|x86.Build.0 = Release|Win32 - {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|Any CPU.ActiveCfg = Release|x64 - {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|Any CPU.Build.0 = Release|x64 - {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|ARM.ActiveCfg = Release|ARM - {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|ARM.Build.0 = Release|ARM {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|ARM64.Build.0 = Release|ARM64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|x64.ActiveCfg = Release|x64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|x64.Build.0 = Release|x64 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|x86.ActiveCfg = Release|Win32 {BB14D603-F44E-4415-8770-BF3E13F4C17F}.TestRelease|x86.Build.0 = Release|Win32 - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|Any CPU.ActiveCfg = Debug|x64 - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|ARM.ActiveCfg = Debug|ARM - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|ARM.Build.0 = Debug|ARM {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|ARM64.ActiveCfg = Debug|ARM64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|ARM64.Build.0 = Debug|ARM64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|x64.ActiveCfg = Debug|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|x64.Build.0 = Debug|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|x86.ActiveCfg = Debug|Win32 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|x86.Build.0 = Debug|Win32 - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64 - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Fuzzing|Any CPU.Build.0 = Fuzzing|x64 - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Fuzzing|ARM.ActiveCfg = Fuzzing|x64 - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Fuzzing|ARM.Build.0 = Fuzzing|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Fuzzing|ARM64.ActiveCfg = Fuzzing|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Fuzzing|ARM64.Build.0 = Fuzzing|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Fuzzing|x64.Build.0 = Fuzzing|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Fuzzing|x86.ActiveCfg = Fuzzing|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Fuzzing|x86.Build.0 = Fuzzing|x64 - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|Any CPU.ActiveCfg = Release|x64 - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|Any CPU.Build.0 = Release|x64 - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|ARM.ActiveCfg = Release|ARM - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|ARM.Build.0 = Release|ARM {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|ARM64.ActiveCfg = Release|ARM64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|ARM64.Build.0 = Release|ARM64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|x64.ActiveCfg = Release|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|x64.Build.0 = Release|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|x86.ActiveCfg = Release|Win32 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|x86.Build.0 = Release|Win32 - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.TestRelease|Any CPU.ActiveCfg = Release|x64 - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.TestRelease|Any CPU.Build.0 = Release|x64 - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.TestRelease|ARM.ActiveCfg = Release|ARM - {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.TestRelease|ARM.Build.0 = Release|ARM {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.TestRelease|ARM64.Build.0 = Release|ARM64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.TestRelease|x64.ActiveCfg = Release|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.TestRelease|x64.Build.0 = Release|x64 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.TestRelease|x86.ActiveCfg = Release|Win32 {F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.TestRelease|x86.Build.0 = Release|Win32 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|Any CPU.ActiveCfg = Debug|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM.ActiveCfg = Debug|ARM - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM.Build.0 = Debug|ARM {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM64.ActiveCfg = Debug|ARM64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM64.Build.0 = Debug|ARM64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x64.ActiveCfg = Debug|x64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x64.Build.0 = Debug|x64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x86.ActiveCfg = Debug|Win32 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x86.Build.0 = Debug|Win32 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|Any CPU.ActiveCfg = Debug|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|Any CPU.Build.0 = Debug|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM.ActiveCfg = Debug|ARM - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM.Build.0 = Debug|ARM {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM64.Build.0 = Debug|ARM64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x64.ActiveCfg = Debug|x64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x64.Build.0 = Debug|x64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x86.ActiveCfg = Debug|Win32 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x86.Build.0 = Debug|Win32 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|Any CPU.ActiveCfg = Release|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|Any CPU.Build.0 = Release|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM.ActiveCfg = Release|ARM - {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM.Build.0 = Release|ARM {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM64.ActiveCfg = Release|ARM64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM64.Build.0 = Release|ARM64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x64.ActiveCfg = Release|x64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x64.Build.0 = Release|x64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x86.ActiveCfg = Release|Win32 {CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x86.Build.0 = Release|Win32 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|Any CPU.ActiveCfg = Release|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|Any CPU.Build.0 = Release|x64 - {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM.ActiveCfg = Release|ARM - {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM.Build.0 = Release|ARM {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM64.ActiveCfg = Release|ARM64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|ARM64.Build.0 = Release|ARM64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x64.ActiveCfg = Release|x64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x64.Build.0 = Release|x64 {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x86.ActiveCfg = Release|Win32 {CA460806-5E41-4E97-9A3D-1D74B433B663}.TestRelease|x86.Build.0 = Release|Win32 - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|Any CPU.ActiveCfg = Debug|x64 - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM.ActiveCfg = Debug|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM.Build.0 = Debug|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM64.ActiveCfg = Debug|arm64 {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM64.Build.0 = Debug|arm64 {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x64.ActiveCfg = Debug|x64 {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x64.Build.0 = Debug|x64 {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x86.ActiveCfg = Debug|x86 {E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x86.Build.0 = Debug|x86 - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|Any CPU.ActiveCfg = Debug|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|Any CPU.Build.0 = Debug|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|ARM.ActiveCfg = Debug|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|ARM.Build.0 = Debug|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|ARM64.ActiveCfg = Debug|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|ARM64.Build.0 = Debug|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|x64.ActiveCfg = Debug|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|x64.Build.0 = Debug|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|x86.ActiveCfg = Debug|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|x86.Build.0 = Debug|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|Any CPU.Build.0 = Release|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|ARM.ActiveCfg = Release|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|ARM.Build.0 = Release|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|ARM64.ActiveCfg = Release|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|ARM64.Build.0 = Release|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|x64.ActiveCfg = Release|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|x64.Build.0 = Release|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|x86.ActiveCfg = Release|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|x86.Build.0 = Release|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|Any CPU.ActiveCfg = Release|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|Any CPU.Build.0 = Release|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|ARM.ActiveCfg = Release|Any CPU - {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|ARM.Build.0 = Release|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|ARM64.ActiveCfg = Release|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|ARM64.Build.0 = Release|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|x64.ActiveCfg = Release|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|x64.Build.0 = Release|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|x86.ActiveCfg = Release|Any CPU {E8454BF1-2068-4513-A525-ABF55CC8742C}.TestRelease|x86.Build.0 = Release|Any CPU - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|Any CPU.ActiveCfg = Debug|x64 - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|ARM.ActiveCfg = Debug|x64 - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|ARM.Build.0 = Debug|x64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|ARM64.ActiveCfg = Debug|arm64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|ARM64.Build.0 = Debug|arm64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|x64.ActiveCfg = Debug|x64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|x64.Build.0 = Debug|x64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|x86.ActiveCfg = Debug|x86 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|x86.Build.0 = Debug|x86 - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|Any CPU.ActiveCfg = Debug|x64 - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|Any CPU.Build.0 = Debug|x64 - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|ARM.ActiveCfg = Debug|x64 - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|ARM.Build.0 = Debug|x64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|ARM64.ActiveCfg = Debug|arm64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|ARM64.Build.0 = Debug|arm64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|x64.ActiveCfg = Debug|x64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|x64.Build.0 = Debug|x64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|x86.ActiveCfg = Debug|x86 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|x86.Build.0 = Debug|x86 - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|Any CPU.ActiveCfg = Release|x64 - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|Any CPU.Build.0 = Release|x64 - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|ARM.ActiveCfg = Release|x64 - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|ARM.Build.0 = Release|x64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|ARM64.ActiveCfg = Release|arm64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|ARM64.Build.0 = Release|arm64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|x64.ActiveCfg = Release|x64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|x64.Build.0 = Release|x64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|x86.ActiveCfg = Release|x86 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|x86.Build.0 = Release|x86 - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|Any CPU.ActiveCfg = Release|x64 - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|Any CPU.Build.0 = Release|x64 - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|ARM.ActiveCfg = Release|x64 - {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|ARM.Build.0 = Release|x64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|ARM64.ActiveCfg = Release|arm64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|ARM64.Build.0 = Release|arm64 {EE43C990-7789-4A60-B077-BF0ED3D093A1}.TestRelease|x64.ActiveCfg = Release|x64 diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj index bcf9f79ce1..80df710d4b 100644 --- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj +++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj @@ -88,7 +88,7 @@ $(PlatformTarget)\$(Configuration)\ $(RootNamespace) true - false + true ..\CodeAnalysis.ruleset