Browse Source

Fixes #2 (Win+X combination is now handled and opens the power user menu)

pull/20/head 22000.1.0.4
Valentin Radu 5 years ago
parent
commit
c850e5063a
  1. 8
      ExplorerPatcher/ExplorerPatcher.rc
  2. 8
      ExplorerPatcherLibrary/ExplorerPatcherLibrary.rc
  3. 122
      ExplorerPatcherLibrary/dllmain.c
  4. 5
      README.md

8
ExplorerPatcher/ExplorerPatcher.rc

@ -51,8 +51,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 22000,1,0,3 FILEVERSION 22000,1,0,4
PRODUCTVERSION 22000,1,0,3 PRODUCTVERSION 22000,1,0,4
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -69,12 +69,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "VALINET Solutions SRL" VALUE "CompanyName", "VALINET Solutions SRL"
VALUE "FileDescription", "ExplorerPatcher Daemon" VALUE "FileDescription", "ExplorerPatcher Daemon"
VALUE "FileVersion", "22000.1.0.3" VALUE "FileVersion", "22000.1.0.4"
VALUE "InternalName", "ExplorerPatcher.exe" VALUE "InternalName", "ExplorerPatcher.exe"
VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved." VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved."
VALUE "OriginalFilename", "ExplorerPatcher.exe" VALUE "OriginalFilename", "ExplorerPatcher.exe"
VALUE "ProductName", "ExplorerPatcher" VALUE "ProductName", "ExplorerPatcher"
VALUE "ProductVersion", "22000.1.0.3" VALUE "ProductVersion", "22000.1.0.4"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

8
ExplorerPatcherLibrary/ExplorerPatcherLibrary.rc

@ -51,8 +51,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 22000,1,0,3 FILEVERSION 22000,1,0,4
PRODUCTVERSION 22000,1,0,3 PRODUCTVERSION 22000,1,0,4
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -69,12 +69,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "VALINET Solutions SRL" VALUE "CompanyName", "VALINET Solutions SRL"
VALUE "FileDescription", "ExplorerPatcher Library" VALUE "FileDescription", "ExplorerPatcher Library"
VALUE "FileVersion", "22000.1.0.3" VALUE "FileVersion", "22000.1.0.4"
VALUE "InternalName", "ExplorerPatcherLibrary.dll" VALUE "InternalName", "ExplorerPatcherLibrary.dll"
VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved." VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved."
VALUE "OriginalFilename", "ExplorerPatcherLibrary.dll" VALUE "OriginalFilename", "ExplorerPatcherLibrary.dll"
VALUE "ProductName", "WinOverview" VALUE "ProductName", "WinOverview"
VALUE "ProductVersion", "22000.1.0.3" VALUE "ProductVersion", "22000.1.0.4"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

122
ExplorerPatcherLibrary/dllmain.c

