xref: /reactos/ntoskrnl/ex/win32k.c (revision 84ccccab)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS Kernel
4  * FILE:            ntoskrnl/ex/win32k.c
5  * PURPOSE:         Executive Win32 Object Support (Desktop/WinStation)
6  * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
7  */
8 
9 #include <ntoskrnl.h>
10 #define NDEBUG
11 #include <debug.h>
12 
13 #if defined (ALLOC_PRAGMA)
14 #pragma alloc_text(INIT, ExpWin32kInit)
15 #endif
16 
17 typedef struct _WIN32_KERNEL_OBJECT_HEADER
18 {
19     ULONG SessionId;
20 } WIN32_KERNEL_OBJECT_HEADER, *PWIN32_KERNEL_OBJECT_HEADER;
21 
22 
23 /* DATA **********************************************************************/
24 
25 POBJECT_TYPE ExWindowStationObjectType = NULL;
26 POBJECT_TYPE ExDesktopObjectType = NULL;
27 
28 GENERIC_MAPPING ExpWindowStationMapping =
29 {
30     STANDARD_RIGHTS_READ,
31     STANDARD_RIGHTS_WRITE,
32     STANDARD_RIGHTS_EXECUTE,
33     STANDARD_RIGHTS_REQUIRED
34 };
35 
36 GENERIC_MAPPING ExpDesktopMapping =
37 {
38     STANDARD_RIGHTS_READ,
39     STANDARD_RIGHTS_WRITE,
40     STANDARD_RIGHTS_EXECUTE,
41     STANDARD_RIGHTS_REQUIRED
42 };
43 
44 PKWIN32_SESSION_CALLOUT ExpWindowStationObjectParse = NULL;
45 PKWIN32_SESSION_CALLOUT ExpWindowStationObjectDelete = NULL;
46 PKWIN32_SESSION_CALLOUT ExpWindowStationObjectOkToClose = NULL;
47 PKWIN32_SESSION_CALLOUT ExpDesktopObjectOkToClose = NULL;
48 PKWIN32_SESSION_CALLOUT ExpDesktopObjectDelete = NULL;
49 PKWIN32_SESSION_CALLOUT ExpDesktopObjectOpen = NULL;
50 PKWIN32_SESSION_CALLOUT ExpDesktopObjectClose = NULL;
51 
52 /* FUNCTIONS ****************************************************************/
53 
54 NTSTATUS
55 NTAPI
56 ExpWin32SessionCallout(
57     _In_ PVOID Object,
58     _In_ PKWIN32_SESSION_CALLOUT CalloutProcedure,
59     _Inout_opt_ PVOID Parameter)
60 {
61     PWIN32_KERNEL_OBJECT_HEADER Win32ObjectHeader;
62     PVOID SessionEntry = NULL;
63     KAPC_STATE ApcState;
64     NTSTATUS Status;
65 
66     /* The objects have a common header. And the kernel accesses it!
67        Thanks MS for this kind of retarded "design"! */
68     Win32ObjectHeader = Object;
69 
70     /* Check if we are not already in the correct session */
71     if (!PsGetCurrentProcess()->ProcessInSession ||
72         (PsGetCurrentProcessSessionId() != Win32ObjectHeader->SessionId))
73     {
74         /* Get the session from the objects session Id */
75         DPRINT("SessionId == %d\n", Win32ObjectHeader->SessionId);
76         SessionEntry = MmGetSessionById(Win32ObjectHeader->SessionId);
77         if (SessionEntry == NULL)
78         {
79             /* The requested session does not even exist! */
80             ASSERT(FALSE);
81             return STATUS_NOT_FOUND;
82         }
83 
84         /* Attach to the session */
85         Status = MmAttachSession(SessionEntry, &ApcState);
86         if (!NT_SUCCESS(Status))
87         {
88             DPRINT1("Could not attach to 0x%p, object %p, callout 0x%p\n",
89                     SessionEntry,
90                     Win32ObjectHeader,
91                     CalloutProcedure);
92 
93             /* Cleanup and return */
94             MmQuitNextSession(SessionEntry);
95             ASSERT(FALSE);
96             return Status;
97         }
98     }
99 
100     /* Call the callout routine */
101     Status = CalloutProcedure(Parameter);
102 
103     /* Check if we have a session */
104     if (SessionEntry != NULL)
105     {
106         /* Detach from the session and quit using it */
107         MmDetachSession(SessionEntry, &ApcState);
108         MmQuitNextSession(SessionEntry);
109     }
110 
111     /* Return the callback status */
112     return Status;
113 }
114 
115 BOOLEAN
116 NTAPI
117 ExpDesktopOkToClose( IN PEPROCESS Process OPTIONAL,
118                      IN PVOID Object,
119                      IN HANDLE Handle,
120                      IN KPROCESSOR_MODE AccessMode)
121 {
122     WIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters;
123     NTSTATUS Status;
124 
125     Parameters.Process = Process;
126     Parameters.Object = Object;
127     Parameters.Handle = Handle;
128     Parameters.PreviousMode = AccessMode;
129 
130     Status = ExpWin32SessionCallout(Object,
131                                     ExpDesktopObjectOkToClose,
132                                     &Parameters);
133 
134     return NT_SUCCESS(Status);
135 }
136 
137 BOOLEAN
138 NTAPI
139 ExpWindowStationOkToClose( IN PEPROCESS Process OPTIONAL,
140                      IN PVOID Object,
141                      IN HANDLE Handle,
142                      IN KPROCESSOR_MODE AccessMode)
143 {
144     WIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters;
145     NTSTATUS Status;
146 
147     Parameters.Process = Process;
148     Parameters.Object = Object;
149     Parameters.Handle = Handle;
150     Parameters.PreviousMode = AccessMode;
151 
152     Status = ExpWin32SessionCallout(Object,
153                                     ExpWindowStationObjectOkToClose,
154                                     &Parameters);
155 
156     return NT_SUCCESS(Status);
157 }
158 
159 VOID
160 NTAPI
161 ExpWinStaObjectDelete(PVOID DeletedObject)
162 {
163     WIN32_DELETEMETHOD_PARAMETERS Parameters;
164 
165     /* Fill out the callback structure */
166     Parameters.Object = DeletedObject;
167 
168     ExpWin32SessionCallout(DeletedObject,
169                            ExpWindowStationObjectDelete,
170                            &Parameters);
171 }
172 
173 NTSTATUS
174 NTAPI
175 ExpWinStaObjectParse(IN PVOID ParseObject,
176                      IN PVOID ObjectType,
177                      IN OUT PACCESS_STATE AccessState,
178                      IN KPROCESSOR_MODE AccessMode,
179                      IN ULONG Attributes,
180                      IN OUT PUNICODE_STRING CompleteName,
181                      IN OUT PUNICODE_STRING RemainingName,
182                      IN OUT PVOID Context OPTIONAL,
183                      IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
184                      OUT PVOID *Object)
185 {
186     WIN32_PARSEMETHOD_PARAMETERS Parameters;
187 
188     /* Fill out the callback structure */
189     Parameters.ParseObject = ParseObject;
190     Parameters.ObjectType = ObjectType;
191     Parameters.AccessState = AccessState;
192     Parameters.AccessMode = AccessMode;
193     Parameters.Attributes = Attributes;
194     Parameters.CompleteName = CompleteName;
195     Parameters.RemainingName = RemainingName;
196     Parameters.Context = Context;
197     Parameters.SecurityQos = SecurityQos;
198     Parameters.Object = Object;
199 
200     return ExpWin32SessionCallout(ParseObject,
201                                   ExpWindowStationObjectParse,
202                                   &Parameters);
203 }
204 VOID
205 NTAPI
206 ExpDesktopDelete(PVOID DeletedObject)
207 {
208     WIN32_DELETEMETHOD_PARAMETERS Parameters;
209 
210     /* Fill out the callback structure */
211     Parameters.Object = DeletedObject;
212 
213     ExpWin32SessionCallout(DeletedObject,
214                            ExpDesktopObjectDelete,
215                            &Parameters);
216 }
217 
218 NTSTATUS
219 NTAPI
220 ExpDesktopOpen(IN OB_OPEN_REASON Reason,
221                IN PEPROCESS Process OPTIONAL,
222                IN PVOID ObjectBody,
223                IN ACCESS_MASK GrantedAccess,
224                IN ULONG HandleCount)
225 {
226     WIN32_OPENMETHOD_PARAMETERS Parameters;
227 
228     Parameters.OpenReason = Reason;
229     Parameters.Process = Process;
230     Parameters.Object = ObjectBody;
231     Parameters.GrantedAccess = GrantedAccess;
232     Parameters.HandleCount = HandleCount;
233 
234     return ExpWin32SessionCallout(ObjectBody,
235                                   ExpDesktopObjectOpen,
236                                   &Parameters);
237 }
238 
239 VOID
240 NTAPI
241 ExpDesktopClose(IN PEPROCESS Process OPTIONAL,
242                 IN PVOID Object,
243                 IN ACCESS_MASK GrantedAccess,
244                 IN ULONG ProcessHandleCount,
245                 IN ULONG SystemHandleCount)
246 {
247     WIN32_CLOSEMETHOD_PARAMETERS Parameters;
248 
249     Parameters.Process = Process;
250     Parameters.Object = Object;
251     Parameters.AccessMask = GrantedAccess;
252     Parameters.ProcessHandleCount = ProcessHandleCount;
253     Parameters.SystemHandleCount = SystemHandleCount;
254 
255     ExpWin32SessionCallout(Object,
256                            ExpDesktopObjectClose,
257                            &Parameters);
258 }
259 
260 BOOLEAN
261 INIT_FUNCTION
262 NTAPI
263 ExpWin32kInit(VOID)
264 {
265     OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
266     UNICODE_STRING Name;
267     NTSTATUS Status;
268     DPRINT("Creating Win32 Object Types\n");
269 
270     /* Create the window station Object Type */
271     RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
272     RtlInitUnicodeString(&Name, L"WindowStation");
273     ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
274     ObjectTypeInitializer.GenericMapping = ExpWindowStationMapping;
275     ObjectTypeInitializer.PoolType = NonPagedPool;
276     ObjectTypeInitializer.DeleteProcedure = ExpWinStaObjectDelete;
277     ObjectTypeInitializer.ParseProcedure = ExpWinStaObjectParse;
278     ObjectTypeInitializer.OkayToCloseProcedure = ExpWindowStationOkToClose;
279     ObjectTypeInitializer.SecurityRequired = TRUE;
280     ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK |
281                                               OBJ_PERMANENT |
282                                               OBJ_EXCLUSIVE;
283     ObjectTypeInitializer.ValidAccessMask = STANDARD_RIGHTS_REQUIRED;
284     Status = ObCreateObjectType(&Name,
285                                 &ObjectTypeInitializer,
286                                 NULL,
287                                 &ExWindowStationObjectType);
288     if (!NT_SUCCESS(Status)) return FALSE;
289 
290     /* Create desktop object type */
291     RtlInitUnicodeString(&Name, L"Desktop");
292     ObjectTypeInitializer.GenericMapping = ExpDesktopMapping;
293     ObjectTypeInitializer.DeleteProcedure = ExpDesktopDelete;
294     ObjectTypeInitializer.ParseProcedure = NULL;
295     ObjectTypeInitializer.OkayToCloseProcedure = ExpDesktopOkToClose;
296     ObjectTypeInitializer.OpenProcedure = ExpDesktopOpen;
297     ObjectTypeInitializer.CloseProcedure = ExpDesktopClose;
298     Status = ObCreateObjectType(&Name,
299                                 &ObjectTypeInitializer,
300                                 NULL,
301                                 &ExDesktopObjectType);
302     if (!NT_SUCCESS(Status)) return FALSE;
303 
304     return TRUE;
305 }
306 
307 /* EOF */
308