ReactOS 0.4.17-dev-470-gf9e3448
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 1389 of file desktop.c.

1390{
1391 if (pWnd->head.rpdesk &&
1392 pWnd->head.rpdesk->pDeskInfo)
1393 return pWnd->head.rpdesk->pDeskInfo->spwnd;
1394 return NULL;
1395}
#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 1707 of file desktop.c.

1708{
1710 HWND* HwndList;
1711
1712 if (!gpsi->uiShellMsg)
1713 {
1714 gpsi->uiShellMsg = IntAddAtom(L"SHELLHOOK");
1715
1716 TRACE("MsgType = %x\n", gpsi->uiShellMsg);
1717 if (!gpsi->uiShellMsg)
1718 ERR("LastError: %x\n", EngGetLastError());
1719 }
1720
1721 if (!Desktop)
1722 {
1723 TRACE("IntShellHookNotify: No desktop!\n");
1724 return;
1725 }
1726
1727 // Allow other devices have a shot at foreground.
1728 if (Message == HSHELL_APPCOMMAND) ptiLastInput = NULL;
1729
1730 // FIXME: System Tray Support.
1731
1733 if (HwndList)
1734 {
1735 HWND* cursor = HwndList;
1736 LPARAM shellhookparam = (Message == HSHELL_LANGUAGE || Message == HSHELL_APPCOMMAND)
1737 ? lParam : (LPARAM)wParam;
1738
1739 for (; *cursor; cursor++)
1740 {
1741 TRACE("Sending notify\n");
1744 Message,
1745 shellhookparam);
1746/* co_IntPostOrSendMessage(*cursor,
1747 gpsi->uiShellMsg,
1748 Message,
1749 shellhookparam);*/
1750 }
1751
1753 }
1754
1755 if (ISITHOOKED(WH_SHELL))
1756 {
1758 }
1759}
#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:1285
static HWND *FASTCALL UserBuildShellHookHwndList(PDESKTOP Desktop)
Definition: desktop.c:1666
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 1632 of file desktop.c.

1633{
1634 PWND pwnd = Desktop->pDeskInfo->spwnd;
1636 ASSERT(pwnd);
1637
1638 if (!bRedraw)
1640
1642
1643 if (bRedraw)
1645
1646 return STATUS_SUCCESS;
1647}
GLbitfield flags
Definition: glext.h:7161
unsigned int UINT
Definition: sysinfo.c:13
#define ASSERT(a)
Definition: mode.c:44
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:897
_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 1561 of file desktop.c.

1562{
1563 BOOL Ret;
1564 MSG Msg;
1565
1567
1569
1570 /* Register system classes. This thread does not belong to any desktop so the
1571 classes will be allocated from the shared heap */
1573
1575
1576 while (TRUE)
1577 {
1578 Ret = co_IntGetPeekMessage(&Msg, 0, 0, 0, PM_REMOVE, TRUE);
1579 if (Ret)
1580 {
1582 }
1583 }
1584
1585 UserLeave();
1586}
struct @1777 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 1457 of file desktop.c.

1458{
1459 *lResult = 0;
1460
1461 switch (Msg)
1462 {
1463 case WM_NCCREATE:
1464 if (!Wnd->fnid)
1465 Wnd->fnid = FNID_DESKTOP;
1466 *lResult = (LRESULT)TRUE;
1467 return TRUE;
1468
1469 case WM_CREATE:
1470 {
1471 /* Save process and thread IDs */
1472 ULONG Value;
1478 }
1479 case WM_CLOSE:
1480 return TRUE;
1481
1482 case WM_DISPLAYCHANGE:
1484 return TRUE;
1485
1486 case WM_ERASEBKGND:
1488 *lResult = (LRESULT)TRUE;
1489 return TRUE;
1490
1491 case WM_PAINT:
1492 {
1493 PAINTSTRUCT Ps;
1494 if (IntBeginPaint(Wnd, &Ps))
1495 IntEndPaint(Wnd, &Ps);
1496 return TRUE;
1497 }
1498
1499 case WM_SYSCOLORCHANGE:
1501 return TRUE;
1502
1503 case WM_SETCURSOR:
1504 {
1505 PCURICON_OBJECT pcurOld, pcurNew;
1507 if (!pcurNew)
1508 return TRUE;
1509
1510 pcurNew->CURSORF_flags |= CURSORF_CURRENT;
1511 pcurOld = UserSetCursor(pcurNew, FALSE);
1512 if (pcurOld)
1513 {
1514 pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
1515 UserDereferenceObject(pcurOld);
1516 }
1517 return TRUE;
1518 }
1519
1521 {
1522 PWINDOWPOS pWindowPos = (PWINDOWPOS)lParam;
1523 if ((pWindowPos->flags & SWP_SHOWWINDOW) != 0)
1524 {
1526 IntSetThreadDesktop(hdesk, FALSE);
1527 }
1528 break;
1529 }
1530
1531 default:
1532 TRACE("DWP calling IDWP Msg %d\n",Msg);
1533 *lResult = IntDefWindowProc(Wnd, Msg, wParam, lParam, FALSE);
1534 }
1535
1536 return TRUE; /* We are done. Do not do any callbacks to user mode */
1537}
#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
LRESULT FASTCALL IntDefWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL Ansi)
Definition: defwnd.c:633
#define LRESULT
Definition: ole.h:14
#define LOWORD(l)
Definition: pedump.c:82
#define __fallthrough
Definition: sal_old.h:314
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:1443
BOOL FASTCALL IntEndPaint(PWND Wnd, PPAINTSTRUCT Ps)
Definition: painting.c:1539
_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:2652
BOOL FASTCALL IntPaintDesktop(HDC hDC)
Definition: desktop.c:1852
BOOL IntSetThreadDesktop(IN HDESK hDesktop, IN BOOL FreeOnFailure)
Definition: desktop.c:3295
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:643
LONG FASTCALL co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
Definition: window.c:4025
#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 306 of file desktop.c.

310{
312
313 RTL_OSVERSIONINFOEXW VerInfo;
314 UNICODE_STRING BuildLabString;
315 UNICODE_STRING CSDVersionString;
316 RTL_QUERY_REGISTRY_TABLE VersionConfigurationTable[] =
317 {
318 {
319 NULL,
321 L"BuildLab",
322 &BuildLabString,
323 REG_NONE, NULL, 0
324 },
325 {
326 NULL,
328 L"CSDVersion",
329 &CSDVersionString,
330 REG_NONE, NULL, 0
331 },
332
333 {0}
334 };
335
336 WCHAR BuildLabBuffer[256];
337 WCHAR VersionBuffer[256];
338 PWCHAR EndBuffer;
339
340 VerInfo.dwOSVersionInfoSize = sizeof(VerInfo);
341
342 /*
343 * This call is uniquely used to retrieve the current CSD numbers.
344 * All the rest (major, minor, ...) is either retrieved from the
345 * SharedUserData structure, or from the registry.
346 */
348
349 /*
350 * - Retrieve the BuildLab string from the registry (set by the kernel).
351 * - In kernel-mode, szCSDVersion is not initialized. Initialize it
352 * and query its value from the registry.
353 */
354 RtlZeroMemory(BuildLabBuffer, sizeof(BuildLabBuffer));
355 RtlInitEmptyUnicodeString(&BuildLabString,
356 BuildLabBuffer,
357 sizeof(BuildLabBuffer));
358 RtlZeroMemory(VerInfo.szCSDVersion, sizeof(VerInfo.szCSDVersion));
359 RtlInitEmptyUnicodeString(&CSDVersionString,
360 VerInfo.szCSDVersion,
361 sizeof(VerInfo.szCSDVersion));
363 L"",
364 VersionConfigurationTable,
365 NULL,
366 NULL);
367 if (!NT_SUCCESS(Status))
368 {
369 /* Indicate nothing is there */
370 BuildLabString.Length = 0;
371 CSDVersionString.Length = 0;
372 }
373 /* NULL-terminate the strings */
374 BuildLabString.Buffer[BuildLabString.Length / sizeof(WCHAR)] = UNICODE_NULL;
375 CSDVersionString.Buffer[CSDVersionString.Length / sizeof(WCHAR)] = UNICODE_NULL;
376
377 EndBuffer = VersionBuffer;
378 if ( /* VerInfo.wServicePackMajor != 0 && */ CSDVersionString.Length)
379 {
380 /* Print the version string */
381 Status = RtlStringCbPrintfExW(VersionBuffer,
382 sizeof(VersionBuffer),
383 &EndBuffer,
384 NULL,
385 0,
386 L": %wZ",
387 &CSDVersionString);
388 if (!NT_SUCCESS(Status))
389 {
390 /* No version, NULL-terminate the string */
391 *EndBuffer = UNICODE_NULL;
392 }
393 }
394 else
395 {
396 /* No version, NULL-terminate the string */
397 *EndBuffer = UNICODE_NULL;
398 }
399
400 if (InSafeMode)
401 {
402 /* String for Safe Mode */
403 Status = RtlStringCchPrintfW(pwszzVersion,
404 cchDest,
405 L"ReactOS Version %S %wZ (NT %u.%u Build %u%s)\n",
406 KERNEL_VERSION_STR,
407 &BuildLabString,
408 SharedUserData->NtMajorVersion,
409 SharedUserData->NtMinorVersion,
410 (VerInfo.dwBuildNumber & 0xFFFF),
411 VersionBuffer);
412
413 if (AppendNtSystemRoot && NT_SUCCESS(Status))
414 {
415 Status = RtlStringCbPrintfW(VersionBuffer,
416 sizeof(VersionBuffer),
417 L" - %s\n",
418 SharedUserData->NtSystemRoot);
419 if (NT_SUCCESS(Status))
420 {
421 /* Replace the last newline by a NULL, before concatenating */
422 EndBuffer = wcsrchr(pwszzVersion, L'\n');
423 if (EndBuffer) *EndBuffer = UNICODE_NULL;
424
425 /* The concatenated string has a terminating newline */
426 Status = RtlStringCchCatW(pwszzVersion,
427 cchDest,
428 VersionBuffer);
429 if (!NT_SUCCESS(Status))
430 {
431 /* Concatenation failed, put back the newline */
432 if (EndBuffer) *EndBuffer = L'\n';
433 }
434 }
435
436 /* Override any failures as the NtSystemRoot string is optional */
438 }
439 }
440 else
441 {
442 /* Multi-string for Normal Mode */
443 Status = RtlStringCchPrintfW(pwszzVersion,
444 cchDest,
445 L"ReactOS Version %S\n"
446 L"Build %wZ\n"
447 L"Reporting NT %u.%u (Build %u%s)\n",
448 KERNEL_VERSION_STR,
449 &BuildLabString,
450 SharedUserData->NtMajorVersion,
451 SharedUserData->NtMinorVersion,
452 (VerInfo.dwBuildNumber & 0xFFFF),
453 VersionBuffer);
454
455 if (AppendNtSystemRoot && NT_SUCCESS(Status))
456 {
457 Status = RtlStringCbPrintfW(VersionBuffer,
458 sizeof(VersionBuffer),
459 L"%s\n",
460 SharedUserData->NtSystemRoot);
461 if (NT_SUCCESS(Status))
462 {
463 Status = RtlStringCchCatW(pwszzVersion,
464 cchDest,
465 VersionBuffer);
466 }
467
468 /* Override any failures as the NtSystemRoot string is optional */
470 }
471 }
472
473 if (!NT_SUCCESS(Status))
474 {
475 /* Fall-back string */
476 Status = RtlStringCchPrintfW(pwszzVersion,
477 cchDest,
478 L"ReactOS Version %S %wZ\n",
479 KERNEL_VERSION_STR,
480 &BuildLabString);
481 if (!NT_SUCCESS(Status))
482 {
483 /* General failure, NULL-terminate the string */
484 pwszzVersion[0] = UNICODE_NULL;
485 }
486 }
487
488 /*
489 * Convert the string separators (newlines) into NULLs
490 * and NULL-terminate the multi-string.
491 */
492 while (*pwszzVersion)
493 {
494 EndBuffer = wcschr(pwszzVersion, L'\n');
495 if (!EndBuffer) break;
496 pwszzVersion = EndBuffer;
497
498 *pwszzVersion++ = UNICODE_NULL;
499 }
500 *pwszzVersion = UNICODE_NULL;
501
502 return Status;
503}
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:24
#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:1161
#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 275 of file desktop.c.

