Skip to content

Commit

Permalink
Taskbar10: Proper NeedsRo_PositionStartMenuForMonitor fix for 22621.2…
Browse files Browse the repository at this point in the history
…792+ (without relying on disabling a feature flag)
  • Loading branch information
Amrsatrio committed Mar 11, 2024
1 parent a0885c6 commit 8f84a96
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 59 deletions.
54 changes: 40 additions & 14 deletions ExplorerPatcher/StartMenu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
}
Expand Down
21 changes: 14 additions & 7 deletions ExplorerPatcher/StartMenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,35 +336,35 @@ 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);
};

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
Expand All @@ -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
Expand Down
50 changes: 13 additions & 37 deletions ExplorerPatcher/dllmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
//
Expand Down Expand Up @@ -12677,7 +12683,7 @@ DWORD Inject(BOOL bIsExplorer)
// - 23545.1000
BOOL bPerformMoment2Patches = IsWindows11Version22H2Build2134OrHigher();
#endif
if (!bOldTaskbar)
if (bOldTaskbar != 1)
{
bPerformMoment2Patches = FALSE;
}
Expand Down Expand Up @@ -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");
}
}
}

Expand Down
1 change: 0 additions & 1 deletion ExplorerPatcher/utility.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "utility.h"
#include <Wininet.h>
#pragma comment(lib, "Wininet.lib")
#include <TlHelp32.h>

RTL_OSVERSIONINFOW global_rovi;
DWORD32 global_ubr;
Expand Down

0 comments on commit 8f84a96

Please sign in to comment.