ReactOS  0.4.15-dev-3316-g067ca88
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 1335 of file desktop.c.

1336 {
1337  if (pWnd->head.rpdesk &&
1338  pWnd->head.rpdesk->pDeskInfo)
1339  return pWnd->head.rpdesk->pDeskInfo->spwnd;
1340  return NULL;
1341 }
struct _DESKTOP * rpdesk
Definition: ntuser.h:186
THRDESKHEAD head
Definition: ntuser.h:665
#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 1659 of file desktop.c.

1660 {
1662  HWND* HwndList;
1663 
1664  if (!gpsi->uiShellMsg)
1665  {
1666  gpsi->uiShellMsg = IntAddAtom(L"SHELLHOOK");
1667 
1668  TRACE("MsgType = %x\n", gpsi->uiShellMsg);
1669  if (!gpsi->uiShellMsg)
1670  ERR("LastError: %x\n", EngGetLastError());
1671  }
1672 
1673  if (!Desktop)
1674  {
1675  TRACE("IntShellHookNotify: No desktop!\n");
1676  return;
1677  }
1678 
1679  // Allow other devices have a shot at foreground.
1680  if (Message == HSHELL_APPCOMMAND) ptiLastInput = NULL;
1681 
1682  // FIXME: System Tray Support.
1683 
1684  HwndList = UserBuildShellHookHwndList(Desktop);
1685  if (HwndList)
1686  {
1687  HWND* cursor = HwndList;
1688 
1689  for (; *cursor; cursor++)
1690  {
1691  TRACE("Sending notify\n");
1693  gpsi->uiShellMsg,
1694  Message,
1695  (Message == HSHELL_LANGUAGE ? lParam : (LPARAM)wParam) );
1696 /* co_IntPostOrSendMessage(*cursor,
1697  gpsi->uiShellMsg,
1698  Message,
1699  (Message == HSHELL_LANGUAGE ? lParam : (LPARAM)wParam) );*/
1700  }
1701 
1703  }
1704 
1705  if (ISITHOOKED(WH_SHELL))
1706  {
1708  }
1709 }
UINT uiShellMsg
Definition: ntuser.h:1025
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:1618
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:1231
#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 1584 of file desktop.c.

1585 {
1586  PWND pwnd = Desktop->pDeskInfo->spwnd;
1588  ASSERT(pwnd);
1589 
1590  if (!bRedraw)
1591  flags |= SWP_NOREDRAW;
1592 
1593  co_WinPosSetWindowPos(pwnd, NULL, 0, 0, Width, Height, flags);
1594 
1595  if (bRedraw)
1597 
1598  return STATUS_SUCCESS;
1599 }
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:1233
#define ASSERT(a)
Definition: mode.c:44
#define SWP_NOACTIVATE
Definition: winuser.h:1228
GLbitfield flags
Definition: glext.h:7161
Definition: ntuser.h:663
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:1234
#define SWP_NOREDRAW
Definition: winuser.h:1232
#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 1513 of file desktop.c.

1514 {
1515  BOOL Ret;
1516  MSG Msg;
1517 
1519 
1521 
1522  /* Register system classes. This thread does not belong to any desktop so the
1523  classes will be allocated from the shared heap */
1525 
1527 
1528  while (TRUE)
1529  {
1530  Ret = co_IntGetPeekMessage(&Msg, 0, 0, 0, PM_REMOVE, TRUE);
1531  if (Ret)
1532  {
1534  }
1535  }
1536 
1537  UserLeave();
1538 }
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:245
PKEVENT gpDesktopThreadStartedEvent
Definition: desktop.c:39
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:253
BOOL APIENTRY co_IntGetPeekMessage(PMSG pMsg, HWND hWnd, UINT MsgFilterMin, UINT MsgFilterMax, UINT RemoveMsg, BOOL bGMSG)
Definition: message.c:1177
struct @1587 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 1406 of file desktop.c.

1407 {
1408  PAINTSTRUCT Ps;
1409  ULONG Value;
1410  //ERR("DesktopWindowProc\n");
1411 
1412  *lResult = 0;
1413 
1414  switch (Msg)
1415  {
1416  case WM_NCCREATE:
1417  if (!Wnd->fnid)
1418  {
1419  Wnd->fnid = FNID_DESKTOP;
1420  }
1421  *lResult = (LRESULT)TRUE;
1422  return TRUE;
1423 
1424  case WM_CREATE:
1426  // Save Process ID
1429  // Save Thread ID
1431  case WM_CLOSE:
1432  return TRUE;
1433 
1434  case WM_DISPLAYCHANGE:
1436  return TRUE;
1437 
1438  case WM_ERASEBKGND:
1440  *lResult = 1;
1441  return TRUE;
1442 
1443  case WM_PAINT:
1444  {
1445  if (IntBeginPaint(Wnd, &Ps))
1446  {
1447  IntEndPaint(Wnd, &Ps);
1448  }
1449  return TRUE;
1450  }
1451  case WM_SYSCOLORCHANGE:
1453  return TRUE;
1454 
1455  case WM_SETCURSOR:
1456  {
1457  PCURICON_OBJECT pcurOld, pcurNew;
1459  if (!pcurNew)
1460  {
1461  return TRUE;
1462  }
1463 
1464  pcurNew->CURSORF_flags |= CURSORF_CURRENT;
1465  pcurOld = UserSetCursor(pcurNew, FALSE);
1466  if (pcurOld)
1467  {
1468  pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
1469  UserDereferenceObject(pcurOld);
1470  }
1471  return TRUE;
1472  }
1473 
1474  case WM_WINDOWPOSCHANGING:
1475  {
1476  PWINDOWPOS pWindowPos = (PWINDOWPOS)lParam;
1477  if ((pWindowPos->flags & SWP_SHOWWINDOW) != 0)
1478  {
1479  HDESK hdesk = UserOpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
1480  IntSetThreadDesktop(hdesk, FALSE);
1481  }
1482  break;
1483  }
1484  default:
1485  TRACE("DWP calling IDWP Msg %d\n",Msg);
1486  //*lResult = IntDefWindowProc(Wnd, Msg, wParam, lParam, FALSE);
1487  }
1488  return TRUE; /* We are done. Do not do any callbacks to user mode */
1489 }
#define WM_SYSCOLORCHANGE
Definition: winuser.h:1609
#define CURSORF_CURRENT
Definition: ntuser.h:1165
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:1233
#define DT_GWL_THREADID
Definition: desktop.h:56
HCURSOR gDesktopCursor
Definition: desktop.c:38
#define WM_NCCREATE
Definition: winuser.h:1666
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:679
#define FNID_DESKTOP
Definition: ntuser.h:832
#define WM_SETCURSOR
Definition: winuser.h:1619
BOOL FASTCALL IntPaintDesktop(HDC hDC)
Definition: desktop.c:1794
PsGetCurrentThreadId
Definition: CrNtStubs.h:7
UINT flags
Definition: winuser.h:3570
HDESK UserOpenInputDesktop(DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess)
Definition: desktop.c:2577
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:213
#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:1228
#define RDW_ERASE
Definition: winuser.h:1197
#define WM_WINDOWPOSCHANGING
Definition: winuser.h:1644
#define WM_CLOSE
Definition: winuser.h:1604
HDC FASTCALL IntBeginPaint(PWND Window, PPAINTSTRUCT Ps)
Definition: painting.c:1434
#define WM_PAINT
Definition: winuser.h:1603
ULONG CURSORF_flags
Definition: cursoricon.h:16
#define LRESULT
Definition: ole.h:14
#define DESKTOP_ALL_ACCESS
Definition: precomp.h:20
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:3219
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:1234
struct @1587 Msg[]
#define WM_CREATE
Definition: winuser.h:1591
#define HIWORD(l)
Definition: typedefs.h:247
unsigned int ULONG
Definition: retypes.h:1
#define WM_ERASEBKGND
Definition: winuser.h:1608
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 2311 of file desktop.c.

