Compare commits

..

4 commits

3 changed files with 486 additions and 46 deletions

View file

@ -4,12 +4,12 @@ Mods for Windhawk
## Classic Theme Explorer ## Classic Theme Explorer
Classic Theme mitigations for Explorer as a Windhawk mod. 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. Based on [ExplorerPatcher](https://github.com/valinet/ExplorerPatcher), [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/SimpleClassicTheme.FileExplorerHook) and the AutoHotkey scripts that came before it.
## Classic Theme Windows ## Classic Theme Windows
Forces Classic Theme on all Windows Forces Classic Theme on all Windows
Originally written by WinClassic user Travis. Added DWM disabler from BasicThemer2 for classic titlebars and Classic File Picker. Originally written by WinClassic user Travis. Added DWM disabler ala BasicThemer2 for classic titlebars and Classic File Picker.
## ~~Classic File Picker~~ ## ~~Classic File Picker~~
~~Restores pre-Vista file picker. Requires Classic Theme Windows mod or else Windows just upgrades the dialog.~~ ~~Restores pre-Vista file picker. Requires Classic Theme Windows mod or else Windows just upgrades the dialog.~~

View file

@ -7,7 +7,7 @@
// @github https://github.com/Cynosphere // @github https://github.com/Cynosphere
// @homepage https://c7.pm/ // @homepage https://c7.pm/
// @include explorer.exe // @include explorer.exe
// @compilerOptions -lcomctl32 // @compilerOptions -lcomctl32 -luxtheme -lgdi32
// ==/WindhawkMod== // ==/WindhawkMod==
// ==WindhawkModReadme== // ==WindhawkModReadme==
@ -15,7 +15,7 @@
# Classic Theme Explorer # Classic Theme Explorer
Classic Theme mitigations for Explorer as a Windhawk mod. 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. Based on [ExplorerPatcher](https://github.com/valinet/ExplorerPatcher), [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/SimpleClassicTheme.FileExplorerHook) and the AutoHotkey scripts that came before it.
*/ */
// ==/WindhawkModReadme== // ==/WindhawkModReadme==
@ -45,6 +45,9 @@ Based on [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/S
- hideRefresh: true - hideRefresh: true
$name: "Hide Refresh Button" $name: "Hide Refresh Button"
$description: "Hides the refresh button from Classic Address Bar" $description: "Hides the refresh button from Classic Address Bar"
- epMitigate: true
$name: "ExplorerPatcher's Mitigations"
$description: "ExplorerPatcher's Mitigations"
*/ */
// ==/WindhawkModSettings== // ==/WindhawkModSettings==
@ -53,6 +56,9 @@ Based on [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/S
#include <initguid.h> #include <initguid.h>
#include <commctrl.h> #include <commctrl.h>
#include <dwmapi.h> #include <dwmapi.h>
#include <uxtheme.h>
#include <wingdi.h>
#include <string> #include <string>
#include <regex> #include <regex>
#include <locale> #include <locale>
@ -67,6 +73,7 @@ struct {
bool addressSyncFullPath; bool addressSyncFullPath;
bool addressHeight; bool addressHeight;
bool hideRefresh; bool hideRefresh;
bool epMitigate;
} settings; } settings;
void LoadSettings() { void LoadSettings() {
@ -78,6 +85,7 @@ void LoadSettings() {
settings.addressSyncFullPath = Wh_GetIntSetting(L"addressSyncFullPath"); settings.addressSyncFullPath = Wh_GetIntSetting(L"addressSyncFullPath");
settings.addressHeight = Wh_GetIntSetting(L"addressHeight"); settings.addressHeight = Wh_GetIntSetting(L"addressHeight");
settings.hideRefresh = Wh_GetIntSetting(L"hideRefresh"); settings.hideRefresh = Wh_GetIntSetting(L"hideRefresh");
settings.epMitigate = Wh_GetIntSetting(L"epMitigate");
} }
// Explorer modifications // Explorer modifications
@ -457,28 +465,387 @@ HWND WINAPI SHCreateWorkerWindowHook(WNDPROC wndProc, HWND hWndParent, DWORD dwE
return result; return result;
} }
// taskbar fixes from ExplorerPatcher
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) {
if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"TrayNotifyWnd"))
{
dwExStyle |= WS_EX_STATICEDGE;
}
if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"NotifyIconOverflowWindow"))
{
dwExStyle |= WS_EX_STATICEDGE;
}
if (settings.clientEdge && (*((WORD*)&(lpClassName)+1)) && (!wcscmp(lpClassName, L"SysListView32") || !wcscmp(lpClassName, L"SysTreeView32"))) // !wcscmp(lpClassName, L"FolderView")
{
wchar_t wszClassName[200];
ZeroMemory(wszClassName, 200);
GetClassNameW(GetAncestor(hWndParent, GA_ROOT), wszClassName, 200);
if (!wcscmp(wszClassName, L"CabinetWClass"))
{
dwExStyle |= WS_EX_CLIENTEDGE;
}
}
if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"ReBarWindow32"))
{
wchar_t wszClassName[200];
ZeroMemory(wszClassName, 200);
GetClassNameW(hWndParent, wszClassName, 200);
if (!wcscmp(wszClassName, L"Shell_TrayWnd"))
{
dwStyle |= RBS_BANDBORDERS;
}
}
HWND hWnd = CreateWindowExW_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam);
return hWnd;
}
using SetWindowLongPtrW_t = decltype(&SetWindowLongPtrW);
SetWindowLongPtrW_t SetWindowLongPtrW_Orig;
LONG_PTR SetWindowLongPtrW_Hook(HWND hWnd, int nIndex, LONG_PTR dwNewLong) {
WCHAR lpClassName[200];
ZeroMemory(lpClassName, 200);
GetClassNameW(hWnd, lpClassName, 200);
HWND hWndParent = GetParent(hWnd);
if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"TrayNotifyWnd"))
{
if (nIndex == GWL_EXSTYLE)
{
dwNewLong |= WS_EX_STATICEDGE;
}
}
if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"NotifyIconOverflowWindow"))
{
if (nIndex == GWL_EXSTYLE)
{
dwNewLong |= WS_EX_STATICEDGE;
}
}
if (settings.clientEdge && (*((WORD*)&(lpClassName)+1)) && (!wcscmp(lpClassName, L"SysListView32") || !wcscmp(lpClassName, L"SysTreeView32"))) // !wcscmp(lpClassName, L"FolderView")
{
wchar_t wszClassName[200];
ZeroMemory(wszClassName, 200);
GetClassNameW(GetAncestor(hWndParent, GA_ROOT), wszClassName, 200);
if (!wcscmp(wszClassName, L"CabinetWClass"))
{
if (nIndex == GWL_EXSTYLE)
{
dwNewLong |= WS_EX_CLIENTEDGE;
}
}
}
if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"ReBarWindow32"))
{
wchar_t wszClassName[200];
ZeroMemory(wszClassName, 200);
GetClassNameW(hWndParent, wszClassName, 200);
if (!wcscmp(wszClassName, L"Shell_TrayWnd"))
{
if (nIndex == GWL_STYLE)
{
dwNewLong |= RBS_BANDBORDERS;
}
}
}
return SetWindowLongPtrW_Orig(hWnd, nIndex, dwNewLong);
}
HTHEME(*pOriginalOpenThemeDataForDpi)(HWND hWnd, LPCWSTR pszClassList, UINT dpi);
HTHEME OpenThemeDataForDpiHook(HWND hWnd, LPCWSTR pszClassList, UINT dpi)
{
if (settings.epMitigate && (*((WORD*)&(pszClassList)+1)) && !wcscmp(pszClassList, L"Taskband2")) {
Wh_Log(L"Redirecting Taskband2 hTheme");
return (HTHEME)0xDEADBEEF;
} else if (settings.epMitigate && (*((WORD*)&(pszClassList)+1)) && !wcscmp(pszClassList, L"TrayNotifyFlyout")) {
Wh_Log(L"Redirecting TrayNotifyFlyout hTheme");
return (HTHEME)0xDEADBEFF;
}
return pOriginalOpenThemeDataForDpi(hWnd, pszClassList, dpi);
}
HRESULT(*pOriginalGetThemeMetric)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, int* piVal);
HRESULT GetThemeMetricHook(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, int* piVal) {
Wh_Log(L"hTheme: %08X", hTheme);
if (!settings.epMitigate || (hTheme != (HTHEME)0xDEADBEFF)) {
return pOriginalGetThemeMetric(hTheme, hdc, iPartId, iStateId, iPropId, piVal);
}
const int TMT_WIDTH = 2416;
const int TMT_HEIGHT = 2417;
if (hTheme == (HTHEME)0xDEADBEFF && iPropId == TMT_WIDTH && iPartId == 3 && iStateId == 0)
{
*piVal = GetSystemMetrics(SM_CXICON);
}
else if (hTheme == (HTHEME)0xDEADBEFF && iPropId == TMT_HEIGHT && iPartId == 3 && iStateId == 0)
{
*piVal = GetSystemMetrics(SM_CYICON);
}
return S_OK;
}
HRESULT(*pOriginalGetThemeMargins)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, LPCRECT prc, MARGINS* pMargins);
HRESULT GetThemeMarginsHook(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, LPCRECT prc, MARGINS* pMargins) {
Wh_Log(L"hTheme: %08X", hTheme);
if (!settings.epMitigate || (hTheme != (HTHEME)0xDEADBEEF && hTheme != (HTHEME)0xDEADBEFF)) {
return pOriginalGetThemeMargins(hTheme, hdc, iPartId, iStateId, iPropId, prc, pMargins);
}
const int TMT_SIZINGMARGINS = 3601;
const int TMT_CONTENTMARGINS = 3602;
HRESULT hr = S_OK;
if (hTheme)
{
hr = pOriginalGetThemeMargins(
hTheme,
hdc,
iPartId,
iStateId,
iPropId,
prc,
pMargins
);
}
if (hTheme == (HTHEME)0xDEADBEEF && iPropId == TMT_CONTENTMARGINS && iPartId == 5 && iStateId == 1) {
// task list button measurements
pMargins->cxLeftWidth = 4;
pMargins->cyTopHeight = 3;
pMargins->cxRightWidth = 4;
pMargins->cyBottomHeight = 3;
} else if (hTheme == (HTHEME)0xDEADBEEF && iPropId == TMT_CONTENTMARGINS && iPartId == 1 && iStateId == 0) {
// task list measurements
pMargins->cxLeftWidth = 0;
pMargins->cyTopHeight = 0;
pMargins->cxRightWidth = 4;
pMargins->cyBottomHeight = 0;
} else if (hTheme == (HTHEME)0xDEADBEEF && iPropId == TMT_SIZINGMARGINS && iPartId == 5 && iStateId == 1) {
pMargins->cxLeftWidth = 10;
pMargins->cyTopHeight = 10;
pMargins->cxRightWidth = 10;
pMargins->cyBottomHeight = 10;
} else if (hTheme == (HTHEME)0xDEADBEFF && iPropId == TMT_CONTENTMARGINS && iPartId == 3 && iStateId == 0) {
pMargins->cxLeftWidth = 4; // GetSystemMetrics(SM_CXICONSPACING);
pMargins->cyTopHeight = 4; // GetSystemMetrics(SM_CYICONSPACING);
pMargins->cxRightWidth = 4; //GetSystemMetrics(SM_CXICONSPACING);
pMargins->cyBottomHeight = 4; // GetSystemMetrics(SM_CYICONSPACING);
}
HWND hShell_TrayWnd = FindWindowEx(NULL, NULL, L"Shell_TrayWnd", NULL);
if (hShell_TrayWnd) {
LONG dwStyle = 0;
dwStyle = GetWindowLongW(hShell_TrayWnd, GWL_STYLE);
dwStyle |= WS_DLGFRAME;
SetWindowLongW(hShell_TrayWnd, GWL_STYLE, dwStyle);
dwStyle &= ~WS_DLGFRAME;
SetWindowLongW(hShell_TrayWnd, GWL_STYLE, dwStyle);
}
HWND hWnd = NULL;
do {
hWnd = FindWindowEx(
NULL,
hWnd,
L"Shell_SecondaryTrayWnd",
NULL
);
if (hWnd) {
LONG dwStyle = 0;
dwStyle = GetWindowLongW(hWnd, GWL_STYLE);
dwStyle |= WS_DLGFRAME;
SetWindowLongW(hWnd, GWL_STYLE, dwStyle);
dwStyle &= ~WS_DLGFRAME;
SetWindowLongW(hWnd, GWL_STYLE, dwStyle);
}
} while (hWnd);
return S_OK;
}
HRESULT(*pOriginalDrawThemeTextEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, LPRECT pRect, const DTTOPTS* pOptions);
HRESULT DrawThemeTextExHook(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, LPRECT pRect, const DTTOPTS* pOptions) {
if (!settings.epMitigate) {
return pOriginalDrawThemeTextEx(hTheme, hdc, iPartId, iStateId, pszText, cchText, dwTextFlags, pRect, pOptions);
}
COLORREF bc = GetBkColor(hdc);
COLORREF fc = GetTextColor(hdc);
int mode = SetBkMode(hdc, TRANSPARENT);
wchar_t text[200];
GetWindowTextW(GetForegroundWindow(), text, 200);
BOOL bIsActiveUnhovered = (iPartId == 5 && iStateId == 5);
BOOL bIsInactiveUnhovered = (iPartId == 5 && iStateId == 1);
BOOL bIsInactiveHovered = (iPartId == 5 && iStateId == 2);
BOOL bIsActiveHovered = bIsInactiveHovered && !wcscmp(text, pszText);
SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
NONCLIENTMETRICSW ncm;
ncm.cbSize = sizeof(NONCLIENTMETRICSW);
SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncm, 0);
HFONT hFont = NULL;
if (bIsActiveUnhovered)
{
hFont = CreateFontIndirectW(&(ncm.lfCaptionFont));
}
else if (bIsInactiveUnhovered)
{
hFont = CreateFontIndirectW(&(ncm.lfMenuFont));
}
else if (bIsActiveHovered)
{
hFont = CreateFontIndirectW(&(ncm.lfCaptionFont));
}
else if (bIsInactiveHovered)
{
hFont = CreateFontIndirectW(&(ncm.lfMenuFont));
}
else
{
hFont = CreateFontIndirectW(&(ncm.lfMenuFont));
}
if (iPartId == 5 && iStateId == 0) // clock
{
pRect->top += 2;
}
HGDIOBJ hOldFont = SelectObject(hdc, hFont);
DrawTextW(
hdc,
pszText,
cchText,
pRect,
dwTextFlags
);
SelectObject(hdc, hOldFont);
DeleteObject(hFont);
SetBkColor(hdc, bc);
SetTextColor(hdc, fc);
SetBkMode(hdc, mode);
return S_OK;
}
HRESULT(*pOriginalDrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPRECT pRect, LPCRECT pClipRect);
HRESULT DrawThemeBackgroundHook(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPRECT pRect, LPCRECT pClipRect) {
if (settings.epMitigate) {
if (iPartId == 4 && iStateId == 1) {
COLORREF bc = GetBkColor(hdc);
COLORREF fc = GetTextColor(hdc);
int mode = SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
NONCLIENTMETRICSW ncm;
ncm.cbSize = sizeof(NONCLIENTMETRICSW);
SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncm, 0);
HFONT hFont = CreateFontIndirectW(&(ncm.lfCaptionFont));
/*UINT dpiX, dpiY;
HRESULT hr = GetDpiForMonitor(
MonitorFromWindow(WindowFromDC(hdc), MONITOR_DEFAULTTOPRIMARY),
MDT_DEFAULT,
&dpiX,
&dpiY
);
double dx = dpiX / 96.0, dy = dpiY / 96.0;*/
HGDIOBJ hOldFont = SelectObject(hdc, hFont);
DWORD dwTextFlags = DT_SINGLELINE | DT_CENTER | DT_VCENTER;
RECT rc = *pRect;
rc.bottom -= 7;
DrawTextW(
hdc,
L"\u2026",
-1,
&rc,
dwTextFlags
);
SelectObject(hdc, hOldFont);
DeleteObject(hFont);
SetBkColor(hdc, bc);
SetTextColor(hdc, fc);
SetBkMode(hdc, mode);
}
return S_OK;
}
return pOriginalDrawThemeBackground(hTheme, hdc, iPartId, iStateId, pRect, pClipRect);
}
struct WINCOMPATTRDATA
{
DWORD attribute;
PVOID pData;
ULONG dataSize;
};
BOOL (WINAPI *pOriginalSetWindowCompositionAttribute)(HWND hWnd, WINCOMPATTRDATA* pData);
BOOL WINAPI SetWindowCompositionAttributeHook(HWND hWnd, WINCOMPATTRDATA* pData) {
if (settings.epMitigate) {
return TRUE;
}
return pOriginalSetWindowCompositionAttribute(hWnd, pData);
}
// Windhawk boilerplate // Windhawk boilerplate
BOOL Wh_ModInit() { BOOL Wh_ModInit() {
Wh_Log(L"Init");
LoadSettings(); LoadSettings();
HMODULE hShcore = GetModuleHandle(L"shcore.dll"); HMODULE hShcore = GetModuleHandle(L"shcore.dll");
void* origFunc = (void*)GetProcAddress(hShcore, (LPCSTR)188); void* origCWW = (void*)GetProcAddress(hShcore, (LPCSTR)188);
Wh_SetFunctionHook(origFunc, (void*)SHCreateWorkerWindowHook, (void**)&pOriginalSHCreateWorkerWindow); Wh_SetFunctionHook(origCWW, (void*)SHCreateWorkerWindowHook, (void**)&pOriginalSHCreateWorkerWindow);
HMODULE hUxtheme = GetModuleHandle(L"uxtheme.dll");
void* origOTDFD = (void*)GetProcAddress(hUxtheme, "OpenThemeDataForDpi");
Wh_SetFunctionHook(origOTDFD, (void*)OpenThemeDataForDpiHook, (void**)&pOriginalOpenThemeDataForDpi);
void* origGTMe = (void*)GetProcAddress(hUxtheme, "GetThemeMetric");
Wh_SetFunctionHook(origGTMe, (void*)GetThemeMetricHook, (void**)&pOriginalGetThemeMetric);
void* origGTMa = (void*)GetProcAddress(hUxtheme, "GetThemeMargins");
Wh_SetFunctionHook(origGTMa, (void*)GetThemeMarginsHook, (void**)&pOriginalGetThemeMargins);
void* origDTTE = (void*)GetProcAddress(hUxtheme, "DrawThemeTextEx");
Wh_SetFunctionHook(origDTTE, (void*)DrawThemeTextExHook, (void**)&pOriginalDrawThemeTextEx);
void* origDTB = (void*)GetProcAddress(hUxtheme, "DrawThemeBackground");
Wh_SetFunctionHook(origDTB, (void*)DrawThemeBackgroundHook, (void**)&pOriginalDrawThemeBackground);
//HMODULE hUser32 = GetModuleHandle(L"user32.dll");
//void* origSWCA = (void*)GetProcAddress(hUser32, "SetWindowCompositionAttribute");
//Wh_SetFunctionHook(origSWCA, (void*)SetWindowCompositionAttributeHook, (void**)&pOriginalSetWindowCompositionAttribute);
Wh_SetFunctionHook((void*)CreateWindowExW,
(void*)CreateWindowExW_Hook,
(void**)&CreateWindowExW_Orig);
Wh_SetFunctionHook((void*)SetWindowLongPtrW,
(void*)SetWindowLongPtrW_Hook,
(void**)&SetWindowLongPtrW_Orig);
return TRUE; return TRUE;
} }
void Wh_ModUninit() { void Wh_ModUninit() {
Wh_Log(L"Uninit");
if (g_uiThreadId != 0) EnumThreadWindows(g_uiThreadId, EnumBrowserWindowsUnsubclassFunc, 0); if (g_uiThreadId != 0) EnumThreadWindows(g_uiThreadId, EnumBrowserWindowsUnsubclassFunc, 0);
} }
void Wh_ModSettingsChanged() { void Wh_ModSettingsChanged() {
Wh_Log(L"SettingsChanged");
LoadSettings(); LoadSettings();
} }

