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
30 #include <internal/debug.h>
32 /* DATA **********************************************************************/
34 POBJECT_TYPE EXPORTED ExWindowStationObjectType
= NULL
;
35 POBJECT_TYPE EXPORTED ExDesktopObjectType
= NULL
;
37 static GENERIC_MAPPING ExpWindowStationMapping
= {
43 static GENERIC_MAPPING ExpDesktopMapping
= {
49 /* FUNCTIONS ****************************************************************/
53 ExpWinStaObjectCreate(PVOID ObjectBody
,
56 struct _OBJECT_ATTRIBUTES
* ObjectAttributes
)
58 PWINSTATION_OBJECT WinSta
= (PWINSTATION_OBJECT
)ObjectBody
;
59 UNICODE_STRING UnicodeString
;
62 if (RemainingPath
== NULL
)
64 return STATUS_SUCCESS
;
67 if (wcschr((RemainingPath
+ 1), '\\') != NULL
)
69 return STATUS_UNSUCCESSFUL
;
72 RtlInitUnicodeString(&UnicodeString
, (RemainingPath
+ 1));
74 DPRINT("Creating window station (0x%X) Name (%wZ)\n", WinSta
, &UnicodeString
);
76 Status
= RtlCreateUnicodeString(&WinSta
->Name
, UnicodeString
.Buffer
);
77 if (!NT_SUCCESS(Status
))
82 KeInitializeSpinLock(&WinSta
->Lock
);
84 InitializeListHead(&WinSta
->DesktopListHead
);
87 WinSta
->AtomTable
= NULL
;
90 Status
= RtlCreateAtomTable(37, &WinSta
->AtomTable
);
91 if (!NT_SUCCESS(Status
))
93 RtlFreeUnicodeString(&WinSta
->Name
);
97 WinSta
->SystemMenuTemplate
= (HANDLE
)0;
99 DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta
->Name
);
101 return STATUS_SUCCESS
;
105 ExpWinStaObjectDelete(PVOID DeletedObject
)
107 PWINSTATION_OBJECT WinSta
= (PWINSTATION_OBJECT
)DeletedObject
;
109 DPRINT("Deleting window station (0x%X)\n", WinSta
);
111 RtlDestroyAtomTable(WinSta
->AtomTable
);
113 RtlFreeUnicodeString(&WinSta
->Name
);
117 ExpWinStaObjectFind(PWINSTATION_OBJECT WinStaObject
,
122 PDESKTOP_OBJECT CurrentObject
;
124 DPRINT("WinStaObject (0x%X) Name (%wS)\n", WinStaObject
, Name
);
131 Current
= WinStaObject
->DesktopListHead
.Flink
;
132 while (Current
!= &WinStaObject
->DesktopListHead
)
134 CurrentObject
= CONTAINING_RECORD(Current
, DESKTOP_OBJECT
, ListEntry
);
135 DPRINT("Scanning %wZ for %wS\n", &CurrentObject
->Name
, Name
);
136 if (Attributes
& OBJ_CASE_INSENSITIVE
)
138 if (_wcsicmp(CurrentObject
->Name
.Buffer
, Name
) == 0)
140 DPRINT("Found desktop at (0x%X)\n", CurrentObject
);
141 return CurrentObject
;
146 if (wcscmp(CurrentObject
->Name
.Buffer
, Name
) == 0)
148 DPRINT("Found desktop at (0x%X)\n", CurrentObject
);
149 return CurrentObject
;
152 Current
= Current
->Flink
;
155 DPRINT("Returning NULL\n");
161 ExpWinStaObjectParse(PVOID Object
,
163 PUNICODE_STRING FullPath
,
171 DPRINT("Object (0x%X) Path (0x%X) *Path (%wS)\n", Object
, Path
, *Path
);
175 if ((Path
== NULL
) || ((*Path
) == NULL
))
177 return STATUS_SUCCESS
;
180 End
= wcschr((*Path
) + 1, '\\');
183 DPRINT("Name contains illegal characters\n");
184 return STATUS_UNSUCCESSFUL
;
187 FoundObject
= ExpWinStaObjectFind(Object
, (*Path
) + 1, Attributes
);
188 if (FoundObject
== NULL
)
190 DPRINT("Name was not found\n");
191 return STATUS_UNSUCCESSFUL
;
194 Status
= ObReferenceObjectByPointer(
196 STANDARD_RIGHTS_REQUIRED
,
200 *NextObject
= FoundObject
;
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 RtlRosInitUnicodeStringFromLiteral(&ExWindowStationObjectType
->TypeName
, L
"WindowStation");
289 ObpCreateTypeObject(ExWindowStationObjectType
);
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 RtlRosInitUnicodeStringFromLiteral(&ExDesktopObjectType
->TypeName
, L
"Desktop");
319 ObpCreateTypeObject(ExDesktopObjectType
);