ReactOS 0.4.17-dev-116-ga4b6fe9
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 = 3 * 1024
 
DWORD gdwNOIOSectionSize = 128
 
DWORD gdwWinlogonSectionSize = 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 1383 of file desktop.c.

1384{
1385 if (pWnd->head.rpdesk &&
1386 pWnd->head.rpdesk->pDeskInfo)
1387 return pWnd->head.rpdesk->pDeskInfo->spwnd;
1388 return NULL;
1389}
#define NULL
Definition: types.h:112
struct _DESKTOP * rpdesk
Definition: ntuser.h:194
THRDESKHEAD head
Definition: ntuser.h:695

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

1705{
1707 HWND* HwndList;
1708
1709 if (!gpsi->uiShellMsg)
1710 {
1711 gpsi->uiShellMsg = IntAddAtom(L"SHELLHOOK");
1712
1713 TRACE("MsgType = %x\n", gpsi->uiShellMsg);
1714 if (!gpsi->uiShellMsg)
1715 ERR("LastError: %x\n", EngGetLastError());
1716 }
1717
1718 if (!Desktop)
1719 {
1720 TRACE("IntShellHookNotify: No desktop!\n");
1721 return;
1722 }
1723
1724 // Allow other devices have a shot at foreground.
1725 if (Message == HSHELL_APPCOMMAND) ptiLastInput = NULL;
1726
1727 // FIXME: System Tray Support.
1728
1730 if (HwndList)
1731 {
1732 HWND* cursor = HwndList;
1733 LPARAM shellhookparam = (Message == HSHELL_LANGUAGE || Message == HSHELL_APPCOMMAND)
1734 ? lParam : (LPARAM)wParam;
1735
1736 for (; *cursor; cursor++)
1737 {
1738 TRACE("Sending notify\n");
1741 Message,
1742 shellhookparam);
1743/* co_IntPostOrSendMessage(*cursor,
1744 gpsi->uiShellMsg,
1745 Message,
1746 shellhookparam);*/
1747 }
1748
1750 }
1751
1752 if (ISITHOOKED(WH_SHELL))
1753 {
1755 }
1756}
#define ERR(fmt,...)
Definition: precomp.h:57
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
static CHAR Desktop[MAX_PATH]
Definition: dem.c:256
static const WCHAR Message[]
Definition: register.c:74
#define L(x)
Definition: resources.c:13
PTHREADINFO ptiLastInput
Definition: focus.c:18
#define ISITHOOKED(HookId)
Definition: hook.h:6
const char cursor[]
Definition: icontest.c:13
PSERVERINFO gpsi
Definition: imm.c:18
LONG_PTR LPARAM
Definition: minwindef.h:175
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
LRESULT APIENTRY co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:1102
#define TRACE(s)
Definition: solgame.cpp:4
UINT uiShellMsg
Definition: ntuser.h:1063
RTL_ATOM FASTCALL IntAddAtom(LPWSTR AtomName)
Definition: useratom.c:13
PDESKTOP FASTCALL IntGetActiveDesktop(VOID)
Definition: desktop.c:1279
static HWND *FASTCALL UserBuildShellHookHwndList(PDESKTOP Desktop)
Definition: desktop.c:1663
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1395
#define USERTAG_WINDOWLIST
Definition: tags.h:298
ENGAPI ULONG APIENTRY EngGetLastError(VOID)
Definition: error.c:9
#define WH_SHELL
Definition: winuser.h:40

Referenced by co_IntLoadKeyboardLayoutEx(), co_IntUnloadKeyboardLayoutEx(), co_UserActivateKeyboardLayout(), co_UserCreateWindowEx(), co_UserDestroyWindow(), co_UserProcessHotKeys(), co_WinPosSetWindowPos(), DefSetText(), IntCheckFullscreen(), IntDefWindowProc(), NtUserCallHwndLock(), NtUserDefSetText(), and UpdateShellHook().

◆ co_IntShowDesktop()

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

Definition at line 1629 of file desktop.c.

1630{
1631 PWND pwnd = Desktop->pDeskInfo->spwnd;
1633 ASSERT(pwnd);
1634
1635 if (!bRedraw)
1637
1639
1640 if (bRedraw)
1642
1643 return STATUS_SUCCESS;
1644}
GLbitfield flags
Definition: glext.h:7161
#define ASSERT(a)
Definition: mode.c:44
unsigned int UINT
Definition: ndis.h:50
BOOLEAN FASTCALL co_WinPosSetWindowPos(PWND Window, HWND WndInsertAfter, INT x, INT y, INT cx, INT cy, UINT flags)
Definition: winpos.c:1792
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: ntuser.h:694
BOOL FASTCALL co_UserRedrawWindow(PWND Window, const RECTL *UpdateRect, PREGION UpdateRgn, ULONG Flags)
Definition: painting.c:895
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
Definition: font.h:89
_In_ HFONT _Out_ PUINT Height
Definition: font.h:88
#define SWP_NOACTIVATE
Definition: winuser.h:1253
#define SWP_NOREDRAW
Definition: winuser.h:1257
#define RDW_UPDATENOW
Definition: winuser.h:1231
#define RDW_ALLCHILDREN
Definition: winuser.h:1232
#define SWP_SHOWWINDOW
Definition: winuser.h:1259
#define SWP_NOZORDER
Definition: winuser.h:1258
#define RDW_INVALIDATE
Definition: winuser.h:1225

Referenced by co_IntInitializeDesktopGraphics(), and NtUserSwitchDesktop().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserDesktop  )

◆ DesktopThreadMain()

VOID NTAPI DesktopThreadMain ( VOID  )

Definition at line 1558 of file desktop.c.

1559{
1560 BOOL Ret;
1561 MSG Msg;
1562
1564
1566
1567 /* Register system classes. This thread does not belong to any desktop so the
1568 classes will be allocated from the shared heap */
1570
1572
1573 while (TRUE)
1574 {
1575 Ret = co_IntGetPeekMessage(&Msg, 0, 0, 0, PM_REMOVE, TRUE);
1576 if (Ret)
1577 {
1579 }
1580 }
1581
1582 UserLeave();
1583}
struct @1767 Msg[]
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
unsigned int BOOL
Definition: ntddk_ex.h:94
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
BOOL FASTCALL UserRegisterSystemClasses(VOID)
Definition: class.c:2337
PTHREADINFO gptiDesktopThread
Definition: desktop.c:54
PKEVENT gpDesktopThreadStartedEvent
Definition: desktop.c:56
LRESULT FASTCALL IntDispatchMessage(PMSG pMsg)
Definition: message.c:890
BOOL APIENTRY co_IntGetPeekMessage(PMSG pMsg, HWND hWnd, UINT MsgFilterMin, UINT MsgFilterMax, UINT RemoveMsg, BOOL bGMSG)
Definition: message.c:1226
#define PM_REMOVE
Definition: winuser.h:1207
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by UserSystemThreadProc().

◆ DesktopWindowProc()

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

Definition at line 1451 of file desktop.c.

1452{
1453 PAINTSTRUCT Ps;
1454 ULONG Value;
1455 //ERR("DesktopWindowProc\n");
1456
1457 *lResult = 0;
1458
1459 switch (Msg)
1460 {
1461 case WM_NCCREATE:
1462 if (!Wnd->fnid)
1463 {
1464 Wnd->fnid = FNID_DESKTOP;
1465 }
1466 *lResult = (LRESULT)TRUE;
1467 return TRUE;
1468
1469 case WM_CREATE:
1471 // Save Process ID
1474 // Save Thread ID
1476 case WM_CLOSE:
1477 return TRUE;
1478
1479 case WM_DISPLAYCHANGE:
1481 return TRUE;
1482
1483 case WM_ERASEBKGND:
1485 *lResult = 1;
1486 return TRUE;
1487
1488 case WM_PAINT:
1489 {
1490 if (IntBeginPaint(Wnd, &Ps))
1491 {
1492 IntEndPaint(Wnd, &Ps);
1493 }
1494 return TRUE;
1495 }
1496 case WM_SYSCOLORCHANGE:
1498 return TRUE;
1499
1500 case WM_SETCURSOR:
1501 {
1502 PCURICON_OBJECT pcurOld, pcurNew;
1504 if (!pcurNew)
1505 {
1506 return TRUE;
1507 }
1508
1509 pcurNew->CURSORF_flags |= CURSORF_CURRENT;
1510 pcurOld = UserSetCursor(pcurNew, FALSE);
1511 if (pcurOld)
1512 {
1513 pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
1514 UserDereferenceObject(pcurOld);
1515 }
1516 return TRUE;
1517 }
1518
1520 {
1521 PWINDOWPOS pWindowPos = (PWINDOWPOS)lParam;
1522 if ((pWindowPos->flags & SWP_SHOWWINDOW) != 0)
1523 {
1525 IntSetThreadDesktop(hdesk, FALSE);
1526 }
1527 break;
1528 }
1529 default:
1530 TRACE("DWP calling IDWP Msg %d\n",Msg);
1531 //*lResult = IntDefWindowProc(Wnd, Msg, wParam, lParam, FALSE);
1532 }
1533 return TRUE; /* We are done. Do not do any callbacks to user mode */
1534}
#define HandleToULong(h)
Definition: basetsd.h:89
#define DT_GWL_THREADID
Definition: desktop.h:56
#define DT_GWL_PROCESSID
Definition: desktop.h:55
PsGetCurrentThreadId
Definition: CrNtStubs.h:8
#define FNID_DESKTOP
Definition: ntuser.h:862
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
#define CURSORF_CURRENT
Definition: ntuser.h:1207
#define DESKTOP_ALL_ACCESS
Definition: precomp.h:22
static HDC
Definition: imagelist.c:88
PCURICON_OBJECT FASTCALL UserSetCursor(PCURICON_OBJECT NewCursor, BOOL ForceChange)
Definition: msgqueue.c:93
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
#define LRESULT
Definition: ole.h:14
#define LOWORD(l)
Definition: pedump.c:82
ULONG CURSORF_flags
Definition: cursoricon.h:16
UINT flags
Definition: winuser.h:3702
DWORD fnid
Definition: ntuser.h:709
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
HDC FASTCALL IntBeginPaint(PWND Window, PPAINTSTRUCT Ps)
Definition: painting.c:1441
BOOL FASTCALL IntEndPaint(PWND Wnd, PPAINTSTRUCT Ps)
Definition: painting.c:1537
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
Definition: cursoricon.c:200
HCURSOR gDesktopCursor
Definition: desktop.c:55
HDESK UserOpenInputDesktop(DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess)
Definition: desktop.c:2650
BOOL FASTCALL IntPaintDesktop(HDC hDC)
Definition: desktop.c:1849
BOOL IntSetThreadDesktop(IN HDESK hDesktop, IN BOOL FreeOnFailure)
Definition: desktop.c:3293
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:643
LONG FASTCALL co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
Definition: window.c:4033
#define WM_PAINT
Definition: winuser.h:1648
#define WM_ERASEBKGND
Definition: winuser.h:1653
#define WM_CLOSE
Definition: winuser.h:1649
#define WM_WINDOWPOSCHANGING
Definition: winuser.h:1689
#define WM_CREATE
Definition: winuser.h:1636
#define RDW_ERASE
Definition: winuser.h:1222
#define WM_SYSCOLORCHANGE
Definition: winuser.h:1654
#define WM_NCCREATE
Definition: winuser.h:1711
#define WM_SETCURSOR
Definition: winuser.h:1664
struct _WINDOWPOS * PWINDOWPOS

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

304{
306
307 RTL_OSVERSIONINFOEXW VerInfo;
308 UNICODE_STRING BuildLabString;
309 UNICODE_STRING CSDVersionString;
310 RTL_QUERY_REGISTRY_TABLE VersionConfigurationTable[] =
311 {
312 {
313 NULL,
315 L"BuildLab",
316 &BuildLabString,
317 REG_NONE, NULL, 0
318 },
319 {
320 NULL,
322 L"CSDVersion",
323 &CSDVersionString,
324 REG_NONE, NULL, 0
325 },
326
327 {0}
328 };
329
330 WCHAR BuildLabBuffer[256];
331 WCHAR VersionBuffer[256];
332 PWCHAR EndBuffer;
333
334 VerInfo.dwOSVersionInfoSize = sizeof(VerInfo);
335
336 /*
337 * This call is uniquely used to retrieve the current CSD numbers.
338 * All the rest (major, minor, ...) is either retrieved from the
339 * SharedUserData structure, or from the registry.
340 */
342
343 /*
344 * - Retrieve the BuildLab string from the registry (set by the kernel).
345 * - In kernel-mode, szCSDVersion is not initialized. Initialize it
346 * and query its value from the registry.
347 */
348 RtlZeroMemory(BuildLabBuffer, sizeof(BuildLabBuffer));
349 RtlInitEmptyUnicodeString(&BuildLabString,
350 BuildLabBuffer,
351 sizeof(BuildLabBuffer));
352 RtlZeroMemory(VerInfo.szCSDVersion, sizeof(VerInfo.szCSDVersion));
353 RtlInitEmptyUnicodeString(&CSDVersionString,
354 VerInfo.szCSDVersion,
355 sizeof(VerInfo.szCSDVersion));
357 L"",
358 VersionConfigurationTable,
359 NULL,
360 NULL);
361 if (!NT_SUCCESS(Status))
362 {
363 /* Indicate nothing is there */
364 BuildLabString.Length = 0;
365 CSDVersionString.Length = 0;
366 }
367 /* NULL-terminate the strings */
368 BuildLabString.Buffer[BuildLabString.Length / sizeof(WCHAR)] = UNICODE_NULL;
369 CSDVersionString.Buffer[CSDVersionString.Length / sizeof(WCHAR)] = UNICODE_NULL;
370
371 EndBuffer = VersionBuffer;
372 if ( /* VerInfo.wServicePackMajor != 0 && */ CSDVersionString.Length)
373 {
374 /* Print the version string */
375 Status = RtlStringCbPrintfExW(VersionBuffer,
376 sizeof(VersionBuffer),
377 &EndBuffer,
378 NULL,
379 0,
380 L": %wZ",
381 &CSDVersionString);
382 if (!NT_SUCCESS(Status))
383 {
384 /* No version, NULL-terminate the string */
385 *EndBuffer = UNICODE_NULL;
386 }
387 }
388 else
389 {
390 /* No version, NULL-terminate the string */
391 *EndBuffer = UNICODE_NULL;
392 }
393
394 if (InSafeMode)
395 {
396 /* String for Safe Mode */
397 Status = RtlStringCchPrintfW(pwszzVersion,
398 cchDest,
399 L"ReactOS Version %S %wZ (NT %u.%u Build %u%s)\n",
400 KERNEL_VERSION_STR,
401 &BuildLabString,
402 SharedUserData->NtMajorVersion,
403 SharedUserData->NtMinorVersion,
404 (VerInfo.dwBuildNumber & 0xFFFF),
405 VersionBuffer);
406
407 if (AppendNtSystemRoot && NT_SUCCESS(Status))
408 {
409 Status = RtlStringCbPrintfW(VersionBuffer,
410 sizeof(VersionBuffer),
411 L" - %s\n",
412 SharedUserData->NtSystemRoot);
413 if (NT_SUCCESS(Status))
414 {
415 /* Replace the last newline by a NULL, before concatenating */
416 EndBuffer = wcsrchr(pwszzVersion, L'\n');
417 if (EndBuffer) *EndBuffer = UNICODE_NULL;
418
419 /* The concatenated string has a terminating newline */
420 Status = RtlStringCchCatW(pwszzVersion,
421 cchDest,
422 VersionBuffer);
423 if (!NT_SUCCESS(Status))
424 {
425 /* Concatenation failed, put back the newline */
426 if (EndBuffer) *EndBuffer = L'\n';
427 }
428 }
429
430 /* Override any failures as the NtSystemRoot string is optional */
432 }
433 }
434 else
435 {
436 /* Multi-string for Normal Mode */
437 Status = RtlStringCchPrintfW(pwszzVersion,
438 cchDest,
439 L"ReactOS Version %S\n"
440 L"Build %wZ\n"
441 L"Reporting NT %u.%u (Build %u%s)\n",
442 KERNEL_VERSION_STR,
443 &BuildLabString,
444 SharedUserData->NtMajorVersion,
445 SharedUserData->NtMinorVersion,
446 (VerInfo.dwBuildNumber & 0xFFFF),
447 VersionBuffer);
448
449 if (AppendNtSystemRoot && NT_SUCCESS(Status))
450 {
451 Status = RtlStringCbPrintfW(VersionBuffer,
452 sizeof(VersionBuffer),
453 L"%s\n",
454 SharedUserData->NtSystemRoot);
455 if (NT_SUCCESS(Status))
456 {
457 Status = RtlStringCchCatW(pwszzVersion,
458 cchDest,
459 VersionBuffer);
460 }
461
462 /* Override any failures as the NtSystemRoot string is optional */
464 }
465 }
466
467 if (!NT_SUCCESS(Status))
468 {
469 /* Fall-back string */
470 Status = RtlStringCchPrintfW(pwszzVersion,
471 cchDest,
472 L"ReactOS Version %S %wZ\n",
473 KERNEL_VERSION_STR,
474 &BuildLabString);
475 if (!NT_SUCCESS(Status))
476 {
477 /* General failure, NULL-terminate the string */
478 pwszzVersion[0] = UNICODE_NULL;
479 }
480 }
481
482 /*
483 * Convert the string separators (newlines) into NULLs
484 * and NULL-terminate the multi-string.
485 */
486 while (*pwszzVersion)
487 {
488 EndBuffer = wcschr(pwszzVersion, L'\n');
489 if (!EndBuffer) break;
490 pwszzVersion = EndBuffer;
491
492 *pwszzVersion++ = UNICODE_NULL;
493 }
494 *pwszzVersion = UNICODE_NULL;
495
496 return Status;
497}
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS NTAPI RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
Definition: version.c:182
#define wcschr
Definition: compat.h:17
#define wcsrchr
Definition: compat.h:16
Status
Definition: gdiplustypes.h:25
#define RTL_REGISTRY_WINDOWS_NT
Definition: nt_native.h:164
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define REG_NONE
Definition: nt_native.h:1495
#define UNICODE_NULL
NTSTRSAFEAPI RtlStringCchCatW(_Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:601
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
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
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
short WCHAR
Definition: pedump.c:58
_In_ INT cchDest
Definition: shlwapi.h:1151
#define SharedUserData
WCHAR szCSDVersion[128]
Definition: rtltypes.h:274
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:269
ULONG dwBuildNumber
Definition: rtltypes.h:272
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint16_t * PWCHAR
Definition: typedefs.h:56
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)

