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>
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 Status
= ObReferenceObjectByPointer(
102 STANDARD_RIGHTS_REQUIRED
,
105 if (!NT_SUCCESS(Status
))
107 RtlDestroyAtomTable(WinSta
->AtomTable
);
108 RtlFreeUnicodeString(&WinSta
->Name
);
115 (RemainingPath
+ 1));
116 ObDereferenceObject(Parent
);
118 DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta
->Name
);
120 return STATUS_SUCCESS
;
124 ExpWinStaObjectDelete(PVOID DeletedObject
)
126 PWINSTATION_OBJECT WinSta
= (PWINSTATION_OBJECT
)DeletedObject
;
128 DPRINT("Deleting window station (0x%X)\n", WinSta
);
130 RtlDestroyAtomTable(WinSta
->AtomTable
);
132 RtlFreeUnicodeString(&WinSta
->Name
);
136 ExpWinStaObjectFind(PWINSTATION_OBJECT WinStaObject
,
141 PDESKTOP_OBJECT CurrentObject
;
143 DPRINT("WinStaObject (0x%X) Name (%wS)\n", WinStaObject
, Name
);
150 Current
= WinStaObject
->DesktopListHead
.Flink
;
151 while (Current
!= &WinStaObject
->DesktopListHead
)
153 CurrentObject
= CONTAINING_RECORD(Current
, DESKTOP_OBJECT
, ListEntry
);
154 DPRINT("Scanning %wZ for %wS\n", &CurrentObject
->Name
, Name
);
155 if (Attributes
& OBJ_CASE_INSENSITIVE
)
157 if (_wcsicmp(CurrentObject
->Name
.Buffer
, Name
) == 0)
159 DPRINT("Found desktop at (0x%X)\n", CurrentObject
);
160 return CurrentObject
;
165 if (wcscmp(CurrentObject
->Name
.Buffer
, Name
) == 0)
167 DPRINT("Found desktop at (0x%X)\n", CurrentObject
);
168 return CurrentObject
;
171 Current
= Current
->Flink
;
174 DPRINT("Returning NULL\n");
180 ExpWinStaObjectParse(PVOID Object
,
182 PUNICODE_STRING FullPath
,
184 POBJECT_TYPE ObjectType
,
191 DPRINT("Object (0x%X) Path (0x%X) *Path (%wS)\n", Object
, Path
, *Path
);
195 if ((Path
== NULL
) || ((*Path
) == NULL
))
197 return STATUS_SUCCESS
;
200 End
= wcschr((*Path
) + 1, '\\');
203 DPRINT("Name contains illegal characters\n");
204 return STATUS_UNSUCCESSFUL
;
207 FoundObject
= ExpWinStaObjectFind(Object
, (*Path
) + 1, Attributes
);
208 if (FoundObject
== NULL
)
210 DPRINT("Name was not found\n");
211 return STATUS_UNSUCCESSFUL
;
214 Status
= ObReferenceObjectByPointer(
216 STANDARD_RIGHTS_REQUIRED
,
226 ExpDesktopObjectCreate(PVOID ObjectBody
,
229 struct _OBJECT_ATTRIBUTES
* ObjectAttributes
)
231 PDESKTOP_OBJECT Desktop
= (PDESKTOP_OBJECT
)ObjectBody
;
232 UNICODE_STRING UnicodeString
;
234 if (RemainingPath
== NULL
)
236 return STATUS_SUCCESS
;
239 if (wcschr((RemainingPath
+ 1), '\\') != NULL
)
241 return STATUS_UNSUCCESSFUL
;
244 RtlInitUnicodeString(&UnicodeString
, (RemainingPath
+ 1));
246 DPRINT("Creating desktop (0x%X) Name (%wZ)\n", Desktop
, &UnicodeString
);
248 KeInitializeSpinLock(&Desktop
->Lock
);
250 Desktop
->WindowStation
= (PWINSTATION_OBJECT
)Parent
;
252 /* Put the desktop on the window station's list of associcated desktops */
253 ExInterlockedInsertTailList(
254 &Desktop
->WindowStation
->DesktopListHead
,
256 &Desktop
->WindowStation
->Lock
);
258 return RtlCreateUnicodeString(&Desktop
->Name
, UnicodeString
.Buffer
);
262 ExpDesktopObjectDelete(PVOID DeletedObject
)
264 PDESKTOP_OBJECT Desktop
= (PDESKTOP_OBJECT
)DeletedObject
;
267 DPRINT("Deleting desktop (0x%X)\n", Desktop
);
269 /* Remove the desktop from the window station's list of associcated desktops */
270 KeAcquireSpinLock(&Desktop
->WindowStation
->Lock
, &OldIrql
);
271 RemoveEntryList(&Desktop
->ListEntry
);
272 KeReleaseSpinLock(&Desktop
->WindowStation
->Lock
, OldIrql
);
274 RtlFreeUnicodeString(&Desktop
->Name
);
280 /* Create window station object type */
281 ExWindowStationObjectType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
282 if (ExWindowStationObjectType
== NULL
)
284 CPRINT("Could not create window station object type\n");
288 ExWindowStationObjectType
->Tag
= TAG('W', 'I', 'N', 'S');
289 ExWindowStationObjectType
->TotalObjects
= 0;
290 ExWindowStationObjectType
->TotalHandles
= 0;
291 ExWindowStationObjectType
->MaxObjects
= ULONG_MAX
;
292 ExWindowStationObjectType
->MaxHandles
= ULONG_MAX
;
293 ExWindowStationObjectType
->PagedPoolCharge
= 0;
294 ExWindowStationObjectType
->NonpagedPoolCharge
= sizeof(WINSTATION_OBJECT
);
295 ExWindowStationObjectType
->Mapping
= &ExpWindowStationMapping
;
296 ExWindowStationObjectType
->Dump
= NULL
;
297 ExWindowStationObjectType
->Open
= NULL
;
298 ExWindowStationObjectType
->Close
= NULL
;
299 ExWindowStationObjectType
->Delete
= ExpWinStaObjectDelete
;
300 ExWindowStationObjectType
->Parse
= ExpWinStaObjectParse
;
301 ExWindowStationObjectType
->Security
= NULL
;
302 ExWindowStationObjectType
->QueryName
= NULL
;
303 ExWindowStationObjectType
->OkayToClose
= NULL
;
304 ExWindowStationObjectType
->Create
= ExpWinStaObjectCreate
;
305 RtlInitUnicodeString(&ExWindowStationObjectType
->TypeName
, L
"WindowStation");
307 /* Create desktop object type */
308 ExDesktopObjectType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
309 if (ExDesktopObjectType
== NULL
)
311 CPRINT("Could not create desktop object type\n");
315 ExDesktopObjectType
->Tag
= TAG('D', 'E', 'S', 'K');
316 ExDesktopObjectType
->TotalObjects
= 0;
317 ExDesktopObjectType
->TotalHandles
= 0;
318 ExDesktopObjectType
->MaxObjects
= ULONG_MAX
;
319 ExDesktopObjectType
->MaxHandles
= ULONG_MAX
;
320 ExDesktopObjectType
->PagedPoolCharge
= 0;
321 ExDesktopObjectType
->NonpagedPoolCharge
= sizeof(DESKTOP_OBJECT
);
322 ExDesktopObjectType
->Mapping
= &ExpDesktopMapping
;
323 ExDesktopObjectType
->Dump
= NULL
;
324 ExDesktopObjectType
->Open
= NULL
;
325 ExDesktopObjectType
->Close
= NULL
;
326 ExDesktopObjectType
->Delete
= ExpDesktopObjectDelete
;
327 ExDesktopObjectType
->Parse
= NULL
;
328 ExDesktopObjectType
->Security
= NULL
;
329 ExDesktopObjectType
->QueryName
= NULL
;
330 ExDesktopObjectType
->OkayToClose
= NULL
;
331 ExDesktopObjectType
->Create
= ExpDesktopObjectCreate
;
332 RtlInitUnicodeString(&ExDesktopObjectType
->TypeName
, L
"Desktop");