2319 {
2320  NTSTATUS Status;
2321  PDESKTOP pdesk = NULL;
2322  HDESK hDesk;
2323  BOOLEAN Context = FALSE;
2324  UNICODE_STRING ClassName;
2325  LARGE_STRING WindowName;
2326  BOOL NoHooks = FALSE;
2327  PWND pWnd = NULL;
2328  CREATESTRUCTW Cs;
2329  PTHREADINFO ptiCurrent;
2330  PCLS pcls;
2331 
2332  TRACE("Enter IntCreateDesktop\n");
2333 
2335 
2336  ASSERT(phDesktop);
2337  *phDesktop = NULL;
2338 
2339  ptiCurrent = PsGetCurrentThreadWin32Thread();
2340  ASSERT(ptiCurrent);
2342 
2343  /* Turn off hooks when calling any CreateWindowEx from inside win32k */
2344  NoHooks = (ptiCurrent->TIF_flags & TIF_DISABLEHOOKS);
2345  ptiCurrent->TIF_flags |= TIF_DISABLEHOOKS;
2346  ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
2347 
2348  /*
2349  * Try to open already existing desktop
2350  */
2353  AccessMode,
2354  NULL,
2355  dwDesiredAccess,
2356  (PVOID)&Context,
2357  (PHANDLE)&hDesk);
2358  if (!NT_SUCCESS(Status))
2359  {
2360  ERR("ObOpenObjectByName failed to open/create desktop\n");
2361  goto Quit;
2362  }
2363 
2364  /* In case the object was not created (eg if it existed), return now */
2365  if (Context == FALSE)
2366  {
2367  TRACE("IntCreateDesktop opened desktop '%wZ'\n", ObjectAttributes->ObjectName);
2369  goto Quit;
2370  }
2371 
2372  /* Reference the desktop */
2374  0,
2376  KernelMode,
2377  (PVOID*)&pdesk,
2378  NULL);
2379  if (!NT_SUCCESS(Status))
2380  {
2381  ERR("Failed to reference desktop object\n");
2382  goto Quit;
2383  }
2384 
2385  /* Get the desktop window class. The thread desktop does not belong to any desktop
2386  * so the classes created there (including the desktop class) are allocated in the shared heap
2387  * It would cause problems if we used a class that belongs to the caller
2388  */
2389  ClassName.Buffer = WC_DESKTOP;
2390  ClassName.Length = 0;
2391  pcls = IntGetAndReferenceClass(&ClassName, 0, TRUE);
2392  if (pcls == NULL)
2393  {
2394  ASSERT(FALSE);
2396  goto Quit;
2397  }
2398 
2399  RtlZeroMemory(&WindowName, sizeof(WindowName));
2400  RtlZeroMemory(&Cs, sizeof(Cs));
2406  Cs.hInstance = hModClient; // hModuleWin; // Server side winproc!
2407  Cs.lpszName = (LPCWSTR) &WindowName;
2408  Cs.lpszClass = (LPCWSTR) &ClassName;
2409 
2410  /* Use IntCreateWindow instead of co_UserCreateWindowEx because the later expects a thread with a desktop */
2411  pWnd = IntCreateWindow(&Cs, &WindowName, pcls, NULL, NULL, NULL, pdesk, WINVER);
2412  if (pWnd == NULL)
2413  {
2414  ERR("Failed to create desktop window for the new desktop\n");
2416  goto Quit;
2417  }
2418 
2420  pdesk->DesktopWindow = pWnd->head.h;
2421  pdesk->pDeskInfo->spwnd = pWnd;
2422  pWnd->fnid = FNID_DESKTOP;
2423 
2424  ClassName.Buffer = MAKEINTATOM(gpsi->atomSysClass[ICLS_HWNDMESSAGE]);
2425  ClassName.Length = 0;
2426  pcls = IntGetAndReferenceClass(&ClassName, 0, TRUE);
2427  if (pcls == NULL)
2428  {
2429  ASSERT(FALSE);
2431  goto Quit;
2432  }
2433 
2434  RtlZeroMemory(&WindowName, sizeof(WindowName));
2435  RtlZeroMemory(&Cs, sizeof(Cs));
2436  Cs.cx = Cs.cy = 100;
2438  Cs.hInstance = hModClient; // hModuleWin; // Server side winproc!
2439  Cs.lpszName = (LPCWSTR)&WindowName;
2440  Cs.lpszClass = (LPCWSTR)&ClassName;
2441  pWnd = IntCreateWindow(&Cs, &WindowName, pcls, NULL, NULL, NULL, pdesk, WINVER);
2442  if (pWnd == NULL)
2443  {
2444  ERR("Failed to create message window for the new desktop\n");
2446  goto Quit;
2447  }
2448 
2449  pdesk->spwndMessage = pWnd;
2450  pWnd->fnid = FNID_MESSAGEWND;
2451 
2452  /* Now...
2453  if !(WinStaObject->Flags & WSF_NOIO) is (not set) for desktop input output mode (see wiki)
2454  Create Tooltip. Saved in DesktopObject->spwndTooltip.
2455  Tooltip dwExStyle: WS_EX_TOOLWINDOW|WS_EX_TOPMOST
2456  hWndParent are spwndMessage. Use hModuleWin for server side winproc!
2457  The rest is same as message window.
2458  http://msdn.microsoft.com/en-us/library/bb760250(VS.85).aspx
2459  */
2461 
2462 Quit:
2463  if (pdesk != NULL)
2464  {
2465  ObDereferenceObject(pdesk);
2466  }
2467  if (!NT_SUCCESS(Status) && hDesk != NULL)
2468  {
2469  ObCloseHandle(hDesk, AccessMode);
2470  hDesk = NULL;
2471  }
2472  if (!NoHooks)
2473  {
2474  ptiCurrent->TIF_flags &= ~TIF_DISABLEHOOKS;
2475  ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
2476  }
2477 
2478  TRACE("Leave IntCreateDesktop, Status 0x%08lx\n", Status);
2479 
2480  if (NT_SUCCESS(Status))
2481  *phDesktop = hDesk;
2482  else
2484  return Status;
2485 }
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:96
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:834
#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:679
unsigned int BOOL
Definition: ntddk_ex.h:94
#define FNID_DESKTOP
Definition: ntuser.h:832
HWND DesktopWindow
Definition: desktop.h:40
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:395
THRDESKHEAD head
Definition: ntuser.h:665
unsigned char BOOLEAN
Definition: ntuser.h:539
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:2932
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:95
#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:2940
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
struct _WND * spwnd
Definition: ntuser.h:133
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:663
#define WS_POPUP
Definition: pedump.c:616
#define NULL
Definition: types.h:112
BOOL FASTCALL UserIsEnteredExclusive(VOID)
Definition: ntuser.c:229
LPCWSTR lpszClass
Definition: winuser.h:2941
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define TIF_DISABLEHOOKS
Definition: ntuser.h:273
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:1022

Referenced by IntResolveDesktop(), and NtUserCreateDesktop().

◆ IntDeRegisterShellHookWindow()

BOOL IntDeRegisterShellHookWindow ( HWND  hWnd)

Definition at line 1751 of file desktop.c.

1752 {
1754  PDESKTOP Desktop = pti->rpdesk;
1755  PLIST_ENTRY ListEntry;
1756  PSHELL_HOOK_WINDOW Current;
1757 
1758  ListEntry = Desktop->ShellHookWindows.Flink;
1759  while (ListEntry != &Desktop->ShellHookWindows)
1760  {
1761  Current = CONTAINING_RECORD(ListEntry, SHELL_HOOK_WINDOW, ListEntry);
1762  ListEntry = ListEntry->Flink;
1763  if (Current->hWnd == hWnd)
1764  {
1765  RemoveEntryList(&Current->ListEntry);
1766  ExFreePoolWithTag(Current, TAG_WINSTA);
1767  return TRUE;
1768  }
1769  }
1770 
1771  return FALSE;
1772 }
#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:93
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:3101
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:245
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:253
#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:133
#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:3145
#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:2219
#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:89
HDESK hdesk
Definition: win32.h:109
HDESK hdeskStartup
Definition: win32.h:261
#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 1775 of file desktop.c.

1776 {
1777  /* FIXME: Disable until unmapping works in mm */
1778 #if 0
1779  if (Desktop->pheapDesktop != NULL)
1780  {
1781  MmUnmapViewInSessionSpace(Desktop->pheapDesktop);
1782  Desktop->pheapDesktop = NULL;
1783  }
1784 
1785  if (Desktop->hsectionDesktop != NULL)
1786  {
1787  ObDereferenceObject(Desktop->hsectionDesktop);
1788  Desktop->hsectionDesktop = NULL;
1789  }
1790 #endif
1791 }
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 1391 of file desktop.c.

1392 {
1394  PDESKTOP pdo = pti->rpdesk;
1395  if (NULL == pdo)
1396  {
1397  ERR("Thread doesn't have a desktop\n");
1398  return NULL;
1399  }
1400  return pdo->DesktopWindow;
1401 }
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
struct _DESKTOP * rpdesk
Definition: win32.h:93
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 1240 of file desktop.c.

1241 {
1242  NTSTATUS Status;
1243  HDESK hDesk;
1244 
1245  ASSERT(DesktopObject);
1246 
1248  DesktopObject,
1250  NULL,
1251  (PHANDLE)&hDesk))
1252  {
1253  Status = ObOpenObjectByPointer(DesktopObject,
1254  0,
1255  NULL,
1256  0,
1258  UserMode,
1259  (PHANDLE)&hDesk);
1260  if (!NT_SUCCESS(Status))
1261  {
1262  /* Unable to create a handle */
1263  ERR("Unable to create a desktop handle\n");
1264  return NULL;
1265  }
1266  }
1267  else
1268  {
1269  TRACE("Got handle: 0x%p\n", hDesk);
1270  }
1271 
1272  return hDesk;
1273 }
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 1343 of file desktop.c.

1344 {
1345  PDESKTOP pdo = IntGetActiveDesktop();
1346  if (!pdo)
1347  {
1348  TRACE("No active desktop\n");
1349  return NULL;
1350  }
1351  return pdo->DesktopWindow;
1352 }
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:1231

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 1276 of file desktop.c.

1277 {
1278  PDESKTOP pdo = IntGetActiveDesktop();
1279  if (!pdo)
1280  {
1281  TRACE("No active desktop\n");
1282  return(NULL);
1283  }
1285 }
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:1231

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 1367 of file desktop.c.