Referenced by IntPaintDesktop().

◆ InitDesktopImpl()

NTSTATUS NTAPI InitDesktopImpl ( VOID  )

Definition at line 269 of file desktop.c.

270{
271 GENERIC_MAPPING IntDesktopMapping = { DESKTOP_READ,
275
276 /* Set Desktop Object Attributes */
278 ExDesktopObjectType->TypeInfo.GenericMapping = IntDesktopMapping;
280
281 /* Allocate memory for the event structure */
283 sizeof(KEVENT),
286 {
287 ERR("Failed to allocate event!\n");
288 return STATUS_NO_MEMORY;
289 }
290
291 /* Initialize the kernel event */
294 FALSE);
295
296 return STATUS_SUCCESS;
297}
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
struct _DESKTOP DESKTOP
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define NonPagedPool
Definition: env_spec_w32.h:307
@ SynchronizationEvent
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:365
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
POBJECT_TYPE ExDesktopObjectType
Definition: win32k.c:22
#define DESKTOP_WRITE
Definition: security.h:19
#define DESKTOP_EXECUTE
Definition: security.h:27
#define DESKTOP_READ
Definition: security.h:15
#define USERTAG_EVENT
Definition: tags.h:230

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

2393{
2395 PDESKTOP pdesk = NULL;
2396 HDESK hDesk;
2398 UNICODE_STRING ClassName;
2399 LARGE_STRING WindowName;
2400 BOOL NoHooks = FALSE;
2401 PWND pWnd = NULL;
2402 CREATESTRUCTW Cs;
2403 PTHREADINFO ptiCurrent;
2404 PCLS pcls;
2405
2406 TRACE("Enter IntCreateDesktop\n");
2407
2409
2410 ASSERT(phDesktop);
2411 *phDesktop = NULL;
2412
2413 ptiCurrent = PsGetCurrentThreadWin32Thread();
2414 ASSERT(ptiCurrent);
2416
2417 /* Turn off hooks when calling any CreateWindowEx from inside win32k */
2418 NoHooks = (ptiCurrent->TIF_flags & TIF_DISABLEHOOKS);
2419 ptiCurrent->TIF_flags |= TIF_DISABLEHOOKS;
2420 ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
2421
2422 /*
2423 * Try to open already existing desktop
2424 */
2427 AccessMode,
2428 NULL,
2429 dwDesiredAccess,
2430 (PVOID)&Context,
2431 (PHANDLE)&hDesk);
2432 if (!NT_SUCCESS(Status))
2433 {
2434 ERR("ObOpenObjectByName failed to open/create desktop\n");
2435 goto Quit;
2436 }
2437
2438 /* In case the object was not created (eg if it existed), return now */
2439 if (Context == FALSE)
2440 {
2441 TRACE("IntCreateDesktop opened desktop '%wZ'\n", ObjectAttributes->ObjectName);
2443 goto Quit;
2444 }
2445
2446 /* Reference the desktop */
2448 0,
2450 KernelMode,
2451 (PVOID*)&pdesk,
2452 NULL);
2453 if (!NT_SUCCESS(Status))
2454 {
2455 ERR("Failed to reference desktop object\n");
2456 goto Quit;
2457 }
2458
2459 /* Get the desktop window class. The thread desktop does not belong to any desktop
2460 * so the classes created there (including the desktop class) are allocated in the shared heap
2461 * It would cause problems if we used a class that belongs to the caller
2462 */
2463 ClassName.Buffer = WC_DESKTOP;
2464 ClassName.Length = 0;
2465 pcls = IntGetAndReferenceClass(&ClassName, 0, TRUE);
2466 if (pcls == NULL)
2467 {
2468 ASSERT(FALSE);
2470 goto Quit;
2471 }
2472
2473 RtlZeroMemory(&WindowName, sizeof(WindowName));
2474 RtlZeroMemory(&Cs, sizeof(Cs));
2480 Cs.hInstance = hModClient; // hModuleWin; // Server side winproc!
2481 Cs.lpszName = (LPCWSTR) &WindowName;
2482 Cs.lpszClass = (LPCWSTR) &ClassName;
2483
2484 /* Use IntCreateWindow instead of co_UserCreateWindowEx because the later expects a thread with a desktop */
2485 pWnd = IntCreateWindow(&Cs, &WindowName, pcls, NULL, NULL, NULL, pdesk, WINVER);
2486 if (pWnd == NULL)
2487 {
2488 ERR("Failed to create desktop window for the new desktop\n");
2490 goto Quit;
2491 }
2492
2494 pdesk->DesktopWindow = UserHMGetHandle(pWnd);
2495 pdesk->pDeskInfo->spwnd = pWnd;
2496 pWnd->fnid = FNID_DESKTOP;
2497
2498 ClassName.Buffer = MAKEINTATOM(gpsi->atomSysClass[ICLS_HWNDMESSAGE]);
2499 ClassName.Length = 0;
2500 pcls = IntGetAndReferenceClass(&ClassName, 0, TRUE);
2501 if (pcls == NULL)
2502 {
2503 ASSERT(FALSE);
2505 goto Quit;
2506 }
2507
2508 RtlZeroMemory(&WindowName, sizeof(WindowName));
2509 RtlZeroMemory(&Cs, sizeof(Cs));
2510 Cs.cx = Cs.cy = 100;
2512 Cs.hInstance = hModClient; // hModuleWin; // Server side winproc!
2513 Cs.lpszName = (LPCWSTR)&WindowName;
2514 Cs.lpszClass = (LPCWSTR)&ClassName;
2515 pWnd = IntCreateWindow(&Cs, &WindowName, pcls, NULL, NULL, NULL, pdesk, WINVER);
2516 if (pWnd == NULL)
2517 {
2518 ERR("Failed to create message window for the new desktop\n");
2520 goto Quit;
2521 }
2522
2523 pdesk->spwndMessage = pWnd;
2524 pWnd->fnid = FNID_MESSAGEWND;
2525
2526 /* Now...
2527 if !(WinStaObject->Flags & WSF_NOIO) is (not set) for desktop input output mode (see wiki)
2528 Create Tooltip. Saved in DesktopObject->spwndTooltip.
2529 Tooltip dwExStyle: WS_EX_TOOLWINDOW|WS_EX_TOPMOST
2530 hWndParent are spwndMessage. Use hModuleWin for server side winproc!
2531 The rest is same as message window.
2532 https://learn.microsoft.com/en-us/windows/win32/controls/tooltip-controls
2533 */
2535
2536Quit:
2537 if (pdesk != NULL)
2538 {
2539 ObDereferenceObject(pdesk);
2540 }
2541 if (!NT_SUCCESS(Status) && hDesk != NULL)
2542 {
2543 ObCloseHandle(hDesk, AccessMode);
2544 hDesk = NULL;
2545 }
2546 if (!NoHooks)
2547 {
2548 ptiCurrent->TIF_flags &= ~TIF_DISABLEHOOKS;
2549 ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
2550 }
2551
2552 TRACE("Leave IntCreateDesktop, Status 0x%08lx\n", Status);
2553
2554 if (NT_SUCCESS(Status))
2555 *phDesktop = hDesk;
2556 else
2558 return Status;
2559}
unsigned char BOOLEAN
Definition: actypes.h:127
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define FNID_MESSAGEWND
Definition: ntuser.h:864
#define TIF_DISABLEHOOKS
Definition: ntuser.h:291
#define KernelMode
Definition: asm.h:38
ULONG NTAPI PsGetCurrentProcessSessionId(VOID)
Definition: process.c:1133
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
HINSTANCE hModClient
Definition: ntuser.c:25
BOOL FASTCALL UserIsEnteredExclusive(VOID)
Definition: ntuser.c:231
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
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:2532
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 WS_POPUP
Definition: pedump.c:616
#define WS_CLIPCHILDREN
Definition: pedump.c:619
_In_ PVOID Context
Definition: storport.h:2269
Definition: ntuser.h:566
struct _WND * spwnd
Definition: ntuser.h:137
PWND spwndMessage
Definition: desktop.h:20
HWND DesktopWindow
Definition: desktop.h:40
PDESKTOPINFO pDeskInfo
Definition: desktop.h:8
DWORD dwSessionId
Definition: desktop.h:6
struct _CLIENTINFO * pClientInfo
Definition: win32.h:94
FLONG TIF_flags
Definition: win32.h:95
LPCWSTR lpszClass
Definition: winuser.h:3073
LPCWSTR lpszName
Definition: winuser.h:3072
HINSTANCE hInstance
Definition: winuser.h:3064
ATOM atomSysClass[ICLS_NOTUSED+1]
Definition: ntuser.h:1060
#define WINVER
Definition: targetver.h:11
const uint16_t * LPCWSTR
Definition: typedefs.h:57
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define WC_DESKTOP
Definition: undocuser.h:12
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:30
PCLS IntGetAndReferenceClass(PUNICODE_STRING ClassName, HINSTANCE hInstance, BOOL bDesktopThread)
Definition: class.c:1450
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:209
PWND FASTCALL IntCreateWindow(CREATESTRUCTW *Cs, PLARGE_STRING WindowName, PCLS Class, PWND ParentWindow, PWND OwnerWindow, PVOID acbiBuffer, PDESKTOP pdeskCreated, DWORD dwVer)
Definition: window.c:1805
#define MAKEINTATOM(i)
Definition: winbase.h:1220
#define SM_CYVIRTUALSCREEN
Definition: winuser.h:1050
#define SM_CXVIRTUALSCREEN
Definition: winuser.h:1049
#define SM_XVIRTUALSCREEN
Definition: winuser.h:1047
#define SM_YVIRTUALSCREEN
Definition: winuser.h:1048
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by IntResolveDesktop(), and NtUserCreateDesktop().

◆ IntDeRegisterShellHookWindow()

BOOL IntDeRegisterShellHookWindow ( HWND  hWnd)

Definition at line 1798 of file desktop.c.

1799{
1801 PDESKTOP Desktop = pti->rpdesk;
1802 PLIST_ENTRY ListEntry;
1803 PSHELL_HOOK_WINDOW Current;
1804
1805 // FIXME: This probably shouldn't happen, but it does
1806 if (Desktop == NULL)
1807 {
1809 if (Desktop == NULL)
1810 return FALSE;
1811 }
1812
1813 ListEntry = Desktop->ShellHookWindows.Flink;
1814 while (ListEntry != &Desktop->ShellHookWindows)
1815 {
1816 Current = CONTAINING_RECORD(ListEntry, SHELL_HOOK_WINDOW, ListEntry);
1817 ListEntry = ListEntry->Flink;
1818 if (Current->hWnd == hWnd)
1819 {
1820 RemoveEntryList(&Current->ListEntry);
1821 ExFreePoolWithTag(Current, TAG_WINSTA);
1822 return TRUE;
1823 }
1824 }
1825
1826 return FALSE;
1827}
HWND hWnd
Definition: settings.c:17
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY ListEntry
Definition: desktop.h:67
struct _DESKTOP * rpdesk
Definition: win32.h:92
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define TAG_WINSTA
Definition: tags.h:11

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

◆ IntDesktopObjectClose()

NTSTATUS NTAPI IntDesktopObjectClose ( _In_ PVOID  Parameters)

Definition at line 244 of file desktop.c.

246{
247 NTSTATUS Ret;
249 PPROCESSINFO ppi = PsGetProcessWin32Process(CloseParameters->Process);
250 if (ppi == NULL)
251 {
252 /* This happens when the process leaks desktop handles.
253 * At this point the PPROCESSINFO is already destroyed */
254 return STATUS_SUCCESS;
255 }
256
258 Ret = IntUnmapDesktopView((PDESKTOP)CloseParameters->Object);
259 UserLeave();
260 return Ret;
261}
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
static NTSTATUS IntUnmapDesktopView(IN PDESKTOP pdesk)
Definition: desktop.c:3175

Referenced by DriverEntry().

◆ IntDesktopObjectDelete()

NTSTATUS NTAPI IntDesktopObjectDelete ( _In_ PVOID  Parameters)

Definition at line 172 of file desktop.c.

174{
176 PDESKTOP pdesk = (PDESKTOP)DeleteParameters->Object;
177
178 TRACE("Deleting desktop object 0x%p\n", pdesk);
179
180 if (pdesk->pDeskInfo &&
181 pdesk->pDeskInfo->spwnd)
182 {
183 ASSERT(pdesk->pDeskInfo->spwnd->spwndChild == NULL);
185 }
186
187 if (pdesk->spwndMessage)
189
190 /* Remove the desktop from the window station's list of associated desktops */
191 RemoveEntryList(&pdesk->ListEntry);
192
193 /* Free the heap */
194 IntFreeDesktopHeap(pdesk);
195
197
198 return STATUS_SUCCESS;
199}
struct _DESKTOP * PDESKTOP
LIST_ENTRY ListEntry
Definition: desktop.h:9
struct _WINSTATION_OBJECT * rpwinstaParent
Definition: desktop.h:11
BOOLEAN co_UserDestroyWindow(PVOID Object)
Definition: window.c:2865
static VOID IntFreeDesktopHeap(IN PDESKTOP pdesk)

