1 #pragma once 2 3 typedef struct _DESKTOP 4 { 5 /* Must be the first member */ 6 DWORD dwSessionId; 7 8 PDESKTOPINFO pDeskInfo; 9 LIST_ENTRY ListEntry; 10 /* Pointer to the associated window station. */ 11 struct _WINSTATION_OBJECT *rpwinstaParent; 12 DWORD dwDTFlags; 13 DWORD_PTR dwDesktopId; 14 PMENU spmenuSys; 15 PMENU spmenuDialogSys; 16 PMENU spmenuHScroll; 17 PMENU spmenuVScroll; 18 PWND spwndForeground; 19 PWND spwndTray; 20 PWND spwndMessage; 21 PWND spwndTooltip; 22 PVOID hsectionDesktop; 23 PWIN32HEAP pheapDesktop; 24 ULONG_PTR ulHeapSize; 25 LIST_ENTRY PtiList; 26 27 /* One console input thread per desktop, maintained by CONSRV */ 28 DWORD dwConsoleThreadId; 29 30 /* Use for tracking mouse moves. */ 31 PWND spwndTrack; 32 DWORD htEx; 33 RECT rcMouseHover; 34 DWORD dwMouseHoverTime; 35 36 /* ReactOS */ 37 /* Pointer to the active queue. */ 38 struct _USER_MESSAGE_QUEUE *ActiveMessageQueue; 39 /* Handle of the desktop window. */ 40 HWND DesktopWindow; 41 /* Thread blocking input */ 42 PVOID BlockInputThread; 43 LIST_ENTRY ShellHookWindows; 44 } DESKTOP, *PDESKTOP; 45 46 // Desktop flags 47 #define DF_TME_HOVER 0x00000400 48 #define DF_TME_LEAVE 0x00000800 49 #define DF_HOTTRACK 0x00004000 50 #define DF_DESTROYED 0x00008000 51 #define DF_DESKWNDDESTROYED 0x00010000 52 #define DF_DYING 0x00020000 53 54 // Index offset for Desktop data. Should these be global? 55 #define DT_GWL_PROCESSID 0 56 #define DT_GWL_THREADID 4 57 58 #define DESKTOP_READ STANDARD_RIGHTS_READ | \ 59 DESKTOP_ENUMERATE | \ 60 DESKTOP_READOBJECTS 61 62 #define DESKTOP_WRITE STANDARD_RIGHTS_WRITE | \ 63 DESKTOP_CREATEMENU | \ 64 DESKTOP_CREATEWINDOW | \ 65 DESKTOP_HOOKCONTROL | \ 66 DESKTOP_JOURNALPLAYBACK | \ 67 DESKTOP_JOURNALRECORD | \ 68 DESKTOP_WRITEOBJECTS 69 70 #define DESKTOP_EXECUTE STANDARD_RIGHTS_EXECUTE | \ 71 DESKTOP_SWITCHDESKTOP 72 73 #define DESKTOP_ALL_ACCESS STANDARD_RIGHTS_REQUIRED | \ 74 DESKTOP_CREATEMENU | \ 75 DESKTOP_CREATEWINDOW | \ 76 DESKTOP_ENUMERATE | \ 77 DESKTOP_HOOKCONTROL | \ 78 DESKTOP_JOURNALPLAYBACK | \ 79 DESKTOP_JOURNALRECORD | \ 80 DESKTOP_READOBJECTS | \ 81 DESKTOP_SWITCHDESKTOP | \ 82 DESKTOP_WRITEOBJECTS 83 84 extern PDESKTOP gpdeskInputDesktop; 85 extern PCLS DesktopWindowClass; 86 extern HDC ScreenDeviceContext; 87 extern PTHREADINFO gptiForeground; 88 extern PTHREADINFO gptiDesktopThread; 89 extern PKEVENT gpDesktopThreadStartedEvent; 90 91 typedef struct _SHELL_HOOK_WINDOW 92 { 93 LIST_ENTRY ListEntry; 94 HWND hWnd; 95 } SHELL_HOOK_WINDOW, *PSHELL_HOOK_WINDOW; 96 97 CODE_SEG("INIT") 98 NTSTATUS 99 NTAPI 100 InitDesktopImpl(VOID); 101 102 NTSTATUS 103 APIENTRY 104 IntDesktopObjectParse(IN PVOID ParseObject, 105 IN PVOID ObjectType, 106 IN OUT PACCESS_STATE AccessState, 107 IN KPROCESSOR_MODE AccessMode, 108 IN ULONG Attributes, 109 IN OUT PUNICODE_STRING CompleteName, 110 IN OUT PUNICODE_STRING RemainingName, 111 IN OUT PVOID Context OPTIONAL, 112 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, 113 OUT PVOID *Object); 114 115 NTSTATUS 116 NTAPI 117 IntDesktopObjectDelete( 118 _In_ PVOID Parameters); 119 120 NTSTATUS 121 NTAPI 122 IntDesktopOkToClose( 123 _In_ PVOID Parameters); 124 125 NTSTATUS 126 NTAPI 127 IntDesktopObjectOpen( 128 _In_ PVOID Parameters); 129 130 NTSTATUS 131 NTAPI 132 IntDesktopObjectClose( 133 _In_ PVOID Parameters); 134 135 HDC FASTCALL 136 IntGetScreenDC(VOID); 137 138 HWND FASTCALL 139 IntGetDesktopWindow (VOID); 140 141 PWND FASTCALL 142 UserGetDesktopWindow(VOID); 143 144 HWND FASTCALL 145 IntGetCurrentThreadDesktopWindow(VOID); 146 147 PUSER_MESSAGE_QUEUE FASTCALL 148 IntGetFocusMessageQueue(VOID); 149 150 VOID FASTCALL 151 IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue); 152 153 PDESKTOP FASTCALL 154 IntGetActiveDesktop(VOID); 155 156 NTSTATUS FASTCALL 157 co_IntShowDesktop(PDESKTOP Desktop, ULONG Width, ULONG Height, BOOL Redraw); 158 159 NTSTATUS FASTCALL 160 IntHideDesktop(PDESKTOP Desktop); 161 162 BOOL IntSetThreadDesktop(IN HDESK hDesktop, 163 IN BOOL FreeOnFailure); 164 165 NTSTATUS 166 FASTCALL 167 IntResolveDesktop( 168 IN PEPROCESS Process, 169 IN PUNICODE_STRING DesktopPath, 170 IN BOOL bInherit, 171 OUT HWINSTA* phWinSta, 172 OUT HDESK* phDesktop); 173 174 NTSTATUS FASTCALL 175 IntValidateDesktopHandle( 176 HDESK Desktop, 177 KPROCESSOR_MODE AccessMode, 178 ACCESS_MASK DesiredAccess, 179 PDESKTOP *Object); 180 181 NTSTATUS 182 FASTCALL 183 IntCreateDesktop( 184 OUT HDESK* phDesktop, 185 IN POBJECT_ATTRIBUTES ObjectAttributes, 186 IN KPROCESSOR_MODE AccessMode, 187 IN PUNICODE_STRING lpszDesktopDevice OPTIONAL, 188 IN LPDEVMODEW lpdmw OPTIONAL, 189 IN DWORD dwFlags, 190 IN ACCESS_MASK dwDesiredAccess); 191 192 VOID APIENTRY UserRedrawDesktop(VOID); 193 BOOL IntRegisterShellHookWindow(HWND hWnd); 194 BOOL IntDeRegisterShellHookWindow(HWND hWnd); 195 VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam); 196 HDC FASTCALL UserGetDesktopDC(ULONG,BOOL,BOOL); 197 198 #define IntIsActiveDesktop(Desktop) \ 199 ((Desktop)->rpwinstaParent->ActiveDesktop == (Desktop)) 200 201 HWND FASTCALL IntGetMessageWindow(VOID); 202 PWND FASTCALL UserGetMessageWindow(VOID); 203 204 #if 0 205 static __inline BOOL 206 UserIsDesktopWindow(IN PWND pWnd) 207 { 208 // return (pWnd == UserGetDesktopWindow()); 209 return (pWnd && (pWnd->fnid == FNID_DESKTOP)); 210 } 211 212 static __inline BOOL 213 UserIsMessageWindow(IN PWND pWnd) 214 { 215 // return (pWnd == UserGetMessageWindow()); 216 return (pWnd && (pWnd->fnid == FNID_MESSAGEWND)); 217 } 218 #else 219 220 #define UserIsDesktopWindow(pWnd) \ 221 ((pWnd) && ((pWnd)->fnid == FNID_DESKTOP)) 222 223 #define UserIsMessageWindow(pWnd) \ 224 ((pWnd) && ((pWnd)->fnid == FNID_MESSAGEWND)) 225 226 #endif 227 228 229 static __inline PVOID 230 DesktopHeapAlloc(IN PDESKTOP Desktop, 231 IN SIZE_T Bytes) 232 { 233 /* Desktop heap has no lock, using global user lock instead. */ 234 ASSERT(UserIsEnteredExclusive()); 235 return RtlAllocateHeap(Desktop->pheapDesktop, 236 HEAP_NO_SERIALIZE, 237 Bytes); 238 } 239 240 static __inline BOOL 241 DesktopHeapFree(IN PDESKTOP Desktop, 242 IN PVOID lpMem) 243 { 244 /* Desktop heap has no lock, using global user lock instead. */ 245 ASSERT(UserIsEnteredExclusive()); 246 return RtlFreeHeap(Desktop->pheapDesktop, 247 HEAP_NO_SERIALIZE, 248 lpMem); 249 } 250 251 static __inline PVOID 252 DesktopHeapReAlloc(IN PDESKTOP Desktop, 253 IN PVOID lpMem, 254 IN SIZE_T Bytes) 255 { 256 #if 0 257 /* NOTE: ntoskrnl doesn't export RtlReAllocateHeap... */ 258 return RtlReAllocateHeap(Desktop->pheapDesktop, 259 HEAP_NO_SERIALIZE, 260 lpMem, 261 Bytes); 262 #else 263 SIZE_T PrevSize; 264 PVOID pNew; 265 266 /* Desktop heap has no lock, using global user lock instead. */ 267 ASSERT(UserIsEnteredExclusive()); 268 269 PrevSize = RtlSizeHeap(Desktop->pheapDesktop, 270 HEAP_NO_SERIALIZE, 271 lpMem); 272 273 if (PrevSize == Bytes) 274 return lpMem; 275 276 pNew = RtlAllocateHeap(Desktop->pheapDesktop, 277 HEAP_NO_SERIALIZE, 278 Bytes); 279 if (pNew != NULL) 280 { 281 if (PrevSize < Bytes) 282 Bytes = PrevSize; 283 284 RtlCopyMemory(pNew, 285 lpMem, 286 Bytes); 287 288 RtlFreeHeap(Desktop->pheapDesktop, 289 HEAP_NO_SERIALIZE, 290 lpMem); 291 } 292 293 return pNew; 294 #endif 295 } 296 297 static __inline ULONG_PTR 298 DesktopHeapGetUserDelta(VOID) 299 { 300 PW32HEAP_USER_MAPPING Mapping; 301 PTHREADINFO pti; 302 PPROCESSINFO W32Process; 303 PWIN32HEAP pheapDesktop; 304 ULONG_PTR Delta = 0; 305 306 pti = PsGetCurrentThreadWin32Thread(); 307 if (!pti->rpdesk) 308 return 0; 309 310 pheapDesktop = pti->rpdesk->pheapDesktop; 311 312 W32Process = PsGetCurrentProcessWin32Process(); 313 314 /* 315 * Start the search at the next mapping: skip the first entry 316 * as it must be the global user heap mapping. 317 */ 318 Mapping = W32Process->HeapMappings.Next; 319 while (Mapping != NULL) 320 { 321 if (Mapping->KernelMapping == (PVOID)pheapDesktop) 322 { 323 Delta = (ULONG_PTR)Mapping->KernelMapping - (ULONG_PTR)Mapping->UserMapping; 324 break; 325 } 326 327 Mapping = Mapping->Next; 328 } 329 330 return Delta; 331 } 332 333 static __inline PVOID 334 DesktopHeapAddressToUser(PVOID lpMem) 335 { 336 PW32HEAP_USER_MAPPING Mapping; 337 PPROCESSINFO W32Process; 338 339 W32Process = PsGetCurrentProcessWin32Process(); 340 341 /* 342 * Start the search at the next mapping: skip the first entry 343 * as it must be the global user heap mapping. 344 */ 345 Mapping = W32Process->HeapMappings.Next; 346 while (Mapping != NULL) 347 { 348 if ((ULONG_PTR)lpMem >= (ULONG_PTR)Mapping->KernelMapping && 349 (ULONG_PTR)lpMem < (ULONG_PTR)Mapping->KernelMapping + Mapping->Limit) 350 { 351 return (PVOID)(((ULONG_PTR)lpMem - (ULONG_PTR)Mapping->KernelMapping) + 352 (ULONG_PTR)Mapping->UserMapping); 353 } 354 355 Mapping = Mapping->Next; 356 } 357 358 return NULL; 359 } 360 361 PWND FASTCALL IntGetThreadDesktopWindow(PTHREADINFO); 362 PWND FASTCALL co_GetDesktopWindow(PWND); 363 BOOL FASTCALL IntPaintDesktop(HDC); 364 BOOL FASTCALL DesktopWindowProc(PWND, UINT, WPARAM, LPARAM, LRESULT *); 365 BOOL FASTCALL UserMessageWindowProc(PWND pwnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *lResult); 366 VOID NTAPI DesktopThreadMain(VOID); 367 HDESK UserOpenInputDesktop(DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess); 368 369 /* EOF */ 370