ReactOS 0.4.17-dev-684-ga6524ef
desktop.c File Reference
#include <win32k.h>
#include <reactos/buildno.h>
Include dependency graph for desktop.c:

Go to the source code of this file.

Functions

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

Variables

DWORD gdwDesktopSectionSize = 3 * 1024
 
DWORD gdwNOIOSectionSize = 128
 
DWORD gdwWinlogonSectionSize = 128
 
PDESKTOP gpdeskInputDesktop = NULL
 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 1390 of file desktop.c.

1391{
1392 if (pWnd->head.rpdesk &&
1393 pWnd->head.rpdesk->pDeskInfo)
1394 return pWnd->head.rpdesk->pDeskInfo->spwnd;
1395 return NULL;
1396}
#define NULL
Definition: types.h:112
struct _DESKTOP * rpdesk
Definition: ntuser.h:194
THRDESKHEAD head
Definition: ntuser.h:695

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

◆ co_IntShellHookNotify()

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

Definition at line 1708 of file desktop.c.

1709{
1711 HWND* HwndList;
1712
1713 if (!gpsi->uiShellMsg)
1714 {
1715 gpsi->uiShellMsg = IntAddAtom(L"SHELLHOOK");
1716
1717 TRACE("MsgType = %x\n", gpsi->uiShellMsg);
1718 if (!gpsi->uiShellMsg)
1719 ERR("LastError: %x\n", EngGetLastError());
1720 }
1721
1722 if (!Desktop)
1723 {
1724 TRACE("IntShellHookNotify: No desktop!\n");
1725 return;
1726 }
1727
1728 // Allow other devices have a shot at foreground.
1729 if (Message == HSHELL_APPCOMMAND) ptiLastInput = NULL;
1730
1731 // FIXME: System Tray Support.
1732
1734 if (HwndList)
1735 {
1736 HWND* cursor = HwndList;
1737 LPARAM shellhookparam = (Message == HSHELL_LANGUAGE || Message == HSHELL_APPCOMMAND)
1738 ? lParam : (LPARAM)wParam;
1739
1740 for (; *cursor; cursor++)
1741 {
1742 TRACE("Sending notify\n");
1745 Message,
1746 shellhookparam);
1747/* co_IntPostOrSendMessage(*cursor,
1748 gpsi->uiShellMsg,
1749 Message,
1750 shellhookparam);*/
1751 }
1752
1754 }
1755
1756 if (ISITHOOKED(WH_SHELL))
1757 {
1759 }
1760}
#define ERR(fmt,...)
Definition: precomp.h:57
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
static CHAR Desktop[MAX_PATH]
Definition: dem.c:256
static const WCHAR Message[]
Definition: register.c:74
#define L(x)
Definition: resources.c:13
PTHREADINFO ptiLastInput
Definition: focus.c:18
#define ISITHOOKED(HookId)
Definition: hook.h:6
const char cursor[]
Definition: icontest.c:13
PSERVERINFO gpsi
Definition: imm.c:18
LONG_PTR LPARAM
Definition: minwindef.h:175
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
LRESULT APIENTRY co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:1102
#define TRACE(s)
Definition: solgame.cpp:4
UINT uiShellMsg
Definition: ntuser.h:1063
RTL_ATOM FASTCALL IntAddAtom(LPWSTR AtomName)
Definition: useratom.c:13
PDESKTOP FASTCALL IntGetActiveDesktop(VOID)
Definition: desktop.c:1286
static HWND *FASTCALL UserBuildShellHookHwndList(PDESKTOP Desktop)
Definition: desktop.c:1667
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 1633 of file desktop.c.

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

Referenced by co_IntInitializeDesktopGraphics(), and NtUserSwitchDesktop().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserDesktop  )

◆ DesktopThreadMain()

VOID NTAPI DesktopThreadMain ( VOID  )

Definition at line 1562 of file desktop.c.

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

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

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

◆ GetSystemVersionString()

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

Definition at line 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().

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

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

Referenced by IntResolveDesktop(), and NtUserCreateDesktop().

◆ IntDeRegisterShellHookWindow()

BOOL IntDeRegisterShellHookWindow ( HWND  hWnd)

Definition at line 1802 of file desktop.c.