1368 {
1369  PDESKTOP pdo = IntGetActiveDesktop();
1370 
1371  if (!pdo)
1372  {
1373  TRACE("No active desktop\n");
1374  return NULL;
1375  }
1376  return pdo->spwndMessage->head.h;
1377 }
THRDESKHEAD head
Definition: ntuser.h:665
#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:1231

Referenced by NtUserFindWindowEx(), and NtUserSetParent().

◆ IntGetThreadDesktopWindow()

PWND FASTCALL IntGetThreadDesktopWindow ( PTHREADINFO  pti)

Definition at line 1328 of file desktop.c.

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

Referenced by ActivateOtherWindowMin().

◆ IntHideDesktop()

NTSTATUS FASTCALL IntHideDesktop ( PDESKTOP  Desktop)

Definition at line 1602 of file desktop.c.

1603 {
1604  PWND DesktopWnd;
1605 
1606  DesktopWnd = IntGetWindowObject(Desktop->DesktopWindow);
1607  if (! DesktopWnd)
1608  {
1610  }
1611  DesktopWnd->style &= ~WS_VISIBLE;
1612 
1613  return STATUS_SUCCESS;
1614 }
#define ERROR_INVALID_WINDOW_HANDLE
Definition: winerror.h:881
Definition: ntuser.h:663
#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:676

Referenced by IntEndDesktopGraphics(), and NtUserSwitchDesktop().

◆ IntMapDesktopView()

static NTSTATUS IntMapDesktopView ( IN PDESKTOP  pdesk)
static

Definition at line 3145 of file desktop.c.

3146 {
3147  PPROCESSINFO ppi;
3148  PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
3149  PVOID UserBase = NULL;
3150  SIZE_T ViewSize = 0;
3152  NTSTATUS Status;
3153 
3154  TRACE("IntMapDesktopView called for desktop object 0x%p\n", pdesk);
3155 
3157 
3158  /*
3159  * Find out if another thread already mapped the desktop heap.
3160  * Start the search at the next mapping: skip the first entry
3161  * as it must be the global user heap mapping.
3162  */
3163  PrevLink = &ppi->HeapMappings.Next;
3164  HeapMapping = *PrevLink;
3165  while (HeapMapping != NULL)
3166  {
3167  if (HeapMapping->KernelMapping == (PVOID)pdesk->pheapDesktop)
3168  {
3169  HeapMapping->Count++;
3170  return STATUS_SUCCESS;
3171  }
3172 
3173  PrevLink = &HeapMapping->Next;
3174  HeapMapping = HeapMapping->Next;
3175  }
3176 
3177  /* We're the first, map the heap */
3178  Offset.QuadPart = 0;
3179  Status = MmMapViewOfSection(pdesk->hsectionDesktop,
3181  &UserBase,
3182  0,
3183  0,
3184  &Offset,
3185  &ViewSize,
3186  ViewUnmap,
3187  SEC_NO_CHANGE,
3188  PAGE_EXECUTE_READ); /* Would prefer PAGE_READONLY, but thanks to RTL heaps... */
3189  if (!NT_SUCCESS(Status))
3190  {
3191  ERR("Failed to map desktop\n");
3192  return Status;
3193  }
3194 
3195  TRACE("ppi 0x%p mapped heap of desktop 0x%p\n", ppi, pdesk);
3196 
3197  /* Add the mapping */
3198  HeapMapping = UserHeapAlloc(sizeof(*HeapMapping));
3199  if (HeapMapping == NULL)
3200  {
3202  ERR("UserHeapAlloc() failed!\n");
3203  return STATUS_NO_MEMORY;
3204  }
3205 
3206  HeapMapping->Next = NULL;
3207  HeapMapping->KernelMapping = (PVOID)pdesk->pheapDesktop;
3208  HeapMapping->UserMapping = UserBase;
3209  HeapMapping->Limit = ViewSize;
3210  HeapMapping->Count = 1;
3211  *PrevLink = HeapMapping;
3212 
3213  ObReferenceObject(pdesk);
3214 
3215  return STATUS_SUCCESS;
3216 }
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:3906
W32HEAP_USER_MAPPING HeapMappings
Definition: win32.h:288
void * PVOID
Definition: retypes.h:9
Status
Definition: gdiplustypes.h:24
ULONG_PTR Limit
Definition: win32.h:204
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:201

Referenced by IntDesktopObjectOpen(), and IntSetThreadDesktop().

◆ IntPaintDesktop()

BOOL FASTCALL IntPaintDesktop ( HDC  hDC)

Definition at line 1794 of file desktop.c.

