1
0
mirror of https://github.com/valinet/ExplorerPatcher.git synced 2024-11-23 23:21:08 +01:00

Functionality to bring back power menu (Win+X).

This commit is contained in:
Valentin Radu 2021-08-12 02:30:09 +03:00
parent 00745079de
commit dfaf1ee806
15 changed files with 1121 additions and 66 deletions

6
.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[submodule "libs/libvalinet"]
path = libs/libvalinet
url = https://github.com/valinet/libvalinet
[submodule "libs/funchook"]
path = libs/funchook
url = https://github.com/kubo/funchook

View File

@ -1,9 +1,11 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31410.357
VisualStudioVersion = 16.0.30002.166
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExplorerPatcher", "ExplorerPatcher\ExplorerPatcher.vcxproj", "{DED2A41B-0EA8-4D8E-8A02-31A29EF9F91C}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExplorerPatcher", "ExplorerPatcher\ExplorerPatcher.vcxproj", "{05EB9B16-4C34-47A2-97F5-E65E4955F71B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExplorerPatcherLibrary", "ExplorerPatcherLibrary\ExplorerPatcherLibrary.vcxproj", "{DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -13,19 +15,27 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DED2A41B-0EA8-4D8E-8A02-31A29EF9F91C}.Debug|x64.ActiveCfg = Debug|x64
{DED2A41B-0EA8-4D8E-8A02-31A29EF9F91C}.Debug|x64.Build.0 = Debug|x64
{DED2A41B-0EA8-4D8E-8A02-31A29EF9F91C}.Debug|x86.ActiveCfg = Debug|Win32
{DED2A41B-0EA8-4D8E-8A02-31A29EF9F91C}.Debug|x86.Build.0 = Debug|Win32
{DED2A41B-0EA8-4D8E-8A02-31A29EF9F91C}.Release|x64.ActiveCfg = Release|x64
{DED2A41B-0EA8-4D8E-8A02-31A29EF9F91C}.Release|x64.Build.0 = Release|x64
{DED2A41B-0EA8-4D8E-8A02-31A29EF9F91C}.Release|x86.ActiveCfg = Release|Win32
{DED2A41B-0EA8-4D8E-8A02-31A29EF9F91C}.Release|x86.Build.0 = Release|Win32
{05EB9B16-4C34-47A2-97F5-E65E4955F71B}.Debug|x64.ActiveCfg = Debug|x64
{05EB9B16-4C34-47A2-97F5-E65E4955F71B}.Debug|x64.Build.0 = Debug|x64
{05EB9B16-4C34-47A2-97F5-E65E4955F71B}.Debug|x86.ActiveCfg = Debug|Win32
{05EB9B16-4C34-47A2-97F5-E65E4955F71B}.Debug|x86.Build.0 = Debug|Win32
{05EB9B16-4C34-47A2-97F5-E65E4955F71B}.Release|x64.ActiveCfg = Release|x64
{05EB9B16-4C34-47A2-97F5-E65E4955F71B}.Release|x64.Build.0 = Release|x64
{05EB9B16-4C34-47A2-97F5-E65E4955F71B}.Release|x86.ActiveCfg = Release|Win32
{05EB9B16-4C34-47A2-97F5-E65E4955F71B}.Release|x86.Build.0 = Release|Win32
{DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Debug|x64.ActiveCfg = Debug|x64
{DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Debug|x64.Build.0 = Debug|x64
{DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Debug|x86.ActiveCfg = Debug|Win32
{DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Debug|x86.Build.0 = Debug|Win32
{DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Release|x64.ActiveCfg = Release|x64
{DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Release|x64.Build.0 = Release|x64
{DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Release|x86.ActiveCfg = Release|Win32
{DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {1D4372C5-52FF-4B30-9C71-5ED6F36C1966}
SolutionGuid = {39EBC2F0-6949-46EC-9FC2-776591FEE2DA}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,100 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 22000,1,0,1
PRODUCTVERSION 22000,1,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "VALINET Solutions SRL"
VALUE "FileDescription", "ExplorerPatcher Daemon"
VALUE "FileVersion", "22000.1.0.1"
VALUE "InternalName", "ExplorerPatcher.exe"
VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved."
VALUE "OriginalFilename", "ExplorerPatcher.exe"
VALUE "ProductName", "ExplorerPatcher"
VALUE "ProductVersion", "22000.1.0.1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -18,21 +18,12 @@
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{ded2a41b-0ea8-4d8e-8a02-31a29ef9f91c}</ProjectGuid>
<RootNamespace>ExplorerPatcher</RootNamespace>
<ProjectGuid>{05EB9B16-4C34-47A2-97F5-E65E4955F71B}</ProjectGuid>
<RootNamespace>CenterTitlebarText</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>ExplorerPatcher</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -82,22 +73,35 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -110,30 +114,16 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
@ -142,7 +132,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -151,6 +141,15 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ExplorerPatcher.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -3,7 +3,7 @@
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
<Extensions>cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
@ -14,19 +14,19 @@
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc">
<ResourceCompile Include="ExplorerPatcher.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -1,32 +1,63 @@
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#include <valinet/hooking/exeinject.h>
#include <Windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <Psapi.h>
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
#define CLASS_NAME TEXT("ExplorerPatcher")
#define APP_NAME TEXT("Windows Explorer")
#define NOP 0x90
#define PATCH_OFFSET 0x8cb33
HANDLE hProcess = NULL;
HMODULE hMod = NULL;
LPVOID hInjection = NULL;
HWND hWnd = NULL;
LRESULT CALLBACK WindowProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch (uMsg)
{
case WM_APP_CRASHED:
{
TerminateProcess(GetCurrentProcess(), 0);
}
}
return VnWindowProc(
hWnd,
uMsg,
wParam,
lParam
);
}
// https://stackoverflow.com/questions/8046097/how-to-check-if-a-process-has-the-administrative-rights
BOOL IsElevated() {
BOOL fRet = FALSE;
HANDLE hToken = NULL;
if (OpenProcessToken(
GetCurrentProcess(),
TOKEN_QUERY,
GetCurrentProcess(),
TOKEN_QUERY,
&hToken
))
))
{
TOKEN_ELEVATION Elevation;
DWORD cbSize = sizeof(TOKEN_ELEVATION);
if (GetTokenInformation(
hToken,
hToken,
TokenElevation,
&Elevation,
sizeof(Elevation),
&Elevation,
sizeof(Elevation),
&cbSize
)) {
fRet = Elevation.TokenIsElevated;
@ -146,6 +177,18 @@ int WINAPI wWinMain(
MODULEENTRY32 me32 = { 0 };
THREADENTRY32 th32 = { 0 };
TCHAR szExplorerPath[MAX_PATH];
FILE* conout;
TCHAR szLibPath[MAX_PATH];
#ifdef DEBUG
if (!AllocConsole());
if (freopen_s(
&conout,
"CONOUT$",
"w",
stdout
));
#endif
if (install_uninstall())
{
@ -178,10 +221,10 @@ int WINAPI wWinMain(
}
if ((hExplorer = OpenProcess(
PROCESS_VM_READ |
PROCESS_VM_WRITE |
PROCESS_QUERY_INFORMATION |
PROCESS_VM_OPERATION |
PROCESS_VM_READ |
PROCESS_VM_WRITE |
PROCESS_QUERY_INFORMATION |
PROCESS_VM_OPERATION |
SYNCHRONIZE,
FALSE,
dwExplorerPID
@ -195,7 +238,7 @@ int WINAPI wWinMain(
CharLower(szExplorerPath);
me32.dwSize = sizeof(MODULEENTRY32);
hSnapshot = CreateToolhelp32Snapshot(
TH32CS_SNAPMODULE,
TH32CS_SNAPMODULE,
dwExplorerPID
);
if (Module32First(hSnapshot, &me32) == TRUE)
@ -248,7 +291,41 @@ int WINAPI wWinMain(
{
DebugActiveProcessStop(dwExplorerPID);
}
return 0;
GetModuleFileName(
GetModuleHandle(NULL),
szLibPath,
MAX_PATH
);
PathRemoveFileSpec(szLibPath);
lstrcat(
szLibPath,
L"\\ExplorerPatcherLibrary.dll"
);
Sleep(2000);
return VnInjectAndMonitorProcess(
szLibPath,
MAX_PATH,
"main",
TEXT("explorer.exe"),
CLASS_NAME,
NULL,
hInstance,
stdout,
0,
WindowProc,
TRUE,
0,
0,
NULL,
&hProcess,
&hMod,
&hInjection,
NULL,
0,
&hWnd,
&hWnd
);
}
return 0;
return 0;
}

View File

@ -1,6 +1,7 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by resource.rc
// Used by ExplorerPatcher.rc
//
// Next default values for new objects
//

View File

@ -0,0 +1,100 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 22000,1,0,1
PRODUCTVERSION 22000,1,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "VALINET Solutions SRL"
VALUE "FileDescription", "ExplorerPatcher Library"
VALUE "FileVersion", "22000.1.0.1"
VALUE "InternalName", "ExplorerPatcherLibrary.dll"
VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved."
VALUE "OriginalFilename", "ExplorerPatcherLibrary.dll"
VALUE "ProductName", "WinOverview"
VALUE "ProductVersion", "22000.1.0.1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}</ProjectGuid>
<RootNamespace>CenterTitlebarTextLibrary</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>ExplorerPatcherLibrary</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</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" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)libs\funchook\include;$(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)libs\funchook\build\Release\funchook.lib;$(SolutionDir)libs\funchook\build\Release\distorm.lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(SolutionDir)libs\funchook\build\Release\funchook.lib;$(SolutionDir)libs\funchook\build\Release\distorm.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)libs\funchook\include;$(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)libs\funchook\build\Release\funchook.lib;$(SolutionDir)libs\funchook\build\Release\distorm.lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(SolutionDir)libs\funchook\build\Release\funchook.lib;$(SolutionDir)libs\funchook\build\Release\distorm.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dllmain.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ExplorerPatcherLibrary.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ExplorerPatcherLibrary.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,467 @@
#include <initguid.h>
#include <stdio.h>
#include <stdbool.h>
#include <Windows.h>
#include <funchook.h>
#pragma comment(lib, "Psapi.lib") // required by funchook
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
funchook_t* funchook = NULL;
HMODULE hModule = NULL;
HWND messageWindow = NULL;
static HWND(WINAPI* CreateWindowInBand)(
_In_ DWORD dwExStyle,
_In_opt_ ATOM atom,
_In_opt_ LPCWSTR lpWindowName,
_In_ DWORD dwStyle,
_In_ int X,
_In_ int Y,
_In_ int nWidth,
_In_ int nHeight,
_In_opt_ HWND hWndParent,
_In_opt_ HMENU hMenu,
_In_opt_ HINSTANCE hInstance,
_In_opt_ LPVOID lpParam,
DWORD band
);
static INT64(*CLauncherTipContextMenu_ShowLauncherTipContextMenuFunc)(
void* _this,
POINT* pt
);
static void(*CLauncherTipContextMenu_ExecuteCommand)(
void* _this,
int a2
);
static void(*CLauncherTipContextMenu_ExecuteShutdownCommand)(
void* _this,
void* a2
);
static INT64(*InternalAddRef)(
void* a1,
INT64 a2
);
static INT64(*ImmersiveContextMenuHelper_ApplyOwnerDrawToMenu)(
HMENU h1,
HMENU h2,
HWND a3,
unsigned int a4,
void* data
);
static INT64(*CLauncherTipContextMenu_GetMenuItemsAsync)(
void* _this,
void* rect,
void** iunk
);
DEFINE_GUID(IID_ILauncherTipContextMenu,
0xb8c1db5f,
0xcbb3, 0x48bc, 0xaf, 0xd9,
0xce, 0x6b, 0x88, 0x0c, 0x79, 0xed
);
#define CLASS_NAME L"LauncherTipWnd"
static HRESULT(*CImmersiveHotkeyNotification_OnMessageFunc)(
void* _this,
INT64 msg,
INT wParam,
INT64 lParam
);
static INT64(*CImmersiveHotkeyNotification_GetMonitorForHotkeyNotificationFunc)(
void* _this,
void** a2,
HWND* a3
);
static BOOL(*IsDesktopInputContextFunc)(
void* p1,
void* p2
);
HANDLE hThread;
typedef struct
{
void* _this;
POINT point;
IUnknown* iunk;
} ShowLauncherTipContextMenuParameters;
DWORD ShowLauncherTipContextMenu(
ShowLauncherTipContextMenuParameters* params
)
{
WNDCLASS wc = { 0 };
wc.style = CS_DBLCLKS;
wc.lpfnWndProc = DefWindowProc; // CLauncherTipContextMenu_WndProc
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = CLASS_NAME;
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
RegisterClass(&wc);
HWND hWnd = CreateWindowInBand(
0,
CLASS_NAME,
0,
WS_POPUP,
0,
0,
0,
0,
0,
0,
GetModuleHandle(NULL),
params->_this,
7
);
ShowWindow(hWnd, SW_SHOW);
SetForegroundWindow(hWnd);
while (!(*((HMENU*)((char*)params->_this + 0xe8))))
{
Sleep(1);
}
if (!(*((HMENU*)((char*)params->_this + 0xe8))))
{
goto finalize;
}
/*
void* v25 = 0;
ImmersiveContextMenuHelper_ApplyOwnerDrawToMenu(
*((HMENU*)((char*)params->_this + 0xe8)),
hWnd,
&(params->point),
0xc,
&v25
);
*/
BOOL res = TrackPopupMenu(
*((HMENU*)((char*)params->_this + 0xe8)),
TPM_RETURNCMD,
params->point.x,
params->point.y,
0,
hWnd,
0
);
if (res > 0)
{
if (res < 4000)
{
INT64 info = *(INT64*)((char*)(*(INT64*)((char*)params->_this + 0xa8 - 0x58)) + (INT64)res * 8 - 8);
CLauncherTipContextMenu_ExecuteCommand(
(char*)params->_this - 0x58,
&info
);
}
else
{
INT64 info = *(INT64*)((char*)(*(INT64*)((char*)params->_this + 0xc8 - 0x58)) + ((INT64)res - 4000) * 8);
CLauncherTipContextMenu_ExecuteShutdownCommand(
(char*)params->_this - 0x58,
&info
);
}
}
// ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenu
finalize:
params->iunk->lpVtbl->Release(params->iunk);
SendMessage(
hWnd,
WM_CLOSE,
0,
0
);
free(params);
hThread = NULL;
return 0;
}
INT64 CLauncherTipContextMenu_ShowLauncherTipContextMenuHook(
void* _this,
POINT* pt
)
{
if (hThread)
{
goto finalize;
}
POINT point;
if (pt)
{
point = *pt;
}
else
{
POINT ptCursor;
GetCursorPos(&ptCursor);
MONITORINFO mi;
mi.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(
MonitorFromPoint(
ptCursor,
MONITOR_DEFAULTTONEAREST
),
&mi
);
// https://stackoverflow.com/questions/44746234/programatically-get-windows-taskbar-info-autohidden-state-taskbar-coordinates
APPBARDATA abd;
abd.cbSize = sizeof(APPBARDATA);
SHAppBarMessage(ABM_GETTASKBARPOS, &abd);
if (abd.rc.left < 5 && abd.rc.top > 5)
{
// TB_POS_BOTTOM
point.x = mi.rcMonitor.left;
point.y = mi.rcMonitor.bottom;
}
else if (abd.rc.left < 5 && abd.rc.top < 5 && abd.rc.right > abd.rc.bottom)
{
// TB_POS_TOP
point.x = mi.rcMonitor.left;
point.y = mi.rcMonitor.top;
}
else if (abd.rc.left < 5 && abd.rc.top < 5 && abd.rc.right < abd.rc.bottom)
{
// TB_POS_LEFT
point.x = mi.rcMonitor.left;
point.y = mi.rcMonitor.top;
}
else if (abd.rc.left > 5 && abd.rc.top < 5)
{
// TB_POS_RIGHT
point.x = mi.rcMonitor.right;
point.y = mi.rcMonitor.top;
}
}
IUnknown* iunk;
INT64 r = CLauncherTipContextMenu_GetMenuItemsAsync(
_this,
&point,
&iunk
);
iunk->lpVtbl->AddRef(iunk);
ShowLauncherTipContextMenuParameters* params = malloc(
sizeof(ShowLauncherTipContextMenuParameters)
);
params->_this = _this;
params->point = point;
params->iunk = iunk;
hThread = CreateThread(
0,
0,
ShowLauncherTipContextMenu,
params,
0,
0
);
finalize:
return CLauncherTipContextMenu_ShowLauncherTipContextMenuFunc(_this, pt);
}
HRESULT CImmersiveHotkeyNotification_OnMessageHook(
void* _this,
INT64 msg,
INT wParam,
INT64 lParam
)
{
if (wParam == 28 && IsDesktopInputContextFunc(_this, msg)) // 15
{
IUnknown* pMonitor;
HRESULT hr = CImmersiveHotkeyNotification_GetMonitorForHotkeyNotificationFunc(
(char*)_this - 0x68,
&pMonitor,
0
);
if (SUCCEEDED(hr))
{
IUnknown* pMenu;
IUnknown_QueryService(
pMonitor,
&IID_ILauncherTipContextMenu,
&IID_ILauncherTipContextMenu,
&pMenu
);
if (pMenu)
{
CLauncherTipContextMenu_ShowLauncherTipContextMenuHook(
pMenu,
0
);
pMenu->lpVtbl->Release(pMenu);
}
}
return 0;
}
return CImmersiveHotkeyNotification_OnMessageFunc(
_this,
msg,
wParam,
lParam
);
}
__declspec(dllexport) DWORD WINAPI main(
_In_ LPVOID lpParameter
)
{
/*
FILE* conout;
AllocConsole();
freopen_s(&conout, "CONOUT$", "w", stdout);
*/
int rv;
if (!funchook)
{
messageWindow = (HWND)lpParameter;
funchook = funchook_create();
HANDLE hUser32 = GetModuleHandle(L"user32.dll");
if (hUser32) CreateWindowInBand = GetProcAddress(hUser32, "CreateWindowInBand");
HANDLE hTwinuiPcshell = GetModuleHandle(L"twinui.pcshell.dll");
InternalAddRef = (INT64(*)(void*, INT64))
((uintptr_t)hTwinuiPcshell + 0x46650);
CLauncherTipContextMenu_GetMenuItemsAsync = (INT64(*)(void*, void*, void**))
((uintptr_t)hTwinuiPcshell + 0x5051F0);
ImmersiveContextMenuHelper_ApplyOwnerDrawToMenu = (INT64(*)(HMENU, HMENU, HWND, unsigned int, void*))
((uintptr_t)hTwinuiPcshell + 0x535AF8);
CLauncherTipContextMenu_ExecuteShutdownCommand = (void(*)(void*, void*))
((uintptr_t)hTwinuiPcshell + 0x514714);
CLauncherTipContextMenu_ExecuteCommand = (void(*)(void*, int))
((uintptr_t)hTwinuiPcshell + 0x5143D0);
CLauncherTipContextMenu_ShowLauncherTipContextMenuFunc = (INT64(*)(void*, POINT*))
((uintptr_t)hTwinuiPcshell + 0x506EE0);
rv = funchook_prepare(
funchook,
(void**)&CLauncherTipContextMenu_ShowLauncherTipContextMenuFunc,
CLauncherTipContextMenu_ShowLauncherTipContextMenuHook
);
if (rv != 0)
{
FreeLibraryAndExitThread(hModule, rv);
return rv;
}
HANDLE hTwinui = GetModuleHandle(L"twinui.dll");
CImmersiveHotkeyNotification_GetMonitorForHotkeyNotificationFunc = (INT64(*)(void*, void**, HWND*))
((uintptr_t)hTwinui + 0x24B4A8);
IsDesktopInputContextFunc = (BOOL(*)(void*, void*))
((uintptr_t)hTwinui + 0x24A5C4);
CImmersiveHotkeyNotification_OnMessageFunc = (HRESULT(*)(void*, INT64, INT, INT64))
((uintptr_t)hTwinui + 0xB2A70);
rv = funchook_prepare(
funchook,
(void**)&CImmersiveHotkeyNotification_OnMessageFunc,
CImmersiveHotkeyNotification_OnMessageHook
);
if (rv != 0)
{
FreeLibraryAndExitThread(hModule, rv);
return rv;
}
rv = funchook_install(funchook, 0);
if (rv != 0)
{
FreeLibraryAndExitThread(hModule, rv);
return rv;
}
}
else
{
rv = funchook_uninstall(funchook, 0);
if (rv != 0)
{
FreeLibraryAndExitThread(hModule, rv);
return rv;
}
rv = funchook_destroy(funchook);
if (rv != 0)
{
FreeLibraryAndExitThread(hModule, rv);
return rv;
}
FreeLibraryAndExitThread(hModule, 0);
}
return 0;
}
BOOL WINAPI DllMain(
_In_ HINSTANCE hinstDLL,
_In_ DWORD fdwReason,
_In_ LPVOID lpvReserved
)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
hModule = hinstDLL;
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

View File

@ -0,0 +1,15 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by ExplorerPatcherLibrary.rc
//
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -2,9 +2,95 @@
Explorer Patcher is a patcher that enables various stuff in Explorer. For the moment, it includes the following:
* allows using the old taskbar in Windows 11 without the side effects of UndockingDisabled and with fully working search, modern apps showing properly, screen snip still working etc
* reenables the power menu (Win+X) when using the classic taskbar in Windows 11
This has been tested only on Windows 11 build 22000.1. It probably does not work on other builds due to different offsets in explorer.exe and its libraries. Once this matures, a solution will be offered for dynamically determining the necessary offsets. As it stands, the application is more in a proof of concept phase.
A detailed description of how this works is available on my web site [here](https://valinet.ro/2021/08/09/Restore-Windows-11-to-working-Windows-10-UI.html).
Precompiled binaries are available in [Releases](https://github.com/valinet/ExplorerPatcher/releases).
Please help me fix the known issues described below in order to get feature parity with regular Windows 10 releases. As it stands, the application works but it is not perfect, yet.
## Installation
To install, save the executable in a safe directory, run it once as an administrator to have it register as [Taskman](https://www.geoffchappell.com/notes/windows/shell/explorer/taskman.htm) for Explorer and just restart Explorer or reboot.
The application does not currently offer a way to configure its behavior. In the mean time, I recommend commenting out whatever you do not like and compile your own executable, as described below (instructions are very simple).
## Known issues
* The power menu (Win+X menu) is unskinned - it has the default menu appearance from Windows 11 instead of the look the clock, taskbar etc context menus get; at the moment, I think it boils down to correctly calling `ImmersiveContextMenuHelper::ApplyOwnerDrawToMenu`, but unfortunately I've yet to do it correctly
* The power menu (Win+X menu) is mapped to Win+F for the moment, as I've yet to have the time to investigate where exactly Win+X is handled (i.e. it is not in `CImmersiveHotkeyNotification::OnMessage`)
## License
Hooking is done using the excellent [funchook](https://github.com/kubo/funchook) library (GPLv2 with linking exception), which in turn is powered by the [diStorm3](https://github.com/gdabah/distorm/) (3-clause BSD) disassembler. Thus, I am offering this under GNU General Public License Version 2.0, which I believe is compatible.
## Compiling
The following prerequisites are necessary in order to compile this project:
* Microsoft C/C++ Optimizing Compiler - this can be obtained by installing either of these packages:
* Visual Studio - this is a fully featured IDE; you'll need to check "C/C++ application development role" when installing. If you do not require the full suite, use the package bellow.
* Build Tools for Visual Studio - this just installs the compiler, which you'll be able to use from the command line, or from other applications like CMake
Download either of those [here](http://go.microsoft.com/fwlink/p/?LinkId=840931). The guide assumes you have installed either Visual Studio 2019, either Build Tools for Visual Studio 2019.
* [CMake](https://cmake.org/) - for easier usage, make sure to have it added to PATH during installation
* Git - you can use [Git for Windows](https://git-scm.com/download/win), or git command via the Windows Subsystem for Linux.
Steps:
1. Clone git repo along with all submodules
```
git clone --recursive https://github.com/valinet/ExplorerPatcher
```
If "git" is not found as a command, type its full path, or have its folder added to PATH, or open Git command window in the respective folder if using Git for Windows.
2. Compile funchook
```
cd libs
cd funchook
md build
cd build
cmake -G "Visual Studio 16 2019" -A x64 ..
cmake --build . --config Release
```
If "cmake" is not found as a command, type its full path, or have its folder added to PATH.
Type "Win32" instead of "x64" above, if compiling for x86. The command above works for x64.
3. Compile ExplorerPatcher
* Double click the ExplorerPatcher.sln to open the solution in Visual Studio. Choose Release and your processor architecture in the toolbar. Press F6 to compile.
* Open an "x86 Native Tools Command Prompt for VS 2019" (for x86), or "x64 Native Tools Command Prompt for VS 2019" (for x64) (search that in Start), go to folder containing solution file and type:
* For x86:
```
msbuild ExplorerPatcher.sln /property:Configuration=Release /property:Platform=x86
```
* For x64:
```
msbuild ExplorerPatcher.sln /property:Configuration=Release /property:Platform=x64
```
The resulting exe and dll will be in "Release" folder (if you chose x86), or "x64\Release" (if you chose x64) in the folder containing the solution file.
That's it. later, if you want to recompile, make sure to update the repository and the submodules first:
```
git pull
git submodule update --init --recursive
```

1
libs/funchook Submodule

@ -0,0 +1 @@
Subproject commit f3928f99f5ec77bf750c8c7ebaec44e44ba34257

1
libs/libvalinet Submodule

@ -0,0 +1 @@
Subproject commit d345b62ab1062b9414a1db934c69ce777d467169