ReactOS  0.4.15-dev-3017-g1d9542d
desktop.c File Reference
#include <win32k.h>
#include <reactos/buildno.h>
Include dependency graph for desktop.c:

Go to the source code of this file.

Functions

 DBG_DEFAULT_CHANNEL (UserDesktop)
 
static NTSTATUS UserInitializeDesktop (PDESKTOP pdesk, PUNICODE_STRING DesktopName, PWINSTATION_OBJECT pwinsta)
 
static NTSTATUS IntMapDesktopView (IN PDESKTOP pdesk)
 
static NTSTATUS IntUnmapDesktopView (IN PDESKTOP pdesk)
 
static VOID IntFreeDesktopHeap (IN PDESKTOP pdesk)
 
NTSTATUS APIENTRY IntDesktopObjectParse (IN PVOID ParseObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context OPTIONAL, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object)
 
NTSTATUS NTAPI IntDesktopObjectDelete (_In_ PVOID Parameters)
 
NTSTATUS NTAPI IntDesktopOkToClose (_In_ PVOID Parameters)
 
NTSTATUS NTAPI IntDesktopObjectOpen (_In_ PVOID Parameters)
 
NTSTATUS NTAPI IntDesktopObjectClose (_In_ PVOID Parameters)
 
NTSTATUS NTAPI InitDesktopImpl (VOID)
 
static NTSTATUS GetSystemVersionString (OUT PWSTR pwszzVersion, IN SIZE_T cchDest, IN BOOLEAN InSafeMode, IN BOOLEAN AppendNtSystemRoot)
 
NTSTATUS FASTCALL IntResolveDesktop (IN PEPROCESS Process, IN PUNICODE_STRING DesktopPath, IN BOOL bInherit, OUT HWINSTA *phWinSta, OUT HDESK *phDesktop)
 
NTSTATUS FASTCALL IntValidateDesktopHandle (HDESK Desktop, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PDESKTOP *Object)
 
PDESKTOP FASTCALL IntGetActiveDesktop (VOID)
 
HDESK FASTCALL IntGetDesktopObjectHandle (PDESKTOP DesktopObject)
 
PUSER_MESSAGE_QUEUE FASTCALL IntGetFocusMessageQueue (VOID)
 
VOID FASTCALL IntSetFocusMessageQueue (PUSER_MESSAGE_QUEUE NewQueue)
 
PWND FASTCALL IntGetThreadDesktopWindow (PTHREADINFO pti)
 
PWND FASTCALL co_GetDesktopWindow (PWND pWnd)
 
HWND FASTCALL IntGetDesktopWindow (VOID)
 
PWND FASTCALL UserGetDesktopWindow (VOID)
 
HWND FASTCALL IntGetMessageWindow (VOID)
 
PWND FASTCALL UserGetMessageWindow (VOID)
 
HWND FASTCALL IntGetCurrentThreadDesktopWindow (VOID)
 
BOOL FASTCALL DesktopWindowProc (PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
 
BOOL FASTCALL UserMessageWindowProc (PWND pwnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
 
VOID NTAPI DesktopThreadMain (VOID)
 
HDC FASTCALL UserGetDesktopDC (ULONG DcType, BOOL bAltDc, BOOL ValidatehWnd)
 
VOID APIENTRY UserRedrawDesktop (VOID)
 
NTSTATUS FASTCALL co_IntShowDesktop (PDESKTOP Desktop, ULONG Width, ULONG Height, BOOL bRedraw)
 
NTSTATUS FASTCALL IntHideDesktop (PDESKTOP Desktop)
 
static HWND *FASTCALL UserBuildShellHookHwndList (PDESKTOP Desktop)
 
VOID co_IntShellHookNotify (WPARAM Message, WPARAM wParam, LPARAM lParam)
 
BOOL IntRegisterShellHookWindow (HWND hWnd)
 
BOOL IntDeRegisterShellHookWindow (HWND hWnd)
 
static VOID IntFreeDesktopHeap (IN OUT PDESKTOP Desktop)
 
BOOL FASTCALL IntPaintDesktop (HDC hDC)
 
NTSTATUS FASTCALL IntCreateDesktop (OUT HDESK *phDesktop, IN POBJECT_ATTRIBUTES ObjectAttributes, IN KPROCESSOR_MODE AccessMode, IN PUNICODE_STRING lpszDesktopDevice OPTIONAL, IN LPDEVMODEW lpdmw OPTIONAL, IN DWORD dwFlags, IN ACCESS_MASK dwDesiredAccess)
 
HDESK APIENTRY NtUserCreateDesktop (POBJECT_ATTRIBUTES ObjectAttributes, PUNICODE_STRING lpszDesktopDevice, LPDEVMODEW lpdmw, DWORD dwFlags, ACCESS_MASK dwDesiredAccess)
 
HDESK APIENTRY NtUserOpenDesktop (POBJECT_ATTRIBUTES ObjectAttributes, DWORD dwFlags, ACCESS_MASK dwDesiredAccess)
 
HDESK UserOpenInputDesktop (DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess)
 
HDESK APIENTRY NtUserOpenInputDesktop (DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess)
 
BOOL APIENTRY NtUserCloseDesktop (HDESK hDesktop)
 
BOOL APIENTRY NtUserPaintDesktop (HDC hDC)
 
HDESK NTAPI NtUserResolveDesktop (IN HANDLE ProcessHandle, IN PUNICODE_STRING DesktopPath, IN BOOL bInherit, OUT HWINSTA *phWinSta)
 
BOOL APIENTRY NtUserSwitchDesktop (HDESK hdesk)
 
HDESK APIENTRY NtUserGetThreadDesktop (DWORD dwThreadId, HDESK hConsoleDesktop)
 
BOOL IntSetThreadDesktop (IN HDESK hDesktop, IN BOOL FreeOnFailure)
 
BOOL APIENTRY NtUserSetThreadDesktop (HDESK hDesktop)
 

Variables

DWORD gdwDesktopSectionSize = 512
 
DWORD gdwNOIOSectionSize = 128
 
PDESKTOP gpdeskInputDesktop = NULL
 
HDC ScreenDeviceContext = NULL
 
PTHREADINFO gptiDesktopThread = NULL
 
HCURSOR gDesktopCursor = NULL
 
PKEVENT gpDesktopThreadStartedEvent = NULL
 

Function Documentation

◆ co_GetDesktopWindow()

PWND FASTCALL co_GetDesktopWindow ( PWND  pWnd)

Definition at line 1334 of file desktop.c.

1335 {
1336  if (pWnd->head.rpdesk &&
1337  pWnd->head.rpdesk->pDeskInfo)
1338  return pWnd->head.rpdesk->pDeskInfo->spwnd;
1339  return NULL;
1340 }
struct _DESKTOP * rpdesk
Definition: ntuser.h:189
THRDESKHEAD head
Definition: ntuser.h:660
#define NULL
Definition: types.h:112

Referenced by co_IntSendActivateMessages(), co_IntSetParent(), co_UserCreateWindowEx(), IntDefWindowProc(), IntIsTopLevelWindow(), and IntWinListOwnedPopups().

◆ co_IntShellHookNotify()

VOID co_IntShellHookNotify ( WPARAM  Message,
WPARAM  wParam,
LPARAM  lParam 
)

Definition at line 1660 of file desktop.c.

1661 {
1663  HWND* HwndList;
1664 
1665  if (!gpsi->uiShellMsg)
1666  {
1667  gpsi->uiShellMsg = IntAddAtom(L"SHELLHOOK");
1668 
1669  TRACE("MsgType = %x\n", gpsi->uiShellMsg);
1670  if (!gpsi->uiShellMsg)
1671  ERR("LastError: %x\n", EngGetLastError());
1672  }
1673 
1674  if (!Desktop)
1675  {
1676  TRACE("IntShellHookNotify: No desktop!\n");
1677  return;
1678  }
1679 
1680  // Allow other devices have a shot at foreground.
1681  if (Message == HSHELL_APPCOMMAND) ptiLastInput = NULL;
1682 
1683  // FIXME: System Tray Support.
1684 
1685  HwndList = UserBuildShellHookHwndList(Desktop);
1686  if (HwndList)
1687  {
1688  HWND* cursor = HwndList;
1689 
1690  for (; *cursor; cursor++)
1691  {
1692  TRACE("Sending notify\n");
1694  gpsi->uiShellMsg,
1695  Message,
1696  (Message == HSHELL_LANGUAGE ? lParam : (LPARAM)wParam) );
1697 /* co_IntPostOrSendMessage(*cursor,
1698  gpsi->uiShellMsg,
1699  Message,
1700  (Message == HSHELL_LANGUAGE ? lParam : (LPARAM)wParam) );*/
1701  }
1702 
1704  }
1705 
1706  if (ISITHOOKED(WH_SHELL))
1707  {
1709  }
1710 }
UINT uiShellMsg
Definition: ntuser.h:1019
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1346
ENGAPI ULONG APIENTRY EngGetLastError(VOID)
Definition: error.c:12
#define WH_SHELL
Definition: winuser.h:40
PSERVERINFO gpsi
Definition: main.c:27
WPARAM wParam
Definition: combotst.c:138
LONG_PTR LPARAM
Definition: windef.h:208
PTHREADINFO ptiLastInput
Definition: focus.c:17
#define TRACE(s)
Definition: solgame.cpp:4
#define ISITHOOKED(HookId)
Definition: hook.h:6
CHAR Message[80]
Definition: alive.c:5
LRESULT APIENTRY co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:1103
static HWND *FASTCALL UserBuildShellHookHwndList(PDESKTOP Desktop)
Definition: desktop.c:1619
static const WCHAR L[]
Definition: oid.c:1250
#define ERR(fmt,...)
Definition: debug.h:110
const char cursor[]
Definition: icontest.c:13
#define NULL
Definition: types.h:112
PDESKTOP FASTCALL IntGetActiveDesktop(VOID)
Definition: desktop.c:1230
#define USERTAG_WINDOWLIST
Definition: tags.h:297
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
RTL_ATOM FASTCALL IntAddAtom(LPWSTR AtomName)
Definition: useratom.c:13
LPARAM lParam
Definition: combotst.c:139

Referenced by co_UserCreateWindowEx(), co_UserDestroyWindow(), co_UserProcessHotKeys(), co_WinPosSetWindowPos(), DefSetText(), IntDefWindowProc(), NtUserActivateKeyboardLayout(), NtUserCallHwndLock(), NtUserDefSetText(), NtUserLoadKeyboardLayoutEx(), and UpdateShellHook().

◆ co_IntShowDesktop()

NTSTATUS FASTCALL co_IntShowDesktop ( PDESKTOP  Desktop,
ULONG  Width,
ULONG  Height,
BOOL  bRedraw 
)

Definition at line 1585 of file desktop.c.

1586 {
1587  PWND pwnd = Desktop->pDeskInfo->spwnd;
1589  ASSERT(pwnd);
1590 
1591  if (!bRedraw)
1592  flags |= SWP_NOREDRAW;
1593 
1594  co_WinPosSetWindowPos(pwnd, NULL, 0, 0, Width, Height, flags);
1595 
1596  if (bRedraw)
1598 
1599  return STATUS_SUCCESS;
1600 }
BOOLEAN FASTCALL co_WinPosSetWindowPos(PWND Window, HWND WndInsertAfter, INT x, INT y, INT cx, INT cy, UINT flags)
Definition: winpos.c:1720
#define SWP_NOZORDER
Definition: winuser.h:1232
#define ASSERT(a)
Definition: mode.c:44
#define SWP_NOACTIVATE
Definition: winuser.h:1227
GLbitfield flags
Definition: glext.h:7161
Definition: ntuser.h:658
BOOL FASTCALL co_UserRedrawWindow(PWND Window, const RECTL *UpdateRect, PREGION UpdateRgn, ULONG Flags)
Definition: painting.c:888
#define RDW_ALLCHILDREN
Definition: winuser.h:1207
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define SWP_SHOWWINDOW
Definition: winuser.h:1233
#define SWP_NOREDRAW
Definition: winuser.h:1231
#define RDW_UPDATENOW
Definition: winuser.h:1206
#define STATUS_SUCCESS
Definition: shellext.h:65
#define RDW_INVALIDATE
Definition: winuser.h:1200

Referenced by co_IntInitializeDesktopGraphics(), and NtUserSwitchDesktop().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserDesktop  )

◆ DesktopThreadMain()

VOID NTAPI DesktopThreadMain ( VOID  )

Definition at line 1512 of file desktop.c.

1513 {
1514  BOOL Ret;
1515  MSG Msg;
1516 
1518 
1520 
1521  /* Register system classes. This thread does not belong to any desktop so the
1522  classes will be allocated from the shared heap */
1524 
1526 
1527  while (TRUE)
1528  {
1529  Ret = co_IntGetPeekMessage(&Msg, 0, 0, 0, PM_REMOVE, TRUE);
1530  if (Ret)
1531  {
1533  }
1534  }
1535 
1536  UserLeave();
1537 }
LRESULT FASTCALL IntDispatchMessage(PMSG pMsg)
Definition: message.c:841
#define TRUE
Definition: types.h:120
BOOL FASTCALL UserRegisterSystemClasses(VOID)
Definition: class.c:2306
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
PTHREADINFO gptiDesktopThread
Definition: desktop.c:37
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:263
PKEVENT gpDesktopThreadStartedEvent
Definition: desktop.c:39
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:271
BOOL APIENTRY co_IntGetPeekMessage(PMSG pMsg, HWND hWnd, UINT MsgFilterMin, UINT MsgFilterMax, UINT RemoveMsg, BOOL bGMSG)
Definition: message.c:1177
struct @1599 Msg[]
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define PM_REMOVE
Definition: winuser.h:1182

Referenced by UserSystemThreadProc().

◆ DesktopWindowProc()

BOOL FASTCALL DesktopWindowProc ( PWND  Wnd,
UINT  Msg,
WPARAM  wParam,
LPARAM  lParam,
LRESULT lResult 
)

Definition at line 1405 of file desktop.c.

1406 {
1407  PAINTSTRUCT Ps;
1408  ULONG Value;
1409  //ERR("DesktopWindowProc\n");
1410 
1411  *lResult = 0;
1412 
1413  switch (Msg)
1414  {
1415  case WM_NCCREATE:
1416  if (!Wnd->fnid)
1417  {
1418  Wnd->fnid = FNID_DESKTOP;
1419  }
1420  *lResult = (LRESULT)TRUE;
1421  return TRUE;
1422 
1423  case WM_CREATE:
1425  // Save Process ID
1428  // Save Thread ID
1430  case WM_CLOSE:
1431  return TRUE;
1432 
1433  case WM_DISPLAYCHANGE:
1435  return TRUE;
1436 
1437  case WM_ERASEBKGND:
1439  *lResult = 1;
1440  return TRUE;
1441 
1442  case WM_PAINT:
1443  {
1444  if (IntBeginPaint(Wnd, &Ps))
1445  {
1446  IntEndPaint(Wnd, &Ps);
1447  }
1448  return TRUE;
1449  }
1450  case WM_SYSCOLORCHANGE:
1452  return TRUE;
1453 
1454  case WM_SETCURSOR:
1455  {
1456  PCURICON_OBJECT pcurOld, pcurNew;
1458  if (!pcurNew)
1459  {
1460  return TRUE;
1461  }
1462 
1463  pcurNew->CURSORF_flags |= CURSORF_CURRENT;
1464  pcurOld = UserSetCursor(pcurNew, FALSE);
1465  if (pcurOld)
1466  {
1467  pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
1468  UserDereferenceObject(pcurOld);
1469  }
1470  return TRUE;
1471  }
1472 
1473  case WM_WINDOWPOSCHANGING:
1474  {
1475  PWINDOWPOS pWindowPos = (PWINDOWPOS)lParam;
1476  if ((pWindowPos->flags & SWP_SHOWWINDOW) != 0)
1477  {
1478  HDESK hdesk = UserOpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
1479  IntSetThreadDesktop(hdesk, FALSE);
1480  }
1481  break;
1482  }
1483  default:
1484  TRACE("DWP calling IDWP Msg %d\n",Msg);
1485  //*lResult = IntDefWindowProc(Wnd, Msg, wParam, lParam, FALSE);
1486  }
1487  return TRUE; /* We are done. Do not do any callbacks to user mode */
1488 }
#define WM_SYSCOLORCHANGE
Definition: winuser.h:1608
#define CURSORF_CURRENT
Definition: ntuser.h:1159
PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
Definition: cursoricon.c:200
#define TRUE
Definition: types.h:120
BOOLEAN FASTCALL co_WinPosSetWindowPos(PWND Window, HWND WndInsertAfter, INT x, INT y, INT cx, INT cy, UINT flags)
Definition: winpos.c:1720
static HDC
Definition: imagelist.c:92
#define HandleToULong(h)
Definition: basetsd.h:95
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:610
#define SWP_NOZORDER
Definition: winuser.h:1232
#define DT_GWL_THREADID
Definition: desktop.h:56
HCURSOR gDesktopCursor
Definition: desktop.c:38
#define WM_NCCREATE
Definition: winuser.h:1665
WPARAM wParam
Definition: combotst.c:138
#define DT_GWL_PROCESSID
Definition: desktop.h:55
#define FALSE
Definition: types.h:117
DWORD fnid
Definition: ntuser.h:674
#define FNID_DESKTOP
Definition: ntuser.h:827
#define WM_SETCURSOR
Definition: winuser.h:1618
BOOL FASTCALL IntPaintDesktop(HDC hDC)
Definition: desktop.c:1795
PsGetCurrentThreadId
Definition: CrNtStubs.h:7
UINT flags
Definition: winuser.h:3569
HDESK UserOpenInputDesktop(DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess)
Definition: desktop.c:2576
struct _WINDOWPOS * PWINDOWPOS
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define UserHMGetHandle(obj)
Definition: ntuser.h:208
#define TRACE(s)
Definition: solgame.cpp:4
LONG FASTCALL co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
Definition: window.c:3762
#define SWP_NOACTIVATE
Definition: winuser.h:1227
#define RDW_ERASE
Definition: winuser.h:1197
#define WM_WINDOWPOSCHANGING
Definition: winuser.h:1643
#define WM_CLOSE
Definition: winuser.h:1603
HDC FASTCALL IntBeginPaint(PWND Window, PPAINTSTRUCT Ps)
Definition: painting.c:1434
#define WM_PAINT
Definition: winuser.h:1602
ULONG CURSORF_flags
Definition: cursoricon.h:16
#define LRESULT
Definition: ole.h:14
#define DESKTOP_ALL_ACCESS
Definition: precomp.h:20
struct @1599 Msg[]
BOOL FASTCALL co_UserRedrawWindow(PWND Window, const RECTL *UpdateRect, PREGION UpdateRgn, ULONG Flags)
Definition: painting.c:888
#define RDW_ALLCHILDREN
Definition: winuser.h:1207
BOOL IntSetThreadDesktop(IN HDESK hDesktop, IN BOOL FreeOnFailure)
Definition: desktop.c:3215
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
BOOL FASTCALL IntEndPaint(PWND Wnd, PPAINTSTRUCT Ps)
Definition: painting.c:1530
#define NULL
Definition: types.h:112
#define SWP_SHOWWINDOW
Definition: winuser.h:1233
#define WM_CREATE
Definition: winuser.h:1590
#define HIWORD(l)
Definition: typedefs.h:247
unsigned int ULONG
Definition: retypes.h:1
#define WM_ERASEBKGND
Definition: winuser.h:1607
PCURICON_OBJECT FASTCALL UserSetCursor(PCURICON_OBJECT NewCursor, BOOL ForceChange)
Definition: msgqueue.c:93
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
#define RDW_INVALIDATE
Definition: winuser.h:1200

