From c4d84e84cee8cd9648548f2989aadaa43f98f80d Mon Sep 17 00:00:00 2001 From: Cynthia Foxwell Date: Thu, 30 Mar 2023 20:40:17 -0600 Subject: [PATCH] Classic Theme Windows: try 3 of dwm disabler, actually stable this time --- classic-theme-windows.wh.cpp | 147 ++++++++++++++++++++++++++--------- 1 file changed, 110 insertions(+), 37 deletions(-) diff --git a/classic-theme-windows.wh.cpp b/classic-theme-windows.wh.cpp index bdce86f..4eebb94 100644 --- a/classic-theme-windows.wh.cpp +++ b/classic-theme-windows.wh.cpp @@ -30,7 +30,7 @@ // @exclude PhoneExperienceHost.exe // @exclude SecurityHealthTray.exe // @exclude Window Detective.exe -// @compilerOptions -luxtheme -ldwmapi -lole32 -lcomdlg32 +// @compilerOptions -luxtheme -ldwmapi -lole32 -lcomdlg32 -lcomctl32 // ==/WindhawkMod== // ==WindhawkModReadme== @@ -43,63 +43,134 @@ Forces Classic Theme on all Windows #include #include #include - -DWORD thisPid = -1; +#include // BasicThemer2 reimplementation to render classic titlebars -/*static const int DisableDWM = DWMNCRP_DISABLED; +static const int DisableDWM = DWMNCRP_DISABLED; static const int EnableDWM = DWMNCRP_ENABLED; -void BasicThemerEnable(HWND hwnd) { +void DisableDWMForHwnd(HWND hwnd) { DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &DisableDWM, sizeof(int)); } -void BasicThemerDisable(HWND hwnd) { +void EnableDWMForHwnd(HWND hwnd) { DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &EnableDWM, sizeof(int)); } +DWORD g_uiThreadId; + +BOOL CALLBACK DisableDWMForAll(HWND hWnd, LPARAM lParam) { + DWORD dwProcessId = 0; + DWORD dwThreadId = GetWindowThreadProcessId(hWnd, &dwProcessId); + if (!dwThreadId || dwProcessId != GetCurrentProcessId()) { + return TRUE; + } + + if (g_uiThreadId && g_uiThreadId != dwThreadId) { + return TRUE; + } + + if (IsWindow(hWnd)) { + Wh_Log(L"[Init] Window found: %08X", (DWORD)(ULONG_PTR)hWnd); + + if (!g_uiThreadId) { + g_uiThreadId = dwThreadId; + } + + DisableDWMForHwnd(hWnd); + } + + return TRUE; +} + +BOOL CALLBACK EnableDWMForAll(HWND hWnd, LPARAM lParam) { + DWORD dwProcessId = 0; + DWORD dwThreadId = GetWindowThreadProcessId(hWnd, &dwProcessId); + if (!dwThreadId || dwProcessId != GetCurrentProcessId()) { + return TRUE; + } + + if (g_uiThreadId && g_uiThreadId != dwThreadId) { + return TRUE; + } + + if (IsWindow(hWnd)) { + Wh_Log(L"[Cleanup] Window found: %08X", (DWORD)(ULONG_PTR)hWnd); + + if (!g_uiThreadId) { + g_uiThreadId = dwThreadId; + } + + EnableDWMForHwnd(hWnd); + } + + return TRUE; +} + using CreateWindowExW_t = decltype(&CreateWindowExW); CreateWindowExW_t CreateWindowExW_Orig; HWND WINAPI CreateWindowExW_Hook(DWORD dwExStyle,LPCWSTR lpClassName,LPCWSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam) { - HWND res = CreateWindowExW_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam); + HWND hWnd = CreateWindowExW_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam); - if (thisPid != -1) { - DWORD targetPid; - GetWindowThreadProcessId(res, &targetPid); - if (targetPid == thisPid) { - BasicThemerEnable(res); - } + if (!hWnd) { + return hWnd; } - return res; + if (g_uiThreadId && g_uiThreadId != GetCurrentThreadId()) { + return hWnd; + } + + if (IsWindow(hWnd)) { + Wh_Log(L"[CreateWindowExW] Window created: %08X", (DWORD)(ULONG_PTR)hWnd); + + if (!g_uiThreadId) { + g_uiThreadId = GetCurrentThreadId(); + } + + DisableDWMForHwnd(hWnd); + EnumWindows(DisableDWMForAll, 0); + } + + return hWnd; } using CreateWindowExA_t = decltype(&CreateWindowExA); CreateWindowExA_t CreateWindowExA_Orig; HWND WINAPI CreateWindowExA_Hook(DWORD dwExStyle,LPCSTR lpClassName,LPCSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam) { - HWND res = CreateWindowExA_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam); + HWND hWnd = CreateWindowExA_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam); - if (thisPid != -1) { - DWORD targetPid; - GetWindowThreadProcessId(res, &targetPid); - if (targetPid == thisPid) { - BasicThemerEnable(res); - } + if (!hWnd) { + return hWnd; } - return res; + if (g_uiThreadId && g_uiThreadId != GetCurrentThreadId()) { + return hWnd; + } + + if (IsWindow(hWnd)) { + Wh_Log(L"[CreateWindowExA] Window created: %08X", (DWORD)(ULONG_PTR)hWnd); + + if (!g_uiThreadId) { + g_uiThreadId = GetCurrentThreadId(); + } + + DisableDWMForHwnd(hWnd); + EnumWindows(DisableDWMForAll, 0); + } + + return hWnd; } -BOOL CALLBACK EnableBasicThemerForAll(HWND hWnd, LPARAM lParam) { - if (IsWindow(hWnd)) - BasicThemerEnable(hWnd); +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 = pOriginalSHCreateWorkerWindow(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, wnd_extra); - return TRUE; + if (dwExStyle == 0x10000 && dwStyle == 0x46000000 && result) { + DisableDWMForHwnd(hWndParent); + EnumWindows(DisableDWMForAll, 0); + } + + return result; } -BOOL CALLBACK DisableBasicThemerForAll(HWND hWnd, LPARAM lParam) { - if (IsWindow(hWnd)) - BasicThemerDisable(hWnd); - - return TRUE; -}*/ // File picker template @@ -134,16 +205,19 @@ BOOL Wh_ModInit() { SetThemeAppProperties(0); // BasicThemer hooks - /*Wh_SetFunctionHook((void*)CreateWindowExW, + Wh_SetFunctionHook((void*)CreateWindowExW, (void*)CreateWindowExW_Hook, (void**)&CreateWindowExW_Orig); Wh_SetFunctionHook((void*)CreateWindowExA, (void*)CreateWindowExA_Hook, (void**)&CreateWindowExA_Orig); + HMODULE hShcore = GetModuleHandle(L"shcore.dll"); + void* origFunc = (void*)GetProcAddress(hShcore, (LPCSTR)188); + Wh_SetFunctionHook(origFunc, (void*)SHCreateWorkerWindowHook, (void**)&pOriginalSHCreateWorkerWindow); + // Iterate every window to enable BasicThemer - thisPid = GetProcessIdOfThread(GetCurrentThread()); - EnumWindows(EnableBasicThemerForAll, thisPid);*/ + EnumWindows(DisableDWMForAll, 0); // File picker Wh_SetFunctionHook((void*)CoCreateInstance, (void*)CoCreateInstance_Hook, @@ -159,6 +233,5 @@ void Wh_ModUninit() { } // Iterate every window to disable BasicThemer - /*thisPid = GetProcessIdOfThread(GetCurrentThread()); - EnumWindows(DisableBasicThemerForAll, thisPid);*/ + EnumWindows(EnableDWMForAll, 0); } \ No newline at end of file