1
0
mirror of https://github.com/valinet/ExplorerPatcher.git synced 2025-02-09 15:38:21 +01:00

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;
}