#pragma once typedef struct _DESKTOP { /* Must be the first member */ DWORD dwSessionId; PDESKTOPINFO pDeskInfo; LIST_ENTRY ListEntry; /* Pointer to the associated window station. */ struct _WINSTATION_OBJECT *rpwinstaParent; DWORD dwDTFlags; DWORD_PTR dwDesktopId; PMENU spmenuSys; PMENU spmenuDialogSys; PMENU spmenuHScroll; PMENU spmenuVScroll; PWND spwndForeground; PWND spwndTray; PWND spwndMessage; PWND spwndTooltip; PVOID hsectionDesktop; PWIN32HEAP pheapDesktop; ULONG_PTR ulHeapSize; LIST_ENTRY PtiList; /* One console input thread per desktop, maintained by CONSRV */ DWORD dwConsoleThreadId; /* Use for tracking mouse moves. */ PWND spwndTrack; DWORD htEx; RECT rcMouseHover; DWORD dwMouseHoverTime; /* ReactOS */ /* Pointer to the active queue. */ struct _USER_MESSAGE_QUEUE *ActiveMessageQueue; /* Handle of the desktop window. */ HWND DesktopWindow; /* Thread blocking input */ PVOID BlockInputThread; LIST_ENTRY ShellHookWindows; } DESKTOP, *PDESKTOP; // Desktop flags #define DF_TME_HOVER 0x00000400 #define DF_TME_LEAVE 0x00000800 #define DF_HOTTRACK 0x00004000 #define DF_DESTROYED 0x00008000 #define DF_DESKWNDDESTROYED 0x00010000 #define DF_DYING 0x00020000 // Index offset for Desktop data. Should these be global? #define DT_GWL_PROCESSID 0 #define DT_GWL_THREADID 4 #define DESKTOP_READ STANDARD_RIGHTS_READ | \ DESKTOP_ENUMERATE | \ DESKTOP_READOBJECTS #define DESKTOP_WRITE STANDARD_RIGHTS_WRITE | \ DESKTOP_CREATEMENU | \ DESKTOP_CREATEWINDOW | \ DESKTOP_HOOKCONTROL | \ DESKTOP_JOURNALPLAYBACK | \ DESKTOP_JOURNALRECORD | \ DESKTOP_WRITEOBJECTS #define DESKTOP_EXECUTE STANDARD_RIGHTS_EXECUTE | \ DESKTOP_SWITCHDESKTOP #define DESKTOP_ALL_ACCESS STANDARD_RIGHTS_REQUIRED | \ DESKTOP_CREATEMENU | \ DESKTOP_CREATEWINDOW | \ DESKTOP_ENUMERATE | \ DESKTOP_HOOKCONTROL | \ DESKTOP_JOURNALPLAYBACK | \ DESKTOP_JOURNALRECORD | \ DESKTOP_READOBJECTS | \ DESKTOP_SWITCHDESKTOP | \ DESKTOP_WRITEOBJECTS extern PDESKTOP gpdeskInputDesktop; extern PCLS DesktopWindowClass; extern HDC ScreenDeviceContext; extern PTHREADINFO gptiForeground; extern PTHREADINFO gptiDesktopThread; extern PKEVENT gpDesktopThreadStartedEvent; typedef struct _SHELL_HOOK_WINDOW { LIST_ENTRY ListEntry; HWND hWnd; } SHELL_HOOK_WINDOW, *PSHELL_HOOK_WINDOW; INIT_FUNCTION NTSTATUS NTAPI InitDesktopImpl(VOID); 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); HDC FASTCALL IntGetScreenDC(VOID); HWND FASTCALL IntGetDesktopWindow (VOID); PWND FASTCALL UserGetDesktopWindow(VOID); HWND FASTCALL IntGetCurrentThreadDesktopWindow(VOID); PUSER_MESSAGE_QUEUE FASTCALL IntGetFocusMessageQueue(VOID); VOID FASTCALL IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue); PDESKTOP FASTCALL IntGetActiveDesktop(VOID); NTSTATUS FASTCALL co_IntShowDesktop(PDESKTOP Desktop, ULONG Width, ULONG Height, BOOL Redraw); NTSTATUS FASTCALL IntHideDesktop(PDESKTOP Desktop); BOOL IntSetThreadDesktop(IN HDESK hDesktop, IN BOOL FreeOnFailure); 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); 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); VOID APIENTRY UserRedrawDesktop(VOID); BOOL IntRegisterShellHookWindow(HWND hWnd); BOOL IntDeRegisterShellHookWindow(HWND hWnd); VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam); HDC FASTCALL UserGetDesktopDC(ULONG,BOOL,BOOL); #define IntIsActiveDesktop(Desktop) \ ((Desktop)->rpwinstaParent->ActiveDesktop == (Desktop)) HWND FASTCALL IntGetMessageWindow(VOID); PWND FASTCALL UserGetMessageWindow(VOID); #if 0 static __inline BOOL UserIsDesktopWindow(IN PWND pWnd) { // return (pWnd == UserGetDesktopWindow()); return (pWnd && (pWnd->fnid == FNID_DESKTOP)); } static __inline BOOL UserIsMessageWindow(IN PWND pWnd) { // return (pWnd == UserGetMessageWindow()); return (pWnd && (pWnd->fnid == FNID_MESSAGEWND)); } #else #define UserIsDesktopWindow(pWnd) \ ((pWnd) && ((pWnd)->fnid == FNID_DESKTOP)) #define UserIsMessageWindow(pWnd) \ ((pWnd) && ((pWnd)->fnid == FNID_MESSAGEWND)) #endif static __inline PVOID DesktopHeapAlloc(IN PDESKTOP Desktop, IN SIZE_T Bytes) { return RtlAllocateHeap(Desktop->pheapDesktop, HEAP_NO_SERIALIZE, Bytes); } static __inline BOOL DesktopHeapFree(IN PDESKTOP Desktop, IN PVOID lpMem) { return RtlFreeHeap(Desktop->pheapDesktop, HEAP_NO_SERIALIZE, lpMem); } static __inline PVOID DesktopHeapReAlloc(IN PDESKTOP Desktop, IN PVOID lpMem, IN SIZE_T Bytes) { #if 0 /* NOTE: ntoskrnl doesn't export RtlReAllocateHeap... */ return RtlReAllocateHeap(Desktop->pheapDesktop, HEAP_NO_SERIALIZE, lpMem, Bytes); #else SIZE_T PrevSize; PVOID pNew; PrevSize = RtlSizeHeap(Desktop->pheapDesktop, HEAP_NO_SERIALIZE, lpMem); if (PrevSize == Bytes) return lpMem; pNew = RtlAllocateHeap(Desktop->pheapDesktop, HEAP_NO_SERIALIZE, Bytes); if (pNew != NULL) { if (PrevSize < Bytes) Bytes = PrevSize; RtlCopyMemory(pNew, lpMem, Bytes); RtlFreeHeap(Desktop->pheapDesktop, HEAP_NO_SERIALIZE, lpMem); } return pNew; #endif } static __inline ULONG_PTR DesktopHeapGetUserDelta(VOID) { PW32HEAP_USER_MAPPING Mapping; PTHREADINFO pti; PPROCESSINFO W32Process; PWIN32HEAP pheapDesktop; ULONG_PTR Delta = 0; pti = PsGetCurrentThreadWin32Thread(); if (!pti->rpdesk) return 0; pheapDesktop = pti->rpdesk->pheapDesktop; W32Process = PsGetCurrentProcessWin32Process(); /* * Start the search at the next mapping: skip the first entry * as it must be the global user heap mapping. */ Mapping = W32Process->HeapMappings.Next; while (Mapping != NULL) { if (Mapping->KernelMapping == (PVOID)pheapDesktop) { Delta = (ULONG_PTR)Mapping->KernelMapping - (ULONG_PTR)Mapping->UserMapping; break; } Mapping = Mapping->Next; } return Delta; } static __inline PVOID DesktopHeapAddressToUser(PVOID lpMem) { PW32HEAP_USER_MAPPING Mapping; PPROCESSINFO W32Process; W32Process = PsGetCurrentProcessWin32Process(); /* * Start the search at the next mapping: skip the first entry * as it must be the global user heap mapping. */ Mapping = W32Process->HeapMappings.Next; while (Mapping != NULL) { if ((ULONG_PTR)lpMem >= (ULONG_PTR)Mapping->KernelMapping && (ULONG_PTR)lpMem < (ULONG_PTR)Mapping->KernelMapping + Mapping->Limit) { return (PVOID)(((ULONG_PTR)lpMem - (ULONG_PTR)Mapping->KernelMapping) + (ULONG_PTR)Mapping->UserMapping); } Mapping = Mapping->Next; } return NULL; } PWND FASTCALL IntGetThreadDesktopWindow(PTHREADINFO); PWND FASTCALL co_GetDesktopWindow(PWND); BOOL FASTCALL IntPaintDesktop(HDC); BOOL FASTCALL DesktopWindowProc(PWND, UINT, WPARAM, LPARAM, LRESULT *); BOOL FASTCALL UserMessageWindowProc(PWND pwnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *lResult); VOID NTAPI DesktopThreadMain(VOID); HDESK UserOpenInputDesktop(DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess); /* EOF */