ReactOS 0.4.17-dev-806-gffa4164
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)
 
static VOID IntCalcWallpaperCoordinates (_In_ PWND pwndDesktop, _Out_ PSIZE pszDesk, _Out_ PSIZE pszSrc, _Out_ PSIZE pszDst, _Out_ PPOINT pptSrc, _Out_ PPOINT pptDst)
 
HBITMAP IntStretchWallpaper (_In_ PWND pwndDesktop, _In_ HBITMAP hBitmap)
 
static BOOL IntPaintWallpaper (HDC hDC, PWND pwndDesktop)
 
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
 Currently active desktop.
 
HDC ScreenDeviceContext = NULL
 
PTHREADINFO gptiDesktopThread = NULL
 
HCURSOR gDesktopCursor = NULL
 
PKEVENT gpDesktopThreadStartedEvent = NULL
 
PKEVENT gpDesktopSwitchEvent = NULL
 WinSta0_DesktopSwitch legacy (NT 3.5+) event.
 
HANDLE ghDesktopSwitchEvent = NULL
 WinSta0_DesktopSwitch handle in the CSRSS process.
 

Function Documentation

◆ co_GetDesktopWindow()

PWND FASTCALL co_GetDesktopWindow ( PWND  pWnd)

Definition at line 1394 of file desktop.c.

1395{
1396 if (pWnd->head.rpdesk &&
1397 pWnd->head.rpdesk->pDeskInfo)
1398 return pWnd->head.rpdesk->pDeskInfo->spwnd;
1399 return NULL;
1400}
#define NULL
Definition: types.h:112
struct _DESKTOP * rpdesk
Definition: ntuser.h:197
THRDESKHEAD head
Definition: ntuser.h:699

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

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

1638{
1639 PWND pwnd = Desktop->pDeskInfo->spwnd;
1641 ASSERT(pwnd);
1642
1643 if (!bRedraw)
1645
1647
1648 if (bRedraw)
1650
1651 return STATUS_SUCCESS;
1652}
_Check_return_ _In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ PDXGKARG_SYSTEM_DISPLAY_ENABLE_FLAGS _Out_ UINT _Out_ UINT * Height
Definition: dispmprt.h:1445
_Check_return_ _In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ PDXGKARG_SYSTEM_DISPLAY_ENABLE_FLAGS _Out_ UINT * Width
Definition: dispmprt.h:1444
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:698
BOOL FASTCALL co_UserRedrawWindow(PWND Window, const RECTL *UpdateRect, PREGION UpdateRgn, ULONG Flags)
Definition: painting.c:897
#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 1566 of file desktop.c.

1567{
1568 BOOL Ret;
1569 MSG Msg;
1570
1572
1574
1575 /* Register system classes. This thread does not belong to any desktop so the
1576 classes will be allocated from the shared heap */
1578
1580
1581 while (TRUE)
1582 {
1583 Ret = co_IntGetPeekMessage(&Msg, 0, 0, 0, PM_REMOVE, TRUE);
1584 if (Ret)
1585 {
1587 }
1588 }
1589
1590 UserLeave();
1591}
struct @1803 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:53
PKEVENT gpDesktopThreadStartedEvent
Definition: desktop.c:55
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 1462 of file desktop.c.

1463{
1464 *lResult = 0;
1465
1466 switch (Msg)
1467 {
1468 case WM_NCCREATE:
1469 if (!Wnd->fnid)
1470 Wnd->fnid = FNID_DESKTOP;
1471 *lResult = (LRESULT)TRUE;
1472 return TRUE;
1473
1474 case WM_CREATE:
1475 {
1476 /* Save process and thread IDs */
1477 ULONG Value;
1483 }
1484 case WM_CLOSE:
1485 return TRUE;
1486
1487 case WM_DISPLAYCHANGE:
1489 return TRUE;
1490
1491 case WM_ERASEBKGND:
1493 *lResult = (LRESULT)TRUE;
1494 return TRUE;
1495
1496 case WM_PAINT:
1497 {
1498 PAINTSTRUCT Ps;
1499 if (IntBeginPaint(Wnd, &Ps))
1500 IntEndPaint(Wnd, &Ps);
1501 return TRUE;
1502 }
1503
1504 case WM_SYSCOLORCHANGE:
1506 return TRUE;
1507
1508 case WM_SETCURSOR:
1509 {
1510 PCURICON_OBJECT pcurOld, pcurNew;
1512 if (!pcurNew)
1513 return TRUE;
1514
1515 pcurNew->CURSORF_flags |= CURSORF_CURRENT;
1516 pcurOld = UserSetCursor(pcurNew, FALSE);
1517 if (pcurOld)
1518 {
1519 pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
1520 UserDereferenceObject(pcurOld);
1521 }
1522 return TRUE;
1523 }
1524
1526 {
1527 PWINDOWPOS pWindowPos = (PWINDOWPOS)lParam;
1528 if ((pWindowPos->flags & SWP_SHOWWINDOW) != 0)
1529 {
1531 IntSetThreadDesktop(hdesk, FALSE);
1532 }
1533 break;
1534 }
1535
1536 default:
1537 TRACE("DWP calling IDWP Msg %d\n",Msg);
1538 *lResult = IntDefWindowProc(Wnd, Msg, wParam, lParam, FALSE);
1539 }
1540
1541 return TRUE; /* We are done. Do not do any callbacks to user mode */
1542}
#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:866
#define UserHMGetHandle(obj)
Definition: ntuser.h:233
#define CURSORF_CURRENT
Definition: ntuser.h:1211
#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:1153
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:713
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:54
HDESK UserOpenInputDesktop(DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess)
Definition: desktop.c:2747
BOOL FASTCALL IntPaintDesktop(HDC hDC)
Definition: desktop.c:2130
BOOL IntSetThreadDesktop(IN HDESK hDesktop, IN BOOL FreeOnFailure)
Definition: desktop.c:3400
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:647
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 307 of file desktop.c.

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

277{
278 GENERIC_MAPPING IntDesktopMapping = { DESKTOP_READ,
282
283 /* Set Desktop Object Attributes */
285 ExDesktopObjectType->TypeInfo.GenericMapping = IntDesktopMapping;
287
288 /* Allocate memory for the event structure */
290 sizeof(KEVENT),
293 {
294 ERR("Failed to allocate event!\n");
295 return STATUS_NO_MEMORY;
296 }
297
298 /* Initialize the kernel event */
301 FALSE);
302
303 return STATUS_SUCCESS;
304}
#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:379
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:386
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:411
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().

◆ IntCalcWallpaperCoordinates()

static VOID IntCalcWallpaperCoordinates ( _In_ PWND  pwndDesktop,
_Out_ PSIZE  pszDesk,
_Out_ PSIZE  pszSrc,
_Out_ PSIZE  pszDst,
_Out_ PPOINT  pptSrc,
_Out_ PPOINT  pptDst 
)
static

Definition at line 1857 of file desktop.c.