1803{
1805 PDESKTOP Desktop = pti->rpdesk;
1806 PLIST_ENTRY ListEntry;
1807 PSHELL_HOOK_WINDOW Current;
1808
1809 // FIXME: This probably shouldn't happen, but it does
1810 if (Desktop == NULL)
1811 {
1813 if (Desktop == NULL)
1814 return FALSE;
1815 }
1816
1817 ListEntry = Desktop->ShellHookWindows.Flink;
1818 while (ListEntry != &Desktop->ShellHookWindows)
1819 {
1820 Current = CONTAINING_RECORD(ListEntry, SHELL_HOOK_WINDOW, ListEntry);
1821 ListEntry = ListEntry->Flink;
1822 if (Current->hWnd == hWnd)
1823 {
1824 RemoveEntryList(&Current->ListEntry);
1825 ExFreePoolWithTag(Current, TAG_WINSTA);
1826 return TRUE;
1827 }
1828 }
1829
1830 return FALSE;
1831}
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:92
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define TAG_WINSTA
Definition: tags.h:11

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

◆ IntDesktopObjectClose()

NTSTATUS NTAPI IntDesktopObjectClose ( _In_ PVOID  Parameters)

Definition at line 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}
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
static NTSTATUS IntUnmapDesktopView(IN PDESKTOP pdesk)
Definition: desktop.c:3188

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:3232

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
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
ULONG NTAPI PsGetCurrentProcessSessionId(VOID)
Definition: process.c:1133
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:189
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c: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
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
static NTSTATUS UserInitializeDesktop(PDESKTOP pdesk, PUNICODE_STRING DesktopName, PWINSTATION_OBJECT pwinsta)
Definition: desktop.c:2278
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:264
PPROCESSINFO ppi
Definition: win32.h:88
HDESK hdesk
Definition: win32.h:108
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145

Referenced by DriverEntry().

◆ IntFreeDesktopHeap() [1/2]

static VOID IntFreeDesktopHeap ( IN OUT PDESKTOP  Desktop)
static

Definition at line 1834 of file desktop.c.

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

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

Referenced by NtUserFindWindowEx().

◆ IntGetDesktopObjectHandle()

HDESK FASTCALL IntGetDesktopObjectHandle ( PDESKTOP  DesktopObject)

Definition at line 1295 of file desktop.c.

1296{
1298 HDESK hDesk;
1299
1300 ASSERT(DesktopObject);
1301
1303 DesktopObject,
1305 NULL,
1306 (PHANDLE)&hDesk))
1307 {
1308 Status = ObOpenObjectByPointer(DesktopObject,
1309 0,
1310 NULL,
1311 0,
1313 UserMode,
1314 (PHANDLE)&hDesk);
1315 if (!NT_SUCCESS(Status))
1316 {
1317 /* Unable to create a handle */
1318 ERR("Unable to create a desktop handle\n");
1319 return NULL;
1320 }
1321 }
1322 else
1323 {
1324 TRACE("Got handle: 0x%p\n", hDesk);
1325 }
1326
1327 return hDesk;
1328}
#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 1421 of file desktop.c.

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

Referenced by NtUserFindWindowEx(), and NtUserSetParent().

◆ IntGetThreadDesktopWindow()

PWND FASTCALL IntGetThreadDesktopWindow ( PTHREADINFO  pti)

Definition at line 1383 of file desktop.c.

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

Referenced by ActivateOtherWindowMin().

◆ IntHideDesktop()

NTSTATUS FASTCALL IntHideDesktop ( PDESKTOP  Desktop)

Definition at line 1651 of file desktop.c.

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

Referenced by IntEndDesktopGraphics(), and NtUserSwitchDesktop().

◆ IntMapDesktopView()

static NTSTATUS IntMapDesktopView ( IN PDESKTOP  pdesk)
static

Definition at line 3232 of file desktop.c.

