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:
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)