diff --git a/ExplorerPatcher/ExplorerPatcher.vcxproj b/ExplorerPatcher/ExplorerPatcher.vcxproj index ba2daba..31f56dd 100644 --- a/ExplorerPatcher/ExplorerPatcher.vcxproj +++ b/ExplorerPatcher/ExplorerPatcher.vcxproj @@ -292,7 +292,7 @@ true true - + true true diff --git a/ExplorerPatcher/Taskbar10.c b/ExplorerPatcher/Taskbar10.c deleted file mode 100644 index 6c064a0..0000000 --- a/ExplorerPatcher/Taskbar10.c +++ /dev/null @@ -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\) 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 diff --git a/ExplorerPatcher/Taskbar10.cpp b/ExplorerPatcher/Taskbar10.cpp new file mode 100644 index 0000000..43d21ff --- /dev/null +++ b/ExplorerPatcher/Taskbar10.cpp @@ -0,0 +1,267 @@ +#include "utility.h" + +#include + +#include +#include +#include + +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\) 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, 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 instance; + RETURN_IF_FAILED(Microsoft::WRL::MakeAndInitialize(&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 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 diff --git a/ExplorerPatcher/dllmain.c b/ExplorerPatcher/dllmain.c index f620431..47c02c0 100644 --- a/ExplorerPatcher/dllmain.c +++ b/ExplorerPatcher/dllmain.c @@ -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()) diff --git a/ExplorerPatcher/utility.c b/ExplorerPatcher/utility.c index fab1fe0..08a7927 100644 --- a/ExplorerPatcher/utility.c +++ b/ExplorerPatcher/utility.c @@ -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) { diff --git a/ExplorerPatcher/utility.h b/ExplorerPatcher/utility.h index b3de9a4..a84e458 100644 --- a/ExplorerPatcher/utility.h +++ b/ExplorerPatcher/utility.h @@ -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);