user: Make ExitWindowsEx asynchronous by deferring the real work to the explorer process.
diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c index 70ec9fc..743bded 100644 --- a/dlls/user/user_main.c +++ b/dlls/user/user_main.c
@@ -411,6 +411,18 @@ { TRACE("(%x,%lx)\n", flags, reason); + if (!WIN_IsCurrentThread( GetDesktopWindow() )) + { + BOOL ret = PostMessageW( GetDesktopWindow(), WM_USER + 666, + MAKEWPARAM( flags, 0xbabe ), reason); + if (ret) + return TRUE; + /* this can happen if explorer hasn't been started or created the + * desktop window yet */ + WARN("PostMessage failed with error %ld\n", GetLastError()); + /* fall through to doing it in the same process */ + } + if ((flags & EWX_FORCE) == 0) { HWND *list; @@ -468,6 +480,5 @@ MESSAGE("wine: Failed to start wineboot\n"); } - ExitProcess(0); return TRUE; }
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index 67025b8..d4db46d 100644 --- a/programs/explorer/desktop.c +++ b/programs/explorer/desktop.c
@@ -62,6 +62,13 @@ } return 0; + /* simple check to prevent applications accidentally triggering the + * ExitWindowsEx code if they send random messages to the desktop window */ + case WM_USER + 666: + if (HIWORD(wp) == 0xbabe) + return ExitWindowsEx( LOWORD(wp), lp ); + return DefWindowProcW( hwnd, message, wp, lp ); + default: return DefWindowProcW( hwnd, message, wp, lp ); }