commit cee95925c544d7d1493a5d3300004c87290a51bf
parent 7481c148ac71e822d2a211c6055070b36275b38a
Author: Chacón <lechacon@users.noreply.github.com>
Date: Wed, 12 Jan 2022 14:44:43 -0800
Fix DLL load error in WinGetUtil (#1844)
Load and call `IsWow64GuestMachineSupported()` dynamically only if it is available, instead of calling it directly. This prevents a DLL load error when running on RS1, as happens on the Azure Functions of the service.
This is based on the existing pattern to call `GetMachineTypeAttributes()`.
Diffstat:
2 files changed, 54 insertions(+), 9 deletions(-)
diff --git 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
@@ -10,15 +10,55 @@ namespace AppInstaller::Utility
{
namespace
{
- void AddArchitectureIfGuestMachineSupported(std::vector<Architecture>& 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<IsWow64GuestMachineSupportedPtr>(GetProcAddress(m_module.get(), "IsWow64GuestMachineSupported"));
+ if (!m_isWow64GuestMachineSupported)
+ {
+ AICLI_LOG(Core, Verbose, << "Could not get proc address of IsWow64GuestMachineSupported");
+ return;
+ }
}
+
+ void AddArchitectureIfGuestMachineSupported(std::vector<Architecture>& 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<Architecture>& 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<Architecture>& target, Architecture architecture, USHORT guestMachine)
+ {
+ GetMachineTypeAttributesHelper helper;
+ helper.AddArchitectureIfMachineTypeAttributesUserEnabled(target, architecture, guestMachine);
+ }
+
// Gets the applicable architectures for the current machine.
std::vector<Architecture> 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);
}