mirror of
https://github.com/reactos/reactos.git
synced 2026-07-02 00:54:22 +08:00
[WIN32SS:NTUSER] Improve initialization of window station and desktop objects
As soon as `ObCreateObject()` is successfully invoked, zero-out the winsta and desktop object buffers and assign them the current process session ID (into their first `dwSessionId` member). Only then, continue with regular initialization. It's done in this systematic way in order to ensure that, in case the regular initialization of these objects fails and `ObDereferenceObject()` is invoked, the `nt!ExpWin32SessionCallout()` routine (in `ntoskrnl/ex/win32k.c`) that is executed as part of the Win32 "delete" object callback registered by win32k.sys with the Object Manager, correctly finds a valid initialized `SessionId` value in the "common header" of either the window station or the desktop object being deleted. As a side-result, other parts of win32k can directly refer to `pdesk->dwSessionId` instead of `pdesk->rpwinstaParent->dwSessionId` for a given desktop.
This commit is contained in:
@@ -143,7 +143,13 @@ IntDesktopObjectParse(IN PVOID ParseObject,
|
||||
0,
|
||||
0,
|
||||
(PVOID*)&Desktop);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
RtlZeroMemory(Desktop, sizeof(DESKTOP));
|
||||
|
||||
/* Assign the session ID to the desktop */
|
||||
Desktop->dwSessionId = PsGetCurrentProcessSessionId(); // gSessionId
|
||||
ASSERT(Desktop->dwSessionId == WinStaObject->dwSessionId);
|
||||
|
||||
/* Assign security to the desktop we have created */
|
||||
Status = IntAssignDesktopSecurityOnParse(WinStaObject, Desktop, AccessState);
|
||||
@@ -2278,8 +2284,6 @@ UserInitializeDesktop(PDESKTOP pdesk, PUNICODE_STRING DesktopName, PWINSTATION_O
|
||||
|
||||
TRACE("UserInitializeDesktop desktop 0x%p with name %wZ\n", pdesk, DesktopName);
|
||||
|
||||
RtlZeroMemory(pdesk, sizeof(DESKTOP));
|
||||
|
||||
/* Set desktop size, based on whether the WinSta is interactive or not */
|
||||
if (pwinsta == InputWindowStation)
|
||||
{
|
||||
@@ -2488,8 +2492,7 @@ IntCreateDesktop(
|
||||
}
|
||||
pWnd->fnid = FNID_DESKTOP;
|
||||
|
||||
/* Assign the session ID and the desktop window to the desktop */
|
||||
pdesk->dwSessionId = PsGetCurrentProcessSessionId();
|
||||
/* Assign the desktop window to the desktop */
|
||||
pdesk->DesktopWindow = UserHMGetHandle(pWnd);
|
||||
pdesk->pDeskInfo->spwnd = pWnd;
|
||||
|
||||
@@ -2982,7 +2985,7 @@ NtUserSwitchDesktop(HDESK hdesk)
|
||||
goto Exit; // Return FALSE
|
||||
}
|
||||
|
||||
if (PsGetCurrentProcessSessionId() != pdesk->rpwinstaParent->dwSessionId)
|
||||
if (PsGetCurrentProcessSessionId() != pdesk->dwSessionId)
|
||||
{
|
||||
ObDereferenceObject(pdesk);
|
||||
ERR("NtUserSwitchDesktop called for a desktop of a different session\n");
|
||||
|
||||
@@ -321,7 +321,7 @@ IntDestroyMenuObject(PMENU Menu, BOOL bRecurse)
|
||||
{
|
||||
PWND Window;
|
||||
|
||||
if (PsGetCurrentProcessSessionId() == Menu->head.rpdesk->rpwinstaParent->dwSessionId)
|
||||
if (PsGetCurrentProcessSessionId() == Menu->head.rpdesk->dwSessionId)
|
||||
{
|
||||
BOOL ret;
|
||||
if (Menu->hWnd)
|
||||
|
||||
@@ -504,12 +504,13 @@ IntCreateWindowStation(
|
||||
SetLastNtError(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Initialize the window station */
|
||||
RtlZeroMemory(WindowStation, sizeof(WINSTATION_OBJECT));
|
||||
|
||||
/* Assign the session ID to the window station */
|
||||
WindowStation->dwSessionId = PsGetCurrentProcessSessionId(); // gSessionId
|
||||
|
||||
/* Initialize the window station */
|
||||
InitializeListHead(&WindowStation->DesktopListHead);
|
||||
WindowStation->dwSessionId = NtCurrentPeb()->SessionId;
|
||||
Status = RtlCreateAtomTable(37, &WindowStation->AtomTable);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user