[WIN32K:NTUSER] Assert global user lock is held exclusively when using global & deskt...
[reactos.git] / win32ss / user / ntuser / desktop.h
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 */