Referenced by DriverEntry().

◆ IntDesktopObjectOpen()

NTSTATUS NTAPI IntDesktopObjectOpen ( _In_ PVOID  Parameters)

Definition at line 227 of file desktop.c.

229{
230 NTSTATUS Ret;
232 PPROCESSINFO ppi = PsGetProcessWin32Process(OpenParameters->Process);
233 if (ppi == NULL)
234 return STATUS_SUCCESS;
235
237 Ret = IntMapDesktopView((PDESKTOP)OpenParameters->Object);
238 UserLeave();
239 return Ret;
240}
static NTSTATUS IntMapDesktopView(IN PDESKTOP pdesk)
Definition: desktop.c:3219

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

72{
76 PLIST_ENTRY NextEntry, ListHead;
77 PWINSTATION_OBJECT WinStaObject = (PWINSTATION_OBJECT)ParseObject;
78 UNICODE_STRING DesktopName;
79 PBOOLEAN pContext = (PBOOLEAN) Context;
80
81 if (pContext)
82 *pContext = FALSE;
83
84 /* Set the list pointers and loop the window station */
85 ListHead = &WinStaObject->DesktopListHead;
86 NextEntry = ListHead->Flink;
87 while (NextEntry != ListHead)
88 {
89 /* Get the current desktop */
90 Desktop = CONTAINING_RECORD(NextEntry, DESKTOP, ListEntry);
91
92 /* Get the desktop name */
93 ASSERT(Desktop->pDeskInfo != NULL);
94 RtlInitUnicodeString(&DesktopName, Desktop->pDeskInfo->szDesktopName);
95
96 /* Compare the name */
98 &DesktopName,
100 {
101 /* We found a match. Did this come from a create? */
102 if (Context)
103 {
104 /* Unless OPEN_IF was given, fail with an error */
105 if (!(Attributes & OBJ_OPENIF))
106 {
107 /* Name collision */
109 }
110 else
111 {
112 /* Otherwise, return with a warning only */
114 }
115 }
116 else
117 {
118 /* This was a real open, so this is OK */
120 }
121
122 /* Reference the desktop and return it */
124 *Object = Desktop;
125 return Status;
126 }
127
128 /* Go to the next desktop */
129 NextEntry = NextEntry->Flink;
130 }
131
132 /* If we got here but this isn't a create, just fail */
134
135 /* Create the desktop object */
141 NULL,
142 sizeof(DESKTOP),
143 0,
144 0,
145 (PVOID*)&Desktop);
146 if (!NT_SUCCESS(Status)) return Status;
147
148 /* Assign security to the desktop we have created */
150 if (!NT_SUCCESS(Status))
151 {
153 return Status;
154 }
155
156 /* Initialize the desktop */
158 if (!NT_SUCCESS(Status))
159 {
161 return Status;
162 }
163
164 /* Set the desktop object and return success */
165 *Object = Desktop;
166 *pContext = TRUE;
167 return STATUS_SUCCESS;
168}
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:802
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:189
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:1039
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
LIST_ENTRY DesktopListHead
Definition: winsta.h:19
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
static NTSTATUS UserInitializeDesktop(PDESKTOP pdesk, PUNICODE_STRING DesktopName, PWINSTATION_OBJECT pwinsta)
Definition: desktop.c:2274
NTSTATUS NTAPI IntAssignDesktopSecurityOnParse(_In_ PWINSTATION_OBJECT WinSta, _In_ PDESKTOP Desktop, _In_ PACCESS_STATE AccessState)
Assigns a security descriptor to the desktop object during a desktop object parse procedure.
Definition: security.c:270
struct _WINSTATION_OBJECT * PWINSTATION_OBJECT
#define ObReferenceObject
Definition: obfuncs.h:204
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417

Referenced by IntWinStaObjectParse().

◆ IntDesktopOkToClose()

NTSTATUS NTAPI IntDesktopOkToClose ( _In_ PVOID  Parameters)

Definition at line 203 of file desktop.c.

205{
208
209 if (pti == NULL)
210 {
211 /* This happens when we leak desktop handles */
212 return STATUS_SUCCESS;
213 }
214
215 /* Do not allow the current desktop or the initial desktop to be closed */
216 if (OkToCloseParameters->Handle == pti->ppi->hdeskStartup ||
217 OkToCloseParameters->Handle == pti->hdesk)
218 {
220 }
221
222 return STATUS_SUCCESS;
223}
HDESK hdeskStartup
Definition: win32.h:264
PPROCESSINFO ppi
Definition: win32.h:88
HDESK hdesk
Definition: win32.h:108
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145

Referenced by DriverEntry().

◆ IntFreeDesktopHeap() [1/2]

static VOID IntFreeDesktopHeap ( IN OUT PDESKTOP  Desktop)
static

Definition at line 1830 of file desktop.c.

1831{
1832 /* FIXME: Disable until unmapping works in mm */
1833#if 0
1834 if (Desktop->pheapDesktop != NULL)
1835 {
1836 MmUnmapViewInSessionSpace(Desktop->pheapDesktop);
1837 Desktop->pheapDesktop = NULL;
1838 }
1839
1840 if (Desktop->hsectionDesktop != NULL)
1841 {
1842 ObDereferenceObject(Desktop->hsectionDesktop);
1843 Desktop->hsectionDesktop = NULL;
1844 }
1845#endif
1846}
NTSTATUS NTAPI MmUnmapViewInSessionSpace(IN PVOID MappedBase)
Definition: section.c:2731

◆ IntFreeDesktopHeap() [2/2]

static VOID IntFreeDesktopHeap ( IN PDESKTOP  pdesk)
static

Referenced by IntDesktopObjectDelete().

◆ IntGetActiveDesktop()

◆ IntGetCurrentThreadDesktopWindow()

HWND FASTCALL IntGetCurrentThreadDesktopWindow ( VOID  )

Definition at line 1436 of file desktop.c.

1437{
1439 PDESKTOP pdo = pti->rpdesk;
1440 if (!pdo)
1441 {
1442 ERR("Thread doesn't have a desktop\n");
1443 return NULL;
1444 }
1445 return pdo->DesktopWindow;
1446}

Referenced by NtUserFindWindowEx().

◆ IntGetDesktopObjectHandle()

HDESK FASTCALL IntGetDesktopObjectHandle ( PDESKTOP  DesktopObject)

Definition at line 1288 of file desktop.c.

1289{
1291 HDESK hDesk;
1292
1293 ASSERT(DesktopObject);
1294
1296 DesktopObject,
1298 NULL,
1299 (PHANDLE)&hDesk))
1300 {
1301 Status = ObOpenObjectByPointer(DesktopObject,
1302 0,
1303 NULL,
1304 0,
1306 UserMode,
1307 (PHANDLE)&hDesk);
1308 if (!NT_SUCCESS(Status))
1309 {
1310 /* Unable to create a handle */
1311 ERR("Unable to create a desktop handle\n");
1312 return NULL;
1313 }
1314 }
1315 else
1316 {
1317 TRACE("Got handle: 0x%p\n", hDesk);
1318 }
1319
1320 return hDesk;
1321}
#define UserMode
Definition: asm.h:39
BOOLEAN NTAPI ObFindHandleForObject(IN PEPROCESS Process, IN PVOID Object, IN POBJECT_TYPE ObjectType, IN POBJECT_HANDLE_INFORMATION HandleInformation, OUT PHANDLE Handle)
Definition: obhandle.c:2856
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:2742
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by NtUserGetThreadDesktop(), and NtUserSetInformationThread().

◆ IntGetDesktopWindow()

◆ IntGetFocusMessageQueue()

◆ IntGetMessageWindow()

HWND FASTCALL IntGetMessageWindow ( VOID  )

Definition at line 1414 of file desktop.c.

1415{
1417 if (!pdo)
1418 {
1419 TRACE("No active desktop\n");
1420 return NULL;
1421 }
1422 return UserHMGetHandle(pdo->spwndMessage);
1423}

Referenced by NtUserFindWindowEx(), and NtUserSetParent().

◆ IntGetThreadDesktopWindow()

PWND FASTCALL IntGetThreadDesktopWindow ( PTHREADINFO  pti)

Definition at line 1376 of file desktop.c.

1377{
1378 if (!pti) pti = PsGetCurrentThreadWin32Thread();
1379 if (pti->pDeskInfo) return pti->pDeskInfo->spwnd;
1380 return NULL;
1381}
struct _DESKTOPINFO * pDeskInfo
Definition: win32.h:93

Referenced by ActivateOtherWindowMin().

◆ IntHideDesktop()

NTSTATUS FASTCALL IntHideDesktop ( PDESKTOP  Desktop)

Definition at line 1647 of file desktop.c.

1648{
1649 PWND DesktopWnd;
1650
1651 DesktopWnd = IntGetWindowObject(Desktop->DesktopWindow);
1652 if (! DesktopWnd)
1653 {
1655 }
1656 DesktopWnd->style &= ~WS_VISIBLE;
1657
1658 return STATUS_SUCCESS;
1659}
DWORD style
Definition: ntuser.h:706
PWND FASTCALL IntGetWindowObject(HWND hWnd)
Definition: window.c:75
#define ERROR_INVALID_WINDOW_HANDLE
Definition: winerror.h:1226

Referenced by IntEndDesktopGraphics(), and NtUserSwitchDesktop().

◆ IntMapDesktopView()

static NTSTATUS IntMapDesktopView ( IN PDESKTOP  pdesk)
static

Definition at line 3219 of file desktop.c.

