ReactOS 0.4.15-dev-7788-g1ad9096
desktop.c File Reference
#include <win32k.h>
#include <reactos/buildno.h>
Include dependency graph for desktop.c:

Go to the source code of this file.

Functions

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

Variables

DWORD gdwDesktopSectionSize = 512
 
DWORD gdwNOIOSectionSize = 128
 
PDESKTOP gpdeskInputDesktop = NULL
 
HDC ScreenDeviceContext = NULL
 
PTHREADINFO gptiDesktopThread = NULL
 
HCURSOR gDesktopCursor = NULL
 
PKEVENT gpDesktopThreadStartedEvent = NULL
 

Function Documentation

◆ co_GetDesktopWindow()

PWND FASTCALL co_GetDesktopWindow ( PWND  pWnd)

Definition at line 1366 of file desktop.c.

1367{
1368 if (pWnd->head.rpdesk &&
1369 pWnd->head.rpdesk->pDeskInfo)
1370 return pWnd->head.rpdesk->pDeskInfo->spwnd;
1371 return NULL;
1372}
#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 1692 of file desktop.c.

1693{
1695 HWND* HwndList;
1696
1697 if (!gpsi->uiShellMsg)
1698 {
1699 gpsi->uiShellMsg = IntAddAtom(L"SHELLHOOK");
1700
1701 TRACE("MsgType = %x\n", gpsi->uiShellMsg);
1702 if (!gpsi->uiShellMsg)
1703 ERR("LastError: %x\n", EngGetLastError());
1704 }
1705
1706 if (!Desktop)
1707 {
1708 TRACE("IntShellHookNotify: No desktop!\n");
1709 return;
1710 }
1711
1712 // Allow other devices have a shot at foreground.
1713 if (Message == HSHELL_APPCOMMAND) ptiLastInput = NULL;
1714
1715 // FIXME: System Tray Support.
1716
1718 if (HwndList)
1719 {
1720 HWND* cursor = HwndList;
1721
1722 for (; *cursor; cursor++)
1723 {
1724 TRACE("Sending notify\n");
1727 Message,
1728 (Message == HSHELL_LANGUAGE ? lParam : (LPARAM)wParam) );
1729/* co_IntPostOrSendMessage(*cursor,
1730 gpsi->uiShellMsg,
1731 Message,
1732 (Message == HSHELL_LANGUAGE ? lParam : (LPARAM)wParam) );*/
1733 }
1734
1736 }
1737
1738 if (ISITHOOKED(WH_SHELL))
1739 {
1741 }
1742}
#define ERR(fmt,...)
Definition: debug.h:110
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
PSERVERINFO gpsi
Definition: imm.c:18
static const WCHAR Message[]
Definition: register.c:74
PTHREADINFO ptiLastInput
Definition: focus.c:18
#define ISITHOOKED(HookId)
Definition: hook.h:6
const char cursor[]
Definition: icontest.c:13
#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 L(x)
Definition: ntvdm.h:50
#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:1262
static HWND *FASTCALL UserBuildShellHookHwndList(PDESKTOP Desktop)
Definition: desktop.c:1651
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1345
#define USERTAG_WINDOWLIST
Definition: tags.h:298
ENGAPI ULONG APIENTRY EngGetLastError(VOID)
Definition: error.c:9
LONG_PTR LPARAM
Definition: windef.h:208
#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 1617 of file desktop.c.

1618{
1619 PWND pwnd = Desktop->pDeskInfo->spwnd;
1621 ASSERT(pwnd);
1622
1623 if (!bRedraw)
1625
1627
1628 if (bRedraw)
1630
1631 return STATUS_SUCCESS;
1632}
GLbitfield flags
Definition: glext.h:7161
#define ASSERT(a)
Definition: mode.c:44
unsigned int UINT
Definition: ndis.h:50
BOOLEAN FASTCALL co_WinPosSetWindowPos(PWND Window, HWND WndInsertAfter, INT x, INT y, INT cx, INT cy, UINT flags)
Definition: winpos.c:1786
#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:888
_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:1242
#define SWP_NOREDRAW
Definition: winuser.h:1246
#define RDW_UPDATENOW
Definition: winuser.h:1220
#define RDW_ALLCHILDREN
Definition: winuser.h:1221
#define SWP_SHOWWINDOW
Definition: winuser.h:1248
#define SWP_NOZORDER
Definition: winuser.h:1247
#define RDW_INVALIDATE
Definition: winuser.h:1214

Referenced by co_IntInitializeDesktopGraphics(), and NtUserSwitchDesktop().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserDesktop  )

◆ DesktopThreadMain()

VOID NTAPI DesktopThreadMain ( VOID  )

Definition at line 1546 of file desktop.c.

1547{
1548 BOOL Ret;
1549 MSG Msg;
1550
1552
1554
1555 /* Register system classes. This thread does not belong to any desktop so the
1556 classes will be allocated from the shared heap */
1558
1560
1561 while (TRUE)
1562 {
1563 Ret = co_IntGetPeekMessage(&Msg, 0, 0, 0, PM_REMOVE, TRUE);
1564 if (Ret)
1565 {
1567 }
1568 }
1569
1570 UserLeave();
1571}
struct @1627 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:251
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:242
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
BOOL FASTCALL UserRegisterSystemClasses(VOID)
Definition: class.c:2317
PTHREADINFO gptiDesktopThread
Definition: desktop.c:37
PKEVENT gpDesktopThreadStartedEvent
Definition: desktop.c:39
LRESULT FASTCALL IntDispatchMessage(PMSG pMsg)
Definition: message.c:840
BOOL APIENTRY co_IntGetPeekMessage(PMSG pMsg, HWND hWnd, UINT MsgFilterMin, UINT MsgFilterMax, UINT RemoveMsg, BOOL bGMSG)
Definition: message.c:1176
#define PM_REMOVE
Definition: winuser.h:1196
#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 1439 of file desktop.c.

1440{
1441 PAINTSTRUCT Ps;
1442 ULONG Value;
1443 //ERR("DesktopWindowProc\n");
1444
1445 *lResult = 0;
1446
1447 switch (Msg)
1448 {
1449 case WM_NCCREATE:
1450 if (!Wnd->fnid)
1451 {
1452 Wnd->fnid = FNID_DESKTOP;
1453 }
1454 *lResult = (LRESULT)TRUE;
1455 return TRUE;
1456
1457 case WM_CREATE:
1459 // Save Process ID
1462 // Save Thread ID
1464 case WM_CLOSE:
1465 return TRUE;
1466
1467 case WM_DISPLAYCHANGE:
1469 return TRUE;
1470
1471 case WM_ERASEBKGND:
1473 *lResult = 1;
1474 return TRUE;
1475
1476 case WM_PAINT:
1477 {
1478 if (IntBeginPaint(Wnd, &Ps))
1479 {
1480 IntEndPaint(Wnd, &Ps);
1481 }
1482 return TRUE;
1483 }
1484 case WM_SYSCOLORCHANGE:
1486 return TRUE;
1487
1488 case WM_SETCURSOR:
1489 {
1490 PCURICON_OBJECT pcurOld, pcurNew;
1492 if (!pcurNew)
1493 {
1494 return TRUE;
1495 }
1496
1497 pcurNew->CURSORF_flags |= CURSORF_CURRENT;
1498 pcurOld = UserSetCursor(pcurNew, FALSE);
1499 if (pcurOld)
1500 {
1501 pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
1502 UserDereferenceObject(pcurOld);
1503 }
1504 return TRUE;
1505 }
1506
1508 {
1509 PWINDOWPOS pWindowPos = (PWINDOWPOS)lParam;
1510 if ((pWindowPos->flags & SWP_SHOWWINDOW) != 0)
1511 {
1513 IntSetThreadDesktop(hdesk, FALSE);
1514 }
1515 break;
1516 }
1517 default:
1518 TRACE("DWP calling IDWP Msg %d\n",Msg);
1519 //*lResult = IntDefWindowProc(Wnd, Msg, wParam, lParam, FALSE);
1520 }
1521 return TRUE; /* We are done. Do not do any callbacks to user mode */
1522}
#define HandleToULong(h)
Definition: basetsd.h:95
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:92
PCURICON_OBJECT FASTCALL UserSetCursor(PCURICON_OBJECT NewCursor, BOOL ForceChange)
Definition: msgqueue.c:93
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
#define LRESULT
Definition: ole.h:14
#define LOWORD(l)
Definition: pedump.c:82
ULONG CURSORF_flags
Definition: cursoricon.h:16
UINT flags
Definition: winuser.h:3594
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:1435
BOOL FASTCALL IntEndPaint(PWND Wnd, PPAINTSTRUCT Ps)
Definition: painting.c:1532
_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:38
HDESK UserOpenInputDesktop(DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess)
Definition: desktop.c:2617
BOOL FASTCALL IntPaintDesktop(HDC hDC)
Definition: desktop.c:1835
BOOL IntSetThreadDesktop(IN HDESK hDesktop, IN BOOL FreeOnFailure)
Definition: desktop.c:3260
#define DT_GWL_THREADID
Definition: desktop.h:56
#define DT_GWL_PROCESSID
Definition: desktop.h:55
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:644
LONG FASTCALL co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
Definition: window.c:4020
#define WM_PAINT
Definition: winuser.h:1620
#define WM_ERASEBKGND
Definition: winuser.h:1625
#define WM_CLOSE
Definition: winuser.h:1621
#define WM_WINDOWPOSCHANGING
Definition: winuser.h:1661
#define WM_CREATE
Definition: winuser.h:1608
#define RDW_ERASE
Definition: winuser.h:1211
#define WM_SYSCOLORCHANGE
Definition: winuser.h:1626
#define WM_NCCREATE
Definition: winuser.h:1683
#define WM_SETCURSOR
Definition: winuser.h:1636
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 283 of file desktop.c.

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

Referenced by IntPaintDesktop().

◆ InitDesktopImpl()

NTSTATUS NTAPI InitDesktopImpl ( VOID  )

Definition at line 252 of file desktop.c.

253{
254 GENERIC_MAPPING IntDesktopMapping = { DESKTOP_READ,
258
259 /* Set Desktop Object Attributes */
261 ExDesktopObjectType->TypeInfo.GenericMapping = IntDesktopMapping;
263
264 /* Allocate memory for the event structure */
266 sizeof(KEVENT),
269 {
270 ERR("Failed to allocate event!\n");
271 return STATUS_NO_MEMORY;
272 }
273
274 /* Initialize the kernel event */
277 FALSE);
278
279 return STATUS_SUCCESS;
280}
#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
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:365
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
POBJECT_TYPE ExDesktopObjectType
Definition: win32k.c:22
struct _DESKTOP DESKTOP
#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 2352 of file desktop.c.

