user32: Protect from setting as a window owner one of its successors. Take 2.

Dmitry Timoshkov dmitry at codeweavers.com
Wed Aug 4 09:00:34 CDT 2010


This patch applies the same logic used in set_parent() to set_window_owner(),
and fixes the problem reported in the bug 23707.

This version of the patch skips the test which creates circular window tree
under win9x just like it's done for SetParent() in the same set of tests.
---
 dlls/user32/tests/win.c |    9 +++++++++
 server/window.c         |   13 ++++++++++++-
 2 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index 632e382..3af8d75 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -380,6 +380,15 @@ static void test_parent_owner(void)
     check_parents( test, desktop, 0, desktop, 0, test, desktop );
 
     /* window is now child of desktop so GWLP_HWNDPARENT changes owner from now on */
+    if (!is_win9x)
+    {
+        ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)test );
+        ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
+        check_parents( test, desktop, 0, desktop, 0, test, desktop );
+    }
+    else
+        win_skip("Test creates circular window tree under Win9x/WinMe\n" );
+
     ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)child );
     ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
     check_parents( test, desktop, child, desktop, child, test, desktop );
diff --git a/server/window.c b/server/window.c
index 3b912b0..5fdfd13 100644
--- a/server/window.c
+++ b/server/window.c
@@ -1834,7 +1834,7 @@ DECL_HANDLER(get_desktop_window)
 DECL_HANDLER(set_window_owner)
 {
     struct window *win = get_window( req->handle );
-    struct window *owner = NULL;
+    struct window *owner = NULL, *ptr;
 
     if (!win) return;
     if (req->owner && !(owner = get_window( req->owner ))) return;
@@ -1843,6 +1843,17 @@ DECL_HANDLER(set_window_owner)
         set_error( STATUS_ACCESS_DENIED );
         return;
     }
+
+    /* make sure owner is not a successor of window */
+    for (ptr = owner; ptr; ptr = ptr->owner ? get_window( ptr->owner ) : NULL)
+    {
+        if (ptr == win)
+        {
+            set_error( STATUS_INVALID_PARAMETER );
+            return;
+        }
+    }
+
     reply->prev_owner = win->owner;
     reply->full_owner = win->owner = owner ? owner->handle : 0;
 }
-- 
1.7.0.6




More information about the wine-patches mailing list