3233{
3234 PPROCESSINFO ppi;
3235 PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
3236 PVOID UserBase = NULL;
3237 SIZE_T ViewSize = 0;
3240
3241 TRACE("IntMapDesktopView called for desktop object 0x%p\n", pdesk);
3242
3244
3245 /*
3246 * Find out if another thread already mapped the desktop heap.
3247 * Start the search at the next mapping: skip the first entry
3248 * as it must be the global user heap mapping.
3249 */
3250 PrevLink = &ppi->HeapMappings.Next;
3251 HeapMapping = *PrevLink;
3252 while (HeapMapping != NULL)
3253 {
3254 if (HeapMapping->KernelMapping == (PVOID)pdesk->pheapDesktop)
3255 {
3256 HeapMapping->Count++;
3257 return STATUS_SUCCESS;
3258 }
3259
3260 PrevLink = &HeapMapping->Next;
3261 HeapMapping = HeapMapping->Next;
3262 }
3263
3264 /* We're the first, map the heap */
3265 Offset.QuadPart = 0;
3266 Status = MmMapViewOfSection(pdesk->hsectionDesktop,
3268 &UserBase,
3269 0,
3270 0,
3271 &Offset,
3272 &ViewSize,
3273 ViewUnmap,
3276 if (!NT_SUCCESS(Status))
3277 {
3278 ERR("Failed to map desktop\n");
3279 return Status;
3280 }
3281
3282 TRACE("ppi 0x%p mapped heap of desktop 0x%p\n", ppi, pdesk);
3283
3284 /* Add the mapping */
3285 HeapMapping = UserHeapAlloc(sizeof(*HeapMapping));
3286 if (HeapMapping == NULL)
3287 {
3289 ERR("UserHeapAlloc() failed!\n");
3290 return STATUS_NO_MEMORY;
3291 }
3292
3293 HeapMapping->Next = NULL;
3294 HeapMapping->KernelMapping = (PVOID)pdesk->pheapDesktop;
3295 HeapMapping->UserMapping = UserBase;
3296 HeapMapping->Limit = ViewSize;
3297 HeapMapping->Count = 1;
3298 *PrevLink = HeapMapping;
3299
3300 ObReferenceObject(pdesk);
3301
3302 return STATUS_SUCCESS;
3303}
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:1183
NTSTATUS NTAPI MmMapViewOfSection(_In_ PVOID SectionObject, _In_ PEPROCESS Process, _Outptr_result_bytebuffer_(*ViewSize) _Pre_opt_valid_ PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _In_ SIZE_T CommitSize, _Inout_opt_ PLARGE_INTEGER SectionOffset, _Inout_ PSIZE_T ViewSize, _In_range_(ViewShare, ViewUnmap) SECTION_INHERIT InheritDisposition, _In_ ULONG AllocationType, _In_ ULONG Protect)
Definition: section.c:4031
W32HEAP_USER_MAPPING HeapMappings
Definition: win32.h:291
struct _W32HEAP_USER_MAPPING * Next
Definition: win32.h:199
ULONG_PTR Limit
Definition: win32.h:202
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
static __inline PVOID UserHeapAlloc(SIZE_T Bytes)
Definition: usrheap.h:34

Referenced by IntDesktopObjectOpen(), and IntSetThreadDesktop().

◆ IntPaintDesktop()

BOOL FASTCALL IntPaintDesktop ( HDC  hDC)

Definition at line 1853 of file desktop.c.

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

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

◆ IntRegisterShellHookWindow()

BOOL IntRegisterShellHookWindow ( HWND  hWnd)

Definition at line 1770 of file desktop.c.

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

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
1197 UserMode,
1198 NULL,
1200 NULL,
1201 (PHANDLE)&hDesktop);
1202 if (!NT_SUCCESS(Status))
1203 {
1204 ERR("Failed to open the desktop '%wZ' on window station 0x%p, Status 0x%08lx\n",
1205 ObjectName, hWinSta, Status);
1206 goto Quit;
1207 }
1208 }
1209
1210Quit:
1211 /* Release the object attributes */
1212 if (ObjectAttributes)
1213 {
1214 MemSize = 0;
1215 ZwFreeVirtualMemory(ZwCurrentProcess(),
1217 &MemSize,
1218 MEM_RELEASE);
1219 }
1220
1221 /* Close the temporary process handle */
1222 if (hProcess) // if (Process != PsGetCurrentProcess())
1224
1225 if (NT_SUCCESS(Status))
1226 {
1227 *phWinSta = hWinSta;
1228 *phDesktop = hDesktop;
1229 return STATUS_SUCCESS;
1230 }
1231 else
1232 {
1233 ERR("IntResolveDesktop(%wZ) failed, Status 0x%08lx\n", DesktopPath, Status);
1234
1235 if (hDesktopDup)
1236 ObCloseHandle(hDesktopDup, UserMode);
1237 if (hWinStaDup)
1238 ObCloseHandle(hWinStaDup, UserMode);
1239
1240 if (hDesktop)
1241 ObCloseHandle(hDesktop, UserMode);
1242 if (hWinSta)
1243 ObCloseHandle(hWinSta, UserMode);
1244
1246 return Status;
1247 }
1248}
#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:268
struct _DESKTOP * rpdeskStartup
Definition: win32.h:259
struct _WINSTATION_OBJECT * prpwinsta
Definition: win32.h:267
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define max(a, b)
Definition: svc.c:63
#define MAXULONG
Definition: typedefs.h:251
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
POBJECT_TYPE ExWindowStationObjectType
Definition: win32k.c:21
NTSTATUS FASTCALL IntCreateDesktop(OUT HDESK *phDesktop, IN POBJECT_ATTRIBUTES ObjectAttributes, IN KPROCESSOR_MODE AccessMode, IN PUNICODE_STRING lpszDesktopDevice OPTIONAL, IN LPDEVMODEW lpdmw OPTIONAL, IN DWORD dwFlags, IN ACCESS_MASK dwDesiredAccess)
Definition: desktop.c:2387
NTSTATUS GetProcessLuid(IN PETHREAD Thread OPTIONAL, IN PEPROCESS Process OPTIONAL, OUT PLUID Luid)
Definition: misc.c:814
NTSTATUS NTAPI IntCreateServiceSecurity(_Out_ PSECURITY_DESCRIPTOR *ServiceSd)
Creates a security descriptor for the service.
Definition: security.c:327
VOID IntFreeSecurityBuffer(_In_ PVOID Buffer)
Frees an allocated security buffer from UM memory that is been previously allocated by IntAllocateSec...
Definition: security.c:133
#define WINSTA_ACCESS_ALL
Definition: security.h:57
#define WSS_NOIO
Definition: winsta.h:9
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:64
#define DUPLICATE_SAME_ACCESS
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:304
#define SYSTEM_LUID
Definition: setypes.h:700
#define ZwCurrentProcess()