@ -16,8 +16,8 @@
funchook_t* funchook = NULL; funchook_t* funchook = NULL;
HMODULE hModule = NULL; HMODULE hModule = NULL;
HWND messageWindow = NULL; HWND messageWindow = NULL;
HANDLE hIsWinXShown = NULL;
INT64 lockEnsureWinXHotkeyOnlyOnce;
static HWND(WINAPI* CreateWindowInBand)( static HWND(WINAPI* CreateWindowInBand)(
_In_ DWORD dwExStyle, _In_ DWORD dwExStyle,
@ -85,6 +85,12 @@ static INT64(*CImmersiveContextMenuOwnerDrawHelper_s_ContextMenuWndProc)(
BOOL* a5 BOOL* a5
); );
static INT64(*CTray_HandleGlobalHotkeyFunc)(
void* _this,
unsigned int a2,
unsigned int a3
);
DEFINE_GUID(IID_ILauncherTipContextMenu, DEFINE_GUID(IID_ILauncherTipContextMenu,
0xb8c1db5f, 0xb8c1db5f,
0xcbb3, 0x48bc, 0xaf, 0xd9, 0xcbb3, 0x48bc, 0xaf, 0xd9,
@ -249,7 +255,7 @@ interface IImmersiveLauncher10RS
HANDLE hThread;
LRESULT CALLBACK CLauncherTipContextMenu_WndProc( LRESULT CALLBACK CLauncherTipContextMenu_WndProc(
_In_ HWND hWnd, _In_ HWND hWnd,
@ -434,7 +440,7 @@ DWORD ShowLauncherTipContextMenu(
0 0
); );
free(params); free(params);
hThread = NULL; hIsWinXShown = NULL;
return 0; return 0;
} }
@ -443,7 +449,7 @@ INT64 CLauncherTipContextMenu_ShowLauncherTipContextMenuHook(
POINT* pt POINT* pt
) )
{ {
if (hThread) if (hIsWinXShown)
{ {
goto finalize; goto finalize;
} }
@ -510,7 +516,7 @@ INT64 CLauncherTipContextMenu_ShowLauncherTipContextMenuHook(
params->_this = _this; params->_this = _this;
params->point = point; params->point = point;
params->iunk = iunk; params->iunk = iunk;
hThread = CreateThread( hIsWinXShown = CreateThread(
0, 0,
0, 0,
ShowLauncherTipContextMenu, ShowLauncherTipContextMenu,
@ -523,6 +529,85 @@ INT64 CLauncherTipContextMenu_ShowLauncherTipContextMenuHook(
return CLauncherTipContextMenu_ShowLauncherTipContextMenuFunc(_this, pt); return CLauncherTipContextMenu_ShowLauncherTipContextMenuFunc(_this, pt);
} }
INT64 CTray_HandleGlobalHotkeyHook(
void* _this,
unsigned int a2,
unsigned int a3
)
{
if (a2 == 590 && IsDesktopInputContextFunc(_this, a2))
{
// this works just fine but is hacky because using
// the proper way does not work for some reason
// see https://github.com/valinet/ExplorerPatcher/issues/3
if (hIsWinXShown)
{
INPUT ip[2];
ip[0].type = INPUT_KEYBOARD;
ip[0].ki.wScan = 0;
ip[0].ki.time = 0;
ip[0].ki.dwExtraInfo = 0;
ip[0].ki.wVk = VK_ESCAPE;
ip[0].ki.dwFlags = 0;
ip[1].type = INPUT_KEYBOARD;
ip[1].ki.wScan = 0;
ip[1].ki.time = 0;
ip[1].ki.dwExtraInfo = 0;
ip[1].ki.wVk = VK_ESCAPE;
ip[1].ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(2, ip, sizeof(INPUT));
return 0;
}
InterlockedExchange64(&lockEnsureWinXHotkeyOnlyOnce, 1);
HWND hWnd = GetForegroundWindow();
HWND g_ProgWin = FindWindowEx(
NULL,
NULL,
L"Progman",
NULL
);
SetForegroundWindow(g_ProgWin);
INPUT ip[4];
ip[0].type = INPUT_KEYBOARD;
ip[0].ki.wScan = 0;
ip[0].ki.time = 0;
ip[0].ki.dwExtraInfo = 0;
ip[0].ki.wVk = VK_LWIN;
ip[0].ki.dwFlags = 0;
ip[1].type = INPUT_KEYBOARD;
ip[1].ki.wScan = 0;
ip[1].ki.time = 0;
ip[1].ki.dwExtraInfo = 0;
ip[1].ki.wVk = 0x51; // 0x46;
ip[1].ki.dwFlags = 0;
ip[2].type = INPUT_KEYBOARD;
ip[2].ki.wScan = 0;
ip[2].ki.time = 0;
ip[2].ki.dwExtraInfo = 0;
ip[2].ki.wVk = 0x51; // 0x46;
ip[2].ki.dwFlags = KEYEVENTF_KEYUP;
ip[3].type = INPUT_KEYBOARD;
ip[3].ki.wScan = 0;
ip[3].ki.time = 0;
ip[3].ki.dwExtraInfo = 0;
ip[3].ki.wVk = VK_LWIN;
ip[3].ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(4, ip, sizeof(INPUT));
SetForegroundWindow(hWnd);
return 0;
}
return CTray_HandleGlobalHotkeyFunc(
_this,
a2,
a3
);
}
HRESULT CImmersiveHotkeyNotification_OnMessageHook( HRESULT CImmersiveHotkeyNotification_OnMessageHook(
void* _this, void* _this,
INT64 msg, INT64 msg,
@ -530,9 +615,12 @@ HRESULT CImmersiveHotkeyNotification_OnMessageHook(
INT64 lParam INT64 lParam
) )
{ {
if (wParam == 28 && IsDesktopInputContextFunc(_this, msg)) // 15 if (InterlockedExchange64(&lockEnsureWinXHotkeyOnlyOnce, 0) &&
wParam == 30 && // 28, 15
IsDesktopInputContextFunc(_this, msg)
)
{ {
IUnknown* pMonitor; IUnknown* pMonitor = NULL;
HRESULT hr = CImmersiveHotkeyNotification_GetMonitorForHotkeyNotificationFunc( HRESULT hr = CImmersiveHotkeyNotification_GetMonitorForHotkeyNotificationFunc(
(char*)_this - 0x68, (char*)_this - 0x68,
&pMonitor, &pMonitor,
@ -540,7 +628,7 @@ HRESULT CImmersiveHotkeyNotification_OnMessageHook(
); );
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
IUnknown* pMenu; IUnknown* pMenu = NULL;
IUnknown_QueryService( IUnknown_QueryService(
pMonitor, pMonitor,
&IID_ILauncherTipContextMenu, &IID_ILauncherTipContextMenu,
@ -650,7 +738,7 @@ LRESULT CALLBACK OpenStartOnCurentMonitorThreadHook(
); );
HRESULT hr = S_OK; HRESULT hr = S_OK;
IUnknown* pImmersiveShell; IUnknown* pImmersiveShell = NULL;
hr = CoCreateInstance( hr = CoCreateInstance(
&CLSID_ImmersiveShell, &CLSID_ImmersiveShell,
NULL, NULL,
@ -780,6 +868,20 @@ __declspec(dllexport) DWORD WINAPI main(
); );
HANDLE hExplorer = GetModuleHandle(NULL);
CTray_HandleGlobalHotkeyFunc = (INT64(*)(void*, unsigned int, unsigned int))
((uintptr_t)hExplorer + 0x117F8);
rv = funchook_prepare(
funchook,
(void**)&CTray_HandleGlobalHotkeyFunc,
CTray_HandleGlobalHotkeyHook
);
if (rv != 0)
{
FreeLibraryAndExitThread(hModule, rv);
return rv;
}
HANDLE hUser32 = GetModuleHandle(L"user32.dll"); HANDLE hUser32 = GetModuleHandle(L"user32.dll");

5
README.md

@ -19,11 +19,6 @@ To install, save the executable in a safe directory, run it once as an administr
The application does not currently offer a way to configure its behavior. In the mean time, I recommend commenting out whatever you do not like and compile your own executable, as described below (instructions are very simple). The application does not currently offer a way to configure its behavior. In the mean time, I recommend commenting out whatever you do not like and compile your own executable, as described below (instructions are very simple).
## Known issues
* The power user menu (Win+X menu) is unskinned - it has the default menu appearance from Windows 11 instead of the look the clock, taskbar etc context menus get; at the moment, I think it boils down to correctly calling `ImmersiveContextMenuHelper::ApplyOwnerDrawToMenu`, but unfortunately I've yet to do it correctly
* The power user menu (Win+X menu) is mapped to Win+F for the moment, as I've yet to have the time to investigate where exactly Win+X is handled (i.e. it is not in `CImmersiveHotkeyNotification::OnMessage`)
## License ## License
Hooking is done using the excellent [funchook](https://github.com/kubo/funchook) library (GPLv2 with linking exception), which in turn is powered by the [diStorm3](https://github.com/gdabah/distorm/) (3-clause BSD) disassembler. Thus, I am offering this under GNU General Public License Version 2.0, which I believe is compatible. Hooking is done using the excellent [funchook](https://github.com/kubo/funchook) library (GPLv2 with linking exception), which in turn is powered by the [diStorm3](https://github.com/gdabah/distorm/) (3-clause BSD) disassembler. Thus, I am offering this under GNU General Public License Version 2.0, which I believe is compatible.

Loading…
Cancel
Save