1864{
1865 int x, y;
1866 POINT ptSrc, ptDst;
1867 SIZE szDesk, szSrc, szDst;
1868 int scaledWidth, scaledHeight;
1869
1870 szDesk.cx = pwndDesktop->rcWindow.right - pwndDesktop->rcWindow.left;
1871 szDesk.cy = pwndDesktop->rcWindow.bottom - pwndDesktop->rcWindow.top;
1872
1873 if (gspv.WallpaperMode == wmFit ||
1875 {
1876 int scaleNum, scaleDen;
1877
1878 /* Precision improvement over ((sz.cx / gspv.cxWallpaper) > (sz.cy / gspv.cyWallpaper)) */
1879 if ((szDesk.cx * gspv.cyWallpaper) > (szDesk.cy * gspv.cxWallpaper))
1880 {
1881 if (gspv.WallpaperMode == wmFit)
1882 {
1883 scaleNum = szDesk.cy;
1884 scaleDen = gspv.cyWallpaper;
1885 }
1886 else
1887 {
1888 scaleNum = szDesk.cx;
1889 scaleDen = gspv.cxWallpaper;
1890 }
1891 }
1892 else
1893 {
1894 if (gspv.WallpaperMode == wmFit)
1895 {
1896 scaleNum = szDesk.cx;
1897 scaleDen = gspv.cxWallpaper;
1898 }
1899 else
1900 {
1901 scaleNum = szDesk.cy;
1902 scaleDen = gspv.cyWallpaper;
1903 }
1904 }
1905
1906 scaledWidth = EngMulDiv(gspv.cxWallpaper, scaleNum, scaleDen);
1907 scaledHeight = EngMulDiv(gspv.cyWallpaper, scaleNum, scaleDen);
1908 }
1909
1910 if (gspv.WallpaperMode == wmStretch ||
1913 {
1914 x = 0;
1915 y = 0;
1916 }
1917 else if (gspv.WallpaperMode == wmFit)
1918 {
1919 x = (szDesk.cx - scaledWidth) / 2;
1920 y = (szDesk.cy - scaledHeight) / 2;
1921 }
1922 else
1923 {
1924 /* Find the upper left corner, can be negative if the bitmap is bigger than the screen */
1925 x = (szDesk.cx / 2) - (gspv.cxWallpaper / 2);
1926 y = (szDesk.cy / 2) - (gspv.cyWallpaper / 2);
1927 }
1928
1929 if (gspv.WallpaperMode == wmTile)
1930 {
1931 szSrc.cx = 0; // not used
1932 szSrc.cy = 0; // not used
1933 szDst.cx = gspv.cxWallpaper;
1934 szDst.cy = gspv.cyWallpaper;
1935 ptSrc.x = 0;
1936 ptSrc.y = 0;
1937 }
1938 else if (gspv.WallpaperMode == wmStretch)
1939 {
1940 szSrc.cx = gspv.cxWallpaper;
1941 szSrc.cy = gspv.cyWallpaper;
1942 szDst.cx = szDesk.cx;
1943 szDst.cy = szDesk.cy;
1944 ptSrc.x = 0;
1945 ptSrc.y = 0;
1946 }
1947 else if (gspv.WallpaperMode == wmFit)
1948 {
1949 szSrc.cx = gspv.cxWallpaper;
1950 szSrc.cy = gspv.cyWallpaper;
1951 szDst.cx = scaledWidth;
1952 szDst.cy = scaledHeight;
1953 ptSrc.x = 0;
1954 ptSrc.y = 0;
1955 }
1956 else if (gspv.WallpaperMode == wmFill)
1957 {
1958 int wallpaperX = (((scaledWidth - szDesk.cx) * gspv.cxWallpaper) / (2 * scaledWidth));
1959 int wallpaperY = (((scaledHeight - szDesk.cy) * gspv.cyWallpaper) / (2 * scaledHeight));
1960
1961 szSrc.cx = EngMulDiv(gspv.cxWallpaper, szDesk.cx, scaledWidth);
1962 szSrc.cy = EngMulDiv(gspv.cyWallpaper, szDesk.cy, scaledHeight);
1963 szDst.cx = szDesk.cx;
1964 szDst.cy = szDesk.cy;
1965 ptSrc.x = wallpaperX;
1966 ptSrc.y = wallpaperY;
1967 }
1968 else if (gspv.WallpaperMode == wmCenter)
1969 {
1970 szSrc.cx = 0; // not used
1971 szSrc.cy = 0; // not used
1972 szDst.cx = gspv.cxWallpaper;
1973 szDst.cy = gspv.cyWallpaper;
1974 ptSrc.x = 0;
1975 ptSrc.y = 0;
1976 }
1977 ptDst.x = x;
1978 ptDst.y = y;
1979
1980 *pszDesk = szDesk;
1981 *pszSrc = szSrc;
1982 *pszDst = szDst;
1983 *pptSrc = ptSrc;
1984 *pptDst = ptDst;
1985}
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
WALLPAPER_MODE WallpaperMode
Definition: sysparams.h:144
ULONG cxWallpaper
Definition: sysparams.h:143
ULONG cyWallpaper
Definition: sysparams.h:143
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
@ wmCenter
Definition: sysparams.h:41
@ wmFill
Definition: sysparams.h:45
@ wmTile
Definition: sysparams.h:42
@ wmStretch
Definition: sysparams.h:43
@ wmFit
Definition: sysparams.h:44
SPIVALUES gspv
Definition: sysparams.c:17
ENGAPI INT APIENTRY EngMulDiv(_In_ INT a, _In_ INT b, _In_ INT c)
Definition: math.c:26

Referenced by IntPaintWallpaper(), and IntStretchWallpaper().

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

2489{
2491 PDESKTOP pdesk = NULL;
2492 HDESK hDesk;
2494 UNICODE_STRING ClassName;
2495 LARGE_STRING WindowName;
2496 BOOL NoHooks = FALSE;
2497 PWND pWnd = NULL;
2498 CREATESTRUCTW Cs;
2499 PTHREADINFO ptiCurrent;
2500 PCLS pcls;
2501
2502 TRACE("Enter IntCreateDesktop\n");
2503
2505
2506 ASSERT(phDesktop);
2507 *phDesktop = NULL;
2508
2509 ptiCurrent = PsGetCurrentThreadWin32Thread();
2510 ASSERT(ptiCurrent);
2512
2513 /* Turn off hooks when calling any CreateWindowEx from inside win32k */
2514 NoHooks = (ptiCurrent->TIF_flags & TIF_DISABLEHOOKS);
2515 ptiCurrent->TIF_flags |= TIF_DISABLEHOOKS;
2516 ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
2517
2518 /*
2519 * Try to open already existing desktop
2520 */
2523 AccessMode,
2524 NULL,
2525 dwDesiredAccess,
2526 (PVOID)&Context,
2527 (PHANDLE)&hDesk);
2528 if (!NT_SUCCESS(Status))
2529 {
2530 ERR("ObOpenObjectByName failed to open/create desktop\n");
2531 goto Quit;
2532 }
2533
2534 /* In case the object was not created (eg if it existed), return now */
2535 if (Context == FALSE)
2536 {
2537 TRACE("IntCreateDesktop opened desktop '%wZ'\n", ObjectAttributes->ObjectName);
2539 goto Quit;
2540 }
2541
2542 /* Reference the desktop */
2544 0,
2546 KernelMode,
2547 (PVOID*)&pdesk,
2548 NULL);
2549 if (!NT_SUCCESS(Status))
2550 {
2551 ERR("Failed to reference desktop object\n");
2552 goto Quit;
2553 }
2554
2555 /* Get the desktop window class. The thread desktop does not belong to any desktop
2556 * so the classes created there (including the desktop class) are allocated in the shared heap
2557 * It would cause problems if we used a class that belongs to the caller
2558 */
2559 ClassName.Buffer = WC_DESKTOP;
2560 ClassName.Length = 0;
2561 pcls = IntGetAndReferenceClass(&ClassName, 0, TRUE);
2562 if (pcls == NULL)
2563 {
2564 ASSERT(FALSE);
2566 goto Quit;
2567 }
2568
2569 RtlZeroMemory(&WindowName, sizeof(WindowName));
2570 RtlZeroMemory(&Cs, sizeof(Cs));
2576 Cs.hInstance = hModClient; // hModuleWin; // Server side winproc!
2577 Cs.lpszName = (LPCWSTR) &WindowName;
2578 Cs.lpszClass = (LPCWSTR) &ClassName;
2579
2580 /* Use IntCreateWindow instead of co_UserCreateWindowEx because the later expects a thread with a desktop */
2581 pWnd = IntCreateWindow(&Cs, &WindowName, pcls, NULL, NULL, NULL, pdesk, WINVER);
2582 if (pWnd == NULL)
2583 {
2584 ERR("Failed to create desktop window for the new desktop\n");
2586 goto Quit;
2587 }
2588 pWnd->fnid = FNID_DESKTOP;
2589
2590 /* Assign the desktop window to the desktop */
2591 pdesk->DesktopWindow = UserHMGetHandle(pWnd);
2592 pdesk->pDeskInfo->spwnd = pWnd;
2593
2594 ClassName.Buffer = MAKEINTATOM(gpsi->atomSysClass[ICLS_HWNDMESSAGE]);
2595 ClassName.Length = 0;
2596 pcls = IntGetAndReferenceClass(&ClassName, 0, TRUE);
2597 if (pcls == NULL)
2598 {
2599 ASSERT(FALSE);
2601 goto Quit;
2602 }
2603
2604 RtlZeroMemory(&WindowName, sizeof(WindowName));
2605 RtlZeroMemory(&Cs, sizeof(Cs));
2606 Cs.cx = Cs.cy = 100;
2608 Cs.hInstance = hModClient; // hModuleWin; // Server side winproc!
2609 Cs.lpszName = (LPCWSTR)&WindowName;
2610 Cs.lpszClass = (LPCWSTR)&ClassName;
2611 pWnd = IntCreateWindow(&Cs, &WindowName, pcls, NULL, NULL, NULL, pdesk, WINVER);
2612 if (pWnd == NULL)
2613 {
2614 ERR("Failed to create message window for the new desktop\n");
2616 goto Quit;
2617 }
2618 pWnd->fnid = FNID_MESSAGEWND;
2619
2620 /* Assign the message window to the desktop */
2621 pdesk->spwndMessage = pWnd;
2622
2623 /* Now...
2624 if !(WinStaObject->Flags & WSF_NOIO) is (not set) for desktop input output mode (see wiki)
2625 Create Tooltip. Saved in DesktopObject->spwndTooltip.
2626 Tooltip dwExStyle: WS_EX_TOOLWINDOW|WS_EX_TOPMOST
2627 hWndParent are spwndMessage. Use hModuleWin for server side winproc!
2628 The rest is same as message window.
2629 https://learn.microsoft.com/en-us/windows/win32/controls/tooltip-controls
2630 */
2632
2633Quit:
2634 if (pdesk != NULL)
2635 {
2636 ObDereferenceObject(pdesk);
2637 }
2638 if (!NT_SUCCESS(Status) && hDesk != NULL)
2639 {
2640 ObCloseHandle(hDesk, AccessMode);
2641 hDesk = NULL;
2642 }
2643 if (!NoHooks)
2644 {
2645 ptiCurrent->TIF_flags &= ~TIF_DISABLEHOOKS;
2646 ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
2647 }
2648
2649 TRACE("Leave IntCreateDesktop, Status 0x%08lx\n", Status);
2650
2651 if (NT_SUCCESS(Status))
2652 *phDesktop = hDesk;
2653 else
2655 return Status;
2656}
unsigned char BOOLEAN
Definition: actypes.h:127
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define FNID_MESSAGEWND
Definition: ntuser.h:868
#define TIF_DISABLEHOOKS
Definition: ntuser.h:294
#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:3406
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:2554
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:570
struct _WND * spwnd
Definition: ntuser.h:140
PWND spwndMessage
Definition: desktop.h:20
HWND DesktopWindow
Definition: desktop.h:40
PDESKTOPINFO pDeskInfo
Definition: desktop.h:8
struct _CLIENTINFO * pClientInfo
Definition: win32.h:95
FLONG TIF_flags
Definition: win32.h:96
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:1064
#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 1806 of file desktop.c.

