mirror of
https://github.com/valinet/ExplorerPatcher.git
synced 2024-11-23 23:21:08 +01:00
Taskbar10: Revised the method for restoring acrylic to the Windows 10 taskbar on 22621+
This commit is contained in:
parent
5c35f5862f
commit
5e7bad22cd
@ -292,7 +292,7 @@
|
|||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Taskbar10.c">
|
<ClCompile Include="Taskbar10.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
#include "utility.h"
|
|
||||||
|
|
||||||
#pragma region "Enable old taskbar"
|
|
||||||
/***
|
|
||||||
Our target is in `CTray::Init()`. It constructs either the Windows 11 or the Windows 10 taskbar based on the result of
|
|
||||||
`winrt::WindowsUdk::ApplicationModel::AppExtensions::XamlExtensions::IsExtensionAvailable()`. We can to make the last
|
|
||||||
argument of that function be set to false, so that we'll get the Windows 10 taskbar instead of the Windows 11 one that
|
|
||||||
gets constructed through `CTray::InitializeTrayUIComponent()`.
|
|
||||||
|
|
||||||
Alternatively, we can modify the behavior of `CTray::InitializeTrayUIComponent`. It contains the code to call
|
|
||||||
`TrayUI_CreateInstance()` that resides in `Taskbar.dll` (checked through HKLM\SOFTWARE\Classes\CLSID\<the CLSID>) which
|
|
||||||
is a copy of the Windows 10 taskbar code but modified over the time to support the Windows 11 taskbar. We see that it
|
|
||||||
calls `CoCreateInstance` to get an `ITrayUIComponent` interface to an instance of `TrayUIComponent`. We hook that
|
|
||||||
function to make it return our own custom `ITrayUIComponent` instance. Our `ITrayUIComponent::InitializeWithTray()`
|
|
||||||
function calls `TrayUI_CreateInstance()` of `explorer.exe` that is also called when the last argument of
|
|
||||||
`IsExtensionAvailable()` after the call is false.
|
|
||||||
|
|
||||||
This way, we can get the Windows 10 taskbar which resides in explorer.exe without hooking LoadLibraryExW() in order to
|
|
||||||
perform our initial method which has been known to be inconsistent on some systems. (Thanks feature flags!)
|
|
||||||
***/
|
|
||||||
|
|
||||||
static ULONG STDMETHODCALLTYPE nimplAddRefRelease(IUnknown* This)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE ITrayUIComponent_QueryInterface(ITrayUIComponent* This, REFIID riid, void** ppvObject)
|
|
||||||
{
|
|
||||||
// Should never be called
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE ITrayUIComponent_InitializeWithTray(ITrayUIComponent* This, ITrayUIHost* host, ITrayUI** result)
|
|
||||||
{
|
|
||||||
return explorer_TrayUI_CreateInstanceFunc(host, &IID_ITrayUI, (void**)result);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const ITrayUIComponentVtbl instanceof_ITrayUIComponentVtbl = {
|
|
||||||
.QueryInterface = ITrayUIComponent_QueryInterface,
|
|
||||||
.AddRef = nimplAddRefRelease,
|
|
||||||
.Release = nimplAddRefRelease,
|
|
||||||
.InitializeWithTray = ITrayUIComponent_InitializeWithTray
|
|
||||||
};
|
|
||||||
const ITrayUIComponent instanceof_ITrayUIComponent = { &instanceof_ITrayUIComponentVtbl };
|
|
||||||
#pragma endregion
|
|
267
ExplorerPatcher/Taskbar10.cpp
Normal file
267
ExplorerPatcher/Taskbar10.cpp
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
#include "utility.h"
|
||||||
|
|
||||||
|
#include <dcomptypes.h>
|
||||||
|
|
||||||
|
#include <wrl/implements.h>
|
||||||
|
#include <wrl/wrappers/corewrappers.h>
|
||||||
|
#include <wil/result_macros.h>
|
||||||
|
|
||||||
|
extern "C" DWORD (*CImmersiveColor_GetColorFunc)(int colorType);
|
||||||
|
|
||||||
|
#pragma region "Enable old taskbar"
|
||||||
|
/***
|
||||||
|
Our target is in `CTray::Init()`. It constructs either the Windows 11 or the Windows 10 taskbar based on the result of
|
||||||
|
`winrt::WindowsUdk::ApplicationModel::AppExtensions::XamlExtensions::IsExtensionAvailable()`. We can to make the last
|
||||||
|
argument of that function be set to false, so that we'll get the Windows 10 taskbar instead of the Windows 11 one that
|
||||||
|
gets constructed through `CTray::InitializeTrayUIComponent()`.
|
||||||
|
|
||||||
|
Alternatively, we can modify the behavior of `CTray::InitializeTrayUIComponent`. It contains the code to call
|
||||||
|
`TrayUI_CreateInstance()` that resides in `Taskbar.dll` (checked through HKLM\SOFTWARE\Classes\CLSID\<the CLSID>) which
|
||||||
|
is a copy of the Windows 10 taskbar code but modified over the time to support the Windows 11 taskbar. We see that it
|
||||||
|
calls `CoCreateInstance` to get an `ITrayUIComponent` interface to an instance of `TrayUIComponent`. We hook that
|
||||||
|
function to make it return our own custom `ITrayUIComponent` instance. Our `ITrayUIComponent::InitializeWithTray()`
|
||||||
|
function calls `TrayUI_CreateInstance()` of `explorer.exe` that is also called when the last argument of
|
||||||
|
`IsExtensionAvailable()` after the call is false.
|
||||||
|
|
||||||
|
This way, we can get the Windows 10 taskbar which resides in explorer.exe without hooking LoadLibraryExW() in order to
|
||||||
|
perform our initial method which has been known to be inconsistent on some systems. (Thanks feature flags!)
|
||||||
|
***/
|
||||||
|
|
||||||
|
MIDL_INTERFACE("27775f88-01d3-46ec-a1c1-64b4c09b211b")
|
||||||
|
ITrayUIComponent : IUnknown
|
||||||
|
{
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE InitializeWithTray(ITrayUIHost* host, ITrayUI** result) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class EPTrayUIComponent : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, ITrayUIComponent>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
STDMETHODIMP InitializeWithTray(ITrayUIHost* host, ITrayUI** result) override
|
||||||
|
{
|
||||||
|
RETURN_IF_FAILED(explorer_TrayUI_CreateInstanceFunc(host, IID_ITrayUI, (void**)result));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" HRESULT EPTrayUIComponent_CreateInstance(REFIID riid, void** ppvObject)
|
||||||
|
{
|
||||||
|
Microsoft::WRL::ComPtr<EPTrayUIComponent> instance;
|
||||||
|
RETURN_IF_FAILED(Microsoft::WRL::MakeAndInitialize<EPTrayUIComponent>(&instance));
|
||||||
|
RETURN_HR(instance.CopyTo(riid, ppvObject));
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region "Restore acrylic background"
|
||||||
|
typedef enum WINDOWCOMPOSITIONATTRIB
|
||||||
|
{
|
||||||
|
WCA_UNDEFINED = 0,
|
||||||
|
WCA_NCRENDERING_ENABLED = 1,
|
||||||
|
WCA_NCRENDERING_POLICY = 2,
|
||||||
|
WCA_TRANSITIONS_FORCEDISABLED = 3,
|
||||||
|
WCA_ALLOW_NCPAINT = 4,
|
||||||
|
WCA_CAPTION_BUTTON_BOUNDS = 5,
|
||||||
|
WCA_NONCLIENT_RTL_LAYOUT = 6,
|
||||||
|
WCA_FORCE_ICONIC_REPRESENTATION = 7,
|
||||||
|
WCA_EXTENDED_FRAME_BOUNDS = 8,
|
||||||
|
WCA_HAS_ICONIC_BITMAP = 9,
|
||||||
|
WCA_THEME_ATTRIBUTES = 10,
|
||||||
|
WCA_NCRENDERING_EXILED = 11,
|
||||||
|
WCA_NCADORNMENTINFO = 12,
|
||||||
|
WCA_EXCLUDED_FROM_LIVEPREVIEW = 13,
|
||||||
|
WCA_VIDEO_OVERLAY_ACTIVE = 14,
|
||||||
|
WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
|
||||||
|
WCA_DISALLOW_PEEK = 16,
|
||||||
|
WCA_CLOAK = 17,
|
||||||
|
WCA_CLOAKED = 18,
|
||||||
|
WCA_ACCENT_POLICY = 19,
|
||||||
|
WCA_FREEZE_REPRESENTATION = 20,
|
||||||
|
WCA_EVER_UNCLOAKED = 21,
|
||||||
|
WCA_VISUAL_OWNER = 22,
|
||||||
|
WCA_HOLOGRAPHIC = 23,
|
||||||
|
WCA_EXCLUDED_FROM_DDA = 24,
|
||||||
|
WCA_PASSIVEUPDATEMODE = 25,
|
||||||
|
WCA_USEDARKMODECOLORS = 26,
|
||||||
|
WCA_CORNER_STYLE = 27,
|
||||||
|
WCA_PART_COLOR = 28,
|
||||||
|
WCA_DISABLE_MOVESIZE_FEEDBACK = 29,
|
||||||
|
WCA_SYSTEMBACKDROP_TYPE = 30,
|
||||||
|
WCA_SET_TAGGED_WINDOW_RECT = 31,
|
||||||
|
WCA_CLEAR_TAGGED_WINDOW_RECT = 32,
|
||||||
|
WCA_LAST = 33,
|
||||||
|
} WINDOWCOMPOSITIONATTRIB;
|
||||||
|
|
||||||
|
typedef struct tagWINDOWCOMPOSITIONATTRIBDATA
|
||||||
|
{
|
||||||
|
WINDOWCOMPOSITIONATTRIB Attrib;
|
||||||
|
void* pvData;
|
||||||
|
unsigned int cbData;
|
||||||
|
} WINDOWCOMPOSITIONATTRIBDATA;
|
||||||
|
|
||||||
|
typedef enum ACCENT_STATE
|
||||||
|
{
|
||||||
|
ACCENT_DISABLED = 0,
|
||||||
|
ACCENT_ENABLE_GRADIENT = 1,
|
||||||
|
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
|
||||||
|
ACCENT_ENABLE_BLURBEHIND = 3,
|
||||||
|
ACCENT_ENABLE_ACRYLICBLURBEHIND = 4,
|
||||||
|
ACCENT_ENABLE_HOSTBACKDROP = 5,
|
||||||
|
ACCENT_INVALID_STATE = 6,
|
||||||
|
} ACCENT_STATE;
|
||||||
|
|
||||||
|
typedef struct ACCENT_POLICY
|
||||||
|
{
|
||||||
|
ACCENT_STATE AccentState;
|
||||||
|
unsigned int AccentFlags;
|
||||||
|
unsigned long GradientColor;
|
||||||
|
long AnimationId;
|
||||||
|
} ACCENT_POLICY;
|
||||||
|
|
||||||
|
namespace ABI::WindowsUdk::UI::Themes
|
||||||
|
{
|
||||||
|
enum class VisualTheme
|
||||||
|
{
|
||||||
|
Dark = 0,
|
||||||
|
Light = 1,
|
||||||
|
HighContrastBlack = 2,
|
||||||
|
HighContrastWhite = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
MIDL_INTERFACE("8f0a6c35-72ca-5f4a-a5fb-1a731ec8b514")
|
||||||
|
ISystemVisualThemeStatics : IInspectable
|
||||||
|
{
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE get_Current(VisualTheme* value) = 0;
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE add_Changed(void* handler, EventRegistrationToken* token) = 0;
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE remove_Changed(EventRegistrationToken token) = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TaskbarTheme
|
||||||
|
{
|
||||||
|
bool bColorPrevalence;
|
||||||
|
bool bEnableTransparency;
|
||||||
|
ABI::WindowsUdk::UI::Themes::VisualTheme visualTheme;
|
||||||
|
|
||||||
|
bool IsHighContrast() const
|
||||||
|
{
|
||||||
|
using namespace ABI::WindowsUdk::UI::Themes;
|
||||||
|
return visualTheme == VisualTheme::HighContrastBlack || visualTheme == VisualTheme::HighContrastWhite;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsDark() const
|
||||||
|
{
|
||||||
|
using namespace ABI::WindowsUdk::UI::Themes;
|
||||||
|
return visualTheme == VisualTheme::Dark || visualTheme == VisualTheme::HighContrastBlack;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct struct_b
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
int b;
|
||||||
|
int c;
|
||||||
|
int d;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef HRESULT (*NtDCompositionGetFrameStatistics_t)(DCOMPOSITION_FRAME_STATISTICS*, struct_b*);
|
||||||
|
|
||||||
|
inline HRESULT NtDCompositionGetFrameStatistics(DCOMPOSITION_FRAME_STATISTICS* a, struct_b* b)
|
||||||
|
{
|
||||||
|
static NtDCompositionGetFrameStatistics_t f = nullptr;
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
HMODULE h = GetModuleHandleW(L"dcomp.dll");
|
||||||
|
if (h)
|
||||||
|
f = (NtDCompositionGetFrameStatistics_t)GetProcAddress(h, MAKEINTRESOURCEA(1046));
|
||||||
|
}
|
||||||
|
return f ? f(a, b) : E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShouldApplyBlur()
|
||||||
|
{
|
||||||
|
DCOMPOSITION_FRAME_STATISTICS v7;
|
||||||
|
struct_b v6;
|
||||||
|
return SUCCEEDED(NtDCompositionGetFrameStatistics(&v7, &v6)) && v6.d && !v6.c;
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskbarTheme GetTaskbarTheme()
|
||||||
|
{
|
||||||
|
TaskbarTheme rv;
|
||||||
|
// rv.visualTheme = winrt::WindowsUdk::UI::Themes::SystemVisualTheme::Current();
|
||||||
|
|
||||||
|
rv.visualTheme = ABI::WindowsUdk::UI::Themes::VisualTheme::Light;
|
||||||
|
Microsoft::WRL::ComPtr<ABI::WindowsUdk::UI::Themes::ISystemVisualThemeStatics> systemVisualTheme;
|
||||||
|
HRESULT hr = RoGetActivationFactory(
|
||||||
|
Microsoft::WRL::Wrappers::HStringReference(L"WindowsUdk.UI.Themes.SystemVisualTheme").Get(),
|
||||||
|
IID_PPV_ARGS(&systemVisualTheme)
|
||||||
|
);
|
||||||
|
if (SUCCEEDED_LOG(hr))
|
||||||
|
{
|
||||||
|
ABI::WindowsUdk::UI::Themes::VisualTheme theme;
|
||||||
|
if (SUCCEEDED_LOG(systemVisualTheme->get_Current(&theme)))
|
||||||
|
{
|
||||||
|
rv.visualTheme = theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD bColorPrevalence = 0;
|
||||||
|
rv.bColorPrevalence =
|
||||||
|
SUCCEEDED(SHRegGetDWORD(
|
||||||
|
HKEY_CURRENT_USER,
|
||||||
|
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
|
||||||
|
L"ColorPrevalence",
|
||||||
|
&bColorPrevalence
|
||||||
|
)) && bColorPrevalence;
|
||||||
|
|
||||||
|
bool bApplyBlur = ShouldApplyBlur();
|
||||||
|
DWORD bEnableTransparency;
|
||||||
|
rv.bEnableTransparency = !rv.IsHighContrast() && bApplyBlur
|
||||||
|
&& SUCCEEDED(SHRegGetDWORD(
|
||||||
|
HKEY_CURRENT_USER,
|
||||||
|
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
|
||||||
|
L"EnableTransparency",
|
||||||
|
&bEnableTransparency
|
||||||
|
)) && bEnableTransparency;
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD GetTaskbarColor()
|
||||||
|
{
|
||||||
|
TaskbarTheme tt = GetTaskbarTheme();
|
||||||
|
|
||||||
|
if (tt.IsHighContrast())
|
||||||
|
return GetSysColor(COLOR_WINDOW);
|
||||||
|
|
||||||
|
if (tt.bColorPrevalence && CImmersiveColor_GetColorFunc)
|
||||||
|
{
|
||||||
|
DWORD result = CImmersiveColor_GetColorFunc(tt.IsDark() ? 6 /*IMCLR_SystemAccentDark2*/ : 2 /*IMCLR_SystemAccentLight2*/);
|
||||||
|
if (tt.bEnableTransparency)
|
||||||
|
return (result & 0xFFFFFF) | 0xCC000000;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tt.IsDark())
|
||||||
|
return tt.bEnableTransparency ? 0x80202020 : 0xFF202020;
|
||||||
|
|
||||||
|
return tt.bEnableTransparency ? 0xF3F3F3 : 0xFFF3F3F3;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void UpdateWindowAccentProperties_PatchAttribData(WINDOWCOMPOSITIONATTRIBDATA* pAttrData)
|
||||||
|
{
|
||||||
|
ACCENT_POLICY* pAccentPolicy = (ACCENT_POLICY*)pAttrData->pvData;
|
||||||
|
if (false) // STTest makes it like this:
|
||||||
|
{
|
||||||
|
pAccentPolicy->AccentState = ACCENT_ENABLE_TRANSPARENTGRADIENT;
|
||||||
|
pAccentPolicy->GradientColor = 0;
|
||||||
|
pAccentPolicy->AnimationId = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pAccentPolicy->AccentState = GetTaskbarTheme().bEnableTransparency ? ACCENT_ENABLE_ACRYLICBLURBEHIND : ACCENT_ENABLE_GRADIENT;
|
||||||
|
pAccentPolicy->GradientColor = GetTaskbarColor();
|
||||||
|
pAccentPolicy->AnimationId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pAccentPolicy->AccentFlags = 0x1 | 0x2 | 0x10;
|
||||||
|
}
|
||||||
|
#pragma endregion
|
@ -1594,6 +1594,8 @@ finalize:
|
|||||||
|
|
||||||
#pragma region "Windows 10 Taskbar Hooks"
|
#pragma region "Windows 10 Taskbar Hooks"
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
DWORD (*CImmersiveColor_GetColorFunc)(int colorType);
|
||||||
|
|
||||||
// credits: https://github.com/m417z/7-Taskbar-Tweaker
|
// credits: https://github.com/m417z/7-Taskbar-Tweaker
|
||||||
|
|
||||||
DEFINE_GUID(IID_ITaskGroup,
|
DEFINE_GUID(IID_ITaskGroup,
|
||||||
@ -9355,148 +9357,23 @@ HRESULT explorer_DwmUpdateThumbnailPropertiesHook(HTHUMBNAIL hThumbnailId, DWM_T
|
|||||||
return DwmUpdateThumbnailProperties(hThumbnailId, ptnProperties);
|
return DwmUpdateThumbnailProperties(hThumbnailId, ptnProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateWindowAccentProperties_PatchAttribData(WINCOMPATTRDATA* pAttrData);
|
||||||
|
|
||||||
BOOL WINAPI explorer_SetWindowCompositionAttribute(HWND hWnd, WINCOMPATTRDATA* pData)
|
BOOL WINAPI explorer_SetWindowCompositionAttribute(HWND hWnd, WINCOMPATTRDATA* pData)
|
||||||
{
|
{
|
||||||
if (bClassicThemeMitigations)
|
if (bClassicThemeMitigations)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
if (bOldTaskbar && global_rovi.dwBuildNumber >= 22581 && GetTaskbarColor && GetTaskbarTheme &&
|
if (bOldTaskbar && global_rovi.dwBuildNumber >= 22581 &&
|
||||||
(GetClassWord(hWnd, GCW_ATOM) == RegisterWindowMessageW(L"Shell_TrayWnd") ||
|
(GetClassWord(hWnd, GCW_ATOM) == RegisterWindowMessageW(L"Shell_TrayWnd") ||
|
||||||
GetClassWord(hWnd, GCW_ATOM) == RegisterWindowMessageW(L"Shell_SecondaryTrayWnd")) &&
|
GetClassWord(hWnd, GCW_ATOM) == RegisterWindowMessageW(L"Shell_SecondaryTrayWnd")) &&
|
||||||
pData->nAttribute == 19 && pData->pData && pData->ulDataSize == sizeof(ACCENTPOLICY))
|
pData->nAttribute == 19 && pData->pData && pData->ulDataSize == sizeof(ACCENTPOLICY))
|
||||||
{
|
{
|
||||||
ACCENTPOLICY* pAccentPolicy = pData->pData;
|
UpdateWindowAccentProperties_PatchAttribData(pData);
|
||||||
pAccentPolicy->nAccentState = (unsigned __int16)GetTaskbarTheme() >> 8 != 0 ? 4 : 1;
|
|
||||||
pAccentPolicy->nColor = GetTaskbarColor(0, 0);
|
|
||||||
}
|
}
|
||||||
return SetWindowCompositionAttribute(hWnd, pData);
|
return SetWindowCompositionAttribute(hWnd, pData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatchExplorer_UpdateWindowAccentProperties()
|
|
||||||
{
|
|
||||||
HMODULE hExplorer = GetModuleHandleW(NULL);
|
|
||||||
if (hExplorer)
|
|
||||||
{
|
|
||||||
PIMAGE_DOS_HEADER dosHeader = hExplorer;
|
|
||||||
if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE)
|
|
||||||
{
|
|
||||||
PIMAGE_NT_HEADERS64 ntHeader = (PIMAGE_NT_HEADERS64)((u_char*)dosHeader + dosHeader->e_lfanew);
|
|
||||||
if (ntHeader->Signature == IMAGE_NT_SIGNATURE)
|
|
||||||
{
|
|
||||||
PBYTE pPatchArea = NULL;
|
|
||||||
// test al, al; jz rip+0x11; and ...
|
|
||||||
BYTE p1[] = { 0x84, 0xC0, 0x74, 0x11, 0x83, 0x65 };
|
|
||||||
BYTE p2[] = { 0xF3, 0xF3, 0xF3, 0xFF };
|
|
||||||
PBYTE pattern1 = p1;
|
|
||||||
int sizeof_pattern1 = 6;
|
|
||||||
if (global_rovi.dwBuildNumber >= 22581)
|
|
||||||
{
|
|
||||||
pattern1 = p2;
|
|
||||||
sizeof_pattern1 = 4;
|
|
||||||
}
|
|
||||||
BOOL bTwice = FALSE;
|
|
||||||
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeader);
|
|
||||||
for (unsigned int i = 0; i < ntHeader->FileHeader.NumberOfSections; ++i)
|
|
||||||
{
|
|
||||||
if (section->Characteristics & IMAGE_SCN_CNT_CODE)
|
|
||||||
{
|
|
||||||
if (section->SizeOfRawData && !bTwice)
|
|
||||||
{
|
|
||||||
PBYTE pSectionBegin = (PBYTE)hExplorer + section->VirtualAddress;
|
|
||||||
PBYTE pCandidate = NULL;
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
pCandidate = memmem(
|
|
||||||
!pCandidate ? pSectionBegin : pCandidate,
|
|
||||||
!pCandidate ? section->SizeOfRawData : (uintptr_t)section->SizeOfRawData - (uintptr_t)(pCandidate - pSectionBegin),
|
|
||||||
pattern1,
|
|
||||||
sizeof_pattern1
|
|
||||||
);
|
|
||||||
if (!pCandidate)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!pPatchArea)
|
|
||||||
{
|
|
||||||
pPatchArea = pCandidate;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bTwice = TRUE;
|
|
||||||
}
|
|
||||||
pCandidate += sizeof_pattern1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
section++;
|
|
||||||
}
|
|
||||||
if (pPatchArea && !bTwice)
|
|
||||||
{
|
|
||||||
if (global_rovi.dwBuildNumber >= 22581)
|
|
||||||
{
|
|
||||||
int dec_size = 200;
|
|
||||||
_DecodedInst* decodedInstructions = calloc(110, sizeof(_DecodedInst));
|
|
||||||
if (decodedInstructions)
|
|
||||||
{
|
|
||||||
PBYTE diasmBegin = pPatchArea - dec_size;
|
|
||||||
unsigned int decodedInstructionsCount = 0;
|
|
||||||
_DecodeResult res = distorm_decode(0, diasmBegin, dec_size + 20, Decode64Bits, decodedInstructions, 100, &decodedInstructionsCount);
|
|
||||||
int status = 0;
|
|
||||||
for (int i = decodedInstructionsCount - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
if (status == 0 && strstr(decodedInstructions[i].instructionHex.p, "f3f3f3ff"))
|
|
||||||
{
|
|
||||||
status = 1;
|
|
||||||
}
|
|
||||||
else if (status == 1 && !strcmp(decodedInstructions[i].instructionHex.p, "c3"))
|
|
||||||
{
|
|
||||||
status = 2;
|
|
||||||
}
|
|
||||||
else if (status == 2 && strcmp(decodedInstructions[i].instructionHex.p, "cc"))
|
|
||||||
{
|
|
||||||
GetTaskbarColor = diasmBegin + decodedInstructions[i].offset;
|
|
||||||
status = 3;
|
|
||||||
}
|
|
||||||
else if (status == 3 && !strncmp(decodedInstructions[i].instructionHex.p, "e8", 2))
|
|
||||||
{
|
|
||||||
status = 4;
|
|
||||||
}
|
|
||||||
else if (status == 4 && !strncmp(decodedInstructions[i].instructionHex.p, "e8", 2))
|
|
||||||
{
|
|
||||||
uint32_t* off = diasmBegin + decodedInstructions[i].offset + 1;
|
|
||||||
GetTaskbarTheme = diasmBegin + decodedInstructions[i].offset + decodedInstructions[i].size + (*off);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (status >= 2)
|
|
||||||
{
|
|
||||||
i = i + 2;
|
|
||||||
if (i >= decodedInstructionsCount)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (SetWindowCompositionAttribute && GetTaskbarColor && GetTaskbarTheme)
|
|
||||||
{
|
|
||||||
VnPatchIAT(GetModuleHandleW(NULL), "user32.dll", "SetWindowCompositionAttribute", explorer_SetWindowCompositionAttribute);
|
|
||||||
printf("Patched taskbar transparency in newer OS builds\n");
|
|
||||||
}
|
|
||||||
free(decodedInstructions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DWORD dwOldProtect;
|
|
||||||
VirtualProtect(pPatchArea, sizeof_pattern1, PAGE_EXECUTE_READWRITE, &dwOldProtect);
|
|
||||||
pPatchArea[2] = 0xEB; // replace jz with jmp
|
|
||||||
VirtualProtect(pPatchArea, sizeof_pattern1, dwOldProtect, &dwOldProtect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
@ -10821,6 +10698,29 @@ inline BOOL FollowJnz(PBYTE pJnz, PBYTE* pTarget, DWORD* pJnzSize)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD* pOffsets)
|
||||||
|
{
|
||||||
|
if (!pOffsets[0] || pOffsets[0] == 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
// CImmersiveColor::GetColor()
|
||||||
|
// Ref: Anything `CImmersiveColor::GetColor(colorTheme == CT_Light ? IMCLR_LightAltMediumLow : IMCLR_DarkListLow)`
|
||||||
|
// = 1 = 323 = 298
|
||||||
|
// 8D 41 19 0F 44 C8 E8 ?? ?? ?? ?? 44 8B
|
||||||
|
// ^^^^^^^^^^^
|
||||||
|
PBYTE match = FindPattern(
|
||||||
|
hExplorer, pmiExplorer->SizeOfImage,
|
||||||
|
"\x8D\x41\x19\x0F\x44\xC8\xE8\x00\x00\x00\x00\x44\x8B",
|
||||||
|
"xxxxxxx????xx"
|
||||||
|
);
|
||||||
|
if (match)
|
||||||
|
{
|
||||||
|
match += 6;
|
||||||
|
pOffsets[0] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
|
||||||
|
printf("explorer.exe!CImmersiveColor::GetColor() = %lX\n", pOffsets[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets)
|
void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets)
|
||||||
{
|
{
|
||||||
// We read from the file instead of from memory because other tweak software might've modified the functions we're looking for
|
// We read from the file instead of from memory because other tweak software might've modified the functions we're looking for
|
||||||
@ -12293,6 +12193,17 @@ DWORD Inject(BOOL bIsExplorer)
|
|||||||
HANDLE hExplorer = GetModuleHandleW(NULL);
|
HANDLE hExplorer = GetModuleHandleW(NULL);
|
||||||
MODULEINFO miExplorer;
|
MODULEINFO miExplorer;
|
||||||
GetModuleInformation(GetCurrentProcess(), hExplorer, &miExplorer, sizeof(MODULEINFO));
|
GetModuleInformation(GetCurrentProcess(), hExplorer, &miExplorer, sizeof(MODULEINFO));
|
||||||
|
|
||||||
|
if (IsWindows11Version22H2OrHigher())
|
||||||
|
{
|
||||||
|
TryToFindExplorerOffsets(hExplorer, &miExplorer, symbols_PTRS.explorer_PTRS);
|
||||||
|
|
||||||
|
if (symbols_PTRS.explorer_PTRS[0] && symbols_PTRS.explorer_PTRS[0] != 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
CImmersiveColor_GetColorFunc = (DWORD(*)(int))((uintptr_t)hExplorer + symbols_PTRS.explorer_PTRS[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SetChildWindowNoActivateFunc = GetProcAddress(GetModuleHandleW(L"user32.dll"), (LPCSTR)2005);
|
SetChildWindowNoActivateFunc = GetProcAddress(GetModuleHandleW(L"user32.dll"), (LPCSTR)2005);
|
||||||
if (bOldTaskbar)
|
if (bOldTaskbar)
|
||||||
{
|
{
|
||||||
@ -12357,7 +12268,10 @@ DWORD Inject(BOOL bIsExplorer)
|
|||||||
if (global_rovi.dwBuildNumber >= 22572)
|
if (global_rovi.dwBuildNumber >= 22572)
|
||||||
{
|
{
|
||||||
VnPatchIAT(hExplorer, "dwmapi.dll", "DwmUpdateThumbnailProperties", explorer_DwmUpdateThumbnailPropertiesHook);
|
VnPatchIAT(hExplorer, "dwmapi.dll", "DwmUpdateThumbnailProperties", explorer_DwmUpdateThumbnailPropertiesHook);
|
||||||
PatchExplorer_UpdateWindowAccentProperties();
|
if (!bClassicThemeMitigations)
|
||||||
|
{
|
||||||
|
VnPatchIAT(hExplorer, "user32.dll", "SetWindowCompositionAttribute", explorer_SetWindowCompositionAttribute);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IsWindows11())
|
if (IsWindows11())
|
||||||
@ -14457,45 +14371,7 @@ void InjectShellExperienceHostFor22H2OrHigher() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT SHRegGetBOOLWithREGSAM(HKEY key, LPCWSTR subKey, LPCWSTR value, REGSAM regSam, BOOL* data)
|
#ifdef _WIN64
|
||||||
{
|
|
||||||
DWORD dwType = REG_NONE;
|
|
||||||
DWORD dwData;
|
|
||||||
DWORD cbData = 4;
|
|
||||||
LSTATUS lRes = RegGetValueW(
|
|
||||||
key,
|
|
||||||
subKey,
|
|
||||||
value,
|
|
||||||
((regSam & 0x100) << 8) | RRF_RT_REG_DWORD | RRF_RT_REG_SZ | RRF_NOEXPAND,
|
|
||||||
&dwType,
|
|
||||||
&dwData,
|
|
||||||
&cbData
|
|
||||||
);
|
|
||||||
if (lRes != ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
if (lRes == ERROR_MORE_DATA)
|
|
||||||
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
|
||||||
if (lRes > 0)
|
|
||||||
return HRESULT_FROM_WIN32(lRes);
|
|
||||||
return lRes;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dwType == REG_DWORD)
|
|
||||||
{
|
|
||||||
if (dwData > 1)
|
|
||||||
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
|
||||||
*data = dwData == 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (cbData != 4 || (WCHAR)dwData != L'0' && (WCHAR)dwData != L'1')
|
|
||||||
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
|
||||||
*data = (WCHAR)dwData == L'1';
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsUserOOBE()
|
bool IsUserOOBE()
|
||||||
{
|
{
|
||||||
BOOL b = FALSE;
|
BOOL b = FALSE;
|
||||||
@ -14526,6 +14402,7 @@ bool IsUserOOBEOrCredentialReset()
|
|||||||
{
|
{
|
||||||
return IsUserOOBE() || IsCredentialReset();
|
return IsUserOOBE() || IsCredentialReset();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DLL_INJECTION_METHOD_DXGI 0
|
#define DLL_INJECTION_METHOD_DXGI 0
|
||||||
#define DLL_INJECTION_METHOD_COM 1
|
#define DLL_INJECTION_METHOD_COM 1
|
||||||
@ -14614,12 +14491,14 @@ HRESULT EntryPoint(DWORD dwMethod)
|
|||||||
bIsExplorerProcess = bIsThisExplorer;
|
bIsExplorerProcess = bIsThisExplorer;
|
||||||
if (bIsThisExplorer)
|
if (bIsThisExplorer)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN64
|
||||||
if (IsUserOOBEOrCredentialReset())
|
if (IsUserOOBEOrCredentialReset())
|
||||||
{
|
{
|
||||||
IncrementDLLReferenceCount(hModule);
|
IncrementDLLReferenceCount(hModule);
|
||||||
bInstanced = TRUE;
|
bInstanced = TRUE;
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
BOOL desktopExists = IsDesktopWindowAlreadyPresent();
|
BOOL desktopExists = IsDesktopWindowAlreadyPresent();
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
if (!desktopExists && CrashCounterHandleEntryPoint())
|
if (!desktopExists && CrashCounterHandleEntryPoint())
|
||||||
|
@ -1535,6 +1535,52 @@ BOOL ExtractMonitorByIndex(HMONITOR hMonitor, HDC hDC, LPRECT lpRect, MonitorOve
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT SHRegGetBOOLWithREGSAM(HKEY key, LPCWSTR subKey, LPCWSTR value, REGSAM regSam, BOOL* data)
|
||||||
|
{
|
||||||
|
DWORD dwType = REG_NONE;
|
||||||
|
DWORD dwData;
|
||||||
|
DWORD cbData = 4;
|
||||||
|
LSTATUS lRes = RegGetValueW(
|
||||||
|
key,
|
||||||
|
subKey,
|
||||||
|
value,
|
||||||
|
((regSam & 0x100) << 8) | RRF_RT_REG_DWORD | RRF_RT_REG_SZ | RRF_NOEXPAND,
|
||||||
|
&dwType,
|
||||||
|
&dwData,
|
||||||
|
&cbData
|
||||||
|
);
|
||||||
|
if (lRes != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (lRes == ERROR_MORE_DATA)
|
||||||
|
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||||||
|
if (lRes > 0)
|
||||||
|
return HRESULT_FROM_WIN32(lRes);
|
||||||
|
return lRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dwType == REG_DWORD)
|
||||||
|
{
|
||||||
|
if (dwData > 1)
|
||||||
|
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||||||
|
*data = dwData == 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cbData != 4 || (WCHAR)dwData != L'0' && (WCHAR)dwData != L'1')
|
||||||
|
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||||||
|
*data = (WCHAR)dwData == L'1';
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT SHRegGetDWORD(HKEY hkey, const WCHAR* pwszSubKey, const WCHAR* pwszValue, DWORD* pdwData)
|
||||||
|
{
|
||||||
|
DWORD dwSize = sizeof(DWORD);
|
||||||
|
LSTATUS lres = RegGetValueW(hkey, pwszSubKey, pwszValue, RRF_RT_REG_DWORD, NULL, pdwData, &dwSize);
|
||||||
|
return HRESULT_FROM_WIN32(lres);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
inline BOOL MaskCompare(PVOID pBuffer, LPCSTR lpPattern, LPCSTR lpMask)
|
inline BOOL MaskCompare(PVOID pBuffer, LPCSTR lpPattern, LPCSTR lpMask)
|
||||||
{
|
{
|
||||||
|
@ -96,43 +96,12 @@ DEFINE_GUID(IID_ITrayUI,
|
|||||||
0xae, 0x7f, 0x54, 0x91, 0x99, 0xd6
|
0xae, 0x7f, 0x54, 0x91, 0x99, 0xd6
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef interface ITrayUIComponent ITrayUIComponent;
|
|
||||||
|
|
||||||
DEFINE_GUID(IID_ITrayUIComponent,
|
DEFINE_GUID(IID_ITrayUIComponent,
|
||||||
0x27775f88,
|
0x27775f88,
|
||||||
0x01d3, 0x46ec, 0xa1, 0xc1,
|
0x01d3, 0x46ec, 0xa1, 0xc1,
|
||||||
0x64, 0xb4, 0xc0, 0x9b, 0x21, 0x1b
|
0x64, 0xb4, 0xc0, 0x9b, 0x21, 0x1b
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef struct ITrayUIComponentVtbl // : IUnknownVtbl
|
|
||||||
{
|
|
||||||
BEGIN_INTERFACE
|
|
||||||
|
|
||||||
HRESULT(STDMETHODCALLTYPE* QueryInterface)(
|
|
||||||
__RPC__in ITrayUIComponent* This,
|
|
||||||
/* [in] */ __RPC__in REFIID riid,
|
|
||||||
/* [annotation][iid_is][out] */
|
|
||||||
_COM_Outptr_ void** ppvObject);
|
|
||||||
|
|
||||||
ULONG(STDMETHODCALLTYPE* AddRef)(
|
|
||||||
__RPC__in ITrayUIComponent* This);
|
|
||||||
|
|
||||||
ULONG(STDMETHODCALLTYPE* Release)(
|
|
||||||
__RPC__in ITrayUIComponent* This);
|
|
||||||
|
|
||||||
HRESULT(STDMETHODCALLTYPE* InitializeWithTray)(
|
|
||||||
__RPC__in ITrayUIComponent* This,
|
|
||||||
/* [in] */ __RPC__in ITrayUIHost* host,
|
|
||||||
/* [out] */ __RPC__out ITrayUI** result);
|
|
||||||
END_INTERFACE
|
|
||||||
} ITrayUIComponentVtbl;
|
|
||||||
|
|
||||||
interface ITrayUIComponent // : IInspectable
|
|
||||||
{
|
|
||||||
const struct ITrayUIComponentVtbl* lpVtbl;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const ITrayUIComponent instanceof_ITrayUIComponent;
|
|
||||||
HRESULT(*explorer_TrayUI_CreateInstanceFunc)(ITrayUIHost* host, REFIID riid, void** ppv);
|
HRESULT(*explorer_TrayUI_CreateInstanceFunc)(ITrayUIHost* host, REFIID riid, void** ppv);
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
@ -278,6 +247,8 @@ static bool(*ShouldSystemUseDarkMode)();
|
|||||||
|
|
||||||
static void(*GetThemeName)(void*, void*, void*);
|
static void(*GetThemeName)(void*, void*, void*);
|
||||||
|
|
||||||
|
extern DWORD (*CImmersiveColor_GetColorFunc)(int colorType);
|
||||||
|
|
||||||
void* ReadFromFile(wchar_t* wszFileName, DWORD* dwSize);
|
void* ReadFromFile(wchar_t* wszFileName, DWORD* dwSize);
|
||||||
|
|
||||||
int ComputeFileHash(LPCWSTR filename, LPSTR hash, DWORD dwHash);
|
int ComputeFileHash(LPCWSTR filename, LPSTR hash, DWORD dwHash);
|
||||||
@ -670,6 +641,8 @@ typedef struct _MonitorOverrideData
|
|||||||
} MonitorOverrideData;
|
} MonitorOverrideData;
|
||||||
|
|
||||||
BOOL ExtractMonitorByIndex(HMONITOR hMonitor, HDC hDC, LPRECT lpRect, MonitorOverrideData* mod);
|
BOOL ExtractMonitorByIndex(HMONITOR hMonitor, HDC hDC, LPRECT lpRect, MonitorOverrideData* mod);
|
||||||
|
HRESULT SHRegGetBOOLWithREGSAM(HKEY key, LPCWSTR subKey, LPCWSTR value, REGSAM regSam, BOOL* data);
|
||||||
|
HRESULT SHRegGetDWORD(HKEY hkey, const WCHAR* pwszSubKey, const WCHAR* pwszValue, DWORD* pdwData);
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
PVOID FindPattern(PVOID pBase, SIZE_T dwSize, LPCSTR lpPattern, LPCSTR lpMask);
|
PVOID FindPattern(PVOID pBase, SIZE_T dwSize, LPCSTR lpPattern, LPCSTR lpMask);
|
||||||
|
Loading…
Reference in New Issue
Block a user