Module: wine Branch: master Commit: dfe6ae58afdebd830fa491a4dec1bed9ee6527eb URL: http://source.winehq.org/git/wine.git/?a=commit;h=dfe6ae58afdebd830fa491a4de...
Author: Dmitry Timoshkov dmitry@codeweavers.com Date: Wed Aug 4 23:00:34 2010 +0900
user32: Protect from setting as a window owner one of its successors.
---
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; }