1795 {
1796  static WCHAR s_wszSafeMode[] = L"Safe Mode"; // FIXME: Localize!
1797 
1798  RECTL Rect;
1799  HBRUSH DesktopBrush, PreviousBrush;
1800  HWND hWndDesktop;
1801  BOOL doPatBlt = TRUE;
1802  PWND WndDesktop;
1803  BOOLEAN InSafeMode;
1804 
1805  if (GdiGetClipBox(hDC, &Rect) == ERROR)
1806  return FALSE;
1807 
1808  hWndDesktop = IntGetDesktopWindow(); // rpdesk->DesktopWindow;
1809 
1810  WndDesktop = UserGetWindowObject(hWndDesktop); // rpdesk->pDeskInfo->spwnd;
1811  if (!WndDesktop)
1812  return FALSE;
1813 
1814  /* Retrieve the current SafeMode state */
1815  InSafeMode = (UserGetSystemMetrics(SM_CLEANBOOT) != 0); // gpsi->aiSysMet[SM_CLEANBOOT];
1816 
1817  if (!InSafeMode)
1818  {
1819  DesktopBrush = (HBRUSH)WndDesktop->pcls->hbrBackground;
1820 
1821  /*
1822  * Paint desktop background
1823  */
1824  if (gspv.hbmWallpaper != NULL)
1825  {
1826  SIZE sz;
1827  int x, y;
1828  int scaledWidth, scaledHeight;
1829  int wallpaperX, wallpaperY, wallpaperWidth, wallpaperHeight;
1830  HDC hWallpaperDC;
1831 
1832  sz.cx = WndDesktop->rcWindow.right - WndDesktop->rcWindow.left;
1833  sz.cy = WndDesktop->rcWindow.bottom - WndDesktop->rcWindow.top;
1834 
1835  if (gspv.WallpaperMode == wmFit ||
1837  {
1838  int scaleNum, scaleDen;
1839 
1840  // Precision improvement over ((sz.cx / gspv.cxWallpaper) > (sz.cy / gspv.cyWallpaper))
1841  if ((sz.cx * gspv.cyWallpaper) > (sz.cy * gspv.cxWallpaper))
1842  {
1843  if (gspv.WallpaperMode == wmFit)
1844  {
1845  scaleNum = sz.cy;
1846  scaleDen = gspv.cyWallpaper;
1847  }
1848  else
1849  {
1850  scaleNum = sz.cx;
1851  scaleDen = gspv.cxWallpaper;
1852  }
1853  }
1854  else
1855  {
1856  if (gspv.WallpaperMode == wmFit)
1857  {
1858  scaleNum = sz.cx;
1859  scaleDen = gspv.cxWallpaper;
1860  }
1861  else
1862  {
1863  scaleNum = sz.cy;
1864  scaleDen = gspv.cyWallpaper;
1865  }
1866  }
1867 
1868  scaledWidth = EngMulDiv(gspv.cxWallpaper, scaleNum, scaleDen);
1869  scaledHeight = EngMulDiv(gspv.cyWallpaper, scaleNum, scaleDen);
1870 
1871  if (gspv.WallpaperMode == wmFill)
1872  {
1873  wallpaperX = (((scaledWidth - sz.cx) * gspv.cxWallpaper) / (2 * scaledWidth));
1874  wallpaperY = (((scaledHeight - sz.cy) * gspv.cyWallpaper) / (2 * scaledHeight));
1875 
1876  wallpaperWidth = (sz.cx * gspv.cxWallpaper) / scaledWidth;
1877  wallpaperHeight = (sz.cy * gspv.cyWallpaper) / scaledHeight;
1878  }
1879  }
1880 
1881  if (gspv.WallpaperMode == wmStretch ||
1882  gspv.WallpaperMode == wmTile ||
1884  {
1885  x = 0;
1886  y = 0;
1887  }
1888  else if (gspv.WallpaperMode == wmFit)
1889  {
1890  x = (sz.cx - scaledWidth) / 2;
1891  y = (sz.cy - scaledHeight) / 2;
1892  }
1893  else
1894  {
1895  /* Find the upper left corner, can be negative if the bitmap is bigger than the screen */
1896  x = (sz.cx / 2) - (gspv.cxWallpaper / 2);
1897  y = (sz.cy / 2) - (gspv.cyWallpaper / 2);
1898  }
1899 
1900  hWallpaperDC = NtGdiCreateCompatibleDC(hDC);
1901  if (hWallpaperDC != NULL)
1902  {
1903  HBITMAP hOldBitmap;
1904 
1905  /* Fill in the area that the bitmap is not going to cover */
1906  if (x > 0 || y > 0)
1907  {
1908  /* FIXME: Clip out the bitmap
1909  can be replaced with "NtGdiPatBlt(hDC, x, y, gspv.cxWallpaper, gspv.cyWallpaper, PATCOPY | DSTINVERT);"
1910  once we support DSTINVERT */
1911  PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
1912  NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
1913  NtGdiSelectBrush(hDC, PreviousBrush);
1914  }
1915 
1916  /* Do not fill the background after it is painted no matter the size of the picture */
1917  doPatBlt = FALSE;
1918 
1919  hOldBitmap = NtGdiSelectBitmap(hWallpaperDC, gspv.hbmWallpaper);
1920 
1921  if (gspv.WallpaperMode == wmStretch)
1922  {
1923  if (Rect.right && Rect.bottom)
1925  x,
1926  y,
1927  sz.cx,
1928  sz.cy,
1929  hWallpaperDC,
1930  0,
1931  0,
1932  gspv.cxWallpaper,
1933  gspv.cyWallpaper,
1934  SRCCOPY,
1935  0);
1936  }
1937  else if (gspv.WallpaperMode == wmTile)
1938  {
1939  /* Paint the bitmap across the screen then down */
1940  for (y = 0; y < Rect.bottom; y += gspv.cyWallpaper)
1941  {
1942  for (x = 0; x < Rect.right; x += gspv.cxWallpaper)
1943  {
1944  NtGdiBitBlt(hDC,
1945  x,
1946  y,
1947  gspv.cxWallpaper,
1948  gspv.cyWallpaper,
1949  hWallpaperDC,
1950  0,
1951  0,
1952  SRCCOPY,
1953  0,
1954  0);
1955  }
1956  }
1957  }
1958  else if (gspv.WallpaperMode == wmFit)
1959  {
1960  if (Rect.right && Rect.bottom)
1961  {
1963  x,
1964  y,
1965  scaledWidth,
1966  scaledHeight,
1967  hWallpaperDC,
1968  0,
1969  0,
1970  gspv.cxWallpaper,
1971  gspv.cyWallpaper,
1972  SRCCOPY,
1973  0);
1974  }
1975  }
1976  else if (gspv.WallpaperMode == wmFill)
1977  {
1978  if (Rect.right && Rect.bottom)
1979  {
1981  x,
1982  y,
1983  sz.cx,
1984  sz.cy,
1985  hWallpaperDC,
1986  wallpaperX,
1987  wallpaperY,
1988  wallpaperWidth,
1989  wallpaperHeight,
1990  SRCCOPY,
1991  0);
1992  }
1993  }
1994  else
1995  {
1996  NtGdiBitBlt(hDC,
1997  x,
1998  y,
1999  gspv.cxWallpaper,
2000  gspv.cyWallpaper,
2001  hWallpaperDC,
2002  0,
2003  0,
2004  SRCCOPY,
2005  0,
2006  0);
2007  }
2008  NtGdiSelectBitmap(hWallpaperDC, hOldBitmap);
2009  NtGdiDeleteObjectApp(hWallpaperDC);
2010  }
2011  }
2012  }
2013  else
2014  {
2015  /* Black desktop background in Safe Mode */
2016  DesktopBrush = StockObjects[BLACK_BRUSH];
2017  }
2018 
2019  /* Background is set to none, clear the screen */
2020  if (doPatBlt)
2021  {
2022  PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
2023  NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
2024  NtGdiSelectBrush(hDC, PreviousBrush);
2025  }
2026 
2027  /*
2028  * Display the system version on the desktop background
2029  */
2030  if (InSafeMode || g_AlwaysDisplayVersion || g_PaintDesktopVersion)
2031  {
2032  NTSTATUS Status;
2033  static WCHAR wszzVersion[1024] = L"\0";
2034 
2035  /* Only used in normal mode */
2036  // We expect at most 4 strings (3 for version, 1 for optional NtSystemRoot)
2037  static POLYTEXTW VerStrs[4] = {{0},{0},{0},{0}};
2038  INT i = 0;
2039  SIZE_T len;
2040 
2041  HFONT hFont1 = NULL, hFont2 = NULL, hOldFont = NULL;
2042  COLORREF crText, color_old;
2043  UINT align_old;
2044  INT mode_old;
2045  PDC pdc;
2046 
2047  if (!UserSystemParametersInfo(SPI_GETWORKAREA, 0, &Rect, 0))
2048  {
2049  Rect.left = Rect.top = 0;
2052  }
2053  else
2054  {
2055  RECTL_vOffsetRect(&Rect, -Rect.left, -Rect.top);
2056  }
2057 
2058  /*
2059  * Set up the fonts (otherwise use default ones)
2060  */
2061 
2062  /* Font for the principal version string */
2063  hFont1 = GreCreateFontIndirectW(&gspv.ncm.lfCaptionFont);
2064  /* Font for the secondary version strings */
2065  hFont2 = GreCreateFontIndirectW(&gspv.ncm.lfMenuFont);
2066 
2067  if (hFont1)
2068  hOldFont = NtGdiSelectFont(hDC, hFont1);
2069 
2070  if (gspv.hbmWallpaper == NULL)
2071  {
2072  /* Retrieve the brush fill colour */
2073  // TODO: The following code constitutes "GreGetBrushColor".
2074  PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
2075  pdc = DC_LockDc(hDC);
2076  if (pdc)
2077  {
2078  crText = pdc->eboFill.ulRGBColor;
2079  DC_UnlockDc(pdc);
2080  }
2081  else
2082  {
2083  crText = RGB(0, 0, 0);
2084  }
2085  NtGdiSelectBrush(hDC, PreviousBrush);
2086 
2087  /* Adjust text colour according to the brush */
2088  if (GetRValue(crText) + GetGValue(crText) + GetBValue(crText) > 128 * 3)
2089  crText = RGB(0, 0, 0);
2090  else
2091  crText = RGB(255, 255, 255);
2092  }
2093  else
2094  {
2095  /* Always use white when the text is displayed on top of a wallpaper */
2096  crText = RGB(255, 255, 255);
2097  }
2098 
2099  color_old = IntGdiSetTextColor(hDC, crText);
2100  align_old = IntGdiSetTextAlign(hDC, TA_RIGHT);
2101  mode_old = IntGdiSetBkMode(hDC, TRANSPARENT);
2102 
2103  /* Display the system version information */
2104  if (!*wszzVersion)
2105  {
2106  Status = GetSystemVersionString(wszzVersion,
2107  ARRAYSIZE(wszzVersion),
2108  InSafeMode,
2110  if (!InSafeMode && NT_SUCCESS(Status) && *wszzVersion)
2111  {
2112  PWCHAR pstr = wszzVersion;
2113  for (i = 0; (i < ARRAYSIZE(VerStrs)) && *pstr; ++i)
2114  {
2115  VerStrs[i].n = lstrlenW(pstr);
2116  VerStrs[i].lpstr = pstr;
2117  pstr += (VerStrs[i].n + 1);
2118  }
2119  }
2120  }
2121  else
2122  {
2124  }
2125  if (NT_SUCCESS(Status) && *wszzVersion)
2126  {
2127  if (!InSafeMode)
2128  {
2129  SIZE Size = {0, 0};
2130  LONG TotalHeight = 0;
2131 
2132  /* Normal Mode: multiple version information text separated by newlines */
2134 
2135  /* Compute the heights of the strings */
2136  if (hFont1) NtGdiSelectFont(hDC, hFont1);
2137  for (i = 0; i < ARRAYSIZE(VerStrs); ++i)
2138  {
2139  if (!VerStrs[i].lpstr || !*VerStrs[i].lpstr || (VerStrs[i].n == 0))
2140  break;
2141 
2142  GreGetTextExtentW(hDC, VerStrs[i].lpstr, VerStrs[i].n, &Size, 1);
2143  VerStrs[i].y = Size.cy; // Store the string height
2144  TotalHeight += Size.cy;
2145 
2146  /* While the first string was using hFont1, all the others use hFont2 */
2147  if (hFont2) NtGdiSelectFont(hDC, hFont2);
2148  }
2149  /* The total height must not exceed the screen height */
2150  TotalHeight = min(TotalHeight, Rect.bottom);
2151 
2152  /* Display the strings */
2153  if (hFont1) NtGdiSelectFont(hDC, hFont1);
2154  for (i = 0; i < ARRAYSIZE(VerStrs); ++i)
2155  {
2156  if (!VerStrs[i].lpstr || !*VerStrs[i].lpstr || (VerStrs[i].n == 0))
2157  break;
2158 
2159  TotalHeight -= VerStrs[i].y;
2161  Rect.right - 5,
2162  Rect.bottom - TotalHeight - 5,
2163  0, NULL,
2164  VerStrs[i].lpstr,
2165  VerStrs[i].n,
2166  NULL, 0);
2167 
2168  /* While the first string was using hFont1, all the others use hFont2 */
2169  if (hFont2) NtGdiSelectFont(hDC, hFont2);
2170  }
2171  }
2172  else
2173  {
2174  if (hFont1) NtGdiSelectFont(hDC, hFont1);
2175 
2176  /* Safe Mode: single version information text in top center */
2177  len = wcslen(wszzVersion);
2178 
2180  GreExtTextOutW(hDC, (Rect.right + Rect.left)/2, Rect.top + 3, 0, NULL, wszzVersion, len, NULL, 0);
2181  }
2182  }
2183 
2184  if (InSafeMode)
2185  {
2186  if (hFont1) NtGdiSelectFont(hDC, hFont1);
2187 
2188  /* Print Safe Mode text in corners */
2189  len = wcslen(s_wszSafeMode);
2190 
2192  GreExtTextOutW(hDC, Rect.left, Rect.top + 3, 0, NULL, s_wszSafeMode, len, NULL, 0);
2194  GreExtTextOutW(hDC, Rect.right, Rect.top + 3, 0, NULL, s_wszSafeMode, len, NULL, 0);
2196  GreExtTextOutW(hDC, Rect.left, Rect.bottom - 5, 0, NULL, s_wszSafeMode, len, NULL, 0);
2198  GreExtTextOutW(hDC, Rect.right, Rect.bottom - 5, 0, NULL, s_wszSafeMode, len, NULL, 0);
2199  }
2200 
2201  IntGdiSetBkMode(hDC, mode_old);
2202  IntGdiSetTextAlign(hDC, align_old);
2203  IntGdiSetTextColor(hDC, color_old);
2204 
2205  if (hFont2)
2206  GreDeleteObject(hFont2);
2207 
2208  if (hFont1)
2209  {
2210  NtGdiSelectFont(hDC, hOldFont);
2211  GreDeleteObject(hFont1);
2212  }
2213  }
2214 
2215  return TRUE;
2216 }
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:2563
LPCWSTR lpstr
Definition: wingdi.h:2564
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:984
#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:932
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:930
#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:950
unsigned char BOOLEAN
#define TA_BOTTOM
Definition: wingdi.h:929
__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:896
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:180
#define TA_RIGHT
Definition: wingdi.h:933
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:561
__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:686
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
#define PATCOPY
Definition: wingdi.h:335
Definition: ntuser.h:663
FORCEINLINE VOID RECTL_vOffsetRect(_Inout_ RECTL *prcl, _In_ INT cx, _In_ INT cy)
Definition: rect.h:31
HWND FASTCALL IntGetDesktopWindow(VOID)
Definition: desktop.c:1343
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:931
#define STATUS_SUCCESS
Definition: shellext.h:65
LONG cy
Definition: windef.h:335
ULONG cxWallpaper
Definition: sysparams.h:143
#define SRCCOPY
Definition: wingdi.h:333
struct Rect Rect
WALLPAPER_MODE WallpaperMode
Definition: sysparams.h:144
BOOL g_PaintDesktopVersion
Definition: sysparams.c:19
PCLS pcls
Definition: ntuser.h:690

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

