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