Moved and renamed some ReactOS specific macros
[reactos.git] / reactos / ntoskrnl / ex / win32k.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /*
20 * PROJECT: ReactOS kernel
21 * FILE: kernel/ex/win32k.c
22 * PURPOSE: Executive Win32 subsystem support
23 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
24 * UPDATE HISTORY:
25 * 04-06-2001 CSH Created
26 */
27 #include <limits.h>
28 #include <ddk/ntddk.h>
29 #include <internal/ex.h>
30 #include <internal/ob.h>
31 #include <rosrtl/string.h>
32 #include <wchar.h>
33
34 #define NDEBUG
35 #include <internal/debug.h>
36
37 /* DATA **********************************************************************/
38
39 POBJECT_TYPE EXPORTED ExWindowStationObjectType = NULL;
40 POBJECT_TYPE EXPORTED ExDesktopObjectType = NULL;
41
42 static GENERIC_MAPPING ExpWindowStationMapping = {
43 FILE_GENERIC_READ,
44 FILE_GENERIC_WRITE,
45 FILE_GENERIC_EXECUTE,
46 FILE_ALL_ACCESS };
47
48 static GENERIC_MAPPING ExpDesktopMapping = {
49 FILE_GENERIC_READ,
50 FILE_GENERIC_WRITE,
51 FILE_GENERIC_EXECUTE,
52 FILE_ALL_ACCESS };
53
54 /* FUNCTIONS ****************************************************************/
55
56
57 NTSTATUS STDCALL
58 ExpWinStaObjectCreate(PVOID ObjectBody,
59 PVOID Parent,
60 PWSTR RemainingPath,
61 struct _OBJECT_ATTRIBUTES* ObjectAttributes)
62 {
63 PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)ObjectBody;
64 UNICODE_STRING UnicodeString;
65 NTSTATUS Status;
66
67 if (RemainingPath == NULL)
68 {
69 return STATUS_SUCCESS;
70 }
71
72 if (wcschr((RemainingPath + 1), '\\') != NULL)
73 {
74 return STATUS_UNSUCCESSFUL;
75 }
76
77 RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
78
79 DPRINT("Creating window station (0x%X) Name (%wZ)\n", WinSta, &UnicodeString);
80
81 Status = RtlCreateUnicodeString(&WinSta->Name, UnicodeString.Buffer);
82 if (!NT_SUCCESS(Status))
83 {
84 return Status;
85 }
86
87 KeInitializeSpinLock(&WinSta->Lock);
88
89 InitializeListHead(&WinSta->DesktopListHead);
90
91 #if 1
92 WinSta->AtomTable = NULL;
93 #endif
94
95 Status = RtlCreateAtomTable(37, &WinSta->AtomTable);
96 if (!NT_SUCCESS(Status))
97 {
98 RtlFreeUnicodeString(&WinSta->Name);
99 return Status;
100 }
101
102 WinSta->SystemMenuTemplate = (HANDLE)0;
103
104 DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta->Name);
105
106 return STATUS_SUCCESS;
107 }
108
109 VOID STDCALL
110 ExpWinStaObjectDelete(PVOID DeletedObject)
111 {
112 PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)DeletedObject;
113
114 DPRINT("Deleting window station (0x%X)\n", WinSta);
115
116 RtlDestroyAtomTable(WinSta->AtomTable);
117
118 RtlFreeUnicodeString(&WinSta->Name);
119 }
120
121 PVOID
122 ExpWinStaObjectFind(PWINSTATION_OBJECT WinStaObject,
123 PWSTR Name,
124 ULONG Attributes)
125 {
126 PLIST_ENTRY Current;
127 PDESKTOP_OBJECT CurrentObject;
128
129 DPRINT("WinStaObject (0x%X) Name (%wS)\n", WinStaObject, Name);
130
131 if (Name[0] == 0)
132 {
133 return NULL;
134 }
135
136 Current = WinStaObject->DesktopListHead.Flink;
137 while (Current != &WinStaObject->DesktopListHead)
138 {
139 CurrentObject = CONTAINING_RECORD(Current, DESKTOP_OBJECT, ListEntry);
140 DPRINT("Scanning %wZ for %wS\n", &CurrentObject->Name, Name);
141 if (Attributes & OBJ_CASE_INSENSITIVE)
142 {
143 if (_wcsicmp(CurrentObject->Name.Buffer, Name) == 0)
144 {
145 DPRINT("Found desktop at (0x%X)\n", CurrentObject);
146 return CurrentObject;
147 }
148 }
149 else
150 {
151 if (wcscmp(CurrentObject->Name.Buffer, Name) == 0)
152 {
153 DPRINT("Found desktop at (0x%X)\n", CurrentObject);
154 return CurrentObject;
155 }
156 }
157 Current = Current->Flink;
158 }
159
160 DPRINT("Returning NULL\n");
161
162 return NULL;
163 }
164
165 NTSTATUS STDCALL
166 ExpWinStaObjectParse(PVOID Object,
167 PVOID *NextObject,
168 PUNICODE_STRING FullPath,
169 PWSTR *Path,
170 ULONG Attributes)
171 {
172 PVOID FoundObject;
173 NTSTATUS Status;
174 PWSTR End;
175
176 DPRINT("Object (0x%X) Path (0x%X) *Path (%wS)\n", Object, Path, *Path);
177
178 *NextObject = NULL;
179
180 if ((Path == NULL) || ((*Path) == NULL))
181 {
182 return STATUS_SUCCESS;
183 }
184
185 End = wcschr((*Path) + 1, '\\');
186 if (End != NULL)
187 {
188 DPRINT("Name contains illegal characters\n");
189 return STATUS_UNSUCCESSFUL;
190 }
191
192 FoundObject = ExpWinStaObjectFind(Object, (*Path) + 1, Attributes);
193 if (FoundObject == NULL)
194 {
195 DPRINT("Name was not found\n");
196 return STATUS_UNSUCCESSFUL;
197 }
198
199 Status = ObReferenceObjectByPointer(
200 FoundObject,
201 STANDARD_RIGHTS_REQUIRED,
202 NULL,
203 UserMode);
204
205 *NextObject = FoundObject;
206 *Path = NULL;
207
208 return Status;
209 }
210
211 NTSTATUS STDCALL
212 ExpDesktopObjectCreate(PVOID ObjectBody,
213 PVOID Parent,
214 PWSTR RemainingPath,
215 struct _OBJECT_ATTRIBUTES* ObjectAttributes)
216 {
217 PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)ObjectBody;
218 UNICODE_STRING UnicodeString;
219
220 if (RemainingPath == NULL)
221 {
222 return STATUS_SUCCESS;
223 }
224
225 if (wcschr((RemainingPath + 1), '\\') != NULL)
226 {
227 return STATUS_UNSUCCESSFUL;
228 }
229
230 RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
231
232 DPRINT("Creating desktop (0x%X) Name (%wZ)\n", Desktop, &UnicodeString);
233
234 KeInitializeSpinLock(&Desktop->Lock);
235
236 Desktop->WindowStation = (PWINSTATION_OBJECT)Parent;
237
238 /* Put the desktop on the window station's list of associcated desktops */
239 ExInterlockedInsertTailList(
240 &Desktop->WindowStation->DesktopListHead,
241 &Desktop->ListEntry,
242 &Desktop->WindowStation->Lock);
243
244 return RtlCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer);
245 }
246
247 VOID STDCALL
248 ExpDesktopObjectDelete(PVOID DeletedObject)
249 {
250 PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject;
251 KIRQL OldIrql;
252
253 DPRINT("Deleting desktop (0x%X)\n", Desktop);
254
255 /* Remove the desktop from the window station's list of associcated desktops */
256 KeAcquireSpinLock(&Desktop->WindowStation->Lock, &OldIrql);
257 RemoveEntryList(&Desktop->ListEntry);
258 KeReleaseSpinLock(&Desktop->WindowStation->Lock, OldIrql);
259
260 RtlFreeUnicodeString(&Desktop->Name);
261 }
262
263 VOID INIT_FUNCTION
264 ExpWin32kInit(VOID)
265 {
266 /* Create window station object type */
267 ExWindowStationObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
268 if (ExWindowStationObjectType == NULL)
269 {
270 CPRINT("Could not create window station object type\n");
271 KEBUGCHECK(0);
272 }
273
274 ExWindowStationObjectType->Tag = TAG('W', 'I', 'N', 'S');
275 ExWindowStationObjectType->TotalObjects = 0;
276 ExWindowStationObjectType->TotalHandles = 0;
277 ExWindowStationObjectType->MaxObjects = ULONG_MAX;
278 ExWindowStationObjectType->MaxHandles = ULONG_MAX;
279 ExWindowStationObjectType->PagedPoolCharge = 0;
280 ExWindowStationObjectType->NonpagedPoolCharge = sizeof(WINSTATION_OBJECT);
281 ExWindowStationObjectType->Mapping = &ExpWindowStationMapping;
282 ExWindowStationObjectType->Dump = NULL;
283 ExWindowStationObjectType->Open = NULL;
284 ExWindowStationObjectType->Close = NULL;
285 ExWindowStationObjectType->Delete = ExpWinStaObjectDelete;
286 ExWindowStationObjectType->Parse = ExpWinStaObjectParse;
287 ExWindowStationObjectType->Security = NULL;
288 ExWindowStationObjectType->QueryName = NULL;
289 ExWindowStationObjectType->OkayToClose = NULL;
290 ExWindowStationObjectType->Create = ExpWinStaObjectCreate;
291 ExWindowStationObjectType->DuplicationNotify = NULL;
292 RtlRosInitUnicodeStringFromLiteral(&ExWindowStationObjectType->TypeName, L"WindowStation");
293
294 ObpCreateTypeObject(ExWindowStationObjectType);
295
296 /* Create desktop object type */
297 ExDesktopObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
298 if (ExDesktopObjectType == NULL)
299 {
300 CPRINT("Could not create desktop object type\n");
301 KEBUGCHECK(0);
302 }
303
304 ExDesktopObjectType->Tag = TAG('D', 'E', 'S', 'K');
305 ExDesktopObjectType->TotalObjects = 0;
306 ExDesktopObjectType->TotalHandles = 0;
307 ExDesktopObjectType->MaxObjects = ULONG_MAX;
308 ExDesktopObjectType->MaxHandles = ULONG_MAX;
309 ExDesktopObjectType->PagedPoolCharge = 0;
310 ExDesktopObjectType->NonpagedPoolCharge = sizeof(DESKTOP_OBJECT);
311 ExDesktopObjectType->Mapping = &ExpDesktopMapping;
312 ExDesktopObjectType->Dump = NULL;
313 ExDesktopObjectType->Open = NULL;
314 ExDesktopObjectType->Close = NULL;
315 ExDesktopObjectType->Delete = ExpDesktopObjectDelete;
316 ExDesktopObjectType->Parse = NULL;
317 ExDesktopObjectType->Security = NULL;
318 ExDesktopObjectType->QueryName = NULL;
319 ExDesktopObjectType->OkayToClose = NULL;
320 ExDesktopObjectType->Create = ExpDesktopObjectCreate;
321 ExDesktopObjectType->DuplicationNotify = NULL;
322 RtlRosInitUnicodeStringFromLiteral(&ExDesktopObjectType->TypeName, L"Desktop");
323
324 ObpCreateTypeObject(ExDesktopObjectType);
325 }
326
327 /* EOF */