Referenced by co_IntSendMessageTimeoutSingle(), co_IntSendMessageWithCallBack(), IntDispatchMessage(), and NtUserMessageCall().

◆ GetSystemVersionString()

static NTSTATUS GetSystemVersionString ( OUT PWSTR  pwszzVersion,
IN SIZE_T  cchDest,
IN BOOLEAN  InSafeMode,
IN BOOLEAN  AppendNtSystemRoot 
)
static

Definition at line 271 of file desktop.c.

275 {
277 
278  RTL_OSVERSIONINFOEXW VerInfo;
279  UNICODE_STRING BuildLabString;
280  UNICODE_STRING CSDVersionString;
281  RTL_QUERY_REGISTRY_TABLE VersionConfigurationTable[] =
282  {
283  {
284  NULL,
286  L"BuildLab",
287  &BuildLabString,
288  REG_NONE, NULL, 0
289  },
290  {
291  NULL,
293  L"CSDVersion",
294  &CSDVersionString,
295  REG_NONE, NULL, 0
296  },
297 
298  {0}
299  };
300 
301  WCHAR BuildLabBuffer[256];
302  WCHAR VersionBuffer[256];
303  PWCHAR EndBuffer;
304 
305  VerInfo.dwOSVersionInfoSize = sizeof(VerInfo);
306 
307  /*
308  * This call is uniquely used to retrieve the current CSD numbers.
309  * All the rest (major, minor, ...) is either retrieved from the
310  * SharedUserData structure, or from the registry.
311  */
313 
314  /*
315  * - Retrieve the BuildLab string from the registry (set by the kernel).
316  * - In kernel-mode, szCSDVersion is not initialized. Initialize it
317  * and query its value from the registry.
318  */
319  RtlZeroMemory(BuildLabBuffer, sizeof(BuildLabBuffer));
320  RtlInitEmptyUnicodeString(&BuildLabString,
321  BuildLabBuffer,
322  sizeof(BuildLabBuffer));
323  RtlZeroMemory(VerInfo.szCSDVersion, sizeof(VerInfo.szCSDVersion));
324  RtlInitEmptyUnicodeString(&CSDVersionString,
325  VerInfo.szCSDVersion,
326  sizeof(VerInfo.szCSDVersion));
328  L"",
329  VersionConfigurationTable,
330  NULL,
331  NULL);
332  if (!NT_SUCCESS(Status))
333  {
334  /* Indicate nothing is there */
335  BuildLabString.Length = 0;
336  CSDVersionString.Length = 0;
337  }
338  /* NULL-terminate the strings */
339  BuildLabString.Buffer[BuildLabString.Length / sizeof(WCHAR)] = UNICODE_NULL;
340  CSDVersionString.Buffer[CSDVersionString.Length / sizeof(WCHAR)] = UNICODE_NULL;
341 
342  EndBuffer = VersionBuffer;
343  if ( /* VerInfo.wServicePackMajor != 0 && */ CSDVersionString.Length)
344  {
345  /* Print the version string */
346  Status = RtlStringCbPrintfExW(VersionBuffer,
347  sizeof(VersionBuffer),
348  &EndBuffer,
349  NULL,
350  0,
351  L": %wZ",
352  &CSDVersionString);
353  if (!NT_SUCCESS(Status))
354  {
355  /* No version, NULL-terminate the string */
356  *EndBuffer = UNICODE_NULL;
357  }
358  }
359  else
360  {
361  /* No version, NULL-terminate the string */
362  *EndBuffer = UNICODE_NULL;
363  }
364 
365  if (InSafeMode)
366  {
367  /* String for Safe Mode */
368  Status = RtlStringCchPrintfW(pwszzVersion,
369  cchDest,
370  L"ReactOS Version %S %wZ (NT %u.%u Build %u%s)\n",
371  KERNEL_VERSION_STR,
372  &BuildLabString,
373  SharedUserData->NtMajorVersion,
374  SharedUserData->NtMinorVersion,
375  (VerInfo.dwBuildNumber & 0xFFFF),
376  VersionBuffer);
377 
378  if (AppendNtSystemRoot && NT_SUCCESS(Status))
379  {
380  Status = RtlStringCbPrintfW(VersionBuffer,
381  sizeof(VersionBuffer),
382  L" - %s\n",
383  SharedUserData->NtSystemRoot);
384  if (NT_SUCCESS(Status))
385  {
386  /* Replace the last newline by a NULL, before concatenating */
387  EndBuffer = wcsrchr(pwszzVersion, L'\n');
388  if (EndBuffer) *EndBuffer = UNICODE_NULL;
389 
390  /* The concatenated string has a terminating newline */
391  Status = RtlStringCchCatW(pwszzVersion,
392  cchDest,
393  VersionBuffer);
394  if (!NT_SUCCESS(Status))
395  {
396  /* Concatenation failed, put back the newline */
397  if (EndBuffer) *EndBuffer = L'\n';
398  }
399  }
400 
401  /* Override any failures as the NtSystemRoot string is optional */
403  }
404  }
405  else
406  {
407  /* Multi-string for Normal Mode */
408  Status = RtlStringCchPrintfW(pwszzVersion,
409  cchDest,
410  L"ReactOS Version %S\n"
411  L"Build %wZ\n"
412  L"Reporting NT %u.%u (Build %u%s)\n",
413  KERNEL_VERSION_STR,
414  &BuildLabString,
415  SharedUserData->NtMajorVersion,
416  SharedUserData->NtMinorVersion,
417  (VerInfo.dwBuildNumber & 0xFFFF),
418  VersionBuffer);
419 
420  if (AppendNtSystemRoot && NT_SUCCESS(Status))
421  {
422  Status = RtlStringCbPrintfW(VersionBuffer,
423  sizeof(VersionBuffer),
424  L"%s\n",
425  SharedUserData->NtSystemRoot);
426  if (NT_SUCCESS(Status))
427  {
428  Status = RtlStringCchCatW(pwszzVersion,
429  cchDest,
430  VersionBuffer);
431  }
432 
433  /* Override any failures as the NtSystemRoot string is optional */
435  }
436  }
437 
438  if (!NT_SUCCESS(Status))
439  {
440  /* Fall-back string */
441  Status = RtlStringCchPrintfW(pwszzVersion,
442  cchDest,
443  L"ReactOS Version %S %wZ\n",
444  KERNEL_VERSION_STR,
445  &BuildLabString);
446  if (!NT_SUCCESS(Status))
447  {
448  /* General failure, NULL-terminate the string */
449  pwszzVersion[0] = UNICODE_NULL;
450  }
451  }
452 
453  /*
454  * Convert the string separators (newlines) into NULLs
455  * and NULL-terminate the multi-string.
456  */
457  while (*pwszzVersion)
458  {
459  EndBuffer = wcschr(pwszzVersion, L'\n');
460  if (!EndBuffer) break;
461  pwszzVersion = EndBuffer;
462 
463  *pwszzVersion++ = UNICODE_NULL;
464  }
465  *pwszzVersion = UNICODE_NULL;
466 
467  return Status;
468 }
ULONG dwBuildNumber
Definition: rtltypes.h:272
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:269
NTSTATUS NTAPI RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
Definition: version.c:158
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define RTL_REGISTRY_WINDOWS_NT
Definition: nt_native.h:164
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
LONG NTSTATUS
Definition: precomp.h:26
NTSTRSAFEVAPI RtlStringCbPrintfExW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR *ppszDestEnd, _Out_opt_ size_t *pcbRemaining, _In_ STRSAFE_DWORD dwFlags, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1335
uint16_t * PWCHAR
Definition: typedefs.h:56
#define UNICODE_NULL
Status
Definition: gdiplustypes.h:24
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
NTSTRSAFEAPI RtlStringCchCatW(_Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:601
#define SharedUserData
static const WCHAR L[]
Definition: oid.c:1250
WCHAR szCSDVersion[128]
Definition: rtltypes.h:274
#define wcsrchr
Definition: compat.h:16
#define NULL
Definition: types.h:112
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
#define REG_NONE
Definition: nt_native.h:1492
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144

Referenced by IntPaintDesktop().

◆ InitDesktopImpl()

NTSTATUS NTAPI InitDesktopImpl ( VOID  )

Definition at line 240 of file desktop.c.

241 {
242  GENERIC_MAPPING IntDesktopMapping = { DESKTOP_READ,
246 
247  /* Set Desktop Object Attributes */
249  ExDesktopObjectType->TypeInfo.GenericMapping = IntDesktopMapping;
251 
252  /* Allocate memory for the event structure */
254  sizeof(KEVENT),
255  USERTAG_EVENT);
257  {
258  ERR("Failed to allocate event!\n");
259  return STATUS_NO_MEMORY;
260  }
261 
262  /* Initialize the kernel event */
265  FALSE);
266 
267  return STATUS_SUCCESS;
268 }
#define DESKTOP_EXECUTE
Definition: desktop.h:70
POBJECT_TYPE ExDesktopObjectType
Definition: win32k.c:22
#define USERTAG_EVENT
Definition: tags.h:229
#define FALSE
Definition: types.h:117
PKEVENT gpDesktopThreadStartedEvent
Definition: desktop.c:39
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define DESKTOP_WRITE
Definition: desktop.h:62
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
#define DESKTOP_ALL_ACCESS
Definition: precomp.h:20
#define ERR(fmt,...)
Definition: debug.h:110
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
struct _DESKTOP DESKTOP
#define DESKTOP_READ
Definition: desktop.h:58
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:365

Referenced by DriverEntry().

◆ IntCreateDesktop()

NTSTATUS FASTCALL IntCreateDesktop ( OUT HDESK *  phDesktop,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN KPROCESSOR_MODE  AccessMode,
IN PUNICODE_STRING lpszDesktopDevice  OPTIONAL,
IN LPDEVMODEW lpdmw  OPTIONAL,
IN DWORD  dwFlags,
IN ACCESS_MASK  dwDesiredAccess 
)

Definition at line 2312 of file desktop.c.

2320 {
2321  NTSTATUS Status;
2322  PDESKTOP pdesk = NULL;
2323  HDESK hDesk;
2324  BOOLEAN Context = FALSE;
2325  UNICODE_STRING ClassName;
2326  LARGE_STRING WindowName;
2327  BOOL NoHooks = FALSE;
2328  PWND pWnd = NULL;
2329  CREATESTRUCTW Cs;
2330  PTHREADINFO ptiCurrent;
2331  PCLS pcls;
2332 
2333  TRACE("Enter IntCreateDesktop\n");
2334 
2335  ASSERT(phDesktop);
2336  *phDesktop = NULL;
2337 
2338  ptiCurrent = PsGetCurrentThreadWin32Thread();
2339  ASSERT(ptiCurrent);
2341 
2342  /* Turn off hooks when calling any CreateWindowEx from inside win32k */
2343  NoHooks = (ptiCurrent->TIF_flags & TIF_DISABLEHOOKS);
2344  ptiCurrent->TIF_flags |= TIF_DISABLEHOOKS;
2345  ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
2346 
2347  /*
2348  * Try to open already existing desktop
2349  */
2352  AccessMode,
2353  NULL,
2354  dwDesiredAccess,
2355  (PVOID)&Context,
2356  (PHANDLE)&hDesk);
2357  if (!NT_SUCCESS(Status))
2358  {
2359  ERR("ObOpenObjectByName failed to open/create desktop\n");
2360  goto Quit;
2361  }
2362 
2363  /* In case the object was not created (eg if it existed), return now */
2364  if (Context == FALSE)
2365  {
2366  TRACE("IntCreateDesktop opened desktop '%wZ'\n", ObjectAttributes->ObjectName);
2368  goto Quit;
2369  }
2370 
2371  /* Reference the desktop */
2373  0,
2375  KernelMode,
2376  (PVOID*)&pdesk,
2377  NULL);
2378  if (!NT_SUCCESS(Status))
2379  {
2380  ERR("Failed to reference desktop object\n");
2381  goto Quit;
2382  }
2383 
2384  /* Get the desktop window class. The thread desktop does not belong to any desktop
2385  * so the classes created there (including the desktop class) are allocated in the shared heap
2386  * It would cause problems if we used a class that belongs to the caller
2387  */
2388  ClassName.Buffer = WC_DESKTOP;
2389  ClassName.Length = 0;
2390  pcls = IntGetAndReferenceClass(&ClassName, 0, TRUE);
2391  if (pcls == NULL)
2392  {
2393  ASSERT(FALSE);
2395  goto Quit;
2396  }
2397 
2398  RtlZeroMemory(&WindowName, sizeof(WindowName));
2399  RtlZeroMemory(&Cs, sizeof(Cs));
2405  Cs.hInstance = hModClient; // hModuleWin; // Server side winproc!
2406  Cs.lpszName = (LPCWSTR) &WindowName;
2407  Cs.lpszClass = (LPCWSTR) &ClassName;
2408 
2409  /* Use IntCreateWindow instead of co_UserCreateWindowEx because the later expects a thread with a desktop */
2410  pWnd = IntCreateWindow(&Cs, &WindowName, pcls, NULL, NULL, NULL, pdesk, WINVER);
2411  if (pWnd == NULL)
2412  {
2413  ERR("Failed to create desktop window for the new desktop\n");
2415  goto Quit;
2416  }
2417 
2419  pdesk->DesktopWindow = pWnd->head.h;
2420  pdesk->pDeskInfo->spwnd = pWnd;
2421  pWnd->fnid = FNID_DESKTOP;
2422 
2423  ClassName.Buffer = MAKEINTATOM(gpsi->atomSysClass[ICLS_HWNDMESSAGE]);
2424  ClassName.Length = 0;
2425  pcls = IntGetAndReferenceClass(&ClassName, 0, TRUE);
2426  if (pcls == NULL)
2427  {
2428  ASSERT(FALSE);
2430  goto Quit;
2431  }
2432 
2433  RtlZeroMemory(&WindowName, sizeof(WindowName));
2434  RtlZeroMemory(&Cs, sizeof(Cs));
2435  Cs.cx = Cs.cy = 100;
2437  Cs.hInstance = hModClient; // hModuleWin; // Server side winproc!
2438  Cs.lpszName = (LPCWSTR)&WindowName;
2439  Cs.lpszClass = (LPCWSTR)&ClassName;
2440  pWnd = IntCreateWindow(&Cs, &WindowName, pcls, NULL, NULL, NULL, pdesk, WINVER);
2441  if (pWnd == NULL)
2442  {
2443  ERR("Failed to create message window for the new desktop\n");
2445  goto Quit;
2446  }
2447 
2448  pdesk->spwndMessage = pWnd;
2449  pWnd->fnid = FNID_MESSAGEWND;
2450 
2451  /* Now,,,
2452  if !(WinStaObject->Flags & WSF_NOIO) is (not set) for desktop input output mode (see wiki)
2453  Create Tooltip. Saved in DesktopObject->spwndTooltip.
2454  Tooltip dwExStyle: WS_EX_TOOLWINDOW|WS_EX_TOPMOST
2455  hWndParent are spwndMessage. Use hModuleWin for server side winproc!
2456  The rest is same as message window.
2457  http://msdn.microsoft.com/en-us/library/bb760250(VS.85).aspx
2458  */
2460 
2461 Quit:
2462  if (pdesk != NULL)
2463  {
2464  ObDereferenceObject(pdesk);
2465  }
2466  if (!NT_SUCCESS(Status) && hDesk != NULL)
2467  {
2468  ObCloseHandle(hDesk, AccessMode);
2469  hDesk = NULL;
2470  }
2471  if (!NoHooks)
2472  {
2473  ptiCurrent->TIF_flags &= ~TIF_DISABLEHOOKS;
2474  ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
2475  }
2476 
2477  TRACE("Leave IntCreateDesktop, Status 0x%08lx\n", Status);
2478 
2479  if (NT_SUCCESS(Status))
2480  *phDesktop = hDesk;
2481  else
2483  return Status;
2484 }
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2528
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
PDESKTOPINFO pDeskInfo
Definition: desktop.h:8
#define SM_XVIRTUALSCREEN
Definition: winuser.h:1026
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define SM_CXVIRTUALSCREEN
Definition: winuser.h:1028
#define TRUE
Definition: types.h:120
FLONG TIF_flags
Definition: win32.h:94
DWORD dwSessionId
Definition: desktop.h:6
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
LONG NTSTATUS
Definition: precomp.h:26
#define WINVER
Definition: targetver.h:11
POBJECT_TYPE ExDesktopObjectType
Definition: win32k.c:22
#define WS_CLIPCHILDREN
Definition: pedump.c:619
PSERVERINFO gpsi
Definition: main.c:27
#define FNID_MESSAGEWND
Definition: ntuser.h:829
#define WC_DESKTOP
Definition: undocuser.h:10
PTHREADINFO gptiDesktopThread
Definition: desktop.c:37
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define FALSE
Definition: types.h:117
DWORD fnid
Definition: ntuser.h:674
unsigned int BOOL
Definition: ntddk_ex.h:94
#define FNID_DESKTOP
Definition: ntuser.h:827
HWND DesktopWindow
Definition: desktop.h:40
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:395
THRDESKHEAD head
Definition: ntuser.h:660
unsigned char BOOLEAN
Definition: ntuser.h:534
PWND FASTCALL IntCreateWindow(CREATESTRUCTW *Cs, PLARGE_STRING WindowName, PCLS Class, PWND ParentWindow, PWND OwnerWindow, PVOID acbiBuffer, PDESKTOP pdeskCreated, DWORD dwVer)
Definition: window.c:1612
#define SM_CYVIRTUALSCREEN
Definition: winuser.h:1029
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:180
HINSTANCE hInstance
Definition: winuser.h:2931
Status
Definition: gdiplustypes.h:24
ULONG NTAPI PsGetCurrentProcessSessionId(VOID)
Definition: process.c:1133
#define TRACE(s)
Definition: solgame.cpp:4
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PCLS IntGetAndReferenceClass(PUNICODE_STRING ClassName, HINSTANCE hInstance, BOOL bDesktopThread)
Definition: class.c:1437
#define ObDereferenceObject
Definition: obfuncs.h:203
PWND spwndMessage
Definition: desktop.h:20
struct _CLIENTINFO * pClientInfo
Definition: win32.h:93
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3375
LPCWSTR lpszName
Definition: winuser.h:2939
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
struct _WND * spwnd
Definition: ntuser.h:136
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
#define SM_YVIRTUALSCREEN
Definition: winuser.h:1027
#define ERR(fmt,...)
Definition: debug.h:110
Definition: ntuser.h:658
#define WS_POPUP
Definition: pedump.c:616
#define NULL
Definition: types.h:112
LPCWSTR lpszClass
Definition: winuser.h:2940
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define TIF_DISABLEHOOKS
Definition: ntuser.h:268
HINSTANCE hModClient
Definition: ntuser.c:25
#define STATUS_SUCCESS
Definition: shellext.h:65
#define MAKEINTATOM(i)
Definition: winbase.h:1445
ATOM atomSysClass[ICLS_NOTUSED+1]
Definition: ntuser.h:1016

