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 DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta->Name);
102 return STATUS_SUCCESS;
106 ExpWinStaObjectDelete(PVOID DeletedObject)
108 PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)DeletedObject;
110 DPRINT("Deleting window station (0x%X)\n", WinSta);
112 RtlDestroyAtomTable(WinSta->AtomTable);
114 RtlFreeUnicodeString(&WinSta->Name);
118 ExpWinStaObjectFind(PWINSTATION_OBJECT WinStaObject,
123 PDESKTOP_OBJECT CurrentObject;
125 DPRINT("WinStaObject (0x%X) Name (%wS)\n", WinStaObject, Name);
132 Current = WinStaObject->DesktopListHead.Flink;
133 while (Current != &WinStaObject->DesktopListHead)
135 CurrentObject = CONTAINING_RECORD(Current, DESKTOP_OBJECT, ListEntry);
136 DPRINT("Scanning %wZ for %wS\n", &CurrentObject->Name, Name);
137 if (Attributes & OBJ_CASE_INSENSITIVE)
139 if (_wcsicmp(CurrentObject->Name.Buffer, Name) == 0)
141 DPRINT("Found desktop at (0x%X)\n", CurrentObject);
142 return CurrentObject;
147 if (wcscmp(CurrentObject->Name.Buffer, Name) == 0)
149 DPRINT("Found desktop at (0x%X)\n", CurrentObject);
150 return CurrentObject;
153 Current = Current->Flink;
156 DPRINT("Returning NULL\n");
162 ExpWinStaObjectParse(PVOID Object,
164 PUNICODE_STRING FullPath,
172 DPRINT("Object (0x%X) Path (0x%X) *Path (%wS)\n", Object, Path, *Path);
176 if ((Path == NULL) || ((*Path) == NULL))
178 return STATUS_SUCCESS;
181 End = wcschr((*Path) + 1, '\\');
184 DPRINT("Name contains illegal characters\n");
185 return STATUS_UNSUCCESSFUL;
188 FoundObject = ExpWinStaObjectFind(Object, (*Path) + 1, Attributes);
189 if (FoundObject == NULL)
191 DPRINT("Name was not found\n");
192 return STATUS_UNSUCCESSFUL;
195 Status = ObReferenceObjectByPointer(
197 STANDARD_RIGHTS_REQUIRED,
207 ExpDesktopObjectCreate(PVOID ObjectBody,
210 struct _OBJECT_ATTRIBUTES* ObjectAttributes)
212 PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)ObjectBody;
213 UNICODE_STRING UnicodeString;
215 if (RemainingPath == NULL)
217 return STATUS_SUCCESS;
220 if (wcschr((RemainingPath + 1), '\\') != NULL)
222 return STATUS_UNSUCCESSFUL;
225 RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
227 DPRINT("Creating desktop (0x%X) Name (%wZ)\n", Desktop, &UnicodeString);
229 KeInitializeSpinLock(&Desktop->Lock);
231 Desktop->WindowStation = (PWINSTATION_OBJECT)Parent;
233 /* Put the desktop on the window station's list of associcated desktops */
234 ExInterlockedInsertTailList(
235 &Desktop->WindowStation->DesktopListHead,
237 &Desktop->WindowStation->Lock);
239 return RtlCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer);
243 ExpDesktopObjectDelete(PVOID DeletedObject)
245 PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject;
248 DPRINT("Deleting desktop (0x%X)\n", Desktop);
250 /* Remove the desktop from the window station's list of associcated desktops */
251 KeAcquireSpinLock(&Desktop->WindowStation->Lock, &OldIrql);
252 RemoveEntryList(&Desktop->ListEntry);
253 KeReleaseSpinLock(&Desktop->WindowStation->Lock, OldIrql);
255 RtlFreeUnicodeString(&Desktop->Name);
261 /* Create window station object type */
262 ExWindowStationObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
263 if (ExWindowStationObjectType == NULL)
265 CPRINT("Could not create window station object type\n");
269 ExWindowStationObjectType->Tag = TAG('W', 'I', 'N', 'S');
270 ExWindowStationObjectType->TotalObjects = 0;
271 ExWindowStationObjectType->TotalHandles = 0;
272 ExWindowStationObjectType->MaxObjects = ULONG_MAX;
273 ExWindowStationObjectType->MaxHandles = ULONG_MAX;
274 ExWindowStationObjectType->PagedPoolCharge = 0;
275 ExWindowStationObjectType->NonpagedPoolCharge = sizeof(WINSTATION_OBJECT);
276 ExWindowStationObjectType->Mapping = &ExpWindowStationMapping;
277 ExWindowStationObjectType->Dump = NULL;
278 ExWindowStationObjectType->Open = NULL;
279 ExWindowStationObjectType->Close = NULL;
280 ExWindowStationObjectType->Delete = ExpWinStaObjectDelete;
281 ExWindowStationObjectType->Parse = ExpWinStaObjectParse;
282 ExWindowStationObjectType->Security = NULL;
283 ExWindowStationObjectType->QueryName = NULL;
284 ExWindowStationObjectType->OkayToClose = NULL;
285 ExWindowStationObjectType->Create = ExpWinStaObjectCreate;
286 ExWindowStationObjectType->DuplicationNotify = NULL;
287 RtlInitUnicodeStringFromLiteral(&ExWindowStationObjectType->TypeName, L"WindowStation");
289 /* Create desktop object type */
290 ExDesktopObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
291 if (ExDesktopObjectType == NULL)
293 CPRINT("Could not create desktop object type\n");
297 ExDesktopObjectType->Tag = TAG('D', 'E', 'S', 'K');
298 ExDesktopObjectType->TotalObjects = 0;
299 ExDesktopObjectType->TotalHandles = 0;
300 ExDesktopObjectType->MaxObjects = ULONG_MAX;
301 ExDesktopObjectType->MaxHandles = ULONG_MAX;
302 ExDesktopObjectType->PagedPoolCharge = 0;
303 ExDesktopObjectType->NonpagedPoolCharge = sizeof(DESKTOP_OBJECT);
304 ExDesktopObjectType->Mapping = &ExpDesktopMapping;
305 ExDesktopObjectType->Dump = NULL;
306 ExDesktopObjectType->Open = NULL;
307 ExDesktopObjectType->Close = NULL;
308 ExDesktopObjectType->Delete = ExpDesktopObjectDelete;
309 ExDesktopObjectType->Parse = NULL;
310 ExDesktopObjectType->Security = NULL;
311 ExDesktopObjectType->QueryName = NULL;
312 ExDesktopObjectType->OkayToClose = NULL;
313 ExDesktopObjectType->Create = ExpDesktopObjectCreate;
314 ExDesktopObjectType->DuplicationNotify = NULL;
315 RtlInitUnicodeStringFromLiteral(&ExDesktopObjectType->TypeName, L"Desktop");