winget-cli

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

commit be0be282cc5b38533bfb5958ff96cabd40e00d54
parent 480f4568ea3d433973b85835fa4567e961857b53
Author: KEINOS <github+fork-qiita-news@keinos.com>
Date:   Tue, 27 May 2025 17:26:07 +0000

Merge remote-tracking branch 'upstream/master'

Diffstat:
M.github/actions/spelling/expect.txt | 1+
Msrc/AppInstallerRepositoryCore/Microsoft/PredefinedInstalledSourceFactory.cpp | 51++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/AppInstallerRepositoryCore/pch.h | 6++++--
Msrc/Microsoft.Management.Deployment/Helpers.cpp | 36+++++++++++++++++++++++-------------
4 files changed, 72 insertions(+), 22 deletions(-)

diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt @@ -123,6 +123,7 @@ deliveryoptimization deliveryoptimizationerrors DENYWR desktopappinstaller +devblogs devhome DFX dic diff --git a/src/AppInstallerRepositoryCore/Microsoft/PredefinedInstalledSourceFactory.cpp b/src/AppInstallerRepositoryCore/Microsoft/PredefinedInstalledSourceFactory.cpp @@ -262,6 +262,43 @@ namespace AppInstaller::Repository::Microsoft struct CachedInstalledIndex { + // https://devblogs.microsoft.com/oldnewthing/20210215-00/?p=104865 + struct Singleton + { + struct Holder : public winrt::implements<Holder, winrt::Windows::Foundation::IInspectable> + { + static constexpr std::wstring_view Guid{ L"{48c47064-4fff-4eca-812c-dbb4f33a8fcb}" }; + std::shared_ptr<CachedInstalledIndex> m_shared{ std::make_shared<CachedInstalledIndex>() }; + }; + + std::weak_ptr<CachedInstalledIndex> m_weak; + winrt::slim_mutex m_lock; + + std::shared_ptr<CachedInstalledIndex> Get() + { + { + const std::shared_lock lock{ m_lock }; + if (auto cachedIndex = m_weak.lock()) + { + return cachedIndex; + } + } + + auto value = winrt::make_self<Holder>(); + + const std::shared_lock lock{ m_lock }; + if (auto cachedIndex = m_weak.lock()) + { + return cachedIndex; + } + + winrt::Windows::ApplicationModel::Core::CoreApplication::Properties().Insert(Holder::Guid, value.as<winrt::Windows::Foundation::IInspectable>()); + + m_weak = value->m_shared; + return value->m_shared; + } + }; + CachedInstalledIndex() { ARPHelper arpHelper; @@ -340,7 +377,7 @@ namespace AppInstaller::Repository::Microsoft if (PredefinedInstalledSourceFactory::StringToFilter(m_details.Arg) == PredefinedInstalledSourceFactory::Filter::NoneWithForcedCacheUpdate) { - GetCachedInstalledIndex().ForceNextUpdate(); + GetCachedInstalledIndex()->ForceNextUpdate(); } } @@ -359,9 +396,9 @@ namespace AppInstaller::Repository::Microsoft // Only cache for the unfiltered install data if (filter == PredefinedInstalledSourceFactory::Filter::None || filter == PredefinedInstalledSourceFactory::Filter::NoneWithForcedCacheUpdate) { - CachedInstalledIndex& cachedIndex = GetCachedInstalledIndex(); - cachedIndex.UpdateIndexIfNeeded(); - return std::make_shared<SQLiteIndexSource>(m_details, cachedIndex.GetCopy(), true); + std::shared_ptr<CachedInstalledIndex> cachedIndex = GetCachedInstalledIndex(); + cachedIndex->UpdateIndexIfNeeded(); + return std::make_shared<SQLiteIndexSource>(m_details, cachedIndex->GetCopy(), true); } else { @@ -370,10 +407,10 @@ namespace AppInstaller::Repository::Microsoft } private: - CachedInstalledIndex& GetCachedInstalledIndex() + std::shared_ptr<CachedInstalledIndex> GetCachedInstalledIndex() { - static CachedInstalledIndex s_installedIndex; - return s_installedIndex; + static CachedInstalledIndex::Singleton s_installedIndex; + return s_installedIndex.Get(); } SourceDetails m_details; diff --git a/src/AppInstallerRepositoryCore/pch.h b/src/AppInstallerRepositoryCore/pch.h @@ -21,7 +21,8 @@ #include <winsqlite/winsqlite3.h> -#include <winrt/Windows.ApplicationModel.h> +#include <winrt/Windows.ApplicationModel.h> +#include <winrt/Windows.ApplicationModel.Core.h> #include <winrt/Windows.Foundation.h> #include <winrt/Windows.Foundation.Collections.h> #include <winrt/Windows.Management.Deployment.h> @@ -41,7 +42,8 @@ #include <memory> #include <optional> #include <random> -#include <set> +#include <set> +#include <shared_mutex> #include <string> #include <string_view> #include <sstream> diff --git a/src/Microsoft.Management.Deployment/Helpers.cpp b/src/Microsoft.Management.Deployment/Helpers.cpp @@ -78,26 +78,36 @@ namespace winrt::Microsoft::Management::Deployment::implementation // Get the caller process id and use it to check if the caller has permissions to access the feature. winrt::Windows::Security::Authorization::AppCapabilityAccess::AppCapabilityAccessStatus status = winrt::Windows::Security::Authorization::AppCapabilityAccess::AppCapabilityAccessStatus::DeniedBySystem; - auto capability = winrt::Windows::Security::Authorization::AppCapabilityAccess::AppCapability::CreateWithProcessIdForUser(nullptr, GetStringForCapability(requiredCapability), callerProcessId); - status = capability.CheckAccess(); + winrt::Windows::Security::Authorization::AppCapabilityAccess::AppCapability capability{ nullptr }; - allowed = (status == winrt::Windows::Security::Authorization::AppCapabilityAccess::AppCapabilityAccessStatus::Allowed); - } - else - { - // If AppCapability is not present, require at least medium IL callers - auto requiredIntegrityLevel = AppInstaller::Security::IntegrityLevel::Medium; - - if (callerProcessId != GetCurrentProcessId()) + try + { + capability = winrt::Windows::Security::Authorization::AppCapabilityAccess::AppCapability::CreateWithProcessIdForUser(nullptr, GetStringForCapability(requiredCapability), callerProcessId); + } + catch (const winrt::hresult_invalid_argument&) { - allowed = AppInstaller::Security::IsCOMCallerIntegrityLevelAtLeast(requiredIntegrityLevel); } - else + + if (capability) { - allowed = AppInstaller::Security::IsCurrentIntegrityLevelAtLeast(requiredIntegrityLevel); + status = capability.CheckAccess(); + + return ((status == winrt::Windows::Security::Authorization::AppCapabilityAccess::AppCapabilityAccessStatus::Allowed) ? S_OK : E_ACCESSDENIED); } } + // If AppCapability is not present, require at least medium IL callers + auto requiredIntegrityLevel = AppInstaller::Security::IntegrityLevel::Medium; + + if (callerProcessId != GetCurrentProcessId()) + { + allowed = AppInstaller::Security::IsCOMCallerIntegrityLevelAtLeast(requiredIntegrityLevel); + } + else + { + allowed = AppInstaller::Security::IsCurrentIntegrityLevelAtLeast(requiredIntegrityLevel); + } + return (allowed ? S_OK : E_ACCESSDENIED); }