mirror of
https://github.com/valinet/ExplorerPatcher.git
synced 2024-11-27 17:00:59 +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)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Taskbar10.c">
|
||||
<ClCompile Include="Taskbar10.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</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"
|
||||
#ifdef _WIN64
|
||||
DWORD (*CImmersiveColor_GetColorFunc)(int colorType);
|
||||
|
||||
// credits: https://github.com/m417z/7-Taskbar-Tweaker
|
||||
|
||||
DEFINE_GUID(IID_ITaskGroup,
|
||||
@ -9355,148 +9357,23 @@ HRESULT explorer_DwmUpdateThumbnailPropertiesHook(HTHUMBNAIL hThumbnailId, DWM_T
|
||||
return DwmUpdateThumbnailProperties(hThumbnailId, ptnProperties);
|
||||
}
|
||||
|
||||
void UpdateWindowAccentProperties_PatchAttribData(WINCOMPATTRDATA* pAttrData);
|
||||
|
||||
BOOL WINAPI explorer_SetWindowCompositionAttribute(HWND hWnd, WINCOMPATTRDATA* pData)
|
||||
{
|
||||
if (bClassicThemeMitigations)
|
||||
{
|
||||
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_SecondaryTrayWnd")) &&
|
||||
pData->nAttribute == 19 && pData->pData && pData->ulDataSize == sizeof(ACCENTPOLICY))
|
||||
{
|
||||
ACCENTPOLICY* pAccentPolicy = pData->pData;
|
||||
pAccentPolicy->nAccentState = (unsigned __int16)GetTaskbarTheme() >> 8 != 0 ? 4 : 1;
|
||||
pAccentPolicy->nColor = GetTaskbarColor(0, 0);
|
||||
UpdateWindowAccentProperties_PatchAttribData(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
|
||||
#pragma endregion
|
||||
|
||||
@ -10821,6 +10698,29 @@ inline BOOL FollowJnz(PBYTE pJnz, PBYTE* pTarget, DWORD* pJnzSize)
|
||||
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)
|
||||
{
|
||||
// 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);
|
||||
MODULEINFO miExplorer;
|
||||
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);
|
||||
if (bOldTaskbar)
|
||||
{
|
||||
@ -12357,7 +12268,10 @@ DWORD Inject(BOOL bIsExplorer)
|
||||
if (global_rovi.dwBuildNumber >= 22572)
|
||||
{
|
||||
VnPatchIAT(hExplorer, "dwmapi.dll", "DwmUpdateThumbnailProperties", explorer_DwmUpdateThumbnailPropertiesHook);
|
||||
PatchExplorer_UpdateWindowAccentProperties();
|
||||
if (!bClassicThemeMitigations)
|
||||
{
|
||||
VnPatchIAT(hExplorer, "user32.dll", "SetWindowCompositionAttribute", explorer_SetWindowCompositionAttribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsWindows11())
|
||||
@ -14457,45 +14371,7 @@ void InjectShellExperienceHostFor22H2OrHigher() {
|
||||
#endif
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
bool IsUserOOBE()
|
||||
{
|
||||
BOOL b = FALSE;
|
||||
@ -14526,6 +14402,7 @@ bool IsUserOOBEOrCredentialReset()
|
||||
{
|
||||
return IsUserOOBE() || IsCredentialReset();
|
||||
}
|
||||
#endif
|
||||
|
||||
#define DLL_INJECTION_METHOD_DXGI 0
|
||||
#define DLL_INJECTION_METHOD_COM 1
|
||||
@ -14614,12 +14491,14 @@ HRESULT EntryPoint(DWORD dwMethod)
|
||||
bIsExplorerProcess = bIsThisExplorer;
|
||||
if (bIsThisExplorer)
|
||||
{
|
||||
#ifdef _WIN64
|
||||
if (IsUserOOBEOrCredentialReset())
|
||||
{
|
||||
IncrementDLLReferenceCount(hModule);
|
||||
bInstanced = TRUE;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
#endif
|
||||
BOOL desktopExists = IsDesktopWindowAlreadyPresent();
|
||||
#ifdef _WIN64
|
||||
if (!desktopExists && CrashCounterHandleEntryPoint())
|
||||
|
@ -1535,6 +1535,52 @@ BOOL ExtractMonitorByIndex(HMONITOR hMonitor, HDC hDC, LPRECT lpRect, MonitorOve
|
||||
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
|
||||
inline BOOL MaskCompare(PVOID pBuffer, LPCSTR lpPattern, LPCSTR lpMask)
|
||||
{
|
||||
|
@ -96,43 +96,12 @@ DEFINE_GUID(IID_ITrayUI,
|
||||
0xae, 0x7f, 0x54, 0x91, 0x99, 0xd6
|
||||
);
|
||||
|
||||
typedef interface ITrayUIComponent ITrayUIComponent;
|
||||
|
||||
DEFINE_GUID(IID_ITrayUIComponent,
|
||||
0x27775f88,
|
||||
0x01d3, 0x46ec, 0xa1, 0xc1,
|
||||
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);
|
||||
#pragma endregion
|
||||
|
||||
@ -278,6 +247,8 @@ static bool(*ShouldSystemUseDarkMode)();
|
||||
|
||||
static void(*GetThemeName)(void*, void*, void*);
|
||||
|
||||
extern DWORD (*CImmersiveColor_GetColorFunc)(int colorType);
|
||||
|
||||
void* ReadFromFile(wchar_t* wszFileName, DWORD* dwSize);
|
||||
|
||||
int ComputeFileHash(LPCWSTR filename, LPSTR hash, DWORD dwHash);
|
||||
@ -670,6 +641,8 @@ typedef struct _MonitorOverrideData
|
||||
} MonitorOverrideData;
|
||||
|
||||
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
|
||||
PVOID FindPattern(PVOID pBase, SIZE_T dwSize, LPCSTR lpPattern, LPCSTR lpMask);
|
||||
|
Loading…
Reference in New Issue
Block a user