2360{
2362 PDESKTOP pdesk = NULL;
2363 HDESK hDesk;
2365 UNICODE_STRING ClassName;
2366 LARGE_STRING WindowName;
2367 BOOL NoHooks = FALSE;
2368 PWND pWnd = NULL;
2369 CREATESTRUCTW Cs;
2370 PTHREADINFO ptiCurrent;
2371 PCLS pcls;
2372
2373 TRACE("Enter IntCreateDesktop\n");
2374
2376
2377 ASSERT(phDesktop);
2378 *phDesktop = NULL;
2379
2380 ptiCurrent = PsGetCurrentThreadWin32Thread();
2381 ASSERT(ptiCurrent);
2383
2384 /* Turn off hooks when calling any CreateWindowEx from inside win32k */
2385 NoHooks = (ptiCurrent->TIF_flags & TIF_DISABLEHOOKS);
2386 ptiCurrent->TIF_flags |= TIF_DISABLEHOOKS;
2387 ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
2388
2389 /*
2390 * Try to open already existing desktop
2391 */
2394 AccessMode,
2395 NULL,
2396 dwDesiredAccess,
2397 (PVOID)&Context,
2398 (PHANDLE)&hDesk);
2399 if (!NT_SUCCESS(Status))
2400 {
2401 ERR("ObOpenObjectByName failed to open/create desktop\n");
2402 goto Quit;
2403 }
2404
2405 /* In case the object was not created (eg if it existed), return now */
2406 if (Context == FALSE)
2407 {
2408 TRACE("IntCreateDesktop opened desktop '%wZ'\n", ObjectAttributes->ObjectName);
2410 goto Quit;
2411 }
2412
2413 /* Reference the desktop */
2415 0,
2417 KernelMode,
2418 (PVOID*)&pdesk,
2419 NULL);
2420 if (!NT_SUCCESS(Status))
2421 {
2422 ERR("Failed to reference desktop object\n");
2423 goto Quit;
2424 }
2425
2426 /* Get the desktop window class. The thread desktop does not belong to any desktop
2427 * so the classes created there (including the desktop class) are allocated in the shared heap
2428 * It would cause problems if we used a class that belongs to the caller
2429 */
2430 ClassName.Buffer = WC_DESKTOP;
2431 ClassName.Length = 0;
2432 pcls = IntGetAndReferenceClass(&ClassName, 0, TRUE);
2433 if (pcls == NULL)
2434 {
2435 ASSERT(FALSE);
2437 goto Quit;
2438 }
2439
2440 RtlZeroMemory(&WindowName, sizeof(WindowName));
2441 RtlZeroMemory(&Cs, sizeof(Cs));
2447 Cs.hInstance = hModClient; // hModuleWin; // Server side winproc!
2448 Cs.lpszName = (LPCWSTR) &WindowName;
2449 Cs.lpszClass = (LPCWSTR) &ClassName;
2450
2451 /* Use IntCreateWindow instead of co_UserCreateWindowEx because the later expects a thread with a desktop */
2452 pWnd = IntCreateWindow(&Cs, &WindowName, pcls, NULL, NULL, NULL, pdesk, WINVER);
2453 if (pWnd == NULL)
2454 {
2455 ERR("Failed to create desktop window for the new desktop\n");
2457 goto Quit;
2458 }
2459
2461 pdesk->DesktopWindow = UserHMGetHandle(pWnd);
2462 pdesk->pDeskInfo->spwnd = pWnd;
2463 pWnd->fnid = FNID_DESKTOP;
2464
2465 ClassName.Buffer = MAKEINTATOM(gpsi->atomSysClass[ICLS_HWNDMESSAGE]);
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));
2477 Cs.cx = Cs.cy = 100;
2479 Cs.hInstance = hModClient; // hModuleWin; // Server side winproc!
2480 Cs.lpszName = (LPCWSTR)&WindowName;
2481 Cs.lpszClass = (LPCWSTR)&ClassName;
2482 pWnd = IntCreateWindow(&Cs, &WindowName, pcls, NULL, NULL, NULL, pdesk, WINVER);
2483 if (pWnd == NULL)
2484 {
2485 ERR("Failed to create message window for the new desktop\n");
2487 goto Quit;
2488 }
2489
2490 pdesk->spwndMessage = pWnd;
2491 pWnd->fnid = FNID_MESSAGEWND;
2492
2493 /* Now...
2494 if !(WinStaObject->Flags & WSF_NOIO) is (not set) for desktop input output mode (see wiki)
2495 Create Tooltip. Saved in DesktopObject->spwndTooltip.
2496 Tooltip dwExStyle: WS_EX_TOOLWINDOW|WS_EX_TOPMOST
2497 hWndParent are spwndMessage. Use hModuleWin for server side winproc!
2498 The rest is same as message window.
2499 http://msdn.microsoft.com/en-us/library/bb760250(VS.85).aspx
2500 */
2502
2503Quit:
2504 if (pdesk != NULL)
2505 {
2506 ObDereferenceObject(pdesk);
2507 }
2508 if (!NT_SUCCESS(Status) && hDesk != NULL)
2509 {
2510 ObCloseHandle(hDesk, AccessMode);
2511 hDesk = NULL;
2512 }
2513 if (!NoHooks)
2514 {
2515 ptiCurrent->TIF_flags &= ~TIF_DISABLEHOOKS;
2516 ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
2517 }
2518
2519 TRACE("Leave IntCreateDesktop, Status 0x%08lx\n", Status);
2520
2521 if (NT_SUCCESS(Status))
2522 *phDesktop = hDesk;
2523 else
2525 return Status;
2526}
unsigned char BOOLEAN
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:34
ULONG NTAPI PsGetCurrentProcessSessionId(VOID)
Definition: process.c:1133
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
HINSTANCE hModClient
Definition: ntuser.c:25
BOOL FASTCALL UserIsEnteredExclusive(VOID)
Definition: ntuser.c:224
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2532
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define WS_POPUP
Definition: pedump.c:616
#define WS_CLIPCHILDREN
Definition: pedump.c:619
Definition: ntuser.h:566
struct _WND * spwnd
Definition: ntuser.h:137
PWND spwndMessage
Definition: desktop.h:20
HWND DesktopWindow
Definition: desktop.h:40
PDESKTOPINFO pDeskInfo
Definition: desktop.h:8
DWORD dwSessionId
Definition: desktop.h:6
struct _CLIENTINFO * pClientInfo
Definition: win32.h:94
FLONG TIF_flags
Definition: win32.h:95
LPCWSTR lpszClass
Definition: winuser.h:2965
LPCWSTR lpszName
Definition: winuser.h:2964
HINSTANCE hInstance
Definition: winuser.h:2956
ATOM atomSysClass[ICLS_NOTUSED+1]
Definition: ntuser.h:1060
#define WINVER
Definition: targetver.h:11
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define WC_DESKTOP
Definition: undocuser.h:10
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
PCLS IntGetAndReferenceClass(PUNICODE_STRING ClassName, HINSTANCE hInstance, BOOL bDesktopThread)
Definition: class.c:1448
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:213
PWND FASTCALL IntCreateWindow(CREATESTRUCTW *Cs, PLARGE_STRING WindowName, PCLS Class, PWND ParentWindow, PWND OwnerWindow, PVOID acbiBuffer, PDESKTOP pdeskCreated, DWORD dwVer)
Definition: window.c:1801
#define MAKEINTATOM(i)
Definition: winbase.h:1463
#define SM_CYVIRTUALSCREEN
Definition: winuser.h:1039
#define SM_CXVIRTUALSCREEN
Definition: winuser.h:1038
#define SM_XVIRTUALSCREEN
Definition: winuser.h:1036
#define SM_YVIRTUALSCREEN
Definition: winuser.h:1037
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
#define ObDereferenceObject
Definition: obfuncs.h:203
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by IntResolveDesktop(), and NtUserCreateDesktop().

◆ IntDeRegisterShellHookWindow()

BOOL IntDeRegisterShellHookWindow ( HWND  hWnd)

Definition at line 1784 of file desktop.c.

1785{
1787 PDESKTOP Desktop = pti->rpdesk;
1788 PLIST_ENTRY ListEntry;
1789 PSHELL_HOOK_WINDOW Current;
1790
1791 // FIXME: This probably shouldn't happen, but it does
1792 if (Desktop == NULL)
1793 {
1795 if (Desktop == NULL)
1796 return FALSE;
1797 }
1798
1799 ListEntry = Desktop->ShellHookWindows.Flink;
1800 while (ListEntry != &Desktop->ShellHookWindows)
1801 {
1802 Current = CONTAINING_RECORD(ListEntry, SHELL_HOOK_WINDOW, ListEntry);
1803 ListEntry = ListEntry->Flink;
1804 if (Current->hWnd == hWnd)
1805 {
1806 RemoveEntryList(&Current->ListEntry);
1807 ExFreePoolWithTag(Current, TAG_WINSTA);
1808 return TRUE;
1809 }
1810 }
1811
1812 return FALSE;
1813}
HWND hWnd
Definition: settings.c:17
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY ListEntry
Definition: desktop.h:67
struct _DESKTOP * rpdesk
Definition: win32.h:92
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define TAG_WINSTA
Definition: tags.h:11

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

◆ IntDesktopObjectClose()

NTSTATUS NTAPI IntDesktopObjectClose ( _In_ PVOID  Parameters)

Definition at line 227 of file desktop.c.

229{
230 NTSTATUS Ret;
232 PPROCESSINFO ppi = PsGetProcessWin32Process(CloseParameters->Process);
233 if (ppi == NULL)
234 {
235 /* This happens when the process leaks desktop handles.
236 * At this point the PPROCESSINFO is already destroyed */
237 return STATUS_SUCCESS;
238 }
239
241 Ret = IntUnmapDesktopView((PDESKTOP)CloseParameters->Object);
242 UserLeave();
243 return Ret;
244}
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:3142

Referenced by DriverEntry().

◆ IntDesktopObjectDelete()

NTSTATUS NTAPI IntDesktopObjectDelete ( _In_ PVOID  Parameters)

Definition at line 155 of file desktop.c.

157{
159 PDESKTOP pdesk = (PDESKTOP)DeleteParameters->Object;
160
161 TRACE("Deleting desktop object 0x%p\n", pdesk);
162
163 if (pdesk->pDeskInfo &&
164 pdesk->pDeskInfo->spwnd)
165 {
166 ASSERT(pdesk->pDeskInfo->spwnd->spwndChild == NULL);
168 }
169
170 if (pdesk->spwndMessage)
172
173 /* Remove the desktop from the window station's list of associated desktops */
174 RemoveEntryList(&pdesk->ListEntry);
175
176 /* Free the heap */
177 IntFreeDesktopHeap(pdesk);
178
180
181 return STATUS_SUCCESS;
182}
LIST_ENTRY ListEntry
Definition: desktop.h:9
struct _WINSTATION_OBJECT * rpwinstaParent
Definition: desktop.h:11
BOOLEAN co_UserDestroyWindow(PVOID Object)
Definition: window.c:2853
static VOID IntFreeDesktopHeap(IN PDESKTOP pdesk)
struct _DESKTOP * PDESKTOP

Referenced by DriverEntry().

◆ IntDesktopObjectOpen()

NTSTATUS NTAPI IntDesktopObjectOpen ( _In_ PVOID  Parameters)

Definition at line 210 of file desktop.c.

212{
213 NTSTATUS Ret;
215 PPROCESSINFO ppi = PsGetProcessWin32Process(OpenParameters->Process);
216 if (ppi == NULL)
217 return STATUS_SUCCESS;
218
220 Ret = IntMapDesktopView((PDESKTOP)OpenParameters->Object);
221 UserLeave();
222 return Ret;
223}
static NTSTATUS IntMapDesktopView(IN PDESKTOP pdesk)
Definition: desktop.c:3186

Referenced by DriverEntry().

◆ IntDesktopObjectParse()

NTSTATUS APIENTRY IntDesktopObjectParse ( IN PVOID  ParseObject,
IN PVOID  ObjectType,
IN OUT PACCESS_STATE  AccessState,
IN KPROCESSOR_MODE  AccessMode,
IN ULONG  Attributes,
IN OUT PUNICODE_STRING  CompleteName,
IN OUT PUNICODE_STRING  RemainingName,
IN OUT PVOID Context  OPTIONAL,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos  OPTIONAL,
OUT PVOID Object 
)

Definition at line 45 of file desktop.c.

55{
59 PLIST_ENTRY NextEntry, ListHead;
60 PWINSTATION_OBJECT WinStaObject = (PWINSTATION_OBJECT)ParseObject;
61 UNICODE_STRING DesktopName;
62 PBOOLEAN pContext = (PBOOLEAN) Context;
63
64 if (pContext)
65 *pContext = FALSE;
66
67 /* Set the list pointers and loop the window station */
68 ListHead = &WinStaObject->DesktopListHead;
69 NextEntry = ListHead->Flink;
70 while (NextEntry != ListHead)
71 {
72 /* Get the current desktop */
73 Desktop = CONTAINING_RECORD(NextEntry, DESKTOP, ListEntry);
74
75 /* Get the desktop name */
76 ASSERT(Desktop->pDeskInfo != NULL);
77 RtlInitUnicodeString(&DesktopName, Desktop->pDeskInfo->szDesktopName);
78
79 /* Compare the name */
81 &DesktopName,
83 {
84 /* We found a match. Did this come from a create? */
85 if (Context)
86 {
87 /* Unless OPEN_IF was given, fail with an error */
88 if (!(Attributes & OBJ_OPENIF))
89 {
90 /* Name collision */
92 }
93 else
94 {
95 /* Otherwise, return with a warning only */
97 }
98 }
99 else
100 {
101 /* This was a real open, so this is OK */
103 }
104
105 /* Reference the desktop and return it */
107 *Object = Desktop;
108 return Status;
109 }
110
111 /* Go to the next desktop */
112 NextEntry = NextEntry->Flink;
113 }
114
115 /* If we got here but this isn't a create, just fail */
117
118 /* Create the desktop object */
124 NULL,
125 sizeof(DESKTOP),
126 0,
127 0,
128 (PVOID*)&Desktop);
129 if (!NT_SUCCESS(Status)) return Status;
130
131 /* Assign security to the desktop we have created */
133 if (!NT_SUCCESS(Status))
134 {
136 return Status;
137 }
138
139 /* Initialize the desktop */
141 if (!NT_SUCCESS(Status))
142 {
144 return Status;
145 }
146
147 /* Set the desktop object and return success */
148 *Object = Desktop;
149 *pContext = TRUE;
150 return STATUS_SUCCESS;
151}
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:802
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:1039
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:2260
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 186 of file desktop.c.

188{
191
192 if (pti == NULL)
193 {
194 /* This happens when we leak desktop handles */
195 return STATUS_SUCCESS;
196 }
197
198 /* Do not allow the current desktop or the initial desktop to be closed */
199 if (OkToCloseParameters->Handle == pti->ppi->hdeskStartup ||
200 OkToCloseParameters->Handle == pti->hdesk)
201 {
203 }
204
205 return STATUS_SUCCESS;
206}
HDESK hdeskStartup
Definition: win32.h:263
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 1816 of file desktop.c.

1817{
1818 /* FIXME: Disable until unmapping works in mm */
1819#if 0
1820 if (Desktop->pheapDesktop != NULL)
1821 {
1822 MmUnmapViewInSessionSpace(Desktop->pheapDesktop);
1823 Desktop->pheapDesktop = NULL;
1824 }
1825
1826 if (Desktop->hsectionDesktop != NULL)
1827 {
1828 ObDereferenceObject(Desktop->hsectionDesktop);
1829 Desktop->hsectionDesktop = NULL;
1830 }
1831#endif
1832}
NTSTATUS NTAPI MmUnmapViewInSessionSpace(IN PVOID MappedBase)
Definition: section.c:3089

