api: add support for WoW64

Some functions of SetupAPI only work when invoked from a native process.
Registry and filesystem reflection makes them fail on WoW64. For WoW64
processes, a minimum set of rundll32 functions are provided.

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2020-07-24 09:39:02 +02:00 committed by Jason A. Donenfeld
parent b592e071d2
commit 5925f914e4
9 changed files with 130 additions and 12 deletions

10
.gitignore vendored
View File

@ -4,12 +4,14 @@
# Build Output
/dist
/x86/Release
/x86/Debug
/amd64/Release
/amd64/Debug
/arm64/Release
/amd64/Release
/arm/Debug
/arm/Release
/arm64/Debug
/arm64/Release
/x86/Debug
/x86/Release
# Static Driver Verifier Output
/sdv

View File

@ -1,6 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
@ -9,6 +13,10 @@
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
@ -62,6 +70,12 @@
<PlatformToolset>v142</PlatformToolset>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
@ -75,6 +89,12 @@
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
@ -96,6 +116,10 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\wintun.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\wintun.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\wintun.props" />
@ -104,6 +128,10 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\wintun.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\wintun.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>..\$(WintunPlatform)\$(Configuration)\</OutDir>
@ -169,6 +197,7 @@
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="registry.c" />
<ClCompile Include="rundll32.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@ -45,6 +45,9 @@
<ClCompile Include="nci.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="rundll32.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="registry.c">
<Filter>Source Files</Filter>
</ClCompile>

62
api/rundll32.c Normal file
View File