276{
277 GENERIC_MAPPING IntDesktopMapping = { DESKTOP_READ,
281
282 /* Set Desktop Object Attributes */
284 ExDesktopObjectType->TypeInfo.GenericMapping = IntDesktopMapping;
286
287 /* Allocate memory for the event structure */
289 sizeof(KEVENT),
292 {
293 ERR("Failed to allocate event!\n");
294 return STATUS_NO_MEMORY;
295 }
296
297 /* Initialize the kernel event */
300 FALSE);
301
302 return STATUS_SUCCESS;
303}
#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 2386 of file desktop.c.

2394{
2396 PDESKTOP pdesk = NULL;
2397 HDESK hDesk;
2399 UNICODE_STRING ClassName;
2400 LARGE_STRING WindowName;
2401 BOOL NoHooks = FALSE;
2402 PWND pWnd = NULL;
2403 CREATESTRUCTW Cs;
2404 PTHREADINFO ptiCurrent;
2405 PCLS pcls;
2406
2407 TRACE("Enter IntCreateDesktop\n");
2408
2410
2411 ASSERT(phDesktop);
2412 *phDesktop = NULL;
2413
2414 ptiCurrent = PsGetCurrentThreadWin32Thread();
2415 ASSERT(ptiCurrent);
2417
2418 /* Turn off hooks when calling any CreateWindowEx from inside win32k */
2419 NoHooks = (ptiCurrent->TIF_flags & TIF_DISABLEHOOKS);
2420 ptiCurrent->TIF_flags |= TIF_DISABLEHOOKS;
2421 ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
2422
2423 /*
2424 * Try to open already existing desktop
2425 */
2428 AccessMode,
2429 NULL,
2430 dwDesiredAccess,
2431 (PVOID)&Context,
2432 (PHANDLE)&hDesk);
2433 if (!NT_SUCCESS(Status))
2434 {
2435 ERR("ObOpenObjectByName failed to open/create desktop\n");
2436 goto Quit;
2437 }
2438
2439 /* In case the object was not created (eg if it existed), return now */
2440 if (Context == FALSE)
2441 {
2442 TRACE("IntCreateDesktop opened desktop '%wZ'\n", ObjectAttributes->ObjectName);
2444 goto Quit;
2445 }
2446
2447 /* Reference the desktop */
2449 0,
2451 KernelMode,
2452 (PVOID*)&pdesk,
2453 NULL);
2454 if (!NT_SUCCESS(Status))
2455 {
2456 ERR("Failed to reference desktop object\n");
2457 goto Quit;
2458 }
2459
2460 /* Get the desktop window class. The thread desktop does not belong to any desktop
2461 * so the classes created there (including the desktop class) are allocated in the shared heap
2462 * It would cause problems if we used a class that belongs to the caller
2463 */
2464 ClassName.Buffer = WC_DESKTOP;
2465 ClassName.Length = 0;
2466 pcls = IntGetAndReferenceClass(&ClassName, 0, TRUE);
2467 if (pcls == NULL)
2468 {
2469 ASSERT(FALSE);
2471 goto Quit;
2472 }
2473
2474 RtlZeroMemory(&WindowName, sizeof(WindowName));
2475 RtlZeroMemory(&Cs, sizeof(Cs));
2481 Cs.hInstance = hModClient; // hModuleWin; // Server side winproc!
2482 Cs.lpszName = (LPCWSTR) &WindowName;
2483 Cs.lpszClass = (LPCWSTR) &ClassName;
2484
2485 /* Use IntCreateWindow instead of co_UserCreateWindowEx because the later expects a thread with a desktop */
2486 pWnd = IntCreateWindow(&Cs, &WindowName, pcls, NULL, NULL, NULL, pdesk, WINVER);
2487 if (pWnd == NULL)
2488 {
2489 ERR("Failed to create desktop window for the new desktop\n");
2491 goto Quit;
2492 }
2493 pWnd->fnid = FNID_DESKTOP;
2494
2495 /* Assign the desktop window to the desktop */
2496 pdesk->DesktopWindow = UserHMGetHandle(pWnd);
2497 pdesk->pDeskInfo->spwnd = pWnd;
2498
2499 ClassName.Buffer = MAKEINTATOM(gpsi->atomSysClass[ICLS_HWNDMESSAGE]);
2500 ClassName.Length = 0;
2501 pcls = IntGetAndReferenceClass(&ClassName, 0, TRUE);
2502 if (pcls == NULL)
2503 {
2504 ASSERT(FALSE);
2506 goto Quit;
2507 }
2508
2509 RtlZeroMemory(&WindowName, sizeof(WindowName));
2510 RtlZeroMemory(&Cs, sizeof(Cs));
2511 Cs.cx = Cs.cy = 100;
2513 Cs.hInstance = hModClient; // hModuleWin; // Server side winproc!
2514 Cs.lpszName = (LPCWSTR)&WindowName;
2515 Cs.lpszClass = (LPCWSTR)&ClassName;
2516 pWnd = IntCreateWindow(&Cs, &WindowName, pcls, NULL, NULL, NULL, pdesk, WINVER);
2517 if (pWnd == NULL)
2518 {
2519 ERR("Failed to create message window for the new desktop\n");
2521 goto Quit;
2522 }
2523 pWnd->fnid = FNID_MESSAGEWND;
2524
2525 /* Assign the message window to the desktop */
2526 pdesk->spwndMessage = pWnd;
2527
2528 /* Now...
2529 if !(WinStaObject->Flags & WSF_NOIO) is (not set) for desktop input output mode (see wiki)
2530 Create Tooltip. Saved in DesktopObject->spwndTooltip.
2531 Tooltip dwExStyle: WS_EX_TOOLWINDOW|WS_EX_TOPMOST
2532 hWndParent are spwndMessage. Use hModuleWin for server side winproc!
2533 The rest is same as message window.
2534 https://learn.microsoft.com/en-us/windows/win32/controls/tooltip-controls
2535 */
2537
2538Quit:
2539 if (pdesk != NULL)
2540 {
2541 ObDereferenceObject(pdesk);
2542 }
2543 if (!NT_SUCCESS(Status) && hDesk != NULL)
2544 {
2545 ObCloseHandle(hDesk, AccessMode);
2546 hDesk = NULL;
2547 }
2548 if (!NoHooks)
2549 {
2550 ptiCurrent->TIF_flags &= ~TIF_DISABLEHOOKS;
2551 ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
2552 }
2553
2554 TRACE("Leave IntCreateDesktop, Status 0x%08lx\n", Status);
2555
2556 if (NT_SUCCESS(Status))
2557 *phDesktop = hDesk;
2558 else
2560 return Status;
2561}
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
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:3388
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:2535
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:493
#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
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:1198
#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 1801 of file desktop.c.

1802{
1804 PDESKTOP Desktop = pti->rpdesk;
1805 PLIST_ENTRY ListEntry;
1806 PSHELL_HOOK_WINDOW Current;
1807
1808 // FIXME: This probably shouldn't happen, but it does
1809 if (Desktop == NULL)
1810 {
1812 if (Desktop == NULL)
1813 return FALSE;
1814 }
1815
1816 ListEntry = Desktop->ShellHookWindows.Flink;
1817 while (ListEntry != &Desktop->ShellHookWindows)
1818 {
1819 Current = CONTAINING_RECORD(ListEntry, SHELL_HOOK_WINDOW, ListEntry);
1820 ListEntry = ListEntry->Flink;
1821 if (Current->hWnd == hWnd)
1822 {
1823 RemoveEntryList(&Current->ListEntry);
1824 ExFreePoolWithTag(Current, TAG_WINSTA);
1825 return TRUE;
1826 }
1827 }
1828
1829 return FALSE;
1830}
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 250 of file desktop.c.

