diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index 8f7f2a61b0..00a39eaff0 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -26,6 +26,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Project", "Project", "{8D53 ..\cgmanifest.json = ..\cgmanifest.json ..\README.md = ..\README.md ..\doc\Settings.md = ..\doc\Settings.md + ..\WinGetUtil.nuspec = ..\WinGetUtil.nuspec EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "catch2", "catch2\catch2.vcxitems", "{5295E21E-9868-4DE2-A177-FBB97B36579B}" diff --git a/src/AppInstallerCommonCore/Architecture.cpp b/src/AppInstallerCommonCore/Architecture.cpp index 7960dc4d10..2e40069dcc 100644 --- a/src/AppInstallerCommonCore/Architecture.cpp +++ b/src/AppInstallerCommonCore/Architecture.cpp @@ -10,15 +10,55 @@ namespace AppInstaller::Utility { namespace { - void AddArchitectureIfGuestMachineSupported(std::vector& target, Architecture architecture, USHORT guestMachine) + // IsWow64GuestMachineSupported() is available starting on Windows 10, version 1709 (RS3). + // We generally target a later version (version 1809, RS5), but the WinGetUtil is used in + // Azure Functions that run on version 1607 (RS1) where it is not available. So, we load and + // call this function only if available. + using IsWow64GuestMachineSupportedPtr = decltype(&IsWow64GuestMachineSupported); + + struct IsWow64GuestMachineSupportedHelper { - BOOL supported = FALSE; - LOG_IF_FAILED(IsWow64GuestMachineSupported(guestMachine, &supported)); - - if (supported) + IsWow64GuestMachineSupportedHelper() { - target.push_back(architecture); + m_module.reset(LoadLibraryEx(L"api-ms-win-core-wow64-l1-1-2.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32)); + if (!m_module) + { + AICLI_LOG(Core, Verbose, << "Could not load api-ms-win-core-wow64-l1-1-2.dll"); + return; + } + + m_isWow64GuestMachineSupported = + reinterpret_cast(GetProcAddress(m_module.get(), "IsWow64GuestMachineSupported")); + if (!m_isWow64GuestMachineSupported) + { + AICLI_LOG(Core, Verbose, << "Could not get proc address of IsWow64GuestMachineSupported"); + return; + } } + + void AddArchitectureIfGuestMachineSupported(std::vector& target, Architecture architecture, USHORT guestMachine) + { + if (m_isWow64GuestMachineSupported) + { + BOOL supported = FALSE; + LOG_IF_FAILED(m_isWow64GuestMachineSupported(guestMachine, &supported)); + + if (supported) + { + target.push_back(architecture); + } + } + } + + private: + wil::unique_hmodule m_module; + IsWow64GuestMachineSupportedPtr m_isWow64GuestMachineSupported = nullptr; + }; + + void AddArchitectureIfGuestMachineSupported(std::vector& target, Architecture architecture, USHORT guestMachine) + { + IsWow64GuestMachineSupportedHelper helper; + helper.AddArchitectureIfGuestMachineSupported(target, architecture, guestMachine); } // These types are defined in a future SDK and can be removed when we actually have them available. @@ -75,6 +115,12 @@ namespace AppInstaller::Utility GetMachineTypeAttributesPtr m_getMachineTypeAttributes = nullptr; }; + void AddArchitectureIfMachineTypeAttributesUserEnabled(std::vector& target, Architecture architecture, USHORT guestMachine) + { + GetMachineTypeAttributesHelper helper; + helper.AddArchitectureIfMachineTypeAttributesUserEnabled(target, architecture, guestMachine); + } + // Gets the applicable architectures for the current machine. std::vector CreateApplicableArchitecturesVector() { @@ -84,11 +130,9 @@ namespace AppInstaller::Utility { 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); + AddArchitectureIfMachineTypeAttributesUserEnabled(applicableArchs, Architecture::X64, IMAGE_FILE_MACHINE_AMD64); AddArchitectureIfGuestMachineSupported(applicableArchs, Architecture::X86, IMAGE_FILE_MACHINE_I386); applicableArchs.push_back(Architecture::Neutral); }