1807{
1809 PDESKTOP Desktop = pti->rpdesk;
1810 PLIST_ENTRY ListEntry;
1811 PSHELL_HOOK_WINDOW Current;
1812
1813 // FIXME: This probably shouldn't happen, but it does
1814 if (Desktop == NULL)
1815 {
1817 if (Desktop == NULL)
1818 return FALSE;
1819 }
1820
1821 ListEntry = Desktop->ShellHookWindows.Flink;
1822 while (ListEntry != &Desktop->ShellHookWindows)
1823 {
1824 Current = CONTAINING_RECORD(ListEntry, SHELL_HOOK_WINDOW, ListEntry);
1825 ListEntry = ListEntry->Flink;
1826 if (Current->hWnd == hWnd)
1827 {
1828 RemoveEntryList(&Current->ListEntry);
1829 ExFreePoolWithTag(Current, TAG_WINSTA);
1830 return TRUE;
1831 }
1832 }
1833
1834 return FALSE;
1835}
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:69
struct _DESKTOP * rpdesk
Definition: win32.h:93
#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 251 of file desktop.c.

253{
254 NTSTATUS Ret;
256 PPROCESSINFO ppi = PsGetProcessWin32Process(CloseParameters->Process);
257 if (ppi == NULL)
258 {
259 /* This happens when the process leaks desktop handles.
260 * At this point the PPROCESSINFO is already destroyed */
261 return STATUS_SUCCESS;
262 }
263
265 Ret = IntUnmapDesktopView((PDESKTOP)CloseParameters->Object);
266 UserLeave();
267 return Ret;
268}
_In_ HANDLE _In_ CONST PDXGKMDT_OPM_GET_INFO_PARAMETERS Parameters
Definition: dispmprt.h:321
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1223
static NTSTATUS IntUnmapDesktopView(IN PDESKTOP pdesk)
Definition: desktop.c:3282

Referenced by DriverEntry().

◆ IntDesktopObjectDelete()

NTSTATUS NTAPI IntDesktopObjectDelete ( _In_ PVOID  Parameters)

Definition at line 179 of file desktop.c.

181{
183 PDESKTOP pdesk = (PDESKTOP)DeleteParameters->Object;
184
185 TRACE("Deleting desktop object 0x%p\n", pdesk);
186
187 if (pdesk->pDeskInfo &&
188 pdesk->pDeskInfo->spwnd)
189 {
190 ASSERT(pdesk->pDeskInfo->spwnd->spwndChild == NULL);
192 }
193
194 if (pdesk->spwndMessage)
196
197 /* Remove the desktop from the window station's list of associated desktops */
198 RemoveEntryList(&pdesk->ListEntry);
199
200 /* Free the heap */
201 IntFreeDesktopHeap(pdesk);
202
204
205 return STATUS_SUCCESS;
206}
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 234 of file desktop.c.

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

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

73{
77 PLIST_ENTRY NextEntry, ListHead;
78 PWINSTATION_OBJECT WinStaObject = (PWINSTATION_OBJECT)ParseObject;
79 UNICODE_STRING DesktopName;
80 PBOOLEAN pContext = (PBOOLEAN) Context;
81
82 if (pContext)
83 *pContext = FALSE;
84
85 /* Set the list pointers and loop the window station */
86 ListHead = &WinStaObject->DesktopListHead;
87 NextEntry = ListHead->Flink;
88 while (NextEntry != ListHead)
89 {
90 /* Get the current desktop */
91 Desktop = CONTAINING_RECORD(NextEntry, DESKTOP, ListEntry);
92
93 /* Get the desktop name */
94 ASSERT(Desktop->pDeskInfo != NULL);
95 RtlInitUnicodeString(&DesktopName, Desktop->pDeskInfo->szDesktopName);
96
97 /* Compare the name */
99 &DesktopName,
101 {
102 /* We found a match. Did this come from a create? */
103 if (Context)
104 {
105 /* Unless OPEN_IF was given, fail with an error */
106 if (!(Attributes & OBJ_OPENIF))
107 {
108 /* Name collision */
110 }
111 else
112 {
113 /* Otherwise, return with a warning only */
115 }
116 }
117 else
118 {
119 /* This was a real open, so this is OK */
121 }
122
123 /* Reference the desktop and return it */
125 *Object = Desktop;
126 return Status;
127 }
128
129 /* Go to the next desktop */
130 NextEntry = NextEntry->Flink;
131 }
132
133 /* If we got here but this isn't a create, just fail */
135
136 /* Create the desktop object */
142 NULL,
143 sizeof(DESKTOP),
144 0,
145 0,
146 (PVOID*)&Desktop);
147 if (!NT_SUCCESS(Status))
148 return Status;
149 RtlZeroMemory(Desktop, sizeof(DESKTOP));
150
151 /* Assign the session ID to the desktop */
152 Desktop->dwSessionId = PsGetCurrentProcessSessionId(); // gSessionId
153 ASSERT(Desktop->dwSessionId == WinStaObject->dwSessionId);
154
155 /* Assign security to the desktop we have created */
157 if (!NT_SUCCESS(Status))
158 {
160 return Status;
161 }
162
163 /* Initialize the desktop */
165 if (!NT_SUCCESS(Status))
166 {
168 return Status;
169 }
170
171 /* Set the desktop object and return success */
172 *Object = Desktop;
173 *pContext = TRUE;
174 return STATUS_SUCCESS;
175}
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:802
_In_ ULONG Attributes
Definition: dispmprt.h:1077
#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:1163
#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:1040
#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
static NTSTATUS UserInitializeDesktop(PDESKTOP pdesk, PUNICODE_STRING DesktopName, PWINSTATION_OBJECT pwinsta)
Definition: desktop.c:2372
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 210 of file desktop.c.

212{
215
216 if (pti == NULL)
217 {
218 /* This happens when we leak desktop handles */
219 return STATUS_SUCCESS;
220 }
221
222 /* Do not allow the current desktop or the initial desktop to be closed */
223 if (OkToCloseParameters->Handle == pti->ppi->hdeskStartup ||
224 OkToCloseParameters->Handle == pti->hdesk)
225 {
227 }
228
229 return STATUS_SUCCESS;
230}
HDESK hdeskStartup
Definition: win32.h:265
PPROCESSINFO ppi
Definition: win32.h:89
HDESK hdesk
Definition: win32.h:109
#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 1838 of file desktop.c.

1839{
1840 /* FIXME: Disable until unmapping works in mm */
1841#if 0
1842 if (Desktop->pheapDesktop != NULL)
1843 {
1844 MmUnmapViewInSessionSpace(Desktop->pheapDesktop);
1845 Desktop->pheapDesktop = NULL;
1846 }
1847
1848 if (Desktop->hsectionDesktop != NULL)
1849 {
1850 ObDereferenceObject(Desktop->hsectionDesktop);
1851 Desktop->hsectionDesktop = NULL;
1852 }
1853#endif
1854}
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 1447 of file desktop.c.

1448{
1450 PDESKTOP pdo = pti->rpdesk;
1451 if (!pdo)
1452 {
1453 ERR("Thread doesn't have a desktop\n");
1454 return NULL;
1455 }
1456 return pdo->DesktopWindow;
1457}

Referenced by NtUserFindWindowEx().

◆ IntGetDesktopObjectHandle()

HDESK FASTCALL IntGetDesktopObjectHandle ( PDESKTOP  DesktopObject)

Definition at line 1299 of file desktop.c.

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

Referenced by NtUserGetThreadDesktop(), and NtUserSetInformationThread().

◆ IntGetDesktopWindow()

◆ IntGetFocusMessageQueue()

◆ IntGetMessageWindow()

HWND FASTCALL IntGetMessageWindow ( VOID  )

Definition at line 1425 of file desktop.c.

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

Referenced by NtUserFindWindowEx(), and NtUserSetParent().

◆ IntGetThreadDesktopWindow()

PWND FASTCALL IntGetThreadDesktopWindow ( PTHREADINFO  pti)

Definition at line 1387 of file desktop.c.

1388{
1389 if (!pti) pti = PsGetCurrentThreadWin32Thread();
1390 if (pti->pDeskInfo) return pti->pDeskInfo->spwnd;
1391 return NULL;
1392}
struct _DESKTOPINFO * pDeskInfo
Definition: win32.h:94

Referenced by ActivateOtherWindowMin().

◆ IntHideDesktop()

NTSTATUS FASTCALL IntHideDesktop ( PDESKTOP  Desktop)

Definition at line 1655 of file desktop.c.

1656{
1657 PWND DesktopWnd;
1658
1659 DesktopWnd = IntGetWindowObject(Desktop->DesktopWindow);
1660 if (! DesktopWnd)
1661 {
1663 }
1664 DesktopWnd->style &= ~WS_VISIBLE;
1665
1666 return STATUS_SUCCESS;
1667}
DWORD style
Definition: ntuser.h:710
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 3326 of file desktop.c.