252{
253 NTSTATUS Ret;
255 PPROCESSINFO ppi = PsGetProcessWin32Process(CloseParameters->Process);
256 if (ppi == NULL)
257 {
258 /* This happens when the process leaks desktop handles.
259 * At this point the PPROCESSINFO is already destroyed */
260 return STATUS_SUCCESS;
261 }
262
264 Ret = IntUnmapDesktopView((PDESKTOP)CloseParameters->Object);
265 UserLeave();
266 return Ret;
267}
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:3177

Referenced by DriverEntry().

◆ IntDesktopObjectDelete()

NTSTATUS NTAPI IntDesktopObjectDelete ( _In_ PVOID  Parameters)

Definition at line 178 of file desktop.c.

180{
182 PDESKTOP pdesk = (PDESKTOP)DeleteParameters->Object;
183
184 TRACE("Deleting desktop object 0x%p\n", pdesk);
185
186 if (pdesk->pDeskInfo &&
187 pdesk->pDeskInfo->spwnd)
188 {
189 ASSERT(pdesk->pDeskInfo->spwnd->spwndChild == NULL);
191 }
192
193 if (pdesk->spwndMessage)
195
196 /* Remove the desktop from the window station's list of associated desktops */
197 RemoveEntryList(&pdesk->ListEntry);
198
199 /* Free the heap */
200 IntFreeDesktopHeap(pdesk);
201
203
204 return STATUS_SUCCESS;
205}
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:2857
static VOID IntFreeDesktopHeap(IN PDESKTOP pdesk)

Referenced by DriverEntry().

◆ IntDesktopObjectOpen()

NTSTATUS NTAPI IntDesktopObjectOpen ( _In_ PVOID  Parameters)

Definition at line 233 of file desktop.c.

235{
236 NTSTATUS Ret;
238 PPROCESSINFO ppi = PsGetProcessWin32Process(OpenParameters->Process);
239 if (ppi == NULL)
240 return STATUS_SUCCESS;
241
243 Ret = IntMapDesktopView((PDESKTOP)OpenParameters->Object);
244 UserLeave();
245 return Ret;
246}
static NTSTATUS IntMapDesktopView(IN PDESKTOP pdesk)
Definition: desktop.c:3221

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))
147 return Status;
148 RtlZeroMemory(Desktop, sizeof(DESKTOP));
149
150 /* Assign the session ID to the desktop */
151 Desktop->dwSessionId = PsGetCurrentProcessSessionId(); // gSessionId
152 ASSERT(Desktop->dwSessionId == WinStaObject->dwSessionId);
153
154 /* Assign security to the desktop we have created */
156 if (!NT_SUCCESS(Status))
157 {
159 return Status;
160 }
161
162 /* Initialize the desktop */
164 if (!NT_SUCCESS(Status))
165 {
167 return Status;
168 }
169
170 /* Set the desktop object and return success */
171 *Object = Desktop;
172 *pContext = TRUE;
173 return STATUS_SUCCESS;
174}
_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)
ULONG NTAPI PsGetCurrentProcessSessionId(VOID)
Definition: process.c:1133
#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
DWORD dwSessionId
Definition: winsta.h:17
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:2277
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 209 of file desktop.c.

211{
214
215 if (pti == NULL)
216 {
217 /* This happens when we leak desktop handles */
218 return STATUS_SUCCESS;
219 }
220
221 /* Do not allow the current desktop or the initial desktop to be closed */
222 if (OkToCloseParameters->Handle == pti->ppi->hdeskStartup ||
223 OkToCloseParameters->Handle == pti->hdesk)
224 {
226 }
227
228 return STATUS_SUCCESS;
229}
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 1833 of file desktop.c.

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

◆ IntFreeDesktopHeap() [2/2]

static VOID IntFreeDesktopHeap ( IN PDESKTOP  pdesk)
static

Referenced by IntDesktopObjectDelete().

◆ IntGetActiveDesktop()

◆ IntGetCurrentThreadDesktopWindow()

HWND FASTCALL IntGetCurrentThreadDesktopWindow ( VOID  )

Definition at line 1442 of file desktop.c.

1443{
1445 PDESKTOP pdo = pti->rpdesk;
1446 if (!pdo)
1447 {
1448 ERR("Thread doesn't have a desktop\n");
1449 return NULL;
1450 }
1451 return pdo->DesktopWindow;
1452}

Referenced by NtUserFindWindowEx().

◆ IntGetDesktopObjectHandle()

HDESK FASTCALL IntGetDesktopObjectHandle ( PDESKTOP  DesktopObject)

Definition at line 1294 of file desktop.c.

1295{
1297 HDESK hDesk;
1298
1299 ASSERT(DesktopObject);
1300
1302 DesktopObject,
1304 NULL,
1305 (PHANDLE)&hDesk))
1306 {
1307 Status = ObOpenObjectByPointer(DesktopObject,
1308 0,
1309 NULL,
1310 0,
1312 UserMode,
1313 (PHANDLE)&hDesk);
1314 if (!NT_SUCCESS(Status))
1315 {
1316 /* Unable to create a handle */
1317 ERR("Unable to create a desktop handle\n");
1318 return NULL;
1319 }
1320 }
1321 else
1322 {
1323 TRACE("Got handle: 0x%p\n", hDesk);
1324 }
1325
1326 return hDesk;
1327}
#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:2859
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:2745
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by NtUserGetThreadDesktop(), and NtUserSetInformationThread().

◆ IntGetDesktopWindow()

◆ IntGetFocusMessageQueue()

◆ IntGetMessageWindow()

HWND FASTCALL IntGetMessageWindow ( VOID  )

Definition at line 1420 of file desktop.c.

1421{
1423 if (!pdo)
1424 {
1425 TRACE("No active desktop\n");
1426 return NULL;
1427 }
1428 return UserHMGetHandle(pdo->spwndMessage);
1429}

Referenced by NtUserFindWindowEx(), and NtUserSetParent().

◆ IntGetThreadDesktopWindow()

PWND FASTCALL IntGetThreadDesktopWindow ( PTHREADINFO  pti)

Definition at line 1382 of file desktop.c.

1383{
1384 if (!pti) pti = PsGetCurrentThreadWin32Thread();
1385 if (pti->pDeskInfo) return pti->pDeskInfo->spwnd;
1386 return NULL;
1387}
struct _DESKTOPINFO * pDeskInfo
Definition: win32.h:93

Referenced by ActivateOtherWindowMin().

◆ IntHideDesktop()

NTSTATUS FASTCALL IntHideDesktop ( PDESKTOP  Desktop)

Definition at line 1650 of file desktop.c.

1651{
1652 PWND DesktopWnd;
1653
1654 DesktopWnd = IntGetWindowObject(Desktop->DesktopWindow);
1655 if (! DesktopWnd)
1656 {
1658 }
1659 DesktopWnd->style &= ~WS_VISIBLE;
1660
1661 return STATUS_SUCCESS;
1662}
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 3221 of file desktop.c.