Referenced by IntResolveDesktop(), and NtUserCreateDesktop().

◆ IntDeRegisterShellHookWindow()

BOOL IntDeRegisterShellHookWindow ( HWND  hWnd)

Definition at line 1752 of file desktop.c.

1753 {
1755  PDESKTOP Desktop = pti->rpdesk;
1756  PLIST_ENTRY ListEntry;
1757  PSHELL_HOOK_WINDOW Current;
1758 
1759  ListEntry = Desktop->ShellHookWindows.Flink;
1760  while (ListEntry != &Desktop->ShellHookWindows)
1761  {
1762  Current = CONTAINING_RECORD(ListEntry, SHELL_HOOK_WINDOW, ListEntry);
1763  ListEntry = ListEntry->Flink;
1764  if (Current->hWnd == hWnd)
1765  {
1766  RemoveEntryList(&Current->ListEntry);
1767  ExFreePoolWithTag(Current, TAG_WINSTA);
1768  return TRUE;
1769  }
1770  }
1771 
1772  return FALSE;
1773 }
#define TRUE
Definition: types.h:120
#define TAG_WINSTA
Definition: tags.h:11
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
LIST_ENTRY ListEntry
Definition: desktop.h:93
HWND hWnd
Definition: settings.c:17
struct _DESKTOP * rpdesk
Definition: win32.h:91
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define FALSE
Definition: types.h:117
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: typedefs.h:119
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by co_UserFreeWindow(), IntRegisterShellHookWindow(), and NtUserCallHwnd().

◆ IntDesktopObjectClose()

NTSTATUS NTAPI IntDesktopObjectClose ( _In_ PVOID  Parameters)

Definition at line 215 of file desktop.c.

217 {
218  NTSTATUS Ret;
219  PWIN32_CLOSEMETHOD_PARAMETERS CloseParameters = Parameters;
220  PPROCESSINFO ppi = PsGetProcessWin32Process(CloseParameters->Process);
221  if (ppi == NULL)
222  {
223  /* This happens when the process leaks desktop handles.
224  * At this point the PPROCESSINFO is already destroyed */
225  return STATUS_SUCCESS;
226  }
227 
229  Ret = IntUnmapDesktopView((PDESKTOP)CloseParameters->Object);
230  UserLeave();
231  return Ret;
232 }
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:863
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
LONG NTSTATUS
Definition: precomp.h:26
static NTSTATUS IntUnmapDesktopView(IN PDESKTOP pdesk)
Definition: desktop.c:3097
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:263
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:271
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by DriverEntry().

◆ IntDesktopObjectDelete()

NTSTATUS NTAPI IntDesktopObjectDelete ( _In_ PVOID  Parameters)

Definition at line 147 of file desktop.c.

149 {
150  PWIN32_DELETEMETHOD_PARAMETERS DeleteParameters = Parameters;
151  PDESKTOP pdesk = (PDESKTOP)DeleteParameters->Object;
152 
153  TRACE("Deleting desktop object 0x%p\n", pdesk);
154 
155  if (pdesk->pDeskInfo &&
156  pdesk->pDeskInfo->spwnd)
157  {
158  ASSERT(pdesk->pDeskInfo->spwnd->spwndChild == NULL);
160  }
161 
162  if (pdesk->spwndMessage)
164 
165  /* Remove the desktop from the window station's list of associcated desktops */
166  RemoveEntryList(&pdesk->ListEntry);
167 
168  /* Free the heap */
169  IntFreeDesktopHeap(pdesk);
170 
172 
173  return STATUS_SUCCESS;
174 }
PDESKTOPINFO pDeskInfo
Definition: desktop.h:8
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:863
static VOID IntFreeDesktopHeap(IN PDESKTOP pdesk)
struct _DESKTOP * PDESKTOP
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOLEAN co_UserDestroyWindow(PVOID Object)
Definition: window.c:2579
struct _WINSTATION_OBJECT * rpwinstaParent
Definition: desktop.h:11
#define TRACE(s)
Definition: solgame.cpp:4
#define ASSERT(a)
Definition: mode.c:44
#define ObDereferenceObject
Definition: obfuncs.h:203
PWND spwndMessage
Definition: desktop.h:20
struct _WND * spwnd
Definition: ntuser.h:136
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65
LIST_ENTRY ListEntry
Definition: desktop.h:9

Referenced by DriverEntry().

◆ IntDesktopObjectOpen()

NTSTATUS NTAPI IntDesktopObjectOpen ( _In_ PVOID  Parameters)

Definition at line 202 of file desktop.c.

204 {
205  PWIN32_OPENMETHOD_PARAMETERS OpenParameters = Parameters;
206  PPROCESSINFO ppi = PsGetProcessWin32Process(OpenParameters->Process);
207  if (ppi == NULL)
208  return STATUS_SUCCESS;
209 
210  return IntMapDesktopView((PDESKTOP)OpenParameters->Object);
211 }
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:863
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
static NTSTATUS IntMapDesktopView(IN PDESKTOP pdesk)
Definition: desktop.c:3141
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by DriverEntry().

◆ IntDesktopObjectParse()

NTSTATUS APIENTRY IntDesktopObjectParse ( IN PVOID  ParseObject,
IN PVOID  ObjectType,
IN OUT PACCESS_STATE  AccessState,
IN KPROCESSOR_MODE  AccessMode,
IN ULONG  Attributes,
IN OUT PUNICODE_STRING  CompleteName,
IN OUT PUNICODE_STRING  RemainingName,
IN OUT PVOID Context  OPTIONAL,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos  OPTIONAL,
OUT PVOID Object 
)

Definition at line 45 of file desktop.c.

55 {
59  PLIST_ENTRY NextEntry, ListHead;
60  PWINSTATION_OBJECT WinStaObject = (PWINSTATION_OBJECT)ParseObject;
61  UNICODE_STRING DesktopName;
62  PBOOLEAN pContext = (PBOOLEAN) Context;
63 
64  if (pContext)
65  *pContext = FALSE;
66 
67  /* Set the list pointers and loop the window station */
68  ListHead = &WinStaObject->DesktopListHead;
69  NextEntry = ListHead->Flink;
70  while (NextEntry != ListHead)
71  {
72  /* Get the current desktop */
73  Desktop = CONTAINING_RECORD(NextEntry, DESKTOP, ListEntry);
74 
75  /* Get the desktop name */
76  ASSERT(Desktop->pDeskInfo != NULL);
77  RtlInitUnicodeString(&DesktopName, Desktop->pDeskInfo->szDesktopName);
78 
79  /* Compare the name */
81  &DesktopName,
83  {
84  /* We found a match. Did this come from a create? */
85  if (Context)
86  {
87  /* Unless OPEN_IF was given, fail with an error */
88  if (!(Attributes & OBJ_OPENIF))
89  {
90  /* Name collision */
92  }
93  else
94  {
95  /* Otherwise, return with a warning only */
97  }
98  }
99  else
100  {
101  /* This was a real open, so this is OK */
103  }
104 
105  /* Reference the desktop and return it */
107  *Object = Desktop;
108  return Status;
109  }
110 
111  /* Go to the next desktop */
112  NextEntry = NextEntry->Flink;
113  }
114 
115  /* If we got here but this isn't a create, just fail */
117 
118  /* Create the desktop object */
123  KernelMode,
124  NULL,
125  sizeof(DESKTOP),
126  0,
127  0,
128  (PVOID*)&Desktop);
129  if (!NT_SUCCESS(Status)) return Status;
130 
131  /* Initialize the desktop */
133  if (!NT_SUCCESS(Status))
134  {
136  return Status;
137  }
138 
139  /* Set the desktop object and return success */
140  *Object = Desktop;
141  *pContext = TRUE;
142  return STATUS_SUCCESS;
143 }
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define TRUE
Definition: types.h:120
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
LONG NTSTATUS
Definition: precomp.h:26
POBJECT_TYPE ExDesktopObjectType
Definition: win32k.c:22
LIST_ENTRY DesktopListHead
Definition: winsta.h:18
#define OBJ_OPENIF
Definition: winternl.h:229
#define FALSE
Definition: types.h:117
static CHAR Desktop[MAX_PATH]
Definition: dem.c:256
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:952
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
struct _WINSTATION_OBJECT * PWINSTATION_OBJECT
char * PBOOLEAN
Definition: retypes.h:11
Definition: typedefs.h:119
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define NULL
Definition: types.h:112
static NTSTATUS UserInitializeDesktop(PDESKTOP pdesk, PUNICODE_STRING DesktopName, PWINSTATION_OBJECT pwinsta)
Definition: desktop.c:2220
#define ObReferenceObject
Definition: obfuncs.h:204
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:801

Referenced by IntWinStaObjectParse().

◆ IntDesktopOkToClose()

NTSTATUS NTAPI IntDesktopOkToClose ( _In_ PVOID  Parameters)

Definition at line 178 of file desktop.c.

180 {
181  PWIN32_OKAYTOCLOSEMETHOD_PARAMETERS OkToCloseParameters = Parameters;
183 
184  if (pti == NULL)
185  {
186  /* This happens when we leak desktop handles */
187  return STATUS_SUCCESS;
188  }
189 
190  /* Do not allow the current desktop or the initial desktop to be closed */
191  if (OkToCloseParameters->Handle == pti->ppi->hdeskStartup ||
192  OkToCloseParameters->Handle == pti->hdesk)
193  {
194  return STATUS_ACCESS_DENIED;
195  }
196 
197  return STATUS_SUCCESS;
198 }
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:863
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
PPROCESSINFO ppi
Definition: win32.h:87
HDESK hdesk
Definition: win32.h:107
HDESK hdeskStartup
Definition: win32.h:255
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by DriverEntry().

◆ IntFreeDesktopHeap() [1/2]

static VOID IntFreeDesktopHeap ( IN PDESKTOP  pdesk)
static

Referenced by IntDesktopObjectDelete().

◆ IntFreeDesktopHeap() [2/2]

static VOID IntFreeDesktopHeap ( IN OUT PDESKTOP  Desktop)
static

Definition at line 1776 of file desktop.c.

1777 {
1778  /* FIXME: Disable until unmapping works in mm */
1779 #if 0
1780  if (Desktop->pheapDesktop != NULL)
1781  {
1782  MmUnmapViewInSessionSpace(Desktop->pheapDesktop);
1783  Desktop->pheapDesktop = NULL;
1784  }
1785 
1786  if (Desktop->hsectionDesktop != NULL)
1787  {
1788  ObDereferenceObject(Desktop->hsectionDesktop);
1789  Desktop->hsectionDesktop = NULL;
1790  }
1791 #endif
1792 }
NTSTATUS NTAPI MmUnmapViewInSessionSpace(IN PVOID MappedBase)
Definition: section.c:3081
#define ObDereferenceObject
Definition: obfuncs.h:203
#define NULL
Definition: types.h:112

◆ IntGetActiveDesktop()

◆ IntGetCurrentThreadDesktopWindow()

HWND FASTCALL IntGetCurrentThreadDesktopWindow ( VOID  )

Definition at line 1390 of file desktop.c.

1391 {
1393  PDESKTOP pdo = pti->rpdesk;
1394  if (NULL == pdo)
1395  {
1396  ERR("Thread doesn't have a desktop\n");
1397  return NULL;
1398  }
1399  return pdo->DesktopWindow;
1400 }
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
struct _DESKTOP * rpdesk
Definition: win32.h:91
HWND DesktopWindow
Definition: desktop.h:40
#define ERR(fmt,...)
Definition: debug.h:110
#define NULL
Definition: types.h:112

Referenced by NtUserFindWindowEx().

◆ IntGetDesktopObjectHandle()

HDESK FASTCALL IntGetDesktopObjectHandle ( PDESKTOP  DesktopObject)

Definition at line 1239 of file desktop.c.

1240 {
1241  NTSTATUS Status;
1242  HDESK hDesk;
1243 
1244  ASSERT(DesktopObject);
1245 
1247  DesktopObject,
1249  NULL,
1250  (PHANDLE)&hDesk))
1251  {
1252  Status = ObOpenObjectByPointer(DesktopObject,
1253  0,
1254  NULL,
1255  0,
1257  UserMode,
1258  (PHANDLE)&hDesk);
1259  if (!NT_SUCCESS(Status))
1260  {
1261  /* Unable to create a handle */
1262  ERR("Unable to create a desktop handle\n");
1263  return NULL;
1264  }
1265  }
1266  else
1267  {
1268  TRACE("Got handle: 0x%p\n", hDesk);
1269  }
1270 
1271  return hDesk;
1272 }
BOOLEAN NTAPI ObFindHandleForObject(IN PEPROCESS Process, IN PVOID Object, IN POBJECT_TYPE ObjectType, IN POBJECT_HANDLE_INFORMATION HandleInformation, OUT PHANDLE Handle)
Definition: obhandle.c:2852
LONG NTSTATUS
Definition: precomp.h:26
POBJECT_TYPE ExDesktopObjectType
Definition: win32k.c:22
NTSTATUS NTAPI ObOpenObjectByPointer(IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle)
Definition: obhandle.c:2738
#define PsGetCurrentProcess
Definition: psfuncs.h:17
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
#define ERR(fmt,...)
Definition: debug.h:110
#define NULL
Definition: types.h:112

Referenced by NtUserGetThreadDesktop(), and NtUserSetInformationThread().

◆ IntGetDesktopWindow()

HWND FASTCALL IntGetDesktopWindow ( VOID  )

Definition at line 1342 of file desktop.c.

1343 {
1344  PDESKTOP pdo = IntGetActiveDesktop();
1345  if (!pdo)
1346  {
1347  TRACE("No active desktop\n");
1348  return NULL;
1349  }
1350  return pdo->DesktopWindow;
1351 }
HWND DesktopWindow
Definition: desktop.h:40
#define TRACE(s)
Definition: solgame.cpp:4
#define NULL
Definition: types.h:112
PDESKTOP FASTCALL IntGetActiveDesktop(VOID)
Definition: desktop.c:1230

Referenced by co_IntProcessKeyboardMessage(), co_IntSetWindowLongPtr(), co_UserSetParent(), co_WinPosSetWindowPos(), DceUpdateVisRgn(), IntPaintDesktop(), NtUserAlterWindowStyle(), NtUserRedrawWindow(), NtUserSetParent(), NtUserSetWindowLong(), NtUserSetWindowWord(), NtUserWindowFromPoint(), SnapWindow(), UserGetAncestor(), UserRealizePalette(), and UserRegisterUserApiHook().

◆ IntGetFocusMessageQueue()

PUSER_MESSAGE_QUEUE FASTCALL IntGetFocusMessageQueue ( VOID  )

Definition at line 1275 of file desktop.c.

1276 {
1277  PDESKTOP pdo = IntGetActiveDesktop();
1278  if (!pdo)
1279  {
1280  TRACE("No active desktop\n");
1281  return(NULL);
1282  }
1284 }
struct _USER_MESSAGE_QUEUE * ActiveMessageQueue
Definition: desktop.h:38
#define TRACE(s)
Definition: solgame.cpp:4
#define NULL
Definition: types.h:112
PDESKTOP FASTCALL IntGetActiveDesktop(VOID)
Definition: desktop.c:1230

