mirror of
https://github.com/valinet/ExplorerPatcher.git
synced 2025-02-09 15:38:21 +01:00
742 lines
25 KiB
C
742 lines
25 KiB
C
#include "StartMenu.h"
|
|
|
|
void OpenStartOnMonitor(HMONITOR monitor)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IUnknown* pImmersiveShell = NULL;
|
|
hr = CoCreateInstance(
|
|
&CLSID_ImmersiveShell,
|
|
NULL,
|
|
CLSCTX_NO_CODE_DOWNLOAD | CLSCTX_LOCAL_SERVER,
|
|
&IID_IServiceProvider,
|
|
&pImmersiveShell
|
|
);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IImmersiveMonitorService* pMonitorService = NULL;
|
|
IUnknown_QueryService(
|
|
pImmersiveShell,
|
|
&SID_IImmersiveMonitorService,
|
|
&IID_IImmersiveMonitorService,
|
|
&pMonitorService
|
|
);
|
|
if (pMonitorService)
|
|
{
|
|
IUnknown* pMonitor = NULL;
|
|
pMonitorService->lpVtbl->GetFromHandle(
|
|
pMonitorService,
|
|
monitor,
|
|
&pMonitor
|
|
);
|
|
IImmersiveLauncher10RS* pLauncher = NULL;
|
|
IUnknown_QueryService(
|
|
pImmersiveShell,
|
|
&SID_ImmersiveLauncher,
|
|
&IID_IImmersiveLauncher10RS,
|
|
&pLauncher
|
|
);
|
|
if (pLauncher)
|
|
{
|
|
BOOL bIsVisible = FALSE;
|
|
pLauncher->lpVtbl->IsVisible(pLauncher, &bIsVisible);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (!bIsVisible)
|
|
{
|
|
if (pMonitor)
|
|
{
|
|
pLauncher->lpVtbl->ConnectToMonitor(pLauncher, pMonitor);
|
|
}
|
|
pLauncher->lpVtbl->ShowStartView(pLauncher, 11, 0);
|
|
}
|
|
else
|
|
{
|
|
pLauncher->lpVtbl->Dismiss(pLauncher);
|
|
}
|
|
}
|
|
pLauncher->lpVtbl->Release(pLauncher);
|
|
}
|
|
if (pMonitor)
|
|
{
|
|
pMonitor->lpVtbl->Release(pMonitor);
|
|
}
|
|
pMonitorService->lpVtbl->Release(pMonitorService);
|
|
}
|
|
pImmersiveShell->lpVtbl->Release(pImmersiveShell);
|
|
}
|
|
}
|
|
|
|
typedef struct _MonitorOverrideData
|
|
{
|
|
DWORD cbIndex;
|
|
DWORD dwIndex;
|
|
HMONITOR hMonitor;
|
|
} MonitorOverrideData;
|
|
|
|
BOOL ExtractMonitorByIndex(HMONITOR hMonitor, HDC hDC, LPRECT lpRect, MonitorOverrideData* mod)
|
|
{
|
|
POINT pt; pt.x = 0; pt.y = 0;
|
|
if (MonitorFromPoint(pt, MONITOR_DEFAULTTONULL) == hMonitor)
|
|
{
|
|
return TRUE;
|
|
}
|
|
if (mod->cbIndex == mod->dwIndex)
|
|
{
|
|
mod->hMonitor = hMonitor;
|
|
return FALSE;
|
|
}
|
|
mod->cbIndex++;
|
|
return TRUE;
|
|
}
|
|
|
|
LRESULT CALLBACK OpenStartOnCurentMonitorThreadHook(
|
|
int code,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
if (code == HC_ACTION && wParam)
|
|
{
|
|
MSG* msg = (MSG*)lParam;
|
|
if (GetSystemMetrics(SM_CMONITORS) >= 2 && msg->message == WM_SYSCOMMAND && (msg->wParam & 0xFFF0) == SC_TASKLIST)
|
|
{
|
|
printf("Position Start\n");
|
|
if (bMonitorOverride == 1)
|
|
{
|
|
goto finish;
|
|
}
|
|
|
|
/*DWORD dwStatus = 0;
|
|
DWORD dwSize = sizeof(DWORD);
|
|
HMODULE hModule = GetModuleHandle(TEXT("Shlwapi.dll"));
|
|
FARPROC SHRegGetValueFromHKCUHKLMFunc = GetProcAddress(hModule, "SHRegGetValueFromHKCUHKLM");
|
|
if (!SHRegGetValueFromHKCUHKLMFunc || SHRegGetValueFromHKCUHKLMFunc(
|
|
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage"),
|
|
TEXT("MonitorOverride"),
|
|
SRRF_RT_REG_DWORD,
|
|
NULL,
|
|
&dwStatus,
|
|
(LPDWORD)(&dwSize)
|
|
) != ERROR_SUCCESS || dwStatus == 1)
|
|
{
|
|
goto finish;
|
|
}*/
|
|
|
|
HMONITOR monitor = NULL;
|
|
if (!bMonitorOverride)
|
|
{
|
|
DWORD pts = GetMessagePos();
|
|
POINT pt;
|
|
pt.x = GET_X_LPARAM(pts);
|
|
pt.y = GET_Y_LPARAM(pts);
|
|
printf("!! %d %d\n", pt.x, pt.y);
|
|
monitor = MonitorFromPoint(
|
|
pt,
|
|
MONITOR_DEFAULTTONULL
|
|
);
|
|
}
|
|
else
|
|
{
|
|
MonitorOverrideData mod;
|
|
mod.cbIndex = 2;
|
|
mod.dwIndex = bMonitorOverride;
|
|
mod.hMonitor = NULL;
|
|
EnumDisplayMonitors(NULL, NULL, ExtractMonitorByIndex, &mod);
|
|
if (mod.hMonitor == NULL)
|
|
{
|
|
POINT pt; pt.x = 0; pt.y = 0;
|
|
monitor = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
|
|
}
|
|
else
|
|
{
|
|
monitor = mod.hMonitor;
|
|
}
|
|
}
|
|
OpenStartOnMonitor(monitor);
|
|
|
|
msg->message = WM_NULL;
|
|
}
|
|
}
|
|
finish:
|
|
return CallNextHookEx(NULL, code, wParam, lParam);
|
|
}
|
|
|
|
DWORD OpenStartOnCurentMonitorThread(OpenStartOnCurentMonitorThreadParams* unused)
|
|
{
|
|
HANDLE hEvent = CreateEventW(0, 0, 0, L"ShellDesktopSwitchEvent");
|
|
if (!hEvent)
|
|
{
|
|
printf("Failed to start \"Open Start on current monitor\" thread.\n");
|
|
return 0;
|
|
}
|
|
WaitForSingleObject(
|
|
hEvent,
|
|
INFINITE
|
|
);
|
|
printf("Started \"Open Start on current monitor\" thread.\n");
|
|
HWND g_ProgWin = NULL;
|
|
while (!g_ProgWin)
|
|
{
|
|
g_ProgWin = GetShellWindow();
|
|
if (!g_ProgWin)
|
|
{
|
|
Sleep(100);
|
|
}
|
|
}
|
|
printf("Progman: %d\n", g_ProgWin);
|
|
DWORD progThread = GetWindowThreadProcessId(
|
|
g_ProgWin,
|
|
NULL
|
|
);
|
|
HHOOK g_ProgHook = SetWindowsHookEx(
|
|
WH_GETMESSAGE,
|
|
OpenStartOnCurentMonitorThreadHook,
|
|
NULL,
|
|
progThread
|
|
);
|
|
printf("Progman hook: %d\n", g_ProgHook);
|
|
MSG msg = { 0 };
|
|
while (GetMessage(&msg, NULL, 0, 0))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
printf("Ended \"Open Start on current monitor\" thread.\n");
|
|
}
|
|
|
|
DWORD OpenStartAtLogonThread(OpenStartAtLogonThreadParams* unused)
|
|
{
|
|
HANDLE hEvent = CreateEvent(0, 0, 0, L"ShellDesktopSwitchEvent");
|
|
if (!hEvent)
|
|
{
|
|
printf("Failed to start \"Open Start at Logon\" thread.\n");
|
|
return 0;
|
|
}
|
|
WaitForSingleObject(
|
|
hEvent,
|
|
INFINITE
|
|
);
|
|
printf("Started \"Open Start at Logon\" thread.\n");
|
|
|
|
if (!bOpenAtLogon)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/*DWORD dwStatus = 0;
|
|
DWORD dwSize = sizeof(DWORD);
|
|
HMODULE hModule = GetModuleHandle(TEXT("Shlwapi"));
|
|
FARPROC SHRegGetValueFromHKCUHKLMFunc = GetProcAddress(hModule, "SHRegGetValueFromHKCUHKLM");
|
|
if (!SHRegGetValueFromHKCUHKLMFunc || SHRegGetValueFromHKCUHKLMFunc(
|
|
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage"),
|
|
TEXT("OpenAtLogon"),
|
|
SRRF_RT_REG_DWORD,
|
|
NULL,
|
|
&dwStatus,
|
|
(LPDWORD)(&dwSize)
|
|
) != ERROR_SUCCESS || dwStatus == 0)
|
|
{
|
|
return 0;
|
|
}*/
|
|
|
|
POINT pt;
|
|
pt.x = 0;
|
|
pt.y = 0;
|
|
HMONITOR monitor = MonitorFromPoint(
|
|
pt,
|
|
MONITOR_DEFAULTTOPRIMARY
|
|
);
|
|
OpenStartOnMonitor(monitor);
|
|
|
|
printf("Ended \"Open Start at Logon\" thread.\n");
|
|
}
|
|
|
|
DWORD WINAPI HookStartMenu(HookStartMenuParams* params)
|
|
{
|
|
printf("Started \"Hook Start Menu\" thread.\n");
|
|
|
|
TCHAR wszKnownPath[MAX_PATH];
|
|
GetWindowsDirectoryW(wszKnownPath, MAX_PATH);
|
|
wcscat_s(wszKnownPath, MAX_PATH, L"\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\StartMenuExperienceHost.exe");
|
|
|
|
while (TRUE)
|
|
{
|
|
unsigned int retry = 0;
|
|
HANDLE hProcess, hSnapshot;
|
|
PROCESSENTRY32 pe32;
|
|
while (TRUE)
|
|
{
|
|
hProcess = NULL;
|
|
hSnapshot = NULL;
|
|
ZeroMemory(&pe32, sizeof(PROCESSENTRY32));
|
|
pe32.dwSize = sizeof(PROCESSENTRY32);
|
|
hSnapshot = CreateToolhelp32Snapshot(
|
|
TH32CS_SNAPPROCESS,
|
|
0
|
|
);
|
|
if (Process32First(hSnapshot, &pe32) == TRUE)
|
|
{
|
|
do
|
|
{
|
|
if (!wcscmp(pe32.szExeFile, TEXT("StartMenuExperienceHost.exe")))
|
|
{
|
|
hProcess = OpenProcess(
|
|
PROCESS_QUERY_LIMITED_INFORMATION |
|
|
PROCESS_VM_OPERATION |
|
|
PROCESS_VM_READ |
|
|
PROCESS_VM_WRITE |
|
|
PROCESS_CREATE_THREAD |
|
|
SYNCHRONIZE,
|
|
FALSE,
|
|
pe32.th32ProcessID
|
|
);
|
|
if (!hProcess)
|
|
{
|
|
printf("Unable to open handle to StartMenuExperienceHost.exe.\n");
|
|
CloseHandle(hSnapshot);
|
|
Sleep(params->dwTimeout);
|
|
continue;
|
|
}
|
|
TCHAR wszProcessPath[MAX_PATH];
|
|
DWORD dwLength = MAX_PATH;
|
|
QueryFullProcessImageNameW(
|
|
hProcess,
|
|
0,
|
|
wszProcessPath,
|
|
&dwLength
|
|
);
|
|
if (!_wcsicmp(wszProcessPath, wszKnownPath))
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
CloseHandle(hProcess);
|
|
hProcess = NULL;
|
|
}
|
|
}
|
|
} while (Process32Next(hSnapshot, &pe32) == TRUE);
|
|
}
|
|
if (hSnapshot)
|
|
{
|
|
CloseHandle(hSnapshot);
|
|
}
|
|
if (hProcess)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
retry++;
|
|
if (retry > 20) return 0;
|
|
Sleep(params->dwTimeout);
|
|
}
|
|
}
|
|
printf("[StartMenu] Process found.\n");
|
|
LPVOID lpRemotePath = VirtualAllocEx(
|
|
hProcess,
|
|
NULL,
|
|
MAX_PATH,
|
|
MEM_COMMIT | MEM_RESERVE,
|
|
PAGE_READWRITE
|
|
);
|
|
if (!lpRemotePath)
|
|
{
|
|
printf("[StartMenu] Unable to allocate path memory.\n");
|
|
Sleep(1000);
|
|
continue;
|
|
}
|
|
printf("[StartMenu] Allocated path memory.\n");
|
|
if (!WriteProcessMemory(
|
|
hProcess,
|
|
lpRemotePath,
|
|
(void*)params->wszModulePath,
|
|
MAX_PATH,
|
|
NULL
|
|
))
|
|
{
|
|
printf("[StartMenu] Unable to write path.\n");
|
|
Sleep(params->dwTimeout);
|
|
continue;
|
|
}
|
|
wprintf(L"[StartMenu] Wrote path: %s.\n", params->wszModulePath);
|
|
//Sleep(8000);
|
|
|
|
BYTE shellcode[] = {
|
|
// sub rsp, 28h
|
|
//// 0x48, 0x83, 0xec, 0x28,
|
|
// mov [rsp + 18h], rax
|
|
//// 0x48, 0x89, 0x44, 0x24, 0x18,
|
|
// mov [rsp + 10h], rcx
|
|
//// 0x48, 0x89, 0x4c, 0x24, 0x10,
|
|
// int 3
|
|
//0xcc,
|
|
|
|
// sub rsp, 28h
|
|
0x48, 0x83, 0xec, 0x28,
|
|
// mov rcx, 1111111111111111h; placeholder for DLL path
|
|
0x48, 0xb9, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
|
|
// mov rax, 2222222222222222h; placeholder for "LoadLibraryW" address
|
|
0x48, 0xb8, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
|
|
// call rax
|
|
0xff, 0xd0,
|
|
// cmp rax, 0
|
|
0x48, 0x83, 0xF8, 0x00,
|
|
// jz; skip if LoadLibraryW failed
|
|
0x74, 0x14,
|
|
// mov rcx, 4444444444444444h; placeholder for entry point
|
|
0x48, 0xb9, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
// add rax, rcx
|
|
0x48, 0x01, 0xc8,
|
|
// call rax
|
|
0xff, 0xd0,
|
|
// add rsp, 28h
|
|
0x48, 0x83, 0xc4, 0x28,
|
|
// ret
|
|
0xc3,
|
|
// mov rax, 5555555555555555h; placeholder for "GetLastError" address
|
|
0x48, 0xb8, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
|
|
// call rax
|
|
0xff, 0xd0,
|
|
// add rsp, 28h
|
|
0x48, 0x83, 0xc4, 0x28,
|
|
// ret
|
|
0xc3,
|
|
|
|
// mov rcx, [rsp + 10h]
|
|
//// 0x48, 0x8b, 0x4c, 0x24, 0x10,
|
|
// mov rax, [rsp + 18h]
|
|
//// 0x48, 0x8b, 0x44, 0x24, 0x18,
|
|
// add rsp, 28h
|
|
//// 0x48, 0x83, 0xc4, 0x28,
|
|
// mov r11, 33333333333333333h; placeholder for the original RIP
|
|
0x49, 0xbb, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
|
|
// jmp r11
|
|
0x41, 0xff, 0xe3
|
|
};
|
|
uintptr_t pattern = 0;
|
|
pattern = 0x1111111111111111;
|
|
*(LPVOID*)(memmem(shellcode, sizeof(shellcode), &pattern, sizeof(uintptr_t))) = lpRemotePath;
|
|
pattern = 0x2222222222222222;
|
|
*(LPVOID*)(memmem(shellcode, sizeof(shellcode), &pattern, sizeof(uintptr_t))) = LoadLibraryW;
|
|
pattern = 0x4444444444444444;
|
|
*(LPVOID*)(memmem(shellcode, sizeof(shellcode), &pattern, sizeof(uintptr_t))) = ((uintptr_t)params->proc - (uintptr_t)params->hModule);
|
|
pattern = 0x5555555555555555;
|
|
*(LPVOID*)(memmem(shellcode, sizeof(shellcode), &pattern, sizeof(uintptr_t))) = GetLastError;
|
|
|
|
LPVOID lpRemoteCode = VirtualAllocEx(
|
|
hProcess,
|
|
NULL,
|
|
sizeof(shellcode),
|
|
MEM_COMMIT | MEM_RESERVE,
|
|
PAGE_EXECUTE_READWRITE
|
|
);
|
|
if (!lpRemoteCode)
|
|
{
|
|
printf("[StartMenu] Unable to allocate shellcode memory.\n");
|
|
Sleep(1000);
|
|
continue;
|
|
}
|
|
printf("[StartMenu] Allocated shellcode memory %p.\n", lpRemoteCode);
|
|
if (!WriteProcessMemory(
|
|
hProcess,
|
|
lpRemoteCode,
|
|
shellcode,
|
|
sizeof(shellcode),
|
|
NULL
|
|
))
|
|
{
|
|
printf("[StartMenu] Unable to write shellcode.\n");
|
|
Sleep(params->dwTimeout);
|
|
continue;
|
|
}
|
|
wprintf(L"[StartMenu] Wrote shellcode.\n");
|
|
|
|
wprintf(L"[StartMenu] Size of image: %d\n", RtlImageNtHeader(params->hModule)->OptionalHeader.SizeOfImage);
|
|
|
|
HANDLE hThread = CreateRemoteThread(
|
|
hProcess,
|
|
NULL,
|
|
0,
|
|
lpRemoteCode,
|
|
0,
|
|
0,
|
|
NULL
|
|
);
|
|
if (!hThread)
|
|
{
|
|
printf("[StartMenu] Unable to inject DLL.\n");
|
|
Sleep(params->dwTimeout);
|
|
continue;
|
|
}
|
|
printf("[StartMenu] Injected DLL.\n");
|
|
if (WaitForSingleObject(hThread, INFINITE) != WAIT_OBJECT_0)
|
|
{
|
|
printf("[StartMenu] Unable to determine LoadLibrary outcome.\n");
|
|
Sleep(params->dwTimeout);
|
|
continue;
|
|
}
|
|
DWORD dwExitCode = 10;
|
|
GetExitCodeThread(hThread, &dwExitCode);
|
|
CloseHandle(hThread);
|
|
printf("[StartMenu] Library initialization returned: 0x%x.\n", dwExitCode);
|
|
|
|
WaitForSingleObject(
|
|
hProcess,
|
|
INFINITE
|
|
);
|
|
CloseHandle(hProcess);
|
|
}
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented(void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static ULONG STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_AddRefRelease(void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_GetAlignment_Left(
|
|
void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings,
|
|
DWORD* pAlignment
|
|
)
|
|
{
|
|
*pAlignment = 0;
|
|
return 0;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_GetAlignment_Center(
|
|
void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings,
|
|
DWORD* pAlignment
|
|
)
|
|
{
|
|
*pAlignment = 1;
|
|
return 0;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_GetLocation_Left(
|
|
void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings,
|
|
DWORD* pLocation
|
|
)
|
|
{
|
|
*pLocation = 0;
|
|
return 0;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_GetLocation_Center(
|
|
void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings,
|
|
DWORD* pLocation
|
|
)
|
|
{
|
|
*pLocation = 1;
|
|
return 0;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_GetSearchMode(
|
|
void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings,
|
|
DWORD* pSearchMode
|
|
)
|
|
{
|
|
*pSearchMode = 1;
|
|
return 0;
|
|
}
|
|
|
|
static void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[41] = { // : IInspectableVtbl
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_AddRefRelease,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_AddRefRelease,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_GetAlignment_Left,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_GetLocation_Left,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_GetSearchMode,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented,
|
|
WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented
|
|
};
|
|
typedef struct instanceof_WindowsUdk_UI_Shell_ITaskbarSettings // : IInspectable
|
|
{
|
|
void* lpVtbl;
|
|
} WindowsUdk_UI_Shell_ITaskbarSettings;
|
|
static const WindowsUdk_UI_Shell_ITaskbarSettings instanceof_WindowsUdk_UI_Shell_ITaskbarSettings = { instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl };
|
|
|
|
BOOL NeedsRo_PositionStartMenuForMonitor(
|
|
HMONITOR hMonitor,
|
|
HDC unused1,
|
|
LPRECT unused2,
|
|
StartMenuPositioningData* data
|
|
)
|
|
{
|
|
// For this to have any chance to succeed, the Windows Runtime has to be
|
|
// already initialized on the calling thread, concurrency model RO_INIT_MULTITHREADED
|
|
|
|
HRESULT hr = S_OK;
|
|
HSTRING_HEADER hstringHeader_of_WindowsUdk_UI_Shell_TaskbarLayout;
|
|
HSTRING hstring_of_WindowsUdk_UI_Shell_TaskbarLayout = NULL;
|
|
WindowsUdk_UI_Shell_TaskbarLayoutStatics* pTaskbarLayoutFactory = NULL;
|
|
IInspectable* pTaskbarLayout = NULL;
|
|
WindowsUdk_UI_Shell_TaskbarLayoutManager* pTaskbarLayoutManager = NULL;
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = WindowsCreateStringReference(
|
|
L"WindowsUdk.UI.Shell.TaskbarLayout",
|
|
33,
|
|
&hstringHeader_of_WindowsUdk_UI_Shell_TaskbarLayout,
|
|
&hstring_of_WindowsUdk_UI_Shell_TaskbarLayout
|
|
);
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = RoGetActivationFactory(
|
|
hstring_of_WindowsUdk_UI_Shell_TaskbarLayout,
|
|
&IID_WindowsUdk_UI_Shell_TaskbarLayoutStatics,
|
|
&pTaskbarLayoutFactory
|
|
);
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//hr = (*(HRESULT(**)(INT64, INT64*))(*(INT64*)pTaskbarLayoutFactory + 48))(pTaskbarLayoutFactory, &v12);
|
|
hr = pTaskbarLayoutFactory->lpVtbl->get_Current(pTaskbarLayoutFactory, &pTaskbarLayout);
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
/*hr = (**(HRESULT(***)(INT64, GUID*, INT64*))v12)(
|
|
v12,
|
|
&IID_WindowsUdk_UI_Shell_ITaskbarLayoutManager,
|
|
(INT64*)&v13
|
|
);*/
|
|
hr = pTaskbarLayout->lpVtbl->QueryInterface(
|
|
pTaskbarLayout,
|
|
&IID_WindowsUdk_UI_Shell_ITaskbarLayoutManager,
|
|
&pTaskbarLayoutManager
|
|
);
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//hr = (*(HRESULT(**)(INT64, HMONITOR, INT64(***)(), INT64))(*v13 + 48 + (sizeof(uintptr_t) * data->operation)))(v13, hMonitor, &p, 0);
|
|
|
|
// Filling a vtable for a winrt::WindowsUdk::UI::Shell::ITaskbarSettings interface
|
|
// some info about it can be found in method:
|
|
// > WindowsUdk::UI::Shell::Bamo::TaskbarLayoutBamoPrincipal::SetSettings
|
|
// from windowsudk.shellcommon.dll
|
|
// useful refrences: https://blog.magnusmontin.net/2017/12/30/minimal-uwp-wrl-xaml-app/
|
|
// registry: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsRuntime\ActivatableClassId\WindowsUdk.UI.Shell.TaskbarLayout
|
|
if (data->location)
|
|
{
|
|
instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[6] = WindowsUdk_UI_Shell_ITaskbarSettings_GetAlignment_Center;
|
|
instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[10] = WindowsUdk_UI_Shell_ITaskbarSettings_GetLocation_Center;
|
|
}
|
|
else
|
|
{
|
|
instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[6] = WindowsUdk_UI_Shell_ITaskbarSettings_GetAlignment_Left;
|
|
instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[10] = WindowsUdk_UI_Shell_ITaskbarSettings_GetLocation_Left;
|
|
}
|
|
instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[14] = WindowsUdk_UI_Shell_ITaskbarSettings_GetSearchMode;
|
|
|
|
if (data->operation == STARTMENU_POSITIONING_OPERATION_ADD)
|
|
{
|
|
hr = pTaskbarLayoutManager->lpVtbl->ReportMonitorAdded(
|
|
pTaskbarLayoutManager,
|
|
hMonitor,
|
|
&instanceof_WindowsUdk_UI_Shell_ITaskbarSettings,
|
|
NULL
|
|
);
|
|
data->pMonitorList[InterlockedIncrement(data->pMonitorCount) - 1] = hMonitor;
|
|
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
|
|
);
|
|
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
|
|
);
|
|
printf("[Positioning] Removed settings for monitor: %p\n", hMonitor);
|
|
}
|
|
}
|
|
if (pTaskbarLayoutManager)
|
|
{
|
|
pTaskbarLayoutManager->lpVtbl->Release(pTaskbarLayoutManager);
|
|
pTaskbarLayoutManager = NULL;
|
|
}
|
|
if (pTaskbarLayout)
|
|
{
|
|
pTaskbarLayout->lpVtbl->Release(pTaskbarLayout);
|
|
pTaskbarLayout = NULL;
|
|
}
|
|
if (pTaskbarLayoutFactory)
|
|
{
|
|
pTaskbarLayoutFactory->lpVtbl->Release(pTaskbarLayoutFactory);
|
|
pTaskbarLayoutFactory = NULL;
|
|
}
|
|
if (hstring_of_WindowsUdk_UI_Shell_TaskbarLayout)
|
|
{
|
|
WindowsDeleteString(hstring_of_WindowsUdk_UI_Shell_TaskbarLayout);
|
|
hstring_of_WindowsUdk_UI_Shell_TaskbarLayout = NULL;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
DWORD GetStartMenuPosition(FARPROC SHRegGetValueFromHKCUHKLMFunc)
|
|
{
|
|
DWORD dwSize = sizeof(DWORD);
|
|
|
|
DWORD dwTaskbarAl = 1;
|
|
if (!SHRegGetValueFromHKCUHKLMFunc || SHRegGetValueFromHKCUHKLMFunc(
|
|
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"),
|
|
TEXT("TaskbarAl"),
|
|
SRRF_RT_REG_DWORD,
|
|
NULL,
|
|
&dwTaskbarAl,
|
|
(LPDWORD)(&dwSize)
|
|
) != ERROR_SUCCESS)
|
|
{
|
|
dwTaskbarAl = 1;
|
|
}
|
|
|
|
return dwTaskbarAl;
|
|
} |