[NTOS:MM] Quick fix: use SIZE_T instead of ULONG, because ULONG is 32-bit and on...
[reactos.git] / ntoskrnl / ex / win32k.c
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 */