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>
30 #include <internal/ob.h>
34 #include <internal/debug.h>
36 /* DATA **********************************************************************/
38 POBJECT_TYPE EXPORTED ExWindowStationObjectType
= NULL
;
39 POBJECT_TYPE EXPORTED ExDesktopObjectType
= NULL
;
41 static GENERIC_MAPPING ExpWindowStationMapping
= {
47 static GENERIC_MAPPING ExpDesktopMapping
= {
53 /* FUNCTIONS ****************************************************************/
57 ExpWinStaObjectCreate(PVOID ObjectBody
,
60 struct _OBJECT_ATTRIBUTES
* ObjectAttributes
)
62 PWINSTATION_OBJECT WinSta
= (PWINSTATION_OBJECT
)ObjectBody
;
63 UNICODE_STRING UnicodeString
;
66 if (RemainingPath
== NULL
)
68 return STATUS_SUCCESS
;
71 if (wcschr((RemainingPath
+ 1), '\\') != NULL
)
73 return STATUS_UNSUCCESSFUL
;
76 RtlInitUnicodeString(&UnicodeString
, (RemainingPath
+ 1));
78 DPRINT("Creating window station (0x%X) Name (%wZ)\n", WinSta
, &UnicodeString
);
80 Status
= RtlCreateUnicodeString(&WinSta
->Name
, UnicodeString
.Buffer
);
81 if (!NT_SUCCESS(Status
))
86 KeInitializeSpinLock(&WinSta
->Lock
);
88 InitializeListHead(&WinSta
->DesktopListHead
);
91 WinSta
->AtomTable
= NULL
;
94 Status
= RtlCreateAtomTable(37, &WinSta
->AtomTable
);
95 if (!NT_SUCCESS(Status
))
97 RtlFreeUnicodeString(&WinSta
->Name
);
101 WinSta
->SystemMenuTemplate
= (HANDLE
)0;
103 DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta
->Name
);
105 return STATUS_SUCCESS
;
109 ExpWinStaObjectDelete(PVOID DeletedObject
)
111 PWINSTATION_OBJECT WinSta
= (PWINSTATION_OBJECT
)DeletedObject
;
113 DPRINT("Deleting window station (0x%X)\n", WinSta
);
115 RtlDestroyAtomTable(WinSta
->AtomTable
);
117 RtlFreeUnicodeString(&WinSta
->Name
);
121 ExpWinStaObjectFind(PWINSTATION_OBJECT WinStaObject
,
126 PDESKTOP_OBJECT CurrentObject
;
128 DPRINT("WinStaObject (0x%X) Name (%wS)\n", WinStaObject
, Name
);
135 Current
= WinStaObject
->DesktopListHead
.Flink
;
136 while (Current
!= &WinStaObject
->DesktopListHead
)
138 CurrentObject
= CONTAINING_RECORD(Current
, DESKTOP_OBJECT
, ListEntry
);
139 DPRINT("Scanning %wZ for %wS\n", &CurrentObject
->Name
, Name
);
140 if (Attributes
& OBJ_CASE_INSENSITIVE
)
142 if (_wcsicmp(CurrentObject
->Name
.Buffer
, Name
) == 0)
144 DPRINT("Found desktop at (0x%X)\n", CurrentObject
);
145 return CurrentObject
;
150 if (wcscmp(CurrentObject
->Name
.Buffer
, Name
) == 0)
152 DPRINT("Found desktop at (0x%X)\n", CurrentObject
);
153 return CurrentObject
;
156 Current
= Current
->Flink
;
159 DPRINT("Returning NULL\n");
165 ExpWinStaObjectParse(PVOID Object
,
167 PUNICODE_STRING FullPath
,
175 DPRINT("Object (0x%X) Path (0x%X) *Path (%wS)\n", Object
, Path
, *Path
);
179 if ((Path
== NULL
) || ((*Path
) == NULL
))
181 return STATUS_SUCCESS
;
184 End
= wcschr((*Path
) + 1, '\\');
187 DPRINT("Name contains illegal characters\n");
188 return STATUS_UNSUCCESSFUL
;
191 FoundObject
= ExpWinStaObjectFind(Object
, (*Path
) + 1, Attributes
);
192 if (FoundObject
== NULL
)
194 DPRINT("Name was not found\n");
195 return STATUS_UNSUCCESSFUL
;
198 Status
= ObReferenceObjectByPointer(
200 STANDARD_RIGHTS_REQUIRED
,
204 *NextObject
= FoundObject
;
211 ExpDesktopObjectCreate(PVOID ObjectBody
,
214 struct _OBJECT_ATTRIBUTES
* ObjectAttributes
)
216 PDESKTOP_OBJECT Desktop
= (PDESKTOP_OBJECT
)ObjectBody
;
217 UNICODE_STRING UnicodeString
;
219 if (RemainingPath
== NULL
)
221 return STATUS_SUCCESS
;
224 if (wcschr((RemainingPath
+ 1), '\\') != NULL
)
226 return STATUS_UNSUCCESSFUL
;
229 RtlInitUnicodeString(&UnicodeString
, (RemainingPath
+ 1));
231 DPRINT("Creating desktop (0x%X) Name (%wZ)\n", Desktop
, &UnicodeString
);
233 KeInitializeSpinLock(&Desktop
->Lock
);
235 Desktop
->WindowStation
= (PWINSTATION_OBJECT
)Parent
;
237 /* Put the desktop on the window station's list of associcated desktops */
238 ExInterlockedInsertTailList(
239 &Desktop
->WindowStation
->DesktopListHead
,
241 &Desktop
->WindowStation
->Lock
);
243 return RtlCreateUnicodeString(&Desktop
->Name
, UnicodeString
.Buffer
);
247 ExpDesktopObjectDelete(PVOID DeletedObject
)
249 PDESKTOP_OBJECT Desktop
= (PDESKTOP_OBJECT
)DeletedObject
;
252 DPRINT("Deleting desktop (0x%X)\n", Desktop
);
254 /* Remove the desktop from the window station's list of associcated desktops */
255 KeAcquireSpinLock(&Desktop
->WindowStation
->Lock
, &OldIrql
);
256 RemoveEntryList(&Desktop
->ListEntry
);
257 KeReleaseSpinLock(&Desktop
->WindowStation
->Lock
, OldIrql
);
259 RtlFreeUnicodeString(&Desktop
->Name
);
265 /* Create window station object type */
266 ExWindowStationObjectType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
267 if (ExWindowStationObjectType
== NULL
)
269 CPRINT("Could not create window station object type\n");
273 ExWindowStationObjectType
->Tag
= TAG('W', 'I', 'N', 'S');
274 ExWindowStationObjectType
->TotalObjects
= 0;
275 ExWindowStationObjectType
->TotalHandles
= 0;
276 ExWindowStationObjectType
->MaxObjects
= ULONG_MAX
;
277 ExWindowStationObjectType
->MaxHandles
= ULONG_MAX
;
278 ExWindowStationObjectType
->PagedPoolCharge
= 0;
279 ExWindowStationObjectType
->NonpagedPoolCharge
= sizeof(WINSTATION_OBJECT
);
280 ExWindowStationObjectType
->Mapping
= &ExpWindowStationMapping
;
281 ExWindowStationObjectType
->Dump
= NULL
;
282 ExWindowStationObjectType
->Open
= NULL
;
283 ExWindowStationObjectType
->Close
= NULL
;
284 ExWindowStationObjectType
->Delete
= ExpWinStaObjectDelete
;
285 ExWindowStationObjectType
->Parse
= ExpWinStaObjectParse
;
286 ExWindowStationObjectType
->Security
= NULL
;
287 ExWindowStationObjectType
->QueryName
= NULL
;
288 ExWindowStationObjectType
->OkayToClose
= NULL
;
289 ExWindowStationObjectType
->Create
= ExpWinStaObjectCreate
;
290 ExWindowStationObjectType
->DuplicationNotify
= NULL
;
291 RtlInitUnicodeStringFromLiteral(&ExWindowStationObjectType
->TypeName
, L
"WindowStation");
293 ObpCreateTypeObject(ExWindowStationObjectType
);
295 /* Create desktop object type */
296 ExDesktopObjectType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
297 if (ExDesktopObjectType
== NULL
)
299 CPRINT("Could not create desktop object type\n");
303 ExDesktopObjectType
->Tag
= TAG('D', 'E', 'S', 'K');
304 ExDesktopObjectType
->TotalObjects
= 0;
305 ExDesktopObjectType
->TotalHandles
= 0;
306 ExDesktopObjectType
->MaxObjects
= ULONG_MAX
;
307 ExDesktopObjectType
->MaxHandles
= ULONG_MAX
;
308 ExDesktopObjectType
->PagedPoolCharge
= 0;
309 ExDesktopObjectType
->NonpagedPoolCharge
= sizeof(DESKTOP_OBJECT
);
310 ExDesktopObjectType
->Mapping
= &ExpDesktopMapping
;
311 ExDesktopObjectType
->Dump
= NULL
;
312 ExDesktopObjectType
->Open
= NULL
;
313 ExDesktopObjectType
->Close
= NULL
;
314 ExDesktopObjectType
->Delete
= ExpDesktopObjectDelete
;
315 ExDesktopObjectType
->Parse
= NULL
;
316 ExDesktopObjectType
->Security
= NULL
;
317 ExDesktopObjectType
->QueryName
= NULL
;
318 ExDesktopObjectType
->OkayToClose
= NULL
;
319 ExDesktopObjectType
->Create
= ExpDesktopObjectCreate
;
320 ExDesktopObjectType
->DuplicationNotify
= NULL
;
321 RtlInitUnicodeStringFromLiteral(&ExDesktopObjectType
->TypeName
, L
"Desktop");
323 ObpCreateTypeObject(ExDesktopObjectType
);