◆ IntFreeDesktopHeap() [2/2]

static VOID IntFreeDesktopHeap ( IN PDESKTOP  pdesk)
static

Referenced by IntDesktopObjectDelete().

◆ IntGetActiveDesktop()

◆ IntGetCurrentThreadDesktopWindow()

HWND FASTCALL IntGetCurrentThreadDesktopWindow ( VOID  )

Definition at line 1424 of file desktop.c.

1425{
1427 PDESKTOP pdo = pti->rpdesk;
1428 if (NULL == pdo)
1429 {
1430 ERR("Thread doesn't have a desktop\n");
1431 return NULL;
1432 }
1433 return pdo->DesktopWindow;
1434}

Referenced by NtUserFindWindowEx().

◆ IntGetDesktopObjectHandle()

HDESK FASTCALL IntGetDesktopObjectHandle ( PDESKTOP  DesktopObject)

Definition at line 1271 of file desktop.c.

1272{
1274 HDESK hDesk;
1275
1276 ASSERT(DesktopObject);
1277
1279 DesktopObject,
1281 NULL,
1282 (PHANDLE)&hDesk))
1283 {
1284 Status = ObOpenObjectByPointer(DesktopObject,
1285 0,
1286 NULL,
1287 0,
1289 UserMode,
1290 (PHANDLE)&hDesk);
1291 if (!NT_SUCCESS(Status))
1292 {
1293 /* Unable to create a handle */
1294 ERR("Unable to create a desktop handle\n");
1295 return NULL;
1296 }
1297 }
1298 else
1299 {
1300 TRACE("Got handle: 0x%p\n", hDesk);
1301 }
1302
1303 return hDesk;
1304}
#define UserMode
Definition: asm.h:35
BOOLEAN NTAPI ObFindHandleForObject(IN PEPROCESS Process, IN PVOID Object, IN POBJECT_TYPE ObjectType, IN POBJECT_HANDLE_INFORMATION HandleInformation, OUT PHANDLE Handle)
Definition: obhandle.c:2856
NTSTATUS NTAPI ObOpenObjectByPointer(IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle)
Definition: obhandle.c:2742
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by NtUserGetThreadDesktop(), and NtUserSetInformationThread().

◆ IntGetDesktopWindow()

◆ IntGetFocusMessageQueue()

PUSER_MESSAGE_QUEUE FASTCALL IntGetFocusMessageQueue ( VOID  )

◆ IntGetMessageWindow()

HWND FASTCALL IntGetMessageWindow ( VOID  )

Definition at line 1399 of file desktop.c.

1400{
1402
1403 if (!pdo)
1404 {
1405 TRACE("No active desktop\n");
1406 return NULL;
1407 }
1408 return UserHMGetHandle(pdo->spwndMessage);
1409}

Referenced by NtUserFindWindowEx(), and NtUserSetParent().

◆ IntGetThreadDesktopWindow()

PWND FASTCALL IntGetThreadDesktopWindow ( PTHREADINFO  pti)

Definition at line 1359 of file desktop.c.

1360{
1361 if (!pti) pti = PsGetCurrentThreadWin32Thread();
1362 if (pti->pDeskInfo) return pti->pDeskInfo->spwnd;
1363 return NULL;
1364}
struct _DESKTOPINFO * pDeskInfo
Definition: win32.h:93

Referenced by ActivateOtherWindowMin().

◆ IntHideDesktop()

NTSTATUS FASTCALL IntHideDesktop ( PDESKTOP  Desktop)

Definition at line 1635 of file desktop.c.

1636{
1637 PWND DesktopWnd;
1638
1639 DesktopWnd = IntGetWindowObject(Desktop->DesktopWindow);
1640 if (! DesktopWnd)
1641 {
1643 }
1644 DesktopWnd->style &= ~WS_VISIBLE;
1645
1646 return STATUS_SUCCESS;
1647}
DWORD style
Definition: ntuser.h:706
PWND FASTCALL IntGetWindowObject(HWND hWnd)
Definition: window.c:73
#define ERROR_INVALID_WINDOW_HANDLE
Definition: winerror.h:881

Referenced by IntEndDesktopGraphics(), and NtUserSwitchDesktop().

◆ IntMapDesktopView()

static NTSTATUS IntMapDesktopView ( IN PDESKTOP  pdesk)
static

Definition at line 3186 of file desktop.c.

3187{
3188 PPROCESSINFO ppi;
3189 PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
3190 PVOID UserBase = NULL;
3191 SIZE_T ViewSize = 0;
3194
3195 TRACE("IntMapDesktopView called for desktop object 0x%p\n", pdesk);
3196
3198
3199 /*
3200 * Find out if another thread already mapped the desktop heap.
3201 * Start the search at the next mapping: skip the first entry
3202 * as it must be the global user heap mapping.
3203 */
3204 PrevLink = &ppi->HeapMappings.Next;
3205 HeapMapping = *PrevLink;
3206 while (HeapMapping != NULL)
3207 {
3208 if (HeapMapping->KernelMapping == (PVOID)pdesk->pheapDesktop)
3209 {
3210 HeapMapping->Count++;
3211 return STATUS_SUCCESS;
3212 }
3213
3214 PrevLink = &HeapMapping->Next;
3215 HeapMapping = HeapMapping->Next;
3216 }
3217
3218 /* We're the first, map the heap */
3219 Offset.QuadPart = 0;
3220 Status = MmMapViewOfSection(pdesk->hsectionDesktop,
3222 &UserBase,
3223 0,
3224 0,
3225 &Offset,
3226 &ViewSize,
3227 ViewUnmap,
3229 PAGE_EXECUTE_READ); /* Would prefer PAGE_READONLY, but thanks to RTL heaps... */
3230 if (!NT_SUCCESS(Status))
3231 {
3232 ERR("Failed to map desktop\n");
3233 return Status;
3234 }
3235
3236 TRACE("ppi 0x%p mapped heap of desktop 0x%p\n", ppi, pdesk);
3237
3238 /* Add the mapping */
3239 HeapMapping = UserHeapAlloc(sizeof(*HeapMapping));
3240 if (HeapMapping == NULL)
3241 {
3243 ERR("UserHeapAlloc() failed!\n");
3244 return STATUS_NO_MEMORY;
3245 }
3246
3247 HeapMapping->Next = NULL;
3248 HeapMapping->KernelMapping = (PVOID)pdesk->pheapDesktop;
3249 HeapMapping->UserMapping = UserBase;
3250 HeapMapping->Limit = ViewSize;
3251 HeapMapping->Count = 1;
3252 *PrevLink = HeapMapping;
3253
3254 ObReferenceObject(pdesk);
3255
3256 return STATUS_SUCCESS;
3257}
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:3117
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
#define SEC_NO_CHANGE
Definition: mmtypes.h:95
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
@ ViewUnmap
Definition: nt_native.h:1279
_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, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3996
W32HEAP_USER_MAPPING HeapMappings
Definition: win32.h:290
struct _W32HEAP_USER_MAPPING * Next
Definition: win32.h:198
ULONG_PTR Limit
Definition: win32.h:201
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 1835 of file desktop.c.

