From 8f84a965a650093a73b7d40aa156134a2ee50fd6 Mon Sep 17 00:00:00 2001 From: Amrsatrio Date: Mon, 11 Mar 2024 23:01:32 +0700 Subject: [PATCH] Taskbar10: Proper NeedsRo_PositionStartMenuForMonitor fix for 22621.2792+ (without relying on disabling a feature flag) --- ExplorerPatcher/StartMenu.c | 54 +++++++++++++++++++++++++++---------- ExplorerPatcher/StartMenu.h | 21 ++++++++++----- ExplorerPatcher/dllmain.c | 50 +++++++++------------------------- ExplorerPatcher/utility.c | 1 - 4 files changed, 67 insertions(+), 59 deletions(-) diff --git a/ExplorerPatcher/StartMenu.c b/ExplorerPatcher/StartMenu.c index 2e4597f5e..7a6415bd6 100644 --- a/ExplorerPatcher/StartMenu.c +++ b/ExplorerPatcher/StartMenu.c @@ -638,6 +638,18 @@ typedef struct instanceof_WindowsUdk_UI_Shell_ITaskbarSettings // : IInspectable } WindowsUdk_UI_Shell_ITaskbarSettings; static const WindowsUdk_UI_Shell_ITaskbarSettings instanceof_WindowsUdk_UI_Shell_ITaskbarSettings = { instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl }; +static unsigned __int64 FindTokenByHMONITOR(const StartMenuPositioningData* data, HMONITOR hMonitor) +{ + for (DWORD i = 0; i < *data->pMonitorCount; i++) + { + if (data->pMonitorList[i].hMonitor == hMonitor) + { + return data->pMonitorList[i].token; + } + } + return 0; +} + BOOL NeedsRo_PositionStartMenuForMonitor( HMONITOR hMonitor, HDC unused1, @@ -724,44 +736,58 @@ BOOL NeedsRo_PositionStartMenuForMonitor( if (data->operation == STARTMENU_POSITIONING_OPERATION_ADD) { + unsigned __int64 token = 0; if (interfaceVersion == 1) { hr = pTaskbarLayoutManager->lpVtbl->ReportMonitorAdded( pTaskbarLayoutManager, - hMonitor, + (unsigned __int64)hMonitor, &instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, NULL ); } else { - unsigned __int64 result = 0; hr = pTaskbarLayoutManager->lpVtbl->ReportMonitorAdded2( pTaskbarLayoutManager, - hMonitor, + (unsigned __int64)hMonitor, &instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, NULL, - &result + &token ); } - data->pMonitorList[InterlockedIncrement(data->pMonitorCount) - 1] = hMonitor; + MonitorListEntry entry = { + .hMonitor = hMonitor, + .token = token + }; + data->pMonitorList[InterlockedIncrement(data->pMonitorCount) - 1] = entry; printf("[Positioning] Added settings for monitor %p : %d\n", hMonitor, data->location); } else if (data->operation == STARTMENU_POSITIONING_OPERATION_CHANGE) { - hr = pTaskbarLayoutManager->lpVtbl->ReportSettingsForMonitor( - pTaskbarLayoutManager, - hMonitor, - &instanceof_WindowsUdk_UI_Shell_ITaskbarSettings - ); // TODO Doesn't work when the 2nd interface is used. Needs further investigation + hr = E_FAIL; + unsigned __int64 arg = interfaceVersion == 1 ? (unsigned __int64)hMonitor : FindTokenByHMONITOR(data, hMonitor); + if (arg) + { + hr = pTaskbarLayoutManager->lpVtbl->ReportSettingsForMonitor( + pTaskbarLayoutManager, + arg, + &instanceof_WindowsUdk_UI_Shell_ITaskbarSettings + ); + } printf("[Positioning] Changed settings for monitor: %p : %d\n", hMonitor, data->location); } else if (data->operation == STARTMENU_POSITIONING_OPERATION_REMOVE) { - hr = pTaskbarLayoutManager->lpVtbl->ReportMonitorRemoved( - pTaskbarLayoutManager, - hMonitor - ); + hr = E_FAIL; + unsigned __int64 arg = interfaceVersion == 1 ? (unsigned __int64)hMonitor : data->pMonitorList[data->i].token; + if (arg) + { + hr = pTaskbarLayoutManager->lpVtbl->ReportMonitorRemoved( + pTaskbarLayoutManager, + arg + ); + } printf("[Positioning] Removed settings for monitor: %p\n", hMonitor); } } diff --git a/ExplorerPatcher/StartMenu.h b/ExplorerPatcher/StartMenu.h index 8ecbe807f..51001d9d9 100644 --- a/ExplorerPatcher/StartMenu.h +++ b/ExplorerPatcher/StartMenu.h @@ -336,13 +336,13 @@ typedef struct WindowsUdk_UI_Shell_TaskbarLayoutManagerVtbl // : IInspectableVtb { HRESULT(STDMETHODCALLTYPE* ReportMonitorAdded)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, - __RPC__in HMONITOR hMonitor, + __RPC__in unsigned __int64 hMonitor, __RPC__in void* _instance_of_winrt_WindowsUdk_UI_Shell_ITaskbarSettings, __RPC__in void* _unknown_shellViewToRectMap); HRESULT(STDMETHODCALLTYPE* ReportMonitorAdded2)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, - __RPC__in HMONITOR hMonitor, + __RPC__in unsigned __int64 hMonitor, __RPC__in void* _instance_of_winrt_WindowsUdk_UI_Shell_ITaskbarSettings, __RPC__in void* _unknown_shellViewToRectMap, /* [out] */ __RPC__out unsigned __int64* result); @@ -350,21 +350,21 @@ typedef struct WindowsUdk_UI_Shell_TaskbarLayoutManagerVtbl // : IInspectableVtb HRESULT(STDMETHODCALLTYPE* ReportMonitorRemoved)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, - __RPC__in HMONITOR hMonitor); + __RPC__in unsigned __int64 hMonitor); HRESULT(STDMETHODCALLTYPE* ReportMonitorChanged)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, - __RPC__in HMONITOR hMonitor, + __RPC__in unsigned __int64 hMonitor, __RPC__in LPRECT _unknown_lpGeometry); HRESULT(STDMETHODCALLTYPE* ReportSettingsForMonitor)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, - __RPC__in HMONITOR hMonitor, + __RPC__in unsigned __int64 hMonitor, __RPC__in void* _instance_of_winrt_WindowsUdk_UI_Shell_ITaskbarSettings); HRESULT(STDMETHODCALLTYPE* ReportShellViewButtonBounds)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, - __RPC__in HMONITOR hMonitor, + __RPC__in unsigned __int64 hMonitor, __RPC__in void* _instanceof_winrt_WindowsUdk_UI_Shell_Bamo_ShellViewButtonBounds); END_INTERFACE @@ -375,12 +375,19 @@ interface WindowsUdk_UI_Shell_TaskbarLayoutManager // : IInspectable CONST_VTBL struct WindowsUdk_UI_Shell_TaskbarLayoutManagerVtbl* lpVtbl; }; +typedef struct _MonitorListEntry +{ + HMONITOR hMonitor; + unsigned __int64 token; +} MonitorListEntry; + typedef struct _StartMenuPositioningData { DWORD location; DWORD operation; DWORD* pMonitorCount; - HMONITOR* pMonitorList; + MonitorListEntry* pMonitorList; + DWORD i; } StartMenuPositioningData; #define STARTMENU_POSITIONING_OPERATION_ADD 0 diff --git a/ExplorerPatcher/dllmain.c b/ExplorerPatcher/dllmain.c index ca3f1f7d1..bd912908e 100644 --- a/ExplorerPatcher/dllmain.c +++ b/ExplorerPatcher/dllmain.c @@ -128,9 +128,6 @@ HANDLE hSwsSettingsChanged = NULL; HANDLE hSwsOpacityMaybeChanged = NULL; HANDLE hWin11AltTabInitialized = NULL; BYTE* lpShouldDisplayCCButton = NULL; -#define MAX_NUM_MONITORS 30 -HMONITOR hMonitorList[MAX_NUM_MONITORS]; -DWORD dwMonitorCount = 0; HANDLE hCanStartSws = NULL; DWORD dwWeatherViewMode = EP_WEATHER_VIEW_ICONTEXT; DWORD dwWeatherTemperatureUnit = EP_WEATHER_TUNIT_CELSIUS; @@ -221,6 +218,12 @@ DWORD dwUpdatePolicy = UPDATE_POLICY_DEFAULT; wchar_t* EP_TASKBAR_LENGTH_PROP_NAME = L"EPTBLEN"; HWND hWinXWnd; +#ifdef _WIN64 +#define MAX_NUM_MONITORS 30 +MonitorListEntry hMonitorList[MAX_NUM_MONITORS]; +DWORD dwMonitorCount = 0; +#endif + HRESULT WINAPI _DllRegisterServer(); HRESULT WINAPI _DllUnregisterServer(); HRESULT WINAPI _DllCanUnloadNow(); @@ -1826,15 +1829,18 @@ void UpdateStartMenuPositioning(LPARAM loIsShouldInitializeArray_hiIsShouldRoIni spd.pMonitorCount = &dwMonitorCount; spd.pMonitorList = hMonitorList; spd.location = dwPosCurrent; + spd.i = (DWORD)-1; if (bShouldInitialize) { spd.operation = STARTMENU_POSITIONING_OPERATION_REMOVE; unsigned int k = InterlockedAdd(&dwMonitorCount, 0); for (unsigned int i = 0; i < k; ++i) { - NeedsRo_PositionStartMenuForMonitor(hMonitorList[i], NULL, NULL, &spd); + spd.i = i; + NeedsRo_PositionStartMenuForMonitor(hMonitorList[i].hMonitor, NULL, NULL, &spd); } InterlockedExchange(&dwMonitorCount, 0); + spd.i = (DWORD)-1; spd.operation = STARTMENU_POSITIONING_OPERATION_ADD; } else @@ -2575,7 +2581,7 @@ INT64 Shell_TrayWndSubclassProc( } case WM_HOTKEY: { - if (wParam == 500 && lParam == MAKELPARAM(MOD_WIN, 'A') && global_rovi.dwBuildNumber >= 25921 && bOldTaskbar == 1) + if (wParam == 500 && lParam == MAKELPARAM(MOD_WIN, 'A') && (bOldTaskbar && bHideControlCenterButton || global_rovi.dwBuildNumber >= 25921 && bOldTaskbar == 1)) { InvokeActionCenter(); return 0; @@ -10081,7 +10087,7 @@ int RtlQueryFeatureConfigurationHook(UINT32 featureId, int sectionType, INT64* c #if !USE_MOMENT_3_FIXES_ON_MOMENT_2 case 26008830: // STTest { - if (bOldTaskbar) + if (bOldTaskbar == 1) { // Disable tablet optimized taskbar feature when using the Windows 10 taskbar // @@ -12677,7 +12683,7 @@ DWORD Inject(BOOL bIsExplorer) // - 23545.1000 BOOL bPerformMoment2Patches = IsWindows11Version22H2Build2134OrHigher(); #endif - if (!bOldTaskbar) + if (bOldTaskbar != 1) { bPerformMoment2Patches = FALSE; } @@ -12949,36 +12955,6 @@ DWORD Inject(BOOL bIsExplorer) VnPatchDelayIAT(hWindowsudkShellcommon, "ext-ms-win-security-slc-l1-1-0.dll", "SLGetWindowsInformationDWORD", windowsudkshellcommon_SLGetWindowsInformationDWORDHook); } } - - if (bOldTaskbar) - { - MODULEINFO mi; - GetModuleInformation(GetCurrentProcess(), hWindowsudkShellcommon, &mi, sizeof(MODULEINFO)); - - // Fix ReportMonitorRemoved in UpdateStartMenuPositioning crashing, *for now* - // We can't use our RtlQueryFeatureConfiguration() hook because our function didn't get called with the feature ID - // TODO Need to check again later after this feature flag has been removed - // E8 ?? ?? ?? ?? 48 8B 7D ?? 84 C0 74 ?? 48 8D 4F 08 - PBYTE match = FindPattern( - hWindowsudkShellcommon, - mi.SizeOfImage, - "\xE8\x00\x00\x00\x00\x48\x8B\x7D\x00\x84\xC0\x74\x00\x48\x8D\x4F\x08", - "x????xxx?xxx?xxxx" - ); - if (match) - { - match += 5 + *(int*)(match + 1); - windowsudkshellcommon_TaskbarMultiMonIsEnabledFunc = match; - printf("wil::details::FeatureImpl<__WilFeatureTraits_Feature_Servicing_TaskbarMultiMon_38545217>::__private_IsEnabled() = %llX\n", match - (PBYTE)hWindowsudkShellcommon); - rv = funchook_prepare( - funchook, - (void**)&windowsudkshellcommon_TaskbarMultiMonIsEnabledFunc, - windowsudkshellcommon_TaskbarMultiMonIsEnabledHook - ); - } - - printf("Setup windowsudk.shellcommon functions done\n"); - } } } diff --git a/ExplorerPatcher/utility.c b/ExplorerPatcher/utility.c index 16ed1f63f..fab1fe07a 100644 --- a/ExplorerPatcher/utility.c +++ b/ExplorerPatcher/utility.c @@ -1,7 +1,6 @@ #include "utility.h" #include #pragma comment(lib, "Wininet.lib") -#include RTL_OSVERSIONINFOW global_rovi; DWORD32 global_ubr;