From 6274dc8a198da2685fc209a28b212cf04fc7c6a4 Mon Sep 17 00:00:00 2001 From: Letao Wang Date: Wed, 24 Sep 2025 15:07:51 -0700 Subject: [PATCH 1/5] idl and generated files --- .../TerminalVelocityFeatures-PackageManager.h | 12 +++- ...erminalVelocityFeatures-PackageManager.xml | 11 ++++ .../API/M.W.M.D.AddPackageOptions.cpp | 17 ++++++ .../API/M.W.M.D.AddPackageOptions.h | 5 +- .../API/M.W.M.D.AppxPackagingObject.cpp | 8 +++ .../API/M.W.M.D.AppxPackagingObject.h | 11 ++++ ...M.W.M.D.PackageCertificateEkuValidator.cpp | 24 ++++++++ .../M.W.M.D.PackageCertificateEkuValidator.h | 19 +++++++ .../M.W.M.D.PackageFamilyNameValidator.cpp | 24 ++++++++ .../API/M.W.M.D.PackageFamilyNameValidator.h | 19 +++++++ ...M.W.M.D.PackageMinimumVersionValidator.cpp | 24 ++++++++ .../M.W.M.D.PackageMinimumVersionValidator.h | 19 +++++++ .../API/M.W.M.D.StagePackageOptions.cpp | 18 ++++++ .../API/M.W.M.D.StagePackageOptions.h | 5 +- dev/PackageManager/API/PackageManager.idl | 56 ++++++++++++++++++- .../API/PackageManager.vcxitems | 10 +++- .../API/PackageManager.vcxitems.filters | 26 ++++++++- 17 files changed, 301 insertions(+), 7 deletions(-) create mode 100644 dev/PackageManager/API/M.W.M.D.AppxPackagingObject.cpp create mode 100644 dev/PackageManager/API/M.W.M.D.AppxPackagingObject.h create mode 100644 dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp create mode 100644 dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h create mode 100644 dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.cpp create mode 100644 dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.h create mode 100644 dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.cpp create mode 100644 dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.h diff --git a/dev/Common/TerminalVelocityFeatures-PackageManager.h b/dev/Common/TerminalVelocityFeatures-PackageManager.h index 99edf97bbd..edc43420d2 100644 --- a/dev/Common/TerminalVelocityFeatures-PackageManager.h +++ b/dev/Common/TerminalVelocityFeatures-PackageManager.h @@ -4,17 +4,19 @@ // THIS FILE IS AUTOMATICALLY GENERATED; DO NOT EDIT IT // INPUT FILE: dev\common\TerminalVelocityFeatures-PackageManager.xml -// OPTIONS: -Channel Experimental -Language C++ -Namespace Microsoft.Windows.Management.Deployment -Path dev\common\TerminalVelocityFeatures-PackageManager.xml -Output dev\common\TerminalVelocityFeatures-PackageManager.h +// OPTIONS: -Channel Experimental -Language C++ -Namespace Microsoft::Windows::Management::Deployment -Path dev\common\TerminalVelocityFeatures-PackageManager.xml -Output dev\common #if defined(__midlrt) namespace features { feature_name Feature_PackageManager = { DisabledByDefault, FALSE }; + feature_name Feature_PackageValidator = { DisabledByDefault, FALSE }; } #endif // defined(__midlrt) // Feature constants #define WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_MANAGEMENT_DEPLOYMENT_FEATURE_PACKAGEMANAGER_ENABLED 1 +#define WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_MANAGEMENT_DEPLOYMENT_FEATURE_PACKAGEVALIDATOR_ENABLED 1 #if defined(__cplusplus) @@ -27,6 +29,12 @@ struct Feature_PackageManager static constexpr bool IsEnabled() { return WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_MANAGEMENT_DEPLOYMENT_FEATURE_PACKAGEMANAGER_ENABLED == 1; } }; -} // namespace Microsoft.Windows.Management.Deployment +__pragma(detect_mismatch("ODR_violation_WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_MANAGEMENT_DEPLOYMENT_FEATURE_PACKAGEVALIDATOR_ENABLED_mismatch", "AlwaysEnabled")) +struct Feature_PackageValidator +{ + static constexpr bool IsEnabled() { return WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_MANAGEMENT_DEPLOYMENT_FEATURE_PACKAGEVALIDATOR_ENABLED == 1; } +}; + +} // namespace Microsoft::Windows::Management::Deployment #endif // defined(__cplusplus) diff --git a/dev/Common/TerminalVelocityFeatures-PackageManager.xml b/dev/Common/TerminalVelocityFeatures-PackageManager.xml index 932aa39394..cd235b8d2e 100644 --- a/dev/Common/TerminalVelocityFeatures-PackageManager.xml +++ b/dev/Common/TerminalVelocityFeatures-PackageManager.xml @@ -17,4 +17,15 @@ Stable + + + Feature_PackageValidator + PackageValidator support in PackageDeploymentManager + AlwaysEnabled + + Preview + Stable + + + diff --git a/dev/PackageManager/API/M.W.M.D.AddPackageOptions.cpp b/dev/PackageManager/API/M.W.M.D.AddPackageOptions.cpp index fb95f820a7..8bca06d78a 100644 --- a/dev/PackageManager/API/M.W.M.D.AddPackageOptions.cpp +++ b/dev/PackageManager/API/M.W.M.D.AddPackageOptions.cpp @@ -4,6 +4,7 @@ #include "pch.h" #include +#include #include "M.W.M.D.AddPackageOptions.h" #include "Microsoft.Windows.Management.Deployment.AddPackageOptions.g.cpp" @@ -172,4 +173,20 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation { m_limitToExistingPackages = value; } + + bool AddPackageOptions::IsPackageValidatorsSupported() + { + // TODO - check presence of AppxPackaging streaming reader feature + return true; + } + winrt::Windows::Foundation::Collections::IMap > AddPackageOptions::PackageValidators() + { + THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); + + if (!m_packageValidators) + { + m_packageValidators = winrt::single_threaded_map >(); + } + return m_packageValidators; + } } diff --git a/dev/PackageManager/API/M.W.M.D.AddPackageOptions.h b/dev/PackageManager/API/M.W.M.D.AddPackageOptions.h index 7ad3423f6b..8bac3fe7bf 100644 --- a/dev/PackageManager/API/M.W.M.D.AddPackageOptions.h +++ b/dev/PackageManager/API/M.W.M.D.AddPackageOptions.h @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation and Contributors. +// Copyright (c) Microsoft Corporation and Contributors. // Licensed under the MIT License. #pragma once @@ -46,6 +46,8 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation bool IsLimitToExistingPackagesSupported(); bool LimitToExistingPackages(); void LimitToExistingPackages(bool value); + bool IsPackageValidatorsSupported(); + winrt::Windows::Foundation::Collections::IMap > PackageValidators(); private: winrt::Microsoft::Windows::Management::Deployment::PackageVolume m_targetVolume{ nullptr }; @@ -67,6 +69,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation bool m_deferRegistrationWhenPackagesAreInUse{}; winrt::Windows::Foundation::Collections::IMap m_expectedDigests; bool m_limitToExistingPackages{}; + winrt::Windows::Foundation::Collections::IMap > m_packageValidators; }; } namespace winrt::Microsoft::Windows::Management::Deployment::factory_implementation diff --git a/dev/PackageManager/API/M.W.M.D.AppxPackagingObject.cpp b/dev/PackageManager/API/M.W.M.D.AppxPackagingObject.cpp new file mode 100644 index 0000000000..9b4733c8d7 --- /dev/null +++ b/dev/PackageManager/API/M.W.M.D.AppxPackagingObject.cpp @@ -0,0 +1,8 @@ +#include "pch.h" +#include "M.W.M.D.AppxPackagingObject.h" +#include "Microsoft.Windows.Management.Deployment.AppxPackagingObject.g.cpp" +#include + +namespace winrt::Microsoft::Windows::Management::Deployment::implementation +{ +} diff --git a/dev/PackageManager/API/M.W.M.D.AppxPackagingObject.h b/dev/PackageManager/API/M.W.M.D.AppxPackagingObject.h new file mode 100644 index 0000000000..67c29fa8c3 --- /dev/null +++ b/dev/PackageManager/API/M.W.M.D.AppxPackagingObject.h @@ -0,0 +1,11 @@ +#pragma once +#include "Microsoft.Windows.Management.Deployment.AppxPackagingObject.g.h" + +namespace winrt::Microsoft::Windows::Management::Deployment::implementation +{ + struct AppxPackagingObject : AppxPackagingObjectT + { + AppxPackagingObject() = default; + + }; +} diff --git a/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp new file mode 100644 index 0000000000..4e6e033b8e --- /dev/null +++ b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp @@ -0,0 +1,24 @@ +#include "pch.h" +#include "M.W.M.D.PackageCertificateEkuValidator.h" +#include "Microsoft.Windows.Management.Deployment.PackageCertificateEkuValidator.g.cpp" +#include + +namespace winrt::Microsoft::Windows::Management::Deployment::implementation +{ + PackageCertificateEkuValidator::PackageCertificateEkuValidator(hstring const& expectedCertificateEku) + { + THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); + + UNREFERENCED_PARAMETER(expectedCertificateEku); + + throw hresult_not_implemented(); + } + bool PackageCertificateEkuValidator::IsPackageValid(winrt::Microsoft::Windows::Management::Deployment::AppxPackagingObject const& packagingObject) + { + THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); + + UNREFERENCED_PARAMETER(packagingObject); + + throw hresult_not_implemented(); + } +} diff --git a/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h new file mode 100644 index 0000000000..357b1cd453 --- /dev/null +++ b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h @@ -0,0 +1,19 @@ +#pragma once +#include "Microsoft.Windows.Management.Deployment.PackageCertificateEkuValidator.g.h" + +namespace winrt::Microsoft::Windows::Management::Deployment::implementation +{ + struct PackageCertificateEkuValidator : PackageCertificateEkuValidatorT + { + PackageCertificateEkuValidator() = default; + + PackageCertificateEkuValidator(hstring const& expectedCertificateEku); + bool IsPackageValid(winrt::Microsoft::Windows::Management::Deployment::AppxPackagingObject const& packagingObject); + }; +} +namespace winrt::Microsoft::Windows::Management::Deployment::factory_implementation +{ + struct PackageCertificateEkuValidator : PackageCertificateEkuValidatorT + { + }; +} diff --git a/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.cpp b/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.cpp new file mode 100644 index 0000000000..81784ed8b6 --- /dev/null +++ b/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.cpp @@ -0,0 +1,24 @@ +#include "pch.h" +#include "M.W.M.D.PackageFamilyNameValidator.h" +#include "Microsoft.Windows.Management.Deployment.PackageFamilyNameValidator.g.cpp" +#include + +namespace winrt::Microsoft::Windows::Management::Deployment::implementation +{ + PackageFamilyNameValidator::PackageFamilyNameValidator(hstring const& expectedPackageFamilyName) + { + THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); + + UNREFERENCED_PARAMETER(expectedPackageFamilyName); + + throw hresult_not_implemented(); + } + bool PackageFamilyNameValidator::IsPackageValid(winrt::Microsoft::Windows::Management::Deployment::AppxPackagingObject const& packagingObject) + { + THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); + + UNREFERENCED_PARAMETER(packagingObject); + + throw hresult_not_implemented(); + } +} diff --git a/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.h b/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.h new file mode 100644 index 0000000000..a85fd18633 --- /dev/null +++ b/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.h @@ -0,0 +1,19 @@ +#pragma once +#include "Microsoft.Windows.Management.Deployment.PackageFamilyNameValidator.g.h" + +namespace winrt::Microsoft::Windows::Management::Deployment::implementation +{ + struct PackageFamilyNameValidator : PackageFamilyNameValidatorT + { + PackageFamilyNameValidator() = default; + + PackageFamilyNameValidator(hstring const& expectedPackageFamilyName); + bool IsPackageValid(winrt::Microsoft::Windows::Management::Deployment::AppxPackagingObject const& packagingObject); + }; +} +namespace winrt::Microsoft::Windows::Management::Deployment::factory_implementation +{ + struct PackageFamilyNameValidator : PackageFamilyNameValidatorT + { + }; +} diff --git a/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.cpp b/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.cpp new file mode 100644 index 0000000000..11c969f609 --- /dev/null +++ b/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.cpp @@ -0,0 +1,24 @@ +#include "pch.h" +#include "M.W.M.D.PackageMinimumVersionValidator.h" +#include "Microsoft.Windows.Management.Deployment.PackageMinimumVersionValidator.g.cpp" +#include + +namespace winrt::Microsoft::Windows::Management::Deployment::implementation +{ + PackageMinimumVersionValidator::PackageMinimumVersionValidator(winrt::Windows::ApplicationModel::PackageVersion const& minimumVersion) + { + THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); + + UNREFERENCED_PARAMETER(minimumVersion); + + throw hresult_not_implemented(); + } + bool PackageMinimumVersionValidator::IsPackageValid(winrt::Microsoft::Windows::Management::Deployment::AppxPackagingObject const& packagingObject) + { + THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); + + UNREFERENCED_PARAMETER(packagingObject); + + throw hresult_not_implemented(); + } +} diff --git a/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.h b/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.h new file mode 100644 index 0000000000..cec9879ea6 --- /dev/null +++ b/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.h @@ -0,0 +1,19 @@ +#pragma once +#include "Microsoft.Windows.Management.Deployment.PackageMinimumVersionValidator.g.h" + +namespace winrt::Microsoft::Windows::Management::Deployment::implementation +{ + struct PackageMinimumVersionValidator : PackageMinimumVersionValidatorT + { + PackageMinimumVersionValidator() = default; + + PackageMinimumVersionValidator(winrt::Windows::ApplicationModel::PackageVersion const& minimumVersion); + bool IsPackageValid(winrt::Microsoft::Windows::Management::Deployment::AppxPackagingObject const& packagingObject); + }; +} +namespace winrt::Microsoft::Windows::Management::Deployment::factory_implementation +{ + struct PackageMinimumVersionValidator : PackageMinimumVersionValidatorT + { + }; +} diff --git a/dev/PackageManager/API/M.W.M.D.StagePackageOptions.cpp b/dev/PackageManager/API/M.W.M.D.StagePackageOptions.cpp index dfd7810dff..da04d830ee 100644 --- a/dev/PackageManager/API/M.W.M.D.StagePackageOptions.cpp +++ b/dev/PackageManager/API/M.W.M.D.StagePackageOptions.cpp @@ -4,6 +4,7 @@ #include "pch.h" #include +#include #include "M.W.M.D.StagePackageOptions.h" #include "Microsoft.Windows.Management.Deployment.StagePackageOptions.g.cpp" @@ -127,4 +128,21 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation } return m_expectedDigests; } + + bool StagePackageOptions::IsPackageValidatorsSupported() + { + // TODO - check presence of AppxPackaging streaming reader feature + return true; + } + winrt::Windows::Foundation::Collections::IMap > StagePackageOptions::PackageValidators() + { + THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); + + if (!m_packageValidators) + { + m_packageValidators = winrt::single_threaded_map >(); + } + return m_packageValidators; + } + } diff --git a/dev/PackageManager/API/M.W.M.D.StagePackageOptions.h b/dev/PackageManager/API/M.W.M.D.StagePackageOptions.h index 386be0cf3a..76ce2577d8 100644 --- a/dev/PackageManager/API/M.W.M.D.StagePackageOptions.h +++ b/dev/PackageManager/API/M.W.M.D.StagePackageOptions.h @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation and Contributors. +// Copyright (c) Microsoft Corporation and Contributors. // Licensed under the MIT License. #pragma once @@ -35,6 +35,8 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation void AllowUnsigned(bool value); bool IsExpectedDigestsSupported(); winrt::Windows::Foundation::Collections::IMap ExpectedDigests(); + bool IsPackageValidatorsSupported(); + winrt::Windows::Foundation::Collections::IMap > PackageValidators(); private: winrt::Microsoft::Windows::Management::Deployment::PackageVolume m_targetVolume{ nullptr }; @@ -51,6 +53,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation bool m_stageInPlace{}; bool m_allowUnsigned{}; winrt::Windows::Foundation::Collections::IMap m_expectedDigests; + winrt::Windows::Foundation::Collections::IMap > m_packageValidators; }; } namespace winrt::Microsoft::Windows::Management::Deployment::factory_implementation diff --git a/dev/PackageManager/API/PackageManager.idl b/dev/PackageManager/API/PackageManager.idl index 1a2a0e27b2..d764e81583 100644 --- a/dev/PackageManager/API/PackageManager.idl +++ b/dev/PackageManager/API/PackageManager.idl @@ -7,7 +7,7 @@ import "M.AM.DynamicDependency.idl"; namespace Microsoft.Windows.Management.Deployment { - [contractversion(2)] + [contractversion(3)] apicontract PackageDeploymentContract{}; /// Features can be queried if currently available/enabled. @@ -171,6 +171,44 @@ namespace Microsoft.Windows.Management.Deployment IVector Items { get; }; } + [feature(Feature_PackageValidator)] + [contract(PackageDeploymentContract, 3)] + [default_interface] + runtimeclass AppxPackagingObject + { + // This is an interop class for COM types defined in AppxPackaging.idl. + // The WinRT side has no methods or properties, but the object supports QueryInterface into the COM interfaces + // IAppxPackageReader or IAppxBundleReader, whichever is relevant for the object being read. + } + + [feature(Feature_PackageValidator)] + [contract(PackageDeploymentContract, 3)] + interface IPackageValidator + { + Boolean IsPackageValid(AppxPackagingObject packagingObject); + } + + [feature(Feature_PackageValidator)] + [contract(PackageDeploymentContract, 3)] + runtimeclass PackageFamilyNameValidator : [default] IPackageValidator + { + PackageFamilyNameValidator(String expectedPackageFamilyName); + } + + [feature(Feature_PackageValidator)] + [contract(PackageDeploymentContract, 3)] + runtimeclass PackageMinimumVersionValidator : [default] IPackageValidator + { + PackageMinimumVersionValidator(Windows.ApplicationModel.PackageVersion minimumVersion); + } + + [feature(Feature_PackageValidator)] + [contract(PackageDeploymentContract, 3)] + runtimeclass PackageCertificateEkuValidator : [default] IPackageValidator + { + PackageCertificateEkuValidator(String expectedCertificateEku); + } + // Requires Windows >= 10.0.19041.0 (aka 2004 aka 20H1) [contract(PackageDeploymentContract, 1)] runtimeclass AddPackageOptions @@ -200,6 +238,14 @@ namespace Microsoft.Windows.Management.Deployment Boolean IsLimitToExistingPackagesSupported { get; }; // Requires Windows >= 10.0.22621.0 (aka Win11 22H2) Boolean LimitToExistingPackages; + + [feature(Feature_PackageValidator)] + [contract(PackageDeploymentContract, 3)] + Boolean IsPackageValidatorsSupported{ get; }; + + [feature(Feature_PackageValidator)] + [contract(PackageDeploymentContract, 3)] + IMap > PackageValidators{ get; }; } // Requires Windows >= 10.0.19041.0 (aka 2004 aka 20H1) @@ -224,6 +270,14 @@ namespace Microsoft.Windows.Management.Deployment Boolean IsExpectedDigestsSupported { get; }; // Requires Windows >= 10.0.22621.0 (aka Win11 22H2) IMap ExpectedDigests{ get; }; + + [feature(Feature_PackageValidator)] + [contract(PackageDeploymentContract, 3)] + Boolean IsPackageValidatorsSupported{ get; }; + + [feature(Feature_PackageValidator)] + [contract(PackageDeploymentContract, 3)] + IMap > PackageValidators{ get; }; } // Requires Windows >= 10.0.19041.0 (aka 2004 aka 20H1) diff --git a/dev/PackageManager/API/PackageManager.vcxitems b/dev/PackageManager/API/PackageManager.vcxitems index 7b67a3efa0..9b34fd3f42 100644 --- a/dev/PackageManager/API/PackageManager.vcxitems +++ b/dev/PackageManager/API/PackageManager.vcxitems @@ -15,9 +15,13 @@ + + + + @@ -32,9 +36,13 @@ + + + + @@ -56,4 +64,4 @@ - + \ No newline at end of file diff --git a/dev/PackageManager/API/PackageManager.vcxitems.filters b/dev/PackageManager/API/PackageManager.vcxitems.filters index e41fd8b76e..c47090b2de 100644 --- a/dev/PackageManager/API/PackageManager.vcxitems.filters +++ b/dev/PackageManager/API/PackageManager.vcxitems.filters @@ -56,6 +56,18 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + @@ -106,8 +118,20 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + - + \ No newline at end of file From 5fdb4111cbfe995c625bfbabd2c4dc79858c2570 Mon Sep 17 00:00:00 2001 From: Letao Wang Date: Wed, 24 Sep 2025 19:17:40 -0700 Subject: [PATCH 2/5] don't need packaging object --- .../API/M.W.M.D.AppxPackagingObject.cpp | 8 -- .../API/M.W.M.D.AppxPackagingObject.h | 11 --- ...M.W.M.D.PackageCertificateEkuValidator.cpp | 4 +- .../M.W.M.D.PackageCertificateEkuValidator.h | 2 +- .../API/M.W.M.D.PackageDeploymentManager.cpp | 79 +++++++++---------- .../API/M.W.M.D.PackageDeploymentManager.h | 23 ++---- .../M.W.M.D.PackageFamilyNameValidator.cpp | 4 +- .../API/M.W.M.D.PackageFamilyNameValidator.h | 2 +- ...M.W.M.D.PackageMinimumVersionValidator.cpp | 4 +- .../M.W.M.D.PackageMinimumVersionValidator.h | 2 +- dev/PackageManager/API/PackageManager.idl | 12 +-- .../API/PackageManager.vcxitems | 2 - .../API/PackageManager.vcxitems.filters | 6 -- 13 files changed, 52 insertions(+), 107 deletions(-) delete mode 100644 dev/PackageManager/API/M.W.M.D.AppxPackagingObject.cpp delete mode 100644 dev/PackageManager/API/M.W.M.D.AppxPackagingObject.h diff --git a/dev/PackageManager/API/M.W.M.D.AppxPackagingObject.cpp b/dev/PackageManager/API/M.W.M.D.AppxPackagingObject.cpp deleted file mode 100644 index 9b4733c8d7..0000000000 --- a/dev/PackageManager/API/M.W.M.D.AppxPackagingObject.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "pch.h" -#include "M.W.M.D.AppxPackagingObject.h" -#include "Microsoft.Windows.Management.Deployment.AppxPackagingObject.g.cpp" -#include - -namespace winrt::Microsoft::Windows::Management::Deployment::implementation -{ -} diff --git a/dev/PackageManager/API/M.W.M.D.AppxPackagingObject.h b/dev/PackageManager/API/M.W.M.D.AppxPackagingObject.h deleted file mode 100644 index 67c29fa8c3..0000000000 --- a/dev/PackageManager/API/M.W.M.D.AppxPackagingObject.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include "Microsoft.Windows.Management.Deployment.AppxPackagingObject.g.h" - -namespace winrt::Microsoft::Windows::Management::Deployment::implementation -{ - struct AppxPackagingObject : AppxPackagingObjectT - { - AppxPackagingObject() = default; - - }; -} diff --git a/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp index 4e6e033b8e..f937d3c225 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp +++ b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp @@ -13,11 +13,11 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation throw hresult_not_implemented(); } - bool PackageCertificateEkuValidator::IsPackageValid(winrt::Microsoft::Windows::Management::Deployment::AppxPackagingObject const& packagingObject) + bool PackageCertificateEkuValidator::IsPackageValid(winrt::Windows::Foundation::IInspectable const& appxPackagingObject) { THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); - UNREFERENCED_PARAMETER(packagingObject); + UNREFERENCED_PARAMETER(appxPackagingObject); throw hresult_not_implemented(); } diff --git a/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h index 357b1cd453..e373839d08 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h +++ b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h @@ -8,7 +8,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation PackageCertificateEkuValidator() = default; PackageCertificateEkuValidator(hstring const& expectedCertificateEku); - bool IsPackageValid(winrt::Microsoft::Windows::Management::Deployment::AppxPackagingObject const& packagingObject); + bool IsPackageValid(winrt::Windows::Foundation::IInspectable const& appxPackagingObject); }; } namespace winrt::Microsoft::Windows::Management::Deployment::factory_implementation diff --git a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp index 8f233ba6cd..acd07d7a93 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp +++ b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp @@ -33,6 +33,7 @@ namespace ABI::Windows::Management::Deployment #include #include +#include static_assert(static_cast(winrt::Microsoft::Windows::Management::Deployment::StubPackageOption::Default) == static_cast(winrt::Windows::Management::Deployment::StubPackageOption::Default), "winrt::Microsoft::Windows::Management::Deployment::StubPackageOption::Default != winrt::Windows::Management::Deployment::StubPackageOption::Default"); @@ -554,7 +555,6 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation PackageDeploymentProgressStatus::Queued, 0} }; progress(packageDeploymentProgress); - winrt::Windows::Management::Deployment::AddPackageOptions addOptions{ ToOptions(options) }; const double progressMaxPerPackage{ 1.0 }; HRESULT error{}; HRESULT extendedError{}; @@ -562,7 +562,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::guid activityId{}; try { - error = LOG_IF_FAILED_MSG(AddPackage(packageUri, addOptions, packageDeploymentProgress, progress, progressMaxPerPackage, extendedError, errorText, activityId), + error = LOG_IF_FAILED_MSG(AddPackage(packageUri, options, packageDeploymentProgress, progress, progressMaxPerPackage, extendedError, errorText, activityId), "ExtendedError:0x%08X PackageUri:%ls", extendedError, packageUri.ToString().c_str()); } @@ -677,7 +677,6 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation PackageDeploymentProgressStatus::Queued, 0} }; progress(packageDeploymentProgress); - winrt::Windows::Management::Deployment::StagePackageOptions stageOptions{ ToOptions(options) }; const double progressMaxPerPackage{ 1.0 }; HRESULT error{}; HRESULT extendedError{}; @@ -685,7 +684,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::guid activityId{}; try { - error = LOG_IF_FAILED_MSG(StagePackage(packageUri, stageOptions, packageDeploymentProgress, progress, progressMaxPerPackage, extendedError, errorText, activityId), + error = LOG_IF_FAILED_MSG(StagePackage(packageUri, options, packageDeploymentProgress, progress, progressMaxPerPackage, extendedError, errorText, activityId), "ExtendedError:0x%08X PackageUri:%ls", extendedError, packageUri.ToString().c_str()); } @@ -1958,6 +1957,12 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation return S_OK; } + if (::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()) + { + auto expectedDigests{ options.AddPackageOptions().ExpectedDigests() }; + ValidatePackagesAndUpdateExpectedDigests(options.AddPackageOptions().PackageValidators(), expectedDigests); + } + const auto progressBefore{ packageDeploymentProgress.Progress }; winrt::Windows::Management::Deployment::AddPackageOptions addOptions{ ToOptions(options) }; auto deploymentOperation{ m_packageManager.AddPackageByUriAsync(packageUri, addOptions) }; @@ -2016,25 +2021,6 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::Microsoft::Windows::Management::Deployment::AddPackageOptions const& options, winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, wistd::function progress, - const double progressMaxPerPackageSetItem, - HRESULT& extendedError, - winrt::hstring& errorText, - winrt::guid& activityId) - { - extendedError = S_OK; - errorText.clear(); - activityId = winrt::guid{}; - - winrt::Windows::Management::Deployment::AddPackageOptions addOptions{ ToOptions(options) }; - RETURN_IF_FAILED(AddPackage(packageUri, addOptions, packageDeploymentProgress, progress, progressMaxPerPackageSetItem, extendedError, errorText, activityId)); - return S_OK; - } - - HRESULT PackageDeploymentManager::AddPackage( - winrt::Windows::Foundation::Uri const& packageUri, - winrt::Windows::Management::Deployment::AddPackageOptions const& addOptions, - winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, - wistd::function progress, const double progressMaxPerPackage, HRESULT& extendedError, winrt::hstring& errorText, @@ -2044,6 +2030,13 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation errorText.clear(); activityId = winrt::guid{}; + if (::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()) + { + auto expectedDigests{ options.ExpectedDigests() }; + ValidatePackagesAndUpdateExpectedDigests(options.PackageValidators(), expectedDigests); + } + + winrt::Windows::Management::Deployment::AddPackageOptions addOptions{ ToOptions(options) }; const auto progressBefore{ packageDeploymentProgress.Progress }; auto deploymentOperation{ m_packageManager.AddPackageByUriAsync(packageUri, addOptions) }; deploymentOperation.Progress([&](winrt::Windows::Foundation::IAsyncOperationWithProgress< @@ -2111,25 +2104,6 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions const& options, winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, wistd::function progress, - const double progressMaxPerPackageSetItem, - HRESULT& extendedError, - winrt::hstring& errorText, - winrt::guid& activityId) - { - extendedError = S_OK; - errorText.clear(); - activityId = winrt::guid{}; - - winrt::Windows::Management::Deployment::StagePackageOptions stageOptions{ ToOptions(options) }; - RETURN_IF_FAILED(StagePackage(packageUri, stageOptions, packageDeploymentProgress, progress, progressMaxPerPackageSetItem, extendedError, errorText, activityId)); - return S_OK; - } - - HRESULT PackageDeploymentManager::StagePackage( - winrt::Windows::Foundation::Uri const& packageUri, - winrt::Windows::Management::Deployment::StagePackageOptions const& stageOptions, - winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, - wistd::function progress, const double progressMaxPerPackage, HRESULT& extendedError, winrt::hstring& errorText, @@ -2139,6 +2113,13 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation errorText.clear(); activityId = winrt::guid{}; + if (::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()) + { + auto expectedDigests{ options.ExpectedDigests() }; + ValidatePackagesAndUpdateExpectedDigests(options.PackageValidators(), expectedDigests); + } + + winrt::Windows::Management::Deployment::StagePackageOptions stageOptions{ ToOptions(options) }; const auto progressBefore{ packageDeploymentProgress.Progress }; auto deploymentOperation{ m_packageManager.StagePackageByUriAsync(packageUri, stageOptions) }; deploymentOperation.Progress([&](winrt::Windows::Foundation::IAsyncOperationWithProgress< @@ -3693,4 +3674,18 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation const auto schemeName{ packageUri.SchemeName() }; return CompareStringOrdinal(schemeName.c_str(), -1, L"ms-uup", -1, TRUE) == CSTR_EQUAL; } + + void PackageDeploymentManager::ValidatePackagesAndUpdateExpectedDigests( + winrt::Windows::Foundation::Collections::IMap > const& packageValidators, + winrt::Windows::Foundation::Collections::IMap& expectedDigests + ) + { + THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); + + UNREFERENCED_PARAMETER(packageValidators); + UNREFERENCED_PARAMETER(expectedDigests); + + throw hresult_not_implemented(); + } + } diff --git a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.h b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.h index 870dbacc6b..b37868785c 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.h +++ b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.h @@ -106,15 +106,6 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation HRESULT& extendedError, winrt::hstring& errorText, winrt::guid& activityId); - HRESULT AddPackage( - winrt::Windows::Foundation::Uri const& packageUri, - winrt::Windows::Management::Deployment::AddPackageOptions const& addOptions, - winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, - wistd::function progress, - const double progressMaxPerPackage, - HRESULT& extendedError, - winrt::hstring& errorText, - winrt::guid& activityId); HRESULT StagePackage( winrt::Windows::Foundation::Uri const& packageUri, winrt::Microsoft::Windows::Management::Deployment::StagePackageOptions const& options, @@ -124,15 +115,6 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation HRESULT& extendedError, winrt::hstring& errorText, winrt::guid& activityId); - HRESULT StagePackage( - winrt::Windows::Foundation::Uri const& packageUri, - winrt::Windows::Management::Deployment::StagePackageOptions const& stageOptions, - winrt::Microsoft::Windows::Management::Deployment::PackageDeploymentProgress& packageDeploymentProgress, - wistd::function progress, - const double progressMaxPerPackage, - HRESULT& extendedError, - winrt::hstring& errorText, - winrt::guid& activityId); HRESULT RegisterPackage( winrt::Windows::Foundation::Uri const& packageUri, winrt::Microsoft::Windows::Management::Deployment::RegisterPackageOptions const& options, @@ -299,6 +281,11 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation winrt::Microsoft::Windows::Management::Deployment::PackageSetItem const& packageSetItem); static bool IsUriScheme_MsUup(winrt::Windows::Foundation::Uri const& packageUri); + void ValidatePackagesAndUpdateExpectedDigests( + winrt::Windows::Foundation::Collections::IMap > const& packageValidators, + winrt::Windows::Foundation::Collections::IMap& expectedDigests + ); + private: static size_t Count(winrt::Windows::Foundation::Collections::IIterable packages) { diff --git a/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.cpp b/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.cpp index 81784ed8b6..7c7baa51d0 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.cpp +++ b/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.cpp @@ -13,11 +13,11 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation throw hresult_not_implemented(); } - bool PackageFamilyNameValidator::IsPackageValid(winrt::Microsoft::Windows::Management::Deployment::AppxPackagingObject const& packagingObject) + bool PackageFamilyNameValidator::IsPackageValid(winrt::Windows::Foundation::IInspectable const& appxPackagingObject) { THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); - UNREFERENCED_PARAMETER(packagingObject); + UNREFERENCED_PARAMETER(appxPackagingObject); throw hresult_not_implemented(); } diff --git a/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.h b/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.h index a85fd18633..94e1119362 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.h +++ b/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.h @@ -8,7 +8,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation PackageFamilyNameValidator() = default; PackageFamilyNameValidator(hstring const& expectedPackageFamilyName); - bool IsPackageValid(winrt::Microsoft::Windows::Management::Deployment::AppxPackagingObject const& packagingObject); + bool IsPackageValid(winrt::Windows::Foundation::IInspectable const& appxPackagingObject); }; } namespace winrt::Microsoft::Windows::Management::Deployment::factory_implementation diff --git a/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.cpp b/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.cpp index 11c969f609..4f6009e66c 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.cpp +++ b/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.cpp @@ -13,11 +13,11 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation throw hresult_not_implemented(); } - bool PackageMinimumVersionValidator::IsPackageValid(winrt::Microsoft::Windows::Management::Deployment::AppxPackagingObject const& packagingObject) + bool PackageMinimumVersionValidator::IsPackageValid(winrt::Windows::Foundation::IInspectable const& appxPackagingObject) { THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); - UNREFERENCED_PARAMETER(packagingObject); + UNREFERENCED_PARAMETER(appxPackagingObject); throw hresult_not_implemented(); } diff --git a/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.h b/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.h index cec9879ea6..174b39a2aa 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.h +++ b/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.h @@ -8,7 +8,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation PackageMinimumVersionValidator() = default; PackageMinimumVersionValidator(winrt::Windows::ApplicationModel::PackageVersion const& minimumVersion); - bool IsPackageValid(winrt::Microsoft::Windows::Management::Deployment::AppxPackagingObject const& packagingObject); + bool IsPackageValid(winrt::Windows::Foundation::IInspectable const& appxPackagingObject); }; } namespace winrt::Microsoft::Windows::Management::Deployment::factory_implementation diff --git a/dev/PackageManager/API/PackageManager.idl b/dev/PackageManager/API/PackageManager.idl index d764e81583..8d9ea58702 100644 --- a/dev/PackageManager/API/PackageManager.idl +++ b/dev/PackageManager/API/PackageManager.idl @@ -171,21 +171,11 @@ namespace Microsoft.Windows.Management.Deployment IVector Items { get; }; } - [feature(Feature_PackageValidator)] - [contract(PackageDeploymentContract, 3)] - [default_interface] - runtimeclass AppxPackagingObject - { - // This is an interop class for COM types defined in AppxPackaging.idl. - // The WinRT side has no methods or properties, but the object supports QueryInterface into the COM interfaces - // IAppxPackageReader or IAppxBundleReader, whichever is relevant for the object being read. - } - [feature(Feature_PackageValidator)] [contract(PackageDeploymentContract, 3)] interface IPackageValidator { - Boolean IsPackageValid(AppxPackagingObject packagingObject); + Boolean IsPackageValid(IInspectable appxPackagingObject); } [feature(Feature_PackageValidator)] diff --git a/dev/PackageManager/API/PackageManager.vcxitems b/dev/PackageManager/API/PackageManager.vcxitems index 9b34fd3f42..00a78dc6ce 100644 --- a/dev/PackageManager/API/PackageManager.vcxitems +++ b/dev/PackageManager/API/PackageManager.vcxitems @@ -15,7 +15,6 @@ - @@ -36,7 +35,6 @@ - diff --git a/dev/PackageManager/API/PackageManager.vcxitems.filters b/dev/PackageManager/API/PackageManager.vcxitems.filters index c47090b2de..b78fe08fce 100644 --- a/dev/PackageManager/API/PackageManager.vcxitems.filters +++ b/dev/PackageManager/API/PackageManager.vcxitems.filters @@ -56,9 +56,6 @@ Source Files - - Source Files - Source Files @@ -118,9 +115,6 @@ Header Files - - Header Files - Header Files From c32be1177e82532e1e7aff2e3fde56cd5d121bb7 Mon Sep 17 00:00:00 2001 From: Letao Wang Date: Wed, 24 Sep 2025 21:32:31 -0700 Subject: [PATCH 3/5] implement part of validators --- dev/PackageManager/API/AppxPackagingObject.h | 25 +++++++++++ ...M.W.M.D.PackageCertificateEkuValidator.cpp | 1 + .../M.W.M.D.PackageCertificateEkuValidator.h | 1 + .../M.W.M.D.PackageFamilyNameValidator.cpp | 43 ++++++++++++++++--- .../API/M.W.M.D.PackageFamilyNameValidator.h | 8 ++++ ...M.W.M.D.PackageMinimumVersionValidator.cpp | 41 +++++++++++++++--- .../M.W.M.D.PackageMinimumVersionValidator.h | 8 ++++ .../API/PackageManager.vcxitems | 1 + 8 files changed, 118 insertions(+), 10 deletions(-) create mode 100644 dev/PackageManager/API/AppxPackagingObject.h diff --git a/dev/PackageManager/API/AppxPackagingObject.h b/dev/PackageManager/API/AppxPackagingObject.h new file mode 100644 index 0000000000..778670f224 --- /dev/null +++ b/dev/PackageManager/API/AppxPackagingObject.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include + +namespace winrt::Microsoft::Windows::Management::Deployment::implementation +{ + struct AppxPackagingObject : winrt::implements + { + AppxPackagingObject(IUnknown* object) + { + m_object.copy_from(object); + } + + int32_t query_interface_tearoff(winrt::guid const& id, void** object) const noexcept override + { + return m_object.as(id, object); + } + + private: + winrt::com_ptr m_object; + }; + +} diff --git a/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp index f937d3c225..d1d53a08d1 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp +++ b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp @@ -13,6 +13,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation throw hresult_not_implemented(); } + bool PackageCertificateEkuValidator::IsPackageValid(winrt::Windows::Foundation::IInspectable const& appxPackagingObject) { THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); diff --git a/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h index e373839d08..2c2ea2e700 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h +++ b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h @@ -11,6 +11,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation bool IsPackageValid(winrt::Windows::Foundation::IInspectable const& appxPackagingObject); }; } + namespace winrt::Microsoft::Windows::Management::Deployment::factory_implementation { struct PackageCertificateEkuValidator : PackageCertificateEkuValidatorT diff --git a/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.cpp b/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.cpp index 7c7baa51d0..0d98739bfc 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.cpp +++ b/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.cpp @@ -3,22 +3,55 @@ #include "Microsoft.Windows.Management.Deployment.PackageFamilyNameValidator.g.cpp" #include +#include + namespace winrt::Microsoft::Windows::Management::Deployment::implementation { PackageFamilyNameValidator::PackageFamilyNameValidator(hstring const& expectedPackageFamilyName) { THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); - UNREFERENCED_PARAMETER(expectedPackageFamilyName); - - throw hresult_not_implemented(); + m_packageFamilyName = expectedPackageFamilyName; } + bool PackageFamilyNameValidator::IsPackageValid(winrt::Windows::Foundation::IInspectable const& appxPackagingObject) { THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); - UNREFERENCED_PARAMETER(appxPackagingObject); + winrt::com_ptr packageReader; + winrt::com_ptr bundleReader; + + if (SUCCEEDED(appxPackagingObject.as(IID_PPV_ARGS(&packageReader)))) + { + winrt::com_ptr manifestReader; + THROW_IF_FAILED(packageReader->GetManifest(manifestReader.put())); + + winrt::com_ptr packageId; + THROW_IF_FAILED(manifestReader->GetPackageId(packageId.put())); + + return CheckIdentity(packageId.get()); + } + else if (SUCCEEDED(appxPackagingObject.as(IID_PPV_ARGS(&bundleReader)))) + { + winrt::com_ptr manifestReader; + THROW_IF_FAILED(bundleReader->GetManifest(manifestReader.put())); + + winrt::com_ptr packageId; + THROW_IF_FAILED(manifestReader->GetPackageId(packageId.put())); + + return CheckIdentity(packageId.get()); + } + else + { + THROW_WIN32(ERROR_NOT_SUPPORTED); + } + } + + bool PackageFamilyNameValidator::CheckIdentity(IAppxManifestPackageId* packageId) + { + wil::unique_cotaskmem_string familyName; + THROW_IF_FAILED(packageId->GetPackageFamilyName(&familyName)); - throw hresult_not_implemented(); + return (CSTR_EQUAL == CompareStringOrdinal(familyName.get(), -1, m_packageFamilyName.c_str(), -1, true)); } } diff --git a/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.h b/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.h index 94e1119362..72e00a1a21 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.h +++ b/dev/PackageManager/API/M.W.M.D.PackageFamilyNameValidator.h @@ -1,6 +1,8 @@ #pragma once #include "Microsoft.Windows.Management.Deployment.PackageFamilyNameValidator.g.h" +#include + namespace winrt::Microsoft::Windows::Management::Deployment::implementation { struct PackageFamilyNameValidator : PackageFamilyNameValidatorT @@ -9,8 +11,14 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation PackageFamilyNameValidator(hstring const& expectedPackageFamilyName); bool IsPackageValid(winrt::Windows::Foundation::IInspectable const& appxPackagingObject); + + private: + bool CheckIdentity(IAppxManifestPackageId* packageId); + + hstring m_packageFamilyName; }; } + namespace winrt::Microsoft::Windows::Management::Deployment::factory_implementation { struct PackageFamilyNameValidator : PackageFamilyNameValidatorT diff --git a/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.cpp b/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.cpp index 4f6009e66c..dc1986fdb6 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.cpp +++ b/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.cpp @@ -9,16 +9,47 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation { THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); - UNREFERENCED_PARAMETER(minimumVersion); - - throw hresult_not_implemented(); + m_minimumVersion = ::AppModel::Identity::PackageVersion{ minimumVersion }.Version; } + bool PackageMinimumVersionValidator::IsPackageValid(winrt::Windows::Foundation::IInspectable const& appxPackagingObject) { THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); - UNREFERENCED_PARAMETER(appxPackagingObject); + winrt::com_ptr packageReader; + winrt::com_ptr bundleReader; + + if (SUCCEEDED(appxPackagingObject.as(IID_PPV_ARGS(&packageReader)))) + { + winrt::com_ptr manifestReader; + THROW_IF_FAILED(packageReader->GetManifest(manifestReader.put())); + + winrt::com_ptr packageId; + THROW_IF_FAILED(manifestReader->GetPackageId(packageId.put())); + + return CheckIdentity(packageId.get()); + } + else if (SUCCEEDED(appxPackagingObject.as(IID_PPV_ARGS(&bundleReader)))) + { + winrt::com_ptr manifestReader; + THROW_IF_FAILED(bundleReader->GetManifest(manifestReader.put())); + + winrt::com_ptr packageId; + THROW_IF_FAILED(manifestReader->GetPackageId(packageId.put())); + + return CheckIdentity(packageId.get()); + } + else + { + THROW_WIN32(ERROR_NOT_SUPPORTED); + } + } + + bool PackageMinimumVersionValidator::CheckIdentity(IAppxManifestPackageId* packageId) + { + UINT64 version; + THROW_IF_FAILED(packageId->GetVersion(&version)); - throw hresult_not_implemented(); + return (version >= m_minimumVersion); } } diff --git a/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.h b/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.h index 174b39a2aa..45ad4f3c2a 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.h +++ b/dev/PackageManager/API/M.W.M.D.PackageMinimumVersionValidator.h @@ -1,6 +1,8 @@ #pragma once #include "Microsoft.Windows.Management.Deployment.PackageMinimumVersionValidator.g.h" +#include + namespace winrt::Microsoft::Windows::Management::Deployment::implementation { struct PackageMinimumVersionValidator : PackageMinimumVersionValidatorT @@ -9,8 +11,14 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation PackageMinimumVersionValidator(winrt::Windows::ApplicationModel::PackageVersion const& minimumVersion); bool IsPackageValid(winrt::Windows::Foundation::IInspectable const& appxPackagingObject); + + private: + bool CheckIdentity(IAppxManifestPackageId* packageId); + + UINT64 m_minimumVersion; }; } + namespace winrt::Microsoft::Windows::Management::Deployment::factory_implementation { struct PackageMinimumVersionValidator : PackageMinimumVersionValidatorT diff --git a/dev/PackageManager/API/PackageManager.vcxitems b/dev/PackageManager/API/PackageManager.vcxitems index 00a78dc6ce..9873a2de9a 100644 --- a/dev/PackageManager/API/PackageManager.vcxitems +++ b/dev/PackageManager/API/PackageManager.vcxitems @@ -34,6 +34,7 @@ + From c9bc154402d0aa5c7bdbafaed8f765731f542f65 Mon Sep 17 00:00:00 2001 From: Letao Wang Date: Mon, 29 Sep 2025 21:15:02 -0700 Subject: [PATCH 4/5] impl --- dev/Common/IsWindowsVersion.h | 10 +- .../API/M.W.M.D.AddPackageOptions.cpp | 3 +- ...M.W.M.D.PackageCertificateEkuValidator.cpp | 180 +++++++++++++++++- .../M.W.M.D.PackageCertificateEkuValidator.h | 7 + .../API/M.W.M.D.PackageDeploymentManager.cpp | 59 +++++- .../API/M.W.M.D.StagePackageOptions.cpp | 3 +- .../API/PackageManager.vcxitems.filters | 3 + 7 files changed, 252 insertions(+), 13 deletions(-) diff --git a/dev/Common/IsWindowsVersion.h b/dev/Common/IsWindowsVersion.h index f7fe5ee17c..efabbdce0c 100644 --- a/dev/Common/IsWindowsVersion.h +++ b/dev/Common/IsWindowsVersion.h @@ -1,10 +1,12 @@ -// Copyright (c) Microsoft Corporation and Contributors. +// Copyright (c) Microsoft Corporation and Contributors. // Licensed under the MIT License. #ifndef __ISWINDOWSVERSION_H #define __ISWINDOWSVERSION_H #include +#include +#include namespace WindowsVersion { @@ -62,6 +64,12 @@ inline bool IsWindows11_24H2OrGreater() // MsixIsPackageFeatureSupported() added to in Windows 11 24H2 (aka NTDDI_WIN11_GE) return IsExportPresent(L"appxdeploymentclient.dll", "MsixIsPackageFeatureSupported"); } + +inline bool SupportsIAppxFactory4() +{ + return wil::CoCreateInstanceNoThrow().get() != nullptr; +} + } #endif // __ISWINDOWSVERSION_H diff --git a/dev/PackageManager/API/M.W.M.D.AddPackageOptions.cpp b/dev/PackageManager/API/M.W.M.D.AddPackageOptions.cpp index 8bca06d78a..3ea65b46bd 100644 --- a/dev/PackageManager/API/M.W.M.D.AddPackageOptions.cpp +++ b/dev/PackageManager/API/M.W.M.D.AddPackageOptions.cpp @@ -176,8 +176,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation bool AddPackageOptions::IsPackageValidatorsSupported() { - // TODO - check presence of AppxPackaging streaming reader feature - return true; + return WindowsVersion::SupportsIAppxFactory4(); } winrt::Windows::Foundation::Collections::IMap > AddPackageOptions::PackageValidators() { diff --git a/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp index d1d53a08d1..e0cf76ce6a 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp +++ b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.cpp @@ -3,23 +3,193 @@ #include "Microsoft.Windows.Management.Deployment.PackageCertificateEkuValidator.g.cpp" #include +#include + namespace winrt::Microsoft::Windows::Management::Deployment::implementation { PackageCertificateEkuValidator::PackageCertificateEkuValidator(hstring const& expectedCertificateEku) { THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); - UNREFERENCED_PARAMETER(expectedCertificateEku); - - throw hresult_not_implemented(); + m_expectedEku = expectedCertificateEku; } bool PackageCertificateEkuValidator::IsPackageValid(winrt::Windows::Foundation::IInspectable const& appxPackagingObject) { THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); - UNREFERENCED_PARAMETER(appxPackagingObject); + winrt::com_ptr packageReader; + winrt::com_ptr bundleReader; - throw hresult_not_implemented(); + if (SUCCEEDED(appxPackagingObject.as(IID_PPV_ARGS(&packageReader)))) + { + winrt::com_ptr signatureFile; + if (SUCCEEDED(packageReader->GetFootprintFile(APPX_FOOTPRINT_FILE_TYPE_SIGNATURE, signatureFile.put()))) + { + return CheckSignature(signatureFile.get()); + } + else + { + return false; // package is not valid because there is no signature present + } + } + else if (SUCCEEDED(appxPackagingObject.as(IID_PPV_ARGS(&bundleReader)))) + { + winrt::com_ptr signatureFile; + if (SUCCEEDED(bundleReader->GetFootprintFile(APPX_BUNDLE_FOOTPRINT_FILE_TYPE_SIGNATURE, signatureFile.put()))) + { + return CheckSignature(signatureFile.get()); + } + else + { + return false; // package is not valid because there is no signature present + } + } + else + { + THROW_WIN32(ERROR_NOT_SUPPORTED); + } } + + bool PackageCertificateEkuValidator::CheckSignature(IAppxFile* signatureFile) + { + winrt::com_ptr signatureStream; + THROW_IF_FAILED(signatureFile->GetStream(signatureStream.put())); + + // The p7x signature should have a leading 4-byte PKCX header + static const DWORD P7xFileId = 0x58434b50; // PKCX + static const DWORD P7xFileIdSize = sizeof(P7xFileId); + + STATSTG streamStats{}; + THROW_IF_FAILED(signatureStream->Stat(&streamStats, STATFLAG_NONAME)); + if (streamStats.cbSize.HighPart > 0 || streamStats.cbSize.LowPart < P7xFileIdSize) + { + return false; // The signature has unexpected size + } + + DWORD streamSize = streamStats.cbSize.LowPart; + auto streamBuffer{ wil::make_unique_nothrow(streamSize) }; + THROW_IF_NULL_ALLOC(streamBuffer); + + ULONG bytesRead{}; + THROW_IF_FAILED(signatureStream->Read(streamBuffer.get(), streamSize, &bytesRead)); + THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_BAD_FORMAT), bytesRead != streamSize); + + if (*reinterpret_cast(streamBuffer.get()) != P7xFileId) + { + return false; // The signature does not have expected header + } + + CRYPT_DATA_BLOB signatureBlob{}; + signatureBlob.cbData = streamSize - P7xFileIdSize; + signatureBlob.pbData = streamBuffer.get() + P7xFileIdSize; + + wil::unique_hcertstore certStore; + wil::unique_hcryptmsg signedMessage; + DWORD queryContentType = 0; + DWORD queryFormatType = 0; + if (!CryptQueryObject( + CERT_QUERY_OBJECT_BLOB, + &signatureBlob, + CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED, + CERT_QUERY_FORMAT_FLAG_BINARY, + 0, // Reserved parameter + NULL, // No encoding info needed + &queryContentType, + &queryFormatType, + &certStore, + &signedMessage, + NULL // No additional params for signed message output + )) + { + return false; // CryptQueryObject could not read the signature + } + + if (queryContentType != CERT_QUERY_CONTENT_PKCS7_SIGNED || queryFormatType != CERT_QUERY_FORMAT_BINARY || !certStore || !signedMessage) + { + return false; // CryptQueryObject returned unexpected data + } + + CMSG_SIGNER_INFO* signerInfo = NULL; + DWORD signerInfoSize = 0; + if (!CryptMsgGetParam(signedMessage.get(), CMSG_SIGNER_INFO_PARAM, 0, NULL, &signerInfoSize)) + { + return false; // CryptMsgGetParam could not read the signature + } + + if (signerInfoSize == 0 || signerInfoSize >= STRSAFE_MAX_CCH) + { + return false; // Signer info has unexpected size + } + + auto signerInfoBuffer{ wil::make_unique_nothrow(signerInfoSize) }; + THROW_IF_NULL_ALLOC(signerInfoBuffer); + signerInfo = reinterpret_cast(signerInfoBuffer.get()); + if (!CryptMsgGetParam(signedMessage.get(), CMSG_SIGNER_INFO_PARAM, 0, signerInfo, &signerInfoSize)) + { + return false; // CryptMsgGetParam could not read the signature + } + + // Get the signing certificate from the certificate store based on the issuer and serial number of the signer info + CERT_INFO certInfo; + certInfo.Issuer = signerInfo->Issuer; + certInfo.SerialNumber = signerInfo->SerialNumber; + + wil::unique_cert_context certContext{ + CertGetSubjectCertificateFromStore( + certStore.get(), + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + &certInfo) + }; + if (!certContext) + { + return false; // CertGetSubjectCertificateFromStore could not find a cert context + } + + DWORD ekuBufferSize = 0; + if (!CertGetEnhancedKeyUsage( + certContext.get(), + 0, // Accept EKU from EKU extension or EKU extended properties + NULL, + &ekuBufferSize)) + { + return false; // CertGetEnhancedKeyUsage could not read EKUs + } + + if (ekuBufferSize < sizeof(CERT_ENHKEY_USAGE)) + { + return false; // No EKUs are found in the signature + } + + auto ekuBuffer{ wil::make_unique_nothrow(ekuBufferSize)}; + THROW_IF_NULL_ALLOC(ekuBuffer); + PCERT_ENHKEY_USAGE ekusFound = reinterpret_cast(ekuBuffer.get()); + if (!CertGetEnhancedKeyUsage( + certContext.get(), + 0, // Accept EKU from EKU extension or EKU extended properties + ekusFound, + &ekuBufferSize)) + { + return false; // CertGetEnhancedKeyUsage could not read EKUs + } + + for (DWORD i = 0; i < ekusFound->cUsageIdentifier; i++) + { + auto eku{ ekusFound->rgpszUsageIdentifier[i] }; + + int length = MultiByteToWideChar(CP_ACP, 0, eku, -1, nullptr, 0); + auto ekuWcharBuffer{ wil::make_unique_nothrow(length) }; + THROW_IF_NULL_ALLOC(ekuWcharBuffer); + + MultiByteToWideChar(CP_ACP, 0, eku, -1, ekuWcharBuffer.get(), length); + + if (wcscmp(ekuWcharBuffer.get(), m_expectedEku.c_str()) == 0) + { + return true; // Found expected EKU + } + } + + return false; // Did not find expected EKU + } + } diff --git a/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h index 2c2ea2e700..abf70be04c 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h +++ b/dev/PackageManager/API/M.W.M.D.PackageCertificateEkuValidator.h @@ -1,6 +1,8 @@ #pragma once #include "Microsoft.Windows.Management.Deployment.PackageCertificateEkuValidator.g.h" +#include + namespace winrt::Microsoft::Windows::Management::Deployment::implementation { struct PackageCertificateEkuValidator : PackageCertificateEkuValidatorT @@ -9,6 +11,11 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation PackageCertificateEkuValidator(hstring const& expectedCertificateEku); bool IsPackageValid(winrt::Windows::Foundation::IInspectable const& appxPackagingObject); + + private: + bool CheckSignature(IAppxFile* signatureFile); + + hstring m_expectedEku{}; }; } diff --git a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp index acd07d7a93..4b804711d5 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp +++ b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp @@ -32,6 +32,9 @@ namespace ABI::Windows::Management::Deployment #include #include +#include +#include + #include #include @@ -3682,10 +3685,60 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation { THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); - UNREFERENCED_PARAMETER(packageValidators); - UNREFERENCED_PARAMETER(expectedDigests); + auto appxFactory{ wil::CoCreateInstance() }; + auto bundleFactory{ wil::CoCreateInstance() }; - throw hresult_not_implemented(); + for (const auto pair : packageValidators) + { + const auto packageUri{ pair.Key() }; + const auto validators{ pair.Value() }; + if (!packageUri || !validators || validators.Size() == 0) + { + continue; + } + + auto expectedDigest{ expectedDigests.TryLookup(packageUri) }; + auto packageUriString{ packageUri.AbsoluteCanonicalUri().c_str() }; + auto expectedDigestString{ expectedDigest.has_value() ? expectedDigest.value().c_str() : nullptr }; + + winrt::com_ptr<::IInspectable> appxObject; + winrt::com_ptr packageReader; + winrt::com_ptr bundleReader; + winrt::com_ptr digestProvider; + + if (SUCCEEDED(appxFactory->CreatePackageReaderFromSourceUri(packageUriString, expectedDigestString, packageReader.put()))) + { + appxObject = winrt::make(packageReader.get()); + digestProvider = packageReader.as(); + } + else if (SUCCEEDED(bundleFactory->CreateBundleReaderFromSourceUri(packageUriString, expectedDigestString, bundleReader.put()))) + { + appxObject = winrt::make(bundleReader.get()); + digestProvider = bundleReader.as(); + } + else + { + THROW_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED); + } + + for (const auto validator : validators) + { + if (!validator) + { + continue; + } + + THROW_HR_IF(APPX_E_DIGEST_MISMATCH, !validator.IsPackageValid(appxObject.as())); + } + + if (!expectedDigestString) + { + wil::unique_cotaskmem_string digest; + THROW_IF_FAILED(digestProvider->GetDigest(&digest)); + + expectedDigests.Insert(packageUri, digest.get()); + } + } } } diff --git a/dev/PackageManager/API/M.W.M.D.StagePackageOptions.cpp b/dev/PackageManager/API/M.W.M.D.StagePackageOptions.cpp index da04d830ee..30a0d9d08d 100644 --- a/dev/PackageManager/API/M.W.M.D.StagePackageOptions.cpp +++ b/dev/PackageManager/API/M.W.M.D.StagePackageOptions.cpp @@ -131,8 +131,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation bool StagePackageOptions::IsPackageValidatorsSupported() { - // TODO - check presence of AppxPackaging streaming reader feature - return true; + return WindowsVersion::SupportsIAppxFactory4(); } winrt::Windows::Foundation::Collections::IMap > StagePackageOptions::PackageValidators() { diff --git a/dev/PackageManager/API/PackageManager.vcxitems.filters b/dev/PackageManager/API/PackageManager.vcxitems.filters index b78fe08fce..7b29981e2c 100644 --- a/dev/PackageManager/API/PackageManager.vcxitems.filters +++ b/dev/PackageManager/API/PackageManager.vcxitems.filters @@ -124,6 +124,9 @@ Header Files + + Header Files + From 1f8ef3ab7dfaaa7935045e9e32272855499b8346 Mon Sep 17 00:00:00 2001 From: Letao Wang Date: Wed, 1 Oct 2025 17:45:29 -0700 Subject: [PATCH 5/5] view --- .../API/M.W.M.D.AddPackageOptions.cpp | 20 ++++++++++++++++-- .../API/M.W.M.D.AddPackageOptions.h | 3 ++- .../API/M.W.M.D.PackageDeploymentManager.cpp | 2 +- .../API/M.W.M.D.PackageDeploymentManager.h | 2 +- .../API/M.W.M.D.StagePackageOptions.cpp | 21 ++++++++++++++++--- .../API/M.W.M.D.StagePackageOptions.h | 3 ++- dev/PackageManager/API/PackageManager.idl | 12 +++++++++-- 7 files changed, 52 insertions(+), 11 deletions(-) diff --git a/dev/PackageManager/API/M.W.M.D.AddPackageOptions.cpp b/dev/PackageManager/API/M.W.M.D.AddPackageOptions.cpp index 3ea65b46bd..37d7df9477 100644 --- a/dev/PackageManager/API/M.W.M.D.AddPackageOptions.cpp +++ b/dev/PackageManager/API/M.W.M.D.AddPackageOptions.cpp @@ -178,14 +178,30 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation { return WindowsVersion::SupportsIAppxFactory4(); } - winrt::Windows::Foundation::Collections::IMap > AddPackageOptions::PackageValidators() + winrt::Windows::Foundation::Collections::IMapView > AddPackageOptions::PackageValidators() { THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); + if (!m_packageValidators) + { + // return an empty view + return winrt::single_threaded_map >().GetView(); + } + else + { + return m_packageValidators.GetView(); + } + } + void AddPackageOptions::AddPackageValidator(winrt::Windows::Foundation::Uri const& packageUri, winrt::Microsoft::Windows::Management::Deployment::IPackageValidator const& validator) + { if (!m_packageValidators) { m_packageValidators = winrt::single_threaded_map >(); } - return m_packageValidators; + if (!m_packageValidators.HasKey(packageUri)) + { + m_packageValidators.Insert(packageUri, winrt::single_threaded_vector()); + } + m_packageValidators.Lookup(packageUri).Append(validator); } } diff --git a/dev/PackageManager/API/M.W.M.D.AddPackageOptions.h b/dev/PackageManager/API/M.W.M.D.AddPackageOptions.h index 8bac3fe7bf..11e984b0f5 100644 --- a/dev/PackageManager/API/M.W.M.D.AddPackageOptions.h +++ b/dev/PackageManager/API/M.W.M.D.AddPackageOptions.h @@ -47,7 +47,8 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation bool LimitToExistingPackages(); void LimitToExistingPackages(bool value); bool IsPackageValidatorsSupported(); - winrt::Windows::Foundation::Collections::IMap > PackageValidators(); + winrt::Windows::Foundation::Collections::IMapView > PackageValidators(); + void AddPackageValidator(winrt::Windows::Foundation::Uri const&, winrt::Microsoft::Windows::Management::Deployment::IPackageValidator const&); private: winrt::Microsoft::Windows::Management::Deployment::PackageVolume m_targetVolume{ nullptr }; diff --git a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp index 4b804711d5..f8d88e2d33 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp +++ b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.cpp @@ -3679,7 +3679,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation } void PackageDeploymentManager::ValidatePackagesAndUpdateExpectedDigests( - winrt::Windows::Foundation::Collections::IMap > const& packageValidators, + winrt::Windows::Foundation::Collections::IMapView > const& packageValidators, winrt::Windows::Foundation::Collections::IMap& expectedDigests ) { diff --git a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.h b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.h index b37868785c..3179a3b949 100644 --- a/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.h +++ b/dev/PackageManager/API/M.W.M.D.PackageDeploymentManager.h @@ -282,7 +282,7 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation static bool IsUriScheme_MsUup(winrt::Windows::Foundation::Uri const& packageUri); void ValidatePackagesAndUpdateExpectedDigests( - winrt::Windows::Foundation::Collections::IMap > const& packageValidators, + winrt::Windows::Foundation::Collections::IMapView > const& packageValidators, winrt::Windows::Foundation::Collections::IMap& expectedDigests ); diff --git a/dev/PackageManager/API/M.W.M.D.StagePackageOptions.cpp b/dev/PackageManager/API/M.W.M.D.StagePackageOptions.cpp index 30a0d9d08d..afcd22c477 100644 --- a/dev/PackageManager/API/M.W.M.D.StagePackageOptions.cpp +++ b/dev/PackageManager/API/M.W.M.D.StagePackageOptions.cpp @@ -133,15 +133,30 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation { return WindowsVersion::SupportsIAppxFactory4(); } - winrt::Windows::Foundation::Collections::IMap > StagePackageOptions::PackageValidators() + winrt::Windows::Foundation::Collections::IMapView > StagePackageOptions::PackageValidators() { THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Management::Deployment::Feature_PackageValidator::IsEnabled()); + if (!m_packageValidators) + { + // return an empty view + return winrt::single_threaded_map >().GetView(); + } + else + { + return m_packageValidators.GetView(); + } + } + void StagePackageOptions::AddPackageValidator(winrt::Windows::Foundation::Uri const& packageUri, winrt::Microsoft::Windows::Management::Deployment::IPackageValidator const& validator) + { if (!m_packageValidators) { m_packageValidators = winrt::single_threaded_map >(); } - return m_packageValidators; + if (!m_packageValidators.HasKey(packageUri)) + { + m_packageValidators.Insert(packageUri, winrt::single_threaded_vector()); + } + m_packageValidators.Lookup(packageUri).Append(validator); } - } diff --git a/dev/PackageManager/API/M.W.M.D.StagePackageOptions.h b/dev/PackageManager/API/M.W.M.D.StagePackageOptions.h index 76ce2577d8..309b805595 100644 --- a/dev/PackageManager/API/M.W.M.D.StagePackageOptions.h +++ b/dev/PackageManager/API/M.W.M.D.StagePackageOptions.h @@ -36,7 +36,8 @@ namespace winrt::Microsoft::Windows::Management::Deployment::implementation bool IsExpectedDigestsSupported(); winrt::Windows::Foundation::Collections::IMap ExpectedDigests(); bool IsPackageValidatorsSupported(); - winrt::Windows::Foundation::Collections::IMap > PackageValidators(); + winrt::Windows::Foundation::Collections::IMapView > PackageValidators(); + void AddPackageValidator(winrt::Windows::Foundation::Uri const&, winrt::Microsoft::Windows::Management::Deployment::IPackageValidator const&); private: winrt::Microsoft::Windows::Management::Deployment::PackageVolume m_targetVolume{ nullptr }; diff --git a/dev/PackageManager/API/PackageManager.idl b/dev/PackageManager/API/PackageManager.idl index 8d9ea58702..109995d12b 100644 --- a/dev/PackageManager/API/PackageManager.idl +++ b/dev/PackageManager/API/PackageManager.idl @@ -235,7 +235,11 @@ namespace Microsoft.Windows.Management.Deployment [feature(Feature_PackageValidator)] [contract(PackageDeploymentContract, 3)] - IMap > PackageValidators{ get; }; + IMapView > PackageValidators{ get; }; + + [feature(Feature_PackageValidator)] + [contract(PackageDeploymentContract, 3)] + void AddPackageValidator(Windows.Foundation.Uri packageUri, IPackageValidator validator); } // Requires Windows >= 10.0.19041.0 (aka 2004 aka 20H1) @@ -267,7 +271,11 @@ namespace Microsoft.Windows.Management.Deployment [feature(Feature_PackageValidator)] [contract(PackageDeploymentContract, 3)] - IMap > PackageValidators{ get; }; + IMapView > PackageValidators{ get; }; + + [feature(Feature_PackageValidator)] + [contract(PackageDeploymentContract, 3)] + void AddPackageValidator(Windows.Foundation.Uri packageUri, IPackageValidator validator); } // Requires Windows >= 10.0.19041.0 (aka 2004 aka 20H1)