winget-cli

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

commit 665ddd9c91c94f035ece1f6f4abd50c9bb5dadf6
parent 88bc528b12af91383889b1a7e913fb204592d0bf
Author: yao-msft <50888816+yao-msft@users.noreply.github.com>
Date:   Mon,  6 Feb 2023 11:53:33 -0800

Fix GetFullNameFromFamilyName for non-elevated context (#2922)


Diffstat:
Msrc/AppInstallerCommonCore/MsixInfo.cpp | 59+++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 51 insertions(+), 8 deletions(-)

diff --git a/src/AppInstallerCommonCore/MsixInfo.cpp b/src/AppInstallerCommonCore/MsixInfo.cpp @@ -7,6 +7,7 @@ #include "Public/AppInstallerLogging.h" #include "Public/AppInstallerStrings.h" #include "Public/AppInstallerDownloader.h" +#include "Public/AppInstallerRuntime.h" using namespace winrt::Windows::Storage::Streams; using namespace Microsoft::WRL; @@ -367,21 +368,63 @@ namespace AppInstaller::Msix PackageManager packageManager; std::wstring pfn = Utility::ConvertToUTF16(familyName); - auto packages = packageManager.FindPackages(pfn); - std::optional<std::string> result; - for (const auto& package : packages) + // PackageManager.FindPackages() can find all packages (including provisioned ones) but requires admin. + // For non admin callers, use FindPackagesByPackageFamily where only packages registered to current user will be found. + if (Runtime::IsRunningAsAdmin()) { - if (result.has_value()) + auto packages = packageManager.FindPackages(pfn); + + std::optional<std::string> result; + for (const auto& package : packages) { - // More than 1 package found. Don't directly error, let caller deal with it. - return {}; + if (result.has_value()) + { + // More than 1 package found. Don't directly error, let caller deal with it. + AICLI_LOG(Core, Error, << "Multiple packages found for family name: " << familyName); + return {}; + } + + result = Utility::ConvertToUTF8(package.Id().FullName()); } - result = Utility::ConvertToUTF8(package.Id().FullName()); + return result; } + else + { + UINT32 fullNameCount = 0; + UINT32 bufferLength = 0; + UINT32 properties = 0; + LONG findResult = FindPackagesByPackageFamily(pfn.c_str(), PACKAGE_FILTER_HEAD, &fullNameCount, nullptr, &bufferLength, nullptr, &properties); + if (findResult == ERROR_SUCCESS || fullNameCount == 0) + { + // No package found + return {}; + } + else if (findResult != ERROR_INSUFFICIENT_BUFFER) + { + THROW_WIN32(findResult); + } + else if (fullNameCount != 1) + { + // Don't directly error, let caller deal with it + AICLI_LOG(Core, Error, << "Multiple packages found for family name: " << fullNameCount); + return {}; + } - return result; + // fullNameCount == 1 at this point + PWSTR fullNamePtr; + std::wstring buffer(static_cast<size_t>(bufferLength) + 1, '\0'); + THROW_IF_WIN32_ERROR(FindPackagesByPackageFamily(pfn.c_str(), PACKAGE_FILTER_HEAD, &fullNameCount, &fullNamePtr, &bufferLength, &buffer[0], &properties)); + if (fullNameCount != 1 || bufferLength == 0) + { + // Something changed in between, abandon + AICLI_LOG(Core, Error, << "Packages found for family name: " << fullNameCount); + return {}; + } + buffer.resize(bufferLength - 1); + return Utility::ConvertToUTF8(buffer); + } } std::string GetPackageFamilyNameFromFullName(std::string_view fullName)