Referenced by InitThreadCallback(), and NtUserResolveDesktop().

◆ IntSetFocusMessageQueue()

VOID FASTCALL IntSetFocusMessageQueue ( PUSER_MESSAGE_QUEUE  NewQueue)

Definition at line 1343 of file desktop.c.

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

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

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

◆ IntUnmapDesktopView()

static NTSTATUS IntUnmapDesktopView ( IN PDESKTOP  pdesk)
static

Definition at line 3188 of file desktop.c.

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

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

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

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

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

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

Referenced by OpenDesktopW().

◆ NtUserOpenInputDesktop()

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

Definition at line 2718 of file desktop.c.

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

Referenced by OpenInputDesktop().

◆ NtUserPaintDesktop()

BOOL APIENTRY NtUserPaintDesktop ( HDC  hDC)

Definition at line 2815 of file desktop.c.

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

Referenced by PaintDesktop().

◆ NtUserResolveDesktop()

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

Definition at line 2865 of file desktop.c.

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

3499{
3500 BOOL ret = FALSE;
3501
3503
3504 // FIXME: IntSetThreadDesktop validates the desktop handle, it should happen
3505 // here too and set the NT error level. Q. Is it necessary to have the validation
3506 // in IntSetThreadDesktop? Is it needed there too?
3507 if (hDesktop || (!hDesktop && PsGetCurrentProcess() == gpepCSRSS))
3508 ret = IntSetThreadDesktop(hDesktop, FALSE);
3509
3510 UserLeave();
3511
3512 return ret;
3513}
return ret
Definition: mutex.c:147

Referenced by SetThreadDesktop().

◆ NtUserSwitchDesktop()

BOOL APIENTRY NtUserSwitchDesktop ( HDESK  hdesk)

Definition at line 2972 of file desktop.c.