3222{
3223 PPROCESSINFO ppi;
3224 PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
3225 PVOID UserBase = NULL;
3226 SIZE_T ViewSize = 0;
3229
3230 TRACE("IntMapDesktopView called for desktop object 0x%p\n", pdesk);
3231
3233
3234 /*
3235 * Find out if another thread already mapped the desktop heap.
3236 * Start the search at the next mapping: skip the first entry
3237 * as it must be the global user heap mapping.
3238 */
3239 PrevLink = &ppi->HeapMappings.Next;
3240 HeapMapping = *PrevLink;
3241 while (HeapMapping != NULL)
3242 {
3243 if (HeapMapping->KernelMapping == (PVOID)pdesk->pheapDesktop)
3244 {
3245 HeapMapping->Count++;
3246 return STATUS_SUCCESS;
3247 }
3248
3249 PrevLink = &HeapMapping->Next;
3250 HeapMapping = HeapMapping->Next;
3251 }
3252
3253 /* We're the first, map the heap */
3254 Offset.QuadPart = 0;
3255 Status = MmMapViewOfSection(pdesk->hsectionDesktop,
3257 &UserBase,
3258 0,
3259 0,
3260 &Offset,
3261 &ViewSize,
3262 ViewUnmap,
3265 if (!NT_SUCCESS(Status))
3266 {
3267 ERR("Failed to map desktop\n");
3268 return Status;
3269 }
3270
3271 TRACE("ppi 0x%p mapped heap of desktop 0x%p\n", ppi, pdesk);
3272
3273 /* Add the mapping */
3274 HeapMapping = UserHeapAlloc(sizeof(*HeapMapping));
3275 if (HeapMapping == NULL)
3276 {
3278 ERR("UserHeapAlloc() failed!\n");
3279 return STATUS_NO_MEMORY;
3280 }
3281
3282 HeapMapping->Next = NULL;
3283 HeapMapping->KernelMapping = (PVOID)pdesk->pheapDesktop;
3284 HeapMapping->UserMapping = UserBase;
3285 HeapMapping->Limit = ViewSize;
3286 HeapMapping->Count = 1;
3287 *PrevLink = HeapMapping;
3288
3289 ObReferenceObject(pdesk);
3290
3291 return STATUS_SUCCESS;
3292}
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:2766
#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 1852 of file desktop.c.

1853{
1854 static WCHAR s_wszSafeMode[] = L"Safe Mode"; // FIXME: Localize!
1855
1856 RECTL Rect;
1857 HBRUSH DesktopBrush, PreviousBrush;
1858 HWND hWndDesktop;
1859 BOOL doPatBlt = TRUE;
1860 PWND WndDesktop;
1861 BOOLEAN InSafeMode;
1862
1863 if (GdiGetClipBox(hDC, &Rect) == ERROR)
1864 return FALSE;
1865
1866 hWndDesktop = IntGetDesktopWindow(); // rpdesk->DesktopWindow;
1867
1868 WndDesktop = UserGetWindowObject(hWndDesktop); // rpdesk->pDeskInfo->spwnd;
1869 if (!WndDesktop)
1870 return FALSE;
1871
1872 /* Retrieve the current SafeMode state */
1873 InSafeMode = (UserGetSystemMetrics(SM_CLEANBOOT) != 0); // gpsi->aiSysMet[SM_CLEANBOOT];
1874
1875 if (!InSafeMode)
1876 {
1877 DesktopBrush = (HBRUSH)WndDesktop->pcls->hbrBackground;
1878
1879 /*
1880 * Paint desktop background
1881 */
1883 {
1884 SIZE sz;
1885 int x, y;
1886 int scaledWidth, scaledHeight;
1887 int wallpaperX, wallpaperY, wallpaperWidth, wallpaperHeight;
1888 HDC hWallpaperDC;
1889
1890 sz.cx = WndDesktop->rcWindow.right - WndDesktop->rcWindow.left;
1891 sz.cy = WndDesktop->rcWindow.bottom - WndDesktop->rcWindow.top;
1892
1893 if (gspv.WallpaperMode == wmFit ||
1895 {
1896 int scaleNum, scaleDen;
1897
1898 // Precision improvement over ((sz.cx / gspv.cxWallpaper) > (sz.cy / gspv.cyWallpaper))
1899 if ((sz.cx * gspv.cyWallpaper) > (sz.cy * gspv.cxWallpaper))
1900 {
1901 if (gspv.WallpaperMode == wmFit)
1902 {
1903 scaleNum = sz.cy;
1904 scaleDen = gspv.cyWallpaper;
1905 }
1906 else
1907 {
1908 scaleNum = sz.cx;
1909 scaleDen = gspv.cxWallpaper;
1910 }
1911 }
1912 else
1913 {
1914 if (gspv.WallpaperMode == wmFit)
1915 {
1916 scaleNum = sz.cx;
1917 scaleDen = gspv.cxWallpaper;
1918 }
1919 else
1920 {
1921 scaleNum = sz.cy;
1922 scaleDen = gspv.cyWallpaper;
1923 }
1924 }
1925
1926 scaledWidth = EngMulDiv(gspv.cxWallpaper, scaleNum, scaleDen);
1927 scaledHeight = EngMulDiv(gspv.cyWallpaper, scaleNum, scaleDen);
1928
1929 if (gspv.WallpaperMode == wmFill)
1930 {
1931 wallpaperX = (((scaledWidth - sz.cx) * gspv.cxWallpaper) / (2 * scaledWidth));
1932 wallpaperY = (((scaledHeight - sz.cy) * gspv.cyWallpaper) / (2 * scaledHeight));
1933
1934 wallpaperWidth = (sz.cx * gspv.cxWallpaper) / scaledWidth;
1935 wallpaperHeight = (sz.cy * gspv.cyWallpaper) / scaledHeight;
1936 }
1937 }
1938
1939 if (gspv.WallpaperMode == wmStretch ||
1942 {
1943 x = 0;
1944 y = 0;
1945 }
1946 else if (gspv.WallpaperMode == wmFit)
1947 {
1948 x = (sz.cx - scaledWidth) / 2;
1949 y = (sz.cy - scaledHeight) / 2;
1950 }
1951 else
1952 {
1953 /* Find the upper left corner, can be negative if the bitmap is bigger than the screen */
1954 x = (sz.cx / 2) - (gspv.cxWallpaper / 2);
1955 y = (sz.cy / 2) - (gspv.cyWallpaper / 2);
1956 }
1957
1958 hWallpaperDC = NtGdiCreateCompatibleDC(hDC);
1959 if (hWallpaperDC != NULL)
1960 {
1961 HBITMAP hOldBitmap;
1962
1963 /* Fill in the area that the bitmap is not going to cover */
1964 if (x > 0 || y > 0)
1965 {
1966 /* FIXME: Clip out the bitmap
1967 can be replaced with "NtGdiPatBlt(hDC, x, y, gspv.cxWallpaper, gspv.cyWallpaper, PATCOPY | DSTINVERT);"
1968 once we support DSTINVERT */
1969 PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
1970 NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
1971 NtGdiSelectBrush(hDC, PreviousBrush);
1972 }
1973
1974 /* Do not fill the background after it is painted no matter the size of the picture */
1975 doPatBlt = FALSE;
1976
1977 hOldBitmap = NtGdiSelectBitmap(hWallpaperDC, gspv.hbmWallpaper);
1978
1980 {
1981 if (Rect.right && Rect.bottom)
1983 x,
1984 y,
1985 sz.cx,
1986 sz.cy,
1987 hWallpaperDC,
1988 0,
1989 0,
1992 SRCCOPY,
1993 CLR_INVALID);
1994 }
1995 else if (gspv.WallpaperMode == wmTile)
1996 {
1997 /* Paint the bitmap across the screen then down */
1998 for (y = 0; y < Rect.bottom; y += gspv.cyWallpaper)
1999 {
2000 for (x = 0; x < Rect.right; x += gspv.cxWallpaper)
2001 {
2003 x,
2004 y,
2007 hWallpaperDC,
2008 0,
2009 0,
2010 SRCCOPY,
2012 0);
2013 }
2014 }
2015 }
2016 else if (gspv.WallpaperMode == wmFit)
2017 {
2018 if (Rect.right && Rect.bottom)
2019 {
2021 x,
2022 y,
2023 scaledWidth,
2024 scaledHeight,
2025 hWallpaperDC,
2026 0,
2027 0,
2030 SRCCOPY,
2031 CLR_INVALID);
2032 }
2033 }
2034 else if (gspv.WallpaperMode == wmFill)
2035 {
2036 if (Rect.right && Rect.bottom)
2037 {
2039 x,
2040 y,
2041 sz.cx,
2042 sz.cy,
2043 hWallpaperDC,
2044 wallpaperX,
2045 wallpaperY,
2046 wallpaperWidth,
2047 wallpaperHeight,
2048 SRCCOPY,
2049 CLR_INVALID);
2050 }
2051 }
2052 else
2053 {
2055 x,
2056 y,
2059 hWallpaperDC,
2060 0,
2061 0,
2062 SRCCOPY,
2064 0);
2065 }
2066 NtGdiSelectBitmap(hWallpaperDC, hOldBitmap);
2067 NtGdiDeleteObjectApp(hWallpaperDC);
2068 }
2069 }
2070 }
2071 else
2072 {
2073 /* Black desktop background in Safe Mode */
2074 DesktopBrush = StockObjects[BLACK_BRUSH];
2075 }
2076
2077 /* Background is set to none, clear the screen */
2078 if (doPatBlt)
2079 {
2080 PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
2081 NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
2082 NtGdiSelectBrush(hDC, PreviousBrush);
2083 }
2084
2085 /*
2086 * Display the system version on the desktop background
2087 */
2088 if (InSafeMode || g_AlwaysDisplayVersion || g_PaintDesktopVersion)
2089 {
2091 static WCHAR wszzVersion[1024] = L"\0";
2092
2093 /* Only used in normal mode */
2094 // We expect at most 4 strings (3 for version, 1 for optional NtSystemRoot)
2095 static POLYTEXTW VerStrs[4] = {{0},{0},{0},{0}};
2096 INT i = 0;
2097 SIZE_T len;
2098
2099 HFONT hFont1 = NULL, hFont2 = NULL, hOldFont = NULL;
2100 COLORREF crText, color_old;
2101 UINT align_old;
2102 INT mode_old;
2103 PDC pdc;
2104
2105 if (!UserSystemParametersInfo(SPI_GETWORKAREA, 0, &Rect, 0))
2106 {
2107 Rect.left = Rect.top = 0;
2110 }
2111 else
2112 {
2113 RECTL_vOffsetRect(&Rect, -Rect.left, -Rect.top);
2114 }
2115
2116 /*
2117 * Set up the fonts (otherwise use default ones)
2118 */
2119
2120 /* Font for the principal version string */
2121 hFont1 = GreCreateFontIndirectW(&gspv.ncm.lfCaptionFont);
2122 /* Font for the secondary version strings */
2123 hFont2 = GreCreateFontIndirectW(&gspv.ncm.lfMenuFont);
2124
2125 if (hFont1)
2126 hOldFont = NtGdiSelectFont(hDC, hFont1);
2127
2128 if (gspv.hbmWallpaper == NULL)
2129 {
2130 /* Retrieve the brush fill colour */
2131 // TODO: The following code constitutes "GreGetBrushColor".
2132 PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
2133 pdc = DC_LockDc(hDC);
2134 if (pdc)
2135 {
2136 crText = pdc->eboFill.ulRGBColor;
2137 DC_UnlockDc(pdc);
2138 }
2139 else
2140 {
2141 crText = RGB(0, 0, 0);
2142 }
2143 NtGdiSelectBrush(hDC, PreviousBrush);
2144
2145 /* Adjust text colour according to the brush */
2146 if (GetRValue(crText) + GetGValue(crText) + GetBValue(crText) > 128 * 3)
2147 crText = RGB(0, 0, 0);
2148 else
2149 crText = RGB(255, 255, 255);
2150 }
2151 else
2152 {
2153 /* Always use white when the text is displayed on top of a wallpaper */
2154 crText = RGB(255, 255, 255);
2155 }
2156
2157 color_old = IntGdiSetTextColor(hDC, crText);
2158 align_old = IntGdiSetTextAlign(hDC, TA_RIGHT);
2159 mode_old = IntGdiSetBkMode(hDC, TRANSPARENT);
2160
2161 /* Display the system version information */
2162 if (!*wszzVersion)
2163 {
2164 Status = GetSystemVersionString(wszzVersion,
2165 ARRAYSIZE(wszzVersion),
2166 InSafeMode,
2168 if (!InSafeMode && NT_SUCCESS(Status) && *wszzVersion)
2169 {
2170 PWCHAR pstr = wszzVersion;
2171 for (i = 0; (i < ARRAYSIZE(VerStrs)) && *pstr; ++i)
2172 {
2173 VerStrs[i].n = lstrlenW(pstr);
2174 VerStrs[i].lpstr = pstr;
2175 pstr += (VerStrs[i].n + 1);
2176 }
2177 }
2178 }
2179 else
2180 {
2182 }
2183 if (NT_SUCCESS(Status) && *wszzVersion)
2184 {
2185 if (!InSafeMode)
2186 {
2187 SIZE Size = {0, 0};
2188 LONG TotalHeight = 0;
2189
2190 /* Normal Mode: multiple version information text separated by newlines */
2192
2193 /* Compute the heights of the strings */
2194 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2195 for (i = 0; i < ARRAYSIZE(VerStrs); ++i)
2196 {
2197 if (!VerStrs[i].lpstr || !*VerStrs[i].lpstr || (VerStrs[i].n == 0))
2198 break;
2199
2200 GreGetTextExtentW(hDC, VerStrs[i].lpstr, VerStrs[i].n, &Size, 1);
2201 VerStrs[i].y = Size.cy; // Store the string height
2202 TotalHeight += Size.cy;
2203
2204 /* While the first string was using hFont1, all the others use hFont2 */
2205 if (hFont2) NtGdiSelectFont(hDC, hFont2);
2206 }
2207 /* The total height must not exceed the screen height */
2208 TotalHeight = min(TotalHeight, Rect.bottom);
2209
2210 /* Display the strings */
2211 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2212 for (i = 0; i < ARRAYSIZE(VerStrs); ++i)
2213 {
2214 if (!VerStrs[i].lpstr || !*VerStrs[i].lpstr || (VerStrs[i].n == 0))
2215 break;
2216
2217 TotalHeight -= VerStrs[i].y;
2219 Rect.right - 5,
2220 Rect.bottom - TotalHeight - 5,
2221 0, NULL,
2222 VerStrs[i].lpstr,
2223 VerStrs[i].n,
2224 NULL, 0);
2225
2226 /* While the first string was using hFont1, all the others use hFont2 */
2227 if (hFont2) NtGdiSelectFont(hDC, hFont2);
2228 }
2229 }
2230 else
2231 {
2232 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2233
2234 /* Safe Mode: single version information text in top center */
2235 len = wcslen(wszzVersion);
2236
2238 GreExtTextOutW(hDC, (Rect.right + Rect.left)/2, Rect.top + 3, 0, NULL, wszzVersion, len, NULL, 0);
2239 }
2240 }
2241
2242 if (InSafeMode)
2243 {
2244 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2245
2246 /* Print Safe Mode text in corners */
2247 len = wcslen(s_wszSafeMode);
2248
2250 GreExtTextOutW(hDC, Rect.left, Rect.top + 3, 0, NULL, s_wszSafeMode, len, NULL, 0);
2252 GreExtTextOutW(hDC, Rect.right, Rect.top + 3, 0, NULL, s_wszSafeMode, len, NULL, 0);
2254 GreExtTextOutW(hDC, Rect.left, Rect.bottom - 5, 0, NULL, s_wszSafeMode, len, NULL, 0);
2256 GreExtTextOutW(hDC, Rect.right, Rect.bottom - 5, 0, NULL, s_wszSafeMode, len, NULL, 0);
2257 }
2258
2259 IntGdiSetBkMode(hDC, mode_old);
2260 IntGdiSetTextAlign(hDC, align_old);
2261 IntGdiSetTextColor(hDC, color_old);
2262
2263 if (hFont2)
2264 GreDeleteObject(hFont2);
2265
2266 if (hFont1)
2267 {
2268 NtGdiSelectFont(hDC, hOldFont);
2269 GreDeleteObject(hFont1);
2270 }
2271 }
2272
2273 return TRUE;
2274}
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:2988
#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:7218
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:1397
static NTSTATUS GetSystemVersionString(OUT PWSTR pwszzVersion, IN SIZE_T cchDest, IN BOOLEAN InSafeMode, IN BOOLEAN AppendNtSystemRoot)
Definition: desktop.c:306
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 1769 of file desktop.c.

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

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