Referenced by co_IntSetForegroundAndFocusWindow(), co_UserSetFocus(), co_WinPosShowWindow(), DoTheScreenSaver(), IntGetCaptureWindow(), IntSendDestroyMsg(), NtUserGetGUIThreadInfo(), ProcessKeyEvent(), UserGetForegroundWindow(), UserProcessKeyboardInput(), and UserSendKeyboardInput().

◆ IntGetMessageWindow()

HWND FASTCALL IntGetMessageWindow ( VOID  )

Definition at line 1366 of file desktop.c.

1367 {
1368  PDESKTOP pdo = IntGetActiveDesktop();
1369 
1370  if (!pdo)
1371  {
1372  TRACE("No active desktop\n");
1373  return NULL;
1374  }
1375  return pdo->spwndMessage->head.h;
1376 }
THRDESKHEAD head
Definition: ntuser.h:660
#define TRACE(s)
Definition: solgame.cpp:4
PWND spwndMessage
Definition: desktop.h:20
#define NULL
Definition: types.h:112
PDESKTOP FASTCALL IntGetActiveDesktop(VOID)
Definition: desktop.c:1230

Referenced by NtUserFindWindowEx(), and NtUserSetParent().

◆ IntGetThreadDesktopWindow()

PWND FASTCALL IntGetThreadDesktopWindow ( PTHREADINFO  pti)

Definition at line 1327 of file desktop.c.

1328 {
1329  if (!pti) pti = PsGetCurrentThreadWin32Thread();
1330  if (pti->pDeskInfo) return pti->pDeskInfo->spwnd;
1331  return NULL;
1332 }
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
#define NULL
Definition: types.h:112
struct _DESKTOPINFO * pDeskInfo
Definition: win32.h:92

Referenced by ActivateOtherWindowMin().

◆ IntHideDesktop()

NTSTATUS FASTCALL IntHideDesktop ( PDESKTOP  Desktop)

Definition at line 1603 of file desktop.c.

1604 {
1605  PWND DesktopWnd;
1606 
1607  DesktopWnd = IntGetWindowObject(Desktop->DesktopWindow);
1608  if (! DesktopWnd)
1609  {
1611  }
1612  DesktopWnd->style &= ~WS_VISIBLE;
1613 
1614  return STATUS_SUCCESS;
1615 }
#define ERROR_INVALID_WINDOW_HANDLE
Definition: winerror.h:881
Definition: ntuser.h:658
#define STATUS_SUCCESS
Definition: shellext.h:65
PWND FASTCALL IntGetWindowObject(HWND hWnd)
Definition: window.c:51
#define WS_VISIBLE
Definition: pedump.c:620
DWORD style
Definition: ntuser.h:671

Referenced by IntEndDesktopGraphics(), and NtUserSwitchDesktop().

◆ IntMapDesktopView()

static NTSTATUS IntMapDesktopView ( IN PDESKTOP  pdesk)
static

Definition at line 3141 of file desktop.c.

3142 {
3143  PPROCESSINFO ppi;
3144  PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
3145  PVOID UserBase = NULL;
3146  SIZE_T ViewSize = 0;
3148  NTSTATUS Status;
3149 
3150  TRACE("IntMapDesktopView called for desktop object 0x%p\n", pdesk);
3151 
3153 
3154  /*
3155  * Find out if another thread already mapped the desktop heap.
3156  * Start the search at the next mapping: skip the first entry
3157  * as it must be the global user heap mapping.
3158  */
3159  PrevLink = &ppi->HeapMappings.Next;
3160  HeapMapping = *PrevLink;
3161  while (HeapMapping != NULL)
3162  {
3163  if (HeapMapping->KernelMapping == (PVOID)pdesk->pheapDesktop)
3164  {
3165  HeapMapping->Count++;
3166  return STATUS_SUCCESS;
3167  }
3168 
3169  PrevLink = &HeapMapping->Next;
3170  HeapMapping = HeapMapping->Next;
3171  }
3172 
3173  /* We're the first, map the heap */
3174  Offset.QuadPart = 0;
3175  Status = MmMapViewOfSection(pdesk->hsectionDesktop,
3177  &UserBase,
3178  0,
3179  0,
3180  &Offset,
3181  &ViewSize,
3182  ViewUnmap,
3183  SEC_NO_CHANGE,
3184  PAGE_EXECUTE_READ); /* Would prefer PAGE_READONLY, but thanks to RTL heaps... */
3185  if (!NT_SUCCESS(Status))
3186  {
3187  ERR("Failed to map desktop\n");
3188  return Status;
3189  }
3190 
3191  TRACE("ppi 0x%p mapped heap of desktop 0x%p\n", ppi, pdesk);
3192 
3193  /* Add the mapping */
3194  HeapMapping = UserHeapAlloc(sizeof(*HeapMapping));
3195  if (HeapMapping == NULL)
3196  {
3198  ERR("UserHeapAlloc() failed!\n");
3199  return STATUS_NO_MEMORY;
3200  }
3201 
3202  HeapMapping->Next = NULL;
3203  HeapMapping->KernelMapping = (PVOID)pdesk->pheapDesktop;
3204  HeapMapping->UserMapping = UserBase;
3205  HeapMapping->Limit = ViewSize;
3206  HeapMapping->Count = 1;
3207  *PrevLink = HeapMapping;
3208 
3209  ObReferenceObject(pdesk);
3210 
3211  return STATUS_SUCCESS;
3212 }
LONG NTSTATUS
Definition: precomp.h:26
static __inline PVOID UserHeapAlloc(SIZE_T Bytes)
Definition: usrheap.h:34
#define PsGetCurrentProcess
Definition: psfuncs.h:17
NTSTATUS NTAPI MmMapViewOfSection(IN PVOID SectionObject, IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3898
W32HEAP_USER_MAPPING HeapMappings
Definition: win32.h:282
void * PVOID
Definition: retypes.h:9
Status
Definition: gdiplustypes.h:24
ULONG_PTR Limit
Definition: win32.h:198
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:3109
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define ERR(fmt,...)
Definition: debug.h:110
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define NULL
Definition: types.h:112
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
#define ObReferenceObject
Definition: obfuncs.h:204
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define STATUS_SUCCESS
Definition: shellext.h:65
#define SEC_NO_CHANGE
Definition: mmtypes.h:94
struct _W32HEAP_USER_MAPPING * Next
Definition: win32.h:195

Referenced by IntDesktopObjectOpen(), and IntSetThreadDesktop().

◆ IntPaintDesktop()

BOOL FASTCALL IntPaintDesktop ( HDC  hDC)

Definition at line 1795 of file desktop.c.

1796 {
1797  static WCHAR s_wszSafeMode[] = L"Safe Mode"; // FIXME: Localize!
1798 
1799  RECTL Rect;
1800  HBRUSH DesktopBrush, PreviousBrush;
1801  HWND hWndDesktop;
1802  BOOL doPatBlt = TRUE;
1803  PWND WndDesktop;
1804  BOOLEAN InSafeMode;
1805 
1806  if (GdiGetClipBox(hDC, &Rect) == ERROR)
1807  return FALSE;
1808 
1809  hWndDesktop = IntGetDesktopWindow(); // rpdesk->DesktopWindow;
1810 
1811  WndDesktop = UserGetWindowObject(hWndDesktop); // rpdesk->pDeskInfo->spwnd;
1812  if (!WndDesktop)
1813  return FALSE;
1814 
1815  /* Retrieve the current SafeMode state */
1816  InSafeMode = (UserGetSystemMetrics(SM_CLEANBOOT) != 0); // gpsi->aiSysMet[SM_CLEANBOOT];
1817 
1818  if (!InSafeMode)
1819  {
1820  DesktopBrush = (HBRUSH)WndDesktop->pcls->hbrBackground;
1821 
1822  /*
1823  * Paint desktop background
1824  */
1825  if (gspv.hbmWallpaper != NULL)
1826  {
1827  SIZE sz;
1828  int x, y;
1829  int scaledWidth, scaledHeight;
1830  int wallpaperX, wallpaperY, wallpaperWidth, wallpaperHeight;
1831  HDC hWallpaperDC;
1832 
1833  sz.cx = WndDesktop->rcWindow.right - WndDesktop->rcWindow.left;
1834  sz.cy = WndDesktop->rcWindow.bottom - WndDesktop->rcWindow.top;
1835 
1836  if (gspv.WallpaperMode == wmFit ||
1838  {
1839  int scaleNum, scaleDen;
1840 
1841  // Precision improvement over ((sz.cx / gspv.cxWallpaper) > (sz.cy / gspv.cyWallpaper))
1842  if ((sz.cx * gspv.cyWallpaper) > (sz.cy * gspv.cxWallpaper))
1843  {
1844  if (gspv.WallpaperMode == wmFit)
1845  {
1846  scaleNum = sz.cy;
1847  scaleDen = gspv.cyWallpaper;
1848  }
1849  else
1850  {
1851  scaleNum = sz.cx;
1852  scaleDen = gspv.cxWallpaper;
1853  }
1854  }
1855  else
1856  {
1857  if (gspv.WallpaperMode == wmFit)
1858  {
1859  scaleNum = sz.cx;
1860  scaleDen = gspv.cxWallpaper;
1861  }
1862  else
1863  {
1864  scaleNum = sz.cy;
1865  scaleDen = gspv.cyWallpaper;
1866  }
1867  }
1868 
1869  scaledWidth = EngMulDiv(gspv.cxWallpaper, scaleNum, scaleDen);
1870  scaledHeight = EngMulDiv(gspv.cyWallpaper, scaleNum, scaleDen);
1871 
1872  if (gspv.WallpaperMode == wmFill)
1873  {
1874  wallpaperX = (((scaledWidth - sz.cx) * gspv.cxWallpaper) / (2 * scaledWidth));
1875  wallpaperY = (((scaledHeight - sz.cy) * gspv.cyWallpaper) / (2 * scaledHeight));
1876 
1877  wallpaperWidth = (sz.cx * gspv.cxWallpaper) / scaledWidth;
1878  wallpaperHeight = (sz.cy * gspv.cyWallpaper) / scaledHeight;
1879  }
1880  }
1881 
1882  if (gspv.WallpaperMode == wmStretch ||
1883  gspv.WallpaperMode == wmTile ||
1885  {
1886  x = 0;
1887  y = 0;
1888  }
1889  else if (gspv.WallpaperMode == wmFit)
1890  {
1891  x = (sz.cx - scaledWidth) / 2;
1892  y = (sz.cy - scaledHeight) / 2;
1893  }
1894  else
1895  {
1896  /* Find the upper left corner, can be negative if the bitmap is bigger than the screen */
1897  x = (sz.cx / 2) - (gspv.cxWallpaper / 2);
1898  y = (sz.cy / 2) - (gspv.cyWallpaper / 2);
1899  }
1900 
1901  hWallpaperDC = NtGdiCreateCompatibleDC(hDC);
1902  if (hWallpaperDC != NULL)
1903  {
1904  HBITMAP hOldBitmap;
1905 
1906  /* Fill in the area that the bitmap is not going to cover */
1907  if (x > 0 || y > 0)
1908  {
1909  /* FIXME: Clip out the bitmap
1910  can be replaced with "NtGdiPatBlt(hDC, x, y, gspv.cxWallpaper, gspv.cyWallpaper, PATCOPY | DSTINVERT);"
1911  once we support DSTINVERT */
1912  PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
1913  NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
1914  NtGdiSelectBrush(hDC, PreviousBrush);
1915  }
1916 
1917  /* Do not fill the background after it is painted no matter the size of the picture */
1918  doPatBlt = FALSE;
1919 
1920  hOldBitmap = NtGdiSelectBitmap(hWallpaperDC, gspv.hbmWallpaper);
1921 
1922  if (gspv.WallpaperMode == wmStretch)
1923  {
1924  if (Rect.right && Rect.bottom)
1926  x,
1927  y,
1928  sz.cx,
1929  sz.cy,
1930  hWallpaperDC,
1931  0,
1932  0,
1933  gspv.cxWallpaper,
1934  gspv.cyWallpaper,
1935  SRCCOPY,
1936  0);
1937  }
1938  else if (gspv.WallpaperMode == wmTile)
1939  {
1940  /* Paint the bitmap across the screen then down */
1941  for (y = 0; y < Rect.bottom; y += gspv.cyWallpaper)
1942  {
1943  for (x = 0; x < Rect.right; x += gspv.cxWallpaper)
1944  {
1945  NtGdiBitBlt(hDC,
1946  x,
1947  y,
1948  gspv.cxWallpaper,
1949  gspv.cyWallpaper,
1950  hWallpaperDC,
1951  0,
1952  0,
1953  SRCCOPY,
1954  0,
1955  0);
1956  }
1957  }
1958  }
1959  else if (gspv.WallpaperMode == wmFit)
1960  {
1961  if (Rect.right && Rect.bottom)
1962  {
1964  x,
1965  y,
1966  scaledWidth,
1967  scaledHeight,
1968  hWallpaperDC,
1969  0,
1970  0,
1971  gspv.cxWallpaper,
1972  gspv.cyWallpaper,
1973  SRCCOPY,
1974  0);
1975  }
1976  }
1977  else if (gspv.WallpaperMode == wmFill)
1978  {
1979  if (Rect.right && Rect.bottom)
1980  {
1982  x,
1983  y,
1984  sz.cx,
1985  sz.cy,
1986  hWallpaperDC,
1987  wallpaperX,
1988  wallpaperY,
1989  wallpaperWidth,
1990  wallpaperHeight,
1991  SRCCOPY,
1992  0);
1993  }
1994  }
1995  else
1996  {
1997  NtGdiBitBlt(hDC,
1998  x,
1999  y,
2000  gspv.cxWallpaper,
2001  gspv.cyWallpaper,
2002  hWallpaperDC,
2003  0,
2004  0,
2005  SRCCOPY,
2006  0,
2007  0);
2008  }
2009  NtGdiSelectBitmap(hWallpaperDC, hOldBitmap);
2010  NtGdiDeleteObjectApp(hWallpaperDC);
2011  }
2012  }
2013  }
2014  else
2015  {
2016  /* Black desktop background in Safe Mode */
2017  DesktopBrush = StockObjects[BLACK_BRUSH];
2018  }
2019 
2020  /* Background is set to none, clear the screen */
2021  if (doPatBlt)
2022  {
2023  PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
2024  NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
2025  NtGdiSelectBrush(hDC, PreviousBrush);
2026  }
2027 
2028  /*
2029  * Display the system version on the desktop background
2030  */
2031  if (InSafeMode || g_AlwaysDisplayVersion || g_PaintDesktopVersion)
2032  {
2033  NTSTATUS Status;
2034  static WCHAR wszzVersion[1024] = L"\0";
2035 
2036  /* Only used in normal mode */
2037  // We expect at most 4 strings (3 for version, 1 for optional NtSystemRoot)
2038  static POLYTEXTW VerStrs[4] = {{0},{0},{0},{0}};
2039  INT i = 0;
2040  SIZE_T len;
2041 
2042  HFONT hFont1 = NULL, hFont2 = NULL, hOldFont = NULL;
2043  COLORREF crText, color_old;
2044  UINT align_old;
2045  INT mode_old;
2046  PDC pdc;
2047 
2048  if (!UserSystemParametersInfo(SPI_GETWORKAREA, 0, &Rect, 0))
2049  {
2050  Rect.left = Rect.top = 0;
2053  }
2054  else
2055  {
2056  RECTL_vOffsetRect(&Rect, -Rect.left, -Rect.top);
2057  }
2058 
2059  /*
2060  * Set up the fonts (otherwise use default ones)
2061  */
2062 
2063  /* Font for the principal version string */
2064  hFont1 = GreCreateFontIndirectW(&gspv.ncm.lfCaptionFont);
2065  /* Font for the secondary version strings */
2066  hFont2 = GreCreateFontIndirectW(&gspv.ncm.lfMenuFont);
2067 
2068  if (hFont1)
2069  hOldFont = NtGdiSelectFont(hDC, hFont1);
2070 
2071  if (gspv.hbmWallpaper == NULL)
2072  {
2073  /* Retrieve the brush fill colour */
2074  // TODO: The following code constitutes "GreGetBrushColor".
2075  PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
2076  pdc = DC_LockDc(hDC);
2077  if (pdc)
2078  {
2079  crText = pdc->eboFill.ulRGBColor;
2080  DC_UnlockDc(pdc);
2081  }
2082  else
2083  {
2084  crText = RGB(0, 0, 0);
2085  }
2086  NtGdiSelectBrush(hDC, PreviousBrush);
2087 
2088  /* Adjust text colour according to the brush */
2089  if (GetRValue(crText) + GetGValue(crText) + GetBValue(crText) > 128 * 3)
2090  crText = RGB(0, 0, 0);
2091  else
2092  crText = RGB(255, 255, 255);
2093  }
2094  else
2095  {
2096  /* Always use white when the text is displayed on top of a wallpaper */
2097  crText = RGB(255, 255, 255);
2098  }
2099 
2100  color_old = IntGdiSetTextColor(hDC, crText);
2101  align_old = IntGdiSetTextAlign(hDC, TA_RIGHT);
2102  mode_old = IntGdiSetBkMode(hDC, TRANSPARENT);
2103 
2104  /* Display the system version information */
2105  if (!*wszzVersion)
2106  {
2107  Status = GetSystemVersionString(wszzVersion,
2108  ARRAYSIZE(wszzVersion),
2109  InSafeMode,
2111  if (!InSafeMode && NT_SUCCESS(Status) && *wszzVersion)
2112  {
2113  PWCHAR pstr = wszzVersion;
2114  for (i = 0; (i < ARRAYSIZE(VerStrs)) && *pstr; ++i)
2115  {
2116  VerStrs[i].n = lstrlenW(pstr);
2117  VerStrs[i].lpstr = pstr;
2118  pstr += (VerStrs[i].n + 1);
2119  }
2120  }
2121  }
2122  else
2123  {
2125  }
2126  if (NT_SUCCESS(Status) && *wszzVersion)
2127  {
2128  if (!InSafeMode)
2129  {
2130  SIZE Size = {0, 0};
2131  LONG TotalHeight = 0;
2132 
2133  /* Normal Mode: multiple version information text separated by newlines */
2135 
2136  /* Compute the heights of the strings */
2137  if (hFont1) NtGdiSelectFont(hDC, hFont1);
2138  for (i = 0; i < ARRAYSIZE(VerStrs); ++i)
2139  {
2140  if (!VerStrs[i].lpstr || !*VerStrs[i].lpstr || (VerStrs[i].n == 0))
2141  break;
2142 
2143  GreGetTextExtentW(hDC, VerStrs[i].lpstr, VerStrs[i].n, &Size, 1);
2144  VerStrs[i].y = Size.cy; // Store the string height
2145  TotalHeight += Size.cy;
2146 
2147  /* While the first string was using hFont1, all the others use hFont2 */
2148  if (hFont2) NtGdiSelectFont(hDC, hFont2);
2149  }
2150  /* The total height must not exceed the screen height */
2151  TotalHeight = min(TotalHeight, Rect.bottom);
2152 
2153  /* Display the strings */
2154  if (hFont1) NtGdiSelectFont(hDC, hFont1);
2155  for (i = 0; i < ARRAYSIZE(VerStrs); ++i)
2156  {
2157  if (!VerStrs[i].lpstr || !*VerStrs[i].lpstr || (VerStrs[i].n == 0))
2158  break;
2159 
2160  TotalHeight -= VerStrs[i].y;
2162  Rect.right - 5,
2163  Rect.bottom - TotalHeight - 5,
2164  0, NULL,
2165  VerStrs[i].lpstr,
2166  VerStrs[i].n,
2167  NULL, 0);
2168 
2169  /* While the first string was using hFont1, all the others use hFont2 */
2170  if (hFont2) NtGdiSelectFont(hDC, hFont2);
2171  }
2172  }
2173  else
2174  {
2175  if (hFont1) NtGdiSelectFont(hDC, hFont1);
2176 
2177  /* Safe Mode: single version information text in top center */
2178  len = wcslen(wszzVersion);
2179 
2181  GreExtTextOutW(hDC, (Rect.right + Rect.left)/2, Rect.top + 3, 0, NULL, wszzVersion, len, NULL, 0);
2182  }
2183  }
2184 
2185  if (InSafeMode)
2186  {
2187  if (hFont1) NtGdiSelectFont(hDC, hFont1);
2188 
2189  /* Print Safe Mode text in corners */
2190  len = wcslen(s_wszSafeMode);
2191 
2193  GreExtTextOutW(hDC, Rect.left, Rect.top + 3, 0, NULL, s_wszSafeMode, len, NULL, 0);
2195  GreExtTextOutW(hDC, Rect.right, Rect.top + 3, 0, NULL, s_wszSafeMode, len, NULL, 0);
2197  GreExtTextOutW(hDC, Rect.left, Rect.bottom - 5, 0, NULL, s_wszSafeMode, len, NULL, 0);
2199  GreExtTextOutW(hDC, Rect.right, Rect.bottom - 5, 0, NULL, s_wszSafeMode, len, NULL, 0);
2200  }
2201 
2202  IntGdiSetBkMode(hDC, mode_old);
2203  IntGdiSetTextAlign(hDC, align_old);
2204  IntGdiSetTextColor(hDC, color_old);
2205 
2206  if (hFont2)
2207  GreDeleteObject(hFont2);
2208 
2209  if (hFont1)
2210  {
2211  NtGdiSelectFont(hDC, hOldFont);
2212  GreDeleteObject(hFont1);
2213  }
2214  }
2215 
2216  return TRUE;
2217 }
HANDLE hbmWallpaper
Definition: sysparams.h:142
ULONG cyWallpaper
Definition: sysparams.h:143
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1158
UINT n
Definition: wingdi.h:2562
LPCWSTR lpstr
Definition: wingdi.h:2563
FORCEINLINE PDC DC_LockDc(HDC hdc)
Definition: dc.h:219
__kernel_entry W32KAPI BOOL APIENTRY NtGdiPatBlt(_In_ HDC hdcDest, _In_ INT x, _In_ INT y, _In_ INT cx, _In_ INT cy, _In_ DWORD dwRop)
Definition: bitblt.c:980
#define RGB(r, g, b)
Definition: precomp.h:62
#define TRUE
Definition: types.h:120
#define ERROR(name)
Definition: error_private.h:53
UINT FASTCALL IntGdiSetTextAlign(HDC hDC, UINT Mode)
Definition: dcutil.c:145
BOOL FASTCALL GreGetTextExtentW(HDC hDC, LPCWSTR lpwsz, INT cwc, LPSIZE psize, UINT flOpts)
Definition: text.c:78
LONG NTSTATUS
Definition: precomp.h:26
static HDC
Definition: imagelist.c:92
NONCLIENTMETRICSW ncm
Definition: sysparams.h:51
GLdouble n
Definition: glext.h:7729
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiSelectBitmap(_In_ HDC hdc, _In_ HBITMAP hbm)
LONG top
Definition: windef.h:307
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
INT FASTCALL IntGdiSetBkMode(HDC hDC, INT backgroundMode)
Definition: dcutil.c:124
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
#define GetRValue(quad)
Definition: precomp.h:64
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static NTSTATUS GetSystemVersionString(OUT PWSTR pwszzVersion, IN SIZE_T cchDest, IN BOOLEAN InSafeMode, IN BOOLEAN AppendNtSystemRoot)
Definition: desktop.c:271
#define TA_LEFT
Definition: wingdi.h:931
uint16_t * PWCHAR
Definition: typedefs.h:56
LONG left
Definition: windef.h:306
if(dx==0 &&dy==0)
Definition: linetemp.h:174
LONG right
Definition: windef.h:308
#define lstrlenW
Definition: compat.h:609
int32_t INT
Definition: typedefs.h:58
__kernel_entry W32KAPI HBRUSH APIENTRY NtGdiSelectBrush(_In_ HDC hdc, _In_ HBRUSH hbrush)
#define TA_TOP
Definition: wingdi.h:929
#define SM_CXSCREEN
Definition: winuser.h:949
HGDIOBJ StockObjects[]
Definition: stockobj.c:100
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
BOOL g_AlwaysDisplayVersion
Definition: ntuser.c:17
#define TRANSPARENT
Definition: wingdi.h:949
unsigned char BOOLEAN
#define TA_BOTTOM
Definition: wingdi.h:928
__kernel_entry W32KAPI BOOL APIENTRY NtGdiBitBlt(_In_ HDC hdcDst, _In_ INT x, _In_ INT y, _In_ INT cx, _In_ INT cy, _In_opt_ HDC hdcSrc, _In_ INT xSrc, _In_ INT ySrc, _In_ DWORD rop4, _In_ DWORD crBackColor, _In_ FLONG fl)
LONG cx
Definition: windef.h:334
#define GetBValue(quad)
Definition: precomp.h:66
COLORREF FASTCALL IntGdiSetTextColor(HDC hDC, COLORREF color)
Definition: dcutil.c:172
HFONT FASTCALL GreCreateFontIndirectW(LOGFONTW *lplf)
Definition: font.c:23
#define GetGValue(quad)
Definition: precomp.h:65
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:103
#define SM_CLEANBOOT
Definition: winuser.h:1017
#define BLACK_BRUSH
Definition: wingdi.h:895
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:180
#define TA_RIGHT
Definition: wingdi.h:932
Status
Definition: gdiplustypes.h:24
__kernel_entry W32KAPI HFONT APIENTRY NtGdiSelectFont(_In_ HDC hdc, _In_ HFONT hf)
Definition: dcobjs.c:597
#define SM_CYSCREEN
Definition: winuser.h:950
Definition: polytest.cpp:40
HBRUSH hbrBackground
Definition: ntuser.h:556
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DWORD COLORREF
Definition: windef.h:300
BOOL APIENTRY GreExtTextOutW(IN HDC hDC, IN INT XStart, IN INT YStart, IN UINT fuOptions, IN OPTIONAL PRECTL lprc, IN LPCWSTR String, IN INT Count, IN OPTIONAL LPINT Dx, IN DWORD dwCodePage)
Definition: freetype.c:6625
SPIVALUES gspv
Definition: sysparams.c:17
static const WCHAR L[]
Definition: oid.c:1250
GLenum GLsizei len
Definition: glext.h:6722
RECT rcWindow
Definition: ntuser.h:681
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
#define PATCOPY
Definition: wingdi.h:334
Definition: ntuser.h:658
FORCEINLINE VOID RECTL_vOffsetRect(_Inout_ RECTL *prcl, _In_ INT cx, _In_ INT cy)
Definition: rect.h:31
HWND FASTCALL IntGetDesktopWindow(VOID)
Definition: desktop.c:1342
static HDC hDC
Definition: 3dtext.c:33
ULONG_PTR SIZE_T
Definition: typedefs.h:80
__kernel_entry W32KAPI BOOL APIENTRY NtGdiDeleteObjectApp(_In_ HANDLE hobj)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
FORCEINLINE VOID DC_UnlockDc(PDC pdc)
Definition: dc.h:237
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
ENGAPI INT APIENTRY EngMulDiv(_In_ INT a, _In_ INT b, _In_ INT c)
Definition: math.c:26
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiStretchBlt(_In_ HDC hdcDst, _In_ INT xDst, _In_ INT yDst, _In_ INT cxDst, _In_ INT cyDst, _In_opt_ HDC hdcSrc, _In_ INT xSrc, _In_ INT ySrc, _In_ INT cxSrc, _In_ INT cySrc, _In_ DWORD dwRop, _In_ DWORD dwBackColor)
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
LONG bottom
Definition: windef.h:309
static LPCSTR lpstr
Definition: font.c:51
BOOL FASTCALL UserSystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni)
Definition: sysparams.c:2088
static HBITMAP
Definition: button.c:44
#define TA_CENTER
Definition: wingdi.h:930
#define STATUS_SUCCESS
Definition: shellext.h:65
LONG cy
Definition: windef.h:335
ULONG cxWallpaper
Definition: sysparams.h:143
#define SRCCOPY
Definition: wingdi.h:332
struct Rect Rect
WALLPAPER_MODE WallpaperMode
Definition: sysparams.h:144
BOOL g_PaintDesktopVersion
Definition: sysparams.c:19
PCLS pcls
Definition: ntuser.h:685