2973{
2974 PDESKTOP pdesk;
2976 BOOL bRedrawDesktop;
2977 BOOL Ret = FALSE;
2978
2980 TRACE("Enter NtUserSwitchDesktop(0x%p)\n", hdesk);
2981
2982 Status = IntValidateDesktopHandle(hdesk, UserMode, 0, &pdesk);
2983 if (!NT_SUCCESS(Status))
2984 {
2985 ERR("Validation of desktop handle 0x%p failed\n", hdesk);
2986 goto Exit;
2987 }
2988
2990 {
2991 ObDereferenceObject(pdesk);
2992 ERR("NtUserSwitchDesktop called for a desktop of a different session\n");
2993 goto Exit;
2994 }
2995
2996 if (pdesk == gpdeskInputDesktop)
2997 {
2998 ObDereferenceObject(pdesk);
2999 WARN("NtUserSwitchDesktop called for active desktop\n");
3000 Ret = TRUE;
3001 goto Exit;
3002 }
3003
3004 /*
3005 * Don't allow applications switch the desktop if it's locked,
3006 * unless the caller is the logon application itself.
3007 */
3008 if ((pdesk->rpwinstaParent->Flags & WSS_LOCKED) &&
3010 {
3011 ObDereferenceObject(pdesk);
3012 ERR("Switching desktop 0x%p denied because the window station is locked!\n", hdesk);
3013 goto Exit;
3014 }
3015
3016 if (pdesk->rpwinstaParent != InputWindowStation)
3017 {
3018 ObDereferenceObject(pdesk);
3019 ERR("Switching desktop 0x%p denied because desktop doesn't belong to the interactive winsta!\n", hdesk);
3020 goto Exit;
3021 }
3022
3023 /* FIXME: Fail if the process is associated with a secured
3024 desktop such as Winlogon or Screen-Saver */
3025 /* FIXME: Connect to input device */
3026
3027 TRACE("Switching from desktop 0x%p to 0x%p\n", gpdeskInputDesktop, pdesk);
3028
3029 bRedrawDesktop = FALSE;
3030
3031 /* The first time SwitchDesktop is called, gpdeskInputDesktop is NULL */
3032 if (gpdeskInputDesktop != NULL)
3033 {
3035 bRedrawDesktop = TRUE;
3036
3037 /* Hide the previous desktop window */
3039 }
3040
3041 /* Set the active desktop in the desktop's window station */
3043
3044 /* Set the global state */
3045 gpdeskInputDesktop = pdesk;
3046
3047 /* Show the new desktop window */
3049
3050 // TODO: Request hard-error popups to be respawned to the new desktop.
3051
3052 /* Notify waiters that a desktop has been switched on the
3053 * interactive window station: pulse the legacy (NT 3.5+)
3054 * event and send the desktop-switch notification (Vista+) */
3056#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
3057 IntNotifyWinEvent(EVENT_SYSTEM_DESKTOPSWITCH, NULL, OBJID_WINDOW, CHILDID_SELF, 0);
3058#endif
3059
3060 TRACE("SwitchDesktop gpdeskInputDesktop 0x%p\n", gpdeskInputDesktop);
3061 ObDereferenceObject(pdesk);
3062
3063 Ret = TRUE;
3064
3065Exit:
3066 TRACE("Leave NtUserSwitchDesktop, ret=%i\n", Ret);
3067 UserLeave();
3068 return Ret;
3069}
#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:1651
NTSTATUS FASTCALL co_IntShowDesktop(PDESKTOP Desktop, ULONG Width, ULONG Height, BOOL bRedraw)
Definition: desktop.c:1633
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 1667 of file desktop.c.

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

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

Referenced by DxEngGetDesktopDC().

◆ UserGetDesktopWindow()

◆ UserGetMessageWindow()

PWND FASTCALL UserGetMessageWindow ( VOID  )

Definition at line 1432 of file desktop.c.

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

◆ UserInitializeDesktop()

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

Definition at line 2278 of file desktop.c.

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

Referenced by IntDesktopObjectParse().

◆ UserMessageWindowProc()

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

Definition at line 1541 of file desktop.c.

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

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

◆ UserOpenInputDesktop()

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

Definition at line 2653 of file desktop.c.

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

1616{
1617 PWND Window = NULL;
1618 PREGION Rgn;
1619
1621 Rgn = IntSysCreateRectpRgnIndirect(&Window->rcWindow);
1622
1624 Rgn,
1627
1628 REGION_Delete(Rgn);
1629}
#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