1836{
1837 static WCHAR s_wszSafeMode[] = L"Safe Mode"; // FIXME: Localize!
1838
1839 RECTL Rect;
1840 HBRUSH DesktopBrush, PreviousBrush;
1841 HWND hWndDesktop;
1842 BOOL doPatBlt = TRUE;
1843 PWND WndDesktop;
1844 BOOLEAN InSafeMode;
1845
1846 if (GdiGetClipBox(hDC, &Rect) == ERROR)
1847 return FALSE;
1848
1849 hWndDesktop = IntGetDesktopWindow(); // rpdesk->DesktopWindow;
1850
1851 WndDesktop = UserGetWindowObject(hWndDesktop); // rpdesk->pDeskInfo->spwnd;
1852 if (!WndDesktop)
1853 return FALSE;
1854
1855 /* Retrieve the current SafeMode state */
1856 InSafeMode = (UserGetSystemMetrics(SM_CLEANBOOT) != 0); // gpsi->aiSysMet[SM_CLEANBOOT];
1857
1858 if (!InSafeMode)
1859 {
1860 DesktopBrush = (HBRUSH)WndDesktop->pcls->hbrBackground;
1861
1862 /*
1863 * Paint desktop background
1864 */
1866 {
1867 SIZE sz;
1868 int x, y;
1869 int scaledWidth, scaledHeight;
1870 int wallpaperX, wallpaperY, wallpaperWidth, wallpaperHeight;
1871 HDC hWallpaperDC;
1872
1873 sz.cx = WndDesktop->rcWindow.right - WndDesktop->rcWindow.left;
1874 sz.cy = WndDesktop->rcWindow.bottom - WndDesktop->rcWindow.top;
1875
1876 if (gspv.WallpaperMode == wmFit ||
1878 {
1879 int scaleNum, scaleDen;
1880
1881 // Precision improvement over ((sz.cx / gspv.cxWallpaper) > (sz.cy / gspv.cyWallpaper))
1882 if ((sz.cx * gspv.cyWallpaper) > (sz.cy * gspv.cxWallpaper))
1883 {
1884 if (gspv.WallpaperMode == wmFit)
1885 {
1886 scaleNum = sz.cy;
1887 scaleDen = gspv.cyWallpaper;
1888 }
1889 else
1890 {
1891 scaleNum = sz.cx;
1892 scaleDen = gspv.cxWallpaper;
1893 }
1894 }
1895 else
1896 {
1897 if (gspv.WallpaperMode == wmFit)
1898 {
1899 scaleNum = sz.cx;
1900 scaleDen = gspv.cxWallpaper;
1901 }
1902 else
1903 {
1904 scaleNum = sz.cy;
1905 scaleDen = gspv.cyWallpaper;
1906 }
1907 }
1908
1909 scaledWidth = EngMulDiv(gspv.cxWallpaper, scaleNum, scaleDen);
1910 scaledHeight = EngMulDiv(gspv.cyWallpaper, scaleNum, scaleDen);
1911
1912 if (gspv.WallpaperMode == wmFill)
1913 {
1914 wallpaperX = (((scaledWidth - sz.cx) * gspv.cxWallpaper) / (2 * scaledWidth));
1915 wallpaperY = (((scaledHeight - sz.cy) * gspv.cyWallpaper) / (2 * scaledHeight));
1916
1917 wallpaperWidth = (sz.cx * gspv.cxWallpaper) / scaledWidth;
1918 wallpaperHeight = (sz.cy * gspv.cyWallpaper) / scaledHeight;
1919 }
1920 }
1921
1922 if (gspv.WallpaperMode == wmStretch ||
1925 {
1926 x = 0;
1927 y = 0;
1928 }
1929 else if (gspv.WallpaperMode == wmFit)
1930 {
1931 x = (sz.cx - scaledWidth) / 2;
1932 y = (sz.cy - scaledHeight) / 2;
1933 }
1934 else
1935 {
1936 /* Find the upper left corner, can be negative if the bitmap is bigger than the screen */
1937 x = (sz.cx / 2) - (gspv.cxWallpaper / 2);
1938 y = (sz.cy / 2) - (gspv.cyWallpaper / 2);
1939 }
1940
1941 hWallpaperDC = NtGdiCreateCompatibleDC(hDC);
1942 if (hWallpaperDC != NULL)
1943 {
1944 HBITMAP hOldBitmap;
1945
1946 /* Fill in the area that the bitmap is not going to cover */
1947 if (x > 0 || y > 0)
1948 {
1949 /* FIXME: Clip out the bitmap
1950 can be replaced with "NtGdiPatBlt(hDC, x, y, gspv.cxWallpaper, gspv.cyWallpaper, PATCOPY | DSTINVERT);"
1951 once we support DSTINVERT */
1952 PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
1953 NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
1954 NtGdiSelectBrush(hDC, PreviousBrush);
1955 }
1956
1957 /* Do not fill the background after it is painted no matter the size of the picture */
1958 doPatBlt = FALSE;
1959
1960 hOldBitmap = NtGdiSelectBitmap(hWallpaperDC, gspv.hbmWallpaper);
1961
1963 {
1964 if (Rect.right && Rect.bottom)
1966 x,
1967 y,
1968 sz.cx,
1969 sz.cy,
1970 hWallpaperDC,
1971 0,
1972 0,
1975 SRCCOPY,
1976 0);
1977 }
1978 else if (gspv.WallpaperMode == wmTile)
1979 {
1980 /* Paint the bitmap across the screen then down */
1981 for (y = 0; y < Rect.bottom; y += gspv.cyWallpaper)
1982 {
1983 for (x = 0; x < Rect.right; x += gspv.cxWallpaper)
1984 {
1986 x,
1987 y,
1990 hWallpaperDC,
1991 0,
1992 0,
1993 SRCCOPY,
1994 0,
1995 0);
1996 }
1997 }
1998 }
1999 else if (gspv.WallpaperMode == wmFit)
2000 {
2001 if (Rect.right && Rect.bottom)
2002 {
2004 x,
2005 y,
2006 scaledWidth,
2007 scaledHeight,
2008 hWallpaperDC,
2009 0,
2010 0,
2013 SRCCOPY,
2014 0);
2015 }
2016 }
2017 else if (gspv.WallpaperMode == wmFill)
2018 {
2019 if (Rect.right && Rect.bottom)
2020 {
2022 x,
2023 y,
2024 sz.cx,
2025 sz.cy,
2026 hWallpaperDC,
2027 wallpaperX,
2028 wallpaperY,
2029 wallpaperWidth,
2030 wallpaperHeight,
2031 SRCCOPY,
2032 0);
2033 }
2034 }
2035 else
2036 {
2038 x,
2039 y,
2042 hWallpaperDC,
2043 0,
2044 0,
2045 SRCCOPY,
2046 0,
2047 0);
2048 }
2049 NtGdiSelectBitmap(hWallpaperDC, hOldBitmap);
2050 NtGdiDeleteObjectApp(hWallpaperDC);
2051 }
2052 }
2053 }
2054 else
2055 {
2056 /* Black desktop background in Safe Mode */
2057 DesktopBrush = StockObjects[BLACK_BRUSH];
2058 }
2059
2060 /* Background is set to none, clear the screen */
2061 if (doPatBlt)
2062 {
2063 PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
2064 NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
2065 NtGdiSelectBrush(hDC, PreviousBrush);
2066 }
2067
2068 /*
2069 * Display the system version on the desktop background
2070 */
2071 if (InSafeMode || g_AlwaysDisplayVersion || g_PaintDesktopVersion)
2072 {
2074 static WCHAR wszzVersion[1024] = L"\0";
2075
2076 /* Only used in normal mode */
2077 // We expect at most 4 strings (3 for version, 1 for optional NtSystemRoot)
2078 static POLYTEXTW VerStrs[4] = {{0},{0},{0},{0}};
2079 INT i = 0;
2080 SIZE_T len;
2081
2082 HFONT hFont1 = NULL, hFont2 = NULL, hOldFont = NULL;
2083 COLORREF crText, color_old;
2084 UINT align_old;
2085 INT mode_old;
2086 PDC pdc;
2087
2088 if (!UserSystemParametersInfo(SPI_GETWORKAREA, 0, &Rect, 0))
2089 {
2090 Rect.left = Rect.top = 0;
2093 }
2094 else
2095 {
2096 RECTL_vOffsetRect(&Rect, -Rect.left, -Rect.top);
2097 }
2098
2099 /*
2100 * Set up the fonts (otherwise use default ones)
2101 */
2102
2103 /* Font for the principal version string */
2104 hFont1 = GreCreateFontIndirectW(&gspv.ncm.lfCaptionFont);
2105 /* Font for the secondary version strings */
2106 hFont2 = GreCreateFontIndirectW(&gspv.ncm.lfMenuFont);
2107
2108 if (hFont1)
2109 hOldFont = NtGdiSelectFont(hDC, hFont1);
2110
2111 if (gspv.hbmWallpaper == NULL)
2112 {
2113 /* Retrieve the brush fill colour */
2114 // TODO: The following code constitutes "GreGetBrushColor".
2115 PreviousBrush = NtGdiSelectBrush(hDC, DesktopBrush);
2116 pdc = DC_LockDc(hDC);
2117 if (pdc)
2118 {
2119 crText = pdc->eboFill.ulRGBColor;
2120 DC_UnlockDc(pdc);
2121 }
2122 else
2123 {
2124 crText = RGB(0, 0, 0);
2125 }
2126 NtGdiSelectBrush(hDC, PreviousBrush);
2127
2128 /* Adjust text colour according to the brush */
2129 if (GetRValue(crText) + GetGValue(crText) + GetBValue(crText) > 128 * 3)
2130 crText = RGB(0, 0, 0);
2131 else
2132 crText = RGB(255, 255, 255);
2133 }
2134 else
2135 {
2136 /* Always use white when the text is displayed on top of a wallpaper */
2137 crText = RGB(255, 255, 255);
2138 }
2139
2140 color_old = IntGdiSetTextColor(hDC, crText);
2141 align_old = IntGdiSetTextAlign(hDC, TA_RIGHT);
2142 mode_old = IntGdiSetBkMode(hDC, TRANSPARENT);
2143
2144 /* Display the system version information */
2145 if (!*wszzVersion)
2146 {
2147 Status = GetSystemVersionString(wszzVersion,
2148 ARRAYSIZE(wszzVersion),
2149 InSafeMode,
2151 if (!InSafeMode && NT_SUCCESS(Status) && *wszzVersion)
2152 {
2153 PWCHAR pstr = wszzVersion;
2154 for (i = 0; (i < ARRAYSIZE(VerStrs)) && *pstr; ++i)
2155 {
2156 VerStrs[i].n = lstrlenW(pstr);
2157 VerStrs[i].lpstr = pstr;
2158 pstr += (VerStrs[i].n + 1);
2159 }
2160 }
2161 }
2162 else
2163 {
2165 }
2166 if (NT_SUCCESS(Status) && *wszzVersion)
2167 {
2168 if (!InSafeMode)
2169 {
2170 SIZE Size = {0, 0};
2171 LONG TotalHeight = 0;
2172
2173 /* Normal Mode: multiple version information text separated by newlines */
2175
2176 /* Compute the heights of the strings */
2177 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2178 for (i = 0; i < ARRAYSIZE(VerStrs); ++i)
2179 {
2180 if (!VerStrs[i].lpstr || !*VerStrs[i].lpstr || (VerStrs[i].n == 0))
2181 break;
2182
2183 GreGetTextExtentW(hDC, VerStrs[i].lpstr, VerStrs[i].n, &Size, 1);
2184 VerStrs[i].y = Size.cy; // Store the string height
2185 TotalHeight += Size.cy;
2186
2187 /* While the first string was using hFont1, all the others use hFont2 */
2188 if (hFont2) NtGdiSelectFont(hDC, hFont2);
2189 }
2190 /* The total height must not exceed the screen height */
2191 TotalHeight = min(TotalHeight, Rect.bottom);
2192
2193 /* Display the strings */
2194 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2195 for (i = 0; i < ARRAYSIZE(VerStrs); ++i)
2196 {
2197 if (!VerStrs[i].lpstr || !*VerStrs[i].lpstr || (VerStrs[i].n == 0))
2198 break;
2199
2200 TotalHeight -= VerStrs[i].y;
2202 Rect.right - 5,
2203 Rect.bottom - TotalHeight - 5,
2204 0, NULL,
2205 VerStrs[i].lpstr,
2206 VerStrs[i].n,
2207 NULL, 0);
2208
2209 /* While the first string was using hFont1, all the others use hFont2 */
2210 if (hFont2) NtGdiSelectFont(hDC, hFont2);
2211 }
2212 }
2213 else
2214 {
2215 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2216
2217 /* Safe Mode: single version information text in top center */
2218 len = wcslen(wszzVersion);
2219
2221 GreExtTextOutW(hDC, (Rect.right + Rect.left)/2, Rect.top + 3, 0, NULL, wszzVersion, len, NULL, 0);
2222 }
2223 }
2224
2225 if (InSafeMode)
2226 {
2227 if (hFont1) NtGdiSelectFont(hDC, hFont1);
2228
2229 /* Print Safe Mode text in corners */
2230 len = wcslen(s_wszSafeMode);
2231
2233 GreExtTextOutW(hDC, Rect.left, Rect.top + 3, 0, NULL, s_wszSafeMode, len, NULL, 0);
2235 GreExtTextOutW(hDC, Rect.right, Rect.top + 3, 0, NULL, s_wszSafeMode, len, NULL, 0);
2237 GreExtTextOutW(hDC, Rect.left, Rect.bottom - 5, 0, NULL, s_wszSafeMode, len, NULL, 0);
2239 GreExtTextOutW(hDC, Rect.right, Rect.bottom - 5, 0, NULL, s_wszSafeMode, len, NULL, 0);
2240 }
2241
2242 IntGdiSetBkMode(hDC, mode_old);
2243 IntGdiSetTextAlign(hDC, align_old);
2244 IntGdiSetTextColor(hDC, color_old);
2245
2246 if (hFont2)
2247 GreDeleteObject(hFont2);
2248
2249 if (hFont1)
2250 {
2251 NtGdiSelectFont(hDC, hOldFont);
2252 GreDeleteObject(hFont1);
2253 }
2254 }
2255
2256 return TRUE;
2257}
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
#define RGB(r, g, b)
Definition: precomp.h:62
#define GetBValue(quad)
Definition: precomp.h:66
#define GetGValue(quad)
Definition: precomp.h:65
#define GetRValue(quad)
Definition: precomp.h:64
#define ERROR(name)
Definition: error_private.h:53
BOOL APIENTRY GreExtTextOutW(IN HDC hDC, IN INT XStart, IN INT YStart, IN UINT fuOptions, IN OPTIONAL PRECTL lprc, IN LPCWSTR String, IN INT Count, IN OPTIONAL LPINT Dx, IN DWORD dwCodePage)
Definition: freetype.c:6537
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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
if(dx< 0)
Definition: linetemp.h:194
static HBITMAP
Definition: button.c:44
static LPCSTR lpstr
Definition: font.c:51
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
#define min(a, b)
Definition: monoChain.cc:55
__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:984
__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
BOOL g_AlwaysDisplayVersion
Definition: ntuser.c:17
long LONG
Definition: pedump.c:60
Definition: polytest.cpp:41
HBRUSH hbrBackground
Definition: ntuser.h:587
LPCWSTR lpstr
Definition: wingdi.h:2564
UINT n
Definition: wingdi.h:2563
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:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
@ 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:122
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
HFONT FASTCALL GreCreateFontIndirectW(LOGFONTW *lplf)
Definition: font.c:23
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(HDC hDC, LPCWSTR lpwsz, INT cwc, LPSIZE psize, UINT flOpts)
Definition: text.c:78
HWND FASTCALL IntGetDesktopWindow(VOID)
Definition: desktop.c:1374
static NTSTATUS GetSystemVersionString(OUT PWSTR pwszzVersion, IN SIZE_T cchDest, IN BOOLEAN InSafeMode, IN BOOLEAN AppendNtSystemRoot)
Definition: desktop.c:283
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:2105
ENGAPI INT APIENTRY EngMulDiv(_In_ INT a, _In_ INT b, _In_ INT c)
Definition: math.c:26
DWORD COLORREF
Definition: windef.h:300
#define TA_RIGHT
Definition: wingdi.h:933
#define TA_LEFT
Definition: wingdi.h:932
#define TRANSPARENT
Definition: wingdi.h:950
#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:960
#define SM_CLEANBOOT
Definition: winuser.h:1027
#define SM_CXSCREEN
Definition: winuser.h:959

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

◆ IntRegisterShellHookWindow()

BOOL IntRegisterShellHookWindow ( HWND  hWnd)

Definition at line 1752 of file desktop.c.

1753{
1755 PDESKTOP Desktop = pti->rpdesk;
1757
1758 TRACE("IntRegisterShellHookWindow\n");
1759
1760 /* First deregister the window, so we can be sure it's never twice in the
1761 * list.
1762 */
1764
1766 sizeof(SHELL_HOOK_WINDOW),
1767 TAG_WINSTA);
1768
1769 if (!Entry)
1770 return FALSE;
1771
1772 Entry->hWnd = hWnd;
1773
1774 InsertTailList(&Desktop->ShellHookWindows, &Entry->ListEntry);
1775
1776 return TRUE;
1777}
#define InsertTailList(ListHead, Entry)
#define PagedPool
Definition: env_spec_w32.h:308
base of all file and directory entries
Definition: entries.h:83
BOOL IntDeRegisterShellHookWindow(HWND hWnd)
Definition: desktop.c:1784

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