3327{
3328 PPROCESSINFO ppi;
3329 PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
3330 PVOID UserBase = NULL;
3331 SIZE_T ViewSize = 0;
3334
3335 TRACE("IntMapDesktopView called for desktop object 0x%p\n", pdesk);
3336
3338
3339 /*
3340 * Find out if another thread already mapped the desktop heap.
3341 * Start the search at the next mapping: skip the first entry
3342 * as it must be the global user heap mapping.
3343 */
3344 PrevLink = &ppi->HeapMappings.Next;
3345 HeapMapping = *PrevLink;
3346 while (HeapMapping != NULL)
3347 {
3348 if (HeapMapping->KernelMapping == (PVOID)pdesk->pheapDesktop)
3349 {
3350 HeapMapping->Count++;
3351 return STATUS_SUCCESS;
3352 }
3353
3354 PrevLink = &HeapMapping->Next;
3355 HeapMapping = HeapMapping->Next;
3356 }
3357
3358 /* We're the first, map the heap */
3359 Offset.QuadPart = 0;
3360 Status = MmMapViewOfSection(pdesk->hsectionDesktop,
3362 &UserBase,
3363 0,
3364 0,
3365 &Offset,
3366 &ViewSize,
3367 ViewUnmap,
3370 if (!NT_SUCCESS(Status))
3371 {
3372 ERR("Failed to map desktop\n");
3373 return Status;
3374 }
3375
3376 TRACE("ppi 0x%p mapped heap of desktop 0x%p\n", ppi, pdesk);
3377
3378 /* Add the mapping */
3379 HeapMapping = UserHeapAlloc(sizeof(*HeapMapping));
3380 if (HeapMapping == NULL)
3381 {
3383 ERR("UserHeapAlloc() failed!\n");
3384 return STATUS_NO_MEMORY;
3385 }
3386
3387 HeapMapping->Next = NULL;
3388 HeapMapping->KernelMapping = (PVOID)pdesk->pheapDesktop;
3389 HeapMapping->UserMapping = UserBase;
3390 HeapMapping->Limit = ViewSize;
3391 HeapMapping->Count = 1;
3392 *PrevLink = HeapMapping;
3393
3394 ObReferenceObject(pdesk);
3395
3396 return STATUS_SUCCESS;
3397}
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:412
#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:1213
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:292
struct _W32HEAP_USER_MAPPING * Next
Definition: win32.h:200
ULONG_PTR Limit
Definition: win32.h:203
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 2130 of file desktop.c.

2131{
2132 static WCHAR s_wszSafeMode[] = L"Safe Mode"; // FIXME: Localize!
2133
2134 RECTL Rect;
2135 HBRUSH DesktopBrush, PreviousBrush;
2136 HWND hWndDesktop;
2137 BOOL doPatBlt = TRUE;
2138 PWND WndDesktop;
2139 BOOLEAN InSafeMode;
2140
2141 if (GdiGetClipBox(hDC, &Rect) == ERROR)
2142 return FALSE;
2143
2144 hWndDesktop = IntGetDesktopWindow(); // rpdesk->DesktopWindow;
2145
2146 WndDesktop = UserGetWindowObject(hWndDesktop); // rpdesk->pDeskInfo->spwnd;
2147 if (!WndDesktop)
2148 return FALSE;
2149
2150 /* Retrieve the current SafeMode state */
2151 InSafeMode = (UserGetSystemMetrics(SM_CLEANBOOT) != 0); // gpsi->aiSysMet[SM_CLEANBOOT];
2152
2153 if (!InSafeMode)
2154 {
2155 DesktopBrush = (HBRUSH)WndDesktop->pcls->hbrBackground;
2156
2157 /*
2158 * Paint desktop background
2159 */
2161 {
2162 /* Do not fill the background after it is painted no matter the size of the picture */
2163 doPatBlt = !IntPaintWallpaper(hDC, WndDesktop);
2164 }
2165 }
2166 else
2167 {
2168 /* Black desktop background in Safe Mode */
2169 DesktopBrush = StockObjects[BLACK_BRUSH];
2170 }
2171
2172 /* Background is set to none, clear the screen */
2173 if (doPatBlt)
2174 {
2175 PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
2176 NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
2177 NtGdiSelectBrush(hDC, PreviousBrush);
2178 }
2179
2180 /*
2181 * Display the system version on the desktop background
2182 */
2183 if (InSafeMode || g_AlwaysDisplayVersion || g_PaintDesktopVersion)
2184 {
2186 static WCHAR wszzVersion[1024] = L"\0";
2187
2188 /* Only used in normal mode */
2189 // We expect at most 4 strings (3 for version, 1 for optional NtSystemRoot)
2190 static POLYTEXTW VerStrs[4] = {{0},{0},{0},{0}};
2191 INT i = 0;
2192 SIZE_T len;
2193
2194 HFONT hFont1 = NULL, hFont2 = NULL, hOldFont = NULL;
2195 COLORREF crText, color_old;
2196 UINT align_old;
2197 INT mode_old;
2198 PDC pdc;
2199
2200 if (!UserSystemParametersInfo(SPI_GETWORKAREA, 0, &Rect, 0))
2201 {
2202 Rect.left = Rect.top = 0;
2205 }
2206 else
2207 {
2208 RECTL_vOffsetRect(&Rect, -Rect.left, -Rect.top);
2209 }
2210
2211 /*
2212 * Set up the fonts (otherwise use default ones)
2213 */
2214
2215 /* Font for the principal version string */
2216 hFont1 = GreCreateFontIndirectW(&gspv.ncm.lfCaptionFont);
2217 /* Font for the secondary version strings */
2218 hFont2 = GreCreateFontIndirectW(&gspv.ncm.lfMenuFont);
2219
2220 if (hFont1)
2221 hOldFont = NtGdiSelectFont(hDC, hFont1);
2222
2223 if (gspv.hbmWallpaper == NULL)
2224 {
2225 /* Retrieve the brush fill colour */
2226 // TODO: The following code constitutes "GreGetBrushColor".
2227 PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
2228 pdc = DC_LockDc(hDC);
2229 if (pdc)
2230 {
2231 crText = pdc->eboFill.ulRGBColor;
2232 DC_UnlockDc(pdc);
2233 }
2234 else
2235 {
2236 crText = RGB(0, 0, 0);
2237 }
2238 NtGdiSelectBrush(hDC, PreviousBrush);
2239
2240 /* Adjust text colour according to the brush */
2241 if (GetRValue(crText) + GetGValue(crText) + GetBValue(crText) > 128 * 3)
2242 crText = RGB(0, 0, 0);
2243 else
2244 crText = RGB(255, 255, 255);
2245 }
2246 else
2247 {
2248 /* Always use white when the text is displayed on top of a wallpaper */
2249 crText = RGB(255, 255, 255);
2250 }
2251
2252 color_old = IntGdiSetTextColor(hDC, crText);
2253 align_old = IntGdiSetTextAlign(hDC, TA_RIGHT);
2254 mode_old = IntGdiSetBkMode(hDC, TRANSPARENT);
2255
2256 /* Display the system version information */
2257 if (!*wszzVersion)
2258 {
2259 Status = GetSystemVersionString(wszzVersion,
2260 ARRAYSIZE(wszzVersion),
2261 InSafeMode,
2263 if (!InSafeMode && NT_SUCCESS(Status) && *wszzVersion)
2264 {
2265 PWCHAR pstr = wszzVersion;
2266 for (i = 0; (i < ARRAYSIZE(VerStrs)) && *pstr; ++i)
2267 {
2268 VerStrs[i].n = lstrlenW(pstr);
2269 VerStrs[i].lpstr = pstr;
2270 pstr += (VerStrs[i].n + 1);
2271 }
2272 }
2273 }
2274 else
2275 {
2277 }
2278 if (NT_SUCCESS(Status) && *wszzVersion)
2279 {
2280 if (!InSafeMode)
2281 {
2282 SIZE Size = {0, 0};
2283 LONG TotalHeight = 0;
2284
2285 /* Normal Mode: multiple version information text separated by newlines */
2287
2288 /* Compute the heights of the strings */
2289 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2290 for (i = 0; i < ARRAYSIZE(VerStrs); ++i)
2291 {
2292 if (!VerStrs[i].lpstr || !*VerStrs[i].lpstr || (VerStrs[i].n == 0))
2293 break;
2294
2295 GreGetTextExtentW(hDC, VerStrs[i].lpstr, VerStrs[i].n, &Size, 1);
2296 VerStrs[i].y = Size.cy; // Store the string height
2297 TotalHeight += Size.cy;
2298
2299 /* While the first string was using hFont1, all the others use hFont2 */
2300 if (hFont2) NtGdiSelectFont(hDC, hFont2);
2301 }
2302 /* The total height must not exceed the screen height */
2303 TotalHeight = min(TotalHeight, Rect.bottom);
2304
2305 /* Display the strings */
2306 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2307 for (i = 0; i < ARRAYSIZE(VerStrs); ++i)
2308 {
2309 if (!VerStrs[i].lpstr || !*VerStrs[i].lpstr || (VerStrs[i].n == 0))
2310 break;
2311
2312 TotalHeight -= VerStrs[i].y;
2314 Rect.right - 5,
2315 Rect.bottom - TotalHeight - 5,
2316 0, NULL,
2317 VerStrs[i].lpstr,
2318 VerStrs[i].n,
2319 NULL, 0);
2320
2321 /* While the first string was using hFont1, all the others use hFont2 */
2322 if (hFont2) NtGdiSelectFont(hDC, hFont2);
2323 }
2324 }
2325 else
2326 {
2327 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2328
2329 /* Safe Mode: single version information text in top center */
2330 len = wcslen(wszzVersion);
2331
2333 GreExtTextOutW(hDC, (Rect.right + Rect.left)/2, Rect.top + 3, 0, NULL, wszzVersion, len, NULL, 0);
2334 }
2335 }
2336
2337 if (InSafeMode)
2338 {
2339 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2340
2341 /* Print Safe Mode text in corners */
2342 len = wcslen(s_wszSafeMode);
2343
2345 GreExtTextOutW(hDC, Rect.left, Rect.top + 3, 0, NULL, s_wszSafeMode, len, NULL, 0);
2347 GreExtTextOutW(hDC, Rect.right, Rect.top + 3, 0, NULL, s_wszSafeMode, len, NULL, 0);
2349 GreExtTextOutW(hDC, Rect.left, Rect.bottom - 5, 0, NULL, s_wszSafeMode, len, NULL, 0);
2351 GreExtTextOutW(hDC, Rect.right, Rect.bottom - 5, 0, NULL, s_wszSafeMode, len, NULL, 0);
2352 }
2353
2354 IntGdiSetBkMode(hDC, mode_old);
2355 IntGdiSetTextAlign(hDC, align_old);
2356 IntGdiSetTextColor(hDC, color_old);
2357
2358 if (hFont2)
2359 GreDeleteObject(hFont2);
2360
2361 if (hFont1)
2362 {
2363 NtGdiSelectFont(hDC, hOldFont);
2364 GreDeleteObject(hFont1);
2365 }
2366 }
2367
2368 return TRUE;
2369}
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:7215
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
#define min(a, b)
Definition: monoChain.cc:55
BOOL g_AlwaysDisplayVersion
Definition: ntuser.c:17
long LONG
Definition: pedump.c:60
__kernel_entry W32KAPI HBRUSH APIENTRY NtGdiSelectBrush(_In_ HDC hdc, _In_ HBRUSH hbrush)
__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 HFONT APIENTRY NtGdiSelectFont(_In_ HDC hdc, _In_ HFONT hf)
Definition: dcobjs.c:597
Definition: polytest.cpp:41
HBRUSH hbrBackground
Definition: ntuser.h:591
LPCWSTR lpstr
Definition: wingdi.h:3010
UINT n
Definition: wingdi.h:3009
NONCLIENTMETRICSW ncm
Definition: sysparams.h:51
HANDLE hbmWallpaper
Definition: sysparams.h:142
PCLS pcls
Definition: ntuser.h:724
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:1158
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:1402
static NTSTATUS GetSystemVersionString(OUT PWSTR pwszzVersion, IN SIZE_T cchDest, IN BOOLEAN InSafeMode, IN BOOLEAN AppendNtSystemRoot)
Definition: desktop.c:307
static BOOL IntPaintWallpaper(HDC hDC, PWND pwndDesktop)
Definition: desktop.c:2046
BOOL g_PaintDesktopVersion
Definition: sysparams.c:19
BOOL FASTCALL UserSystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni)
Definition: sysparams.c:2137
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 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().