580{
582 HWINSTA hWinSta = NULL, hWinStaDup = NULL;
583 HDESK hDesktop = NULL, hDesktopDup = NULL;
584 PPROCESSINFO ppi;
586 LUID ProcessLuid;
587 USHORT StrSize;
588 SIZE_T MemSize;
589 PSECURITY_DESCRIPTOR ServiceSD;
592 UNICODE_STRING WinStaName, DesktopName;
593 const UNICODE_STRING WinSta0Name = RTL_CONSTANT_STRING(L"WinSta0");
594 PWINSTATION_OBJECT WinStaObject;
595 HWINSTA hTempWinSta = NULL;
596 BOOLEAN bUseDefaultWinSta = FALSE;
597 BOOLEAN bInteractive = FALSE;
598 BOOLEAN bAccessAllowed = FALSE;
599
601
602 ASSERT(phWinSta);
603 ASSERT(phDesktop);
604 ASSERT(DesktopPath);
605
606 *phWinSta = NULL;
607 *phDesktop = NULL;
608
610 /* ppi is typically NULL for console applications that connect to Win32 USER */
611 if (!ppi) TRACE("IntResolveDesktop: ppi is NULL!\n");
612
613 if (ppi && ppi->hwinsta != NULL && ppi->hdeskStartup != NULL)
614 {
615 /*
616 * If this process is the current one, just return the cached handles.
617 * Otherwise, open the window station and desktop objects.
618 */
620 {
621 hWinSta = ppi->hwinsta;
622 hDesktop = ppi->hdeskStartup;
623 }
624 else
625 {
627 0,
628 NULL,
631 UserMode,
632 (PHANDLE)&hWinSta);
633 if (!NT_SUCCESS(Status))
634 {
635 ERR("IntResolveDesktop: Could not reference window station 0x%p\n", ppi->prpwinsta);
637 return Status;
638 }
639
641 0,
642 NULL,
645 UserMode,
646 (PHANDLE)&hDesktop);
647 if (!NT_SUCCESS(Status))
648 {
649 ERR("IntResolveDesktop: Could not reference desktop 0x%p\n", ppi->rpdeskStartup);
650 ObCloseHandle(hWinSta, UserMode);
652 return Status;
653 }
654 }
655
656 *phWinSta = hWinSta;
657 *phDesktop = hDesktop;
658 return STATUS_SUCCESS;
659 }
660
661 /* We will by default use the default window station and desktop */
662 RtlInitEmptyUnicodeString(&WinStaName, NULL, 0);
663 RtlInitEmptyUnicodeString(&DesktopName, NULL, 0);
664
665 /*
666 * Parse the desktop path string which can be of the form "WinSta\Desktop"
667 * or just "Desktop". In the latter case we use the default window station
668 * on which the process is attached to (or if none, "WinSta0").
669 */
670 if (DesktopPath->Buffer != NULL && DesktopPath->Length > sizeof(WCHAR))
671 {
672 DesktopName = *DesktopPath;
673
674 /* Find the separator */
675 while (DesktopName.Length > 0 && *DesktopName.Buffer &&
676 *DesktopName.Buffer != OBJ_NAME_PATH_SEPARATOR)
677 {
678 DesktopName.Buffer++;
679 DesktopName.Length -= sizeof(WCHAR);
680 DesktopName.MaximumLength -= sizeof(WCHAR);
681 }
682 if (DesktopName.Length > 0)
683 {
684 RtlInitEmptyUnicodeString(&WinStaName, DesktopPath->Buffer,
685 DesktopPath->Length - DesktopName.Length);
686 // (USHORT)((ULONG_PTR)DesktopName.Buffer - (ULONG_PTR)DesktopPath->Buffer);
687 WinStaName.Length = WinStaName.MaximumLength;
688
689 /* Skip the separator */
690 DesktopName.Buffer++;
691 DesktopName.Length -= sizeof(WCHAR);
692 DesktopName.MaximumLength -= sizeof(WCHAR);
693 }
694 else
695 {
696 RtlInitEmptyUnicodeString(&WinStaName, NULL, 0);
697 DesktopName = *DesktopPath;
698 }
699 }
700
701 TRACE("IntResolveDesktop: WinStaName:'%wZ' ; DesktopName:'%wZ'\n", &WinStaName, &DesktopName);
702
703 /* Retrieve the process LUID */
704 Status = GetProcessLuid(NULL, Process, &ProcessLuid);
705 if (!NT_SUCCESS(Status))
706 {
707 ERR("IntResolveDesktop: Failed to retrieve the process LUID, Status 0x%08lx\n", Status);
709 return Status;
710 }
711
712 /*
713 * If this process is not the current one, obtain a temporary handle
714 * to it so that we can perform handles duplication later.
715 */
717 {
720 NULL,
721 0,
724 &hProcess);
725 if (!NT_SUCCESS(Status))
726 {
727 ERR("IntResolveDesktop: Failed to obtain a handle to process 0x%p, Status 0x%08lx\n", Process, Status);
729 return Status;
730 }
732 }
733
734 /*
735 * If no window station has been specified, search the process handle table
736 * for inherited window station handles, otherwise use a default one.
737 */
738 if (WinStaName.Buffer == NULL)
739 {
740 /*
741 * We want to find a suitable default window station.
742 * For applications that can be interactive, i.e. that have allowed
743 * access to the single interactive window station on the system,
744 * the default window station is 'WinSta0'.
745 * For applications that cannot be interactive, i.e. that do not have
746 * access to 'WinSta0' (e.g. non-interactive services), the default
747 * window station is 'Service-0xXXXX-YYYY$' (created if needed).
748 * Precedence will however be taken by any inherited window station
749 * that possesses the required interactivity property.
750 */
751 bUseDefaultWinSta = TRUE;
752
753 /*
754 * Use the default 'WinSta0' window station. Whether we should
755 * use 'Service-0xXXXX-YYYY$' instead will be determined later.
756 */
757 // RtlInitUnicodeString(&WinStaName, L"WinSta0");
758 WinStaName = WinSta0Name;
759
761 NULL,
763 NULL,
764 (PHANDLE)&hWinSta))
765 {
766 TRACE("IntResolveDesktop: Inherited window station is: 0x%p\n", hWinSta);
767 }
768 }
769
770 /*
771 * If no desktop has been specified, search the process handle table
772 * for inherited desktop handles, otherwise use the Default desktop.
773 * Note that the inherited desktop that we may use, may not belong
774 * to the window station we will connect to.
775 */
776 if (DesktopName.Buffer == NULL)
777 {
778 /* Use a default desktop name */
779 RtlInitUnicodeString(&DesktopName, L"Default");
780
782 NULL,
784 NULL,
785 (PHANDLE)&hDesktop))
786 {
787 TRACE("IntResolveDesktop: Inherited desktop is: 0x%p\n", hDesktop);
788 }
789 }
790
791
792 /*
793 * We are going to open either a window station or a desktop.
794 * Even if this operation is done from kernel-mode, we should
795 * "emulate" an opening from user-mode (i.e. using an ObjectAttributes
796 * allocated in user-mode, with AccessMode == UserMode) for the
797 * Object Manager to perform proper access validation to the
798 * window station or desktop.
799 */
800
801 /*
802 * Estimate the maximum size needed for the window station name
803 * and desktop name to be given to ObjectAttributes->ObjectName.
804 */
805 StrSize = 0;
806
807 /* Window station name */
808 MemSize = _scwprintf(L"Service-0x%x-%x$", MAXULONG, MAXULONG) * sizeof(WCHAR);
810 + max(WinStaName.Length, MemSize) + sizeof(UNICODE_NULL);
811 if (MemSize > MAXUSHORT)
812 {
813 ERR("IntResolveDesktop: Window station name length is too long.\n");
815 goto Quit;
816 }
817 StrSize = max(StrSize, (USHORT)MemSize);
818
819 /* Desktop name */
820 MemSize = max(DesktopName.Length + sizeof(UNICODE_NULL), sizeof(L"Default"));
821 StrSize = max(StrSize, (USHORT)MemSize);
822
823 /* Size for the OBJECT_ATTRIBUTES */
824 MemSize = ALIGN_UP(sizeof(OBJECT_ATTRIBUTES), sizeof(PVOID));
825
826 /* Add the string size */
827 MemSize += ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID));
828 MemSize += StrSize;
829
830 /* Allocate the memory in user-mode */
831 Status = ZwAllocateVirtualMemory(ZwCurrentProcess(),
833 0,
834 &MemSize,
837 if (!NT_SUCCESS(Status))
838 {
839 ERR("ZwAllocateVirtualMemory() failed, Status 0x%08lx\n", Status);
840 goto Quit;
841 }
842
844 ALIGN_UP(sizeof(OBJECT_ATTRIBUTES), sizeof(PVOID)));
845
846 RtlInitEmptyUnicodeString(ObjectName,
848 ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID))),
849 StrSize);
850
851
852 /* If we got an inherited window station handle, duplicate and use it */
853 if (hWinSta)
854 {
855 ASSERT(bUseDefaultWinSta);
856
857 /* Duplicate the handle if it belongs to another process than the current one */
859 {
861 Status = ZwDuplicateObject(hProcess,
862 hWinSta,
864 (PHANDLE)&hWinStaDup,
865 0,
866 0,
868 if (!NT_SUCCESS(Status))
869 {
870 ERR("IntResolveDesktop: Failed to duplicate the window station handle, Status 0x%08lx\n", Status);
871 /* We will use a default window station */
872 hWinSta = NULL;
873 }
874 else
875 {
876 hWinSta = hWinStaDup;
877 }
878 }
879 }
880
881 /*
882 * If we have an inherited window station, check whether
883 * it is interactive and remember that for later.
884 */
885 if (hWinSta)
886 {
887 ASSERT(bUseDefaultWinSta);
888
889 /* Reference the inherited window station */
891 0,
894 (PVOID*)&WinStaObject,
895 NULL);
896 if (!NT_SUCCESS(Status))
897 {
898 ERR("Failed to reference the inherited window station, Status 0x%08lx\n", Status);
899 /* We will use a default window station */
900 if (hWinStaDup)
901 {
902 ASSERT(hWinSta == hWinStaDup);
903 ObCloseHandle(hWinStaDup, UserMode);
904 hWinStaDup = NULL;
905 }
906 hWinSta = NULL;
907 }
908 else
909 {
910 ERR("Process LUID is: 0x%x-%x, inherited window station LUID is: 0x%x-%x\n",
911 ProcessLuid.HighPart, ProcessLuid.LowPart,
912 WinStaObject->luidUser.HighPart, WinStaObject->luidUser.LowPart);
913
914 /* Check whether this window station is interactive, and remember it for later */
915 bInteractive = !(WinStaObject->Flags & WSS_NOIO);
916
917 /* Dereference the window station */
918 ObDereferenceObject(WinStaObject);
919 }
920 }
921
922 /* Build a valid window station name */
924 ObjectName->MaximumLength,
925 L"%wZ\\%wZ",
927 &WinStaName);
928 if (!NT_SUCCESS(Status))
929 {
930 ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
931 goto Quit;
932 }
933 ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
934
935 TRACE("Parsed initial window station: '%wZ'\n", ObjectName);
936
937 /* Try to open the window station */
941 NULL,
942 NULL);
943 if (bInherit)
944 ObjectAttributes->Attributes |= OBJ_INHERIT;
945
948 UserMode,
949 NULL,
951 NULL,
952 (PHANDLE)&hTempWinSta);
953 if (!NT_SUCCESS(Status))
954 {
955 ERR("Failed to open the window station '%wZ', Status 0x%08lx\n", ObjectName, Status);
956 }
957 else
958 {
959 //
960 // FIXME TODO: Perform a window station access check!!
961 // If we fail AND bUseDefaultWinSta == FALSE we just quit.
962 //
963
964 /*
965 * Check whether we are opening the (single) interactive
966 * window station, and if so, perform an access check.
967 */
968 /* Check whether we are allowed to perform interactions */
969 if (RtlEqualUnicodeString(&WinStaName, &WinSta0Name, TRUE))
970 {
971 LUID SystemLuid = SYSTEM_LUID;
972
973 /* Interactive window station: check for user LUID */
974 WinStaObject = InputWindowStation;
975
977
978 // TODO: Check also that we compare wrt. window station WinSta0
979 // which is the only one that can be interactive on the system.
980 if (((!bUseDefaultWinSta || bInherit) && RtlEqualLuid(&ProcessLuid, &SystemLuid)) ||
981 RtlEqualLuid(&ProcessLuid, &WinStaObject->luidUser))
982 {
983 /* We are interactive on this window station */
984 bAccessAllowed = TRUE;
986 }
987 }
988 else
989 {
990 /* Non-interactive window station: we have access since we were able to open it */
991 bAccessAllowed = TRUE;
993 }
994 }
995
996 /* If we failed, bail out if we were not trying to open the default window station */
997 if (!NT_SUCCESS(Status) && !bUseDefaultWinSta) // if (!bAccessAllowed)
998 goto Quit;
999
1000 if (/* bAccessAllowed && */ bInteractive || !bAccessAllowed)
1001 {
1002 /*
1003 * Close WinSta0 if the inherited window station is interactive so that
1004 * we can use it, or we do not have access to the interactive WinSta0.
1005 */
1006 ObCloseHandle(hTempWinSta, UserMode);
1007 hTempWinSta = NULL;
1008 }
1009 if (bInteractive == bAccessAllowed)
1010 {
1011 /* Keep using the inherited window station */
1012 NOTHING;
1013 }
1014 else // if (bInteractive != bAccessAllowed)
1015 {
1016 /*
1017 * Close the inherited window station, we will either keep using
1018 * the interactive WinSta0, or use Service-0xXXXX-YYYY$.
1019 */
1020 if (hWinStaDup)
1021 {
1022 ASSERT(hWinSta == hWinStaDup);
1023 ObCloseHandle(hWinStaDup, UserMode);
1024 hWinStaDup = NULL;
1025 }
1026 hWinSta = hTempWinSta; // hTempWinSta is NULL in case bAccessAllowed == FALSE
1027 }
1028
1029 if (bUseDefaultWinSta)
1030 {
1031 if (hWinSta == NULL && !bInteractive)
1032 {
1033 /* Build a valid window station name from the LUID */
1035 ObjectName->MaximumLength,
1036 L"%wZ\\Service-0x%x-%x$",
1038 ProcessLuid.HighPart,
1039 ProcessLuid.LowPart);
1040 if (!NT_SUCCESS(Status))
1041 {
1042 ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
1043 goto Quit;
1044 }
1045 ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
1046
1047 /*
1048 * Set up a security descriptor for the new service's window station.
1049 * A service has an associated window station and desktop. The newly
1050 * created window station and desktop will get this security descriptor
1051 * if such objects weren't created before.
1052 */
1053 Status = IntCreateServiceSecurity(&ServiceSD);
1054 if (!NT_SUCCESS(Status))
1055 {
1056 ERR("Failed to create a security descriptor for service window station, Status 0x%08lx\n", Status);
1057 goto Quit;
1058 }
1059
1060 /*
1061 * Create or open the non-interactive window station.
1062 * NOTE: The non-interactive window station handle is never inheritable.
1063 */
1065 ObjectName,
1067 NULL,
1068 ServiceSD);
1069
1070 Status = IntCreateWindowStation(&hWinSta,
1072 UserMode,
1073 KernelMode,
1075 0, 0, 0, 0, 0);
1076
1077 IntFreeSecurityBuffer(ServiceSD);
1078
1079 if (!NT_SUCCESS(Status))
1080 {
1081 ASSERT(hWinSta == NULL);
1082 ERR("Failed to create or open the non-interactive window station '%wZ', Status 0x%08lx\n",
1084 goto Quit;
1085 }
1086
1087 //
1088 // FIXME: We might not need to always create or open the "Default"
1089 // desktop on the Service-0xXXXX-YYYY$ window station; we may need
1090 // to use another one....
1091 //
1092
1093 /* Create or open the Default desktop on the window station */
1095 ObjectName->MaximumLength,
1096 L"Default");
1097 if (!NT_SUCCESS(Status))
1098 {
1099 ERR("Impossible to build a valid desktop name, Status 0x%08lx\n", Status);
1100 goto Quit;
1101 }
1102 ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
1103
1104 /*
1105 * NOTE: The non-interactive desktop handle is never inheritable.
1106 * The security descriptor is inherited from the newly created
1107 * window station for the desktop.
1108 */
1110 ObjectName,
1112 hWinSta,
1113 NULL);
1114
1115 Status = IntCreateDesktop(&hDesktop,
1117 UserMode,
1118 NULL,
1119 NULL,
1120 0,
1122 if (!NT_SUCCESS(Status))
1123 {
1124 ASSERT(hDesktop == NULL);
1125 ERR("Failed to create or open the desktop '%wZ' on window station 0x%p, Status 0x%08lx\n",
1126 ObjectName, hWinSta, Status);
1127 }
1128
1129 goto Quit;
1130 }
1131/*
1132 if (hWinSta == NULL)
1133 {
1134 Status = STATUS_UNSUCCESSFUL;
1135 goto Quit;
1136 }
1137*/
1138 }
1139
1140 /*
1141 * If we got an inherited desktop handle, duplicate and use it,
1142 * otherwise open a new desktop.
1143 */
1144 if (hDesktop != NULL)
1145 {
1146 /* Duplicate the handle if it belongs to another process than the current one */
1148 {
1150 Status = ZwDuplicateObject(hProcess,
1151 hDesktop,
1153 (PHANDLE)&hDesktopDup,
1154 0,
1155 0,
1157 if (!NT_SUCCESS(Status))
1158 {
1159 ERR("IntResolveDesktop: Failed to duplicate the desktop handle, Status 0x%08lx\n", Status);
1160 /* We will use a default desktop */
1161 hDesktop = NULL;
1162 }
1163 else
1164 {
1165 hDesktop = hDesktopDup;
1166 }
1167 }
1168 }
1169
1170 if ((hWinSta != NULL) && (hDesktop == NULL))
1171 {
1173 ObjectName->MaximumLength,
1174 DesktopName.Buffer,
1175 DesktopName.Length);
1176 if (!NT_SUCCESS(Status))
1177 {
1178 ERR("Impossible to build a valid desktop name, Status 0x%08lx\n", Status);
1179 goto Quit;
1180 }
1181 ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
1182
1183 TRACE("Parsed initial desktop: '%wZ'\n", ObjectName);
1184
1185 /* Open the desktop object */
1187 ObjectName,
1189 hWinSta,
1190 NULL);
1191 if (bInherit)
1192 ObjectAttributes->Attributes |= OBJ_INHERIT;
1193
1196 UserMode,
1197 NULL,
1199 NULL,
1200 (PHANDLE)&hDesktop);
1201 if (!NT_SUCCESS(Status))
1202 {
1203 ERR("Failed to open the desktop '%wZ' on window station 0x%p, Status 0x%08lx\n",
1204 ObjectName, hWinSta, Status);
1205 goto Quit;
1206 }
1207 }
1208
1209Quit:
1210 /* Release the object attributes */
1211 if (ObjectAttributes)
1212 {
1213 MemSize = 0;
1214 ZwFreeVirtualMemory(ZwCurrentProcess(),
1216 &MemSize,
1217 MEM_RELEASE);
1218 }
1219
1220 /* Close the temporary process handle */
1221 if (hProcess) // if (Process != PsGetCurrentProcess())
1223
1224 if (NT_SUCCESS(Status))
1225 {
1226 *phWinSta = hWinSta;
1227 *phDesktop = hDesktop;
1228 return STATUS_SUCCESS;
1229 }
1230 else
1231 {
1232 ERR("IntResolveDesktop(%wZ) failed, Status 0x%08lx\n", DesktopPath, Status);
1233
1234 if (hDesktopDup)
1235 ObCloseHandle(hDesktopDup, UserMode);
1236 if (hWinStaDup)
1237 ObCloseHandle(hWinStaDup, UserMode);
1238
1239 if (hDesktop)
1240 ObCloseHandle(hDesktop, UserMode);
1241 if (hWinSta)
1242 ObCloseHandle(hWinSta, UserMode);
1243
1245 return Status;
1246 }
1247}
#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:1678
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:450
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:2386
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 1342 of file desktop.c.