◆ IntRegisterShellHookWindow()

BOOL IntRegisterShellHookWindow ( HWND  hWnd)

Definition at line 1719 of file desktop.c.

1720 {
1722  PDESKTOP Desktop = pti->rpdesk;
1724 
1725  TRACE("IntRegisterShellHookWindow\n");
1726 
1727  /* First deregister the window, so we can be sure it's never twice in the
1728  * list.
1729  */
1731 
1733  sizeof(SHELL_HOOK_WINDOW),
1734  TAG_WINSTA);
1735 
1736  if (!Entry)
1737  return FALSE;
1738 
1739  Entry->hWnd = hWnd;
1740 
1741  InsertTailList(&Desktop->ShellHookWindows, &Entry->ListEntry);
1742 
1743  return TRUE;
1744 }
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:93
#define FALSE
Definition: types.h:117
#define TRACE(s)
Definition: solgame.cpp:4
BOOL IntDeRegisterShellHookWindow(HWND hWnd)
Definition: desktop.c:1751
#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 
565 
566  ASSERT(phWinSta);
567  ASSERT(phDesktop);
568  ASSERT(DesktopPath);
569 
570  *phWinSta = NULL;
571  *phDesktop = NULL;
572 
574  /* ppi is typically NULL for console applications that connect to Win32 USER */
575  if (!ppi) TRACE("IntResolveDesktop: ppi is NULL!\n");
576 
577  if (ppi && ppi->hwinsta != NULL && ppi->hdeskStartup != NULL)
578  {
579  /*
580  * If this process is the current one, just return the cached handles.
581  * Otherwise, open the window station and desktop objects.
582  */
583  if (Process == PsGetCurrentProcess())
584  {
585  hWinSta = ppi->hwinsta;
586  hDesktop = ppi->hdeskStartup;
587  }
588  else
589  {
591  0,
592  NULL,
595  UserMode,
596  (PHANDLE)&hWinSta);
597  if (!NT_SUCCESS(Status))
598  {
599  ERR("IntResolveDesktop: Could not reference window station 0x%p\n", ppi->prpwinsta);
601  return Status;
602  }
603 
605  0,
606  NULL,
609  UserMode,
610  (PHANDLE)&hDesktop);
611  if (!NT_SUCCESS(Status))
612  {
613  ERR("IntResolveDesktop: Could not reference desktop 0x%p\n", ppi->rpdeskStartup);
614  ObCloseHandle(hWinSta, UserMode);
616  return Status;
617  }
618  }
619 
620  *phWinSta = hWinSta;
621  *phDesktop = hDesktop;
622  return STATUS_SUCCESS;
623  }
624 
625  /* We will by default use the default window station and desktop */
626  RtlInitEmptyUnicodeString(&WinStaName, NULL, 0);
627  RtlInitEmptyUnicodeString(&DesktopName, NULL, 0);
628 
629  /*
630  * Parse the desktop path string which can be of the form "WinSta\Desktop"
631  * or just "Desktop". In the latter case we use the default window station
632  * on which the process is attached to (or if none, "WinSta0").
633  */
634  if (DesktopPath->Buffer != NULL && DesktopPath->Length > sizeof(WCHAR))
635  {
636  DesktopName = *DesktopPath;
637 
638  /* Find the separator */
639  while (DesktopName.Length > 0 && *DesktopName.Buffer &&
640  *DesktopName.Buffer != OBJ_NAME_PATH_SEPARATOR)
641  {
642  DesktopName.Buffer++;
643  DesktopName.Length -= sizeof(WCHAR);
644  DesktopName.MaximumLength -= sizeof(WCHAR);
645  }
646  if (DesktopName.Length > 0)
647  {
648  RtlInitEmptyUnicodeString(&WinStaName, DesktopPath->Buffer,
649  DesktopPath->Length - DesktopName.Length);
650  // (USHORT)((ULONG_PTR)DesktopName.Buffer - (ULONG_PTR)DesktopPath->Buffer);
651  WinStaName.Length = WinStaName.MaximumLength;
652 
653  /* Skip the separator */
654  DesktopName.Buffer++;
655  DesktopName.Length -= sizeof(WCHAR);
656  DesktopName.MaximumLength -= sizeof(WCHAR);
657  }
658  else
659  {
660  RtlInitEmptyUnicodeString(&WinStaName, NULL, 0);
661  DesktopName = *DesktopPath;
662  }
663  }
664 
665  TRACE("IntResolveDesktop: WinStaName:'%wZ' ; DesktopName:'%wZ'\n", &WinStaName, &DesktopName);
666 
667  /* Retrieve the process LUID */
668  Status = GetProcessLuid(NULL, Process, &ProcessLuid);
669  if (!NT_SUCCESS(Status))
670  {
671  ERR("IntResolveDesktop: Failed to retrieve the process LUID, Status 0x%08lx\n", Status);
673  return Status;
674  }
675 
676  /*
677  * If this process is not the current one, obtain a temporary handle
678  * to it so that we can perform handles duplication later.
679  */
680  if (Process != PsGetCurrentProcess())
681  {
684  NULL,
685  0,
686  *PsProcessType,
687  KernelMode,
688  &hProcess);
689  if (!NT_SUCCESS(Status))
690  {
691  ERR("IntResolveDesktop: Failed to obtain a handle to process 0x%p, Status 0x%08lx\n", Process, Status);
693  return Status;
694  }
695  ASSERT(hProcess);
696  }
697 
698  /*
699  * If no window station has been specified, search the process handle table
700  * for inherited window station handles, otherwise use a default one.
701  */
702  if (WinStaName.Buffer == NULL)
703  {
704  /*
705  * We want to find a suitable default window station.
706  * For applications that can be interactive, i.e. that have allowed
707  * access to the single interactive window station on the system,
708  * the default window station is 'WinSta0'.
709  * For applications that cannot be interactive, i.e. that do not have
710  * access to 'WinSta0' (e.g. non-interactive services), the default
711  * window station is 'Service-0xXXXX-YYYY$' (created if needed).
712  * Precedence will however be taken by any inherited window station
713  * that possesses the required interactivity property.
714  */
715  bUseDefaultWinSta = TRUE;
716 
717  /*
718  * Use the default 'WinSta0' window station. Whether we should
719  * use 'Service-0xXXXX-YYYY$' instead will be determined later.
720  */
721  // RtlInitUnicodeString(&WinStaName, L"WinSta0");
722  WinStaName = WinSta0Name;
723 
725  NULL,
727  NULL,
728  (PHANDLE)&hWinSta))
729  {
730  TRACE("IntResolveDesktop: Inherited window station is: 0x%p\n", hWinSta);
731  }
732  }
733 
734  /*
735  * If no desktop has been specified, search the process handle table
736  * for inherited desktop handles, otherwise use the Default desktop.
737  * Note that the inherited desktop that we may use, may not belong
738  * to the window station we will connect to.
739  */
740  if (DesktopName.Buffer == NULL)
741  {
742  /* Use a default desktop name */
743  RtlInitUnicodeString(&DesktopName, L"Default");
744 
746  NULL,
748  NULL,
749  (PHANDLE)&hDesktop))
750  {
751  TRACE("IntResolveDesktop: Inherited desktop is: 0x%p\n", hDesktop);
752  }
753  }
754 
755 
756  /*
757  * We are going to open either a window station or a desktop.
758  * Even if this operation is done from kernel-mode, we should
759  * "emulate" an opening from user-mode (i.e. using an ObjectAttributes
760  * allocated in user-mode, with AccessMode == UserMode) for the
761  * Object Manager to perform proper access validation to the
762  * window station or desktop.
763  */
764 
765  /*
766  * Estimate the maximum size needed for the window station name
767  * and desktop name to be given to ObjectAttributes->ObjectName.
768  */
769  StrSize = 0;
770 
771  /* Window station name */
772  MemSize = _scwprintf(L"Service-0x%x-%x$", MAXULONG, MAXULONG) * sizeof(WCHAR);
774  + max(WinStaName.Length, MemSize) + sizeof(UNICODE_NULL);
775  if (MemSize > MAXUSHORT)
776  {
777  ERR("IntResolveDesktop: Window station name length is too long.\n");
779  goto Quit;
780  }
781  StrSize = max(StrSize, (USHORT)MemSize);
782 
783  /* Desktop name */
784  MemSize = max(DesktopName.Length + sizeof(UNICODE_NULL), sizeof(L"Default"));
785  StrSize = max(StrSize, (USHORT)MemSize);
786 
787  /* Size for the OBJECT_ATTRIBUTES */
788  MemSize = ALIGN_UP(sizeof(OBJECT_ATTRIBUTES), sizeof(PVOID));
789 
790  /* Add the string size */
791  MemSize += ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID));
792  MemSize += StrSize;
793 
794  /* Allocate the memory in user-mode */
795  Status = ZwAllocateVirtualMemory(ZwCurrentProcess(),
797  0,
798  &MemSize,
799  MEM_COMMIT,
801  if (!NT_SUCCESS(Status))
802  {
803  ERR("ZwAllocateVirtualMemory() failed, Status 0x%08lx\n", Status);
804  goto Quit;
805  }
806 
808  ALIGN_UP(sizeof(OBJECT_ATTRIBUTES), sizeof(PVOID)));
809 
810  RtlInitEmptyUnicodeString(ObjectName,
812  ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID))),
813  StrSize);
814 
815 
816  /* If we got an inherited window station handle, duplicate and use it */
817  if (hWinSta)
818  {
819  ASSERT(bUseDefaultWinSta);
820 
821  /* Duplicate the handle if it belongs to another process than the current one */
822  if (Process != PsGetCurrentProcess())
823  {
824  ASSERT(hProcess);
825  Status = ZwDuplicateObject(hProcess,
826  hWinSta,
828  (PHANDLE)&hWinStaDup,
829  0,
830  0,
832  if (!NT_SUCCESS(Status))
833  {
834  ERR("IntResolveDesktop: Failed to duplicate the window station handle, Status 0x%08lx\n", Status);
835  /* We will use a default window station */
836  hWinSta = NULL;
837  }
838  else
839  {
840  hWinSta = hWinStaDup;
841  }
842  }
843  }
844 
845  /*
846  * If we have an inherited window station, check whether
847  * it is interactive and remember that for later.
848  */
849  if (hWinSta)
850  {
851  ASSERT(bUseDefaultWinSta);
852 
853  /* Reference the inherited window station */
855  0,
857  KernelMode,
858  (PVOID*)&WinStaObject,
859  NULL);
860  if (!NT_SUCCESS(Status))
861  {
862  ERR("Failed to reference the inherited window station, Status 0x%08lx\n", Status);
863  /* We will use a default window station */
864  if (hWinStaDup)
865  {
866  ASSERT(hWinSta == hWinStaDup);
867  ObCloseHandle(hWinStaDup, UserMode);
868  hWinStaDup = NULL;
869  }
870  hWinSta = NULL;
871  }
872  else
873  {
874  ERR("Process LUID is: 0x%x-%x, inherited window station LUID is: 0x%x-%x\n",
875  ProcessLuid.HighPart, ProcessLuid.LowPart,
876  WinStaObject->luidUser.HighPart, WinStaObject->luidUser.LowPart);
877 
878  /* Check whether this window station is interactive, and remember it for later */
879  bInteractive = !(WinStaObject->Flags & WSS_NOIO);
880 
881  /* Dereference the window station */
882  ObDereferenceObject(WinStaObject);
883  }
884  }
885 
886  /* Build a valid window station name */
888  ObjectName->MaximumLength,
889  L"%wZ\\%wZ",
891  &WinStaName);
892  if (!NT_SUCCESS(Status))
893  {
894  ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
895  goto Quit;
896  }
897  ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
898 
899  TRACE("Parsed initial window station: '%wZ'\n", ObjectName);
900 
901  /* Try to open the window station */
903  ObjectName,
905  NULL,
906  NULL);
907  if (bInherit)
908  ObjectAttributes->Attributes |= OBJ_INHERIT;
909 
912  UserMode,
913  NULL,
915  NULL,
916  (PHANDLE)&hTempWinSta);
917  if (!NT_SUCCESS(Status))
918  {
919  ERR("Failed to open the window station '%wZ', Status 0x%08lx\n", ObjectName, Status);
920  }
921  else
922  {
923  //
924  // FIXME TODO: Perform a window station access check!!
925  // If we fail AND bUseDefaultWinSta == FALSE we just quit.
926  //
927 
928  /*
929  * Check whether we are opening the (single) interactive
930  * window station, and if so, perform an access check.
931  */
932  /* Check whether we are allowed to perform interactions */
933  if (RtlEqualUnicodeString(&WinStaName, &WinSta0Name, TRUE))
934  {
935  LUID SystemLuid = SYSTEM_LUID;
936 
937  /* Interactive window station: check for user LUID */
938  WinStaObject = InputWindowStation;
939 
941 
942  // TODO: Check also that we compare wrt. window station WinSta0
943  // which is the only one that can be interactive on the system.
944  if (((!bUseDefaultWinSta || bInherit) && RtlEqualLuid(&ProcessLuid, &SystemLuid)) ||
945  RtlEqualLuid(&ProcessLuid, &WinStaObject->luidUser))
946  {
947  /* We are interactive on this window station */
948  bAccessAllowed = TRUE;
950  }
951  }
952  else
953  {
954  /* Non-interactive window station: we have access since we were able to open it */
955  bAccessAllowed = TRUE;
957  }
958  }
959 
960  /* If we failed, bail out if we were not trying to open the default window station */
961  if (!NT_SUCCESS(Status) && !bUseDefaultWinSta) // if (!bAccessAllowed)
962  goto Quit;
963 
964  if (/* bAccessAllowed && */ bInteractive || !bAccessAllowed)
965  {
966  /*
967  * Close WinSta0 if the inherited window station is interactive so that
968  * we can use it, or we do not have access to the interactive WinSta0.
969  */
970  ObCloseHandle(hTempWinSta, UserMode);
971  hTempWinSta = NULL;
972  }
973  if (bInteractive == bAccessAllowed)
974  {
975  /* Keep using the inherited window station */
976  NOTHING;
977  }
978  else // if (bInteractive != bAccessAllowed)
979  {
980  /*
981  * Close the inherited window station, we will either keep using
982  * the interactive WinSta0, or use Service-0xXXXX-YYYY$.
983  */
984  if (hWinStaDup)
985  {
986  ASSERT(hWinSta == hWinStaDup);
987  ObCloseHandle(hWinStaDup, UserMode);
988  hWinStaDup = NULL;
989  }
990  hWinSta = hTempWinSta; // hTempWinSta is NULL in case bAccessAllowed == FALSE
991  }
992 
993  if (bUseDefaultWinSta)
994  {
995  if (hWinSta == NULL && !bInteractive)
996  {
997  /* Build a valid window station name from the LUID */
999  ObjectName->MaximumLength,
1000  L"%wZ\\Service-0x%x-%x$",
1002  ProcessLuid.HighPart,
1003  ProcessLuid.LowPart);
1004  if (!NT_SUCCESS(Status))
1005  {
1006  ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
1007  goto Quit;
1008  }
1009  ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
1010 
1011  /*
1012  * Create or open the non-interactive window station.
1013  * NOTE: The non-interactive window station handle is never inheritable.
1014  */
1015  // FIXME: Set security!
1017  ObjectName,
1019  NULL,
1020  NULL);
1021 
1022  Status = IntCreateWindowStation(&hWinSta,
1024  UserMode,
1025  KernelMode,
1027  0, 0, 0, 0, 0);
1028  if (!NT_SUCCESS(Status))
1029  {
1030  ASSERT(hWinSta == NULL);
1031  ERR("Failed to create or open the non-interactive window station '%wZ', Status 0x%08lx\n",
1032  ObjectName, Status);
1033  goto Quit;
1034  }
1035 
1036  //
1037  // FIXME: We might not need to always create or open the "Default"
1038  // desktop on the Service-0xXXXX-YYYY$ window station; we may need
1039  // to use another one....
1040  //
1041 
1042  /* Create or open the Default desktop on the window station */
1044  ObjectName->MaximumLength,
1045  L"Default");
1046  if (!NT_SUCCESS(Status))
1047  {
1048  ERR("Impossible to build a valid desktop name, Status 0x%08lx\n", Status);
1049  goto Quit;
1050  }
1051  ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
1052 
1053  /* NOTE: The non-interactive desktop handle is never inheritable. */
1054  // FIXME: Set security!
1056  ObjectName,
1058  hWinSta,
1059  NULL);
1060 
1061  Status = IntCreateDesktop(&hDesktop,
1063  UserMode,
1064  NULL,
1065  NULL,
1066  0,
1067  MAXIMUM_ALLOWED);
1068  if (!NT_SUCCESS(Status))
1069  {
1070  ASSERT(hDesktop == NULL);
1071  ERR("Failed to create or open the desktop '%wZ' on window station 0x%p, Status 0x%08lx\n",
1072  ObjectName, hWinSta, Status);
1073  }
1074 
1075  goto Quit;
1076  }
1077 /*
1078  if (hWinSta == NULL)
1079  {
1080  Status = STATUS_UNSUCCESSFUL;
1081  goto Quit;
1082  }
1083 */
1084  }
1085 
1086  /*
1087  * If we got an inherited desktop handle, duplicate and use it,
1088  * otherwise open a new desktop.
1089  */
1090  if (hDesktop != NULL)
1091  {
1092  /* Duplicate the handle if it belongs to another process than the current one */
1093  if (Process != PsGetCurrentProcess())
1094  {
1095  ASSERT(hProcess);
1096  Status = ZwDuplicateObject(hProcess,
1097  hDesktop,
1098  ZwCurrentProcess(),
1099  (PHANDLE)&hDesktopDup,
1100  0,
1101  0,
1103  if (!NT_SUCCESS(Status))
1104  {
1105  ERR("IntResolveDesktop: Failed to duplicate the desktop handle, Status 0x%08lx\n", Status);
1106  /* We will use a default desktop */
1107  hDesktop = NULL;
1108  }
1109  else
1110  {
1111  hDesktop = hDesktopDup;
1112  }
1113  }
1114  }
1115 
1116  if ((hWinSta != NULL) && (hDesktop == NULL))
1117  {
1119  ObjectName->MaximumLength,
1120  DesktopName.Buffer,
1121  DesktopName.Length);
1122  if (!NT_SUCCESS(Status))
1123  {
1124  ERR("Impossible to build a valid desktop name, Status 0x%08lx\n", Status);
1125  goto Quit;
1126  }
1127  ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
1128 
1129  TRACE("Parsed initial desktop: '%wZ'\n", ObjectName);
1130 
1131  /* Open the desktop object */
1133  ObjectName,
1135  hWinSta,
1136  NULL);
1137  if (bInherit)
1138  ObjectAttributes->Attributes |= OBJ_INHERIT;
1139 
1142  UserMode,
1143  NULL,
1145  NULL,
1146  (PHANDLE)&hDesktop);
1147  if (!NT_SUCCESS(Status))
1148  {
1149  ERR("Failed to open the desktop '%wZ' on window station 0x%p, Status 0x%08lx\n",
1150  ObjectName, hWinSta, Status);
1151  goto Quit;
1152  }
1153  }
1154 
1155 Quit:
1156  /* Release the object attributes */
1157  if (ObjectAttributes)
1158  {
1159  MemSize = 0;
1160  ZwFreeVirtualMemory(ZwCurrentProcess(),
1162  &MemSize,
1163  MEM_RELEASE);
1164  }
1165 
1166  /* Close the temporary process handle */
1167  if (hProcess) // if (Process != PsGetCurrentProcess())
1169 
1170  if (NT_SUCCESS(Status))
1171  {
1172  *phWinSta = hWinSta;
1173  *phDesktop = hDesktop;
1174  return STATUS_SUCCESS;
1175  }
1176  else
1177  {
1178  ERR("IntResolveDesktop(%wZ) failed, Status 0x%08lx\n", DesktopPath, Status);
1179 
1180  if (hDesktopDup)
1181  ObCloseHandle(hDesktopDup, UserMode);
1182  if (hWinStaDup)
1183  ObCloseHandle(hWinStaDup, UserMode);
1184 
1185  if (hDesktop)
1186  ObCloseHandle(hDesktop, UserMode);
1187  if (hWinSta)
1188  ObCloseHandle(hWinSta, UserMode);
1189 
1191  return Status;
1192  }
1193 }
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:264
#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:261
#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:256
#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:687
#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:2311
HWINSTA hwinsta
Definition: win32.h:265
#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
BOOL FASTCALL UserIsEnteredExclusive(VOID)
Definition: ntuser.c:229
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 1288 of file desktop.c.