3220{
3221 PPROCESSINFO ppi;
3222 PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
3223 PVOID UserBase = NULL;
3224 SIZE_T ViewSize = 0;
3227
3228 TRACE("IntMapDesktopView called for desktop object 0x%p\n", pdesk);
3229
3231
3232 /*
3233 * Find out if another thread already mapped the desktop heap.
3234 * Start the search at the next mapping: skip the first entry
3235 * as it must be the global user heap mapping.
3236 */
3237 PrevLink = &ppi->HeapMappings.Next;
3238 HeapMapping = *PrevLink;
3239 while (HeapMapping != NULL)
3240 {
3241 if (HeapMapping->KernelMapping == (PVOID)pdesk->pheapDesktop)
3242 {
3243 HeapMapping->Count++;
3244 return STATUS_SUCCESS;
3245 }
3246
3247 PrevLink = &HeapMapping->Next;
3248 HeapMapping = HeapMapping->Next;
3249 }
3250
3251 /* We're the first, map the heap */
3252 Offset.QuadPart = 0;
3253 Status = MmMapViewOfSection(pdesk->hsectionDesktop,
3255 &UserBase,
3256 0,
3257 0,
3258 &Offset,
3259 &ViewSize,
3260 ViewUnmap,
3263 if (!NT_SUCCESS(Status))
3264 {
3265 ERR("Failed to map desktop\n");
3266 return Status;
3267 }
3268
3269 TRACE("ppi 0x%p mapped heap of desktop 0x%p\n", ppi, pdesk);
3270
3271 /* Add the mapping */
3272 HeapMapping = UserHeapAlloc(sizeof(*HeapMapping));
3273 if (HeapMapping == NULL)
3274 {
3276 ERR("UserHeapAlloc() failed!\n");
3277 return STATUS_NO_MEMORY;
3278 }
3279
3280 HeapMapping->Next = NULL;
3281 HeapMapping->KernelMapping = (PVOID)pdesk->pheapDesktop;
3282 HeapMapping->UserMapping = UserBase;
3283 HeapMapping->Limit = ViewSize;
3284 HeapMapping->Count = 1;
3285 *PrevLink = HeapMapping;
3286
3287 ObReferenceObject(pdesk);
3288
3289 return STATUS_SUCCESS;
3290}
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:2759
#define PAGE_READONLY
Definition: compat.h:138
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
#define SEC_NO_CHANGE
Definition: mmtypes.h:95
@ ViewUnmap
Definition: nt_native.h:1282
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
NTSTATUS NTAPI MmMapViewOfSection(_In_ PVOID SectionObject, _In_ PEPROCESS Process, _Outptr_result_bytebuffer_(*ViewSize) _Pre_opt_valid_ PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _In_ SIZE_T CommitSize, _Inout_opt_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_range_(ViewShare, ViewUnmap) SECTION_INHERIT InheritDisposition, _In_ ULONG AllocationType, _In_ ULONG Protect)
Definition: section.c:4031
W32HEAP_USER_MAPPING HeapMappings
Definition: win32.h:291
struct _W32HEAP_USER_MAPPING * Next
Definition: win32.h:199
ULONG_PTR Limit
Definition: win32.h:202
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
static __inline PVOID UserHeapAlloc(SIZE_T Bytes)
Definition: usrheap.h:34

Referenced by IntDesktopObjectOpen(), and IntSetThreadDesktop().

◆ IntPaintDesktop()

BOOL FASTCALL IntPaintDesktop ( HDC  hDC)

Definition at line 1849 of file desktop.c.

1850{
1851 static WCHAR s_wszSafeMode[] = L"Safe Mode"; // FIXME: Localize!
1852
1853 RECTL Rect;
1854 HBRUSH DesktopBrush, PreviousBrush;
1855 HWND hWndDesktop;
1856 BOOL doPatBlt = TRUE;
1857 PWND WndDesktop;
1858 BOOLEAN InSafeMode;
1859
1860 if (GdiGetClipBox(hDC, &Rect) == ERROR)
1861 return FALSE;
1862
1863 hWndDesktop = IntGetDesktopWindow(); // rpdesk->DesktopWindow;
1864
1865 WndDesktop = UserGetWindowObject(hWndDesktop); // rpdesk->pDeskInfo->spwnd;
1866 if (!WndDesktop)
1867 return FALSE;
1868
1869 /* Retrieve the current SafeMode state */
1870 InSafeMode = (UserGetSystemMetrics(SM_CLEANBOOT) != 0); // gpsi->aiSysMet[SM_CLEANBOOT];
1871
1872 if (!InSafeMode)
1873 {
1874 DesktopBrush = (HBRUSH)WndDesktop->pcls->hbrBackground;
1875
1876 /*
1877 * Paint desktop background
1878 */
1880 {
1881 SIZE sz;
1882 int x, y;
1883 int scaledWidth, scaledHeight;
1884 int wallpaperX, wallpaperY, wallpaperWidth, wallpaperHeight;
1885 HDC hWallpaperDC;
1886
1887 sz.cx = WndDesktop->rcWindow.right - WndDesktop->rcWindow.left;
1888 sz.cy = WndDesktop->rcWindow.bottom - WndDesktop->rcWindow.top;
1889
1890 if (gspv.WallpaperMode == wmFit ||
1892 {
1893 int scaleNum, scaleDen;
1894
1895 // Precision improvement over ((sz.cx / gspv.cxWallpaper) > (sz.cy / gspv.cyWallpaper))
1896 if ((sz.cx * gspv.cyWallpaper) > (sz.cy * gspv.cxWallpaper))
1897 {
1898 if (gspv.WallpaperMode == wmFit)
1899 {
1900 scaleNum = sz.cy;
1901 scaleDen = gspv.cyWallpaper;
1902 }
1903 else
1904 {
1905 scaleNum = sz.cx;
1906 scaleDen = gspv.cxWallpaper;
1907 }
1908 }
1909 else
1910 {
1911 if (gspv.WallpaperMode == wmFit)
1912 {
1913 scaleNum = sz.cx;
1914 scaleDen = gspv.cxWallpaper;
1915 }
1916 else
1917 {
1918 scaleNum = sz.cy;
1919 scaleDen = gspv.cyWallpaper;
1920 }
1921 }
1922
1923 scaledWidth = EngMulDiv(gspv.cxWallpaper, scaleNum, scaleDen);
1924 scaledHeight = EngMulDiv(gspv.cyWallpaper, scaleNum, scaleDen);
1925
1926 if (gspv.WallpaperMode == wmFill)
1927 {
1928 wallpaperX = (((scaledWidth - sz.cx) * gspv.cxWallpaper) / (2 * scaledWidth));
1929 wallpaperY = (((scaledHeight - sz.cy) * gspv.cyWallpaper) / (2 * scaledHeight));
1930
1931 wallpaperWidth = (sz.cx * gspv.cxWallpaper) / scaledWidth;
1932 wallpaperHeight = (sz.cy * gspv.cyWallpaper) / scaledHeight;
1933 }
1934 }
1935
1936 if (gspv.WallpaperMode == wmStretch ||
1939 {
1940 x = 0;
1941 y = 0;
1942 }
1943 else if (gspv.WallpaperMode == wmFit)
1944 {
1945 x = (sz.cx - scaledWidth) / 2;
1946 y = (sz.cy - scaledHeight) / 2;
1947 }
1948 else
1949 {
1950 /* Find the upper left corner, can be negative if the bitmap is bigger than the screen */
1951 x = (sz.cx / 2) - (gspv.cxWallpaper / 2);
1952 y = (sz.cy / 2) - (gspv.cyWallpaper / 2);
1953 }
1954
1955 hWallpaperDC = NtGdiCreateCompatibleDC(hDC);
1956 if (hWallpaperDC != NULL)
1957 {
1958 HBITMAP hOldBitmap;
1959
1960 /* Fill in the area that the bitmap is not going to cover */
1961 if (x > 0 || y > 0)
1962 {
1963 /* FIXME: Clip out the bitmap
1964 can be replaced with "NtGdiPatBlt(hDC, x, y, gspv.cxWallpaper, gspv.cyWallpaper, PATCOPY | DSTINVERT);"
1965 once we support DSTINVERT */
1966 PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
1967 NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
1968 NtGdiSelectBrush(hDC, PreviousBrush);
1969 }
1970
1971 /* Do not fill the background after it is painted no matter the size of the picture */
1972 doPatBlt = FALSE;
1973
1974 hOldBitmap = NtGdiSelectBitmap(hWallpaperDC, gspv.hbmWallpaper);
1975
1977 {
1978 if (Rect.right && Rect.bottom)
1980 x,
1981 y,
1982 sz.cx,
1983 sz.cy,
1984 hWallpaperDC,
1985 0,
1986 0,
1989 SRCCOPY,
1990 CLR_INVALID);
1991 }
1992 else if (gspv.WallpaperMode == wmTile)
1993 {
1994 /* Paint the bitmap across the screen then down */
1995 for (y = 0; y < Rect.bottom; y += gspv.cyWallpaper)
1996 {
1997 for (x = 0; x < Rect.right; x += gspv.cxWallpaper)
1998 {
2000 x,
2001 y,
2004 hWallpaperDC,
2005 0,
2006 0,
2007 SRCCOPY,
2009 0);
2010 }
2011 }
2012 }
2013 else if (gspv.WallpaperMode == wmFit)
2014 {
2015 if (Rect.right && Rect.bottom)
2016 {
2018 x,
2019 y,
2020 scaledWidth,
2021 scaledHeight,
2022 hWallpaperDC,
2023 0,
2024 0,
2027 SRCCOPY,
2028 CLR_INVALID);
2029 }
2030 }
2031 else if (gspv.WallpaperMode == wmFill)
2032 {
2033 if (Rect.right && Rect.bottom)
2034 {
2036 x,
2037 y,
2038 sz.cx,
2039 sz.cy,
2040 hWallpaperDC,
2041 wallpaperX,
2042 wallpaperY,
2043 wallpaperWidth,
2044 wallpaperHeight,
2045 SRCCOPY,
2046 CLR_INVALID);
2047 }
2048 }
2049 else
2050 {
2052 x,
2053 y,
2056 hWallpaperDC,
2057 0,
2058 0,
2059 SRCCOPY,
2061 0);
2062 }
2063 NtGdiSelectBitmap(hWallpaperDC, hOldBitmap);
2064 NtGdiDeleteObjectApp(hWallpaperDC);
2065 }
2066 }
2067 }
2068 else
2069 {
2070 /* Black desktop background in Safe Mode */
2071 DesktopBrush = StockObjects[BLACK_BRUSH];
2072 }
2073
2074 /* Background is set to none, clear the screen */
2075 if (doPatBlt)
2076 {
2077 PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
2078 NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
2079 NtGdiSelectBrush(hDC, PreviousBrush);
2080 }
2081
2082 /*
2083 * Display the system version on the desktop background
2084 */
2085 if (InSafeMode || g_AlwaysDisplayVersion || g_PaintDesktopVersion)
2086 {
2088 static WCHAR wszzVersion[1024] = L"\0";
2089
2090 /* Only used in normal mode */
2091 // We expect at most 4 strings (3 for version, 1 for optional NtSystemRoot)
2092 static POLYTEXTW VerStrs[4] = {{0},{0},{0},{0}};
2093 INT i = 0;
2094 SIZE_T len;
2095
2096 HFONT hFont1 = NULL, hFont2 = NULL, hOldFont = NULL;
2097 COLORREF crText, color_old;
2098 UINT align_old;
2099 INT mode_old;
2100 PDC pdc;
2101
2102 if (!UserSystemParametersInfo(SPI_GETWORKAREA, 0, &Rect, 0))
2103 {
2104 Rect.left = Rect.top = 0;
2107 }
2108 else
2109 {
2110 RECTL_vOffsetRect(&Rect, -Rect.left, -Rect.top);
2111 }
2112
2113 /*
2114 * Set up the fonts (otherwise use default ones)
2115 */
2116
2117 /* Font for the principal version string */
2118 hFont1 = GreCreateFontIndirectW(&gspv.ncm.lfCaptionFont);
2119 /* Font for the secondary version strings */
2120 hFont2 = GreCreateFontIndirectW(&gspv.ncm.lfMenuFont);
2121
2122 if (hFont1)
2123 hOldFont = NtGdiSelectFont(hDC, hFont1);
2124
2125 if (gspv.hbmWallpaper == NULL)
2126 {
2127 /* Retrieve the brush fill colour */
2128 // TODO: The following code constitutes "GreGetBrushColor".
2129 PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
2130 pdc = DC_LockDc(hDC);
2131 if (pdc)
2132 {
2133 crText = pdc->eboFill.ulRGBColor;
2134 DC_UnlockDc(pdc);
2135 }
2136 else
2137 {
2138 crText = RGB(0, 0, 0);
2139 }
2140 NtGdiSelectBrush(hDC, PreviousBrush);
2141
2142 /* Adjust text colour according to the brush */
2143 if (GetRValue(crText) + GetGValue(crText) + GetBValue(crText) > 128 * 3)
2144 crText = RGB(0, 0, 0);
2145 else
2146 crText = RGB(255, 255, 255);
2147 }
2148 else
2149 {
2150 /* Always use white when the text is displayed on top of a wallpaper */
2151 crText = RGB(255, 255, 255);
2152 }
2153
2154 color_old = IntGdiSetTextColor(hDC, crText);
2155 align_old = IntGdiSetTextAlign(hDC, TA_RIGHT);
2156 mode_old = IntGdiSetBkMode(hDC, TRANSPARENT);
2157
2158 /* Display the system version information */
2159 if (!*wszzVersion)
2160 {
2161 Status = GetSystemVersionString(wszzVersion,
2162 ARRAYSIZE(wszzVersion),
2163 InSafeMode,
2165 if (!InSafeMode && NT_SUCCESS(Status) && *wszzVersion)
2166 {
2167 PWCHAR pstr = wszzVersion;
2168 for (i = 0; (i < ARRAYSIZE(VerStrs)) && *pstr; ++i)
2169 {
2170 VerStrs[i].n = lstrlenW(pstr);
2171 VerStrs[i].lpstr = pstr;
2172 pstr += (VerStrs[i].n + 1);
2173 }
2174 }
2175 }
2176 else
2177 {
2179 }
2180 if (NT_SUCCESS(Status) && *wszzVersion)
2181 {
2182 if (!InSafeMode)
2183 {
2184 SIZE Size = {0, 0};
2185 LONG TotalHeight = 0;
2186
2187 /* Normal Mode: multiple version information text separated by newlines */
2189
2190 /* Compute the heights of the strings */
2191 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2192 for (i = 0; i < ARRAYSIZE(VerStrs); ++i)
2193 {
2194 if (!VerStrs[i].lpstr || !*VerStrs[i].lpstr || (VerStrs[i].n == 0))
2195 break;
2196
2197 GreGetTextExtentW(hDC, VerStrs[i].lpstr, VerStrs[i].n, &Size, 1);
2198 VerStrs[i].y = Size.cy; // Store the string height
2199 TotalHeight += Size.cy;
2200
2201 /* While the first string was using hFont1, all the others use hFont2 */
2202 if (hFont2) NtGdiSelectFont(hDC, hFont2);
2203 }
2204 /* The total height must not exceed the screen height */
2205 TotalHeight = min(TotalHeight, Rect.bottom);
2206
2207 /* Display the strings */
2208 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2209 for (i = 0; i < ARRAYSIZE(VerStrs); ++i)
2210 {
2211 if (!VerStrs[i].lpstr || !*VerStrs[i].lpstr || (VerStrs[i].n == 0))
2212 break;
2213
2214 TotalHeight -= VerStrs[i].y;
2216 Rect.right - 5,
2217 Rect.bottom - TotalHeight - 5,
2218 0, NULL,
2219 VerStrs[i].lpstr,
2220 VerStrs[i].n,
2221 NULL, 0);
2222
2223 /* While the first string was using hFont1, all the others use hFont2 */
2224 if (hFont2) NtGdiSelectFont(hDC, hFont2);
2225 }
2226 }
2227 else
2228 {
2229 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2230
2231 /* Safe Mode: single version information text in top center */
2232 len = wcslen(wszzVersion);
2233
2235 GreExtTextOutW(hDC, (Rect.right + Rect.left)/2, Rect.top + 3, 0, NULL, wszzVersion, len, NULL, 0);
2236 }
2237 }
2238
2239 if (InSafeMode)
2240 {
2241 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2242
2243 /* Print Safe Mode text in corners */
2244 len = wcslen(s_wszSafeMode);
2245
2247 GreExtTextOutW(hDC, Rect.left, Rect.top + 3, 0, NULL, s_wszSafeMode, len, NULL, 0);
2249 GreExtTextOutW(hDC, Rect.right, Rect.top + 3, 0, NULL, s_wszSafeMode, len, NULL, 0);
2251 GreExtTextOutW(hDC, Rect.left, Rect.bottom - 5, 0, NULL, s_wszSafeMode, len, NULL, 0);
2253 GreExtTextOutW(hDC, Rect.right, Rect.bottom - 5, 0, NULL, s_wszSafeMode, len, NULL, 0);
2254 }
2255
2256 IntGdiSetBkMode(hDC, mode_old);
2257 IntGdiSetTextAlign(hDC, align_old);
2258 IntGdiSetTextColor(hDC, color_old);
2259
2260 if (hFont2)
2261 GreDeleteObject(hFont2);
2262
2263 if (hFont1)
2264 {
2265 NtGdiSelectFont(hDC, hOldFont);
2266 GreDeleteObject(hFont1);
2267 }
2268 }
2269
2270 return TRUE;
2271}
static HDC hDC
Definition: 3dtext.c:33
FORCEINLINE VOID DC_UnlockDc(PDC pdc)
Definition: dc.h:238
COLORREF FASTCALL IntGdiSetTextColor(HDC hDC, COLORREF color)
Definition: dcutil.c:172
UINT FASTCALL IntGdiSetTextAlign(HDC hDC, UINT Mode)
Definition: dcutil.c:145
INT FASTCALL IntGdiSetBkMode(HDC hDC, INT backgroundMode)
Definition: dcutil.c:124
FORCEINLINE PDC DC_LockDc(HDC hdc)
Definition: dc.h:220
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define lstrlenW
Definition: compat.h:750
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
#define RGB(r, g, b)
Definition: precomp.h:67
#define GetBValue(quad)
Definition: precomp.h:71
#define GetGValue(quad)
Definition: precomp.h:70
#define GetRValue(quad)
Definition: precomp.h:69
#define ERROR(name)
Definition: error_private.h:53
BOOL APIENTRY GreExtTextOutW(_In_ HDC hDC, _In_ INT XStart, _In_ INT YStart, _In_ UINT fuOptions, _In_opt_ PRECTL lprc, _In_reads_opt_(Count) PCWCH String, _In_ INT Count, _In_opt_ const INT *Dx, _In_ DWORD dwCodePage)
Definition: freetype.c:7219
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLdouble n
Definition: glext.h:7729
GLenum GLsizei len
Definition: glext.h:6722
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
if(dx< 0)
Definition: linetemp.h:194
static HBITMAP
Definition: button.c:44
#define min(a, b)
Definition: monoChain.cc:55
BOOL g_AlwaysDisplayVersion
Definition: ntuser.c:17
long LONG
Definition: pedump.c:60
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
__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)
__kernel_entry W32KAPI HBRUSH APIENTRY NtGdiSelectBrush(_In_ HDC hdc, _In_ HBRUSH hbrush)
__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)
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiSelectBitmap(_In_ HDC hdc, _In_ HBITMAP hbm)
__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:988
__kernel_entry W32KAPI BOOL APIENTRY NtGdiDeleteObjectApp(_In_ HANDLE hobj)
__kernel_entry W32KAPI HFONT APIENTRY NtGdiSelectFont(_In_ HDC hdc, _In_ HFONT hf)
Definition: dcobjs.c:597
Definition: polytest.cpp:41
HBRUSH hbrBackground
Definition: ntuser.h:587
LPCWSTR lpstr
Definition: wingdi.h:3010
UINT n
Definition: wingdi.h:3009
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
WALLPAPER_MODE WallpaperMode
Definition: sysparams.h:144
NONCLIENTMETRICSW ncm
Definition: sysparams.h:51
ULONG cxWallpaper
Definition: sysparams.h:143
ULONG cyWallpaper
Definition: sysparams.h:143
HANDLE hbmWallpaper
Definition: sysparams.h:142
PCLS pcls
Definition: ntuser.h:720
RECT rcWindow
Definition: ntuser.h:716
LONG right
Definition: windef.h:108
LONG bottom
Definition: windef.h:109
LONG top
Definition: windef.h:107
LONG left
Definition: windef.h:106
@ wmFill
Definition: sysparams.h:45
@ wmTile
Definition: sysparams.h:42
@ wmStretch
Definition: sysparams.h:43
@ wmFit
Definition: sysparams.h:44
int32_t INT
Definition: typedefs.h:58
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:123
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
HFONT FASTCALL GreCreateFontIndirectW(_In_ const LOGFONTW *lplf)
Definition: font.c:30
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1165
HGDIOBJ StockObjects[]
Definition: stockobj.c:100
FORCEINLINE VOID RECTL_vOffsetRect(_Inout_ RECTL *prcl, _In_ INT cx, _In_ INT cy)
Definition: rect.h:31
BOOL FASTCALL GreGetTextExtentW(_In_ HDC hDC, _In_reads_(cwc) PCWCH lpwsz, _In_ INT cwc, _Out_ PSIZE psize, _In_ UINT flOpts)
Definition: text.c:77
HWND FASTCALL IntGetDesktopWindow(VOID)
Definition: desktop.c:1391
static NTSTATUS GetSystemVersionString(OUT PWSTR pwszzVersion, IN SIZE_T cchDest, IN BOOLEAN InSafeMode, IN BOOLEAN AppendNtSystemRoot)
Definition: desktop.c:300
BOOL g_PaintDesktopVersion
Definition: sysparams.c:19
SPIVALUES gspv
Definition: sysparams.c:17
BOOL FASTCALL UserSystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni)
Definition: sysparams.c:2123
ENGAPI INT APIENTRY EngMulDiv(_In_ INT a, _In_ INT b, _In_ INT c)
Definition: math.c:26
DWORD COLORREF
Definition: windef.h:100
#define TA_RIGHT
Definition: wingdi.h:933
#define TA_LEFT
Definition: wingdi.h:932
#define TRANSPARENT
Definition: wingdi.h:950
#define CLR_INVALID
Definition: wingdi.h:883
#define SRCCOPY
Definition: wingdi.h:333
#define PATCOPY
Definition: wingdi.h:335
#define BLACK_BRUSH
Definition: wingdi.h:896
#define TA_TOP
Definition: wingdi.h:930
#define TA_BOTTOM
Definition: wingdi.h:929
#define TA_CENTER
Definition: wingdi.h:931
#define SM_CYSCREEN
Definition: winuser.h:971
#define SM_CLEANBOOT
Definition: winuser.h:1038
#define SM_CXSCREEN
Definition: winuser.h:970

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