1343{
1346 if (!pdo)
1347 {
1348 TRACE("No active desktop\n");
1349 return;
1350 }
1351 if (NewQueue != NULL)
1352 {
1353 if (NewQueue->Desktop != NULL)
1354 {
1355 TRACE("Message Queue already attached to another desktop!\n");
1356 return;
1357 }
1358 IntReferenceMessageQueue(NewQueue);
1359 (void)InterlockedExchangePointer((PVOID*)&NewQueue->Desktop, pdo);
1360 }
1362 if (Old != NULL)
1363 {
1365 gpqForegroundPrev = Old;
1367 }
1368 // Only one Q can have active foreground even when there are more than one desktop.
1369 if (NewQueue)
1370 {
1372 }
1373 else
1374 {
1376 ERR("ptiLastInput is CLEARED!!\n");
1377 ptiLastInput = NULL; // ReactOS hacks... should check for process death.
1378 }
1379}
#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 3295 of file desktop.c.

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

3178{
3179 PPROCESSINFO ppi;
3180 PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
3182
3183 TRACE("IntUnmapDesktopView called for desktop object %p\n", pdesk);
3184
3186
3187 /*
3188 * Unmap if we're the last thread using the desktop.
3189 * Start the search at the next mapping: skip the first entry
3190 * as it must be the global user heap mapping.
3191 */
3192 PrevLink = &ppi->HeapMappings.Next;
3193 HeapMapping = *PrevLink;
3194 while (HeapMapping != NULL)
3195 {
3196 if (HeapMapping->KernelMapping == (PVOID)pdesk->pheapDesktop)
3197 {
3198 if (--HeapMapping->Count == 0)
3199 {
3200 *PrevLink = HeapMapping->Next;
3201
3202 TRACE("ppi 0x%p unmapped heap of desktop 0x%p\n", ppi, pdesk);
3204 HeapMapping->UserMapping);
3205
3206 ObDereferenceObject(pdesk);
3207
3208 UserHeapFree(HeapMapping);
3209 break;
3210 }
3211 }
3212
3213 PrevLink = &HeapMapping->Next;
3214 HeapMapping = HeapMapping->Next;
3215 }
3216
3217 return Status;
3218}
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 1260 of file desktop.c.