1289 {
1290  PUSER_MESSAGE_QUEUE Old;
1291  PDESKTOP pdo = IntGetActiveDesktop();
1292  if (!pdo)
1293  {
1294  TRACE("No active desktop\n");
1295  return;
1296  }
1297  if (NewQueue != NULL)
1298  {
1299  if (NewQueue->Desktop != NULL)
1300  {
1301  TRACE("Message Queue already attached to another desktop!\n");
1302  return;
1303  }
1304  IntReferenceMessageQueue(NewQueue);
1305  (void)InterlockedExchangePointer((PVOID*)&NewQueue->Desktop, pdo);
1306  }
1308  if (Old != NULL)
1309  {
1311  gpqForegroundPrev = Old;
1313  }
1314  // Only one Q can have active foreground even when there are more than one desktop.
1315  if (NewQueue)
1316  {
1318  }
1319  else
1320  {
1321  gpqForeground = NULL;
1322  ERR("ptiLastInput is CLEARED!!\n");
1323  ptiLastInput = NULL; // ReactOS hacks... should check for process death.
1324  }
1325 }
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:1231
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 3219 of file desktop.c.

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

3102 {
3103  PPROCESSINFO ppi;
3104  PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
3106 
3107  TRACE("IntUnmapDesktopView called for desktop object %p\n", pdesk);
3108 
3110 
3111  /*
3112  * Unmap if we're the last thread using the desktop.
3113  * Start the search at the next mapping: skip the first entry
3114  * as it must be the global user heap mapping.
3115  */
3116  PrevLink = &ppi->HeapMappings.Next;
3117  HeapMapping = *PrevLink;
3118  while (HeapMapping != NULL)
3119  {
3120  if (HeapMapping->KernelMapping == (PVOID)pdesk->pheapDesktop)
3121  {
3122  if (--HeapMapping->Count == 0)
3123  {
3124  *PrevLink = HeapMapping->Next;
3125 
3126  TRACE("ppi 0x%p unmapped heap of desktop 0x%p\n", ppi, pdesk);
3128  HeapMapping->UserMapping);
3129 
3130  ObDereferenceObject(pdesk);
3131 
3132  UserHeapFree(HeapMapping);
3133  break;
3134  }
3135  }
3136 
3137  PrevLink = &HeapMapping->Next;
3138  HeapMapping = HeapMapping->Next;
3139  }
3140 
3141  return Status;
3142 }
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:288
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:201