◆ IntRegisterShellHookWindow()

BOOL IntRegisterShellHookWindow ( HWND  hWnd)

Definition at line 1766 of file desktop.c.

1767{
1769 PDESKTOP Desktop = pti->rpdesk;
1771
1772 TRACE("IntRegisterShellHookWindow\n");
1773
1774 /* First deregister the window, so we can be sure it's never twice in the
1775 * list.
1776 */
1778
1780 sizeof(SHELL_HOOK_WINDOW),
1781 TAG_WINSTA);
1782
1783 if (!Entry)
1784 return FALSE;
1785
1786 Entry->hWnd = hWnd;
1787
1788 InsertTailList(&Desktop->ShellHookWindows, &Entry->ListEntry);
1789
1790 return TRUE;
1791}
#define InsertTailList(ListHead, Entry)
#define PagedPool
Definition: env_spec_w32.h:308
Entry
Definition: section.c:5216
BOOL IntDeRegisterShellHookWindow(HWND hWnd)
Definition: desktop.c:1798

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

574{
576 HWINSTA hWinSta = NULL, hWinStaDup = NULL;
577 HDESK hDesktop = NULL, hDesktopDup = NULL;
578 PPROCESSINFO ppi;
580 LUID ProcessLuid;
581 USHORT StrSize;
582 SIZE_T MemSize;
583 PSECURITY_DESCRIPTOR ServiceSD;
586 UNICODE_STRING WinStaName, DesktopName;
587 const UNICODE_STRING WinSta0Name = RTL_CONSTANT_STRING(L"WinSta0");
588 PWINSTATION_OBJECT WinStaObject;
589 HWINSTA hTempWinSta = NULL;
590 BOOLEAN bUseDefaultWinSta = FALSE;
591 BOOLEAN bInteractive = FALSE;
592 BOOLEAN bAccessAllowed = FALSE;
593
595
596 ASSERT(phWinSta);
597 ASSERT(phDesktop);
598 ASSERT(DesktopPath);
599
600 *phWinSta = NULL;
601 *phDesktop = NULL;
602
604 /* ppi is typically NULL for console applications that connect to Win32 USER */
605 if (!ppi) TRACE("IntResolveDesktop: ppi is NULL!\n");
606
607 if (ppi && ppi->hwinsta != NULL && ppi->hdeskStartup != NULL)
608 {
609 /*
610 * If this process is the current one, just return the cached handles.
611 * Otherwise, open the window station and desktop objects.
612 */
614 {
615 hWinSta = ppi->hwinsta;
616 hDesktop = ppi->hdeskStartup;
617 }
618 else
619 {
621 0,
622 NULL,
625 UserMode,
626 (PHANDLE)&hWinSta);
627 if (!NT_SUCCESS(Status))
628 {
629 ERR("IntResolveDesktop: Could not reference window station 0x%p\n", ppi->prpwinsta);
631 return Status;
632 }
633
635 0,
636 NULL,
639 UserMode,
640 (PHANDLE)&hDesktop);
641 if (!NT_SUCCESS(Status))
642 {
643 ERR("IntResolveDesktop: Could not reference desktop 0x%p\n", ppi->rpdeskStartup);
644 ObCloseHandle(hWinSta, UserMode);
646 return Status;
647 }
648 }
649
650 *phWinSta = hWinSta;
651 *phDesktop = hDesktop;
652 return STATUS_SUCCESS;
653 }
654
655 /* We will by default use the default window station and desktop */
656 RtlInitEmptyUnicodeString(&WinStaName, NULL, 0);
657 RtlInitEmptyUnicodeString(&DesktopName, NULL, 0);
658
659 /*
660 * Parse the desktop path string which can be of the form "WinSta\Desktop"
661 * or just "Desktop". In the latter case we use the default window station
662 * on which the process is attached to (or if none, "WinSta0").
663 */
664 if (DesktopPath->Buffer != NULL && DesktopPath->Length > sizeof(WCHAR))
665 {
666 DesktopName = *DesktopPath;
667
668 /* Find the separator */
669 while (DesktopName.Length > 0 && *DesktopName.Buffer &&
670 *DesktopName.Buffer != OBJ_NAME_PATH_SEPARATOR)
671 {
672 DesktopName.Buffer++;
673 DesktopName.Length -= sizeof(WCHAR);
674 DesktopName.MaximumLength -= sizeof(WCHAR);
675 }
676 if (DesktopName.Length > 0)
677 {
678 RtlInitEmptyUnicodeString(&WinStaName, DesktopPath->Buffer,
679 DesktopPath->Length - DesktopName.Length);
680 // (USHORT)((ULONG_PTR)DesktopName.Buffer - (ULONG_PTR)DesktopPath->Buffer);
681 WinStaName.Length = WinStaName.MaximumLength;
682
683 /* Skip the separator */
684 DesktopName.Buffer++;
685 DesktopName.Length -= sizeof(WCHAR);
686 DesktopName.MaximumLength -= sizeof(WCHAR);
687 }
688 else
689 {
690 RtlInitEmptyUnicodeString(&WinStaName, NULL, 0);
691 DesktopName = *DesktopPath;
692 }
693 }
694
695 TRACE("IntResolveDesktop: WinStaName:'%wZ' ; DesktopName:'%wZ'\n", &WinStaName, &DesktopName);
696
697 /* Retrieve the process LUID */
698 Status = GetProcessLuid(NULL, Process, &ProcessLuid);
699 if (!NT_SUCCESS(Status))
700 {
701 ERR("IntResolveDesktop: Failed to retrieve the process LUID, Status 0x%08lx\n", Status);
703 return Status;
704 }
705
706 /*
707 * If this process is not the current one, obtain a temporary handle
708 * to it so that we can perform handles duplication later.
709 */
711 {
714 NULL,
715 0,
718 &hProcess);
719 if (!NT_SUCCESS(Status))
720 {
721 ERR("IntResolveDesktop: Failed to obtain a handle to process 0x%p, Status 0x%08lx\n", Process, Status);
723 return Status;
724 }
726 }
727
728 /*
729 * If no window station has been specified, search the process handle table
730 * for inherited window station handles, otherwise use a default one.
731 */
732 if (WinStaName.Buffer == NULL)
733 {
734 /*
735 * We want to find a suitable default window station.
736 * For applications that can be interactive, i.e. that have allowed
737 * access to the single interactive window station on the system,
738 * the default window station is 'WinSta0'.
739 * For applications that cannot be interactive, i.e. that do not have
740 * access to 'WinSta0' (e.g. non-interactive services), the default
741 * window station is 'Service-0xXXXX-YYYY$' (created if needed).
742 * Precedence will however be taken by any inherited window station
743 * that possesses the required interactivity property.
744 */
745 bUseDefaultWinSta = TRUE;
746
747 /*
748 * Use the default 'WinSta0' window station. Whether we should
749 * use 'Service-0xXXXX-YYYY$' instead will be determined later.
750 */
751 // RtlInitUnicodeString(&WinStaName, L"WinSta0");
752 WinStaName = WinSta0Name;
753
755 NULL,
757 NULL,
758 (PHANDLE)&hWinSta))
759 {
760 TRACE("IntResolveDesktop: Inherited window station is: 0x%p\n", hWinSta);
761 }
762 }
763
764 /*
765 * If no desktop has been specified, search the process handle table
766 * for inherited desktop handles, otherwise use the Default desktop.
767 * Note that the inherited desktop that we may use, may not belong
768 * to the window station we will connect to.
769 */
770 if (DesktopName.Buffer == NULL)
771 {
772 /* Use a default desktop name */
773 RtlInitUnicodeString(&DesktopName, L"Default");
774
776 NULL,
778 NULL,
779 (PHANDLE)&hDesktop))
780 {
781 TRACE("IntResolveDesktop: Inherited desktop is: 0x%p\n", hDesktop);
782 }
783 }
784
785
786 /*
787 * We are going to open either a window station or a desktop.
788 * Even if this operation is done from kernel-mode, we should
789 * "emulate" an opening from user-mode (i.e. using an ObjectAttributes
790 * allocated in user-mode, with AccessMode == UserMode) for the
791 * Object Manager to perform proper access validation to the
792 * window station or desktop.
793 */
794
795 /*
796 * Estimate the maximum size needed for the window station name
797 * and desktop name to be given to ObjectAttributes->ObjectName.
798 */
799 StrSize = 0;
800
801 /* Window station name */
802 MemSize = _scwprintf(L"Service-0x%x-%x$", MAXULONG, MAXULONG) * sizeof(WCHAR);
804 + max(WinStaName.Length, MemSize) + sizeof(UNICODE_NULL);
805 if (MemSize > MAXUSHORT)
806 {
807 ERR("IntResolveDesktop: Window station name length is too long.\n");
809 goto Quit;
810 }
811 StrSize = max(StrSize, (USHORT)MemSize);
812
813 /* Desktop name */
814 MemSize = max(DesktopName.Length + sizeof(UNICODE_NULL), sizeof(L"Default"));
815 StrSize = max(StrSize, (USHORT)MemSize);
816
817 /* Size for the OBJECT_ATTRIBUTES */
818 MemSize = ALIGN_UP(sizeof(OBJECT_ATTRIBUTES), sizeof(PVOID));
819
820 /* Add the string size */
821 MemSize += ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID));
822 MemSize += StrSize;
823
824 /* Allocate the memory in user-mode */
825 Status = ZwAllocateVirtualMemory(ZwCurrentProcess(),
827 0,
828 &MemSize,
831 if (!NT_SUCCESS(Status))
832 {
833 ERR("ZwAllocateVirtualMemory() failed, Status 0x%08lx\n", Status);
834 goto Quit;
835 }
836
838 ALIGN_UP(sizeof(OBJECT_ATTRIBUTES), sizeof(PVOID)));
839
840 RtlInitEmptyUnicodeString(ObjectName,
842 ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID))),
843 StrSize);
844
845
846 /* If we got an inherited window station handle, duplicate and use it */
847 if (hWinSta)
848 {
849 ASSERT(bUseDefaultWinSta);
850
851 /* Duplicate the handle if it belongs to another process than the current one */
853 {
855 Status = ZwDuplicateObject(hProcess,
856 hWinSta,
858 (PHANDLE)&hWinStaDup,
859 0,
860 0,
862 if (!NT_SUCCESS(Status))
863 {
864 ERR("IntResolveDesktop: Failed to duplicate the window station handle, Status 0x%08lx\n", Status);
865 /* We will use a default window station */
866 hWinSta = NULL;
867 }
868 else
869 {
870 hWinSta = hWinStaDup;
871 }
872 }
873 }
874
875 /*
876 * If we have an inherited window station, check whether
877 * it is interactive and remember that for later.
878 */
879 if (hWinSta)
880 {
881 ASSERT(bUseDefaultWinSta);
882
883 /* Reference the inherited window station */
885 0,
888 (PVOID*)&WinStaObject,
889 NULL);
890 if (!NT_SUCCESS(Status))
891 {
892 ERR("Failed to reference the inherited window station, Status 0x%08lx\n", Status);
893 /* We will use a default window station */
894 if (hWinStaDup)
895 {
896 ASSERT(hWinSta == hWinStaDup);
897 ObCloseHandle(hWinStaDup, UserMode);
898 hWinStaDup = NULL;
899 }
900 hWinSta = NULL;
901 }
902 else
903 {
904 ERR("Process LUID is: 0x%x-%x, inherited window station LUID is: 0x%x-%x\n",
905 ProcessLuid.HighPart, ProcessLuid.LowPart,
906 WinStaObject->luidUser.HighPart, WinStaObject->luidUser.LowPart);
907
908 /* Check whether this window station is interactive, and remember it for later */
909 bInteractive = !(WinStaObject->Flags & WSS_NOIO);
910
911 /* Dereference the window station */
912 ObDereferenceObject(WinStaObject);
913 }
914 }
915
916 /* Build a valid window station name */
918 ObjectName->MaximumLength,
919 L"%wZ\\%wZ",
921 &WinStaName);
922 if (!NT_SUCCESS(Status))
923 {
924 ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
925 goto Quit;
926 }
927 ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
928
929 TRACE("Parsed initial window station: '%wZ'\n", ObjectName);
930
931 /* Try to open the window station */
935 NULL,
936 NULL);
937 if (bInherit)
938 ObjectAttributes->Attributes |= OBJ_INHERIT;
939
942 UserMode,
943 NULL,
945 NULL,
946 (PHANDLE)&hTempWinSta);
947 if (!NT_SUCCESS(Status))
948 {
949 ERR("Failed to open the window station '%wZ', Status 0x%08lx\n", ObjectName, Status);
950 }
951 else
952 {
953 //
954 // FIXME TODO: Perform a window station access check!!
955 // If we fail AND bUseDefaultWinSta == FALSE we just quit.
956 //
957
958 /*
959 * Check whether we are opening the (single) interactive
960 * window station, and if so, perform an access check.
961 */
962 /* Check whether we are allowed to perform interactions */
963 if (RtlEqualUnicodeString(&WinStaName, &WinSta0Name, TRUE))
964 {
965 LUID SystemLuid = SYSTEM_LUID;
966
967 /* Interactive window station: check for user LUID */
968 WinStaObject = InputWindowStation;
969
971
972 // TODO: Check also that we compare wrt. window station WinSta0
973 // which is the only one that can be interactive on the system.
974 if (((!bUseDefaultWinSta || bInherit) && RtlEqualLuid(&ProcessLuid, &SystemLuid)) ||
975 RtlEqualLuid(&ProcessLuid, &WinStaObject->luidUser))
976 {
977 /* We are interactive on this window station */
978 bAccessAllowed = TRUE;
980 }
981 }
982 else
983 {
984 /* Non-interactive window station: we have access since we were able to open it */
985 bAccessAllowed = TRUE;
987 }
988 }
989
990 /* If we failed, bail out if we were not trying to open the default window station */
991 if (!NT_SUCCESS(Status) && !bUseDefaultWinSta) // if (!bAccessAllowed)
992 goto Quit;
993
994 if (/* bAccessAllowed && */ bInteractive || !bAccessAllowed)
995 {
996 /*
997 * Close WinSta0 if the inherited window station is interactive so that
998 * we can use it, or we do not have access to the interactive WinSta0.
999 */
1000 ObCloseHandle(hTempWinSta, UserMode);
1001 hTempWinSta = NULL;
1002 }
1003 if (bInteractive == bAccessAllowed)
1004 {
1005 /* Keep using the inherited window station */
1006 NOTHING;
1007 }
1008 else // if (bInteractive != bAccessAllowed)
1009 {
1010 /*
1011 * Close the inherited window station, we will either keep using
1012 * the interactive WinSta0, or use Service-0xXXXX-YYYY$.
1013 */
1014 if (hWinStaDup)
1015 {
1016 ASSERT(hWinSta == hWinStaDup);
1017 ObCloseHandle(hWinStaDup, UserMode);
1018 hWinStaDup = NULL;
1019 }
1020 hWinSta = hTempWinSta; // hTempWinSta is NULL in case bAccessAllowed == FALSE
1021 }
1022
1023 if (bUseDefaultWinSta)
1024 {
1025 if (hWinSta == NULL && !bInteractive)
1026 {
1027 /* Build a valid window station name from the LUID */
1029 ObjectName->MaximumLength,
1030 L"%wZ\\Service-0x%x-%x$",
1032 ProcessLuid.HighPart,
1033 ProcessLuid.LowPart);
1034 if (!NT_SUCCESS(Status))
1035 {
1036 ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
1037 goto Quit;
1038 }
1039 ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
1040
1041 /*
1042 * Set up a security descriptor for the new service's window station.
1043 * A service has an associated window station and desktop. The newly
1044 * created window station and desktop will get this security descriptor
1045 * if such objects weren't created before.
1046 */
1047 Status = IntCreateServiceSecurity(&ServiceSD);
1048 if (!NT_SUCCESS(Status))
1049 {
1050 ERR("Failed to create a security descriptor for service window station, Status 0x%08lx\n", Status);
1051 goto Quit;
1052 }
1053
1054 /*
1055 * Create or open the non-interactive window station.
1056 * NOTE: The non-interactive window station handle is never inheritable.
1057 */
1059 ObjectName,
1061 NULL,
1062 ServiceSD);
1063
1064 Status = IntCreateWindowStation(&hWinSta,
1066 UserMode,
1067 KernelMode,
1069 0, 0, 0, 0, 0);
1070
1071 IntFreeSecurityBuffer(ServiceSD);
1072
1073 if (!NT_SUCCESS(Status))
1074 {
1075 ASSERT(hWinSta == NULL);
1076 ERR("Failed to create or open the non-interactive window station '%wZ', Status 0x%08lx\n",
1078 goto Quit;
1079 }
1080
1081 //
1082 // FIXME: We might not need to always create or open the "Default"
1083 // desktop on the Service-0xXXXX-YYYY$ window station; we may need
1084 // to use another one....
1085 //
1086
1087 /* Create or open the Default desktop on the window station */
1089 ObjectName->MaximumLength,
1090 L"Default");
1091 if (!NT_SUCCESS(Status))
1092 {
1093 ERR("Impossible to build a valid desktop name, Status 0x%08lx\n", Status);
1094 goto Quit;
1095 }
1096 ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
1097
1098 /*
1099 * NOTE: The non-interactive desktop handle is never inheritable.
1100 * The security descriptor is inherited from the newly created
1101 * window station for the desktop.
1102 */
1104 ObjectName,
1106 hWinSta,
1107 NULL);
1108
1109 Status = IntCreateDesktop(&hDesktop,
1111 UserMode,
1112 NULL,
1113 NULL,
1114 0,
1116 if (!NT_SUCCESS(Status))
1117 {
1118 ASSERT(hDesktop == NULL);
1119 ERR("Failed to create or open the desktop '%wZ' on window station 0x%p, Status 0x%08lx\n",
1120 ObjectName, hWinSta, Status);
1121 }
1122
1123 goto Quit;
1124 }
1125/*
1126 if (hWinSta == NULL)
1127 {
1128 Status = STATUS_UNSUCCESSFUL;
1129 goto Quit;
1130 }
1131*/
1132 }
1133
1134 /*
1135 * If we got an inherited desktop handle, duplicate and use it,
1136 * otherwise open a new desktop.
1137 */
1138 if (hDesktop != NULL)
1139 {
1140 /* Duplicate the handle if it belongs to another process than the current one */
1142 {
1144 Status = ZwDuplicateObject(hProcess,
1145 hDesktop,
1147 (PHANDLE)&hDesktopDup,
1148 0,
1149 0,
1151 if (!NT_SUCCESS(Status))
1152 {
1153 ERR("IntResolveDesktop: Failed to duplicate the desktop handle, Status 0x%08lx\n", Status);
1154 /* We will use a default desktop */
1155 hDesktop = NULL;
1156 }
1157 else
1158 {
1159 hDesktop = hDesktopDup;
1160 }
1161 }
1162 }
1163
1164 if ((hWinSta != NULL) && (hDesktop == NULL))
1165 {
1167 ObjectName->MaximumLength,
1168 DesktopName.Buffer,
1169 DesktopName.Length);
1170 if (!NT_SUCCESS(Status))
1171 {
1172 ERR("Impossible to build a valid desktop name, Status 0x%08lx\n", Status);
1173 goto Quit;
1174 }
1175 ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
1176
1177 TRACE("Parsed initial desktop: '%wZ'\n", ObjectName);
1178
1179 /* Open the desktop object */
1181 ObjectName,
1183 hWinSta,
1184 NULL);
1185 if (bInherit)
1186 ObjectAttributes->Attributes |= OBJ_INHERIT;
1187
1190 UserMode,
1191 NULL,
1193 NULL,
1194 (PHANDLE)&hDesktop);
1195 if (!NT_SUCCESS(Status))
1196 {
1197 ERR("Failed to open the desktop '%wZ' on window station 0x%p, Status 0x%08lx\n",
1198 ObjectName, hWinSta, Status);
1199 goto Quit;
1200 }
1201 }
1202
1203Quit:
1204 /* Release the object attributes */
1205 if (ObjectAttributes)
1206 {
1207 MemSize = 0;
1208 ZwFreeVirtualMemory(ZwCurrentProcess(),
1210 &MemSize,
1211 MEM_RELEASE);
1212 }
1213
1214 /* Close the temporary process handle */
1215 if (hProcess) // if (Process != PsGetCurrentProcess())
1217
1218 if (NT_SUCCESS(Status))
1219 {
1220 *phWinSta = hWinSta;
1221 *phDesktop = hDesktop;
1222 return STATUS_SUCCESS;
1223 }
1224 else
1225 {
1226 ERR("IntResolveDesktop(%wZ) failed, Status 0x%08lx\n", DesktopPath, Status);
1227
1228 if (hDesktopDup)
1229 ObCloseHandle(hDesktopDup, UserMode);
1230 if (hWinStaDup)
1231 ObCloseHandle(hWinStaDup, UserMode);
1232
1233 if (hDesktop)
1234 ObCloseHandle(hDesktop, UserMode);
1235 if (hWinSta)
1236 ObCloseHandle(hWinSta, UserMode);
1237
1239 return Status;
1240 }
1241}
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
_ACRTIMP int __cdecl _scwprintf(const wchar_t *,...)
Definition: wcs.c:1673
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
#define NOTHING
Definition: input_list.c:10
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
#define PAGE_READWRITE
Definition: nt_native.h:1307
#define MEM_RELEASE
Definition: nt_native.h:1319
#define MEM_COMMIT
Definition: nt_native.h:1316
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
POBJECT_TYPE PsProcessType
Definition: process.c:20
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:592
NTSTRSAFEAPI RtlStringCbCopyW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:174
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
PWINSTATION_OBJECT InputWindowStation
Definition: winsta.c:21
UNICODE_STRING gustrWindowStationsDir
Definition: winsta.c:27
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:457
unsigned short USHORT
Definition: pedump.c:61
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_INHERIT
Definition: winternl.h:225
LONG HighPart
DWORD LowPart
HWINSTA hwinsta
Definition: win32.h:268
struct _DESKTOP * rpdeskStartup
Definition: win32.h:259
struct _WINSTATION_OBJECT * prpwinsta
Definition: win32.h:267
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define max(a, b)
Definition: svc.c:63
#define MAXULONG
Definition: typedefs.h:251
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
POBJECT_TYPE ExWindowStationObjectType
Definition: win32k.c:21
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:2385
NTSTATUS GetProcessLuid(IN PETHREAD Thread OPTIONAL, IN PEPROCESS Process OPTIONAL, OUT PLUID Luid)
Definition: misc.c:814
NTSTATUS NTAPI IntCreateServiceSecurity(_Out_ PSECURITY_DESCRIPTOR *ServiceSd)
Creates a security descriptor for the service.
Definition: security.c:327
VOID IntFreeSecurityBuffer(_In_ PVOID Buffer)
Frees an allocated security buffer from UM memory that is been previously allocated by IntAllocateSec...
Definition: security.c:133
#define WINSTA_ACCESS_ALL
Definition: security.h:57
#define WSS_NOIO
Definition: winsta.h:9
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:64
#define DUPLICATE_SAME_ACCESS
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:304
#define SYSTEM_LUID
Definition: setypes.h:700
#define ZwCurrentProcess()

