From 00745079de4be328cb8964d0b8bc1b4cee29b3f2 Mon Sep 17 00:00:00 2001 From: Valentin Radu Date: Mon, 9 Aug 2021 17:30:23 +0300 Subject: [PATCH] Initial commit --- ExplorerPatcher.sln | 31 +++ ExplorerPatcher/ExplorerPatcher.vcxproj | 157 +++++++++++ .../ExplorerPatcher.vcxproj.filters | 32 +++ ExplorerPatcher/main.c | 254 ++++++++++++++++++ ExplorerPatcher/resource.h | 14 + ExplorerPatcher/resource.rc | 100 +++++++ README.md | 12 +- 7 files changed, 598 insertions(+), 2 deletions(-) create mode 100644 ExplorerPatcher.sln create mode 100644 ExplorerPatcher/ExplorerPatcher.vcxproj create mode 100644 ExplorerPatcher/ExplorerPatcher.vcxproj.filters create mode 100644 ExplorerPatcher/main.c create mode 100644 ExplorerPatcher/resource.h create mode 100644 ExplorerPatcher/resource.rc diff --git a/ExplorerPatcher.sln b/ExplorerPatcher.sln new file mode 100644 index 0000000..f3ed24e --- /dev/null +++ b/ExplorerPatcher.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31410.357 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExplorerPatcher", "ExplorerPatcher\ExplorerPatcher.vcxproj", "{DED2A41B-0EA8-4D8E-8A02-31A29EF9F91C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + 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 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1D4372C5-52FF-4B30-9C71-5ED6F36C1966} + EndGlobalSection +EndGlobal diff --git a/ExplorerPatcher/ExplorerPatcher.vcxproj b/ExplorerPatcher/ExplorerPatcher.vcxproj new file mode 100644 index 0000000..d7737e7 --- /dev/null +++ b/ExplorerPatcher/ExplorerPatcher.vcxproj @@ -0,0 +1,157 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + 16.0 + Win32Proj + {ded2a41b-0ea8-4d8e-8a02-31a29ef9f91c} + ExplorerPatcher + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + + + Windows + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Windows + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + + + Windows + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Windows + true + true + true + + + + + + \ No newline at end of file diff --git a/ExplorerPatcher/ExplorerPatcher.vcxproj.filters b/ExplorerPatcher/ExplorerPatcher.vcxproj.filters new file mode 100644 index 0000000..0794076 --- /dev/null +++ b/ExplorerPatcher/ExplorerPatcher.vcxproj.filters @@ -0,0 +1,32 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/ExplorerPatcher/main.c b/ExplorerPatcher/main.c new file mode 100644 index 0000000..93ec123 --- /dev/null +++ b/ExplorerPatcher/main.c @@ -0,0 +1,254 @@ +#pragma comment(linker,"\"/manifestdependency:type='win32' \ +name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ +processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#include +#include +#include +#include + +#define APP_NAME TEXT("Windows Explorer") +#define NOP 0x90 +#define PATCH_OFFSET 0x8cb33 + +// 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, + &hToken + )) + { + TOKEN_ELEVATION Elevation; + DWORD cbSize = sizeof(TOKEN_ELEVATION); + if (GetTokenInformation( + hToken, + TokenElevation, + &Elevation, + sizeof(Elevation), + &cbSize + )) { + fRet = Elevation.TokenIsElevated; + } + } + if (hToken) { + CloseHandle(hToken); + } + return fRet; +} + +int install_uninstall() +{ + TCHAR buffer[200], szFileName[MAX_PATH], szReadName[MAX_PATH] = { 0 }; + HKEY hKey; + DWORD dwReadBytes; + + if (IsElevated()) + { + dwReadBytes = MAX_PATH; + GetModuleFileName(NULL, szFileName, MAX_PATH); + if (RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), + 0, + KEY_READ | KEY_SET_VALUE, + &hKey + ) != ERROR_SUCCESS) + { + goto error_setup; + } + RegGetValue( + hKey, + NULL, + TEXT("Taskman"), + RRF_RT_REG_SZ, + NULL, + szReadName, + (LPDWORD)(&dwReadBytes) + ); + if (!wcscmp(szFileName, szReadName)) + { + if (RegDeleteValue( + hKey, + TEXT("Taskman") + ) != ERROR_SUCCESS) + { + goto error_setup; + } + MessageBox( + 0, + TEXT("Uninstall successful."), + APP_NAME, + MB_ICONINFORMATION + ); + } + else + { + if (RegSetValueEx( + hKey, + TEXT("Taskman"), + 0, + REG_SZ, + (const BYTE*)szFileName, (DWORD)( +#ifdef UNICODE + wcslen(szFileName) +#else + strlen(szFileName) +#endif + * sizeof(TCHAR)) + ) != ERROR_SUCCESS) + { + goto error_setup; + } + MessageBox( + 0, + TEXT("Successfully installed Taskman registry key."), + APP_NAME, + MB_ICONINFORMATION + ); + } + return 1; + error_setup: +#ifdef UNICODE + swprintf(buffer, 200, +#else + sprintf(buffer, +#endif + TEXT("An error occured when servicing the product (%d)."), GetLastError()); + MessageBox( + 0, + buffer, + APP_NAME, + MB_ICONERROR + ); + return -1; + } + else + { + return 0; + } +} + +int WINAPI wWinMain( + _In_ HINSTANCE hInstance, + _In_opt_ HINSTANCE hPrevInstance, + _In_ LPWSTR lpCmdLine, + _In_ int nShowCmd +) +{ + HANDLE hExplorer, hSnapshot; + DWORD dwExplorerPID = 0, dwOldValue; + SIZE_T dwNumberOfBytes; + uintptr_t dwInjectedAddr = 0; + const char szPayload[6] = { NOP, NOP, NOP, NOP, NOP, NOP }; + PROCESSENTRY32 pe32 = { 0 }; + MODULEENTRY32 me32 = { 0 }; + THREADENTRY32 th32 = { 0 }; + TCHAR szExplorerPath[MAX_PATH]; + + if (install_uninstall()) + { + return 0; + } + + while (TRUE) + { + pe32.dwSize = sizeof(PROCESSENTRY32); + hSnapshot = CreateToolhelp32Snapshot( + TH32CS_SNAPPROCESS, + 0 + ); + if (Process32First(hSnapshot, &pe32) == TRUE) + { + do + { + if (!wcscmp(pe32.szExeFile, TEXT("explorer.exe"))) + { + dwExplorerPID = pe32.th32ProcessID; + DebugActiveProcess(dwExplorerPID); + break; + } + } while (Process32Next(hSnapshot, &pe32) == TRUE); + } + CloseHandle(hSnapshot); + if (!dwExplorerPID) + { + break; + } + + if ((hExplorer = OpenProcess( + PROCESS_VM_READ | + PROCESS_VM_WRITE | + PROCESS_QUERY_INFORMATION | + PROCESS_VM_OPERATION | + SYNCHRONIZE, + FALSE, + dwExplorerPID + )) != NULL && GetModuleFileNameEx( + hExplorer, + NULL, + szExplorerPath, + sizeof(szExplorerPath) + )) + { + CharLower(szExplorerPath); + me32.dwSize = sizeof(MODULEENTRY32); + hSnapshot = CreateToolhelp32Snapshot( + TH32CS_SNAPMODULE, + dwExplorerPID + ); + if (Module32First(hSnapshot, &me32) == TRUE) + { + do + { + if (!wcscmp(CharLower(me32.szExePath), szExplorerPath)) + { + dwInjectedAddr = (uintptr_t)me32.modBaseAddr + PATCH_OFFSET; + break; + } + } while (Module32Next(hSnapshot, &me32) == TRUE); + } + CloseHandle(hSnapshot); + + if (dwInjectedAddr) + { + VirtualProtectEx( + hExplorer, + (LPVOID)dwInjectedAddr, + sizeof(szPayload), + PAGE_EXECUTE_READWRITE, + &dwOldValue + ); + WriteProcessMemory( + hExplorer, + (LPVOID)dwInjectedAddr, + szPayload, + sizeof(szPayload), + &dwNumberOfBytes + ); + VirtualProtectEx( + hExplorer, + (LPVOID)dwInjectedAddr, + sizeof(szPayload), + dwOldValue, + (PDWORD)(&dwNumberOfBytes) + ); + DebugActiveProcessStop(dwExplorerPID); + /* + WaitForSingleObject( + hExplorer, + INFINITE + ); + */ + } + CloseHandle(hExplorer); + } + else + { + DebugActiveProcessStop(dwExplorerPID); + } + return 0; + } + return 0; +} \ No newline at end of file diff --git a/ExplorerPatcher/resource.h b/ExplorerPatcher/resource.h new file mode 100644 index 0000000..41050e0 --- /dev/null +++ b/ExplorerPatcher/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.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 diff --git a/ExplorerPatcher/resource.rc b/ExplorerPatcher/resource.rc new file mode 100644 index 0000000..d3cd3cd --- /dev/null +++ b/ExplorerPatcher/resource.rc @@ -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,0 + PRODUCTVERSION 22000,1,0,0 + 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", "Explorer Patcher" + VALUE "FileVersion", "22000.1.0.0" + VALUE "InternalName", "Explorer.exe" + VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved." + VALUE "OriginalFilename", "Explorer.exe" + VALUE "ProductName", "Explorer Patcher" + VALUE "ProductVersion", "22000.1.0.0" + 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 + diff --git a/README.md b/README.md index 74e5dc5..6be13ea 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,10 @@ -# ExplorerPatcher -ExplorerPatcher allows using the old taskbar in Windows 11 without the side effects of UndockingDisabled. +# Explorer Patcher +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 + +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). + +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.