1265{
1267
1271 AccessMode,
1272 (PVOID*)Object,
1273 NULL);
1274
1275 TRACE("IntValidateDesktopHandle: handle:0x%p obj:0x%p access:0x%x Status:0x%lx\n",
1277
1278 if (!NT_SUCCESS(Status))
1280
1281 return Status;
1282}
_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 2757 of file desktop.c.

2758{
2759 PDESKTOP pdesk;
2761 BOOL Ret = FALSE;
2762
2763 TRACE("NtUserCloseDesktop(0x%p) called\n", hDesktop);
2765
2766 if (hDesktop == gptiCurrent->hdesk || hDesktop == gptiCurrent->ppi->hdeskStartup)
2767 {
2768 ERR("Attempted to close thread desktop\n");
2770 goto Exit; // Return FALSE
2771 }
2772
2773 Status = IntValidateDesktopHandle(hDesktop, UserMode, 0, &pdesk);
2774 if (!NT_SUCCESS(Status))
2775 {
2776 ERR("Validation of desktop handle 0x%p failed\n", hDesktop);
2777 goto Exit; // Return FALSE
2778 }
2779
2780 ObDereferenceObject(pdesk);
2781
2782 Status = ObCloseHandle(hDesktop, UserMode);
2783 if (!NT_SUCCESS(Status))
2784 {
2785 ERR("Failed to close desktop handle 0x%p\n", hDesktop);
2787 goto Exit; // Return FALSE
2788 }
2789
2790 Ret = TRUE;
2791
2792Exit:
2793 TRACE("Leave NtUserCloseDesktop, ret=%i\n", Ret);
2794 UserLeave();
2795 return Ret;
2796}
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 2564 of file desktop.c.

2570{
2572 HDESK hDesk;
2573 HDESK Ret = NULL;
2574
2575 TRACE("Enter NtUserCreateDesktop\n");
2577
2578 Status = IntCreateDesktop(&hDesk,
2580 UserMode,
2581 lpszDesktopDevice,
2582 lpdmw,
2583 dwFlags,
2584 dwDesiredAccess);
2585 if (!NT_SUCCESS(Status))
2586 {
2587 ERR("IntCreateDesktop failed, Status 0x%08lx\n", Status);
2588 // SetLastNtError(Status);
2589 goto Exit; // Return NULL
2590 }
2591
2592 Ret = hDesk;
2593
2594Exit:
2595 TRACE("Leave NtUserCreateDesktop, ret=0x%p\n", Ret);
2596 UserLeave();
2597 return Ret;
2598}
_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 3068 of file desktop.c.

3069{
3070 HDESK hDesk;
3072 PTHREADINFO pti;
3074 PDESKTOP DesktopObject;
3076
3078 TRACE("Enter NtUserGetThreadDesktop\n");
3079
3080 if (!dwThreadId)
3081 {
3083 hDesk = NULL;
3084 goto Quit;
3085 }
3086
3087 /* Validate the Win32 thread and retrieve its information */
3089 if (pti)
3090 {
3091 /* Get the desktop handle of the thread */
3092 hDesk = pti->hdesk;
3093 Process = pti->ppi->peProcess;
3094 }
3095 else if (hConsoleDesktop)
3096 {
3097 /*
3098 * The thread may belong to a console, so attempt to use the provided
3099 * console desktop handle as a fallback. Otherwise this means that the
3100 * thread is either not Win32 or invalid.
3101 */
3102 hDesk = hConsoleDesktop;
3104 }
3105 else
3106 {
3108 hDesk = NULL;
3109 goto Quit;
3110 }
3111
3112 if (!hDesk)
3113 {
3114 ERR("Desktop information of thread 0x%x broken!?\n", dwThreadId);
3115 goto Quit;
3116 }
3117
3119 {
3120 /*
3121 * Just return the handle, since we queried the desktop handle
3122 * of a thread running in the same context.
3123 */
3124 goto Quit;
3125 }
3126
3127 /*
3128 * We could just use the cached rpdesk instead of looking up the handle,
3129 * but it may actually be safer to validate the desktop and get a temporary
3130 * reference to it so that it does not disappear under us (e.g. when the
3131 * desktop is being destroyed) during the operation.
3132 */
3133 /*
3134 * Switch into the context of the thread we are trying to get
3135 * the desktop from, so we can use the handle.
3136 */
3137 KeAttachProcess(&Process->Pcb);
3139 0,
3141 UserMode,
3142 (PVOID*)&DesktopObject,
3145
3146 if (NT_SUCCESS(Status))
3147 {
3148 /*
3149 * Lookup our handle table if we can find a handle to the desktop object.
3150 * If not, create one.
3151 * QUESTION: Do we really need to create a handle in case it doesn't exist??
3152 */
3153 hDesk = IntGetDesktopObjectHandle(DesktopObject);
3154
3155 /* All done, we got a valid handle to the desktop */
3156 ObDereferenceObject(DesktopObject);
3157 }
3158 else
3159 {
3160 /* The handle could not be found, there is nothing to get... */
3161 hDesk = NULL;
3162 }
3163
3164 if (!hDesk)
3165 {
3166 ERR("Could not retrieve or access desktop for thread 0x%x\n", dwThreadId);
3168 }
3169
3170Quit:
3171 TRACE("Leave NtUserGetThreadDesktop, hDesk = 0x%p\n", hDesk);
3172 UserLeave();
3173 return hDesk;
3174}
#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:1294
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 2623 of file desktop.c.

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