Referenced by InitThreadCallback(), and NtUserResolveDesktop().

◆ IntSetFocusMessageQueue()

VOID FASTCALL IntSetFocusMessageQueue ( PUSER_MESSAGE_QUEUE  NewQueue)

Definition at line 1336 of file desktop.c.

1337{
1340 if (!pdo)
1341 {
1342 TRACE("No active desktop\n");
1343 return;
1344 }
1345 if (NewQueue != NULL)
1346 {
1347 if (NewQueue->Desktop != NULL)
1348 {
1349 TRACE("Message Queue already attached to another desktop!\n");
1350 return;
1351 }
1352 IntReferenceMessageQueue(NewQueue);
1353 (void)InterlockedExchangePointer((PVOID*)&NewQueue->Desktop, pdo);
1354 }
1356 if (Old != NULL)
1357 {
1359 gpqForegroundPrev = Old;
1361 }
1362 // Only one Q can have active foreground even when there are more than one desktop.
1363 if (NewQueue)
1364 {
1366 }
1367 else
1368 {
1370 ERR("ptiLastInput is CLEARED!!\n");
1371 ptiLastInput = NULL; // ReactOS hacks... should check for process death.
1372 }
1373}
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
PUSER_MESSAGE_QUEUE gpqForeground
Definition: focus.c:13
PUSER_MESSAGE_QUEUE gpqForegroundPrev
Definition: focus.c:14
#define IntReferenceMessageQueue(MsgQueue)
Definition: msgqueue.h:217
#define IntDereferenceMessageQueue(MsgQueue)
Definition: msgqueue.h:220
struct _USER_MESSAGE_QUEUE * PUSER_MESSAGE_QUEUE
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 3293 of file desktop.c.

3295{
3296 PDESKTOP pdesk = NULL, pdeskOld;
3297 PTHREADINFO pti;
3299 PCLIENTTHREADINFO pctiOld, pctiNew = NULL;
3300 PCLIENTINFO pci;
3301
3303
3304 TRACE("IntSetThreadDesktop hDesktop:0x%p, FOF:%i\n",hDesktop, FreeOnFailure);
3305
3307 pci = pti->pClientInfo;
3308
3309 /* If the caller gave us a desktop, ensure it is valid */
3310 if (hDesktop != NULL)
3311 {
3312 /* Validate the new desktop. */
3313 Status = IntValidateDesktopHandle(hDesktop, UserMode, 0, &pdesk);
3314 if (!NT_SUCCESS(Status))
3315 {
3316 ERR("Validation of desktop handle 0x%p failed\n", hDesktop);
3317 return FALSE;
3318 }
3319
3320 if (pti->rpdesk == pdesk)
3321 {
3322 /* Nothing to do */
3323 ObDereferenceObject(pdesk);
3324 return TRUE;
3325 }
3326 }
3327
3328 /* Make sure that we don't own any window in the current desktop */
3329 if (!IsListEmpty(&pti->WindowListHead))
3330 {
3331 if (pdesk)
3332 ObDereferenceObject(pdesk);
3333 ERR("Attempted to change thread desktop although the thread has windows!\n");
3335 return FALSE;
3336 }
3337
3338 /* Desktop is being re-set so clear out foreground. */
3339 if (pti->rpdesk != pdesk && pti->MessageQueue == gpqForeground)
3340 {
3341 // Like above, there shouldn't be any windows, hooks or anything active on this threads desktop!
3343 }
3344
3345 /* Before doing the switch, map the new desktop heap and allocate the new pcti */
3346 if (pdesk != NULL)
3347 {
3348 Status = IntMapDesktopView(pdesk);
3349 if (!NT_SUCCESS(Status))
3350 {
3351 ERR("Failed to map desktop heap!\n");
3352 ObDereferenceObject(pdesk);
3354 return FALSE;
3355 }
3356
3357 pctiNew = DesktopHeapAlloc(pdesk, sizeof(CLIENTTHREADINFO));
3358 if (pctiNew == NULL)
3359 {
3360 ERR("Failed to allocate new pcti\n");
3361 IntUnmapDesktopView(pdesk);
3362 ObDereferenceObject(pdesk);
3364 return FALSE;
3365 }
3366 }
3367
3368 /*
3369 * Processes, in particular Winlogon.exe, that manage window stations
3370 * (especially the interactive WinSta0 window station) and desktops,
3371 * may not be able to connect at startup to a window station and have
3372 * an associated desktop as well, if none exists on the system already.
3373 * Because creating a new window station does not affect the window station
3374 * associated to the process, and because neither by associating a window
3375 * station to the process nor creating a new desktop on it does associate
3376 * a startup desktop to that process, the process has to actually assigns
3377 * one of its threads to a desktop so that it gets automatically an assigned
3378 * startup desktop.
3379 *
3380 * This is what actually happens for Winlogon.exe, which is started without
3381 * any window station and desktop. By creating the first (and therefore
3382 * interactive) WinSta0 window station, then assigning WinSta0 to itself
3383 * and creating the Default desktop on it, and then assigning this desktop
3384 * to its main thread, Winlogon.exe basically does the similar steps that
3385 * would have been done automatically at its startup if there were already
3386 * an existing WinSta0 window station and Default desktop.
3387 *
3388 * Of course all this must not be done if we are a SYSTEM or CSRSS thread.
3389 */
3390 // if (pti->ppi->peProcess != gpepCSRSS)
3391 if (!(pti->TIF_flags & (TIF_SYSTEMTHREAD | TIF_CSRSSTHREAD)) &&
3392 pti->ppi->rpdeskStartup == NULL && hDesktop != NULL)
3393 {
3394 ERR("The process 0x%p '%s' didn't have an assigned startup desktop before, assigning it now!\n",
3395 pti->ppi->peProcess, pti->ppi->peProcess->ImageFileName);
3396
3397 pti->ppi->hdeskStartup = hDesktop;
3398 pti->ppi->rpdeskStartup = pdesk;
3399 }
3400
3401 /* free all classes or move them to the shared heap */
3402 if (pti->rpdesk != NULL)
3403 {
3404 if (!IntCheckProcessDesktopClasses(pti->rpdesk, FreeOnFailure))
3405 {
3406 ERR("Failed to move process classes to shared heap!\n");
3407 if (pdesk)
3408 {
3409 DesktopHeapFree(pdesk, pctiNew);
3410 IntUnmapDesktopView(pdesk);
3411 ObDereferenceObject(pdesk);
3412 }
3413 return FALSE;
3414 }
3415 }
3416
3417 pdeskOld = pti->rpdesk;
3418 if (pti->pcti != &pti->cti)
3419 pctiOld = pti->pcti;
3420 else
3421 pctiOld = NULL;
3422
3423 /* do the switch */
3424 if (pdesk != NULL)
3425 {
3426 pti->rpdesk = pdesk;
3427 pti->hdesk = hDesktop;
3428 pti->pDeskInfo = pti->rpdesk->pDeskInfo;
3429 pti->pcti = pctiNew;
3430
3432 pci->pDeskInfo = (PVOID)((ULONG_PTR)pti->pDeskInfo - pci->ulClientDelta);
3433 pci->pClientThreadInfo = (PVOID)((ULONG_PTR)pti->pcti - pci->ulClientDelta);
3434
3435 /* initialize the new pcti */
3436 if (pctiOld != NULL)
3437 {
3438 RtlCopyMemory(pctiNew, pctiOld, sizeof(CLIENTTHREADINFO));
3439 }
3440 else
3441 {
3442 RtlZeroMemory(pctiNew, sizeof(CLIENTTHREADINFO));
3443 pci->fsHooks = pti->fsHooks;
3444 pci->dwTIFlags = pti->TIF_flags;
3445 }
3446 }
3447 else
3448 {
3449 pti->rpdesk = NULL;
3450 pti->hdesk = NULL;
3451 pti->pDeskInfo = NULL;
3452 pti->pcti = &pti->cti; // Always point inside so there will be no crash when posting or sending msg's!
3453 pci->ulClientDelta = 0;
3454 pci->pDeskInfo = NULL;
3455 pci->pClientThreadInfo = NULL;
3456 }
3457
3458 /* clean up the old desktop */
3459 if (pdeskOld != NULL)
3460 {
3461 RemoveEntryList(&pti->PtiLink);
3462 if (pctiOld) DesktopHeapFree(pdeskOld, pctiOld);
3463 IntUnmapDesktopView(pdeskOld);
3464 ObDereferenceObject(pdeskOld);
3465 }
3466
3467 if (pdesk)
3468 {
3469 InsertTailList(&pdesk->PtiList, &pti->PtiLink);
3470 }
3471
3472 TRACE("IntSetThreadDesktop: pti 0x%p ppi 0x%p switched from object 0x%p to 0x%p\n", pti, pti->ppi, pdeskOld, pdesk);
3473
3474 return TRUE;
3475}
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_BUSY
Definition: dderror.h:12
static __inline ULONG_PTR DesktopHeapGetUserDelta(VOID)
Definition: desktop.h:272
static __inline PVOID DesktopHeapAlloc(IN PDESKTOP Desktop, IN SIZE_T Bytes)
Definition: desktop.h:204
static __inline BOOL DesktopHeapFree(IN PDESKTOP Desktop, IN PVOID lpMem)
Definition: desktop.h:215
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define TIF_CSRSSTHREAD
Definition: ntuser.h:266
#define TIF_SYSTEMTHREAD
Definition: ntuser.h:265
#define NtCurrentTeb
ULONG_PTR ulClientDelta
Definition: ntuser.h:326
ULONG fsHooks
Definition: ntuser.h:328
PCLIENTTHREADINFO pClientThreadInfo
Definition: ntuser.h:332
DWORD dwTIFlags
Definition: ntuser.h:324
PDESKTOPINFO pDeskInfo
Definition: ntuser.h:325
LIST_ENTRY PtiList
Definition: desktop.h:25
ULONG fsHooks
Definition: win32.h:117
CLIENTTHREADINFO cti
Definition: win32.h:144
struct _CLIENTTHREADINFO * pcti
Definition: win32.h:91
LIST_ENTRY WindowListHead
Definition: win32.h:155
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:89
LIST_ENTRY PtiLink
Definition: win32.h:126
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
BOOL IntCheckProcessDesktopClasses(IN PDESKTOP Desktop, IN BOOL FreeOnFailure)
Definition: class.c:1017
VOID FASTCALL IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue)
Definition: desktop.c:1336
NTSTATUS FASTCALL IntValidateDesktopHandle(HDESK Desktop, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PDESKTOP *Object)
Definition: desktop.c:1254
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:21

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

