Jacek Caban : server: Don't allow orphaned windows in set_parent request.

Alexandre Julliard julliard at winehq.org
Wed Feb 9 16:03:49 CST 2022


Module: wine
Branch: master
Commit: 82572350cd1d302bf4402526d6c5152e02c6f4a0
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=82572350cd1d302bf4402526d6c5152e02c6f4a0

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Feb  8 13:13:19 2022 +0100

server: Don't allow orphaned windows in set_parent request.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/user32/tests/win.c |  3 ---
 dlls/user32/win.c       |  2 +-
 server/window.c         | 10 +++++++++-
 3 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index 48b9e5e332c..d38ce382b86 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -865,16 +865,13 @@ static void test_thread_exit_destroy(void)
     SetLastError( 0xdeadbeef );
     tmp = SetParent( child1, adopter );
     ok( tmp == 0, "SetParent returned %p\n", tmp );
-    todo_wine
     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %u\n", GetLastError() );
     SetLastError( 0xdeadbeef );
     tmp = SetParent( child3, adopter );
     ok( tmp == 0, "SetParent returned %p\n", tmp );
-    todo_wine
     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %u\n", GetLastError() );
     SetLastError( 0xdeadbeef );
     tmp = GetParent( child1 );
-    todo_wine
     ok( tmp == params.hwnd, "GetParent returned %p, error %u\n", tmp, GetLastError() );
     ok( GetLastError() == 0xdeadbeef, "GetWindowLongW error %u\n", GetLastError() );
 
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 4f860889024..9e483b4c494 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -3374,7 +3374,7 @@ HWND WINAPI SetParent( HWND hwnd, HWND parent )
     {
         req->handle = wine_server_user_handle( hwnd );
         req->parent = wine_server_user_handle( parent );
-        if ((ret = !wine_server_call( req )))
+        if ((ret = !wine_server_call_err( req )))
         {
             old_parent = wine_server_ptr_handle( reply->old_parent );
             wndPtr->parent = parent = wine_server_ptr_handle( reply->full_parent );
diff --git a/server/window.c b/server/window.c
index 506f0269ee1..6cc2f9d0f70 100644
--- a/server/window.c
+++ b/server/window.c
@@ -200,6 +200,14 @@ static inline int is_desktop_window( const struct window *win )
     return !win->parent;  /* only desktop windows have no parent */
 }
 
+/* check if window is orphaned */
+static int is_orphan_window( struct window *win )
+{
+    do if (!win->handle) return 1;
+    while ((win = win->parent));
+    return 0;
+}
+
 /* get next window in Z-order list */
 static inline struct window *get_next_window( struct window *win )
 {
@@ -2066,7 +2074,7 @@ DECL_HANDLER(set_parent)
     if (!(win = get_window( req->handle ))) return;
     if (req->parent && !(parent = get_window( req->parent ))) return;
 
-    if (is_desktop_window(win))
+    if (is_desktop_window(win) || is_orphan_window( win ) || (parent && is_orphan_window( parent )))
     {
         set_error( STATUS_INVALID_PARAMETER );
         return;




More information about the wine-cvs mailing list