Referenced by IntDesktopObjectClose(), and IntSetThreadDesktop().

◆ IntValidateDesktopHandle()

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

Definition at line 1206 of file desktop.c.

1211 {
1212  NTSTATUS Status;
1213 
1215  DesiredAccess,
1217  AccessMode,
1218  (PVOID*)Object,
1219  NULL);
1220 
1221  TRACE("IntValidateDesktopHandle: handle:0x%p obj:0x%p access:0x%x Status:0x%lx\n",
1223 
1224  if (!NT_SUCCESS(Status))
1226 
1227  return Status;
1228 }
_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 2682 of file desktop.c.

2683 {
2684  PDESKTOP pdesk;
2685  NTSTATUS Status;
2687 
2688  TRACE("NtUserCloseDesktop(0x%p) called\n", hDesktop);
2690 
2691  if (hDesktop == gptiCurrent->hdesk || hDesktop == gptiCurrent->ppi->hdeskStartup)
2692  {
2693  ERR("Attempted to close thread desktop\n");
2695  RETURN(FALSE);
2696  }
2697 
2698  Status = IntValidateDesktopHandle(hDesktop, UserMode, 0, &pdesk);
2699  if (!NT_SUCCESS(Status))
2700  {
2701  ERR("Validation of desktop handle 0x%p failed\n", hDesktop);
2702  RETURN(FALSE);
2703  }
2704 
2705  ObDereferenceObject(pdesk);
2706 
2707  Status = ObCloseHandle(hDesktop, UserMode);
2708  if (!NT_SUCCESS(Status))
2709  {
2710  ERR("Failed to close desktop handle 0x%p\n", hDesktop);
2712  RETURN(FALSE);
2713  }
2714 
2715  RETURN(TRUE);
2716 
2717 CLEANUP:
2718  TRACE("Leave NtUserCloseDesktop, ret=%i\n", _ret_);
2719  UserLeave();
2720  END_CLEANUP;
2721 }
#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:89
HDESK hdesk
Definition: win32.h:109
HDESK hdeskStartup
Definition: win32.h:261
#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:245
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:253
NTSTATUS FASTCALL IntValidateDesktopHandle(HDESK Desktop, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PDESKTOP *Object)
Definition: desktop.c:1206
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 2488 of file desktop.c.