◆ IntPaintWallpaper()

static BOOL IntPaintWallpaper ( HDC  hDC,
PWND  pwndDesktop 
)
static

Definition at line 2046 of file desktop.c.

2047{
2048 HBRUSH DesktopBrush, PreviousBrush;
2049 HBITMAP hOldBitmap;
2050 POINT ptSrc, ptDst;
2051 SIZE szDesk, szSrc, szDst;
2052 RECT Rect;
2053
2054 if (GdiGetClipBox(hDC, &Rect) == ERROR)
2055 return FALSE;
2056
2057 DesktopBrush = (HBRUSH)pwndDesktop->pcls->hbrBackground;
2058
2059 IntCalcWallpaperCoordinates(pwndDesktop, &szDesk, &szSrc, &szDst, &ptSrc, &ptDst);
2060
2061 /* Fill in the area that the bitmap is not going to cover */
2062 if (ptDst.x > 0 || ptDst.y > 0)
2063 {
2064 /* FIXME: Clip out the bitmap
2065 can be replaced with "NtGdiPatBlt(hDC, x, y, gspv.cxWallpaper, gspv.cyWallpaper, PATCOPY | DSTINVERT);"
2066 once we support DSTINVERT */
2067 PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
2068 NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
2069 NtGdiSelectBrush(hDC, PreviousBrush);
2070 }
2071
2073
2074 if (gspv.WallpaperMode == wmStretch ||
2077 {
2079 ptDst.x,
2080 ptDst.y,
2081 szDst.cx,
2082 szDst.cy,
2083 hSystemBM,
2084 ptDst.x,
2085 ptDst.y,
2086 SRCCOPY,
2088 0);
2089 }
2090 else if (gspv.WallpaperMode == wmTile)
2091 {
2092 /* Paint the bitmap across the screen then down */
2093 for (int y = 0; y < Rect.bottom; y += gspv.cyWallpaper)
2094 {
2095 for (int x = 0; x < Rect.right; x += gspv.cxWallpaper)
2096 {
2098 x,
2099 y,
2100 szDst.cx,
2101 szDst.cy,
2102 hSystemBM,
2103 ptSrc.x,
2104 ptSrc.y,
2105 SRCCOPY,
2107 0);
2108 }
2109 }
2110 }
2111 else /* wmCenter */
2112 {
2114 ptDst.x,
2115 ptDst.y,
2116 szDst.cx,
2117 szDst.cy,
2118 hSystemBM,
2119 ptSrc.x,
2120 ptSrc.y,
2121 SRCCOPY,
2123 0);
2124 }
2125 NtGdiSelectBitmap(hSystemBM, hOldBitmap);
2126 return TRUE;
2127}
HDC hSystemBM
Definition: stockobj.c:52
static HBITMAP
Definition: button.c:44
__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 HBITMAP APIENTRY NtGdiSelectBitmap(_In_ HDC hdc, _In_ HBITMAP hbm)
static VOID IntCalcWallpaperCoordinates(_In_ PWND pwndDesktop, _Out_ PSIZE pszDesk, _Out_ PSIZE pszSrc, _Out_ PSIZE pszDst, _Out_ PPOINT pptSrc, _Out_ PPOINT pptDst)
Definition: desktop.c:1857
#define CLR_INVALID
Definition: wingdi.h:883
#define SRCCOPY
Definition: wingdi.h:333

Referenced by IntPaintDesktop().

◆ IntRegisterShellHookWindow()

BOOL IntRegisterShellHookWindow ( HWND  hWnd)

Definition at line 1774 of file desktop.c.

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

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

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

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

