Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for x64 on ARM64 #1441

Merged
merged 3 commits into from
Sep 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/actions/spelling/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ hhx
HINSTANCE
hkey
hlocal
hmodule
hre
hresults
htm
Expand Down Expand Up @@ -246,6 +247,7 @@ pkindex
PMS
positionals
powertoys
processthreads
productcode
pseudocode
pvk
Expand Down
59 changes: 59 additions & 0 deletions src/AppInstallerCommonCore/Architecture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand All @@ -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);
Expand Down