Referenced by co_IntInitializeDesktopGraphics(), DesktopWindowProc(), EngpRegisterGraphicsDevice(), NtUserPaintDesktop(), and UserRealizePalette().

◆ IntRegisterShellHookWindow()

BOOL IntRegisterShellHookWindow ( HWND  hWnd)

Definition at line 1720 of file desktop.c.

1721 {
1723  PDESKTOP Desktop = pti->rpdesk;
1725 
1726  TRACE("IntRegisterShellHookWindow\n");
1727 
1728  /* First deregister the window, so we can be sure it's never twice in the
1729  * list.
1730  */
1732 
1734  sizeof(SHELL_HOOK_WINDOW),
1735  TAG_WINSTA);
1736 
1737  if (!Entry)
1738  return FALSE;
1739 
1740  Entry->hWnd = hWnd;
1741 
1742  InsertTailList(&Desktop->ShellHookWindows, &Entry->ListEntry);
1743 
1744  return TRUE;
1745 }
struct _Entry Entry
Definition: kefuncs.h:627
#define TRUE
Definition: types.h:120
#define TAG_WINSTA
Definition: tags.h:11
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
HWND hWnd
Definition: settings.c:17
#define InsertTailList(ListHead, Entry)
struct _DESKTOP * rpdesk
Definition: win32.h:91
#define FALSE
Definition: types.h:117
#define TRACE(s)
Definition: solgame.cpp:4
BOOL IntDeRegisterShellHookWindow(HWND hWnd)
Definition: desktop.c:1752
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
base of all file and directory entries
Definition: entries.h:82

Referenced by NtUserCallHwnd().

◆ IntResolveDesktop()

NTSTATUS FASTCALL IntResolveDesktop ( IN PEPROCESS  Process,
IN PUNICODE_STRING  DesktopPath,
IN BOOL  bInherit,
OUT HWINSTA *  phWinSta,
OUT HDESK *  phDesktop 
)

Definition at line 539 of file desktop.c.

