diff --git a/reactos/include/ndk/psfuncs.h b/reactos/include/ndk/psfuncs.h index 4b0a96f52af..19c6678ccfa 100644 --- a/reactos/include/ndk/psfuncs.h +++ b/reactos/include/ndk/psfuncs.h @@ -78,6 +78,21 @@ PsGetThreadWin32Thread( PETHREAD Thread ); +NTKERNELAPI +PVOID +NTAPI +PsGetProcessWin32WindowStation( + PEPROCESS Process +); + +NTKERNELAPI +VOID +NTAPI +PsSetProcessWindowStation( + PEPROCESS Process, + PVOID WindowStation +); + NTKERNELAPI PTEB NTAPI diff --git a/reactos/subsystems/win32/win32k/ntuser/winsta.c b/reactos/subsystems/win32/win32k/ntuser/winsta.c index 2d5d3870e07..10150292b73 100644 --- a/reactos/subsystems/win32/win32k/ntuser/winsta.c +++ b/reactos/subsystems/win32/win32k/ntuser/winsta.c @@ -940,6 +940,7 @@ UserSetProcessWindowStation(HWINSTA hWindowStation) ppi = PsGetCurrentProcessWin32Process(); + /* Reference the new window station */ if(hWindowStation !=NULL) { Status = IntValidateWindowStationHandle( hWindowStation, @@ -956,28 +957,29 @@ UserSetProcessWindowStation(HWINSTA hWindowStation) } OldWinSta = ppi->prpwinsta; - hwinstaOld = ppi->hwinsta; - - /* - * FIXME - don't allow changing the window station if there are threads that are attached to desktops and own gui objects - */ - - InterlockedExchangePointer(&PsGetCurrentProcess()->Win32WindowStation, hWindowStation); - - ppi->prpwinsta = NewWinSta; - ppi->hwinsta = hWindowStation; - + hwinstaOld = PsGetProcessWin32WindowStation(ppi->peProcess); + /* Dereference the previous window station */ if(OldWinSta != NULL) { ObDereferenceObject(OldWinSta); } - if(hwinstaOld != NULL) + /* Check if we have a stale handle (it should happen for console apps) */ + if(hwinstaOld != ppi->hwinsta) { ObCloseHandle(hwinstaOld, UserMode); } + /* + * FIXME - don't allow changing the window station if there are threads that are attached to desktops and own gui objects + */ + + PsSetProcessWindowStation(ppi->peProcess, hWindowStation); + + ppi->prpwinsta = NewWinSta; + ppi->hwinsta = hWindowStation; + return TRUE; }