3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
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.
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.
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.
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)
25 * 04-06-2001 CSH Created
28 #include <ddk/ntddk.h>
29 #include <internal/ex.h>
33 #include <internal/debug.h>
35 /* DATA **********************************************************************/
37 POBJECT_TYPE EXPORTED ExWindowStationObjectType = NULL;
38 POBJECT_TYPE EXPORTED ExDesktopObjectType = NULL;
40 static GENERIC_MAPPING ExpWindowStationMapping = {
46 static GENERIC_MAPPING ExpDesktopMapping = {
52 /* FUNCTIONS ****************************************************************/
56 ExpWinStaObjectCreate(PVOID ObjectBody,
59 struct _OBJECT_ATTRIBUTES* ObjectAttributes)
61 PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)ObjectBody;
62 UNICODE_STRING UnicodeString;
65 if (RemainingPath == NULL)
67 return STATUS_SUCCESS;
70 if (wcschr((RemainingPath + 1), '\\') != NULL)
72 return STATUS_UNSUCCESSFUL;
75 RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
77 DPRINT("Creating window station (0x%X) Name (%wZ)\n", WinSta, &UnicodeString);
79 Status = RtlCreateUnicodeString(&WinSta->Name, UnicodeString.Buffer);
80 if (!NT_SUCCESS(Status))
85 KeInitializeSpinLock(&WinSta->Lock);
87 InitializeListHead(&WinSta->DesktopListHead);
90 WinSta->AtomTable = NULL;
93 Status = RtlCreateAtomTable(37, &WinSta->AtomTable);
94 if (!NT_SUCCESS(Status))
96 RtlFreeUnicodeString(&WinSta->Name);
100 WinSta->SystemMenuTemplate = (HANDLE)0;
102 DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta->Name);
104 return STATUS_SUCCESS;
108 ExpWinStaObjectDelete(PVOID DeletedObject)
110 PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)DeletedObject;
112 DPRINT("Deleting window station (0x%X)\n", WinSta);
114 RtlDestroyAtomTable(WinSta->AtomTable);
116 RtlFreeUnicodeString(&WinSta->Name);
120 ExpWinStaObjectFind(PWINSTATION_OBJECT WinStaObject,
125 PDESKTOP_OBJECT CurrentObject;
127 DPRINT("WinStaObject (0x%X) Name (%wS)\n", WinStaObject, Name);
134 Current = WinStaObject->DesktopListHead.Flink;
135 while (Current != &WinStaObject->DesktopListHead)
137 CurrentObject = CONTAINING_RECORD(Current, DESKTOP_OBJECT, ListEntry);
138 DPRINT("Scanning %wZ for %wS\n", &CurrentObject->Name, Name);
139 if (Attributes & OBJ_CASE_INSENSITIVE)
141 if (_wcsicmp(CurrentObject->Name.Buffer, Name) == 0)
143 DPRINT("Found desktop at (0x%X)\n", CurrentObject);
144 return CurrentObject;
149 if (wcscmp(CurrentObject->Name.Buffer, Name) == 0)
151 DPRINT("Found desktop at (0x%X)\n", CurrentObject);
152 return CurrentObject;
155 Current = Current->Flink;
158 DPRINT("Returning NULL\n");
164 ExpWinStaObjectParse(PVOID Object,
166 PUNICODE_STRING FullPath,
174 DPRINT("Object (0x%X) Path (0x%X) *Path (%wS)\n", Object, Path, *Path);
178 if ((Path == NULL) || ((*Path) == NULL))
180 return STATUS_SUCCESS;
183 End = wcschr((*Path) + 1, '\\');
186 DPRINT("Name contains illegal characters\n");
187 return STATUS_UNSUCCESSFUL;
190 FoundObject = ExpWinStaObjectFind(Object, (*Path) + 1, Attributes);
191 if (FoundObject == NULL)
193 DPRINT("Name was not found\n");
194 return STATUS_UNSUCCESSFUL;
197 Status = ObReferenceObjectByPointer(
199 STANDARD_RIGHTS_REQUIRED,
209 ExpDesktopObjectCreate(PVOID ObjectBody,
212 struct _OBJECT_ATTRIBUTES* ObjectAttributes)
214 PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)ObjectBody;
215 UNICODE_STRING UnicodeString;
217 if (RemainingPath == NULL)
219 return STATUS_SUCCESS;
222 if (wcschr((RemainingPath + 1), '\\') != NULL)
224 return STATUS_UNSUCCESSFUL;
227 RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
229 DPRINT("Creating desktop (0x%X) Name (%wZ)\n", Desktop, &UnicodeString);
231 KeInitializeSpinLock(&Desktop->Lock);
233 Desktop->WindowStation = (PWINSTATION_OBJECT)Parent;
235 /* Put the desktop on the window station's list of associcated desktops */
236 ExInterlockedInsertTailList(
237 &Desktop->WindowStation->DesktopListHead,
239 &Desktop->WindowStation->Lock);
241 return RtlCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer);
245 ExpDesktopObjectDelete(PVOID DeletedObject)
247 PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject;
250 DPRINT("Deleting desktop (0x%X)\n", Desktop);
252 /* Remove the desktop from the window station's list of associcated desktops */
253 KeAcquireSpinLock(&Desktop->WindowStation->Lock, &OldIrql);
254 RemoveEntryList(&Desktop->ListEntry);
255 KeReleaseSpinLock(&Desktop->WindowStation->Lock, OldIrql);
257 RtlFreeUnicodeString(&Desktop->Name);
263 /* Create window station object type */
264 ExWindowStationObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
265 if (ExWindowStationObjectType == NULL)
267 CPRINT("Could not create window station object type\n");
271 ExWindowStationObjectType->Tag = TAG('W', 'I', 'N', 'S');
272 ExWindowStationObjectType->TotalObjects = 0;
273 ExWindowStationObjectType->TotalHandles = 0;
274 ExWindowStationObjectType->MaxObjects = ULONG_MAX;
275 ExWindowStationObjectType->MaxHandles = ULONG_MAX;
276 ExWindowStationObjectType->PagedPoolCharge = 0;
277 ExWindowStationObjectType->NonpagedPoolCharge = sizeof(WINSTATION_OBJECT);
278 ExWindowStationObjectType->Mapping = &ExpWindowStationMapping;
279 ExWindowStationObjectType->Dump = NULL;
280 ExWindowStationObjectType->Open = NULL;
281 ExWindowStationObjectType->Close = NULL;
282 ExWindowStationObjectType->Delete = ExpWinStaObjectDelete;
283 ExWindowStationObjectType->Parse = ExpWinStaObjectParse;
284 ExWindowStationObjectType->Security = NULL;
285 ExWindowStationObjectType->QueryName = NULL;
286 ExWindowStationObjectType->OkayToClose = NULL;
287 ExWindowStationObjectType->Create = ExpWinStaObjectCreate;
288 ExWindowStationObjectType->DuplicationNotify = NULL;
289 RtlInitUnicodeStringFromLiteral(&ExWindowStationObjectType->TypeName, L"WindowStation");
291 /* Create desktop object type */
292 ExDesktopObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
293 if (ExDesktopObjectType == NULL)
295 CPRINT("Could not create desktop object type\n");
299 ExDesktopObjectType->Tag = TAG('D', 'E', 'S', 'K');
300 ExDesktopObjectType->TotalObjects = 0;
301 ExDesktopObjectType->TotalHandles = 0;
302 ExDesktopObjectType->MaxObjects = ULONG_MAX;
303 ExDesktopObjectType->MaxHandles = ULONG_MAX;
304 ExDesktopObjectType->PagedPoolCharge = 0;
305 ExDesktopObjectType->NonpagedPoolCharge = sizeof(DESKTOP_OBJECT);
306 ExDesktopObjectType->Mapping = &ExpDesktopMapping;
307 ExDesktopObjectType->Dump = NULL;
308 ExDesktopObjectType->Open = NULL;
309 ExDesktopObjectType->Close = NULL;
310 ExDesktopObjectType->Delete = ExpDesktopObjectDelete;
311 ExDesktopObjectType->Parse = NULL;
312 ExDesktopObjectType->Security = NULL;
313 ExDesktopObjectType->QueryName = NULL;
314 ExDesktopObjectType->OkayToClose = NULL;
315 ExDesktopObjectType->Create = ExpDesktopObjectCreate;
316 ExDesktopObjectType->DuplicationNotify = NULL;
317 RtlInitUnicodeStringFromLiteral(&ExDesktopObjectType->TypeName, L"Desktop");