545 {
547  HWINSTA hWinSta = NULL, hWinStaDup = NULL;
548  HDESK hDesktop = NULL, hDesktopDup = NULL;
549  PPROCESSINFO ppi;
550  HANDLE hProcess = NULL;
551  LUID ProcessLuid;
552  USHORT StrSize;
553  SIZE_T MemSize;
556  UNICODE_STRING WinStaName, DesktopName;
557  const UNICODE_STRING WinSta0Name = RTL_CONSTANT_STRING(L"WinSta0");
558  PWINSTATION_OBJECT WinStaObject;
559  HWINSTA hTempWinSta = NULL;
560  BOOLEAN bUseDefaultWinSta = FALSE;
561  BOOLEAN bInteractive = FALSE;
562  BOOLEAN bAccessAllowed = FALSE;
563 
564  ASSERT(phWinSta);
565  ASSERT(phDesktop);
566  ASSERT(DesktopPath);
567 
568  *phWinSta = NULL;
569  *phDesktop = NULL;
570 
572  /* ppi is typically NULL for console applications that connect to Win32 USER */
573  if (!ppi) TRACE("IntResolveDesktop: ppi is NULL!\n");
574 
575  if (ppi && ppi->hwinsta != NULL && ppi->hdeskStartup != NULL)
576  {
577  /*
578  * If this process is the current one, just return the cached handles.
579  * Otherwise, open the window station and desktop objects.
580  */
581  if (Process == PsGetCurrentProcess())
582  {
583  hWinSta = ppi->hwinsta;
584  hDesktop = ppi->hdeskStartup;
585  }
586  else
587  {
589  0,
590  NULL,
593  UserMode,
594  (PHANDLE)&hWinSta);
595  if (!NT_SUCCESS(Status))
596  {
597  ERR("IntResolveDesktop: Could not reference window station 0x%p\n", ppi->prpwinsta);
599  return Status;
600  }
601 
603  0,
604  NULL,
607  UserMode,
608  (PHANDLE)&hDesktop);
609  if (!NT_SUCCESS(Status))
610  {
611  ERR("IntResolveDesktop: Could not reference desktop 0x%p\n", ppi->rpdeskStartup);
612  ObCloseHandle(hWinSta, UserMode);
614  return Status;
615  }
616  }
617 
618  *phWinSta = hWinSta;
619  *phDesktop = hDesktop;
620  return STATUS_SUCCESS;
621  }
622 
623  /* We will by default use the default window station and desktop */
624  RtlInitEmptyUnicodeString(&WinStaName, NULL, 0);
625  RtlInitEmptyUnicodeString(&DesktopName, NULL, 0);
626 
627  /*
628  * Parse the desktop path string which can be of the form "WinSta\Desktop"
629  * or just "Desktop". In the latter case we use the default window station
630  * on which the process is attached to (or if none, "WinSta0").
631  */
632  if (DesktopPath->Buffer != NULL && DesktopPath->Length > sizeof(WCHAR))
633  {
634  DesktopName = *DesktopPath;
635 
636  /* Find the separator */
637  while (DesktopName.Length > 0 && *DesktopName.Buffer &&
638  *DesktopName.Buffer != OBJ_NAME_PATH_SEPARATOR)
639  {
640  DesktopName.Buffer++;
641  DesktopName.Length -= sizeof(WCHAR);
642  DesktopName.MaximumLength -= sizeof(WCHAR);
643  }
644  if (DesktopName.Length > 0)
645  {
646  RtlInitEmptyUnicodeString(&WinStaName, DesktopPath->Buffer,
647  DesktopPath->Length - DesktopName.Length);
648  // (USHORT)((ULONG_PTR)DesktopName.Buffer - (ULONG_PTR)DesktopPath->Buffer);
649  WinStaName.Length = WinStaName.MaximumLength;
650 
651  /* Skip the separator */
652  DesktopName.Buffer++;
653  DesktopName.Length -= sizeof(WCHAR);
654  DesktopName.MaximumLength -= sizeof(WCHAR);
655  }
656  else
657  {
658  RtlInitEmptyUnicodeString(&WinStaName, NULL, 0);
659  DesktopName = *DesktopPath;
660  }
661  }
662 
663  TRACE("IntResolveDesktop: WinStaName:'%wZ' ; DesktopName:'%wZ'\n", &WinStaName, &DesktopName);
664 
665  /* Retrieve the process LUID */
666  Status = GetProcessLuid(NULL, Process, &ProcessLuid);
667  if (!NT_SUCCESS(Status))
668  {
669  ERR("IntResolveDesktop: Failed to retrieve the process LUID, Status 0x%08lx\n", Status);
671  return Status;
672  }
673 
674  /*
675  * If this process is not the current one, obtain a temporary handle
676  * to it so that we can perform handles duplication later.
677  */
678  if (Process != PsGetCurrentProcess())
679  {
682  NULL,
683  0,
684  *PsProcessType,
685  KernelMode,
686  &hProcess);
687  if (!NT_SUCCESS(Status))
688  {
689  ERR("IntResolveDesktop: Failed to obtain a handle to process 0x%p, Status 0x%08lx\n", Process, Status);
691  return Status;
692  }
693  ASSERT(hProcess);
694  }
695 
696  /*
697  * If no window station has been specified, search the process handle table
698  * for inherited window station handles, otherwise use a default one.
699  */
700  if (WinStaName.Buffer == NULL)
701  {
702  /*
703  * We want to find a suitable default window station.
704  * For applications that can be interactive, i.e. that have allowed
705  * access to the single interactive window station on the system,
706  * the default window station is 'WinSta0'.
707  * For applications that cannot be interactive, i.e. that do not have
708  * access to 'WinSta0' (e.g. non-interactive services), the default
709  * window station is 'Service-0xXXXX-YYYY$' (created if needed).
710  * Precedence will however be taken by any inherited window station
711  * that possesses the required interactivity property.
712  */
713  bUseDefaultWinSta = TRUE;
714 
715  /*
716  * Use the default 'WinSta0' window station. Whether we should
717  * use 'Service-0xXXXX-YYYY$' instead will be determined later.
718  */
719  // RtlInitUnicodeString(&WinStaName, L"WinSta0");
720  WinStaName = WinSta0Name;
721 
723  NULL,
725  NULL,
726  (PHANDLE)&hWinSta))
727  {
728  TRACE("IntResolveDesktop: Inherited window station is: 0x%p\n", hWinSta);
729  }
730  }
731 
732  /*
733  * If no desktop has been specified, search the process handle table
734  * for inherited desktop handles, otherwise use the Default desktop.
735  * Note that the inherited desktop that we may use, may not belong
736  * to the window station we will connect to.
737  */
738  if (DesktopName.Buffer == NULL)
739  {
740  /* Use a default desktop name */
741  RtlInitUnicodeString(&DesktopName, L"Default");
742 
744  NULL,
746  NULL,
747  (PHANDLE)&hDesktop))
748  {
749  TRACE("IntResolveDesktop: Inherited desktop is: 0x%p\n", hDesktop);
750  }
751  }
752 
753 
754  /*
755  * We are going to open either a window station or a desktop.
756  * Even if this operation is done from kernel-mode, we should
757  * "emulate" an opening from user-mode (i.e. using an ObjectAttributes
758  * allocated in user-mode, with AccessMode == UserMode) for the
759  * Object Manager to perform proper access validation to the
760  * window station or desktop.
761  */
762 
763  /*
764  * Estimate the maximum size needed for the window station name
765  * and desktop name to be given to ObjectAttributes->ObjectName.
766  */
767  StrSize = 0;
768 
769  /* Window station name */
770  MemSize = _scwprintf(L"Service-0x%x-%x$", MAXULONG, MAXULONG) * sizeof(WCHAR);
772  + max(WinStaName.Length, MemSize) + sizeof(UNICODE_NULL);
773  if (MemSize > MAXUSHORT)
774  {
775  ERR("IntResolveDesktop: Window station name length is too long.\n");
777  goto Quit;
778  }
779  StrSize = max(StrSize, (USHORT)MemSize);
780 
781  /* Desktop name */
782  MemSize = max(DesktopName.Length + sizeof(UNICODE_NULL), sizeof(L"Default"));
783  StrSize = max(StrSize, (USHORT)MemSize);
784 
785  /* Size for the OBJECT_ATTRIBUTES */
786  MemSize = ALIGN_UP(sizeof(OBJECT_ATTRIBUTES), sizeof(PVOID));
787 
788  /* Add the string size */
789  MemSize += ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID));
790  MemSize += StrSize;
791 
792  /* Allocate the memory in user-mode */
793  Status = ZwAllocateVirtualMemory(ZwCurrentProcess(),
795  0,
796  &MemSize,
797  MEM_COMMIT,
799  if (!NT_SUCCESS(Status))
800  {
801  ERR("ZwAllocateVirtualMemory() failed, Status 0x%08lx\n", Status);
802  goto Quit;
803  }
804 
806  ALIGN_UP(sizeof(OBJECT_ATTRIBUTES), sizeof(PVOID)));
807 
808  RtlInitEmptyUnicodeString(ObjectName,
810  ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID))),
811  StrSize);
812 
813 
814  /* If we got an inherited window station handle, duplicate and use it */
815  if (hWinSta)
816  {
817  ASSERT(bUseDefaultWinSta);
818 
819  /* Duplicate the handle if it belongs to another process than the current one */
820  if (Process != PsGetCurrentProcess())
821  {
822  ASSERT(hProcess);
823  Status = ZwDuplicateObject(hProcess,
824  hWinSta,
826  (PHANDLE)&hWinStaDup,
827  0,
828  0,
830  if (!NT_SUCCESS(Status))
831  {
832  ERR("IntResolveDesktop: Failed to duplicate the window station handle, Status 0x%08lx\n", Status);
833  /* We will use a default window station */
834  hWinSta = NULL;
835  }
836  else
837  {
838  hWinSta = hWinStaDup;
839  }
840  }
841  }
842 
843  /*
844  * If we have an inherited window station, check whether
845  * it is interactive and remember that for later.
846  */
847  if (hWinSta)
848  {
849  ASSERT(bUseDefaultWinSta);
850 
851  /* Reference the inherited window station */
853  0,
855  KernelMode,
856  (PVOID*)&WinStaObject,
857  NULL);
858  if (!NT_SUCCESS(Status))
859  {
860  ERR("Failed to reference the inherited window station, Status 0x%08lx\n", Status);
861  /* We will use a default window station */
862  if (hWinStaDup)
863  {
864  ASSERT(hWinSta == hWinStaDup);
865  ObCloseHandle(hWinStaDup, UserMode);
866  hWinStaDup = NULL;
867  }
868  hWinSta = NULL;
869  }
870  else
871  {
872  ERR("Process LUID is: 0x%x-%x, inherited window station LUID is: 0x%x-%x\n",
873  ProcessLuid.HighPart, ProcessLuid.LowPart,
874  WinStaObject->luidUser.HighPart, WinStaObject->luidUser.LowPart);
875 
876  /* Check whether this window station is interactive, and remember it for later */
877  bInteractive = !(WinStaObject->Flags & WSS_NOIO);
878 
879  /* Dereference the window station */
880  ObDereferenceObject(WinStaObject);
881  }
882  }
883 
884  /* Build a valid window station name */
886  ObjectName->MaximumLength,
887  L"%wZ\\%wZ",
889  &WinStaName);
890  if (!NT_SUCCESS(Status))
891  {
892  ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
893  goto Quit;
894  }
895  ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
896 
897  TRACE("Parsed initial window station: '%wZ'\n", ObjectName);
898 
899  /* Try to open the window station */
901  ObjectName,
903  NULL,
904  NULL);
905  if (bInherit)
906  ObjectAttributes->Attributes |= OBJ_INHERIT;
907 
910  UserMode,
911  NULL,
913  NULL,
914  (PHANDLE)&hTempWinSta);
915  if (!NT_SUCCESS(Status))
916  {
917  ERR("Failed to open the window station '%wZ', Status 0x%08lx\n", ObjectName, Status);
918  }
919  else
920  {
921  //
922  // FIXME TODO: Perform a window station access check!!
923  // If we fail AND bUseDefaultWinSta == FALSE we just quit.
924  //
925 
926  /*
927  * Check whether we are opening the (single) interactive
928  * window station, and if so, perform an access check.
929  */
930  /* Check whether we are allowed to perform interactions */
931  if (RtlEqualUnicodeString(&WinStaName, &WinSta0Name, TRUE))
932  {
933  LUID SystemLuid = SYSTEM_LUID;
934 
935  /* Interactive window station: check for user LUID */
936  WinStaObject = InputWindowStation;
937 
939 
940  // TODO: Check also that we compare wrt. window station WinSta0
941  // which is the only one that can be interactive on the system.
942  if (((!bUseDefaultWinSta || bInherit) && RtlEqualLuid(&ProcessLuid, &SystemLuid)) ||
943  RtlEqualLuid(&ProcessLuid, &WinStaObject->luidUser))
944  {
945  /* We are interactive on this window station */
946  bAccessAllowed = TRUE;
948  }
949  }
950  else
951  {
952  /* Non-interactive window station: we have access since we were able to open it */
953  bAccessAllowed = TRUE;
955  }
956  }
957 
958  /* If we failed, bail out if we were not trying to open the default window station */
959  if (!NT_SUCCESS(Status) && !bUseDefaultWinSta) // if (!bAccessAllowed)
960  goto Quit;
961 
962  if (/* bAccessAllowed && */ bInteractive || !bAccessAllowed)
963  {
964  /*
965  * Close WinSta0 if the inherited window station is interactive so that
966  * we can use it, or we do not have access to the interactive WinSta0.
967  */
968  ObCloseHandle(hTempWinSta, UserMode);
969  hTempWinSta = NULL;
970  }
971  if (bInteractive == bAccessAllowed)
972  {
973  /* Keep using the inherited window station */
974  NOTHING;
975  }
976  else // if (bInteractive != bAccessAllowed)
977  {
978  /*
979  * Close the inherited window station, we will either keep using
980  * the interactive WinSta0, or use Service-0xXXXX-YYYY$.
981  */
982  if (hWinStaDup)
983  {
984  ASSERT(hWinSta == hWinStaDup);
985  ObCloseHandle(hWinStaDup, UserMode);
986  hWinStaDup = NULL;
987  }
988  hWinSta = hTempWinSta; // hTempWinSta is NULL in case bAccessAllowed == FALSE
989  }
990 
991  if (bUseDefaultWinSta)
992  {
993  if (hWinSta == NULL && !bInteractive)
994  {
995  /* Build a valid window station name from the LUID */
997  ObjectName->MaximumLength,
998  L"%wZ\\Service-0x%x-%x$",
1000  ProcessLuid.HighPart,
1001  ProcessLuid.LowPart);
1002  if (!NT_SUCCESS(Status))
1003  {
1004  ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
1005  goto Quit;
1006  }
1007  ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
1008 
1009  /*
1010  * Create or open the non-interactive window station.
1011  * NOTE: The non-interactive window station handle is never inheritable.
1012  */
1013  // FIXME: Set security!
1015  ObjectName,
1017  NULL,
1018  NULL);
1019 
1020  Status = IntCreateWindowStation(&hWinSta,
1022  UserMode,
1023  KernelMode,
1025  0, 0, 0, 0, 0);
1026  if (!NT_SUCCESS(Status))
1027  {
1028  ASSERT(hWinSta == NULL);
1029  ERR("Failed to create or open the non-interactive window station '%wZ', Status 0x%08lx\n",
1030  ObjectName, Status);
1031  goto Quit;
1032  }
1033 
1034  //
1035  // FIXME: We might not need to always create or open the "Default"
1036  // desktop on the Service-0xXXXX-YYYY$ window station; we may need
1037  // to use another one....
1038  //
1039 
1040  /* Create or open the Default desktop on the window station */
1042  ObjectName->MaximumLength,
1043  L"Default");
1044  if (!NT_SUCCESS(Status))
1045  {
1046  ERR("Impossible to build a valid desktop name, Status 0x%08lx\n", Status);
1047  goto Quit;
1048  }
1049  ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
1050 
1051  /* NOTE: The non-interactive desktop handle is never inheritable. */
1052  // FIXME: Set security!
1054  ObjectName,
1056  hWinSta,
1057  NULL);
1058 
1059  Status = IntCreateDesktop(&hDesktop,
1061  UserMode,
1062  NULL,
1063  NULL,
1064  0,
1065  MAXIMUM_ALLOWED);
1066  if (!NT_SUCCESS(Status))
1067  {
1068  ASSERT(hDesktop == NULL);
1069  ERR("Failed to create or open the desktop '%wZ' on window station 0x%p, Status 0x%08lx\n",
1070  ObjectName, hWinSta, Status);
1071  }
1072 
1073  goto Quit;
1074  }
1075 /*
1076  if (hWinSta == NULL)
1077  {
1078  Status = STATUS_UNSUCCESSFUL;
1079  goto Quit;
1080  }
1081 */
1082  }
1083 
1084  /*
1085  * If we got an inherited desktop handle, duplicate and use it,
1086  * otherwise open a new desktop.
1087  */
1088  if (hDesktop != NULL)
1089  {
1090  /* Duplicate the handle if it belongs to another process than the current one */
1091  if (Process != PsGetCurrentProcess())
1092  {
1093  ASSERT(hProcess);
1094  Status = ZwDuplicateObject(hProcess,
1095  hDesktop,
1096  ZwCurrentProcess(),
1097  (PHANDLE)&hDesktopDup,
1098  0,
1099  0,
1101  if (!NT_SUCCESS(Status))
1102  {
1103  ERR("IntResolveDesktop: Failed to duplicate the desktop handle, Status 0x%08lx\n", Status);
1104  /* We will use a default desktop */
1105  hDesktop = NULL;
1106  }
1107  else
1108  {
1109  hDesktop = hDesktopDup;
1110  }
1111  }
1112  }
1113 
1114  if ((hWinSta != NULL) && (hDesktop == NULL))
1115  {
1117  ObjectName->MaximumLength,
1118  DesktopName.Buffer,
1119  DesktopName.Length);
1120  if (!NT_SUCCESS(Status))
1121  {
1122  ERR("Impossible to build a valid desktop name, Status 0x%08lx\n", Status);
1123  goto Quit;
1124  }
1125  ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
1126 
1127  TRACE("Parsed initial desktop: '%wZ'\n", ObjectName);
1128 
1129  /* Open the desktop object */
1131  ObjectName,
1133  hWinSta,
1134  NULL);
1135  if (bInherit)
1136  ObjectAttributes->Attributes |= OBJ_INHERIT;
1137 
1140  UserMode,
1141  NULL,
1143  NULL,
1144  (PHANDLE)&hDesktop);
1145  if (!NT_SUCCESS(Status))
1146  {
1147  ERR("Failed to open the desktop '%wZ' on window station 0x%p, Status 0x%08lx\n",
1148  ObjectName, hWinSta, Status);
1149  goto Quit;
1150  }
1151  }
1152 
1153 Quit:
1154  /* Release the object attributes */
1155  if (ObjectAttributes)
1156  {
1157  MemSize = 0;
1158  ZwFreeVirtualMemory(ZwCurrentProcess(),
1160  &MemSize,
1161  MEM_RELEASE);
1162  }
1163 
1164  /* Close the temporary process handle */
1165  if (hProcess) // if (Process != PsGetCurrentProcess())
1167 
1168  if (NT_SUCCESS(Status))
1169  {
1170  *phWinSta = hWinSta;
1171  *phDesktop = hDesktop;
1172  return STATUS_SUCCESS;
1173  }
1174  else
1175  {
1176  ERR("IntResolveDesktop(%wZ) failed, Status 0x%08lx\n", DesktopPath, Status);
1177 
1178  if (hDesktopDup)
1179  ObCloseHandle(hDesktopDup, UserMode);
1180  if (hWinStaDup)
1181  ObCloseHandle(hWinStaDup, UserMode);
1182 
1183  if (hDesktop)
1184  ObCloseHandle(hDesktop, UserMode);
1185  if (hWinSta)
1186  ObCloseHandle(hWinSta, UserMode);
1187 
1189  return Status;
1190  }
1191 }
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2528
NTSTRSAFEAPI RtlStringCbCopyW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:174
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define max(a, b)
Definition: svc.c:63
POBJECT_TYPE ExWindowStationObjectType
Definition: win32k.c:21
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
USHORT MaximumLength
Definition: env_spec_w32.h:370
BOOLEAN NTAPI ObFindHandleForObject(IN PEPROCESS Process, IN PVOID Object, IN POBJECT_TYPE ObjectType, IN POBJECT_HANDLE_INFORMATION HandleInformation, OUT PHANDLE Handle)
Definition: obhandle.c:2852
#define TRUE
Definition: types.h:120
#define ZwCurrentProcess()
UNICODE_STRING gustrWindowStationsDir
Definition: winsta.c:27
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
PWINSTATION_OBJECT InputWindowStation
Definition: winsta.c:21
LONG NTSTATUS
Definition: precomp.h:26
POBJECT_TYPE ExDesktopObjectType
Definition: win32k.c:22
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
uint16_t * PWCHAR
Definition: typedefs.h:56
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
NTSTATUS NTAPI ObOpenObjectByPointer(IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle)
Definition: obhandle.c:2738
struct _WINSTATION_OBJECT * prpwinsta
Definition: win32.h:258
#define MEM_COMMIT
Definition: nt_native.h:1313
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_OPENIF
Definition: winternl.h:229
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTATUS FASTCALL IntCreateWindowStation(OUT HWINSTA *phWinSta, IN POBJECT_ATTRIBUTES ObjectAttributes, IN KPROCESSOR_MODE AccessMode, IN KPROCESSOR_MODE OwnerMode, IN ACCESS_MASK dwDesiredAccess, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4, DWORD Unknown5, DWORD Unknown6)
Definition: winsta.c:427
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
HDESK hdeskStartup
Definition: win32.h:255
#define DUPLICATE_SAME_ACCESS
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
NTSTRSAFEAPI RtlStringCbCopyNW(_Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_reads_bytes_(cbToCopy) STRSAFE_LPCWSTR pszSrc, _In_ size_t cbToCopy)
Definition: ntstrsafe.h:416
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define WSS_NOIO
Definition: winsta.h:9
unsigned char BOOLEAN
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DWORD LowPart
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
#define OBJ_INHERIT
Definition: winternl.h:225
struct _DESKTOP * rpdeskStartup
Definition: win32.h:250
#define ObDereferenceObject
Definition: obfuncs.h:203
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3375
static const WCHAR L[]
Definition: oid.c:1250
LONG HighPart
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
#define NOTHING
Definition: env_spec_w32.h:461
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
#define SYSTEM_LUID
Definition: setypes.h:672
#define DESKTOP_ALL_ACCESS
Definition: precomp.h:20
#define MAXULONG
Definition: typedefs.h:251
#define ERR(fmt,...)
Definition: debug.h:110
ULONG_PTR SIZE_T
Definition: typedefs.h:80
NTSTATUS FASTCALL IntCreateDesktop(OUT HDESK *phDesktop, IN POBJECT_ATTRIBUTES ObjectAttributes, IN KPROCESSOR_MODE AccessMode, IN PUNICODE_STRING lpszDesktopDevice OPTIONAL, IN LPDEVMODEW lpdmw OPTIONAL, IN DWORD dwFlags, IN ACCESS_MASK dwDesiredAccess)
Definition: desktop.c:2312
HWINSTA hwinsta
Definition: win32.h:259
#define WINSTA_ACCESS_ALL
Definition: winsta.h:65
unsigned short USHORT
Definition: pedump.c:61
NTSTATUS GetProcessLuid(IN PETHREAD Thread OPTIONAL, IN PEPROCESS Process OPTIONAL, OUT PLUID Luid)
Definition: misc.c:790
#define NULL
Definition: types.h:112
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define MAXUSHORT
Definition: typedefs.h:83
#define MEM_RELEASE
Definition: nt_native.h:1316
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_Check_return_ _CRTIMP int __cdecl _scwprintf(_In_z_ _Printf_format_string_ const wchar_t *_Format,...)
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
POBJECT_TYPE PsProcessType
Definition: process.c:20
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by InitThreadCallback(), and NtUserResolveDesktop().

