Jacek Caban : server: Don't allow creating children of orphaned windows.

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


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

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

server: Don't allow creating children of orphaned windows.

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

---

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

diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index a5848ac28da..3ace25056de 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -765,7 +765,7 @@ static LRESULT CALLBACK test_thread_exit_wnd_proc( HWND hwnd, UINT msg, WPARAM w
 static void test_thread_exit_destroy(void)
 {
     struct test_thread_exit_parent_params params;
-    HWND adopter, child1, child2, child3;
+    HWND adopter, child1, child2, child3, child;
     WNDPROC old_wndproc, wndproc;
     WCHAR buffer[MAX_PATH];
     HANDLE thread;
@@ -889,6 +889,14 @@ static void test_thread_exit_destroy(void)
     tmp = GetPropW( child2, L"myprop" );
     ok( HandleToULong(tmp) == 0xdeadbeef, "GetPropW returned %p\n", tmp );
 
+    child = CreateWindowExA( 0, "ToolWindowClass", "Tool window 1", WS_CHILD,
+                             0, 0, 100, 100, child1, 0, 0, NULL );
+    ok( !child && GetLastError() == ERROR_INVALID_PARAMETER,
+        "CreateWindowExA returned %p %u\n", child, GetLastError() );
+
+    ret = MoveWindow( child1, 5, 5, 10, 10, FALSE );
+    ok( ret, "MoveWindow failed: %u\n", GetLastError() );
+
     /* destroying child1 ourselves succeeds */
     ret = DestroyWindow( child1 );
     ok( ret, "DestroyWindow returned %u\n", ret );
@@ -12789,7 +12797,8 @@ static void test_DragDetect(void)
 static LRESULT WINAPI ncdestroy_test_proc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
 {
     unsigned int ret;
-    HWND parent;
+    HWND parent, child;
+    RECT rect, exp;
 
     switch (msg)
     {
@@ -12805,6 +12814,25 @@ static LRESULT WINAPI ncdestroy_test_proc( HWND hwnd, UINT msg, WPARAM wp, LPARA
         parent = SetParent( hwnd, hwndMain );
         ok( parent == 0, "SetParent returned %p\n", parent );
         ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %u\n", GetLastError() );
+
+        ret = GetWindowRect( hwnd, &rect );
+        ok( ret, "GetWindowRect failed: %u\n", GetLastError() );
+        SetRect( &exp, 10, 20, 110, 220 );
+        ok( EqualRect( &rect, &exp ), "unexpected rect %s, expected %s\n", wine_dbgstr_rect( &rect ),
+            wine_dbgstr_rect( &exp ));
+
+        ret = MoveWindow( hwnd, 11, 12, 20, 30, FALSE );
+        ok( ret, "MoveWindow failed: %u\n", GetLastError() );
+        ret = GetWindowRect( hwnd, &rect );
+        ok( ret, "GetWindowRect failed: %u\n", GetLastError() );
+        SetRect( &exp, 11, 12, 31, 42 );
+        ok( EqualRect( &rect, &exp ), "unexpected rect %s, expected %s\n", wine_dbgstr_rect( &rect ),
+            wine_dbgstr_rect( &exp ));
+
+        child = CreateWindowExA( 0, "ToolWindowClass", "Tool window 1", WS_CHILD,
+                                 0, 0, 100, 100, hwnd, 0, 0, NULL );
+        ok( !child && GetLastError() == ERROR_INVALID_PARAMETER,
+            "CreateWindowExA returned %p %u\n", child, GetLastError() );
         break;
     }
 
@@ -12816,6 +12844,7 @@ static void test_ncdestroy(void)
     HWND hwnd;
     hwnd = create_tool_window( WS_POPUP, 0 );
     SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)ncdestroy_test_proc );
+    MoveWindow( hwnd, 10, 20, 100, 200, FALSE );
     DestroyWindow(hwnd);
 }
 
diff --git a/server/window.c b/server/window.c
index da05d024056..ec8ee2f1790 100644
--- a/server/window.c
+++ b/server/window.c
@@ -2025,7 +2025,15 @@ DECL_HANDLER(create_window)
     atom_t atom;
 
     reply->handle = 0;
-    if (req->parent && !(parent = get_window( req->parent ))) return;
+    if (req->parent)
+    {
+        if (!(parent = get_window( req->parent ))) return;
+        if (is_orphan_window( parent ))
+        {
+            set_error( STATUS_INVALID_PARAMETER );
+            return;
+        }
+    }
 
     if (req->owner)
     {




More information about the wine-cvs mailing list