1
0
mirror of https://github.com/valinet/ExplorerPatcher.git synced 2025-02-17 11:08:41 +01:00

Added option to choose language switcher flyout style; fixed #283

This commit is contained in:
Valentin Radu 2021-11-08 07:47:22 +02:00
parent ae11b73475
commit 241fde9c4f
5 changed files with 138 additions and 5 deletions

View File

@ -2,6 +2,18 @@
This document includes the same release notes as in the [Releases](https://github.com/valinet/ExplorerPatcher/releases) section on GitHub.
## 22000.282.33
Tested on build 22000.282.
#### New features
* Ability to choose language switcher flyout style (option available in the "Properties" - "System tray" section)
#### Fixes
* The key above the `Tab` key is now correctly identified for all keyboard layouts, so the per-application Windows 10 window switcher mode works correctly (#283)
## 22000.282.32
Tested on build 22000.282.

View File

@ -51,8 +51,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 22000,282,32,7
PRODUCTVERSION 22000,282,32,7
FILEVERSION 22000,282,33,0
PRODUCTVERSION 22000,282,33,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -69,12 +69,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "VALINET Solutions SRL"
VALUE "FileDescription", "ExplorerPatcher"
VALUE "FileVersion", "22000.282.32.7"
VALUE "FileVersion", "22000.282.33.0"
VALUE "InternalName", "ExplorerPatcher.dll"
VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved."
VALUE "OriginalFilename", "ExplorerPatcher.dll"
VALUE "ProductName", "ExplorerPatcher"
VALUE "ProductVersion", "22000.282.32.7"
VALUE "ProductVersion", "22000.282.33.0"
END
END
BLOCK "VarFileInfo"

View File

@ -29,6 +29,7 @@
#define _LIBVALINET_DEBUG_HOOKING_IATPATCH
#endif
#include <valinet/hooking/iatpatch.h>
#include <valinet/utility/memmem.h>
#define EP_CLSID "{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}"
@ -66,6 +67,7 @@ DWORD bClassicThemeMitigations = FALSE;
DWORD bHookStartMenu = TRUE;
DWORD bNoMenuAccelerator = FALSE;
DWORD bTaskbarMonitorOverride = 0;
DWORD dwIMEStyle = 0;
HMODULE hModule = NULL;
HANDLE hSettingsMonitorThread = NULL;
HANDLE hDelayedInjectionThread = NULL;
@ -2941,6 +2943,15 @@ void WINAPI LoadSettings(BOOL bIsExplorer)
&bTaskbarMonitorOverride,
&dwSize
);
dwSize = sizeof(DWORD);
RegQueryValueExW(
hKey,
TEXT("IMEStyle"),
0,
NULL,
&dwIMEStyle,
&dwSize
);
RegCloseKey(hKey);
}
@ -3613,6 +3624,7 @@ HRESULT explorer_DrawThemeTextEx(
#pragma endregion
#pragma region "Change clock links"
HINSTANCE explorer_ShellExecuteW(
HWND hwnd,
LPCWSTR lpOperation,
@ -3640,6 +3652,102 @@ HINSTANCE explorer_ShellExecuteW(
}
return ShellExecuteW(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd);
}
#pragma endregion
#pragma region "Change language UI style"
DEFINE_GUID(CLSID_InputSwitchControl,
0xB9BC2A50,
0x43C3, 0x41AA, 0xa0, 0x86,
0x5D, 0xB1, 0x4e, 0x18, 0x4b, 0xae
);
DEFINE_GUID(IID_InputSwitchControl,
0xB9BC2A50,
0x43C3, 0x41AA, 0xa0, 0x82,
0x5D, 0xB1, 0x4e, 0x18, 0x4b, 0xae
);
#define LANGUAGEUI_STYLE_DESKTOP 0
#define LANGUAGEUI_STYLE_TOUCHKEYBOARD 1
#define LANGUAGEUI_STYLE_LOGONUI 2
#define LANGUAGEUI_STYLE_UAC 3
#define LANGUAGEUI_STYLE_SETTINGSPANE 4
#define LANGUAGEUI_STYLE_OOBE 5
#define LANGUAGEUI_STYLE_OTHER 100
char mov_edx_val[6] = { 0xBA, 0x00, 0x00, 0x00, 0x00, 0xC3 };
char* ep_pf = NULL;
HRESULT explorer_CoCreateInstanceHook(
REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClsContext,
REFIID riid,
LPVOID* ppv
)
{
if (IsEqualCLSID(rclsid, &CLSID_InputSwitchControl) && IsEqualIID(riid, &IID_InputSwitchControl))
{
HRESULT hr = CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
if (SUCCEEDED(hr))
{
// Pff... how this works:
//
// * This `CoCreateInstance` call will get a pointer to an IInputSwitchControl interface
// (the call to here is made from `explorer!CTrayInputIndicator::_RegisterInputSwitch`);
// the next call on this pointer will be on the `IInputSwitchControl::Init` function.
//
// * `IInputSwitchControl::Init`'s second parameter is a number (x) which tells which
// language switcher UI to prepare (check `IsUtil::MapClientTypeToString` in
// `InputSwitch.dll`). "explorer" requests the "DESKTOP" UI (x = 0), which is the new
// Windows 11 UI; if we replace that number with something else, some other UI will
// be created
//
// * We cannot patch the vtable of the COM object because the executable is protected
// by control flow guard and we would make a jump to an invalid site (maybe there is
// some clever workaround fpr this as well, somehow telling the compiler to place a certain
// canary before our trampoline, so it matches with what the runtime support for CFG expects,
// but we'd have to keep that canary in sync with the one in explorer.exe, so not very
// future proof).
//
// * Taking advantage of the fact that the call to `IInputSwitchControl::Init` is the thing
// that happens right after we return from here, and looking on the disassembly, we see nothing
// else changes `rdx` (which is the second argument to a function call), basically x, besides the
// very `xor edx, edx` instruction before the call. Thus, we patch that out, and we also do
// `mov edx, whatever` here; afterwards, we do NOTHING else, but just return and hope that
// edx will stick
//
// * Needless to say this is **HIGHLY** amd64
char pattern[2] = { 0x33, 0xD2 };
DWORD dwOldProtect;
char* p_mov_edx_val = mov_edx_val;
if (!ep_pf)
{
ep_pf = memmem(_ReturnAddress(), 200, pattern, 2);
if (ep_pf)
{
// Cancel out `xor edx, edx`
VirtualProtect(ep_pf, 2, PAGE_EXECUTE_READWRITE, &dwOldProtect);
memset(ep_pf, 0x90, 2);
VirtualProtect(ep_pf, 2, dwOldProtect, &dwOldProtect);
}
VirtualProtect(p_mov_edx_val, 6, PAGE_EXECUTE_READWRITE, &dwOldProtect);
}
if (ep_pf)
{
// Craft a "function" which does `mov edx, whatever; ret` and call it
DWORD* pVal = mov_edx_val + 1;
*pVal = dwIMEStyle;
void(*pf_mov_edx_val)() = p_mov_edx_val;
pf_mov_edx_val();
}
}
return hr;
}
return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
}
#pragma endregion
DWORD InjectBasicFunctions(BOOL bIsExplorer, BOOL bInstall)
@ -4161,6 +4269,10 @@ __declspec(dllexport) DWORD WINAPI main(
VnPatchIAT(hExplorer, "user32.dll", "SetWindowCompositionAttribute", explorer_SetWindowCompositionAttribute);
}
//VnPatchDelayIAT(hExplorer, "ext-ms-win-rtcore-ntuser-window-ext-l1-1-0.dll", "CreateWindowExW", explorer_CreateWindowExW);
if (dwIMEStyle)
{
VnPatchIAT(hExplorer, "api-ms-win-core-com-l1-1-0.dll", "CoCreateInstance", explorer_CoCreateInstanceHook);
}
#ifdef USE_PRIVATE_INTERFACES

View File

@ -75,6 +75,15 @@
;x 1 Windows 7
"UseWin32TrayClockExperience"=dword:00000000
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher]
;c 6 Language switcher flyout style *
;x 0 Windows 11 (default)
;x 1 Windows 10
;x 2 "LOGONUI"
;x 3 "UAC"
;x 4 "SETTINGSPANE"
;x 5 "OOBE"
"IMEStyle"=dword:00000000
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher]
;a Choosing 'Open Network && Internet settings' when right clicking the
;c 3 network icon should open:
;x 0 Network section in the Settings app (default)

@ -1 +1 @@
Subproject commit ce9c34c82d01eca5c0f0ee63fc3ff18c83d38920
Subproject commit a293c851987c5323438c48c1eb1731f092089c84