◆ IntSetFocusMessageQueue()

VOID FASTCALL IntSetFocusMessageQueue ( PUSER_MESSAGE_QUEUE  NewQueue)

Definition at line 1287 of file desktop.c.

1288 {
1289  PUSER_MESSAGE_QUEUE Old;
1290  PDESKTOP pdo = IntGetActiveDesktop();
1291  if (!pdo)
1292  {
1293  TRACE("No active desktop\n");
1294  return;
1295  }
1296  if (NewQueue != NULL)
1297  {
1298  if (NewQueue->Desktop != NULL)
1299  {
1300  TRACE("Message Queue already attached to another desktop!\n");
1301  return;
1302  }
1303  IntReferenceMessageQueue(NewQueue);
1304  (void)InterlockedExchangePointer((PVOID*)&NewQueue->Desktop, pdo);
1305  }
1307  if (Old != NULL)
1308  {
1310  gpqForegroundPrev = Old;
1312  }
1313  // Only one Q can have active foreground even when there are more than one desktop.
1314  if (NewQueue)
1315  {
1317  }
1318  else
1319  {
1320  gpqForeground = NULL;
1321  ERR("ptiLastInput is CLEARED!!\n");
1322  ptiLastInput = NULL; // ReactOS hacks,,,, should check for process death.
1323  }
1324 }
PUSER_MESSAGE_QUEUE gpqForeground
Definition: focus.c:12
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define IntReferenceMessageQueue(MsgQueue)
Definition: msgqueue.h:217
struct _USER_MESSAGE_QUEUE * ActiveMessageQueue
Definition: desktop.h:38
struct _USER_MESSAGE_QUEUE * PUSER_MESSAGE_QUEUE
PTHREADINFO ptiLastInput
Definition: focus.c:17
#define IntDereferenceMessageQueue(MsgQueue)
Definition: msgqueue.h:220
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define ERR(fmt,...)
Definition: debug.h:110
#define NULL
Definition: types.h:112
PUSER_MESSAGE_QUEUE gpqForegroundPrev
Definition: focus.c:13
PDESKTOP FASTCALL IntGetActiveDesktop(VOID)
Definition: desktop.c:1230
struct _DESKTOP * Desktop
Definition: msgqueue.h:50

Referenced by co_IntSetForegroundMessageQueue(), co_WinPosActivateOtherWindow(), IntSetThreadDesktop(), MsqCleanupMessageQueue(), and UserAttachThreadInput().

◆ IntSetThreadDesktop()

BOOL IntSetThreadDesktop ( IN HDESK  hDesktop,
IN BOOL  FreeOnFailure 
)

Definition at line 3215 of file desktop.c.

3217 {
3218  PDESKTOP pdesk = NULL, pdeskOld;
3219  PTHREADINFO pti;
3220  NTSTATUS Status;
3221  PCLIENTTHREADINFO pctiOld, pctiNew = NULL;
3222  PCLIENTINFO pci;
3223 
3224  ASSERT(NtCurrentTeb());
3225 
3226  TRACE("IntSetThreadDesktop hDesktop:0x%p, FOF:%i\n",hDesktop, FreeOnFailure);
3227 
3229  pci = pti->pClientInfo;
3230 
3231  /* If the caller gave us a desktop, ensure it is valid */
3232  if (hDesktop != NULL)
3233  {
3234  /* Validate the new desktop. */
3235  Status = IntValidateDesktopHandle(hDesktop, UserMode, 0, &pdesk);
3236  if (!NT_SUCCESS(Status))
3237  {
3238  ERR("Validation of desktop handle 0x%p failed\n", hDesktop);
3239  return FALSE;
3240  }
3241 
3242  if (pti->rpdesk == pdesk)
3243  {
3244  /* Nothing to do */
3245  ObDereferenceObject(pdesk);
3246  return TRUE;
3247  }
3248  }
3249 
3250  /* Make sure that we don't own any window in the current desktop */
3251  if (!IsListEmpty(&pti->WindowListHead))
3252  {
3253  if (pdesk)
3254  ObDereferenceObject(pdesk);
3255  ERR("Attempted to change thread desktop although the thread has windows!\n");
3257  return FALSE;
3258  }
3259 
3260  /* Desktop is being re-set so clear out foreground. */
3261  if (pti->rpdesk != pdesk && pti->MessageQueue == gpqForeground)
3262  {
3263  // Like above, there shouldn't be any windows, hooks or anything active on this threads desktop!
3265  }
3266 
3267  /* Before doing the switch, map the new desktop heap and allocate the new pcti */
3268  if (pdesk != NULL)
3269  {
3270  Status = IntMapDesktopView(pdesk);
3271  if (!NT_SUCCESS(Status))
3272  {
3273  ERR("Failed to map desktop heap!\n");
3274  ObDereferenceObject(pdesk);
3276  return FALSE;
3277  }
3278 
3279  pctiNew = DesktopHeapAlloc(pdesk, sizeof(CLIENTTHREADINFO));
3280  if (pctiNew == NULL)
3281  {
3282  ERR("Failed to allocate new pcti\n");
3283  IntUnmapDesktopView(pdesk);
3284  ObDereferenceObject(pdesk);
3286  return FALSE;
3287  }
3288  }
3289 
3290  /*
3291  * Processes, in particular Winlogon.exe, that manage window stations
3292  * (especially the interactive WinSta0 window station) and desktops,
3293  * may not be able to connect at startup to a window station and have
3294  * an associated desktop as well, if none exists on the system already.
3295  * Because creating a new window station does not affect the window station
3296  * associated to the process, and because neither by associating a window
3297  * station to the process nor creating a new desktop on it does associate
3298  * a startup desktop to that process, the process has to actually assigns
3299  * one of its threads to a desktop so that it gets automatically an assigned
3300  * startup desktop.
3301  *
3302  * This is what actually happens for Winlogon.exe, which is started without
3303  * any window station and desktop. By creating the first (and therefore
3304  * interactive) WinSta0 window station, then assigning WinSta0 to itself
3305  * and creating the Default desktop on it, and then assigning this desktop
3306  * to its main thread, Winlogon.exe basically does the similar steps that
3307  * would have been done automatically at its startup if there were already
3308  * an existing WinSta0 window station and Default desktop.
3309  *
3310  * Of course all this must not be done if we are a SYSTEM or CSRSS thread.
3311  */
3312  // if (pti->ppi->peProcess != gpepCSRSS)
3313  if (!(pti->TIF_flags & (TIF_SYSTEMTHREAD | TIF_CSRSSTHREAD)) &&
3314  pti->ppi->rpdeskStartup == NULL && hDesktop != NULL)
3315  {
3316  ERR("The process 0x%p '%s' didn't have an assigned startup desktop before, assigning it now!\n",
3317  pti->ppi->peProcess, pti->ppi->peProcess->ImageFileName);
3318 
3319  pti->ppi->hdeskStartup = hDesktop;
3320  pti->ppi->rpdeskStartup = pdesk;
3321  }
3322 
3323  /* free all classes or move them to the shared heap */
3324  if (pti->rpdesk != NULL)
3325  {
3326  if (!IntCheckProcessDesktopClasses(pti->rpdesk, FreeOnFailure))
3327  {
3328  ERR("Failed to move process classes to shared heap!\n");
3329  if (pdesk)
3330  {
3331  DesktopHeapFree(pdesk, pctiNew);
3332  IntUnmapDesktopView(pdesk);
3333  ObDereferenceObject(pdesk);
3334  }
3335  return FALSE;
3336  }
3337  }
3338 
3339  pdeskOld = pti->rpdesk;
3340  if (pti->pcti != &pti->cti)
3341  pctiOld = pti->pcti;
3342  else
3343  pctiOld = NULL;
3344 
3345  /* do the switch */
3346  if (pdesk != NULL)
3347  {
3348  pti->rpdesk = pdesk;
3349  pti->hdesk = hDesktop;
3350  pti->pDeskInfo = pti->rpdesk->pDeskInfo;
3351  pti->pcti = pctiNew;
3352 
3354  pci->pDeskInfo = (PVOID)((ULONG_PTR)pti->pDeskInfo - pci->ulClientDelta);
3355  pci->pClientThreadInfo = (PVOID)((ULONG_PTR)pti->pcti - pci->ulClientDelta);
3356 
3357  /* initialize the new pcti */
3358  if (pctiOld != NULL)
3359  {
3360  RtlCopyMemory(pctiNew, pctiOld, sizeof(CLIENTTHREADINFO));
3361  }
3362  else
3363  {
3364  RtlZeroMemory(pctiNew, sizeof(CLIENTTHREADINFO));
3365  pci->fsHooks = pti->fsHooks;
3366  pci->dwTIFlags = pti->TIF_flags;
3367  }
3368  }
3369  else
3370  {
3371  pti->rpdesk = NULL;
3372  pti->hdesk = NULL;
3373  pti->pDeskInfo = NULL;
3374  pti->pcti = &pti->cti; // Always point inside so there will be no crash when posting or sending msg's!
3375  pci->ulClientDelta = 0;
3376  pci->pDeskInfo = NULL;
3377  pci->pClientThreadInfo = NULL;
3378  }
3379 
3380  /* clean up the old desktop */
3381  if (pdeskOld != NULL)
3382  {
3383  RemoveEntryList(&pti->PtiLink);
3384  if (pctiOld) DesktopHeapFree(pdeskOld, pctiOld);
3385  IntUnmapDesktopView(pdeskOld);
3386  ObDereferenceObject(pdeskOld);
3387  }
3388 
3389  if (pdesk)
3390  {
3391  InsertTailList(&pdesk->PtiList, &pti->PtiLink);
3392  }
3393 
3394  TRACE("IntSetThreadDesktop: pti 0x%p ppi 0x%p switched from object 0x%p to 0x%p\n", pti, pti->ppi, pdeskOld, pdesk);
3395 
3396  return TRUE;
3397 }
BOOL IntCheckProcessDesktopClasses(IN PDESKTOP Desktop, IN BOOL FreeOnFailure)
Definition: class.c:1012
PUSER_MESSAGE_QUEUE gpqForeground
Definition: focus.c:12
ULONG fsHooks
Definition: ntuser.h:297
LIST_ENTRY PtiList
Definition: desktop.h:25
#define TRUE
Definition: types.h:120
LIST_ENTRY WindowListHead
Definition: win32.h:150
FLONG TIF_flags
Definition: win32.h:94
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
LONG NTSTATUS
Definition: precomp.h:26
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
LIST_ENTRY PtiLink
Definition: win32.h:125
#define InsertTailList(ListHead, Entry)
#define TIF_SYSTEMTHREAD
Definition: ntuser.h:242
struct _DESKTOP * rpdesk
Definition: win32.h:91
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define ERROR_BUSY
Definition: dderror.h:12
PCLIENTTHREADINFO pClientThreadInfo
Definition: ntuser.h:301
PPROCESSINFO ppi
Definition: win32.h:87
uint32_t ULONG_PTR
Definition: typedefs.h:65
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
HDESK hdesk
Definition: win32.h:107
HDESK hdeskStartup
Definition: win32.h:255
static __inline PVOID DesktopHeapAlloc(IN PDESKTOP Desktop, IN SIZE_T Bytes)
Definition: desktop.h:230
#define FALSE
Definition: types.h:117
#define TIF_CSRSSTHREAD
Definition: ntuser.h:243
static NTSTATUS IntUnmapDesktopView(IN PDESKTOP pdesk)
Definition: desktop.c:3097
void * PVOID
Definition: retypes.h:9
struct _CLIENTTHREADINFO * pcti
Definition: win32.h:90
ULONG_PTR ulClientDelta
Definition: ntuser.h:295
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
ULONG fsHooks
Definition: win32.h:116
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static NTSTATUS IntMapDesktopView(IN PDESKTOP pdesk)
Definition: desktop.c:3141
struct _DESKTOP * rpdeskStartup
Definition: win32.h:250
#define ObDereferenceObject
Definition: obfuncs.h:203
struct _CLIENTINFO * pClientInfo
Definition: win32.h:93
CLIENTTHREADINFO cti
Definition: win32.h:139
PDESKTOPINFO pDeskInfo
Definition: ntuser.h:294
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
#define ERR(fmt,...)
Definition: debug.h:110
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:88
VOID FASTCALL IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue)
Definition: desktop.c:1287
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
static __inline ULONG_PTR DesktopHeapGetUserDelta(VOID)
Definition: desktop.h:298
NTSTATUS FASTCALL IntValidateDesktopHandle(HDESK Desktop, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PDESKTOP *Object)
Definition: desktop.c:1204
#define NULL
Definition: types.h:112
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
static __inline BOOL DesktopHeapFree(IN PDESKTOP Desktop, IN PVOID lpMem)
Definition: desktop.h:241
struct _DESKTOPINFO * pDeskInfo
Definition: win32.h:92
DWORD dwTIFlags
Definition: ntuser.h:293
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by DesktopWindowProc(), ExitThreadCallback(), InitThreadCallback(), NtUserSetInformationThread(), and NtUserSetThreadDesktop().

◆ IntUnmapDesktopView()

static NTSTATUS IntUnmapDesktopView ( IN PDESKTOP  pdesk)
static

Definition at line 3097 of file desktop.c.

3098 {
3099  PPROCESSINFO ppi;
3100  PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
3102 
3103  TRACE("IntUnmapDesktopView called for desktop object %p\n", pdesk);
3104 
3106 
3107  /*
3108  * Unmap if we're the last thread using the desktop.
3109  * Start the search at the next mapping: skip the first entry
3110  * as it must be the global user heap mapping.
3111  */
3112  PrevLink = &ppi->HeapMappings.Next;
3113  HeapMapping = *PrevLink;
3114  while (HeapMapping != NULL)
3115  {
3116  if (HeapMapping->KernelMapping == (PVOID)pdesk->pheapDesktop)
3117  {
3118  if (--HeapMapping->Count == 0)
3119  {
3120  *PrevLink = HeapMapping->Next;
3121 
3122  TRACE("ppi 0x%p unmapped heap of desktop 0x%p\n", ppi, pdesk);
3124  HeapMapping->UserMapping);
3125 
3126  ObDereferenceObject(pdesk);
3127 
3128  UserHeapFree(HeapMapping);
3129  break;
3130  }
3131  }
3132 
3133  PrevLink = &HeapMapping->Next;
3134  HeapMapping = HeapMapping->Next;
3135  }
3136 
3137  return Status;
3138 }
LONG NTSTATUS
Definition: precomp.h:26
static __inline BOOL UserHeapFree(PVOID lpMem)
Definition: usrheap.h:44
#define PsGetCurrentProcess
Definition: psfuncs.h:17
W32HEAP_USER_MAPPING HeapMappings
Definition: win32.h:282
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:3109
#define TRACE(s)
Definition: solgame.cpp:4
#define ObDereferenceObject
Definition: obfuncs.h:203
#define NULL
Definition: types.h:112
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _W32HEAP_USER_MAPPING * Next
Definition: win32.h:195

Referenced by IntDesktopObjectClose(), and IntSetThreadDesktop().

◆ IntValidateDesktopHandle()

NTSTATUS FASTCALL IntValidateDesktopHandle ( HDESK  Desktop,
KPROCESSOR_MODE  AccessMode,
ACCESS_MASK  DesiredAccess,
PDESKTOP Object 
)

Definition at line 1204 of file desktop.c.

1209 {
1210  NTSTATUS Status;
1211 
1213  Desktop,
1214  DesiredAccess,
1216  AccessMode,
1217  (PVOID*)Object,
1218  NULL);
1219 
1220  TRACE("IntValidateDesktopHandle: handle:0x%p obj:0x%p access:0x%x Status:0x%lx\n",
1222 
1223  if (!NT_SUCCESS(Status))
1225 
1226  return Status;
1227 }
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
LONG NTSTATUS
Definition: precomp.h:26
POBJECT_TYPE ExDesktopObjectType
Definition: win32k.c:22
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:395
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
#define NULL
Definition: types.h:112

Referenced by InitThreadCallback(), IntSetThreadDesktop(), NtUserBuildHwndList(), NtUserCloseDesktop(), NtUserGetObjectInformation(), and NtUserSwitchDesktop().

◆ NtUserCloseDesktop()

BOOL APIENTRY NtUserCloseDesktop ( HDESK  hDesktop)

Definition at line 2681 of file desktop.c.