View file

@ -30,7 +30,7 @@
// @exclude PhoneExperienceHost.exe // @exclude PhoneExperienceHost.exe
// @exclude SecurityHealthTray.exe // @exclude SecurityHealthTray.exe
// @exclude Window Detective.exe // @exclude Window Detective.exe
// @compilerOptions -luxtheme -ldwmapi -lole32 -lcomdlg32 // @compilerOptions -luxtheme -ldwmapi -lole32 -lcomdlg32 -lcomctl32
// ==/WindhawkMod== // ==/WindhawkMod==
// ==WindhawkModReadme== // ==WindhawkModReadme==
@ -43,62 +43,133 @@ Forces Classic Theme on all Windows
#include <windows.h> #include <windows.h>
#include <uxtheme.h> #include <uxtheme.h>
#include <dwmapi.h> #include <dwmapi.h>
#include <commctrl.h>
DWORD thisPid = -1;
// BasicThemer2 reimplementation to render classic titlebars // BasicThemer2 reimplementation to render classic titlebars
static const int DisableDWM = DWMNCRP_DISABLED; static const int DisableDWM = DWMNCRP_DISABLED;
static const int EnableDWM = DWMNCRP_ENABLED; static const int EnableDWM = DWMNCRP_ENABLED;
void BasicThemerEnable(HWND hwnd) { void DisableDWMForHwnd(HWND hwnd) {
DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &DisableDWM, sizeof(int)); DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &DisableDWM, sizeof(int));
} }
void BasicThemerDisable(HWND hwnd) { void EnableDWMForHwnd(HWND hwnd) {
DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &EnableDWM, sizeof(int)); 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); using CreateWindowExW_t = decltype(&CreateWindowExW);
CreateWindowExW_t CreateWindowExW_Orig; 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 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) { if (!hWnd) {
DWORD targetPid; return hWnd;
GetWindowThreadProcessId(res, &targetPid);
if (targetPid == thisPid) {
BasicThemerEnable(res);
}
} }
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); using CreateWindowExA_t = decltype(&CreateWindowExA);
CreateWindowExA_t CreateWindowExA_Orig; 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 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) { if (!hWnd) {
DWORD targetPid; return hWnd;
GetWindowThreadProcessId(res, &targetPid);
if (targetPid == thisPid) {
BasicThemerEnable(res);
}
} }
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) { HWND(WINAPI *pOriginalSHCreateWorkerWindow)(WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle, DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra);
if (IsWindow(hWnd)) HWND WINAPI SHCreateWorkerWindowHook(WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle, DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra)
BasicThemerEnable(hWnd); {
HWND result = pOriginalSHCreateWorkerWindow(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, wnd_extra);
return TRUE; if (dwExStyle == 0x10000 && dwStyle == 0x46000000 && result) {
} DisableDWMForHwnd(hWndParent);
BOOL CALLBACK DisableBasicThemerForAll(HWND hWnd, LPARAM lParam) { EnumWindows(DisableDWMForAll, 0);
if (IsWindow(hWnd)) }
BasicThemerDisable(hWnd);
return TRUE; return result;
} }
// File picker // File picker
@ -141,9 +212,12 @@ BOOL Wh_ModInit() {
(void*)CreateWindowExA_Hook, (void*)CreateWindowExA_Hook,
(void**)&CreateWindowExA_Orig); (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 // Iterate every window to enable BasicThemer
thisPid = GetProcessIdOfThread(GetCurrentThread()); EnumWindows(DisableDWMForAll, 0);
EnumWindows(EnableBasicThemerForAll, thisPid);
// File picker // File picker
Wh_SetFunctionHook((void*)CoCreateInstance, (void*)CoCreateInstance_Hook, Wh_SetFunctionHook((void*)CoCreateInstance, (void*)CoCreateInstance_Hook,
@ -159,6 +233,5 @@ void Wh_ModUninit() {
} }
// Iterate every window to disable BasicThemer // Iterate every window to disable BasicThemer
thisPid = GetProcessIdOfThread(GetCurrentThread()); EnumWindows(EnableDWMForAll, 0);
EnumWindows(DisableBasicThemerForAll, thisPid);
} }