Referenced by OpenDesktopW().

◆ NtUserOpenInputDesktop()

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

Definition at line 2717 of file desktop.c.

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

Referenced by OpenInputDesktop().

◆ NtUserPaintDesktop()

BOOL APIENTRY NtUserPaintDesktop ( HDC  hDC)

Definition at line 2814 of file desktop.c.

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

Referenced by PaintDesktop().

◆ NtUserResolveDesktop()

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

Definition at line 2864 of file desktop.c.

2869{
2872 HWINSTA hWinSta = NULL;
2873 HDESK hDesktop = NULL;
2874 UNICODE_STRING CapturedDesktopPath;
2875
2876 /* Allow only the Console Server to perform this operation (via CSRSS) */
2878 return NULL;
2879
2880 /* Get the process object the user handle was referencing */
2884 UserMode,
2885 (PVOID*)&Process,
2886 NULL);
2887 if (!NT_SUCCESS(Status))
2888 return NULL;
2889
2891
2892 _SEH2_TRY
2893 {
2894 /* Probe the handle pointer */
2895 // ProbeForWriteHandle
2896 ProbeForWrite(phWinSta, sizeof(HWINSTA), sizeof(HWINSTA));
2897 }
2899 {
2901 _SEH2_YIELD(goto Quit);
2902 }
2903 _SEH2_END;
2904
2905 /* Capture the user desktop path string */
2906 Status = ProbeAndCaptureUnicodeString(&CapturedDesktopPath,
2907 UserMode,
2908 DesktopPath);
2909 if (!NT_SUCCESS(Status))
2910 goto Quit;
2911
2912 /* Call the internal function */
2914 &CapturedDesktopPath,
2915 bInherit,
2916 &hWinSta,
2917 &hDesktop);
2918 if (!NT_SUCCESS(Status))
2919 {
2920 ERR("IntResolveDesktop failed, Status 0x%08lx\n", Status);
2921 hWinSta = NULL;
2922 hDesktop = NULL;
2923 }
2924
2925 _SEH2_TRY
2926 {
2927 /* Return the window station handle */
2928 *phWinSta = hWinSta;
2929 }
2931 {
2933
2934 /* We failed, close the opened desktop and window station */
2935 if (hDesktop) ObCloseHandle(hDesktop, UserMode);
2936 hDesktop = NULL;
2937 if (hWinSta) ObCloseHandle(hWinSta, UserMode);
2938 }
2939 _SEH2_END;
2940
2941 /* Free the captured string */
2942 ReleaseCapturedUnicodeString(&CapturedDesktopPath, UserMode);
2943
2944Quit:
2945 UserLeave();
2946
2947 /* Dereference the process object */
2949
2950 /* Return the desktop handle */
2951 return hDesktop;
2952}
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:574

Referenced by GuiInit().

◆ NtUserSetThreadDesktop()

BOOL APIENTRY NtUserSetThreadDesktop ( HDESK  hDesktop)

Definition at line 3487 of file desktop.c.

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

Referenced by SetThreadDesktop().

◆ NtUserSwitchDesktop()

BOOL APIENTRY NtUserSwitchDesktop ( HDESK  hdesk)

Definition at line 2971 of file desktop.c.

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

Referenced by SwitchDesktop().

◆ UserBuildShellHookHwndList()

static HWND *FASTCALL UserBuildShellHookHwndList ( PDESKTOP  Desktop)
static

Definition at line 1666 of file desktop.c.

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

1590{
1591 PWND DesktopObject = 0;
1592 HDC DesktopHDC = 0;
1593
1594 /* This can be called from GDI/DX, so acquire the USER lock */
1596
1597 if (DcType == DCTYPE_DIRECT)
1598 {
1599 DesktopObject = UserGetDesktopWindow();
1600 DesktopHDC = (HDC)UserGetWindowDC(DesktopObject);
1601 }
1602 else
1603 {
1604 PMONITOR pMonitor = UserGetPrimaryMonitor();
1605 DesktopHDC = IntGdiCreateDisplayDC(pMonitor->hDev, DcType, bAltDc);
1606 }
1607
1608 UserLeave();
1609
1610 return DesktopHDC;
1611}
@ 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:1408
PMONITOR NTAPI UserGetPrimaryMonitor(VOID)
Definition: monitor.c:102

Referenced by DxEngGetDesktopDC().

◆ UserGetDesktopWindow()

◆ UserGetMessageWindow()

PWND FASTCALL UserGetMessageWindow ( VOID  )

Definition at line 1431 of file desktop.c.

1432{
1434 if (!pdo)
1435 {
1436 TRACE("No active desktop\n");
1437 return NULL;
1438 }
1439 return pdo->spwndMessage;
1440}

◆ UserInitializeDesktop()

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

Definition at line 2277 of file desktop.c.

2278{
2279 static const UNICODE_STRING WinlogonDesktop = RTL_CONSTANT_STRING(L"Winlogon");
2280 PVOID DesktopHeapSystemBase = NULL;
2282 SIZE_T DesktopInfoSize;
2283 ULONG i;
2284
2285 TRACE("UserInitializeDesktop desktop 0x%p with name %wZ\n", pdesk, DesktopName);
2286
2287 /* Set desktop size, based on whether the WinSta is interactive or not */
2288 if (pwinsta == InputWindowStation)
2289 {
2290 /* Check if the Desktop is named "Winlogon" */
2291 if (RtlEqualUnicodeString(DesktopName, &WinlogonDesktop, TRUE))
2292 {
2294 }
2295 else
2296 {
2298 }
2299 }
2300 else
2301 {
2303 }
2304
2305 /* Link the desktop with the parent window station */
2306 ObReferenceObject(pwinsta);
2307 pdesk->rpwinstaParent = pwinsta;
2308 InsertTailList(&pwinsta->DesktopListHead, &pdesk->ListEntry);
2309
2310 /* Create the desktop heap */
2311 pdesk->hsectionDesktop = NULL;
2313 &DesktopHeapSystemBase,
2314 HeapSize);
2315 if (pdesk->pheapDesktop == NULL)
2316 {
2317 ERR("Failed to create desktop heap!\n");
2318 return STATUS_NO_MEMORY;
2319 }
2320
2321 /* Create DESKTOPINFO */
2322 DesktopInfoSize = sizeof(DESKTOPINFO) + DesktopName->Length + sizeof(WCHAR);
2323 pdesk->pDeskInfo = RtlAllocateHeap(pdesk->pheapDesktop,
2325 DesktopInfoSize);
2326 if (pdesk->pDeskInfo == NULL)
2327 {
2328 ERR("Failed to create the DESKTOP structure!\n");
2329 return STATUS_NO_MEMORY;
2330 }
2331
2332 /* Initialize the DESKTOPINFO */
2333 pdesk->pDeskInfo->pvDesktopBase = DesktopHeapSystemBase;
2334 pdesk->pDeskInfo->pvDesktopLimit = (PVOID)((ULONG_PTR)DesktopHeapSystemBase + HeapSize);
2336 DesktopName->Buffer,
2337 DesktopName->Length + sizeof(WCHAR));
2338 for (i = 0; i < NB_HOOKS; i++)
2339 {
2341 }
2342
2344 InitializeListHead(&pdesk->PtiList);
2345
2346 return STATUS_SUCCESS;
2347}
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 1540 of file desktop.c.

1541{
1542 *lResult = 0;
1543
1544 switch(Msg)
1545 {
1546 case WM_NCCREATE:
1547 pwnd->fnid |= FNID_MESSAGEWND;
1548 *lResult = (LRESULT)TRUE;
1549 break;
1550 case WM_DESTROY:
1551 pwnd->fnid |= FNID_DESTROY;
1552 break;
1553 default:
1554 ERR("UMWP calling IDWP\n");
1555 *lResult = IntDefWindowProc(pwnd, Msg, wParam, lParam, FALSE);
1556 }
1557
1558 return TRUE; /* We are done. Do not do any callbacks to user mode */
1559}
#define FNID_DESTROY
Definition: ntuser.h:898
#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 2652 of file desktop.c.

2655{
2659 HDESK hdesk = NULL;
2660
2661 if (!gpdeskInputDesktop)
2662 {
2663 return NULL;
2664 }
2665
2666 if (pti->ppi->prpwinsta != InputWindowStation)
2667 {
2668 ERR("Tried to open input desktop from non interactive winsta!\n");
2670 return NULL;
2671 }
2672
2673 if (fInherit) HandleAttributes = OBJ_INHERIT;
2674
2675 /* Create a new handle to the object */
2679 NULL,
2680 dwDesiredAccess,
2682 UserMode,
2683 (PHANDLE)&hdesk);
2684
2685 if (!NT_SUCCESS(Status))
2686 {
2687 ERR("Failed to open input desktop object\n");
2689 }
2690
2691 return hdesk;
2692}
#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:442

Referenced by DesktopWindowProc(), and NtUserOpenInputDesktop().

◆ UserRedrawDesktop()

VOID APIENTRY UserRedrawDesktop ( VOID  )

Definition at line 1614 of file desktop.c.

1615{
1616 PWND Window = NULL;
1617 PREGION Rgn;
1618
1620 Rgn = IntSysCreateRectpRgnIndirect(&Window->rcWindow);
1621
1623 Rgn,
1626
1627 REGION_Delete(Rgn);
1628}
#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:645
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