557{
559 HWINSTA hWinSta = NULL, hWinStaDup = NULL;
560 HDESK hDesktop = NULL, hDesktopDup = NULL;
561 PPROCESSINFO ppi;
563 LUID ProcessLuid;
564 USHORT StrSize;
565 SIZE_T MemSize;
566 PSECURITY_DESCRIPTOR ServiceSD;
569 UNICODE_STRING WinStaName, DesktopName;
570 const UNICODE_STRING WinSta0Name = RTL_CONSTANT_STRING(L"WinSta0");
571 PWINSTATION_OBJECT WinStaObject;
572 HWINSTA hTempWinSta = NULL;
573 BOOLEAN bUseDefaultWinSta = FALSE;
574 BOOLEAN bInteractive = FALSE;
575 BOOLEAN bAccessAllowed = FALSE;
576
578
579 ASSERT(phWinSta);
580 ASSERT(phDesktop);
581 ASSERT(DesktopPath);
582
583 *phWinSta = NULL;
584 *phDesktop = NULL;
585
587 /* ppi is typically NULL for console applications that connect to Win32 USER */
588 if (!ppi) TRACE("IntResolveDesktop: ppi is NULL!\n");
589
590 if (ppi && ppi->hwinsta != NULL && ppi->hdeskStartup != NULL)
591 {
592 /*
593 * If this process is the current one, just return the cached handles.
594 * Otherwise, open the window station and desktop objects.
595 */
597 {
598 hWinSta = ppi->hwinsta;
599 hDesktop = ppi->hdeskStartup;
600 }
601 else
602 {
604 0,
605 NULL,
608 UserMode,
609 (PHANDLE)&hWinSta);
610 if (!NT_SUCCESS(Status))
611 {
612 ERR("IntResolveDesktop: Could not reference window station 0x%p\n", ppi->prpwinsta);
614 return Status;
615 }
616
618 0,
619 NULL,
622 UserMode,
623 (PHANDLE)&hDesktop);
624 if (!NT_SUCCESS(Status))
625 {
626 ERR("IntResolveDesktop: Could not reference desktop 0x%p\n", ppi->rpdeskStartup);
627 ObCloseHandle(hWinSta, UserMode);
629 return Status;
630 }
631 }
632
633 *phWinSta = hWinSta;
634 *phDesktop = hDesktop;
635 return STATUS_SUCCESS;
636 }
637
638 /* We will by default use the default window station and desktop */
639 RtlInitEmptyUnicodeString(&WinStaName, NULL, 0);
640 RtlInitEmptyUnicodeString(&DesktopName, NULL, 0);
641
642 /*
643 * Parse the desktop path string which can be of the form "WinSta\Desktop"
644 * or just "Desktop". In the latter case we use the default window station
645 * on which the process is attached to (or if none, "WinSta0").
646 */
647 if (DesktopPath->Buffer != NULL && DesktopPath->Length > sizeof(WCHAR))
648 {
649 DesktopName = *DesktopPath;
650
651 /* Find the separator */
652 while (DesktopName.Length > 0 && *DesktopName.Buffer &&
653 *DesktopName.Buffer != OBJ_NAME_PATH_SEPARATOR)
654 {
655 DesktopName.Buffer++;
656 DesktopName.Length -= sizeof(WCHAR);
657 DesktopName.MaximumLength -= sizeof(WCHAR);
658 }
659 if (DesktopName.Length > 0)
660 {
661 RtlInitEmptyUnicodeString(&WinStaName, DesktopPath->Buffer,
662 DesktopPath->Length - DesktopName.Length);
663 // (USHORT)((ULONG_PTR)DesktopName.Buffer - (ULONG_PTR)DesktopPath->Buffer);
664 WinStaName.Length = WinStaName.MaximumLength;
665
666 /* Skip the separator */
667 DesktopName.Buffer++;
668 DesktopName.Length -= sizeof(WCHAR);
669 DesktopName.MaximumLength -= sizeof(WCHAR);
670 }
671 else
672 {
673 RtlInitEmptyUnicodeString(&WinStaName, NULL, 0);
674 DesktopName = *DesktopPath;
675 }
676 }
677
678 TRACE("IntResolveDesktop: WinStaName:'%wZ' ; DesktopName:'%wZ'\n", &WinStaName, &DesktopName);
679
680 /* Retrieve the process LUID */
681 Status = GetProcessLuid(NULL, Process, &ProcessLuid);
682 if (!NT_SUCCESS(Status))
683 {
684 ERR("IntResolveDesktop: Failed to retrieve the process LUID, Status 0x%08lx\n", Status);
686 return Status;
687 }
688
689 /*
690 * If this process is not the current one, obtain a temporary handle
691 * to it so that we can perform handles duplication later.
692 */
694 {
697 NULL,
698 0,
701 &hProcess);
702 if (!NT_SUCCESS(Status))
703 {
704 ERR("IntResolveDesktop: Failed to obtain a handle to process 0x%p, Status 0x%08lx\n", Process, Status);
706 return Status;
707 }
709 }
710
711 /*
712 * If no window station has been specified, search the process handle table
713 * for inherited window station handles, otherwise use a default one.
714 */
715 if (WinStaName.Buffer == NULL)
716 {
717 /*
718 * We want to find a suitable default window station.
719 * For applications that can be interactive, i.e. that have allowed
720 * access to the single interactive window station on the system,
721 * the default window station is 'WinSta0'.
722 * For applications that cannot be interactive, i.e. that do not have
723 * access to 'WinSta0' (e.g. non-interactive services), the default
724 * window station is 'Service-0xXXXX-YYYY$' (created if needed).
725 * Precedence will however be taken by any inherited window station
726 * that possesses the required interactivity property.
727 */
728 bUseDefaultWinSta = TRUE;
729
730 /*
731 * Use the default 'WinSta0' window station. Whether we should
732 * use 'Service-0xXXXX-YYYY$' instead will be determined later.
733 */
734 // RtlInitUnicodeString(&WinStaName, L"WinSta0");
735 WinStaName = WinSta0Name;
736
738 NULL,
740 NULL,
741 (PHANDLE)&hWinSta))
742 {
743 TRACE("IntResolveDesktop: Inherited window station is: 0x%p\n", hWinSta);
744 }
745 }
746
747 /*
748 * If no desktop has been specified, search the process handle table
749 * for inherited desktop handles, otherwise use the Default desktop.
750 * Note that the inherited desktop that we may use, may not belong
751 * to the window station we will connect to.
752 */
753 if (DesktopName.Buffer == NULL)
754 {
755 /* Use a default desktop name */
756 RtlInitUnicodeString(&DesktopName, L"Default");
757
759 NULL,
761 NULL,
762 (PHANDLE)&hDesktop))
763 {
764 TRACE("IntResolveDesktop: Inherited desktop is: 0x%p\n", hDesktop);
765 }
766 }
767
768
769 /*
770 * We are going to open either a window station or a desktop.
771 * Even if this operation is done from kernel-mode, we should
772 * "emulate" an opening from user-mode (i.e. using an ObjectAttributes
773 * allocated in user-mode, with AccessMode == UserMode) for the
774 * Object Manager to perform proper access validation to the
775 * window station or desktop.
776 */
777
778 /*
779 * Estimate the maximum size needed for the window station name
780 * and desktop name to be given to ObjectAttributes->ObjectName.
781 */
782 StrSize = 0;
783
784 /* Window station name */
785 MemSize = _scwprintf(L"Service-0x%x-%x$", MAXULONG, MAXULONG) * sizeof(WCHAR);
787 + max(WinStaName.Length, MemSize) + sizeof(UNICODE_NULL);
788 if (MemSize > MAXUSHORT)
789 {
790 ERR("IntResolveDesktop: Window station name length is too long.\n");
792 goto Quit;
793 }
794 StrSize = max(StrSize, (USHORT)MemSize);
795
796 /* Desktop name */
797 MemSize = max(DesktopName.Length + sizeof(UNICODE_NULL), sizeof(L"Default"));
798 StrSize = max(StrSize, (USHORT)MemSize);
799
800 /* Size for the OBJECT_ATTRIBUTES */
801 MemSize = ALIGN_UP(sizeof(OBJECT_ATTRIBUTES), sizeof(PVOID));
802
803 /* Add the string size */
804 MemSize += ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID));
805 MemSize += StrSize;
806
807 /* Allocate the memory in user-mode */
808 Status = ZwAllocateVirtualMemory(ZwCurrentProcess(),
810 0,
811 &MemSize,
814 if (!NT_SUCCESS(Status))
815 {
816 ERR("ZwAllocateVirtualMemory() failed, Status 0x%08lx\n", Status);
817 goto Quit;
818 }
819
821 ALIGN_UP(sizeof(OBJECT_ATTRIBUTES), sizeof(PVOID)));
822
823 RtlInitEmptyUnicodeString(ObjectName,
825 ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID))),
826 StrSize);
827
828
829 /* If we got an inherited window station handle, duplicate and use it */
830 if (hWinSta)
831 {
832 ASSERT(bUseDefaultWinSta);
833
834 /* Duplicate the handle if it belongs to another process than the current one */
836 {
838 Status = ZwDuplicateObject(hProcess,
839 hWinSta,
841 (PHANDLE)&hWinStaDup,
842 0,
843 0,
845 if (!NT_SUCCESS(Status))
846 {
847 ERR("IntResolveDesktop: Failed to duplicate the window station handle, Status 0x%08lx\n", Status);
848 /* We will use a default window station */
849 hWinSta = NULL;
850 }
851 else
852 {
853 hWinSta = hWinStaDup;
854 }
855 }
856 }
857
858 /*
859 * If we have an inherited window station, check whether
860 * it is interactive and remember that for later.
861 */
862 if (hWinSta)
863 {
864 ASSERT(bUseDefaultWinSta);
865
866 /* Reference the inherited window station */
868 0,
871 (PVOID*)&WinStaObject,
872 NULL);
873 if (!NT_SUCCESS(Status))
874 {
875 ERR("Failed to reference the inherited window station, Status 0x%08lx\n", Status);
876 /* We will use a default window station */
877 if (hWinStaDup)
878 {
879 ASSERT(hWinSta == hWinStaDup);
880 ObCloseHandle(hWinStaDup, UserMode);
881 hWinStaDup = NULL;
882 }
883 hWinSta = NULL;
884 }
885 else
886 {
887 ERR("Process LUID is: 0x%x-%x, inherited window station LUID is: 0x%x-%x\n",
888 ProcessLuid.HighPart, ProcessLuid.LowPart,
889 WinStaObject->luidUser.HighPart, WinStaObject->luidUser.LowPart);
890
891 /* Check whether this window station is interactive, and remember it for later */
892 bInteractive = !(WinStaObject->Flags & WSS_NOIO);
893
894 /* Dereference the window station */
895 ObDereferenceObject(WinStaObject);
896 }
897 }
898
899 /* Build a valid window station name */
901 ObjectName->MaximumLength,
902 L"%wZ\\%wZ",
904 &WinStaName);
905 if (!NT_SUCCESS(Status))
906 {
907 ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
908 goto Quit;
909 }
910 ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
911
912 TRACE("Parsed initial window station: '%wZ'\n", ObjectName);
913
914 /* Try to open the window station */
918 NULL,
919 NULL);
920 if (bInherit)
921 ObjectAttributes->Attributes |= OBJ_INHERIT;
922
925 UserMode,
926 NULL,
928 NULL,
929 (PHANDLE)&hTempWinSta);
930 if (!NT_SUCCESS(Status))
931 {
932 ERR("Failed to open the window station '%wZ', Status 0x%08lx\n", ObjectName, Status);
933 }
934 else
935 {
936 //
937 // FIXME TODO: Perform a window station access check!!
938 // If we fail AND bUseDefaultWinSta == FALSE we just quit.
939 //
940
941 /*
942 * Check whether we are opening the (single) interactive
943 * window station, and if so, perform an access check.
944 */
945 /* Check whether we are allowed to perform interactions */
946 if (RtlEqualUnicodeString(&WinStaName, &WinSta0Name, TRUE))
947 {
948 LUID SystemLuid = SYSTEM_LUID;
949
950 /* Interactive window station: check for user LUID */
951 WinStaObject = InputWindowStation;
952
954
955 // TODO: Check also that we compare wrt. window station WinSta0
956 // which is the only one that can be interactive on the system.
957 if (((!bUseDefaultWinSta || bInherit) && RtlEqualLuid(&ProcessLuid, &SystemLuid)) ||
958 RtlEqualLuid(&ProcessLuid, &WinStaObject->luidUser))
959 {
960 /* We are interactive on this window station */
961 bAccessAllowed = TRUE;
963 }
964 }
965 else
966 {
967 /* Non-interactive window station: we have access since we were able to open it */
968 bAccessAllowed = TRUE;
970 }
971 }
972
973 /* If we failed, bail out if we were not trying to open the default window station */
974 if (!NT_SUCCESS(Status) && !bUseDefaultWinSta) // if (!bAccessAllowed)
975 goto Quit;
976
977 if (/* bAccessAllowed && */ bInteractive || !bAccessAllowed)
978 {
979 /*
980 * Close WinSta0 if the inherited window station is interactive so that
981 * we can use it, or we do not have access to the interactive WinSta0.
982 */
983 ObCloseHandle(hTempWinSta, UserMode);
984 hTempWinSta = NULL;
985 }
986 if (bInteractive == bAccessAllowed)
987 {
988 /* Keep using the inherited window station */
989 NOTHING;
990 }
991 else // if (bInteractive != bAccessAllowed)
992 {
993 /*
994 * Close the inherited window station, we will either keep using
995 * the interactive WinSta0, or use Service-0xXXXX-YYYY$.
996 */
997 if (hWinStaDup)
998 {
999 ASSERT(hWinSta == hWinStaDup);
1000 ObCloseHandle(hWinStaDup, UserMode);
1001 hWinStaDup = NULL;
1002 }
1003 hWinSta = hTempWinSta; // hTempWinSta is NULL in case bAccessAllowed == FALSE
1004 }
1005
1006 if (bUseDefaultWinSta)
1007 {
1008 if (hWinSta == NULL && !bInteractive)
1009 {
1010 /* Build a valid window station name from the LUID */
1012 ObjectName->MaximumLength,
1013 L"%wZ\\Service-0x%x-%x$",
1015 ProcessLuid.HighPart,
1016 ProcessLuid.LowPart);
1017 if (!NT_SUCCESS(Status))
1018 {
1019 ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
1020 goto Quit;
1021 }
1022 ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
1023
1024 /*
1025 * Set up a security descriptor for the new service's window station.
1026 * A service has an associated window station and desktop. The newly
1027 * created window station and desktop will get this security descriptor
1028 * if such objects weren't created before.
1029 */
1030 Status = IntCreateServiceSecurity(&ServiceSD);
1031 if (!NT_SUCCESS(Status))
1032 {
1033 ERR("Failed to create a security descriptor for service window station, Status 0x%08lx\n", Status);
1034 goto Quit;
1035 }
1036
1037 /*
1038 * Create or open the non-interactive window station.
1039 * NOTE: The non-interactive window station handle is never inheritable.
1040 */
1042 ObjectName,
1044 NULL,
1045 ServiceSD);
1046
1047 Status = IntCreateWindowStation(&hWinSta,
1049 UserMode,
1050 KernelMode,
1052 0, 0, 0, 0, 0);
1053
1054 IntFreeSecurityBuffer(ServiceSD);
1055
1056 if (!NT_SUCCESS(Status))
1057 {
1058 ASSERT(hWinSta == NULL);
1059 ERR("Failed to create or open the non-interactive window station '%wZ', Status 0x%08lx\n",
1061 goto Quit;
1062 }
1063
1064 //
1065 // FIXME: We might not need to always create or open the "Default"
1066 // desktop on the Service-0xXXXX-YYYY$ window station; we may need
1067 // to use another one....
1068 //
1069
1070 /* Create or open the Default desktop on the window station */
1072 ObjectName->MaximumLength,
1073 L"Default");
1074 if (!NT_SUCCESS(Status))
1075 {
1076 ERR("Impossible to build a valid desktop name, Status 0x%08lx\n", Status);
1077 goto Quit;
1078 }
1079 ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
1080
1081 /*
1082 * NOTE: The non-interactive desktop handle is never inheritable.
1083 * The security descriptor is inherited from the newly created
1084 * window station for the desktop.
1085 */
1087 ObjectName,
1089 hWinSta,
1090 NULL);
1091
1092 Status = IntCreateDesktop(&hDesktop,
1094 UserMode,
1095 NULL,
1096 NULL,
1097 0,
1099 if (!NT_SUCCESS(Status))
1100 {
1101 ASSERT(hDesktop == NULL);
1102 ERR("Failed to create or open the desktop '%wZ' on window station 0x%p, Status 0x%08lx\n",
1103 ObjectName, hWinSta, Status);
1104 }
1105
1106 goto Quit;
1107 }
1108/*
1109 if (hWinSta == NULL)
1110 {
1111 Status = STATUS_UNSUCCESSFUL;
1112 goto Quit;
1113 }
1114*/
1115 }
1116
1117 /*
1118 * If we got an inherited desktop handle, duplicate and use it,
1119 * otherwise open a new desktop.
1120 */
1121 if (hDesktop != NULL)
1122 {
1123 /* Duplicate the handle if it belongs to another process than the current one */
1125 {
1127 Status = ZwDuplicateObject(hProcess,
1128 hDesktop,
1130 (PHANDLE)&hDesktopDup,
1131 0,
1132 0,
1134 if (!NT_SUCCESS(Status))
1135 {
1136 ERR("IntResolveDesktop: Failed to duplicate the desktop handle, Status 0x%08lx\n", Status);
1137 /* We will use a default desktop */
1138 hDesktop = NULL;
1139 }
1140 else
1141 {
1142 hDesktop = hDesktopDup;
1143 }
1144 }
1145 }
1146
1147 if ((hWinSta != NULL) && (hDesktop == NULL))
1148 {
1150 ObjectName->MaximumLength,
1151 DesktopName.Buffer,
1152 DesktopName.Length);
1153 if (!NT_SUCCESS(Status))
1154 {
1155 ERR("Impossible to build a valid desktop name, Status 0x%08lx\n", Status);
1156 goto Quit;
1157 }
1158 ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR));
1159
1160 TRACE("Parsed initial desktop: '%wZ'\n", ObjectName);
1161
1162 /* Open the desktop object */
1164 ObjectName,
1166 hWinSta,
1167 NULL);
1168 if (bInherit)
1169 ObjectAttributes->Attributes |= OBJ_INHERIT;
1170
1173 UserMode,
1174 NULL,
1176 NULL,
1177 (PHANDLE)&hDesktop);
1178 if (!NT_SUCCESS(Status))
1179 {
1180 ERR("Failed to open the desktop '%wZ' on window station 0x%p, Status 0x%08lx\n",
1181 ObjectName, hWinSta, Status);
1182 goto Quit;
1183 }
1184 }
1185
1186Quit:
1187 /* Release the object attributes */
1188 if (ObjectAttributes)
1189 {
1190 MemSize = 0;
1191 ZwFreeVirtualMemory(ZwCurrentProcess(),
1193 &MemSize,
1194 MEM_RELEASE);
1195 }
1196
1197 /* Close the temporary process handle */
1198 if (hProcess) // if (Process != PsGetCurrentProcess())
1200
1201 if (NT_SUCCESS(Status))
1202 {
1203 *phWinSta = hWinSta;
1204 *phDesktop = hDesktop;
1205 return STATUS_SUCCESS;
1206 }
1207 else
1208 {
1209 ERR("IntResolveDesktop(%wZ) failed, Status 0x%08lx\n", DesktopPath, Status);
1210
1211 if (hDesktopDup)
1212 ObCloseHandle(hDesktopDup, UserMode);
1213 if (hWinStaDup)
1214 ObCloseHandle(hWinStaDup, UserMode);
1215
1216 if (hDesktop)
1217 ObCloseHandle(hDesktop, UserMode);
1218 if (hWinSta)
1219 ObCloseHandle(hWinSta, UserMode);
1220
1222 return Status;
1223 }
1224}
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
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
_Check_return_ _CRTIMP int __cdecl _scwprintf(_In_z_ _Printf_format_string_ const wchar_t *_Format,...)
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_INHERIT
Definition: winternl.h:225
#define NOTHING
Definition: input_list.c:10
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define MEM_RELEASE
Definition: nt_native.h:1316
#define MEM_COMMIT
Definition: nt_native.h:1313
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
POBJECT_TYPE PsProcessType
Definition: process.c:20
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
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:447
unsigned short USHORT
Definition: pedump.c:61
LONG HighPart
DWORD LowPart
HWINSTA hwinsta
Definition: win32.h:267
struct _DESKTOP * rpdeskStartup
Definition: win32.h:258
struct _WINSTATION_OBJECT * prpwinsta
Definition: win32.h:266
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define max(a, b)
Definition: svc.c:63
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#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:2352
NTSTATUS GetProcessLuid(IN PETHREAD Thread OPTIONAL, IN PEPROCESS Process OPTIONAL, OUT PLUID Luid)
Definition: misc.c:813
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:301
#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 1319 of file desktop.c.

