Initial commit 2
This commit is contained in:
		
							parent
							
								
									32af8a2b37
								
							
						
					
					
						commit
						fd4f98e6d8
					
				
					 3 changed files with 527 additions and 1 deletions
				
			
		
							
								
								
									
										11
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								README.md
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,12 @@
 | 
			
		|||
# WindhawkMods
 | 
			
		||||
 | 
			
		||||
Mods for Windhawk
 | 
			
		||||
 | 
			
		||||
## Classic Theme Explorer
 | 
			
		||||
Classic Theme mitigations for Explorer as a Windhawk mod.
 | 
			
		||||
 | 
			
		||||
Based on [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/SimpleClassicTheme.FileExplorerHook) and the AutoHotkey scripts that came before it.
 | 
			
		||||
 | 
			
		||||
## Classic Theme Windows
 | 
			
		||||
Forces Classic Theme on all Windows
 | 
			
		||||
 | 
			
		||||
Written by WinClassic user Travis. Nothing is functionally edited here, just a bunch of sane defaults to make things work properly.
 | 
			
		||||
							
								
								
									
										456
									
								
								classic-theme-explorer.wh.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										456
									
								
								classic-theme-explorer.wh.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,456 @@
 | 
			
		|||
// ==WindhawkMod==
 | 
			
		||||
// @id              classic-theme-explorer
 | 
			
		||||
// @name            Classic Theme Explorer
 | 
			
		||||
// @description     Classic Theme mitigations for Explorer as a Windhawk mod
 | 
			
		||||
// @version         0.1
 | 
			
		||||
// @author          Cynosphere
 | 
			
		||||
// @github          https://github.com/Cynosphere
 | 
			
		||||
// @homepage        https://c7.pm/
 | 
			
		||||
// @include         explorer.exe
 | 
			
		||||
// @compilerOptions -lcomctl32
 | 
			
		||||
// ==/WindhawkMod==
 | 
			
		||||
 | 
			
		||||
// ==WindhawkModReadme==
 | 
			
		||||
/*
 | 
			
		||||
# Classic Theme Explorer
 | 
			
		||||
Classic Theme mitigations for Explorer as a Windhawk mod.
 | 
			
		||||
 | 
			
		||||
Based on [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/SimpleClassicTheme.FileExplorerHook) and the AutoHotkey scripts that came before it.
 | 
			
		||||
*/
 | 
			
		||||
// ==/WindhawkModReadme==
 | 
			
		||||
 | 
			
		||||
// ==WindhawkModSettings==
 | 
			
		||||
/*
 | 
			
		||||
- clientEdge: true
 | 
			
		||||
  $name: "Client Edge"
 | 
			
		||||
  $description: "Adds Client Edge styling"
 | 
			
		||||
- rebarBorder: true
 | 
			
		||||
  $name: "Bar Borders"
 | 
			
		||||
  $description: "Adds borders to RebarWindow32 controls"
 | 
			
		||||
- rebarFixedHeight: false
 | 
			
		||||
  $name: "Fixed Bar Height"
 | 
			
		||||
  $description: "Resizes all toolbars to the tallest bar's height"
 | 
			
		||||
- hideNavigation: true
 | 
			
		||||
  $name: "Hide Navigation"
 | 
			
		||||
  $description: "Hide default navigation for use with Classic Explorer Bar and Classic Address Bar/Quero"
 | 
			
		||||
- addressSync: true
 | 
			
		||||
  $name: "Classic Address Bar Sync"
 | 
			
		||||
  $description: "Syncs address bar location on folder change"
 | 
			
		||||
- addressSyncFullPath: true
 | 
			
		||||
  $name: "Address Sync: Use full path"
 | 
			
		||||
  $description: "Uses full path instead of folder name"
 | 
			
		||||
- addressHeight: true
 | 
			
		||||
  $name: "Classic Address Bar Height"
 | 
			
		||||
  $description: "Resizes address bar to 22px"
 | 
			
		||||
- hideRefresh: true
 | 
			
		||||
  $name: "Hide Refresh Button"
 | 
			
		||||
  $description: "Hides the refresh button from Classic Address Bar"
 | 
			
		||||
*/
 | 
			
		||||
// ==/WindhawkModSettings==
 | 
			
		||||
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#include <objbase.h>
 | 
			
		||||
#include <initguid.h>
 | 
			
		||||
#include <commctrl.h>
 | 
			
		||||
