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;