1320{
1323 if (!pdo)
1324 {
1325 TRACE("No active desktop\n");
1326 return;
1327 }
1328 if (NewQueue != NULL)
1329 {
1330 if (NewQueue->Desktop != NULL)
1331 {
1332 TRACE("Message Queue already attached to another desktop!\n");
1333 return;
1334 }
1335 IntReferenceMessageQueue(NewQueue);
1336 (void)InterlockedExchangePointer((PVOID*)&NewQueue->Desktop, pdo);
1337 }
1339 if (Old != NULL)
1340 {
1342 gpqForegroundPrev = Old;
1344 }
1345 // Only one Q can have active foreground even when there are more than one desktop.
1346 if (NewQueue)
1347 {
1349 }
1350 else
1351 {
1353 ERR("ptiLastInput is CLEARED!!\n");
1354 ptiLastInput = NULL; // ReactOS hacks... should check for process death.
1355 }
1356}
#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 3260 of file desktop.c.

3262{
3263 PDESKTOP pdesk = NULL, pdeskOld;
3264 PTHREADINFO pti;
3266 PCLIENTTHREADINFO pctiOld, pctiNew = NULL;
3267 PCLIENTINFO pci;
3268
3270
3271 TRACE("IntSetThreadDesktop hDesktop:0x%p, FOF:%i\n",hDesktop, FreeOnFailure);
3272
3274 pci = pti->pClientInfo;
3275
3276 /* If the caller gave us a desktop, ensure it is valid */
3277 if (hDesktop != NULL)
3278 {
3279 /* Validate the new desktop. */
3280 Status = IntValidateDesktopHandle(hDesktop, UserMode, 0, &pdesk);
3281 if (!NT_SUCCESS(Status))
3282 {
3283 ERR("Validation of desktop handle 0x%p failed\n", hDesktop);
3284 return FALSE;
3285 }
3286
3287 if (pti->rpdesk == pdesk)
3288 {
3289 /* Nothing to do */
3290 ObDereferenceObject(pdesk);
3291 return TRUE;
3292 }
3293 }
3294
3295 /* Make sure that we don't own any window in the current desktop */
3296 if (!IsListEmpty(&pti->WindowListHead))
3297 {
3298 if (pdesk)
3299 ObDereferenceObject(pdesk);
3300 ERR("Attempted to change thread desktop although the thread has windows!\n");
3302 return FALSE;
3303 }
3304
3305 /* Desktop is being re-set so clear out foreground. */
3306 if (pti->rpdesk != pdesk && pti->MessageQueue == gpqForeground)
3307 {
3308 // Like above, there shouldn't be any windows, hooks or anything active on this threads desktop!
3310 }
3311
3312 /* Before doing the switch, map the new desktop heap and allocate the new pcti */
3313 if (pdesk != NULL)
3314 {
3315 Status = IntMapDesktopView(pdesk);
3316 if (!NT_SUCCESS(Status))
3317 {
3318 ERR("Failed to map desktop heap!\n");
3319 ObDereferenceObject(pdesk);
3321 return FALSE;
3322 }
3323
3324 pctiNew = DesktopHeapAlloc(pdesk, sizeof(CLIENTTHREADINFO));
3325 if (pctiNew == NULL)
3326 {
3327 ERR("Failed to allocate new pcti\n");
3328 IntUnmapDesktopView(pdesk);
3329 ObDereferenceObject(pdesk);
3331 return FALSE;
3332 }
3333 }
3334
3335 /*
3336 * Processes, in particular Winlogon.exe, that manage window stations
3337 * (especially the interactive WinSta0 window station) and desktops,
3338 * may not be able to connect at startup to a window station and have
3339 * an associated desktop as well, if none exists on the system already.
3340 * Because creating a new window station does not affect the window station
3341 * associated to the process, and because neither by associating a window
3342 * station to the process nor creating a new desktop on it does associate
3343 * a startup desktop to that process, the process has to actually assigns
3344 * one of its threads to a desktop so that it gets automatically an assigned
3345 * startup desktop.
3346 *
3347 * This is what actually happens for Winlogon.exe, which is started without
3348 * any window station and desktop. By creating the first (and therefore
3349 * interactive) WinSta0 window station, then assigning WinSta0 to itself
3350 * and creating the Default desktop on it, and then assigning this desktop
3351 * to its main thread, Winlogon.exe basically does the similar steps that
3352 * would have been done automatically at its startup if there were already
3353 * an existing WinSta0 window station and Default desktop.
3354 *
3355 * Of course all this must not be done if we are a SYSTEM or CSRSS thread.
3356 */
3357 // if (pti->ppi->peProcess != gpepCSRSS)
3358 if (!(pti->TIF_flags & (TIF_SYSTEMTHREAD | TIF_CSRSSTHREAD)) &&
3359 pti->ppi->rpdeskStartup == NULL && hDesktop != NULL)
3360 {
3361 ERR("The process 0x%p '%s' didn't have an assigned startup desktop before, assigning it now!\n",
3362 pti->ppi->peProcess, pti->ppi->peProcess->ImageFileName);
3363
3364 pti->ppi->hdeskStartup = hDesktop;
3365 pti->ppi->rpdeskStartup = pdesk;
3366 }
3367
3368 /* free all classes or move them to the shared heap */
3369 if (pti->rpdesk != NULL)
3370 {
3371 if (!IntCheckProcessDesktopClasses(pti->rpdesk, FreeOnFailure))
3372 {
3373 ERR("Failed to move process classes to shared heap!\n");
3374 if (pdesk)
3375 {
3376 DesktopHeapFree(pdesk, pctiNew);
3377 IntUnmapDesktopView(pdesk);
3378 ObDereferenceObject(pdesk);
3379 }
3380 return FALSE;
3381 }
3382 }
3383
3384 pdeskOld = pti->rpdesk;
3385 if (pti->pcti != &pti->cti)
3386 pctiOld = pti->pcti;
3387 else
3388 pctiOld = NULL;
3389
3390 /* do the switch */
3391 if (pdesk != NULL)
3392 {
3393 pti->rpdesk = pdesk;
3394 pti->hdesk = hDesktop;
3395 pti->pDeskInfo = pti->rpdesk->pDeskInfo;
3396 pti->pcti = pctiNew;
3397
3399 pci->pDeskInfo = (PVOID)((ULONG_PTR)pti->pDeskInfo - pci->ulClientDelta);
3400 pci->pClientThreadInfo = (PVOID)((ULONG_PTR)pti->pcti - pci->ulClientDelta);
3401
3402 /* initialize the new pcti */
3403 if (pctiOld != NULL)
3404 {
3405 RtlCopyMemory(pctiNew, pctiOld, sizeof(CLIENTTHREADINFO));
3406 }
3407 else
3408 {
3409 RtlZeroMemory(pctiNew, sizeof(CLIENTTHREADINFO));
3410 pci->fsHooks = pti->fsHooks;
3411 pci->dwTIFlags = pti->TIF_flags;
3412 }
3413 }
3414 else
3415 {
3416 pti->rpdesk = NULL;
3417 pti->hdesk = NULL;
3418 pti->pDeskInfo = NULL;
3419 pti->pcti = &pti->cti; // Always point inside so there will be no crash when posting or sending msg's!
3420 pci->ulClientDelta = 0;
3421 pci->pDeskInfo = NULL;
3422 pci->pClientThreadInfo = NULL;
3423 }
3424
3425 /* clean up the old desktop */
3426 if (pdeskOld != NULL)
3427 {
3428 RemoveEntryList(&pti->PtiLink);
3429 if (pctiOld) DesktopHeapFree(pdeskOld, pctiOld);
3430 IntUnmapDesktopView(pdeskOld);
3431 ObDereferenceObject(pdeskOld);
3432 }
3433
3434 if (pdesk)
3435 {
3436 InsertTailList(&pdesk->PtiList, &pti->PtiLink);
3437 }
3438
3439 TRACE("IntSetThreadDesktop: pti 0x%p ppi 0x%p switched from object 0x%p to 0x%p\n", pti, pti->ppi, pdeskOld, pdesk);
3440
3441 return TRUE;
3442}
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_BUSY
Definition: dderror.h:12
#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:1015
VOID FASTCALL IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue)
Definition: desktop.c:1319
NTSTATUS FASTCALL IntValidateDesktopHandle(HDESK Desktop, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PDESKTOP *Object)
Definition: desktop.c:1237
static __inline ULONG_PTR DesktopHeapGetUserDelta(VOID)
Definition: desktop.h:272
static __inline PVOID DesktopHeapAlloc(IN PDESKTOP Desktop, IN SIZE_T Bytes)
Definition: desktop.h:204
static __inline BOOL DesktopHeapFree(IN PDESKTOP Desktop, IN PVOID lpMem)
Definition: desktop.h:215
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22

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