◆ IntUnmapDesktopView()

static NTSTATUS IntUnmapDesktopView ( IN PDESKTOP  pdesk)
static

Definition at line 3175 of file desktop.c.

3176{
3177 PPROCESSINFO ppi;
3178 PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
3180
3181 TRACE("IntUnmapDesktopView called for desktop object %p\n", pdesk);
3182
3184
3185 /*
3186 * Unmap if we're the last thread using the desktop.
3187 * Start the search at the next mapping: skip the first entry
3188 * as it must be the global user heap mapping.
3189 */
3190 PrevLink = &ppi->HeapMappings.Next;
3191 HeapMapping = *PrevLink;
3192 while (HeapMapping != NULL)
3193 {
3194 if (HeapMapping->KernelMapping == (PVOID)pdesk->pheapDesktop)
3195 {
3196 if (--HeapMapping->Count == 0)
3197 {
3198 *PrevLink = HeapMapping->Next;
3199
3200 TRACE("ppi 0x%p unmapped heap of desktop 0x%p\n", ppi, pdesk);
3202 HeapMapping->UserMapping);
3203
3204 ObDereferenceObject(pdesk);
3205
3206 UserHeapFree(HeapMapping);
3207 break;
3208 }
3209 }
3210
3211 PrevLink = &HeapMapping->Next;
3212 HeapMapping = HeapMapping->Next;
3213 }
3214
3215 return Status;
3216}
static __inline BOOL UserHeapFree(PVOID lpMem)
Definition: usrheap.h:44

Referenced by IntDesktopObjectClose(), and IntSetThreadDesktop().

◆ IntValidateDesktopHandle()

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

Definition at line 1254 of file desktop.c.

1259{
1261
1265 AccessMode,
1266 (PVOID*)Object,
1267 NULL);
1268
1269 TRACE("IntValidateDesktopHandle: handle:0x%p obj:0x%p access:0x%x Status:0x%lx\n",
1271
1272 if (!NT_SUCCESS(Status))
1274
1275 return Status;
1276}
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664

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

◆ NtUserCloseDesktop()

BOOL APIENTRY NtUserCloseDesktop ( HDESK  hDesktop)

Definition at line 2755 of file desktop.c.

2756{
2757 PDESKTOP pdesk;
2759 BOOL Ret = FALSE;
2760
2761 TRACE("NtUserCloseDesktop(0x%p) called\n", hDesktop);
2763
2764 if (hDesktop == gptiCurrent->hdesk || hDesktop == gptiCurrent->ppi->hdeskStartup)
2765 {
2766 ERR("Attempted to close thread desktop\n");
2768 goto Exit; // Return FALSE
2769 }
2770
2771 Status = IntValidateDesktopHandle(hDesktop, UserMode, 0, &pdesk);
2772 if (!NT_SUCCESS(Status))
2773 {
2774 ERR("Validation of desktop handle 0x%p failed\n", hDesktop);
2775 goto Exit; // Return FALSE
2776 }
2777
2778 ObDereferenceObject(pdesk);
2779
2780 Status = ObCloseHandle(hDesktop, UserMode);
2781 if (!NT_SUCCESS(Status))
2782 {
2783 ERR("Failed to close desktop handle 0x%p\n", hDesktop);
2785 goto Exit; // Return FALSE
2786 }
2787
2788 Ret = TRUE;
2789
2790Exit:
2791 TRACE("Leave NtUserCloseDesktop, ret=%i\n", Ret);
2792 UserLeave();
2793 return Ret;
2794}
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
static void Exit(void)
Definition: sock.c:1330

Referenced by CloseDesktop().

◆ NtUserCreateDesktop()

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

Definition at line 2562 of file desktop.c.

2568{
2570 HDESK hDesk;
2571 HDESK Ret = NULL;
2572
2573 TRACE("Enter NtUserCreateDesktop\n");
2575
2576 Status = IntCreateDesktop(&hDesk,
2578 UserMode,
2579 lpszDesktopDevice,
2580 lpdmw,
2581 dwFlags,
2582 dwDesiredAccess);
2583 if (!NT_SUCCESS(Status))
2584 {
2585 ERR("IntCreateDesktop failed, Status 0x%08lx\n", Status);
2586 // SetLastNtError(Status);
2587 goto Exit; // Return NULL
2588 }
2589
2590 Ret = hDesk;
2591
2592Exit:
2593 TRACE("Leave NtUserCreateDesktop, ret=0x%p\n", Ret);
2594 UserLeave();
2595 return Ret;
2596}
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141

Referenced by CreateDesktopW().

◆ NtUserGetThreadDesktop()

HDESK APIENTRY NtUserGetThreadDesktop ( DWORD  dwThreadId,
HDESK  hConsoleDesktop 
)

Definition at line 3066 of file desktop.c.

3067{
3068 HDESK hDesk;
3070 PTHREADINFO pti;
3072 PDESKTOP DesktopObject;
3074
3076 TRACE("Enter NtUserGetThreadDesktop\n");
3077
3078 if (!dwThreadId)
3079 {
3081 hDesk = NULL;
3082 goto Quit;
3083 }
3084
3085 /* Validate the Win32 thread and retrieve its information */
3087 if (pti)
3088 {
3089 /* Get the desktop handle of the thread */
3090 hDesk = pti->hdesk;
3091 Process = pti->ppi->peProcess;
3092 }
3093 else if (hConsoleDesktop)
3094 {
3095 /*
3096 * The thread may belong to a console, so attempt to use the provided
3097 * console desktop handle as a fallback. Otherwise this means that the
3098 * thread is either not Win32 or invalid.
3099 */
3100 hDesk = hConsoleDesktop;
3102 }
3103 else
3104 {
3106 hDesk = NULL;
3107 goto Quit;
3108 }
3109
3110 if (!hDesk)
3111 {
3112 ERR("Desktop information of thread 0x%x broken!?\n", dwThreadId);
3113 goto Quit;
3114 }
3115
3117 {
3118 /*
3119 * Just return the handle, since we queried the desktop handle
3120 * of a thread running in the same context.
3121 */
3122 goto Quit;
3123 }
3124
3125 /*
3126 * We could just use the cached rpdesk instead of looking up the handle,
3127 * but it may actually be safer to validate the desktop and get a temporary
3128 * reference to it so that it does not disappear under us (e.g. when the
3129 * desktop is being destroyed) during the operation.
3130 */
3131 /*
3132 * Switch into the context of the thread we are trying to get
3133 * the desktop from, so we can use the handle.
3134 */
3135 KeAttachProcess(&Process->Pcb);
3137 0,
3139 UserMode,
3140 (PVOID*)&DesktopObject,
3143
3144 if (NT_SUCCESS(Status))
3145 {
3146 /*
3147 * Lookup our handle table if we can find a handle to the desktop object.
3148 * If not, create one.
3149 * QUESTION: Do we really need to create a handle in case it doesn't exist??
3150 */
3151 hDesk = IntGetDesktopObjectHandle(DesktopObject);
3152
3153 /* All done, we got a valid handle to the desktop */
3154 ObDereferenceObject(DesktopObject);
3155 }
3156 else
3157 {
3158 /* The handle could not be found, there is nothing to get... */
3159 hDesk = NULL;
3160 }
3161
3162 if (!hDesk)
3163 {
3164 ERR("Could not retrieve or access desktop for thread 0x%x\n", dwThreadId);
3166 }
3167
3168Quit:
3169 TRACE("Leave NtUserGetThreadDesktop, hDesk = 0x%p\n", hDesk);
3170 UserLeave();
3171 return hDesk;
3172}
#define UlongToHandle(ul)
Definition: basetsd.h:91
PEPROCESS gpepCSRSS
Definition: csr.c:15
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
DWORD dwThreadId
Definition: fdebug.c:31
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:621
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:582
HDESK FASTCALL IntGetDesktopObjectHandle(PDESKTOP DesktopObject)
Definition: desktop.c:1288
PTHREADINFO FASTCALL IntTID2PTI(HANDLE id)
Definition: misc.c:41
_In_ ACCESS_MASK _In_opt_ POBJECT_TYPE _In_ KPROCESSOR_MODE _Out_ PVOID _Out_opt_ POBJECT_HANDLE_INFORMATION HandleInformation
Definition: obfuncs.h:44

Referenced by GetThreadDesktop().

◆ NtUserOpenDesktop()

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

Definition at line 2621 of file desktop.c.

2625{
2627 HDESK Desktop;
2628
2632 UserMode,
2633 NULL,
2634 dwDesiredAccess,
2635 NULL,
2636 (HANDLE*)&Desktop);
2637
2638 if (!NT_SUCCESS(Status))
2639 {
2640 ERR("Failed to open desktop\n");
2642 return NULL;
2643 }
2644
2645 TRACE("Opened desktop %S with handle 0x%p\n", ObjectAttributes->ObjectName->Buffer, Desktop);
2646
2647 return Desktop;
2648}

Referenced by OpenDesktopW().

◆ NtUserOpenInputDesktop()

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

Definition at line 2715 of file desktop.c.

2719{
2720 HDESK hdesk;
2721
2723 TRACE("Enter NtUserOpenInputDesktop gpdeskInputDesktop 0x%p\n", gpdeskInputDesktop);
2724
2725 hdesk = UserOpenInputDesktop(dwFlags, fInherit, dwDesiredAccess);
2726
2727 TRACE("NtUserOpenInputDesktop returning 0x%p\n", hdesk);
2728 UserLeave();
2729 return hdesk;
2730}

Referenced by OpenInputDesktop().

◆ NtUserPaintDesktop()

BOOL APIENTRY NtUserPaintDesktop ( HDC  hDC)

Definition at line 2812 of file desktop.c.

2813{
2814 BOOL Ret;
2815
2817 TRACE("Enter NtUserPaintDesktop\n");
2818
2819 Ret = IntPaintDesktop(hDC);
2820
2821 TRACE("Leave NtUserPaintDesktop, ret=%i\n", Ret);
2822 UserLeave();
2823 return Ret;
2824}

Referenced by PaintDesktop().

◆ NtUserResolveDesktop()

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

Definition at line 2862 of file desktop.c.

2867{
2870 HWINSTA hWinSta = NULL;
2871 HDESK hDesktop = NULL;
2872 UNICODE_STRING CapturedDesktopPath;
2873
2874 /* Allow only the Console Server to perform this operation (via CSRSS) */
2876 return NULL;
2877
2878 /* Get the process object the user handle was referencing */
2882 UserMode,
2883 (PVOID*)&Process,
2884 NULL);
2885 if (!NT_SUCCESS(Status))
2886 return NULL;
2887
2889
2890 _SEH2_TRY
2891 {
2892 /* Probe the handle pointer */
2893 // ProbeForWriteHandle
2894 ProbeForWrite(phWinSta, sizeof(HWINSTA), sizeof(HWINSTA));
2895 }
2897 {
2899 _SEH2_YIELD(goto Quit);
2900 }
2901 _SEH2_END;
2902
2903 /* Capture the user desktop path string */
2904 Status = ProbeAndCaptureUnicodeString(&CapturedDesktopPath,
2905 UserMode,
2906 DesktopPath);
2907 if (!NT_SUCCESS(Status))
2908 goto Quit;
2909
2910 /* Call the internal function */
2912 &CapturedDesktopPath,
2913 bInherit,
2914 &hWinSta,
2915 &hDesktop);
2916 if (!NT_SUCCESS(Status))
2917 {
2918 ERR("IntResolveDesktop failed, Status 0x%08lx\n", Status);
2919 hWinSta = NULL;
2920 hDesktop = NULL;
2921 }
2922
2923 _SEH2_TRY
2924 {
2925 /* Return the window station handle */
2926 *phWinSta = hWinSta;
2927 }
2929 {
2931
2932 /* We failed, close the opened desktop and window station */
2933 if (hDesktop) ObCloseHandle(hDesktop, UserMode);
2934 hDesktop = NULL;
2935 if (hWinSta) ObCloseHandle(hWinSta, UserMode);
2936 }
2937 _SEH2_END;
2938
2939 /* Free the captured string */
2940 ReleaseCapturedUnicodeString(&CapturedDesktopPath, UserMode);
2941
2942Quit:
2943 UserLeave();
2944
2945 /* Dereference the process object */
2947
2948 /* Return the desktop handle */
2949 return hDesktop;
2950}
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:162
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
NTSTATUS FASTCALL IntResolveDesktop(IN PEPROCESS Process, IN PUNICODE_STRING DesktopPath, IN BOOL bInherit, OUT HWINSTA *phWinSta, OUT HDESK *phDesktop)
Definition: desktop.c:568

Referenced by GuiInit().

◆ NtUserSetThreadDesktop()

BOOL APIENTRY NtUserSetThreadDesktop ( HDESK  hDesktop)

Definition at line 3485 of file desktop.c.

3486{
3487 BOOL ret = FALSE;
3488
3490
3491 // FIXME: IntSetThreadDesktop validates the desktop handle, it should happen
3492 // here too and set the NT error level. Q. Is it necessary to have the validation
3493 // in IntSetThreadDesktop? Is it needed there too?
3494 if (hDesktop || (!hDesktop && PsGetCurrentProcess() == gpepCSRSS))
3495 ret = IntSetThreadDesktop(hDesktop, FALSE);
3496
3497 UserLeave();
3498
3499 return ret;
3500}
return ret
Definition: mutex.c:146