3402{
3403 PDESKTOP pdesk = NULL, pdeskOld;
3404 PTHREADINFO pti;
3406 PCLIENTTHREADINFO pctiOld, pctiNew = NULL;
3407 PCLIENTINFO pci;
3408
3410
3411 TRACE("IntSetThreadDesktop hDesktop:0x%p, FOF:%i\n",hDesktop, FreeOnFailure);
3412
3414 pci = pti->pClientInfo;
3415
3416 /* If the caller gave us a desktop, ensure it is valid */
3417 if (hDesktop != NULL)
3418 {
3419 /* Validate the new desktop. */
3420 Status = IntValidateDesktopHandle(hDesktop, UserMode, 0, &pdesk);
3421 if (!NT_SUCCESS(Status))
3422 {
3423 ERR("Validation of desktop handle 0x%p failed\n", hDesktop);
3424 return FALSE;
3425 }
3426
3427 if (pti->rpdesk == pdesk)
3428 {
3429 /* Nothing to do */
3430 ObDereferenceObject(pdesk);
3431 return TRUE;
3432 }
3433 }
3434
3435 /* Make sure that we don't own any window in the current desktop */
3436 if (!IsListEmpty(&pti->WindowListHead))
3437 {
3438 if (pdesk)
3439 ObDereferenceObject(pdesk);
3440 ERR("Attempted to change thread desktop although the thread has windows!\n");
3442 return FALSE;
3443 }
3444
3445 /* Desktop is being re-set so clear out foreground. */
3446 if (pti->rpdesk != pdesk && pti->MessageQueue == gpqForeground)
3447 {
3448 // Like above, there shouldn't be any windows, hooks or anything active on this threads desktop!
3450 }
3451
3452 /* Before doing the switch, map the new desktop heap and allocate the new pcti */
3453 if (pdesk != NULL)
3454 {
3455 Status = IntMapDesktopView(pdesk);
3456 if (!NT_SUCCESS(Status))
3457 {
3458 ERR("Failed to map desktop heap!\n");
3459 ObDereferenceObject(pdesk);
3461 return FALSE;
3462 }
3463
3464 pctiNew = DesktopHeapAlloc(pdesk, sizeof(CLIENTTHREADINFO));
3465 if (pctiNew == NULL)
3466 {
3467 ERR("Failed to allocate new pcti\n");
3468 IntUnmapDesktopView(pdesk);
3469 ObDereferenceObject(pdesk);
3471 return FALSE;
3472 }
3473 }
3474
3475 /*
3476 * Processes, in particular Winlogon.exe, that manage window stations
3477 * (especially the interactive WinSta0 window station) and desktops,
3478 * may not be able to connect at startup to a window station and have
3479 * an associated desktop as well, if none exists on the system already.
3480 * Because creating a new window station does not affect the window station
3481 * associated to the process, and because neither by associating a window
3482 * station to the process nor creating a new desktop on it does associate
3483 * a startup desktop to that process, the process has to actually assigns
3484 * one of its threads to a desktop so that it gets automatically an assigned
3485 * startup desktop.
3486 *
3487 * This is what actually happens for Winlogon.exe, which is started without
3488 * any window station and desktop. By creating the first (and therefore
3489 * interactive) WinSta0 window station, then assigning WinSta0 to itself
3490 * and creating the Default desktop on it, and then assigning this desktop
3491 * to its main thread, Winlogon.exe basically does the similar steps that
3492 * would have been done automatically at its startup if there were already
3493 * an existing WinSta0 window station and Default desktop.
3494 *
3495 * Of course all this must not be done if we are a SYSTEM or CSRSS thread.
3496 */
3497 // if (pti->ppi->peProcess != gpepCSRSS)
3498 if (!(pti->TIF_flags & (TIF_SYSTEMTHREAD | TIF_CSRSSTHREAD)) &&
3499 pti->ppi->rpdeskStartup == NULL && hDesktop != NULL)
3500 {
3501 ERR("The process 0x%p '%s' didn't have an assigned startup desktop before, assigning it now!\n",
3502 pti->ppi->peProcess, pti->ppi->peProcess->ImageFileName);
3503
3504 pti->ppi->hdeskStartup = hDesktop;
3505 pti->ppi->rpdeskStartup = pdesk;
3506 }
3507
3508 /* free all classes or move them to the shared heap */
3509 if (pti->rpdesk != NULL)
3510 {
3511 if (!IntCheckProcessDesktopClasses(pti->rpdesk, FreeOnFailure))
3512 {
3513 ERR("Failed to move process classes to shared heap!\n");
3514 if (pdesk)
3515 {
3516 DesktopHeapFree(pdesk, pctiNew);
3517 IntUnmapDesktopView(pdesk);
3518 ObDereferenceObject(pdesk);
3519 }
3520 return FALSE;
3521 }
3522 }
3523
3524 pdeskOld = pti->rpdesk;
3525 if (pti->pcti != &pti->cti)
3526 pctiOld = pti->pcti;
3527 else
3528 pctiOld = NULL;
3529
3530 /* do the switch */
3531 if (pdesk != NULL)
3532 {
3533 pti->rpdesk = pdesk;
3534 pti->hdesk = hDesktop;
3535 pti->pDeskInfo = pti->rpdesk->pDeskInfo;
3536 pti->pcti = pctiNew;
3537
3539 pci->pDeskInfo = (PVOID)((ULONG_PTR)pti->pDeskInfo - pci->ulClientDelta);
3540 pci->pClientThreadInfo = (PVOID)((ULONG_PTR)pti->pcti - pci->ulClientDelta);
3541
3542 /* initialize the new pcti */
3543 if (pctiOld != NULL)
3544 {
3545 RtlCopyMemory(pctiNew, pctiOld, sizeof(CLIENTTHREADINFO));
3546 }
3547 else
3548 {
3549 RtlZeroMemory(pctiNew, sizeof(CLIENTTHREADINFO));
3550 pci->fsHooks = pti->fsHooks;
3551 pci->dwTIFlags = pti->TIF_flags;
3552 }
3553 }
3554 else
3555 {
3556 pti->rpdesk = NULL;
3557 pti->hdesk = NULL;
3558 pti->pDeskInfo = NULL;
3559 pti->pcti = &pti->cti; // Always point inside so there will be no crash when posting or sending msg's!
3560 pci->ulClientDelta = 0;
3561 pci->pDeskInfo = NULL;
3562 pci->pClientThreadInfo = NULL;
3563 }
3564
3565 /* clean up the old desktop */
3566 if (pdeskOld != NULL)
3567 {
3568 RemoveEntryList(&pti->PtiLink);
3569 if (pctiOld) DesktopHeapFree(pdeskOld, pctiOld);
3570 IntUnmapDesktopView(pdeskOld);
3571 ObDereferenceObject(pdeskOld);
3572 }
3573
3574 if (pdesk)
3575 {
3576 InsertTailList(&pdesk->PtiList, &pti->PtiLink);
3577 }
3578
3579 TRACE("IntSetThreadDesktop: pti 0x%p ppi 0x%p switched from object 0x%p to 0x%p\n", pti, pti->ppi, pdeskOld, pdesk);
3580
3581 return TRUE;
3582}
#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:274
static __inline PVOID DesktopHeapAlloc(IN PDESKTOP Desktop, IN SIZE_T Bytes)
Definition: desktop.h:206
static __inline BOOL DesktopHeapFree(IN PDESKTOP Desktop, IN PVOID lpMem)
Definition: desktop.h:217
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define TIF_CSRSSTHREAD
Definition: ntuser.h:269
#define TIF_SYSTEMTHREAD
Definition: ntuser.h:268
#define NtCurrentTeb
ULONG_PTR ulClientDelta
Definition: ntuser.h:330
ULONG fsHooks
Definition: ntuser.h:332
PCLIENTTHREADINFO pClientThreadInfo
Definition: ntuser.h:336
DWORD dwTIFlags
Definition: ntuser.h:328
PDESKTOPINFO pDeskInfo
Definition: ntuser.h:329
LIST_ENTRY PtiList
Definition: desktop.h:25
ULONG fsHooks
Definition: win32.h:118
CLIENTTHREADINFO cti
Definition: win32.h:145
struct _CLIENTTHREADINFO * pcti
Definition: win32.h:92
LIST_ENTRY WindowListHead
Definition: win32.h:156
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:90
LIST_ENTRY PtiLink
Definition: win32.h:127
#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:1347
NTSTATUS FASTCALL IntValidateDesktopHandle(HDESK Desktop, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PDESKTOP *Object)
Definition: desktop.c:1265
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:21

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

◆ IntStretchWallpaper()

HBITMAP IntStretchWallpaper ( _In_ PWND  pwndDesktop,
_In_ HBITMAP  hBitmap 
)

Definition at line 1988 of file desktop.c.

1991{
1992 HDC hWallpaperDC;
1993 HBITMAP hNewBitmap;
1994 POINT ptSrc, ptDst;
1995 SIZE szDesk, szSrc, szDst;
1996
1997 if (!hBitmap)
1998 return NULL;
1999
2000 IntCalcWallpaperCoordinates(pwndDesktop, &szDesk, &szSrc, &szDst, &ptSrc, &ptDst);
2001
2003 if (hWallpaperDC)
2004 {
2005 hNewBitmap = NtGdiCreateCompatibleBitmap(ScreenDeviceContext, szDesk.cx, szDesk.cy);
2006 if (hNewBitmap)
2007 {
2008 HBITMAP hOldBitmap1, hOldBitmap2;
2009
2010 hOldBitmap1 = NtGdiSelectBitmap(hSystemBM, hNewBitmap);
2011 hOldBitmap2 = NtGdiSelectBitmap(hWallpaperDC, hBitmap);
2012
2013 /*
2014 * Stretch the bitmap to the required coordinates
2015 * on the system memory DC first,
2016 * and then simply blit the result to an ouput hDC
2017 * to show the bitmap on the desktop.
2018 * Fixes improper wallpaper painting.
2019 */
2021 ptDst.x,
2022 ptDst.y,
2023 szDst.cx,
2024 szDst.cy,
2025 hWallpaperDC,
2026 ptSrc.x,
2027 ptSrc.y,
2028 szSrc.cx,
2029 szSrc.cy,
2030 SRCCOPY,
2031 0);
2032
2033 NtGdiSelectBitmap(hSystemBM, hOldBitmap1);
2034 NtGdiSelectBitmap(hWallpaperDC, hOldBitmap2);
2035 NtGdiDeleteObjectApp(hWallpaperDC);
2038 return hNewBitmap;
2039 }
2040 NtGdiDeleteObjectApp(hWallpaperDC);
2041 }
2042 return NULL;
2043}
BOOL NTAPI GreSetBitmapOwner(_In_ HBITMAP hbmp, _In_ ULONG ulOwner)
Definition: bitmaps.c:17
static HBITMAP hBitmap
Definition: timezone.c:26
#define GDI_OBJ_HMGR_PUBLIC
Definition: ntgdihdl.h:116
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiCreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
__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 BOOL APIENTRY NtGdiDeleteObjectApp(_In_ HANDLE hobj)
HDC ScreenDeviceContext
Definition: desktop.c:52

Referenced by SpiSetWallpaper().

◆ IntUnmapDesktopView()

static NTSTATUS IntUnmapDesktopView ( IN PDESKTOP  pdesk)
static

Definition at line 3282 of file desktop.c.

3283{
3284 PPROCESSINFO ppi;
3285 PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
3287
3288 TRACE("IntUnmapDesktopView called for desktop object %p\n", pdesk);
3289
3291
3292 /*
3293 * Unmap if we're the last thread using the desktop.
3294 * Start the search at the next mapping: skip the first entry
3295 * as it must be the global user heap mapping.
3296 */
3297 PrevLink = &ppi->HeapMappings.Next;
3298 HeapMapping = *PrevLink;
3299 while (HeapMapping != NULL)
3300 {
3301 if (HeapMapping->KernelMapping == (PVOID)pdesk->pheapDesktop)
3302 {
3303 if (--HeapMapping->Count == 0)
3304 {
3305 *PrevLink = HeapMapping->Next;
3306
3307 TRACE("ppi 0x%p unmapped heap of desktop 0x%p\n", ppi, pdesk);
3309 HeapMapping->UserMapping);
3310
3311 ObDereferenceObject(pdesk);
3312
3313 UserHeapFree(HeapMapping);
3314 break;
3315 }
3316 }
3317
3318 PrevLink = &HeapMapping->Next;
3319 HeapMapping = HeapMapping->Next;
3320 }
3321
3322 return Status;
3323}
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 1265 of file desktop.c.

1270{
1272
1276 AccessMode,
1277 (PVOID*)Object,
1278 NULL);
1279
1280 TRACE("IntValidateDesktopHandle: handle:0x%p obj:0x%p access:0x%x Status:0x%lx\n",
1282
1283 if (!NT_SUCCESS(Status))
1285
1286 return Status;
1287}
_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 2852 of file desktop.c.

2853{
2854 PDESKTOP pdesk;
2856 BOOL Ret = FALSE;
2857
2858 TRACE("NtUserCloseDesktop(0x%p) called\n", hDesktop);
2860
2861 if (hDesktop == gptiCurrent->hdesk || hDesktop == gptiCurrent->ppi->hdeskStartup)
2862 {
2863 ERR("Attempted to close thread desktop\n");
2865 goto Exit; // Return FALSE
2866 }
2867
2868 Status = IntValidateDesktopHandle(hDesktop, UserMode, 0, &pdesk);
2869 if (!NT_SUCCESS(Status))
2870 {
2871 ERR("Validation of desktop handle 0x%p failed\n", hDesktop);
2872 goto Exit; // Return FALSE
2873 }
2874
2875 ObDereferenceObject(pdesk);
2876
2877 Status = ObCloseHandle(hDesktop, UserMode);
2878 if (!NT_SUCCESS(Status))
2879 {
2880 ERR("Failed to close desktop handle 0x%p\n", hDesktop);
2882 goto Exit; // Return FALSE
2883 }
2884
2885 Ret = TRUE;
2886
2887Exit:
2888 TRACE("Leave NtUserCloseDesktop, ret=%i\n", Ret);
2889 UserLeave();
2890 return Ret;
2891}
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 2659 of file desktop.c.