◆ IntUnmapDesktopView()

static NTSTATUS IntUnmapDesktopView ( IN PDESKTOP  pdesk)
static

Definition at line 3142 of file desktop.c.

3143{
3144 PPROCESSINFO ppi;
3145 PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
3147
3148 TRACE("IntUnmapDesktopView called for desktop object %p\n", pdesk);
3149
3151
3152 /*
3153 * Unmap if we're the last thread using the desktop.
3154 * Start the search at the next mapping: skip the first entry
3155 * as it must be the global user heap mapping.
3156 */
3157 PrevLink = &ppi->HeapMappings.Next;
3158 HeapMapping = *PrevLink;
3159 while (HeapMapping != NULL)
3160 {
3161 if (HeapMapping->KernelMapping == (PVOID)pdesk->pheapDesktop)
3162 {
3163 if (--HeapMapping->Count == 0)
3164 {
3165 *PrevLink = HeapMapping->Next;
3166
3167 TRACE("ppi 0x%p unmapped heap of desktop 0x%p\n", ppi, pdesk);
3169 HeapMapping->UserMapping);
3170
3171 ObDereferenceObject(pdesk);
3172
3173 UserHeapFree(HeapMapping);
3174 break;
3175 }
3176 }
3177
3178 PrevLink = &HeapMapping->Next;
3179 HeapMapping = HeapMapping->Next;
3180 }
3181
3182 return Status;
3183}
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 1237 of file desktop.c.

1242{
1244
1248 AccessMode,
1249 (PVOID*)Object,
1250 NULL);
1251
1252 TRACE("IntValidateDesktopHandle: handle:0x%p obj:0x%p access:0x%x Status:0x%lx\n",
1254
1255 if (!NT_SUCCESS(Status))
1257
1258 return Status;
1259}
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658

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

◆ NtUserCloseDesktop()

BOOL APIENTRY NtUserCloseDesktop ( HDESK  hDesktop)

Definition at line 2722 of file desktop.c.

2723{
2724 PDESKTOP pdesk;
2726 BOOL Ret = FALSE;
2727
2728 TRACE("NtUserCloseDesktop(0x%p) called\n", hDesktop);
2730
2731 if (hDesktop == gptiCurrent->hdesk || hDesktop == gptiCurrent->ppi->hdeskStartup)
2732 {
2733 ERR("Attempted to close thread desktop\n");
2735 goto Exit; // Return FALSE
2736 }
2737
2738 Status = IntValidateDesktopHandle(hDesktop, UserMode, 0, &pdesk);
2739 if (!NT_SUCCESS(Status))
2740 {
2741 ERR("Validation of desktop handle 0x%p failed\n", hDesktop);
2742 goto Exit; // Return FALSE
2743 }
2744
2745 ObDereferenceObject(pdesk);
2746
2747 Status = ObCloseHandle(hDesktop, UserMode);
2748 if (!NT_SUCCESS(Status))
2749 {
2750 ERR("Failed to close desktop handle 0x%p\n", hDesktop);
2752 goto Exit; // Return FALSE
2753 }
2754
2755 Ret = TRUE;
2756
2757Exit:
2758 TRACE("Leave NtUserCloseDesktop, ret=%i\n", Ret);
2759 UserLeave();
2760 return Ret;
2761}
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 2529 of file desktop.c.

2535{
2537 HDESK hDesk;
2538 HDESK Ret = NULL;
2539
2540 TRACE("Enter NtUserCreateDesktop\n");
2542
2543 Status = IntCreateDesktop(&hDesk,
2545 UserMode,
2546 lpszDesktopDevice,
2547 lpdmw,
2548 dwFlags,
2549 dwDesiredAccess);
2550 if (!NT_SUCCESS(Status))
2551 {
2552 ERR("IntCreateDesktop failed, Status 0x%08lx\n", Status);
2553 // SetLastNtError(Status);
2554 goto Exit; // Return NULL
2555 }
2556
2557 Ret = hDesk;
2558
2559Exit:
2560 TRACE("Leave NtUserCreateDesktop, ret=0x%p\n", Ret);
2561 UserLeave();
2562 return Ret;
2563}
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176

Referenced by CreateDesktopW().

◆ NtUserGetThreadDesktop()

HDESK APIENTRY NtUserGetThreadDesktop ( DWORD  dwThreadId,
HDESK  hConsoleDesktop 
)

Definition at line 3033 of file desktop.c.

3034{
3035 HDESK hDesk;
3037 PTHREADINFO pti;
3039 PDESKTOP DesktopObject;
3041
3043 TRACE("Enter NtUserGetThreadDesktop\n");
3044
3045 if (!dwThreadId)
3046 {
3048 hDesk = NULL;
3049 goto Quit;
3050 }
3051
3052 /* Validate the Win32 thread and retrieve its information */
3054 if (pti)
3055 {
3056 /* Get the desktop handle of the thread */
3057 hDesk = pti->hdesk;
3058 Process = pti->ppi->peProcess;
3059 }
3060 else if (hConsoleDesktop)
3061 {
3062 /*
3063 * The thread may belong to a console, so attempt to use the provided
3064 * console desktop handle as a fallback. Otherwise this means that the
3065 * thread is either not Win32 or invalid.
3066 */
3067 hDesk = hConsoleDesktop;
3069 }
3070 else
3071 {
3073 hDesk = NULL;
3074 goto Quit;
3075 }
3076
3077 if (!hDesk)
3078 {
3079 ERR("Desktop information of thread 0x%x broken!?\n", dwThreadId);
3080 goto Quit;
3081 }
3082
3084 {
3085 /*
3086 * Just return the handle, since we queried the desktop handle
3087 * of a thread running in the same context.
3088 */
3089 goto Quit;
3090 }
3091
3092 /*
3093 * We could just use the cached rpdesk instead of looking up the handle,
3094 * but it may actually be safer to validate the desktop and get a temporary
3095 * reference to it so that it does not disappear under us (e.g. when the
3096 * desktop is being destroyed) during the operation.
3097 */
3098 /*
3099 * Switch into the context of the thread we are trying to get
3100 * the desktop from, so we can use the handle.
3101 */
3102 KeAttachProcess(&Process->Pcb);
3104 0,
3106 UserMode,
3107 (PVOID*)&DesktopObject,
3110
3111 if (NT_SUCCESS(Status))
3112 {
3113 /*
3114 * Lookup our handle table if we can find a handle to the desktop object.
3115 * If not, create one.
3116 * QUESTION: Do we really need to create a handle in case it doesn't exist??
3117 */
3118 hDesk = IntGetDesktopObjectHandle(DesktopObject);
3119
3120 /* All done, we got a valid handle to the desktop */
3121 ObDereferenceObject(DesktopObject);
3122 }
3123 else
3124 {
3125 /* The handle could not be found, there is nothing to get... */
3126 hDesk = NULL;
3127 }
3128
3129 if (!hDesk)
3130 {
3131 ERR("Could not retrieve or access desktop for thread 0x%x\n", dwThreadId);
3133 }
3134
3135Quit:
3136 TRACE("Leave NtUserGetThreadDesktop, hDesk = 0x%p\n", hDesk);
3137 UserLeave();
3138 return hDesk;
3139}
#define UlongToHandle(ul)
Definition: basetsd.h:97
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:1271
PTHREADINFO FASTCALL IntTID2PTI(HANDLE id)
Definition: misc.c:42
_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 2588 of file desktop.c.

2592{
2594 HDESK Desktop;
2595
2599 UserMode,
2600 NULL,
2601 dwDesiredAccess,
2602 NULL,
2603 (HANDLE*)&Desktop);
2604
2605 if (!NT_SUCCESS(Status))
2606 {
2607 ERR("Failed to open desktop\n");
2609 return NULL;
2610 }
2611
2612 TRACE("Opened desktop %S with handle 0x%p\n", ObjectAttributes->ObjectName->Buffer, Desktop);
2613
2614 return Desktop;
2615}

Referenced by OpenDesktopW().

◆ NtUserOpenInputDesktop()

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

Definition at line 2682 of file desktop.c.

2686{
2687 HDESK hdesk;
2688
2690 TRACE("Enter NtUserOpenInputDesktop gpdeskInputDesktop 0x%p\n", gpdeskInputDesktop);
2691
2692 hdesk = UserOpenInputDesktop(dwFlags, fInherit, dwDesiredAccess);
2693
2694 TRACE("NtUserOpenInputDesktop returning 0x%p\n", hdesk);
2695 UserLeave();
2696 return hdesk;
2697}

Referenced by OpenInputDesktop().

◆ NtUserPaintDesktop()

BOOL APIENTRY NtUserPaintDesktop ( HDC  hDC)

Definition at line 2779 of file desktop.c.

2780{
2781 BOOL Ret;
2782
2784 TRACE("Enter NtUserPaintDesktop\n");
2785
2786 Ret = IntPaintDesktop(hDC);
2787
2788 TRACE("Leave NtUserPaintDesktop, ret=%i\n", Ret);
2789 UserLeave();
2790 return Ret;
2791}

Referenced by PaintDesktop().

◆ NtUserResolveDesktop()

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

Definition at line 2829 of file desktop.c.

2834{
2837 HWINSTA hWinSta = NULL;
2838 HDESK hDesktop = NULL;
2839 UNICODE_STRING CapturedDesktopPath;
2840
2841 /* Allow only the Console Server to perform this operation (via CSRSS) */
2843 return NULL;
2844
2845 /* Get the process object the user handle was referencing */
2849 UserMode,
2850 (PVOID*)&Process,
2851 NULL);
2852 if (!NT_SUCCESS(Status))
2853 return NULL;
2854
2856
2857 _SEH2_TRY
2858 {
2859 /* Probe the handle pointer */
2860 // ProbeForWriteHandle
2861 ProbeForWrite(phWinSta, sizeof(HWINSTA), sizeof(HWINSTA));
2862 }
2864 {
2866 _SEH2_YIELD(goto Quit);
2867 }
2868 _SEH2_END;
2869
2870 /* Capture the user desktop path string */
2871 Status = ProbeAndCaptureUnicodeString(&CapturedDesktopPath,
2872 UserMode,
2873 DesktopPath);
2874 if (!NT_SUCCESS(Status))
2875 goto Quit;
2876
2877 /* Call the internal function */
2879 &CapturedDesktopPath,
2880 bInherit,
2881 &hWinSta,
2882 &hDesktop);
2883 if (!NT_SUCCESS(Status))
2884 {
2885 ERR("IntResolveDesktop failed, Status 0x%08lx\n", Status);
2886 hWinSta = NULL;
2887 hDesktop = NULL;
2888 }
2889
2890 _SEH2_TRY
2891 {
2892 /* Return the window station handle */
2893 *phWinSta = hWinSta;
2894 }
2896 {
2898
2899 /* We failed, close the opened desktop and window station */
2900 if (hDesktop) ObCloseHandle(hDesktop, UserMode);
2901 hDesktop = NULL;
2902 if (hWinSta) ObCloseHandle(hWinSta, UserMode);
2903 }
2904 _SEH2_END;
2905
2906 /* Free the captured string */
2907 ReleaseCapturedUnicodeString(&CapturedDesktopPath, UserMode);
2908
2909Quit:
2910 UserLeave();
2911
2912 /* Dereference the process object */
2914
2915 /* Return the desktop handle */
2916 return hDesktop;
2917}
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:166
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
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:551

Referenced by GuiInit().

◆ NtUserSetThreadDesktop()

BOOL APIENTRY NtUserSetThreadDesktop ( HDESK  hDesktop)

Definition at line 3452 of file desktop.c.

3453{
3454 BOOL ret = FALSE;
3455
3457
3458 // FIXME: IntSetThreadDesktop validates the desktop handle, it should happen
3459 // here too and set the NT error level. Q. Is it necessary to have the validation
3460 // in IntSetThreadDesktop? Is it needed there too?
3461 if (hDesktop || (!hDesktop && PsGetCurrentProcess() == gpepCSRSS))
3462 ret = IntSetThreadDesktop(hDesktop, FALSE);
3463
3464 UserLeave();
3465
3466 return ret;
3467}
int ret

Referenced by SetThreadDesktop().

◆ NtUserSwitchDesktop()

BOOL APIENTRY NtUserSwitchDesktop ( HDESK  hdesk)

Definition at line 2936 of file desktop.c.

2937{
2938 PDESKTOP pdesk;
2940 BOOL bRedrawDesktop;
2941 BOOL Ret = FALSE;
2942
2944 TRACE("Enter NtUserSwitchDesktop(0x%p)\n", hdesk);
2945
2946 Status = IntValidateDesktopHandle(hdesk, UserMode, 0, &pdesk);
2947 if (!NT_SUCCESS(Status))
2948 {
2949 ERR("Validation of desktop handle 0x%p failed\n", hdesk);
2950 goto Exit; // Return FALSE
2951 }
2952
2953 if (PsGetCurrentProcessSessionId() != pdesk->rpwinstaParent->dwSessionId)
2954 {
2955 ObDereferenceObject(pdesk);
2956 ERR("NtUserSwitchDesktop called for a desktop of a different session\n");
2957 goto Exit; // Return FALSE
2958 }
2959
2960 if (pdesk == gpdeskInputDesktop)
2961 {
2962 ObDereferenceObject(pdesk);
2963 WARN("NtUserSwitchDesktop called for active desktop\n");
2964 Ret = TRUE;
2965 goto Exit;
2966 }
2967
2968 /*
2969 * Don't allow applications switch the desktop if it's locked, unless the caller
2970 * is the logon application itself
2971 */
2972 if ((pdesk->rpwinstaParent->Flags & WSS_LOCKED) &&
2974 {
2975 ObDereferenceObject(pdesk);
2976 ERR("Switching desktop 0x%p denied because the window station is locked!\n", hdesk);
2977 goto Exit; // Return FALSE
2978 }
2979
2980 if (pdesk->rpwinstaParent != InputWindowStation)
2981 {
2982 ObDereferenceObject(pdesk);
2983 ERR("Switching desktop 0x%p denied because desktop doesn't belong to the interactive winsta!\n", hdesk);
2984 goto Exit; // Return FALSE
2985 }
2986
2987 /* FIXME: Fail if the process is associated with a secured
2988 desktop such as Winlogon or Screen-Saver */
2989 /* FIXME: Connect to input device */
2990
2991 TRACE("Switching from desktop 0x%p to 0x%p\n", gpdeskInputDesktop, pdesk);
2992
2993 bRedrawDesktop = FALSE;
2994
2995 /* The first time SwitchDesktop is called, gpdeskInputDesktop is NULL */
2996 if (gpdeskInputDesktop != NULL)
2997 {
2999 bRedrawDesktop = TRUE;
3000
3001 /* Hide the previous desktop window */
3003 }
3004
3005 /* Set the active desktop in the desktop's window station. */
3007
3008 /* Set the global state. */
3009 gpdeskInputDesktop = pdesk;
3010
3011 /* Show the new desktop window */
3013
3014 TRACE("SwitchDesktop gpdeskInputDesktop 0x%p\n", gpdeskInputDesktop);
3015 ObDereferenceObject(pdesk);
3016
3017 Ret = TRUE;
3018
3019Exit:
3020 TRACE("Leave NtUserSwitchDesktop, ret=%i\n", Ret);
3021 UserLeave();
3022 return Ret;
3023}
#define WARN(fmt,...)
Definition: debug.h:112
#define WS_VISIBLE
Definition: pedump.c:620
HANDLE gpidLogon
Definition: simplecall.c:15
struct _DESKTOP * ActiveDesktop
Definition: winsta.h:42
NTSTATUS FASTCALL IntHideDesktop(PDESKTOP Desktop)
Definition: desktop.c:1635
NTSTATUS FASTCALL co_IntShowDesktop(PDESKTOP Desktop, ULONG Width, ULONG Height, BOOL bRedraw)
Definition: desktop.c:1617
#define WSS_LOCKED
Definition: winsta.h:7

Referenced by SwitchDesktop().

◆ UserBuildShellHookHwndList()

static HWND *FASTCALL UserBuildShellHookHwndList ( PDESKTOP  Desktop)
static

Definition at line 1651 of file desktop.c.

1652{
1653 ULONG entries=0;
1654 PLIST_ENTRY ListEntry;
1655 PSHELL_HOOK_WINDOW Current;
1656 HWND* list;
1657
1658 /* FIXME: If we save nb elements in desktop, we don't have to loop to find nb entries */
1659 ListEntry = Desktop->ShellHookWindows.Flink;
1660 while (ListEntry != &Desktop->ShellHookWindows)
1661 {
1662 ListEntry = ListEntry->Flink;
1663 entries++;
1664 }
1665
1666 if (!entries) return NULL;
1667
1668 list = ExAllocatePoolWithTag(PagedPool, sizeof(HWND) * (entries + 1), USERTAG_WINDOWLIST); /* alloc one extra for nullterm */
1669 if (list)
1670 {
1671 HWND* cursor = list;
1672
1673 ListEntry = Desktop->ShellHookWindows.Flink;
1674 while (ListEntry != &Desktop->ShellHookWindows)
1675 {
1676 Current = CONTAINING_RECORD(ListEntry, SHELL_HOOK_WINDOW, ListEntry);
1677 ListEntry = ListEntry->Flink;
1678 *cursor++ = Current->hWnd;
1679 }
1680
1681 *cursor = NULL; /* Nullterm list */
1682 }
1683
1684 return list;
1685}
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 1574 of file desktop.c.

1575{
1576 PWND DesktopObject = 0;
1577 HDC DesktopHDC = 0;
1578
1579 /* This can be called from GDI/DX, so acquire the USER lock */
1581
1582 if (DcType == DCTYPE_DIRECT)
1583 {
1584 DesktopObject = UserGetDesktopWindow();
1585 DesktopHDC = (HDC)UserGetWindowDC(DesktopObject);
1586 }
1587 else
1588 {
1589 PMONITOR pMonitor = UserGetPrimaryMonitor();
1590 DesktopHDC = IntGdiCreateDisplayDC(pMonitor->hDev, DcType, bAltDc);
1591 }
1592
1593 UserLeave();
1594
1595 return DesktopHDC;
1596}
@ 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:1386
PMONITOR NTAPI UserGetPrimaryMonitor(VOID)
Definition: monitor.c:102

Referenced by DxEngGetDesktopDC().

◆ UserGetDesktopWindow()

◆ UserGetMessageWindow()

PWND FASTCALL UserGetMessageWindow ( VOID  )

Definition at line 1412 of file desktop.c.

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

◆ UserInitializeDesktop()

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

Definition at line 2260 of file desktop.c.

2261{
2262 PVOID DesktopHeapSystemBase = NULL;
2264 SIZE_T DesktopInfoSize;
2265 ULONG i;
2266
2267 TRACE("UserInitializeDesktop desktop 0x%p with name %wZ\n", pdesk, DesktopName);
2268
2269 RtlZeroMemory(pdesk, sizeof(DESKTOP));
2270
2271 /* Link the desktop with the parent window station */
2272 ObReferenceObject(pwinsta);
2273 pdesk->rpwinstaParent = pwinsta;
2274 InsertTailList(&pwinsta->DesktopListHead, &pdesk->ListEntry);
2275
2276 /* Create the desktop heap */
2277 pdesk->hsectionDesktop = NULL;
2279 &DesktopHeapSystemBase,
2280 HeapSize);
2281 if (pdesk->pheapDesktop == NULL)
2282 {
2283 ERR("Failed to create desktop heap!\n");
2284 return STATUS_NO_MEMORY;
2285 }
2286
2287 /* Create DESKTOPINFO */
2288 DesktopInfoSize = sizeof(DESKTOPINFO) + DesktopName->Length + sizeof(WCHAR);
2289 pdesk->pDeskInfo = RtlAllocateHeap(pdesk->pheapDesktop,
2291 DesktopInfoSize);
2292 if (pdesk->pDeskInfo == NULL)
2293 {
2294 ERR("Failed to create the DESKTOP structure!\n");
2295 return STATUS_NO_MEMORY;
2296 }
2297
2298 /* Initialize the DESKTOPINFO */
2299 pdesk->pDeskInfo->pvDesktopBase = DesktopHeapSystemBase;
2300 pdesk->pDeskInfo->pvDesktopLimit = (PVOID)((ULONG_PTR)DesktopHeapSystemBase + HeapSize);
2302 DesktopName->Buffer,
2303 DesktopName->Length + sizeof(WCHAR));
2304 for (i = 0; i < NB_HOOKS; i++)
2305 {
2307 }
2308
2310 InitializeListHead(&pdesk->PtiList);
2311
2312 return STATUS_SUCCESS;
2313}
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
#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:1692
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:31
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 1525 of file desktop.c.

1526{
1527 *lResult = 0;
1528
1529 switch(Msg)
1530 {
1531 case WM_NCCREATE:
1532 pwnd->fnid |= FNID_MESSAGEWND;
1533 *lResult = (LRESULT)TRUE;
1534 break;
1535 case WM_DESTROY:
1536 pwnd->fnid |= FNID_DESTROY;
1537 break;
1538 default:
1539 ERR("UMWP calling IDWP\n");
1540 *lResult = IntDefWindowProc(pwnd, Msg, wParam, lParam, FALSE);
1541 }
1542
1543 return TRUE; /* We are done. Do not do any callbacks to user mode */
1544}
#define FNID_DESTROY
Definition: ntuser.h:898
LRESULT FASTCALL IntDefWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL Ansi)
Definition: defwnd.c:535
#define WM_DESTROY
Definition: winuser.h:1609

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

◆ UserOpenInputDesktop()

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

Definition at line 2617 of file desktop.c.

2620{
2624 HDESK hdesk = NULL;
2625
2626 if (!gpdeskInputDesktop)
2627 {
2628 return NULL;
2629 }
2630
2631 if (pti->ppi->prpwinsta != InputWindowStation)
2632 {
2633 ERR("Tried to open input desktop from non interactive winsta!\n");
2635 return NULL;
2636 }
2637
2638 if (fInherit) HandleAttributes = OBJ_INHERIT;
2639
2640 /* Create a new handle to the object */
2644 NULL,
2645 dwDesiredAccess,
2647 UserMode,
2648 (PHANDLE)&hdesk);
2649
2650 if (!NT_SUCCESS(Status))
2651 {
2652 ERR("Failed to open input desktop object\n");
2654 }
2655
2656 return hdesk;
2657}
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE _In_ ACCESS_MASK _In_ ULONG HandleAttributes
Definition: obfuncs.h:433

Referenced by DesktopWindowProc(), and NtUserOpenInputDesktop().

◆ UserRedrawDesktop()

VOID APIENTRY UserRedrawDesktop ( VOID  )

Definition at line 1599 of file desktop.c.

1600{
1601 PWND Window = NULL;
1602 PREGION Rgn;
1603
1605 Rgn = IntSysCreateRectpRgnIndirect(&Window->rcWindow);
1606
1608 Rgn,
1611
1612 REGION_Delete(Rgn);
1613}
#define IntSysCreateRectpRgnIndirect(prc)
Definition: region.h:93
Definition: window.c:28
Definition: region.h:8
VOID FASTCALL IntInvalidateWindows(PWND Wnd, PREGION Rgn, ULONG Flags)
Definition: painting.c:642
VOID FASTCALL REGION_Delete(PREGION pRgn)
Definition: region.c:2449
#define RDW_FRAME
Definition: winuser.h:1212

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

Variable Documentation

◆ gDesktopCursor

HCURSOR gDesktopCursor = NULL

Definition at line 38 of file desktop.c.

Referenced by co_IntLoadDefaultCursors(), and DesktopWindowProc().

◆ gdwDesktopSectionSize

DWORD gdwDesktopSectionSize = 512

Definition at line 31 of file desktop.c.

Referenced by UserInitializeDesktop().

◆ gdwNOIOSectionSize

DWORD gdwNOIOSectionSize = 128

Definition at line 32 of file desktop.c.

◆ gpdeskInputDesktop

◆ gpDesktopThreadStartedEvent

PKEVENT gpDesktopThreadStartedEvent = NULL

Definition at line 39 of file desktop.c.

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

◆ gptiDesktopThread

◆ ScreenDeviceContext