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>
31 #include <rosrtl/string.h>
35 #include <internal/debug.h>
37 /* DATA **********************************************************************/
39 POBJECT_TYPE EXPORTED ExWindowStationObjectType
= NULL
;
40 POBJECT_TYPE EXPORTED ExDesktopObjectType
= NULL
;
42 static GENERIC_MAPPING ExpWindowStationMapping
= {
48 static GENERIC_MAPPING ExpDesktopMapping
= {
54 /* FUNCTIONS ****************************************************************/
58 ExpWinStaObjectCreate(PVOID ObjectBody
,
61 struct _OBJECT_ATTRIBUTES
* ObjectAttributes
)
63 PWINSTATION_OBJECT WinSta
= (PWINSTATION_OBJECT
)ObjectBody
;
64 UNICODE_STRING UnicodeString
;
67 if (RemainingPath
== NULL
)
69 return STATUS_SUCCESS
;
72 if (wcschr((RemainingPath
+ 1), '\\') != NULL
)
74 return STATUS_UNSUCCESSFUL
;
77 RtlInitUnicodeString(&UnicodeString
, (RemainingPath
+ 1));
79 DPRINT("Creating window station (0x%X) Name (%wZ)\n", WinSta
, &UnicodeString
);
81 Status
= RtlCreateUnicodeString(&WinSta
->Name
, UnicodeString
.Buffer
);
82 if (!NT_SUCCESS(Status
))
87 KeInitializeSpinLock(&WinSta
->Lock
);
89 InitializeListHead(&WinSta
->DesktopListHead
);
92 WinSta
->AtomTable
= NULL
;
95 Status
= RtlCreateAtomTable(37, &WinSta
->AtomTable
);
96 if (!NT_SUCCESS(Status
))
98 RtlFreeUnicodeString(&WinSta
->Name
);
102 WinSta
->SystemMenuTemplate
= (HANDLE
)0;
104 DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta
->Name
);
106 return STATUS_SUCCESS
;
110 ExpWinStaObjectDelete(PVOID DeletedObject
)
112 PWINSTATION_OBJECT WinSta
= (PWINSTATION_OBJECT
)DeletedObject
;
114 DPRINT("Deleting window station (0x%X)\n", WinSta
);
116 RtlDestroyAtomTable(WinSta
->AtomTable
);
118 RtlFreeUnicodeString(&WinSta
->Name
);
122 ExpWinStaObjectFind(PWINSTATION_OBJECT WinStaObject
,
127 PDESKTOP_OBJECT CurrentObject
;
129 DPRINT("WinStaObject (0x%X) Name (%wS)\n", WinStaObject
, Name
);
136 Current
= WinStaObject
->DesktopListHead
.Flink
;
137 while (Current
!= &WinStaObject
->DesktopListHead
)
139 CurrentObject
= CONTAINING_RECORD(Current
, DESKTOP_OBJECT
, ListEntry
);
140 DPRINT("Scanning %wZ for %wS\n", &CurrentObject
->Name
, Name
);
141 if (Attributes
& OBJ_CASE_INSENSITIVE
)
143 if (_wcsicmp(CurrentObject
->Name
.Buffer
, Name
) == 0)
145 DPRINT("Found desktop at (0x%X)\n", CurrentObject
);
146 return CurrentObject
;
151 if (wcscmp(CurrentObject
->Name
.Buffer
, Name
) == 0)
153 DPRINT("Found desktop at (0x%X)\n", CurrentObject
);
154 return CurrentObject
;
157 Current
= Current
->Flink
;
160 DPRINT("Returning NULL\n");
166 ExpWinStaObjectParse(PVOID Object
,
168 PUNICODE_STRING FullPath
,
176 DPRINT("Object (0x%X) Path (0x%X) *Path (%wS)\n", Object
, Path
, *Path
);
180 if ((Path
== NULL
) || ((*Path
) == NULL
))
182 return STATUS_SUCCESS
;
185 End
= wcschr((*Path
) + 1, '\\');
188 DPRINT("Name contains illegal characters\n");
189 return STATUS_UNSUCCESSFUL
;
192 FoundObject
= ExpWinStaObjectFind(Object
, (*Path
) + 1, Attributes
);
193 if (FoundObject
== NULL
)
195 DPRINT("Name was not found\n");
196 return STATUS_UNSUCCESSFUL
;
199 Status
= ObReferenceObjectByPointer(
201 STANDARD_RIGHTS_REQUIRED
,
205 *NextObject
= FoundObject
;
212 ExpDesktopObjectCreate(PVOID ObjectBody
,
215 struct _OBJECT_ATTRIBUTES
* ObjectAttributes
)
217 PDESKTOP_OBJECT Desktop
= (PDESKTOP_OBJECT
)ObjectBody
;
218 UNICODE_STRING UnicodeString
;
220 if (RemainingPath
== NULL
)
222 return STATUS_SUCCESS
;
225 if (wcschr((RemainingPath
+ 1), '\\') != NULL
)
227 return STATUS_UNSUCCESSFUL
;
230 RtlInitUnicodeString(&UnicodeString
, (RemainingPath
+ 1));
232 DPRINT("Creating desktop (0x%X) Name (%wZ)\n", Desktop
, &UnicodeString
);
234 KeInitializeSpinLock(&Desktop
->Lock
);
236 Desktop
->WindowStation
= (PWINSTATION_OBJECT
)Parent
;
238 /* Put the desktop on the window station's list of associcated desktops */
239 ExInterlockedInsertTailList(
240 &Desktop
->WindowStation
->DesktopListHead
,
242 &Desktop
->WindowStation
->Lock
);
244 return RtlCreateUnicodeString(&Desktop
->Name
, UnicodeString
.Buffer
);
248 ExpDesktopObjectDelete(PVOID DeletedObject
)
250 PDESKTOP_OBJECT Desktop
= (PDESKTOP_OBJECT
)DeletedObject
;
253 DPRINT("Deleting desktop (0x%X)\n", Desktop
);
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
);
260 RtlFreeUnicodeString(&Desktop
->Name
);
266 /* Create window station object type */
267 ExWindowStationObjectType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
268 if (ExWindowStationObjectType
== NULL
)
270 CPRINT("Could not create window station object type\n");
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");
294 ObpCreateTypeObject(ExWindowStationObjectType
);
296 /* Create desktop object type */
297 ExDesktopObjectType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
298 if (ExDesktopObjectType
== NULL
)
300 CPRINT("Could not create desktop object type\n");
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");
324 ObpCreateTypeObject(ExDesktopObjectType
);