#include <dwmapi.h>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <regex>
 | 
			
		||||
#include <locale>
 | 
			
		||||
#include <codecvt>
 | 
			
		||||
 | 
			
		||||
struct {
 | 
			
		||||
    bool clientEdge;
 | 
			
		||||
    bool rebarBorder;
 | 
			
		||||
    bool rebarFixedHeight;
 | 
			
		||||
    bool hideNavigation;
 | 
			
		||||
    bool addressSync;
 | 
			
		||||
    bool addressSyncFullPath;
 | 
			
		||||
    bool addressHeight;
 | 
			
		||||
    bool hideRefresh;
 | 
			
		||||
} settings;
 | 
			
		||||
 | 
			
		||||
void LoadSettings() {
 | 
			
		||||
    settings.clientEdge = Wh_GetIntSetting(L"clientEdge");
 | 
			
		||||
    settings.rebarBorder = Wh_GetIntSetting(L"rebarBorder");
 | 
			
		||||
    settings.rebarFixedHeight = Wh_GetIntSetting(L"rebarFixedHeight");
 | 
			
		||||
    settings.hideNavigation = Wh_GetIntSetting(L"hideNavigation");
 | 
			
		||||
    settings.addressSync = Wh_GetIntSetting(L"addressSync");
 | 
			
		||||
    settings.addressSyncFullPath = Wh_GetIntSetting(L"addressSyncFullPath");
 | 
			
		||||
    settings.addressHeight = Wh_GetIntSetting(L"addressHeight");
 | 
			
		||||
    settings.hideRefresh = Wh_GetIntSetting(L"hideRefresh");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Explorer modifications
 | 
			
		||||
typedef struct EnumChildProcData
 | 
			
		||||
{
 | 
			
		||||
    HWND result;
 | 
			
		||||
    int index;
 | 
			
		||||
    int instancesFound;
 | 
			
		||||
    const wchar_t* className;
 | 
			
		||||
};
 | 
			
		||||
BOOL CALLBACK EnumChildProc(_In_ HWND hwnd, _In_ LPARAM lParam)
 | 
			
		||||
{
 | 
			
		||||
    wchar_t buffer[256];
 | 
			
		||||
    EnumChildProcData* data = (EnumChildProcData*)lParam;
 | 
			
		||||
    GetClassNameW(hwnd, buffer, 256);
 | 
			
		||||
    if (lstrcmpW(buffer, data->className) == 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (data->instancesFound + 1 == data->index)
 | 
			
		||||
        {
 | 
			
		||||
            data->result = hwnd;
 | 
			
		||||
            return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            data->instancesFound++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return TRUE;
 | 
			
		||||
};
 | 
			
		||||
HWND GetChildWindow(HWND parent, const wchar_t* className, int index)
 | 
			
		||||
{
 | 
			
		||||
    EnumChildProcData data = { 0 };
 | 
			
		||||
    data.className = className;
 | 
			
		||||
    data.index = index;
 | 
			
		||||
    EnumChildWindows(parent, EnumChildProc, (LPARAM)&data);
 | 
			
		||||
    return data.result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VOID ClassicThemeExplorer(HWND hWnd, WPARAM wParam)
 | 
			
		||||
{
 | 
			
		||||
    wchar_t classNameBuffer[256];
 | 
			
		||||
    wchar_t pathBuffer[MAX_PATH];
 | 
			
		||||
    HKEY key;
 | 
			
		||||
    RECT rect;
 | 
			
		||||
 | 
			
		||||
    HWND NavBarParent = GetChildWindow((HWND)hWnd, L"WorkerW", 1);
 | 
			
		||||
    HWND NavBarAddressBandRoot = GetChildWindow(NavBarParent, L"Address Band Root", 1);
 | 
			
		||||
    HWND NavBarToolBar = GetChildWindow(NavBarAddressBandRoot, L"ToolbarWindow32", 2);
 | 
			
		||||
    HWND ClassicAddressBandRoot = GetChildWindow((HWND)hWnd, L"Address Band Root", 2);
 | 
			
		||||
    HWND ClassicProgressControl = GetChildWindow(ClassicAddressBandRoot, L"msctls_progress32", 1);
 | 
			
		||||
    HWND ClassicComboBox = GetChildWindow(ClassicAddressBandRoot, L"ComboBoxEx32", 1);
 | 
			
		||||
    HWND ClassicRebar = GetChildWindow((HWND)hWnd, L"ReBarWindow32", 2);
 | 
			
		||||
 | 
			
		||||
    if (settings.clientEdge && (wParam == 1 || wParam == 6)) {
 | 
			
		||||
        HWND TreeView = GetChildWindow((HWND)hWnd, L"SysTreeView32", 1);
 | 
			
		||||
        LONG TreeViewExtendedStyle = GetWindowLongPtrW(TreeView, GWL_EXSTYLE);
 | 
			
		||||
        TreeViewExtendedStyle |= WS_EX_CLIENTEDGE;
 | 
			
		||||
        SetWindowLongPtrW(TreeView, GWL_EXSTYLE, TreeViewExtendedStyle);
 | 
			
		||||
 | 
			
		||||
        HWND FolderView = GetChildWindow((HWND)hWnd, L"FolderView", 1);
 | 
			
		||||
        LONG FolderViewExtendedStyle = GetWindowLongPtrW(FolderView, GWL_EXSTYLE);
 | 
			
		||||
        FolderViewExtendedStyle |= WS_EX_CLIENTEDGE;
 | 
			
		||||
        SetWindowLongPtrW(FolderView, GWL_EXSTYLE, FolderViewExtendedStyle);
 | 
			
		||||
 | 
			
		||||
        HWND ShellTabWindowClass = GetChildWindow((HWND)hWnd, L"ShellTabWindowClass", 1);
 | 
			
		||||
        GetWindowRect(ShellTabWindowClass, &rect);
 | 
			
		||||
        SetWindowPos(ShellTabWindowClass, NULL, NULL, NULL, rect.right - rect.left + 1, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE);
 | 
			
		||||
        SetWindowPos(ShellTabWindowClass, NULL, NULL, NULL, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (settings.rebarBorder && (wParam == 1 || wParam == 6)) {
 | 
			
		||||
        LONG ClassicRebarStyle = GetWindowLongPtrW(ClassicRebar, GWL_STYLE);
 | 
			
		||||
        ClassicRebarStyle |= RBS_BANDBORDERS;
 | 
			
		||||
        ClassicRebarStyle |= WS_BORDER;
 | 
			
		||||
        SetWindowLongPtrW(ClassicRebar, GWL_STYLE, ClassicRebarStyle);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (settings.rebarFixedHeight && (wParam == 1 || wParam == 6)) {
 | 
			
		||||
        LONG ClassicRebarStyle = GetWindowLongPtrW(ClassicRebar, GWL_STYLE);
 | 
			
		||||
        ClassicRebarStyle &= ~RBS_VARHEIGHT;
 | 
			
		||||
        SetWindowLongPtrW(ClassicRebar, GWL_STYLE, ClassicRebarStyle);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Apply bar changes
 | 
			
		||||
    if ((settings.rebarBorder || settings.rebarFixedHeight) && (wParam == 1 || wParam == 6)) {
 | 
			
		||||
        GetWindowRect(ClassicRebar, &rect);
 | 
			
		||||
        SetWindowPos(ClassicRebar, NULL, NULL, NULL, rect.right - rect.left + 1, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE);
 | 
			
		||||
        SetWindowPos(ClassicRebar, NULL, NULL, NULL, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (settings.hideNavigation && wParam == 1) {
 | 
			
		||||
        // Save the location of the Rebar
 | 
			
		||||
        HWND NavBarRebar = GetChildWindow((HWND)hWnd, L"ReBarWindow32", 1);
 | 
			
		||||
        GetWindowRect(NavBarRebar, &rect);
 | 
			
		||||
        LONG xRebar = rect.left;
 | 
			
		||||
        LONG yRebar = rect.top;
 | 
			
		||||
        LONG cxRebar = rect.right - rect.left;
 | 
			
		||||
        LONG cyRebar = rect.bottom - rect.top;
 | 
			
		||||
 | 
			
		||||
        // Destroy the NC area of the rebar
 | 
			
		||||
        SendMessageW(NavBarRebar, WM_NCDESTROY, 0, 0);
 | 
			
		||||
 | 
			
		||||
        // Hide the WorkerW and the Rebar
 | 
			
		||||
        ShowWindow(NavBarParent, SW_HIDE);
 | 
			
		||||
        ShowWindow(NavBarRebar, SW_HIDE);
 | 
			
		||||
 | 
			
		||||
        // Save the location of the ShellTabWindowClass
 | 
			
		||||
        HWND ShellTabWnd = GetChildWindow((HWND)hWnd, L"ShellTabWindowClass", 1);
 | 
			
		||||
        GetWindowRect(NavBarRebar, &rect);
 | 
			
		||||
        LONG xTabWnd = rect.left;
 | 
			
		||||
        LONG yTabWnd = rect.top;
 | 
			
		||||
        LONG cxTabWnd = rect.right - rect.left;
 | 
			
		||||
        LONG cyTabWnd = rect.bottom - rect.top;
 | 
			
		||||
 | 
			
		||||
        // Move ShellTabWindow to (*; yRebar; *; yTabWnd - yRebar + cyTabWnd)
 | 
			
		||||
        SetWindowPos(ShellTabWnd, NULL, xTabWnd, yRebar, cxTabWnd, yTabWnd - yRebar + cyTabWnd, SWP_NOZORDER);
 | 
			
		||||
 | 
			
		||||
        // Move Rebar to (*; *; *; 0)
 | 
			
		||||
        SetWindowPos(NavBarRebar, NULL, xRebar, yRebar, cxRebar, 0, SWP_NOZORDER);
 | 
			
		||||
 | 
			
		||||
        // Resize the window to apply
 | 
			
		||||
        GetWindowRect((HWND)hWnd, &rect);
 | 
			
		||||
        SetWindowPos((HWND)hWnd, NULL, NULL, NULL, rect.right - rect.left, rect.bottom - rect.top + 1, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE);
 | 
			
		||||
        SetWindowPos((HWND)hWnd, NULL, NULL, NULL, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE);
 | 
			
		||||
 | 
			
		||||
        // Redraw the entire explorer window
 | 
			
		||||
        RedrawWindow((HWND)hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW | RDW_UPDATENOW | RDW_ALLCHILDREN);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (settings.addressSync) {
 | 
			
		||||
        if (settings.addressSyncFullPath) {
 | 
			
		||||
            HWND toolbarwindow = GetChildWindow(NavBarAddressBandRoot, L"ToolbarWindow32", 1);
 | 
			
		||||
            GetWindowTextW(toolbarwindow, pathBuffer, MAX_PATH);
 | 
			
		||||
 | 
			
		||||
            // remove "Address: "
 | 
			
		||||
            // FIXME: locale issues, codecvt deprecated as of c++17
 | 
			
		||||
            std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
 | 
			
		||||
 | 
			
		||||
            std::wstring _pathStr = pathBuffer;
 | 
			
		||||
            std::string pathStr(_pathStr.begin(), _pathStr.end());
 | 
			
		||||
            pathStr = std::regex_replace(pathStr, std::regex("Address: "), "");
 | 
			
		||||
            _pathStr = converter.from_bytes(pathStr);
 | 
			
		||||
            wcscpy(pathBuffer, _pathStr.c_str());
 | 
			
		||||
        } else {
 | 
			
		||||
            HWND shelltabwindow = GetChildWindow((HWND)hWnd, L"ShellTabWindowClass", 1);
 | 
			
		||||
            GetWindowTextW(shelltabwindow, pathBuffer, MAX_PATH);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        HWND AddressBarEdit = GetChildWindow(ClassicAddressBandRoot, L"Edit", 1);
 | 
			
		||||
        for (int i = 0; i < 3; i++)
 | 
			
		||||
            SendMessageW(AddressBarEdit, WM_SETTEXT, 0, (LPARAM)pathBuffer);
 | 
			
		||||
 | 
			
		||||
        // TODO: figure out how to get and set folder icon
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (settings.hideRefresh && (wParam == 1 || wParam == 6)) {
 | 
			
		||||
        HWND GoButtonToolbar = GetChildWindow(ClassicAddressBandRoot, L"ToolbarWindow32", 1);
 | 
			
		||||
        SendMessageW(GoButtonToolbar, WM_CLOSE, 0, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (settings.addressHeight) {
 | 
			
		||||
        // Allocate memory inside Explorer
 | 
			
		||||
        DWORD count = SendMessage(GetParent(ClassicAddressBandRoot), RB_GETBANDCOUNT, 0, 0);
 | 
			
		||||
        SIZE_T bytesRead = 0;
 | 
			
		||||
        DWORD ExplorerPID = 0;
 | 
			
		||||
        GetWindowThreadProcessId(ClassicAddressBandRoot, &ExplorerPID);
 | 
			
		||||
        HANDLE ExplorerProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ExplorerPID);
 | 
			
		||||
        void* ExplorerMemoryRebar = VirtualAllocEx(ExplorerProcess, NULL, sizeof(REBARBANDINFO), MEM_COMMIT, PAGE_READWRITE);
 | 
			
		||||
        void* ExplorerMemoryComboBoxItem = VirtualAllocEx(ExplorerProcess, NULL, sizeof(COMBOBOXEXITEM), MEM_COMMIT, PAGE_READWRITE);
 | 
			
		||||
        void* ExplorerMemoryToolbarButton = VirtualAllocEx(ExplorerProcess, NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE);
 | 
			
		||||
 | 
			
		||||
        // Make the band that's 39 pixels high, 22 pixels high
 | 
			
		||||
        // MOD: Except this bar isn't always 39 pixels, so lets check between 39-23px instead
 | 
			
		||||
        REBARBANDINFO bandInfo = { 0 };
 | 
			
		||||
        for (int i = 0; i < count; i++)
 | 
			
		||||
        {
 | 
			
		||||
            bandInfo = { 0 };
 | 
			
		||||
            bandInfo.cbSize = sizeof(REBARBANDINFO);
 | 
			
		||||
            bandInfo.fMask = RBBIM_CHILDSIZE;
 | 
			
		||||
            WriteProcessMemory(ExplorerProcess, ExplorerMemoryRebar, &bandInfo, sizeof(REBARBANDINFO), &bytesRead);
 | 
			
		||||
            SendMessageW(GetParent(ClassicAddressBandRoot), RB_GETBANDINFO, i, (LPARAM)ExplorerMemoryRebar);
 | 
			
		||||
            ReadProcessMemory(ExplorerProcess, ExplorerMemoryRebar, &bandInfo, sizeof(REBARBANDINFO), &bytesRead);
 | 
			
		||||
            if (bandInfo.cyMinChild <= 39 && bandInfo.cyMinChild > 22) {
 | 
			
		||||
                bandInfo.cyMinChild = 22;
 | 
			
		||||
                WriteProcessMemory(ExplorerProcess, ExplorerMemoryRebar, &bandInfo, sizeof(REBARBANDINFO), &bytesRead);
 | 
			
		||||
                SendMessageW(GetParent(ClassicAddressBandRoot), RB_SETBANDINFO, i, (LPARAM)ExplorerMemoryRebar);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Free Explorer Memory
 | 
			
		||||
        VirtualFreeEx(ExplorerProcess, ExplorerMemoryRebar, sizeof(REBARBANDINFO), MEM_DECOMMIT);
 | 
			
		||||
        VirtualFreeEx(ExplorerProcess, ExplorerMemoryToolbarButton, sizeof(REBARBANDINFO), MEM_DECOMMIT);
 | 
			
		||||
        CloseHandle(ExplorerProcess);
 | 
			
		||||
        
 | 
			
		||||
        // Set ComboBox height
 | 
			
		||||
        SendMessageW(ClassicComboBox, CB_SETITEMHEIGHT, -1, 22 - 6);
 | 
			
		||||
        SetParent(ClassicComboBox, ClassicAddressBandRoot);
 | 
			
		||||
        
 | 
			
		||||
        // Remove ProgressBsr
 | 
			
		||||
        SendMessageW(ClassicProgressControl, WM_CLOSE, 0, 0);
 | 
			
		||||
 | 
			
		||||
        // Fix ComboBox
 | 
			
		||||
        GetWindowRect(ClassicComboBox, &rect);
 | 
			
		||||
        SetWindowPos(ClassicComboBox, NULL, NULL, NULL, rect.right - rect.left + 1, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE);
 | 
			
		||||
        SetWindowPos(ClassicComboBox, NULL, NULL, NULL, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE);
 | 
			
		||||
 | 
			
		||||
        // Redraw the ComboBox
 | 
			
		||||
        RedrawWindow(ClassicComboBox, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW | RDW_UPDATENOW | RDW_ALLCHILDREN);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// boilerplate from hide-search-bar
 | 
			
		||||
#if defined(__GNUC__) && __GNUC__ > 8
 | 
			
		||||
#define WINAPI_LAMBDA_RETURN(return_t) -> return_t WINAPI
 | 
			
		||||
#elif defined(__GNUC__)
 | 
			
		||||
#define WINAPI_LAMBDA_RETURN(return_t) WINAPI -> return_t
 | 
			
		||||
#else
 | 
			
		||||
#define WINAPI_LAMBDA_RETURN(return_t) -> return_t
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
DWORD g_uiThreadId;
 | 
			
		||||
 | 
			
		||||
inline LSTATUS SHRegGetValueFromHKCUHKLMWithOpt(PCWSTR pwszKey, PCWSTR pwszValue, REGSAM samDesired, void* pvData, DWORD* pcbData)
 | 
			
		||||
{
 | 
			
		||||
    LSTATUS lRes = ERROR_FILE_NOT_FOUND;
 | 
			
		||||
    HKEY hKey = NULL;
 | 
			
		||||
 | 
			
		||||
    RegOpenKeyExW(HKEY_CURRENT_USER, pwszKey, 0, samDesired, &hKey);
 | 
			
		||||
    if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) hKey = NULL;
 | 
			
		||||
    if (hKey)
 | 
			
		||||
    {
 | 
			
		||||
        lRes = RegQueryValueExW(hKey, pwszValue, 0, NULL, (LPBYTE) pvData, (LPDWORD) pcbData);
 | 
			
		||||
 | 
			
		||||
        RegCloseKey(hKey);
 | 
			
		||||
        if (lRes == ERROR_SUCCESS || lRes == ERROR_MORE_DATA) return lRes;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    RegOpenKeyExW(HKEY_LOCAL_MACHINE, pwszKey, 0, samDesired, &hKey);
 | 
			
		||||
    if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) hKey = NULL;
 | 
			
		||||
 | 
			
		||||
    if (hKey)
 | 
			
		||||
    {
 | 
			
		||||
        lRes = RegQueryValueExW(hKey, pwszValue, 0, NULL, (LPBYTE) pvData, (LPDWORD) pcbData);
 | 
			
		||||
        RegCloseKey(hKey);
 | 
			
		||||
 | 
			
		||||
        if (lRes == ERROR_SUCCESS || lRes == ERROR_MORE_DATA) return lRes;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return lRes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UINT g_subclassRegisteredMsg = RegisterWindowMessage(L"Windhawk_SetWindowSubclassFromAnyThread_classic-theme-explorer");
 | 
			
		||||
 | 
			
		||||
LRESULT CALLBACK ClassicThemeExplorerSubClass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {
 | 
			
		||||
    if (uMsg == WM_DESTROY) {
 | 
			
		||||
        Wh_Log("[Destroy] uMsg: 0x%04x, wParam: 0x%x", uMsg, wParam);
 | 
			
		||||
        RemoveWindowSubclass(hWnd, ClassicThemeExplorerSubClass, 0);
 | 
			
		||||
    } else if (uMsg == g_subclassRegisteredMsg && !wParam) {
 | 
			
		||||
        Wh_Log("[Unsub] uMsg: 0x%04x, wParam: 0x%x", uMsg, wParam);
 | 
			
		||||
        RemoveWindowSubclass(hWnd, ClassicThemeExplorerSubClass, 0);
 | 
			
		||||
    } else if (uMsg == WM_PARENTNOTIFY || uMsg == WM_SIZE || uMsg == WM_GETICON) {
 | 
			
		||||
        Wh_Log("[Target] uMsg: 0x%04x, wParam: 0x%x", uMsg, wParam);
 | 
			
		||||
        ClassicThemeExplorer(hWnd, wParam);
 | 
			
		||||
    } else {
 | 
			
		||||
        Wh_Log("[Unknown] uMsg: 0x%04x, wParam: 0x%x", uMsg, wParam);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return DefSubclassProc(hWnd, uMsg, wParam, lParam);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct SET_WINDOW_SUBCLASS_FROM_ANY_THREAD_PARAM {
 | 
			
		||||
    SUBCLASSPROC pfnSubclass;
 | 
			
		||||
    UINT_PTR uIdSubclass;
 | 
			
		||||
    DWORD_PTR dwRefData;
 | 
			
		||||
    BOOL result;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
LRESULT CALLBACK CallWndProcForWindowSubclass(int nCode, WPARAM wParam, LPARAM lParam) {
 | 
			
		||||
    if (nCode == HC_ACTION) {
 | 
			
		||||
        const CWPSTRUCT* cwp = (const CWPSTRUCT*)lParam;
 | 
			
		||||
        if (cwp->message == g_subclassRegisteredMsg && cwp->wParam) {
 | 
			
		||||
            SET_WINDOW_SUBCLASS_FROM_ANY_THREAD_PARAM* param = (SET_WINDOW_SUBCLASS_FROM_ANY_THREAD_PARAM*)cwp->lParam;
 | 
			
		||||
            param->result = SetWindowSubclass(cwp->hwnd, param->pfnSubclass, param->uIdSubclass, param->dwRefData);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return CallNextHookEx(nullptr, nCode, wParam, lParam);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL SetWindowSubclassFromAnyThread(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {
 | 
			
		||||
    DWORD dwThreadId = GetWindowThreadProcessId(hWnd, nullptr);
 | 
			
		||||
    
 | 
			
		||||
    if (dwThreadId == 0) return FALSE;
 | 
			
		||||
    if (dwThreadId == GetCurrentThreadId()) return SetWindowSubclass(hWnd, pfnSubclass, uIdSubclass, dwRefData);
 | 
			
		||||
 | 
			
		||||
    HHOOK hook = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProcForWindowSubclass, nullptr, dwThreadId);
 | 
			
		||||
 | 
			
		||||
    if (!hook) return FALSE;
 | 
			
		||||
 | 
			
		||||
    SET_WINDOW_SUBCLASS_FROM_ANY_THREAD_PARAM param;
 | 
			
		||||
    param.pfnSubclass = pfnSubclass;
 | 
			
		||||
    param.uIdSubclass = uIdSubclass;
 | 
			
		||||
    param.dwRefData = dwRefData;
 | 
			
		||||
    param.result = FALSE;
 | 
			
		||||
    
 | 
			
		||||
    SendMessage(hWnd, g_subclassRegisteredMsg, TRUE, (WPARAM)¶m);
 | 
			
		||||
 | 
			
		||||
    UnhookWindowsHookEx(hook);
 | 
			
		||||
 | 
			
		||||
    return param.result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL CALLBACK EnumBrowserWindowsUnsubclassFunc(HWND hWnd, LPARAM lParam) {
 | 
			
		||||
    SendMessage(hWnd, g_subclassRegisteredMsg, FALSE, 0);
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
HWND(WINAPI *pOriginalSHCreateWorkerWindow)(WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle, DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra);
 | 
			
		||||
 | 
			
		||||
HWND WINAPI SHCreateWorkerWindowHook(WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle, DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra)
 | 
			
		||||
{
 | 
			
		||||
    HWND result;
 | 
			
		||||
    LSTATUS lRes = ERROR_FILE_NOT_FOUND;
 | 
			
		||||
    DWORD dwSize = 0;
 | 
			
		||||
 | 
			
		||||
    //Wh_Log("g_uiThreadId: %d, GetCurrentThreadId: %d", g_uiThreadId, GetCurrentThreadId());
 | 
			
		||||
 | 
			
		||||
    // is this even needed? it changes thread after some time anyways
 | 
			
		||||
    //if (g_uiThreadId && g_uiThreadId != GetCurrentThreadId()) return pOriginalSHCreateWorkerWindow(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, wnd_extra);
 | 
			
		||||
    /*if (!g_uiThreadId)*/ g_uiThreadId = GetCurrentThreadId();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if (SHRegGetValueFromHKCUHKLMWithOpt(
 | 
			
		||||
        TEXT("SOFTWARE\\Classes\\CLSID\\{056440FD-8568-48e7-A632-72157243B55B}\\InProcServer32"),
 | 
			
		||||
        TEXT(""),
 | 
			
		||||
        KEY_READ | KEY_WOW64_64KEY,
 | 
			
		||||
        NULL,
 | 
			
		||||
        (LPDWORD)(&dwSize)
 | 
			
		||||
    ) == ERROR_SUCCESS && (dwSize < 4) && dwExStyle == 0x10000 && dwStyle == 1174405120) result = 0;
 | 
			
		||||
 | 
			
		||||
    else result = pOriginalSHCreateWorkerWindow(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, wnd_extra);
 | 
			
		||||
 | 
			
		||||
    //Wh_Log("dwExStyle: 0x%x, dwStyle: 0x%x, result: 0x%x", dwExStyle, dwStyle, result);
 | 
			
		||||
 | 
			
		||||
    if (dwExStyle == 0x10000 && dwStyle == 0x46000000 && result) SetWindowSubclassFromAnyThread(hWndParent, ClassicThemeExplorerSubClass, 0, 0);
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Windhawk boilerplate
 | 
			
		||||
BOOL Wh_ModInit() {
 | 
			
		||||
    Wh_Log(L"Init");
 | 
			
		||||
 | 
			
		||||
    LoadSettings();
 | 
			
		||||
 | 
			
		||||
    HMODULE hShcore = GetModuleHandle(L"shcore.dll");
 | 
			
		||||
 | 
			
		||||
    void* origFunc = (void*)GetProcAddress(hShcore, (LPCSTR)188);
 | 
			
		||||
    Wh_SetFunctionHook(origFunc, (void*)SHCreateWorkerWindowHook, (void**)&pOriginalSHCreateWorkerWindow);
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Wh_ModUninit() {
 | 
			
		||||
    Wh_Log(L"Uninit");
 | 
			
		||||
 | 
			
		||||
    if (g_uiThreadId != 0) EnumThreadWindows(g_uiThreadId, EnumBrowserWindowsUnsubclassFunc, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Wh_ModSettingsChanged() {
 | 
			
		||||
    Wh_Log(L"SettingsChanged");
 | 
			
		||||
 | 
			
		||||
    LoadSettings();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								classic-theme-windows.wh.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								classic-theme-windows.wh.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
// ==WindhawkMod==
 | 
			
		||||
// @id              classic-theme-windows
 | 
			
		||||
// @name            Classic Theme Windows
 | 
			
		||||
// @description     Forces Classic Theme on all Windows
 | 
			
		||||
// @version         0.1
 | 
			
		||||
// @author          Travis
 | 
			
		||||
// @include         *
 | 
			
		||||
// @exclude         wininit.exe
 | 
			
		||||
// @exclude         winlogon.exe
 | 
			
		||||
// @exclude         taskmgr.exe
 | 
			
		||||
// @exclude         dwm.exe
 | 
			
		||||
// @exclude         thunderbird.exe
 | 
			
		||||
// @exclude         dwm.exe
 | 
			
		||||
// @exclude         C:\Windows\System32\*.scr
 | 
			
		||||
// @exclude         svchost.exe
 | 
			
		||||
// @exclude         taskhostw.exe
 | 
			
		||||
// @exclude         dllhost.exe
 | 
			
		||||
// @exclude         conhost.exe
 | 
			
		||||
// @exclude         sihost.exe
 | 
			
		||||
// @exclude         lsass.exe
 | 
			
		||||
// @exclude         C:\Program Files (x86)\Steam\*
 | 
			
		||||
// @exclude         Code.exe
 | 
			
		||||
// @exclude         Code - Insiders.exe
 | 
			
		||||
// @exclude         msedge.exe
 | 
			
		||||
// @exclude         iexplorer.exe
 | 
			
		||||
// @exclude         vmware.exe
 | 
			
		||||
// @exclude         vmware-vmx.exe
 | 
			
		||||
// @exclude         rundll32.exe
 | 
			
		||||
// @exclude         Spotify.exe
 | 
			
		||||
// @exclude         smartscreen.exe
 | 
			
		||||
// @exclude         RuntimeBroker.exe
 | 
			
		||||
// @exclude         ApplicationFrameHost.exe
 | 
			
		||||
// @exclude         SystemSettings.exe
 | 
			
		||||
// @exclude         SecHealthUI.exe
 | 
			
		||||
// @exclude         SecurityHealthHost.exe
 | 
			
		||||
// @exclude         PhoneExperienceHost.exe
 | 
			
		||||
// @exclude         SecurityHealthTray.exe
 | 
			
		||||
// @exclude         Window Detective.exe
 | 
			
		||||
// @exclude         Discord.exe
 | 
			
		||||
// @exclude         DiscordPTB.exe
 | 
			
		||||
// @exclude         DiscordCanary.exe
 | 
			
		||||
// @exclude         DiscordDevelopment.exe
 | 
			
		||||
// @compilerOptions -luxtheme
 | 
			
		||||
// ==/WindhawkMod==
 | 
			
		||||
 | 
			
		||||
// ==WindhawkModReadme==
 | 
			
		||||
/*
 | 
			
		||||
# Classic Theme Windows
 | 
			
		||||
Forces Classic Theme on all Windows
 | 
			
		||||
*/
 | 
			
		||||
// ==/WindhawkModReadme==
 | 
			
		||||
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#include <uxtheme.h>
 | 
			
		||||
 | 
			
		||||
BOOL Wh_ModInit() {
 | 
			
		||||
    Wh_Log(L"Init");
 | 
			
		||||
 | 
			
		||||
    SetThemeAppProperties(0);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue