xref: /reactos/win32ss/user/ntuser/desktop.h (revision 2196a06f)
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