Skip to content

Commit

Permalink
Fix DLL load error in WinGetUtil (#1844)
Browse files Browse the repository at this point in the history
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()`.
  • Loading branch information
Chacón authored Jan 12, 2022
1 parent 7481c14 commit cee9592
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/AppInstallerCLI.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand Down
62 changes: 53 additions & 9 deletions src/AppInstallerCommonCore/Architecture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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()
{
Expand All @@ -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);
}
Expand Down

0 comments on commit cee9592

Please sign in to comment.