2665{
2667 HDESK hDesk;
2668 HDESK Ret = NULL;
2669
2670 TRACE("Enter NtUserCreateDesktop\n");
2672
2673 Status = IntCreateDesktop(&hDesk,
2675 UserMode,
2676 lpszDesktopDevice,
2677 lpdmw,
2678 dwFlags,
2679 dwDesiredAccess);
2680 if (!NT_SUCCESS(Status))
2681 {
2682 ERR("IntCreateDesktop failed, Status 0x%08lx\n", Status);
2683 // SetLastNtError(Status);
2684 goto Exit; // Return NULL
2685 }
2686
2687 Ret = hDesk;
2688
2689Exit:
2690 TRACE("Leave NtUserCreateDesktop, ret=0x%p\n", Ret);
2691 UserLeave();
2692 return Ret;
2693}
_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 3173 of file desktop.c.

3174{
3175 HDESK hDesk;
3177 PTHREADINFO pti;
3179 PDESKTOP DesktopObject;
3181
3183 TRACE("Enter NtUserGetThreadDesktop\n");
3184
3185 if (!dwThreadId)
3186 {
3188 hDesk = NULL;
3189 goto Quit;
3190 }
3191
3192 /* Validate the Win32 thread and retrieve its information */
3194 if (pti)
3195 {
3196 /* Get the desktop handle of the thread */
3197 hDesk = pti->hdesk;
3198 Process = pti->ppi->peProcess;
3199 }
3200 else if (hConsoleDesktop)
3201 {
3202 /*
3203 * The thread may belong to a console, so attempt to use the provided
3204 * console desktop handle as a fallback. Otherwise this means that the
3205 * thread is either not Win32 or invalid.
3206 */
3207 hDesk = hConsoleDesktop;
3209 }
3210 else
3211 {
3213 hDesk = NULL;
3214 goto Quit;
3215 }
3216
3217 if (!hDesk)
3218 {
3219 ERR("Desktop information of thread 0x%x broken!?\n", dwThreadId);
3220 goto Quit;
3221 }
3222
3224 {
3225 /*
3226 * Just return the handle, since we queried the desktop handle
3227 * of a thread running in the same context.
3228 */
3229 goto Quit;
3230 }
3231
3232 /*
3233 * We could just use the cached rpdesk instead of looking up the handle,
3234 * but it may actually be safer to validate the desktop and get a temporary
3235 * reference to it so that it does not disappear under us (e.g. when the
3236 * desktop is being destroyed) during the operation.
3237 */
3238 /*
3239 * Switch into the context of the thread we are trying to get
3240 * the desktop from, so we can use the handle.
3241 */
3242 KeAttachProcess(&Process->Pcb);
3244 0,
3246 UserMode,
3247 (PVOID*)&DesktopObject,
3250
3251 if (NT_SUCCESS(Status))
3252 {
3253 /*
3254 * Lookup our handle table if we can find a handle to the desktop object.
3255 * If not, create one.
3256 * QUESTION: Do we really need to create a handle in case it doesn't exist??
3257 */
3258 hDesk = IntGetDesktopObjectHandle(DesktopObject);
3259
3260 /* All done, we got a valid handle to the desktop */
3261 ObDereferenceObject(DesktopObject);
3262 }
3263 else
3264 {
3265 /* The handle could not be found, there is nothing to get... */
3266 hDesk = NULL;
3267 }
3268
3269 if (!hDesk)
3270 {
3271 ERR("Could not retrieve or access desktop for thread 0x%x\n", dwThreadId);
3273 }
3274
3275Quit:
3276 TRACE("Leave NtUserGetThreadDesktop, hDesk = 0x%p\n", hDesk);
3277 UserLeave();
3278 return hDesk;
3279}
#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:1299
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 2718 of file desktop.c.

2722{
2724 HDESK Desktop;
2725
2729 UserMode,
2730 NULL,
2731 dwDesiredAccess,
2732 NULL,
2733 (HANDLE*)&Desktop);
2734
2735 if (!NT_SUCCESS(Status))
2736 {
2737 ERR("Failed to open desktop\n");
2739 return NULL;
2740 }
2741
2742 TRACE("Opened desktop %S with handle 0x%p\n", ObjectAttributes->ObjectName->Buffer, Desktop);
2743
2744 return Desktop;
2745}

Referenced by OpenDesktopW().

◆ NtUserOpenInputDesktop()

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

Definition at line 2812 of file desktop.c.

2816{
2817 HDESK hdesk;
2818
2820 TRACE("Enter NtUserOpenInputDesktop gpdeskInputDesktop 0x%p\n", gpdeskInputDesktop);
2821
2822 hdesk = UserOpenInputDesktop(dwFlags, fInherit, dwDesiredAccess);
2823
2824 TRACE("NtUserOpenInputDesktop returning 0x%p\n", hdesk);
2825 UserLeave();
2826 return hdesk;
2827}

Referenced by OpenInputDesktop().

◆ NtUserPaintDesktop()

BOOL APIENTRY NtUserPaintDesktop ( HDC  hDC)

Definition at line 2909 of file desktop.c.

2910{
2911 BOOL Ret;
2912
2914 TRACE("Enter NtUserPaintDesktop\n");
2915
2916 Ret = IntPaintDesktop(hDC);
2917
2918 TRACE("Leave NtUserPaintDesktop, ret=%i\n", Ret);
2919 UserLeave();
2920 return Ret;
2921}

Referenced by PaintDesktop().

◆ NtUserResolveDesktop()

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

Definition at line 2959 of file desktop.c.

2964{
2967 HWINSTA hWinSta = NULL;
2968 HDESK hDesktop = NULL;
2969 UNICODE_STRING CapturedDesktopPath;
2970
2971 /* Allow only the Console Server to perform this operation (via CSRSS) */
2973 return NULL;
2974
2975 /* Get the process object the user handle was referencing */
2979 UserMode,
2980 (PVOID*)&Process,
2981 NULL);
2982 if (!NT_SUCCESS(Status))
2983 return NULL;
2984
2986
2987 _SEH2_TRY
2988 {
2989 /* Probe the handle pointer */
2990 // ProbeForWriteHandle
2991 ProbeForWrite(phWinSta, sizeof(HWINSTA), sizeof(HWINSTA));
2992 }
2994 {
2996 _SEH2_YIELD(goto Quit);
2997 }
2998 _SEH2_END;
2999
3000 /* Capture the user desktop path string */
3001 Status = ProbeAndCaptureUnicodeString(&CapturedDesktopPath,
3002 UserMode,
3003 DesktopPath);
3004 if (!NT_SUCCESS(Status))
3005 goto Quit;
3006
3007 /* Call the internal function */
3009 &CapturedDesktopPath,
3010 bInherit,
3011 &hWinSta,
3012 &hDesktop);
3013 if (!NT_SUCCESS(Status))
3014 {
3015 ERR("IntResolveDesktop failed, Status 0x%08lx\n", Status);
3016 hWinSta = NULL;
3017 hDesktop = NULL;
3018 }
3019
3020 _SEH2_TRY
3021 {
3022 /* Return the window station handle */
3023 *phWinSta = hWinSta;
3024 }
3026 {
3028
3029 /* We failed, close the opened desktop and window station */
3030 if (hDesktop) ObCloseHandle(hDesktop, UserMode);
3031 hDesktop = NULL;
3032 if (hWinSta) ObCloseHandle(hWinSta, UserMode);
3033 }
3034 _SEH2_END;
3035
3036 /* Free the captured string */
3037 ReleaseCapturedUnicodeString(&CapturedDesktopPath, UserMode);
3038
3039Quit:
3040 UserLeave();
3041
3042 /* Dereference the process object */
3044
3045 /* Return the desktop handle */
3046 return hDesktop;
3047}
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:407
#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:575

Referenced by GuiInit().

◆ NtUserSetThreadDesktop()

BOOL APIENTRY NtUserSetThreadDesktop ( HDESK  hDesktop)

Definition at line 3592 of file desktop.c.

3593{
3594 BOOL ret = FALSE;
3595
3597
3598 // FIXME: IntSetThreadDesktop validates the desktop handle, it should happen
3599 // here too and set the NT error level. Q. Is it necessary to have the validation
3600 // in IntSetThreadDesktop? Is it needed there too?
3601 if (hDesktop || (!hDesktop && PsGetCurrentProcess() == gpepCSRSS))
3602 ret = IntSetThreadDesktop(hDesktop, FALSE);
3603
3604 UserLeave();
3605
3606 return ret;
3607}
return ret
Definition: mutex.c:147

Referenced by SetThreadDesktop().

◆ NtUserSwitchDesktop()

BOOL APIENTRY NtUserSwitchDesktop ( HDESK  hdesk)

Definition at line 3066 of file desktop.c.