2682 {
2683  PDESKTOP pdesk;
2684  NTSTATUS Status;
2686 
2687  TRACE("NtUserCloseDesktop(0x%p) called\n", hDesktop);
2689 
2690  if (hDesktop == gptiCurrent->hdesk || hDesktop == gptiCurrent->ppi->hdeskStartup)
2691  {
2692  ERR("Attempted to close thread desktop\n");
2694  RETURN(FALSE);
2695  }
2696 
2697  Status = IntValidateDesktopHandle(hDesktop, UserMode, 0, &pdesk);
2698  if (!NT_SUCCESS(Status))
2699  {
2700  ERR("Validation of desktop handle 0x%p failed\n", hDesktop);
2701  RETURN(FALSE);
2702  }
2703 
2704  ObDereferenceObject(pdesk);
2705 
2706  Status = ObCloseHandle(hDesktop, UserMode);
2707  if (!NT_SUCCESS(Status))
2708  {
2709  ERR("Failed to close desktop handle 0x%p\n", hDesktop);
2711  RETURN(FALSE);
2712  }
2713 
2714  RETURN(TRUE);
2715 
2716 CLEANUP:
2717  TRACE("Leave NtUserCloseDesktop, ret=%i\n",_ret_);
2718  UserLeave();
2719  END_CLEANUP;
2720 }
#define CLEANUP
Definition: ntuser.h:5
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define ERROR_BUSY
Definition: dderror.h:12
#define RETURN(x)
PPROCESSINFO ppi
Definition: win32.h:87
HDESK hdesk
Definition: win32.h:107
HDESK hdeskStartup
Definition: win32.h:255
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:263
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
#define DECLARE_RETURN(type)
Definition: ntuser.h:3
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3375
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
#define ERR(fmt,...)
Definition: debug.h:110
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:271
NTSTATUS FASTCALL IntValidateDesktopHandle(HDESK Desktop, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PDESKTOP *Object)
Definition: desktop.c:1204
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
#define END_CLEANUP
Definition: ntuser.h:6

Referenced by CloseDesktop().

◆ NtUserCreateDesktop()

HDESK APIENTRY NtUserCreateDesktop ( POBJECT_ATTRIBUTES  ObjectAttributes,
PUNICODE_STRING  lpszDesktopDevice,
LPDEVMODEW  lpdmw,
DWORD  dwFlags,
ACCESS_MASK  dwDesiredAccess 
)

Definition at line 2487 of file desktop.c.

2493 {
2494  NTSTATUS Status;
2495  HDESK hDesk;
2496 
2497  DECLARE_RETURN(HDESK);
2498 
2499  TRACE("Enter NtUserCreateDesktop\n");
2501 
2502  Status = IntCreateDesktop(&hDesk,
2504  UserMode,
2505  lpszDesktopDevice,
2506  lpdmw,
2507  dwFlags,
2508  dwDesiredAccess);
2509  if (!NT_SUCCESS(Status))
2510  {
2511  ERR("IntCreateDesktop failed, Status 0x%08lx\n", Status);
2512  // SetLastNtError(Status);
2513  RETURN(NULL);
2514  }
2515 
2516  RETURN(hDesk);
2517 
2518 CLEANUP:
2519  TRACE("Leave NtUserCreateDesktop, ret=0x%p\n", _ret_);
2520  UserLeave();
2521  END_CLEANUP;
2522 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define CLEANUP
Definition: ntuser.h:5
LONG NTSTATUS
Definition: precomp.h:26
#define RETURN(x)
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:263
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DECLARE_RETURN(type)
Definition: ntuser.h:3
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define ERR(fmt,...)
Definition: debug.h:110
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:271
NTSTATUS FASTCALL IntCreateDesktop(OUT HDESK *phDesktop, IN POBJECT_ATTRIBUTES ObjectAttributes, IN KPROCESSOR_MODE AccessMode, IN PUNICODE_STRING lpszDesktopDevice OPTIONAL, IN LPDEVMODEW lpdmw OPTIONAL, IN DWORD dwFlags, IN ACCESS_MASK dwDesiredAccess)
Definition: desktop.c:2312
#define NULL
Definition: types.h:112
#define END_CLEANUP
Definition: ntuser.h:6

Referenced by CreateDesktopW().

◆ NtUserGetThreadDesktop()

HDESK APIENTRY NtUserGetThreadDesktop ( DWORD  dwThreadId,
HDESK  hConsoleDesktop 
)

Definition at line 2988 of file desktop.c.

2989 {
2990  HDESK hDesk;
2991  NTSTATUS Status;
2992  PTHREADINFO pti;
2994  PDESKTOP DesktopObject;
2996 
2998  TRACE("Enter NtUserGetThreadDesktop\n");
2999 
3000  if (!dwThreadId)
3001  {
3003  hDesk = NULL;
3004  goto Quit;
3005  }
3006 
3007  /* Validate the Win32 thread and retrieve its information */
3009  if (pti)
3010  {
3011  /* Get the desktop handle of the thread */
3012  hDesk = pti->hdesk;
3013  Process = pti->ppi->peProcess;
3014  }
3015  else if (hConsoleDesktop)
3016  {
3017  /*
3018  * The thread may belong to a console, so attempt to use the provided
3019  * console desktop handle as a fallback. Otherwise this means that the
3020  * thread is either not Win32 or invalid.
3021  */
3022  hDesk = hConsoleDesktop;
3023  Process = gpepCSRSS;
3024  }
3025  else
3026  {
3028  hDesk = NULL;
3029  goto Quit;
3030  }
3031 
3032  if (!hDesk)
3033  {
3034  ERR("Desktop information of thread 0x%x broken!?\n", dwThreadId);
3035  goto Quit;
3036  }
3037 
3038  if (Process == PsGetCurrentProcess())
3039  {
3040  /*
3041  * Just return the handle, since we queried the desktop handle
3042  * of a thread running in the same context.
3043  */
3044  goto Quit;
3045  }
3046 
3047  /*
3048  * We could just use the cached rpdesk instead of looking up the handle,
3049  * but it may actually be safer to validate the desktop and get a temporary
3050  * reference to it so that it does not disappear under us (e.g. when the
3051  * desktop is being destroyed) during the operation.
3052  */
3053  /*
3054  * Switch into the context of the thread we are trying to get
3055  * the desktop from, so we can use the handle.
3056  */
3057  KeAttachProcess(&Process->Pcb);
3059  0,
3061  UserMode,
3062  (PVOID*)&DesktopObject,
3064  KeDetachProcess();
3065 
3066  if (NT_SUCCESS(Status))
3067  {
3068  /*
3069  * Lookup our handle table if we can find a handle to the desktop object.
3070  * If not, create one.
3071  * QUESTION: Do we really need to create a handle in case it doesn't exist??
3072  */
3073  hDesk = IntGetDesktopObjectHandle(DesktopObject);
3074 
3075  /* All done, we got a valid handle to the desktop */
3076  ObDereferenceObject(DesktopObject);
3077  }
3078  else
3079  {
3080  /* The handle could not be found, there is nothing to get... */
3081  hDesk = NULL;
3082  }
3083 
3084  if (!hDesk)
3085  {
3086  ERR("Could not retrieve or access desktop for thread 0x%x\n", dwThreadId);
3088  }
3089 
3090 Quit:
3091  TRACE("Leave NtUserGetThreadDesktop, hDesk = 0x%p\n", hDesk);
3092  UserLeave();
3093  return hDesk;
3094 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
PEPROCESS gpepCSRSS
Definition: csr.c:15
LONG NTSTATUS
Definition: precomp.h:26
POBJECT_TYPE ExDesktopObjectType
Definition: win32k.c:22
PPROCESSINFO ppi
Definition: win32.h:87
PTHREADINFO FASTCALL IntTID2PTI(HANDLE id)
Definition: misc.c:41
HDESK hdesk
Definition: win32.h:107
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define PsGetCurrentProcess
Definition: psfuncs.h:17
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:263
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define UlongToHandle(ul)
Definition: basetsd.h:97
HDESK FASTCALL IntGetDesktopObjectHandle(PDESKTOP DesktopObject)
Definition: desktop.c:1239
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_ ACCESS_MASK _In_opt_ POBJECT_TYPE _In_ KPROCESSOR_MODE _Out_ PVOID _Out_opt_ POBJECT_HANDLE_INFORMATION HandleInformation
Definition: obfuncs.h:40
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:621
DWORD dwThreadId
Definition: fdebug.c:31
#define ERR(fmt,...)
Definition: debug.h:110
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:271
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:582
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by GetThreadDesktop().

◆ NtUserOpenDesktop()

HDESK APIENTRY NtUserOpenDesktop ( POBJECT_ATTRIBUTES  ObjectAttributes,
DWORD  dwFlags,
ACCESS_MASK  dwDesiredAccess 
)

Definition at line 2547 of file desktop.c.

2551 {
2552  NTSTATUS Status;
2553  HDESK Desktop;
2554 
2558  UserMode,
2559  NULL,
2560  dwDesiredAccess,
2561  NULL,
2562  (HANDLE*)&Desktop);
2563 
2564  if (!NT_SUCCESS(Status))
2565  {
2566  ERR("Failed to open desktop\n");
2568  return NULL;
2569  }
2570 
2571  TRACE("Opened desktop %S with handle 0x%p\n", ObjectAttributes->ObjectName->Buffer, Desktop);
2572 
2573  return Desktop;
2574 }
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2528
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
LONG NTSTATUS
Definition: precomp.h:26
POBJECT_TYPE ExDesktopObjectType
Definition: win32k.c:22
static CHAR Desktop[MAX_PATH]
Definition: dem.c:256
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
#define ERR(fmt,...)
Definition: debug.h:110
#define NULL
Definition: types.h:112

Referenced by OpenDesktopW().

◆ NtUserOpenInputDesktop()

HDESK APIENTRY NtUserOpenInputDesktop ( DWORD  dwFlags,
BOOL  fInherit,
ACCESS_MASK  dwDesiredAccess 
)

Definition at line 2641 of file desktop.c.

2645 {
2646  HDESK hdesk;
2647 
2649  TRACE("Enter NtUserOpenInputDesktop gpdeskInputDesktop 0x%p\n",gpdeskInputDesktop);
2650 
2651  hdesk = UserOpenInputDesktop(dwFlags, fInherit, dwDesiredAccess);
2652 
2653  TRACE("NtUserOpenInputDesktop returning 0x%p\n",hdesk);
2654  UserLeave();
2655  return hdesk;
2656 }
PDESKTOP gpdeskInputDesktop
Definition: desktop.c:35
HDESK UserOpenInputDesktop(DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess)
Definition: desktop.c:2576
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:263
#define TRACE(s)
Definition: solgame.cpp:4
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:271

Referenced by OpenInputDesktop().

◆ NtUserPaintDesktop()

BOOL APIENTRY NtUserPaintDesktop ( HDC  hDC)

Definition at line 2738 of file desktop.c.

2739 {
2740  BOOL Ret;
2742  TRACE("Enter NtUserPaintDesktop\n");
2743  Ret = IntPaintDesktop(hDC);
2744  TRACE("Leave NtUserPaintDesktop, ret=%i\n",Ret);
2745  UserLeave();
2746  return Ret;
2747 }
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL FASTCALL IntPaintDesktop(HDC hDC)
Definition: desktop.c:1795
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:263
#define TRACE(s)
Definition: solgame.cpp:4
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:271
static HDC hDC
Definition: 3dtext.c:33

Referenced by PaintDesktop().

◆ NtUserResolveDesktop()

HDESK NTAPI NtUserResolveDesktop ( IN HANDLE  ProcessHandle,
IN PUNICODE_STRING  DesktopPath,
IN BOOL  bInherit,
OUT HWINSTA *  phWinSta 
)

Definition at line 2785 of file desktop.c.

2790 {
2791  NTSTATUS Status;
2793  HWINSTA hWinSta = NULL;
2794  HDESK hDesktop = NULL;
2795  UNICODE_STRING CapturedDesktopPath;
2796 
2797  /* Allow only the Console Server to perform this operation (via CSRSS) */
2798  if (PsGetCurrentProcess() != gpepCSRSS)
2799  return NULL;
2800 
2801  /* Get the process object the user handle was referencing */
2804  *PsProcessType,
2805  UserMode,
2806  (PVOID*)&Process,
2807  NULL);
2808  if (!NT_SUCCESS(Status))
2809  return NULL;
2810 
2811  // UserEnterShared();
2812 
2813  _SEH2_TRY
2814  {
2815  /* Probe the handle pointer */
2816  // ProbeForWriteHandle
2817  ProbeForWrite(phWinSta, sizeof(HWINSTA), sizeof(HWINSTA));
2818  }
2820  {
2822  _SEH2_YIELD(goto Quit);
2823  }
2824  _SEH2_END;
2825 
2826  /* Capture the user desktop path string */
2827  Status = ProbeAndCaptureUnicodeString(&CapturedDesktopPath,
2828  UserMode,
2829  DesktopPath);
2830  if (!NT_SUCCESS(Status))
2831  goto Quit;
2832 
2833  /* Call the internal function */
2835  &CapturedDesktopPath,
2836  bInherit,
2837  &hWinSta,
2838  &hDesktop);
2839  if (!NT_SUCCESS(Status))
2840  {
2841  ERR("IntResolveDesktop failed, Status 0x%08lx\n", Status);
2842  hWinSta = NULL;
2843  hDesktop = NULL;
2844  }
2845 
2846  _SEH2_TRY
2847  {
2848  /* Return the window station handle */
2849  *phWinSta = hWinSta;
2850  }
2852  {
2854 
2855  /* We failed, close the opened desktop and window station */
2856  if (hDesktop) ObCloseHandle(hDesktop, UserMode);
2857  hDesktop = NULL;
2858  if (hWinSta) ObCloseHandle(hWinSta, UserMode);
2859  }
2860  _SEH2_END;
2861 
2862  /* Free the captured string */
2863  ReleaseCapturedUnicodeString(&CapturedDesktopPath, UserMode);
2864 
2865 Quit:
2866  // UserLeave();
2867 
2868  /* Dereference the process object */
2870 
2871  /* Return the desktop handle */
2872  return hDesktop;
2873 }
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:166
PEPROCESS gpepCSRSS
Definition: csr.c:15
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_SEH2_TRY
Definition: create.c:4226
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define PsGetCurrentProcess
Definition: psfuncs.h:17
Status
Definition: gdiplustypes.h:24
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ObDereferenceObject
Definition: obfuncs.h:203
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3375
#define ERR(fmt,...)
Definition: debug.h:110
_SEH2_END
Definition: create.c:4400
NTSTATUS FASTCALL IntResolveDesktop(IN PEPROCESS Process, IN PUNICODE_STRING DesktopPath, IN BOOL bInherit, OUT HWINSTA *phWinSta, OUT HDESK *phDesktop)
Definition: desktop.c:539
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
POBJECT_TYPE PsProcessType
Definition: process.c:20

Referenced by GuiInit().

◆ NtUserSetThreadDesktop()

BOOL APIENTRY NtUserSetThreadDesktop ( HDESK  hDesktop)

Definition at line 3407 of file desktop.c.

3408 {
3409  BOOL ret = FALSE;
3410 
3412 
3413  // FIXME: IntSetThreadDesktop validates the desktop handle, it should happen
3414  // here too and set the NT error level. Q. Is it necessary to have the validation
3415  // in IntSetThreadDesktop? Is it needed there too?
3416  if (hDesktop || (!hDesktop && PsGetCurrentProcess() == gpepCSRSS))
3417  ret = IntSetThreadDesktop(hDesktop, FALSE);
3418 
3419  UserLeave();
3420 
3421  return ret;
3422 }
PEPROCESS gpepCSRSS
Definition: csr.c:15
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define PsGetCurrentProcess
Definition: psfuncs.h:17
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:263
int ret
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:271
BOOL IntSetThreadDesktop(IN HDESK hDesktop, IN BOOL FreeOnFailure)
Definition: desktop.c:3215

Referenced by SetThreadDesktop().

◆ NtUserSwitchDesktop()

BOOL APIENTRY NtUserSwitchDesktop ( HDESK  hdesk)

Definition at line 2892 of file desktop.c.

2893 {
2894  PDESKTOP pdesk;
2895  NTSTATUS Status;
2896  BOOL bRedrawDesktop;
2898 
2900  TRACE("Enter NtUserSwitchDesktop(0x%p)\n", hdesk);
2901 
2902  Status = IntValidateDesktopHandle(hdesk, UserMode, 0, &pdesk);
2903  if (!NT_SUCCESS(Status))
2904  {
2905  ERR("Validation of desktop handle 0x%p failed\n", hdesk);
2906  RETURN(FALSE);
2907  }
2908 
2909  if (PsGetCurrentProcessSessionId() != pdesk->rpwinstaParent->dwSessionId)
2910  {
2911  ObDereferenceObject(pdesk);
2912  ERR("NtUserSwitchDesktop called for a desktop of a different session\n");
2913  RETURN(FALSE);
2914  }
2915 
2916  if (pdesk == gpdeskInputDesktop)
2917  {
2918  ObDereferenceObject(pdesk);
2919  WARN("NtUserSwitchDesktop called for active desktop\n");
2920  RETURN(TRUE);
2921  }
2922 
2923  /*
2924  * Don't allow applications switch the desktop if it's locked, unless the caller
2925  * is the logon application itself
2926  */
2927  if ((pdesk->rpwinstaParent->Flags & WSS_LOCKED) &&
2929  {
2930  ObDereferenceObject(pdesk);
2931  ERR("Switching desktop 0x%p denied because the window station is locked!\n", hdesk);
2932  RETURN(FALSE);
2933  }
2934 
2935  if (pdesk->rpwinstaParent != InputWindowStation)
2936  {
2937  ObDereferenceObject(pdesk);
2938  ERR("Switching desktop 0x%p denied because desktop doesn't belong to the interactive winsta!\n", hdesk);
2939  RETURN(FALSE);
2940  }
2941 
2942  /* FIXME: Fail if the process is associated with a secured
2943  desktop such as Winlogon or Screen-Saver */
2944  /* FIXME: Connect to input device */
2945 
2946  TRACE("Switching from desktop 0x%p to 0x%p\n", gpdeskInputDesktop, pdesk);
2947 
2948  bRedrawDesktop = FALSE;
2949 
2950  /* The first time SwitchDesktop is called, gpdeskInputDesktop is NULL */
2951  if (gpdeskInputDesktop != NULL)
2952  {
2954  bRedrawDesktop = TRUE;
2955 
2956  /* Hide the previous desktop window */
2957