[PATCH] server: Make set_caret_info fail if there is no caret window.

Robert Schlicht patch at rschlicht.eu
Fri Feb 21 06:45:35 CST 2020


Additional experimenting on Windows shows that if there is not caret
window, then ShowCaret, HideCaret, SetCaretPos and DestroyCaret fail
with ERROR_ACCESS_DENIED. This is true even though the caret position
is preserved and returned by GetCaretPos.

The current Wine implementation causes calls such as ShowCaret(0) to
proceed as if a caret window would exist. This is an issue because the
call leaks a timer when the hide count has its initial value 1 since
SetSystemTimer( hwnd, TIMERID, Caret.timeout, CARET_Callback );
(user32/caret.c) does not use TIMERID if hwnd is null. This happens,
for example, when a menu is closing (see MENU_ExitTracking() in
user32/menu.c).

The patch makes the set_caret_info request fail (except for
GetCaretPos) if there is no caret window so that the caret functions 
do not manipulate timers and properly return failure. This patch 
supersedes the patch with ID 178871.

Signed-off-by: Robert Schlicht <patch at rschlicht.eu>
---
 server/queue.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/server/queue.c b/server/queue.c
index b5e17be18f..07f43d2c82 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -3025,9 +3025,9 @@ DECL_HANDLER(set_caret_info)
     reply->old_hide    = input->caret_hide;
     reply->old_state   = input->caret_state;
 
-    if (req->handle && get_user_full_handle(req->handle) != input->caret)
+    if (!input->caret || (req->handle && get_user_full_handle(req->handle) != input->caret))
     {
-        set_error( STATUS_ACCESS_DENIED );
+        if (req->flags) set_error( STATUS_ACCESS_DENIED );
         return;
     }
     if (req->flags & SET_CARET_POS)
-- 
2.17.1



More information about the wine-devel mailing list