winget-cli

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

commit 4972fabba208c3715b31dd32a7f9d4e9a175cb55
parent 3a4d0071b6d1e3aad1bca0fc8b0f0a59d1c9ba79
Author: JohnMcPMS <johnmcp@microsoft.com>
Date:   Wed,  8 Sep 2021 11:17:49 -0700

Support for x64 on ARM64 (#1441)

This change fixes #666 by implementing dynamic loading of the API and invoking it specifically for x64 when the machine is ARM64.  The API can replace our current use of `IsWow64GuestMachineSupported`, but there is no need to take the additional risk of that change at this time.
Diffstat:
M.github/actions/spelling/expect.txt | 2++
Msrc/AppInstallerCommonCore/Architecture.cpp | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt @@ -130,6 +130,7 @@ hhx HINSTANCE hkey hlocal +hmodule hre hresults htm @@ -246,6 +247,7 @@ pkindex PMS positionals powertoys +processthreads productcode pseudocode pvk diff --git a/src/AppInstallerCommonCore/Architecture.cpp b/src/AppInstallerCommonCore/Architecture.cpp @@ -21,6 +21,60 @@ namespace AppInstaller::Utility } } + // These types are defined in a future SDK and can be removed when we actually have them available. + // The exception is that None was added (and this is an enum class). + enum class MACHINE_ATTRIBUTES { + None = 0, + UserEnabled = 0x00000001, + KernelEnabled = 0x00000002, + Wow64Container = 0x00000004 + }; + + DEFINE_ENUM_FLAG_OPERATORS(MACHINE_ATTRIBUTES); + + using GetMachineTypeAttributesPtr = HRESULT(WINAPI*)(USHORT Machine, MACHINE_ATTRIBUTES* MachineTypeAttributes); + + // GetMachineTypeAttributes can apparently replace IsWow64GuestMachineSupported, but no reason to do so right now. + struct GetMachineTypeAttributesHelper + { + GetMachineTypeAttributesHelper() + { + m_module.reset(LoadLibraryEx(L"api-ms-win-core-processthreads-l1-1-7.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32)); + if (!m_module) + { + AICLI_LOG(Core, Verbose, << "Could not load api-ms-win-core-processthreads-l1-1-7.dll"); + return; + } + + m_getMachineTypeAttributes = + reinterpret_cast<GetMachineTypeAttributesPtr>(GetProcAddress(m_module.get(), "GetMachineTypeAttributes")); + if (!m_getMachineTypeAttributes) + { + AICLI_LOG(Core, Verbose, << "Could not get proc address of GetMachineTypeAttributes"); + return; + } + } + + void AddArchitectureIfMachineTypeAttributesUserEnabled(std::vector<Architecture>& target, Architecture architecture, USHORT guestMachine) + { + if (m_getMachineTypeAttributes) + { + MACHINE_ATTRIBUTES attributes = MACHINE_ATTRIBUTES::None; + if (SUCCEEDED_LOG(m_getMachineTypeAttributes(guestMachine, &attributes))) + { + if (WI_IsFlagSet(attributes, MACHINE_ATTRIBUTES::UserEnabled)) + { + target.push_back(architecture); + } + } + } + } + + private: + wil::unique_hmodule m_module; + GetMachineTypeAttributesPtr m_getMachineTypeAttributes = nullptr; + }; + // Gets the applicable architectures for the current machine. std::vector<Architecture> CreateApplicableArchitecturesVector() { @@ -29,10 +83,15 @@ namespace AppInstaller::Utility switch (GetSystemArchitecture()) { case Architecture::Arm64: + { + GetMachineTypeAttributesHelper helper; + applicableArchs.push_back(Architecture::Arm64); AddArchitectureIfGuestMachineSupported(applicableArchs, Architecture::Arm, IMAGE_FILE_MACHINE_ARMNT); + helper.AddArchitectureIfMachineTypeAttributesUserEnabled(applicableArchs, Architecture::X64, IMAGE_FILE_MACHINE_AMD64); AddArchitectureIfGuestMachineSupported(applicableArchs, Architecture::X86, IMAGE_FILE_MACHINE_I386); applicableArchs.push_back(Architecture::Neutral); + } break; case Architecture::Arm: applicableArchs.push_back(Architecture::Arm);