2494 {
2495  NTSTATUS Status;
2496  HDESK hDesk;
2497 
2498  DECLARE_RETURN(HDESK);
2499 
2500  TRACE("Enter NtUserCreateDesktop\n");
2502 
2503  Status = IntCreateDesktop(&hDesk,
2505  UserMode,
2506  lpszDesktopDevice,
2507  lpdmw,
2508  dwFlags,
2509  dwDesiredAccess);
2510  if (!NT_SUCCESS(Status))
2511  {
2512  ERR("IntCreateDesktop failed, Status 0x%08lx\n", Status);
2513  // SetLastNtError(Status);
2514  RETURN(NULL);
2515  }
2516 
2517  RETURN(hDesk);
2518 
2519 CLEANUP:
2520  TRACE("Leave NtUserCreateDesktop, ret=0x%p\n", _ret_);
2521  UserLeave();
2522  END_CLEANUP;
2523 }
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:245
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:253
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:2311
#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 2992 of file desktop.c.

2993 {
2994  HDESK hDesk;
2995  NTSTATUS Status;
2996  PTHREADINFO pti;
2998  PDESKTOP DesktopObject;
3000 
3002  TRACE("Enter NtUserGetThreadDesktop\n");
3003 
3004  if (!dwThreadId)
3005  {
3007  hDesk = NULL;
3008  goto Quit;
3009  }
3010 
3011  /* Validate the Win32 thread and retrieve its information */
3013  if (pti)
3014  {
3015  /* Get the desktop handle of the thread */
3016  hDesk = pti->hdesk;
3017  Process = pti->ppi->peProcess;
3018  }
3019  else if (hConsoleDesktop)
3020  {
3021  /*
3022  * The thread may belong to a console, so attempt to use the provided
3023  * console desktop handle as a fallback. Otherwise this means that the
3024  * thread is either not Win32 or invalid.
3025  */
3026  hDesk = hConsoleDesktop;
3027  Process = gpepCSRSS;
3028  }
3029  else
3030  {
3032  hDesk = NULL;
3033  goto Quit;
3034  }
3035 
3036  if (!hDesk)
3037  {
3038  ERR("Desktop information of thread 0x%x broken!?\n", dwThreadId);
3039  goto Quit;
3040  }
3041 
3042  if (Process == PsGetCurrentProcess())
3043  {
3044  /*
3045  * Just return the handle, since we queried the desktop handle
3046  * of a thread running in the same context.
3047  */
3048  goto Quit;
3049  }
3050 
3051  /*
3052  * We could just use the cached rpdesk instead of looking up the handle,
3053  * but it may actually be safer to validate the desktop and get a temporary
3054  * reference to it so that it does not disappear under us (e.g. when the
3055  * desktop is being destroyed) during the operation.
3056  */
3057  /*
3058  * Switch into the context of the thread we are trying to get
3059  * the desktop from, so we can use the handle.
3060  */
3061  KeAttachProcess(&Process->Pcb);
3063  0,
3065  UserMode,
3066  (PVOID*)&DesktopObject,
3068  KeDetachProcess();
3069 
3070  if (NT_SUCCESS(Status))
3071  {
3072  /*
3073  * Lookup our handle table if we can find a handle to the desktop object.
3074  * If not, create one.
3075  * QUESTION: Do we really need to create a handle in case it doesn't exist??
3076  */
3077  hDesk = IntGetDesktopObjectHandle(DesktopObject);
3078 
3079  /* All done, we got a valid handle to the desktop */
3080  ObDereferenceObject(DesktopObject);
3081  }
3082  else
3083  {
3084  /* The handle could not be found, there is nothing to get... */
3085  hDesk = NULL;
3086  }
3087 
3088  if (!hDesk)
3089  {
3090  ERR("Could not retrieve or access desktop for thread 0x%x\n", dwThreadId);
3092  }
3093 
3094 Quit:
3095  TRACE("Leave NtUserGetThreadDesktop, hDesk = 0x%p\n", hDesk);
3096  UserLeave();
3097  return hDesk;
3098 }
#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:89
PTHREADINFO FASTCALL IntTID2PTI(HANDLE id)
Definition: misc.c:41
HDESK hdesk
Definition: win32.h:109
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:245
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:1240
#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:253
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 2548 of file desktop.c.

2552 {
2553  NTSTATUS Status;
2554  HDESK Desktop;
2555 
2559  UserMode,
2560  NULL,
2561  dwDesiredAccess,
2562  NULL,
2563  (HANDLE*)&Desktop);
2564 
2565  if (!NT_SUCCESS(Status))
2566  {
2567  ERR("Failed to open desktop\n");
2569  return NULL;
2570  }
2571 
2572  TRACE("Opened desktop %S with handle 0x%p\n", ObjectAttributes->ObjectName->Buffer, Desktop);
2573 
2574  return Desktop;
2575 }
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 2642 of file desktop.c.

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

Referenced by OpenInputDesktop().

◆ NtUserPaintDesktop()

BOOL APIENTRY NtUserPaintDesktop ( HDC  hDC)

Definition at line 2739 of file desktop.c.

2740 {
2741  BOOL Ret;
2742 
2744  TRACE("Enter NtUserPaintDesktop\n");
2745 
2746  Ret = IntPaintDesktop(hDC);
2747 
2748  TRACE("Leave NtUserPaintDesktop, ret=%i\n", Ret);
2749  UserLeave();
2750  return Ret;
2751 }
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL FASTCALL IntPaintDesktop(HDC hDC)
Definition: desktop.c:1794
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:245
#define TRACE(s)
Definition: solgame.cpp:4
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:253
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 2789 of file desktop.c.

2794 {
2795  NTSTATUS Status;
2797  HWINSTA hWinSta = NULL;
2798  HDESK hDesktop = NULL;
2799  UNICODE_STRING CapturedDesktopPath;
2800 
2801  /* Allow only the Console Server to perform this operation (via CSRSS) */
2802  if (PsGetCurrentProcess() != gpepCSRSS)
2803  return NULL;
2804 
2805  /* Get the process object the user handle was referencing */
2808  *PsProcessType,
2809  UserMode,
2810  (PVOID*)&Process,
2811  NULL);
2812  if (!NT_SUCCESS(Status))
2813  return NULL;
2814 
2816 
2817  _SEH2_TRY
2818  {
2819  /* Probe the handle pointer */
2820  // ProbeForWriteHandle
2821  ProbeForWrite(phWinSta, sizeof(HWINSTA), sizeof(HWINSTA));
2822  }
2824  {
2826  _SEH2_YIELD(goto Quit);
2827  }
2828  _SEH2_END;
2829 
2830  /* Capture the user desktop path string */
2831  Status = ProbeAndCaptureUnicodeString(&CapturedDesktopPath,
2832  UserMode,
2833  DesktopPath);
2834  if (!NT_SUCCESS(Status))
2835  goto Quit;
2836 
2837  /* Call the internal function */
2839  &CapturedDesktopPath,
2840  bInherit,
2841  &hWinSta,
2842  &hDesktop);
2843  if (!NT_SUCCESS(Status))
2844  {
2845  ERR("IntResolveDesktop failed, Status 0x%08lx\n", Status);
2846  hWinSta = NULL;
2847  hDesktop = NULL;
2848  }
2849 
2850  _SEH2_TRY
2851  {
2852  /* Return the window station handle */
2853  *phWinSta = hWinSta;
2854  }
2856  {
2858 
2859  /* We failed, close the opened desktop and window station */
2860  if (hDesktop) ObCloseHandle(hDesktop, UserMode);
2861  hDesktop = NULL;
2862  if (hWinSta) ObCloseHandle(hWinSta, UserMode);
2863  }
2864  _SEH2_END;
2865 
2866  /* Free the captured string */
2867  ReleaseCapturedUnicodeString(&CapturedDesktopPath, UserMode);
2868 
2869 Quit:
2870  UserLeave();
2871 
2872  /* Dereference the process object */
2874 
2875  /* Return the desktop handle */
2876  return hDesktop;
2877 }
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
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:245
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
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:253
_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 3411 of file desktop.c.

3412 {
3413  BOOL ret = FALSE;
3414 
3416 
3417  // FIXME: IntSetThreadDesktop validates the desktop handle, it should happen
3418  // here too and set the NT error level. Q. Is it necessary to have the validation
3419  // in IntSetThreadDesktop? Is it needed there too?
3420  if (hDesktop || (!hDesktop && PsGetCurrentProcess() == gpepCSRSS))
3421  ret = IntSetThreadDesktop(hDesktop, FALSE);
3422 
3423  UserLeave();
3424 
3425  return ret;
3426 }
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:245
int ret
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:253
BOOL IntSetThreadDesktop(IN HDESK hDesktop, IN BOOL FreeOnFailure)
Definition: desktop.c:3219

Referenced by SetThreadDesktop().

◆ NtUserSwitchDesktop()

BOOL APIENTRY NtUserSwitchDesktop ( HDESK  hdesk)

Definition at line 2896 of file desktop.c.

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