[CRT] Massively improve performance of rand_s
[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 extern PDESKTOP gpdeskInputDesktop;
59 extern PCLS DesktopWindowClass;
60 extern HDC ScreenDeviceContext;
61 extern PTHREADINFO gptiForeground;
62 extern PTHREADINFO gptiDesktopThread;
63 extern PKEVENT gpDesktopThreadStartedEvent;
64
65 typedef struct _SHELL_HOOK_WINDOW
66 {
67 LIST_ENTRY ListEntry;
68 HWND hWnd;
69 } SHELL_HOOK_WINDOW, *PSHELL_HOOK_WINDOW;
70
71 CODE_SEG("INIT")
72 NTSTATUS
73 NTAPI
74 InitDesktopImpl(VOID);
75
76 NTSTATUS
77 APIENTRY
78 IntDesktopObjectParse(IN PVOID ParseObject,
79 IN PVOID ObjectType,
80 IN OUT PACCESS_STATE AccessState,
81 IN KPROCESSOR_MODE AccessMode,
82 IN ULONG Attributes,
83 IN OUT PUNICODE_STRING CompleteName,
84 IN OUT PUNICODE_STRING RemainingName,
85 IN OUT PVOID Context OPTIONAL,
86 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
87 OUT PVOID *Object);
88
89 NTSTATUS
90 NTAPI
91 IntDesktopObjectDelete(
92 _In_ PVOID Parameters);
93
94 NTSTATUS
95 NTAPI
96 IntDesktopOkToClose(
97 _In_ PVOID Parameters);
98
99 NTSTATUS
100 NTAPI
101 IntDesktopObjectOpen(
102 _In_ PVOID Parameters);
103
104 NTSTATUS
105 NTAPI
106 IntDesktopObjectClose(
107 _In_ PVOID Parameters);
108
109 HDC FASTCALL
110 IntGetScreenDC(VOID);
111
112 HWND FASTCALL
113 IntGetDesktopWindow (VOID);
114
115 PWND FASTCALL
116 UserGetDesktopWindow(VOID);
117
118 HWND FASTCALL
119 IntGetCurrentThreadDesktopWindow(VOID);
120
121 PUSER_MESSAGE_QUEUE FASTCALL
122 IntGetFocusMessageQueue(VOID);
123
124 VOID FASTCALL
125 IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue);
126
127 PDESKTOP FASTCALL
128 IntGetActiveDesktop(VOID);
129
130 NTSTATUS FASTCALL
131 co_IntShowDesktop(PDESKTOP Desktop, ULONG Width, ULONG Height, BOOL Redraw);
132
133 NTSTATUS FASTCALL
134 IntHideDesktop(PDESKTOP Desktop);
135
136 BOOL IntSetThreadDesktop(IN HDESK hDesktop,
137 IN BOOL FreeOnFailure);
138
139 NTSTATUS
140 FASTCALL
141 IntResolveDesktop(
142 IN PEPROCESS Process,
143 IN PUNICODE_STRING DesktopPath,
144 IN BOOL bInherit,
145 OUT HWINSTA* phWinSta,
146 OUT HDESK* phDesktop);
147
148 NTSTATUS FASTCALL
149 IntValidateDesktopHandle(
150 HDESK Desktop,
151 KPROCESSOR_MODE AccessMode,
152 ACCESS_MASK DesiredAccess,
153 PDESKTOP *Object);
154
155 NTSTATUS
156 FASTCALL
157 IntCreateDesktop(
158 OUT HDESK* phDesktop,
159 IN POBJECT_ATTRIBUTES ObjectAttributes,
160 IN KPROCESSOR_MODE AccessMode,
161 IN PUNICODE_STRING lpszDesktopDevice OPTIONAL,
162 IN LPDEVMODEW lpdmw OPTIONAL,
163 IN DWORD dwFlags,
164 IN ACCESS_MASK dwDesiredAccess);
165
166 VOID APIENTRY UserRedrawDesktop(VOID);
167 BOOL IntRegisterShellHookWindow(HWND hWnd);
168 BOOL IntDeRegisterShellHookWindow(HWND hWnd);
169 VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam);
170 HDC FASTCALL UserGetDesktopDC(ULONG,BOOL,BOOL);
171
172 #define IntIsActiveDesktop(Desktop) \
173 ((Desktop)->rpwinstaParent->ActiveDesktop == (Desktop))
174
175 HWND FASTCALL IntGetMessageWindow(VOID);
176 PWND FASTCALL UserGetMessageWindow(VOID);
177
178 #if 0
179 static __inline BOOL
180 UserIsDesktopWindow(IN PWND pWnd)
181 {
182 // return (pWnd == UserGetDesktopWindow());
183 return (pWnd && (pWnd->fnid == FNID_DESKTOP));
184 }
185
186 static __inline BOOL
187 UserIsMessageWindow(IN PWND pWnd)
188 {
189 // return (pWnd == UserGetMessageWindow());
190 return (pWnd && (pWnd->fnid == FNID_MESSAGEWND));
191 }
192 #else
193
194 #define UserIsDesktopWindow(pWnd) \
195 ((pWnd) && ((pWnd)->fnid == FNID_DESKTOP))
196
197 #define UserIsMessageWindow(pWnd) \
198 ((pWnd) && ((pWnd)->fnid == FNID_MESSAGEWND))
199
200 #endif
201
202
203 static __inline PVOID
204 DesktopHeapAlloc(IN PDESKTOP Desktop,
205 IN SIZE_T Bytes)
206 {
207 /* Desktop heap has no lock, using global user lock instead. */
208 ASSERT(UserIsEnteredExclusive());
209 return RtlAllocateHeap(Desktop->pheapDesktop,
210 HEAP_NO_SERIALIZE,
211 Bytes);
212 }
213
214 static __inline BOOL
215 DesktopHeapFree(IN PDESKTOP Desktop,
216 IN PVOID lpMem)
217 {
218 /* Desktop heap has no lock, using global user lock instead. */
219 ASSERT(UserIsEnteredExclusive());
220 return RtlFreeHeap(Desktop->pheapDesktop,
221 HEAP_NO_SERIALIZE,
222 lpMem);
223 }
224
225 static __inline PVOID
226 DesktopHeapReAlloc(IN PDESKTOP Desktop,
227 IN PVOID lpMem,
228 IN SIZE_T Bytes)
229 {
230 #if 0
231 /* NOTE: ntoskrnl doesn't export RtlReAllocateHeap... */
232 return RtlReAllocateHeap(Desktop->pheapDesktop,
233 HEAP_NO_SERIALIZE,
234 lpMem,
235 Bytes);
236 #else
237 SIZE_T PrevSize;
238 PVOID pNew;
239
240 /* Desktop heap has no lock, using global user lock instead. */
241 ASSERT(UserIsEnteredExclusive());
242
243 PrevSize = RtlSizeHeap(Desktop->pheapDesktop,
244 HEAP_NO_SERIALIZE,
245 lpMem);
246
247 if (PrevSize == Bytes)
248 return lpMem;
249
250 pNew = RtlAllocateHeap(Desktop->pheapDesktop,
251 HEAP_NO_SERIALIZE,
252 Bytes);
253 if (pNew != NULL)
254 {
255 if (PrevSize < Bytes)
256 Bytes = PrevSize;
257
258 RtlCopyMemory(pNew,
259 lpMem,
260 Bytes);
261
262 RtlFreeHeap(Desktop->pheapDesktop,
263 HEAP_NO_SERIALIZE,
264 lpMem);
265 }
266
267 return pNew;
268 #endif
269 }
270
271 static __inline ULONG_PTR
272 DesktopHeapGetUserDelta(VOID)
273 {
274 PW32HEAP_USER_MAPPING Mapping;
275 PTHREADINFO pti;
276 PPROCESSINFO W32Process;
277 PWIN32HEAP pheapDesktop;
278 ULONG_PTR Delta = 0;
279
280 pti = PsGetCurrentThreadWin32Thread();
281 if (!pti->rpdesk)
282 return 0;
283
284 pheapDesktop = pti->rpdesk->pheapDesktop;
285
286 W32Process = PsGetCurrentProcessWin32Process();
287
288 /*
289 * Start the search at the next mapping: skip the first entry
290 * as it must be the global user heap mapping.
291 */
292 Mapping = W32Process->HeapMappings.Next;
293 while (Mapping != NULL)
294 {
295 if (Mapping->KernelMapping == (PVOID)pheapDesktop)
296 {
297 Delta = (ULONG_PTR)Mapping->KernelMapping - (ULONG_PTR)Mapping->UserMapping;
298 break;
299 }
300
301 Mapping = Mapping->Next;
302 }
303
304 return Delta;
305 }
306
307 static __inline PVOID
308 DesktopHeapAddressToUser(PVOID lpMem)
309 {
310 PW32HEAP_USER_MAPPING Mapping;
311 PPROCESSINFO W32Process;
312
313 W32Process = PsGetCurrentProcessWin32Process();
314
315 /*
316 * Start the search at the next mapping: skip the first entry
317 * as it must be the global user heap mapping.
318 */
319 Mapping = W32Process->HeapMappings.Next;
320 while (Mapping != NULL)
321 {
322 if ((ULONG_PTR)lpMem >= (ULONG_PTR)Mapping->KernelMapping &&
323 (ULONG_PTR)lpMem < (ULONG_PTR)Mapping->KernelMapping + Mapping->Limit)
324 {
325 return (PVOID)(((ULONG_PTR)lpMem - (ULONG_PTR)Mapping->KernelMapping) +
326 (ULONG_PTR)Mapping->UserMapping);
327 }
328
329 Mapping = Mapping->Next;
330 }
331
332 return NULL;
333 }
334
335 PWND FASTCALL IntGetThreadDesktopWindow(PTHREADINFO);
336 PWND FASTCALL co_GetDesktopWindow(PWND);
337 BOOL FASTCALL IntPaintDesktop(HDC);
338 BOOL FASTCALL DesktopWindowProc(PWND, UINT, WPARAM, LPARAM, LRESULT *);
339 BOOL FASTCALL UserMessageWindowProc(PWND pwnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *lResult);
340 VOID NTAPI DesktopThreadMain(VOID);
341 HDESK UserOpenInputDesktop(DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess);
342
343 /* EOF */