Referenced by SetThreadDesktop().

◆ NtUserSwitchDesktop()

BOOL APIENTRY NtUserSwitchDesktop ( HDESK  hdesk)

Definition at line 2969 of file desktop.c.

2970{
2971 PDESKTOP pdesk;
2973 BOOL bRedrawDesktop;
2974 BOOL Ret = FALSE;
2975
2977 TRACE("Enter NtUserSwitchDesktop(0x%p)\n", hdesk);
2978
2979 Status = IntValidateDesktopHandle(hdesk, UserMode, 0, &pdesk);
2980 if (!NT_SUCCESS(Status))
2981 {
2982 ERR("Validation of desktop handle 0x%p failed\n", hdesk);
2983 goto Exit; // Return FALSE
2984 }
2985
2986 if (PsGetCurrentProcessSessionId() != pdesk->rpwinstaParent->dwSessionId)
2987 {
2988 ObDereferenceObject(pdesk);
2989 ERR("NtUserSwitchDesktop called for a desktop of a different session\n");
2990 goto Exit; // Return FALSE
2991 }
2992
2993 if (pdesk == gpdeskInputDesktop)
2994 {
2995 ObDereferenceObject(pdesk);
2996 WARN("NtUserSwitchDesktop called for active desktop\n");
2997 Ret = TRUE;
2998 goto Exit;
2999 }
3000
3001 /*
3002 * Don't allow applications switch the desktop if it's locked, unless the caller
3003 * is the logon application itself
3004 */
3005 if ((pdesk->rpwinstaParent->Flags & WSS_LOCKED) &&
3007 {
3008 ObDereferenceObject(pdesk);
3009 ERR("Switching desktop 0x%p denied because the window station is locked!\n", hdesk);
3010 goto Exit; // Return FALSE
3011 }
3012
3013 if (pdesk->rpwinstaParent != InputWindowStation)
3014 {
3015 ObDereferenceObject(pdesk);
3016 ERR("Switching desktop 0x%p denied because desktop doesn't belong to the interactive winsta!\n", hdesk);
3017 goto Exit; // Return FALSE
3018 }
3019
3020 /* FIXME: Fail if the process is associated with a secured
3021 desktop such as Winlogon or Screen-Saver */
3022 /* FIXME: Connect to input device */
3023
3024 TRACE("Switching from desktop 0x%p to 0x%p\n", gpdeskInputDesktop, pdesk);
3025
3026 bRedrawDesktop = FALSE;
3027
3028 /* The first time SwitchDesktop is called, gpdeskInputDesktop is NULL */
3029 if (gpdeskInputDesktop != NULL)
3030 {
3032 bRedrawDesktop = TRUE;
3033
3034 /* Hide the previous desktop window */
3036 }
3037
3038 /* Set the active desktop in the desktop's window station. */
3040
3041 /* Set the global state. */
3042 gpdeskInputDesktop = pdesk;
3043
3044 /* Show the new desktop window */
3046
3047 TRACE("SwitchDesktop gpdeskInputDesktop 0x%p\n", gpdeskInputDesktop);
3048 ObDereferenceObject(pdesk);
3049
3050 Ret = TRUE;
3051
3052Exit:
3053 TRACE("Leave NtUserSwitchDesktop, ret=%i\n", Ret);
3054 UserLeave();
3055 return Ret;
3056}
#define WARN(fmt,...)
Definition: precomp.h:61
#define WS_VISIBLE
Definition: pedump.c:620
HANDLE gpidLogon
Definition: simplecall.c:15
struct _DESKTOP * ActiveDesktop
Definition: winsta.h:42
NTSTATUS FASTCALL IntHideDesktop(PDESKTOP Desktop)
Definition: desktop.c:1647
NTSTATUS FASTCALL co_IntShowDesktop(PDESKTOP Desktop, ULONG Width, ULONG Height, BOOL bRedraw)
Definition: desktop.c:1629
#define WSS_LOCKED
Definition: winsta.h:7

Referenced by SwitchDesktop().

◆ UserBuildShellHookHwndList()

static HWND *FASTCALL UserBuildShellHookHwndList ( PDESKTOP  Desktop)
static

Definition at line 1663 of file desktop.c.

1664{
1665 ULONG entries=0;
1666 PLIST_ENTRY ListEntry;
1667 PSHELL_HOOK_WINDOW Current;
1668 HWND* list;
1669
1670 /* FIXME: If we save nb elements in desktop, we don't have to loop to find nb entries */
1671 ListEntry = Desktop->ShellHookWindows.Flink;
1672 while (ListEntry != &Desktop->ShellHookWindows)
1673 {
1674 ListEntry = ListEntry->Flink;
1675 entries++;
1676 }
1677
1678 if (!entries) return NULL;
1679
1680 list = ExAllocatePoolWithTag(PagedPool, sizeof(HWND) * (entries + 1), USERTAG_WINDOWLIST); /* alloc one extra for nullterm */
1681 if (list)
1682 {
1683 HWND* cursor = list;
1684
1685 ListEntry = Desktop->ShellHookWindows.Flink;
1686 while (ListEntry != &Desktop->ShellHookWindows)
1687 {
1688 Current = CONTAINING_RECORD(ListEntry, SHELL_HOOK_WINDOW, ListEntry);
1689 ListEntry = ListEntry->Flink;
1690 *cursor++ = Current->hWnd;
1691 }
1692
1693 *cursor = NULL; /* Nullterm list */
1694 }
1695
1696 return list;
1697}
Definition: list.h:37
#define list
Definition: rosglue.h:35

Referenced by co_IntShellHookNotify().

◆ UserGetDesktopDC()

HDC FASTCALL UserGetDesktopDC ( ULONG  DcType,
BOOL  bAltDc,
BOOL  ValidatehWnd 
)

Definition at line 1586 of file desktop.c.

1587{
1588 PWND DesktopObject = 0;
1589 HDC DesktopHDC = 0;
1590
1591 /* This can be called from GDI/DX, so acquire the USER lock */
1593
1594 if (DcType == DCTYPE_DIRECT)
1595 {
1596 DesktopObject = UserGetDesktopWindow();
1597 DesktopHDC = (HDC)UserGetWindowDC(DesktopObject);
1598 }
1599 else
1600 {
1601 PMONITOR pMonitor = UserGetPrimaryMonitor();
1602 DesktopHDC = IntGdiCreateDisplayDC(pMonitor->hDev, DcType, bAltDc);
1603 }
1604
1605 UserLeave();
1606
1607 return DesktopHDC;
1608}
@ DCTYPE_DIRECT
Definition: dc.h:41
HDC FASTCALL IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC)
Definition: dclife.c:1063
HDEV hDev
Definition: monitor.h:23
HDC FASTCALL UserGetWindowDC(PWND Wnd)
Definition: windc.c:947
PWND FASTCALL UserGetDesktopWindow(VOID)
Definition: desktop.c:1402
PMONITOR NTAPI UserGetPrimaryMonitor(VOID)
Definition: monitor.c:102

Referenced by DxEngGetDesktopDC().

◆ UserGetDesktopWindow()

◆ UserGetMessageWindow()

PWND FASTCALL UserGetMessageWindow ( VOID  )

Definition at line 1425 of file desktop.c.

1426{
1428 if (!pdo)
1429 {
1430 TRACE("No active desktop\n");
1431 return NULL;
1432 }
1433 return pdo->spwndMessage;
1434}

◆ UserInitializeDesktop()

static NTSTATUS UserInitializeDesktop ( PDESKTOP  pdesk,
PUNICODE_STRING  DesktopName,
PWINSTATION_OBJECT  pwinsta 
)
static

Definition at line 2274 of file desktop.c.

2275{
2276 static const UNICODE_STRING WinlogonDesktop = RTL_CONSTANT_STRING(L"Winlogon");
2277 PVOID DesktopHeapSystemBase = NULL;
2279 SIZE_T DesktopInfoSize;
2280 ULONG i;
2281
2282 TRACE("UserInitializeDesktop desktop 0x%p with name %wZ\n", pdesk, DesktopName);
2283
2284 RtlZeroMemory(pdesk, sizeof(DESKTOP));
2285
2286 /* Set desktop size, based on whether the WinSta is interactive or not */
2287 if (pwinsta == InputWindowStation)
2288 {
2289 /* Check if the Desktop is named "Winlogon" */
2290 if (RtlEqualUnicodeString(DesktopName, &WinlogonDesktop, TRUE))
2291 {
2293 }
2294 else
2295 {
2297 }
2298 }
2299 else
2300 {
2302 }
2303
2304 /* Link the desktop with the parent window station */
2305 ObReferenceObject(pwinsta);
2306 pdesk->rpwinstaParent = pwinsta;
2307 InsertTailList(&pwinsta->DesktopListHead, &pdesk->ListEntry);
2308
2309 /* Create the desktop heap */
2310 pdesk->hsectionDesktop = NULL;
2312 &DesktopHeapSystemBase,
2313 HeapSize);
2314 if (pdesk->pheapDesktop == NULL)
2315 {
2316 ERR("Failed to create desktop heap!\n");
2317 return STATUS_NO_MEMORY;
2318 }
2319
2320 /* Create DESKTOPINFO */
2321 DesktopInfoSize = sizeof(DESKTOPINFO) + DesktopName->Length + sizeof(WCHAR);
2322 pdesk->pDeskInfo = RtlAllocateHeap(pdesk->pheapDesktop,
2324 DesktopInfoSize);
2325 if (pdesk->pDeskInfo == NULL)
2326 {
2327 ERR("Failed to create the DESKTOP structure!\n");
2328 return STATUS_NO_MEMORY;
2329 }
2330
2331 /* Initialize the DESKTOPINFO */
2332 pdesk->pDeskInfo->pvDesktopBase = DesktopHeapSystemBase;
2333 pdesk->pDeskInfo->pvDesktopLimit = (PVOID)((ULONG_PTR)DesktopHeapSystemBase + HeapSize);
2335 DesktopName->Buffer,
2336 DesktopName->Length + sizeof(WCHAR));
2337 for (i = 0; i < NB_HOOKS; i++)
2338 {
2340 }
2341
2343 InitializeListHead(&pdesk->PtiList);
2344
2345 return STATUS_SUCCESS;
2346}
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
struct _DESKTOPINFO DESKTOPINFO
#define NB_HOOKS
Definition: ntuser.h:127
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1695
WCHAR szDesktopName[1]
Definition: ntuser.h:158
LIST_ENTRY aphkStart[NB_HOOKS]
Definition: ntuser.h:139
PVOID pvDesktopLimit
Definition: ntuser.h:136
PVOID pvDesktopBase
Definition: ntuser.h:135
PVOID hsectionDesktop
Definition: desktop.h:22
LIST_ENTRY ShellHookWindows
Definition: desktop.h:43
PWIN32HEAP pheapDesktop
Definition: desktop.h:23
PWIN32HEAP UserCreateHeap(OUT PVOID *SectionObject, IN OUT PVOID *SystemBase, IN SIZE_T HeapSize)
Definition: usrheap.c:181
DWORD gdwDesktopSectionSize
Definition: desktop.c:46
DWORD gdwNOIOSectionSize
Definition: desktop.c:48
DWORD gdwWinlogonSectionSize
Definition: desktop.c:49
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)

Referenced by IntDesktopObjectParse().

◆ UserMessageWindowProc()

BOOL FASTCALL UserMessageWindowProc ( PWND  pwnd,
UINT  Msg,
WPARAM  wParam,
LPARAM  lParam,
LRESULT lResult 
)

Definition at line 1537 of file desktop.c.

1538{
1539 *lResult = 0;
1540
1541 switch(Msg)
1542 {
1543 case WM_NCCREATE:
1544 pwnd->fnid |= FNID_MESSAGEWND;
1545 *lResult = (LRESULT)TRUE;
1546 break;
1547 case WM_DESTROY:
1548 pwnd->fnid |= FNID_DESTROY;
1549 break;
1550 default:
1551 ERR("UMWP calling IDWP\n");
1552 *lResult = IntDefWindowProc(pwnd, Msg, wParam, lParam, FALSE);
1553 }
1554
1555 return TRUE; /* We are done. Do not do any callbacks to user mode */
1556}
#define FNID_DESTROY
Definition: ntuser.h:898
LRESULT FASTCALL IntDefWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL Ansi)
Definition: defwnd.c:633
#define WM_DESTROY
Definition: winuser.h:1637

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

◆ UserOpenInputDesktop()

HDESK UserOpenInputDesktop ( DWORD  dwFlags,
BOOL  fInherit,
ACCESS_MASK  dwDesiredAccess 
)

Definition at line 2650 of file desktop.c.

2653{
2657 HDESK hdesk = NULL;
2658
2659 if (!gpdeskInputDesktop)
2660 {
2661 return NULL;
2662 }
2663
2664 if (pti->ppi->prpwinsta != InputWindowStation)
2665 {
2666 ERR("Tried to open input desktop from non interactive winsta!\n");
2668 return NULL;
2669 }
2670
2671 if (fInherit) HandleAttributes = OBJ_INHERIT;
2672
2673 /* Create a new handle to the object */
2677 NULL,
2678 dwDesiredAccess,
2680 UserMode,
2681 (PHANDLE)&hdesk);
2682
2683 if (!NT_SUCCESS(Status))
2684 {
2685 ERR("Failed to open input desktop object\n");
2687 }
2688
2689 return hdesk;
2690}
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE _In_ ACCESS_MASK _In_ ULONG HandleAttributes
Definition: obfuncs.h:433

Referenced by DesktopWindowProc(), and NtUserOpenInputDesktop().

◆ UserRedrawDesktop()

VOID APIENTRY UserRedrawDesktop ( VOID  )

Definition at line 1611 of file desktop.c.

1612{
1613 PWND Window = NULL;
1614 PREGION Rgn;
1615
1617 Rgn = IntSysCreateRectpRgnIndirect(&Window->rcWindow);
1618
1620 Rgn,
1623
1624 REGION_Delete(Rgn);
1625}
#define IntSysCreateRectpRgnIndirect(prc)
Definition: region.h:93
Definition: window.c:28
Definition: region.h:8
VOID FASTCALL IntInvalidateWindows(PWND Wnd, PREGION Rgn, ULONG Flags)
Definition: painting.c:643
VOID FASTCALL REGION_Delete(PREGION pRgn)
Definition: region.c:2449
#define RDW_FRAME
Definition: winuser.h:1223

Referenced by DxEngRedrawDesktop(), NtUserSetSysColors(), UserChangeDisplaySettings(), and UserRefreshDisplay().

Variable Documentation

◆ gDesktopCursor

HCURSOR gDesktopCursor = NULL

Definition at line 55 of file desktop.c.

Referenced by co_IntLoadDefaultCursors(), and DesktopWindowProc().

◆ gdwDesktopSectionSize

DWORD gdwDesktopSectionSize = 3 * 1024

Definition at line 46 of file desktop.c.

Referenced by UserInitializeDesktop().

◆ gdwNOIOSectionSize

DWORD gdwNOIOSectionSize = 128

Definition at line 48 of file desktop.c.

Referenced by UserInitializeDesktop().

◆ gdwWinlogonSectionSize

DWORD gdwWinlogonSectionSize = 128

Definition at line 49 of file desktop.c.

Referenced by UserInitializeDesktop().

◆ gpdeskInputDesktop

◆ gpDesktopThreadStartedEvent

PKEVENT gpDesktopThreadStartedEvent = NULL

Definition at line 56 of file desktop.c.

Referenced by DesktopThreadMain(), InitDesktopImpl(), and IntCreateWindowStation().

◆ gptiDesktopThread

◆ ScreenDeviceContext