From dcab3151f050778ff21c5e63dc02e2753238e7df Mon Sep 17 00:00:00 2001 From: alvinhochun Date: Mon, 6 Dec 2021 00:51:39 +0800 Subject: [PATCH] Fix SetCursorPos and ClipCursor ignoring DPI awareness --- Sandboxie/core/dll/guimisc.c | 15 +++++++++++++++ Sandboxie/core/svc/GuiServer.cpp | 27 +++++++++++++++++++++++++++ Sandboxie/core/svc/GuiWire.h | 2 ++ 3 files changed, 44 insertions(+) diff --git a/Sandboxie/core/dll/guimisc.c b/Sandboxie/core/dll/guimisc.c index 7622d90d..38cad43e 100644 --- a/Sandboxie/core/dll/guimisc.c +++ b/Sandboxie/core/dll/guimisc.c @@ -123,6 +123,16 @@ typedef int (*P_ReleaseDC)( static P_GetUserObjectInformationW __sys_GetUserObjectInformationW = NULL; +#ifndef _DPI_AWARENESS_CONTEXTS_ +struct DPI_AWARENESS_CONTEXT__ { int unused; }; +typedef DPI_AWARENESS_CONTEXT__ *DPI_AWARENESS_CONTEXT; +#endif + +typedef DPI_AWARENESS_CONTEXT (WINAPI *P_GetThreadDpiAwarenessContext)( + VOID); + +static P_GetThreadDpiAwarenessContext __sys_GetThreadDpiAwarenessContext = NULL; + //--------------------------------------------------------------------------- // Variables @@ -230,6 +240,9 @@ _FX BOOLEAN Gui_InitMisc(void) SBIEDLL_HOOK_GUI(GetRawInputDeviceInfoA); SBIEDLL_HOOK_GUI(GetRawInputDeviceInfoW); + __sys_GetThreadDpiAwarenessContext = (P_GetThreadDpiAwarenessContext) + Ldr_GetProcAddrNew(DllName_user32, L"GetThreadDpiAwarenessContext","GetThreadDpiAwarenessContext"); + return TRUE; } @@ -314,6 +327,7 @@ _FX BOOL Gui_ClipCursor(const RECT *lpRect) memzero(&req.rect, sizeof(req.rect)); Gui_ClipCursorActive = FALSE; } + req.dpi_awareness_ctx = __sys_GetThreadDpiAwarenessContext ? (LONG64)(LONG_PTR)__sys_GetThreadDpiAwarenessContext() : 0; rpl = Gui_CallProxy(&req, sizeof(req), sizeof(ULONG)); if (rpl) { @@ -465,6 +479,7 @@ _FX BOOL Gui_SetCursorPos(int x, int y) req.error = GetLastError(); req.x = x; req.y = y; + req.dpi_awareness_ctx = __sys_GetThreadDpiAwarenessContext ? (LONG64)(LONG_PTR)__sys_GetThreadDpiAwarenessContext() : 0; rpl = Gui_CallProxyEx(&req, sizeof(req), sizeof(ULONG), TRUE); if (rpl) { retval = rpl->retval; diff --git a/Sandboxie/core/svc/GuiServer.cpp b/Sandboxie/core/svc/GuiServer.cpp index 7007da58..bda5c33c 100644 --- a/Sandboxie/core/svc/GuiServer.cpp +++ b/Sandboxie/core/svc/GuiServer.cpp @@ -85,6 +85,14 @@ typedef struct _WND_HOOK { static HWND DDE_Request_ProxyWnd = NULL; +#ifndef _DPI_AWARENESS_CONTEXTS_ +struct DPI_AWARENESS_CONTEXT__ { int unused; }; +typedef DPI_AWARENESS_CONTEXT__ *DPI_AWARENESS_CONTEXT; +#endif +typedef DPI_AWARENESS_CONTEXT (WINAPI *P_SetThreadDpiAwarenessContext)( + DPI_AWARENESS_CONTEXT dpiContext); + +static P_SetThreadDpiAwarenessContext __sys_SetThreadDpiAwarenessContext = NULL; //--------------------------------------------------------------------------- // Constructor @@ -113,6 +121,9 @@ GuiServer::GuiServer() else*/ GetVersionExW(&osvi); // since windows 10 this one is lying m_nOSVersion = osvi.dwMajorVersion * 10 + osvi.dwMinorVersion; + + __sys_SetThreadDpiAwarenessContext = (P_SetThreadDpiAwarenessContext)GetProcAddress( + GetModuleHandle(L"user32.dll"), "SetThreadDpiAwarenessContext"); } @@ -3043,9 +3054,17 @@ ULONG GuiServer::ClipCursorSlave(SlaveArgs *args) if (req->have_rect) rect = &req->rect; + DPI_AWARENESS_CONTEXT old_trd_dpi_ctx = __sys_SetThreadDpiAwarenessContext + ? __sys_SetThreadDpiAwarenessContext((DPI_AWARENESS_CONTEXT)(LONG_PTR)req->dpi_awareness_ctx) + : NULL; + ClipCursor(rect); //if (! ) // as this seems to randomly fail, don't issue errors // return STATUS_ACCESS_DENIED; // todo: add reply and return ret value + if (__sys_SetThreadDpiAwarenessContext) { + __sys_SetThreadDpiAwarenessContext(old_trd_dpi_ctx); + } + return STATUS_SUCCESS; } @@ -3339,11 +3358,19 @@ ULONG GuiServer::SetCursorPosSlave(SlaveArgs *args) if (args->req_len != sizeof(GUI_SET_CURSOR_POS_REQ)) return STATUS_INFO_LENGTH_MISMATCH; + DPI_AWARENESS_CONTEXT old_trd_dpi_ctx = __sys_SetThreadDpiAwarenessContext + ? __sys_SetThreadDpiAwarenessContext((DPI_AWARENESS_CONTEXT)(LONG_PTR)req->dpi_awareness_ctx) + : NULL; + SetLastError(req->error); rpl->retval = (ULONG)SetCursorPos(req->x, req->y); rpl->error = GetLastError(); + if (__sys_SetThreadDpiAwarenessContext) { + __sys_SetThreadDpiAwarenessContext(old_trd_dpi_ctx); + } + args->rpl_len = sizeof(GUI_SET_CURSOR_POS_RPL); return STATUS_SUCCESS; } diff --git a/Sandboxie/core/svc/GuiWire.h b/Sandboxie/core/svc/GuiWire.h index 36e6bfa0..3eb5d47d 100644 --- a/Sandboxie/core/svc/GuiWire.h +++ b/Sandboxie/core/svc/GuiWire.h @@ -545,6 +545,7 @@ struct tagGUI_CLIP_CURSOR_REQ ULONG msgid; BOOLEAN have_rect; RECT rect; + LONG64 dpi_awareness_ctx; }; typedef struct tagGUI_CLIP_CURSOR_REQ GUI_CLIP_CURSOR_REQ; @@ -646,6 +647,7 @@ struct tagGUI_SET_CURSOR_POS_REQ ULONG error; LONG x; LONG y; + LONG64 dpi_awareness_ctx; }; struct tagGUI_SET_CURSOR_POS_RPL