@ -0,0 +1,62 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
*/
#include "pch.h"
#if defined(_M_AMD64) || defined(_M_ARM64)
__declspec(dllexport) VOID __stdcall CreateAdapter(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
UNREFERENCED_PARAMETER(hwnd);
UNREFERENCED_PARAMETER(hinst);
UNREFERENCED_PARAMETER(lpszCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
int Argc;
LPWSTR *Argv = CommandLineToArgvW(GetCommandLineW(), &Argc);
if (Argc < 4)
goto cleanupArgv;
if (wcslen(Argv[2]) >= MAX_POOL)
goto cleanupArgv;
if (wcslen(Argv[3]) >= MAX_ADAPTER_NAME)
goto cleanupArgv;
GUID RequestedGUID;
if (Argc > 4 && FAILED(CLSIDFromString(Argv[4], &RequestedGUID)))
goto cleanupArgv;
WINTUN_ADAPTER *Adapter;
BOOL RebootRequired = FALSE;
DWORD Result = WintunCreateAdapter(Argv[2], Argv[3], Argc > 4 ? &RequestedGUID : NULL, &Adapter, &RebootRequired);
if (Result != ERROR_SUCCESS)
goto cleanupArgv;
WintunFreeAdapter(Adapter);
cleanupArgv:
LocalFree(Argv);
}
__declspec(dllexport) VOID __stdcall DeleteAdapter(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
UNREFERENCED_PARAMETER(hwnd);
UNREFERENCED_PARAMETER(hinst);
UNREFERENCED_PARAMETER(lpszCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
int Argc;
LPWSTR *Argv = CommandLineToArgvW(GetCommandLineW(), &Argc);
if (Argc < 3)
goto cleanupArgv;
WINTUN_ADAPTER Adapter = { 0 };
if (FAILED(CLSIDFromString(Argv[2], &Adapter.CfgInstanceID)))
goto cleanupArgv;
BOOL RebootRequired = FALSE;
WintunDeleteAdapter(&Adapter, &RebootRequired);
cleanupArgv:
LocalFree(Argv);
}
#endif

View File

@ -122,6 +122,8 @@
<WixArch Condition="'$(Platform)'=='ARM64'">arm64</WixArch>
<WixCandleFlags>$(WixCandleFlags) -nologo -arch $(WixArch) -dWINTUN_PLATFORM=$(WintunPlatform) -dWINTUN_VERSION=$(WintunVersion) -dINSTALLER_VERSION_MIN=$(InstallerVersionMin) -sw1086</WixCandleFlags>
<WixLightFlags>$(WixLightFlags) -nologo -b output_dir="$(OutDir.TrimEnd('\'))" -spdb -sw1076 -sw1079</WixLightFlags>
<WixLightFlags Condition="'$(Platform)'=='x64'">$(WixLightFlags) -b output_dir_wow64="..\x86\$(Configuration)"</WixLightFlags>
<WixLightFlags Condition="'$(Platform)'=='ARM64'">$(WixLightFlags) -b output_dir_wow64="..\arm\$(Configuration)"</WixLightFlags>
<WixOutputPath>$(OutDir)</WixOutputPath>
<WixOutputName>wintun</WixOutputName>
<WixOutputExt>.msm</WixOutputExt>

View File

@ -5,11 +5,6 @@
Copyright (C) 2018-2019 WireGuard LLC. All Rights Reserved.
-->
<?if $(var.WINTUN_PLATFORM) = "x86"?>
<?define PlatformSystemFolder = "SystemFolder"?>
<?else?>
<?define PlatformSystemFolder = "System64Folder"?>
<?endif?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Module Id="wintun" Language="0" Version="$(var.WINTUN_VERSION)">
<Package
@ -31,11 +26,24 @@
KeyPath="yes" />
</Component>
<Directory Id="$(var.PlatformSystemFolder)">
<?if $(var.WINTUN_PLATFORM) = "x86"?>
<Directory Id="SystemFolder">
<Component Guid="5dd2a342-6a4c-4af6-8ebc-b05411644b1c">
<File Id="wintun.dll" Name="wintun.dll" Source="!(bindpath.output_dir)wintun.dll" KeyPath="yes" />
</Component>
</Directory>
<?else?>
<Directory Id="SystemFolder">
<Component Guid="493548d6-12f6-4286-8fff-4efa77317a8f">
<File Id="wintun.dll-wow64" Name="wintun.dll" Source="!(bindpath.output_dir_wow64)wintun.dll" KeyPath="yes" />
</Component>
</Directory>
<Directory Id="System64Folder">
<Component Guid="5dd2a342-6a4c-4af6-8ebc-b05411644b1c">
<File Id="wintun.dll" Name="wintun.dll" Source="!(bindpath.output_dir)wintun.dll" KeyPath="yes" />
</Component>
</Directory>
<?endif?>
</Directory>
<Property Id="WintunInstallerHash" Value="$(var.INSTALLER_LIBRARY_HASH)" SuppressModularization="yes" />

View File

@ -15,9 +15,10 @@
<Target Name="Build" DependsOnTargets="Driver-x86;Driver-amd64;Driver-arm64" />
<Target Name="MSM" DependsOnTargets="MSM-x86;MSM-amd64;MSM-arm64" />
<Target Name="Clean">
<RemoveDir Directories="x86\Release\" />
<RemoveDir Directories="amd64\Release\" />
<RemoveDir Directories="arm\Release\" />
<RemoveDir Directories="arm64\Release\" />
<RemoveDir Directories="x86\Release\" />
<RemoveDir Directories="$(SDVDir)" />
<RemoveDir Directories="$(DistributionDir)" />
<Delete Files="smvbuild.log;smvstats.txt;wintun.DVL.XML" />

View File

@ -12,9 +12,10 @@
<WintunVersion>$(WintunVersionMaj).$(WintunVersionMin)</WintunVersion><!-- Used for versioning, must be n.n[.n[.n]]. -->
<!-- .vcxproj are using different platform names. -->
<WintunPlatform Condition="'$(Platform)'=='ARM'">arm</WintunPlatform>
<WintunPlatform Condition="'$(Platform)'=='ARM64'">arm64</WintunPlatform>
<WintunPlatform Condition="'$(Platform)'=='Win32'">x86</WintunPlatform>
<WintunPlatform Condition="'$(Platform)'=='x64'">amd64</WintunPlatform>
<WintunPlatform Condition="'$(Platform)'=='ARM64'">arm64</WintunPlatform>
<DistributionDir>dist\</DistributionDir>
<SDVDir>sdv\</SDVDir>

View File

@ -22,45 +22,55 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|amd64 = Debug|amd64
Debug|arm = Debug|arm
Debug|arm64 = Debug|arm64
Debug|x86 = Debug|x86
Release|amd64 = Release|amd64
Release|arm = Release|arm
Release|arm64 = Release|arm64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Debug|amd64.ActiveCfg = Debug|x64
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Debug|amd64.Build.0 = Debug|x64
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Debug|arm.ActiveCfg = Debug|ARM
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Debug|arm.Build.0 = Debug|ARM
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Debug|arm64.ActiveCfg = Debug|ARM64
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Debug|arm64.Build.0 = Debug|ARM64
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Debug|x86.ActiveCfg = Debug|Win32
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Debug|x86.Build.0 = Debug|Win32
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Release|amd64.ActiveCfg = Release|x64
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Release|amd64.Build.0 = Release|x64
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Release|arm.ActiveCfg = Release|ARM
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Release|arm.Build.0 = Release|ARM
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Release|arm64.ActiveCfg = Release|ARM64
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Release|arm64.Build.0 = Release|ARM64
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Release|x86.ActiveCfg = Release|Win32
{897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Release|x86.Build.0 = Release|Win32
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Debug|amd64.ActiveCfg = Debug|x64
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Debug|amd64.Build.0 = Debug|x64
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Debug|arm.ActiveCfg = Debug|Win32
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Debug|arm64.ActiveCfg = Debug|ARM64
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Debug|arm64.Build.0 = Debug|ARM64
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Debug|x86.ActiveCfg = Debug|Win32
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Debug|x86.Build.0 = Debug|Win32
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|amd64.ActiveCfg = Release|x64
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|amd64.Build.0 = Release|x64
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|arm.ActiveCfg = Release|Win32
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|arm64.ActiveCfg = Release|ARM64
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|arm64.Build.0 = Release|ARM64
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|x86.ActiveCfg = Release|Win32
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|x86.Build.0 = Release|Win32
{D19E6354-A643-4ACC-82D5-B2780BB83475}.Debug|amd64.ActiveCfg = Debug|x64
{D19E6354-A643-4ACC-82D5-B2780BB83475}.Debug|amd64.Build.0 = Debug|x64
{D19E6354-A643-4ACC-82D5-B2780BB83475}.Debug|arm.ActiveCfg = Debug|Win32
{D19E6354-A643-4ACC-82D5-B2780BB83475}.Debug|arm64.ActiveCfg = Debug|ARM64
{D19E6354-A643-4ACC-82D5-B2780BB83475}.Debug|arm64.Build.0 = Debug|ARM64
{D19E6354-A643-4ACC-82D5-B2780BB83475}.Debug|x86.ActiveCfg = Debug|Win32
{D19E6354-A643-4ACC-82D5-B2780BB83475}.Debug|x86.Build.0 = Debug|Win32
{D19E6354-A643-4ACC-82D5-B2780BB83475}.Release|amd64.ActiveCfg = Release|x64
{D19E6354-A643-4ACC-82D5-B2780BB83475}.Release|amd64.Build.0 = Release|x64
{D19E6354-A643-4ACC-82D5-B2780BB83475}.Release|arm.ActiveCfg = Release|Win32
{D19E6354-A643-4ACC-82D5-B2780BB83475}.Release|arm64.ActiveCfg = Release|ARM64
{D19E6354-A643-4ACC-82D5-B2780BB83475}.Release|arm64.Build.0 = Release|ARM64
{D19E6354-A643-4ACC-82D5-B2780BB83475}.Release|x86.ActiveCfg = Release|Win32