3067{
3068 PDESKTOP pdesk;
3070 BOOL bRedrawDesktop;
3071 BOOL Ret = FALSE;
3072
3074 TRACE("Enter NtUserSwitchDesktop(0x%p)\n", hdesk);
3075
3076 Status = IntValidateDesktopHandle(hdesk, UserMode, 0, &pdesk);
3077 if (!NT_SUCCESS(Status))
3078 {
3079 ERR("Validation of desktop handle 0x%p failed\n", hdesk);
3080 goto Exit;
3081 }
3082
3084 {
3085 ObDereferenceObject(pdesk);
3086 ERR("NtUserSwitchDesktop called for a desktop of a different session\n");
3087 goto Exit;
3088 }
3089
3090 if (pdesk == gpdeskInputDesktop)
3091 {
3092 ObDereferenceObject(pdesk);
3093 WARN("NtUserSwitchDesktop called for active desktop\n");
3094 Ret = TRUE;
3095 goto Exit;
3096 }
3097
3098 /*
3099 * Don't allow applications switch the desktop if it's locked,
3100 * unless the caller is the logon application itself.
3101 */
3102 if ((pdesk->rpwinstaParent->Flags & WSS_LOCKED) &&
3104 {
3105 ObDereferenceObject(pdesk);
3106 ERR("Switching desktop 0x%p denied because the window station is locked!\n", hdesk);
3107 goto Exit;
3108 }
3109
3110 if (pdesk->rpwinstaParent != InputWindowStation)
3111 {
3112 ObDereferenceObject(pdesk);
3113 ERR("Switching desktop 0x%p denied because desktop doesn't belong to the interactive winsta!\n", hdesk);
3114 goto Exit;
3115 }
3116
3117 /* FIXME: Fail if the process is associated with a secured
3118 desktop such as Winlogon or Screen-Saver */
3119 /* FIXME: Connect to input device */
3120
3121 TRACE("Switching from desktop 0x%p to 0x%p\n", gpdeskInputDesktop, pdesk);
3122
3123 bRedrawDesktop = FALSE;
3124
3125 /* The first time SwitchDesktop is called, gpdeskInputDesktop is NULL */
3126 if (gpdeskInputDesktop != NULL)
3127 {
3129 bRedrawDesktop = TRUE;
3130
3131 /* Hide the previous desktop window */
3133 }
3134
3135 /* Set the active desktop in the desktop's window station */
3137
3138 /* Set the global state */
3139 gpdeskInputDesktop = pdesk;
3140
3141 /* Show the new desktop window */
3143
3144 // TODO: Request hard-error popups to be respawned to the new desktop.
3145
3146 /* Notify waiters that a desktop has been switched on the
3147 * interactive window station: pulse the legacy (NT 3.5+)
3148 * event and send the desktop-switch notification (Vista+) */
3150#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
3151 IntNotifyWinEvent(EVENT_SYSTEM_DESKTOPSWITCH, NULL, OBJID_WINDOW, CHILDID_SELF, 0);
3152#endif
3153
3154 TRACE("SwitchDesktop gpdeskInputDesktop 0x%p\n", gpdeskInputDesktop);
3155 ObDereferenceObject(pdesk);
3156
3157 Ret = TRUE;
3158
3159Exit:
3160 TRACE("Leave NtUserSwitchDesktop, ret=%i\n", Ret);
3161 UserLeave();
3162 return Ret;
3163}
#define WARN(fmt,...)
Definition: precomp.h:61
LONG NTAPI KePulseEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:69
#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
PKEVENT gpDesktopSwitchEvent
WinSta0_DesktopSwitch legacy (NT 3.5+) event.
Definition: desktop.c:56
NTSTATUS FASTCALL IntHideDesktop(PDESKTOP Desktop)
Definition: desktop.c:1655
NTSTATUS FASTCALL co_IntShowDesktop(PDESKTOP Desktop, ULONG Width, ULONG Height, BOOL bRedraw)
Definition: desktop.c:1637
VOID FASTCALL IntNotifyWinEvent(DWORD Event, PWND pWnd, LONG idObject, LONG idChild, DWORD flags)
Definition: event.c:178
#define WSS_LOCKED
Definition: winsta.h:7
#define OBJID_WINDOW
Definition: winable.h:15
#define CHILDID_SELF
Definition: winable.h:14
#define EVENT_INCREMENT
Definition: iotypes.h:597

Referenced by SwitchDesktop().

◆ UserBuildShellHookHwndList()

static HWND *FASTCALL UserBuildShellHookHwndList ( PDESKTOP  Desktop)
static

Definition at line 1671 of file desktop.c.

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

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

Referenced by DxEngGetDesktopDC().

◆ UserGetDesktopWindow()

◆ UserGetMessageWindow()

PWND FASTCALL UserGetMessageWindow ( VOID  )

Definition at line 1436 of file desktop.c.

1437{
1439 if (!pdo)
1440 {
1441 TRACE("No active desktop\n");
1442 return NULL;
1443 }
1444 return pdo->spwndMessage;
1445}

◆ UserInitializeDesktop()

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

Definition at line 2372 of file desktop.c.

2373{
2374 static const UNICODE_STRING WinlogonDesktop = RTL_CONSTANT_STRING(L"Winlogon");
2375 PVOID DesktopHeapSystemBase = NULL;
2377 SIZE_T DesktopInfoSize;
2378 ULONG i;
2379
2380 TRACE("UserInitializeDesktop desktop 0x%p with name %wZ\n", pdesk, DesktopName);
2381
2382 /* Set desktop size, based on whether the WinSta is interactive or not */
2383 if (pwinsta == InputWindowStation)
2384 {
2385 /* Check if the Desktop is named "Winlogon" */
2386 if (RtlEqualUnicodeString(DesktopName, &WinlogonDesktop, TRUE))
2387 {
2389 }
2390 else
2391 {
2393 }
2394 }
2395 else
2396 {
2398 }
2399
2400 /* Link the desktop with the parent window station */
2401 ObReferenceObject(pwinsta);
2402 pdesk->rpwinstaParent = pwinsta;
2403 InsertTailList(&pwinsta->DesktopListHead, &pdesk->ListEntry);
2404
2405 /* Create the desktop heap */
2406 pdesk->hsectionDesktop = NULL;
2408 &DesktopHeapSystemBase,
2409 HeapSize);
2410 if (pdesk->pheapDesktop == NULL)
2411 {
2412 ERR("Failed to create desktop heap!\n");
2413 return STATUS_NO_MEMORY;
2414 }
2415
2416 /* Create DESKTOPINFO */
2417 DesktopInfoSize = sizeof(DESKTOPINFO) + DesktopName->Length + sizeof(WCHAR);
2418 pdesk->pDeskInfo = RtlAllocateHeap(pdesk->pheapDesktop,
2420 DesktopInfoSize);
2421 if (pdesk->pDeskInfo == NULL)
2422 {
2423 ERR("Failed to create the DESKTOP structure!\n");
2424 return STATUS_NO_MEMORY;
2425 }
2426
2427 /* Initialize the DESKTOPINFO */
2428 pdesk->pDeskInfo->pvDesktopBase = DesktopHeapSystemBase;
2429 pdesk->pDeskInfo->pvDesktopLimit = (PVOID)((ULONG_PTR)DesktopHeapSystemBase + HeapSize);
2431 DesktopName->Buffer,
2432 DesktopName->Length + sizeof(WCHAR));
2433 for (i = 0; i < NB_HOOKS; i++)
2434 {
2436 }
2437
2439 InitializeListHead(&pdesk->PtiList);
2440
2441 return STATUS_SUCCESS;
2442}
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:130
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1695
WCHAR szDesktopName[1]
Definition: ntuser.h:161
LIST_ENTRY aphkStart[NB_HOOKS]
Definition: ntuser.h:142
PVOID pvDesktopLimit
Definition: ntuser.h:139
PVOID pvDesktopBase
Definition: ntuser.h:138
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 1545 of file desktop.c.

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

2750{
2754 HDESK hdesk = NULL;
2755
2756 if (!gpdeskInputDesktop)
2757 {
2758 return NULL;
2759 }
2760
2761 if (pti->ppi->prpwinsta != InputWindowStation)
2762 {
2763 ERR("Tried to open input desktop from non interactive winsta!\n");
2765 return NULL;
2766 }
2767
2768 if (fInherit) HandleAttributes = OBJ_INHERIT;
2769
2770 /* Create a new handle to the object */
2774 NULL,
2775 dwDesiredAccess,
2777 UserMode,
2778 (PHANDLE)&hdesk);
2779
2780 if (!NT_SUCCESS(Status))
2781 {
2782 ERR("Failed to open input desktop object\n");
2784 }
2785
2786 return hdesk;
2787}
#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 1619 of file desktop.c.

1620{
1621 PWND Window = NULL;
1622 PREGION Rgn;
1623
1625 Rgn = IntSysCreateRectpRgnIndirect(&Window->rcWindow);
1626
1628 Rgn,
1631
1632 REGION_Delete(Rgn);
1633}
#define IntSysCreateRectpRgnIndirect(prc)
Definition: region.h:93
Definition: window.c:29
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 54 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().

◆ ghDesktopSwitchEvent

HANDLE ghDesktopSwitchEvent = NULL

WinSta0_DesktopSwitch handle in the CSRSS process.

Definition at line 57 of file desktop.c.

Referenced by IntCreateDesktopSwitchEvent(), and IntWinStaObjectDelete().

◆ gpdeskInputDesktop

PDESKTOP gpdeskInputDesktop = NULL

◆ gpDesktopSwitchEvent

PKEVENT gpDesktopSwitchEvent = NULL

WinSta0_DesktopSwitch legacy (NT 3.5+) event.

Definition at line 56 of file desktop.c.

Referenced by IntCreateDesktopSwitchEvent(), IntWinStaObjectDelete(), and NtUserSwitchDesktop().

◆ gpDesktopThreadStartedEvent

PKEVENT gpDesktopThreadStartedEvent = NULL

Definition at line 55 of file desktop.c.

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

◆ gptiDesktopThread

◆ ScreenDeviceContext