3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/win32k.c
6 * PURPOSE: Executive Win32 subsystem support
8 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
13 #include <internal/debug.h>
15 /* DATA **********************************************************************/
17 #define WINSTA_ACCESSCLIPBOARD (0x4L)
18 #define WINSTA_ACCESSGLOBALATOMS (0x20L)
19 #define WINSTA_CREATEDESKTOP (0x8L)
20 #define WINSTA_ENUMDESKTOPS (0x1L)
21 #define WINSTA_ENUMERATE (0x100L)
22 #define WINSTA_EXITWINDOWS (0x40L)
23 #define WINSTA_READATTRIBUTES (0x2L)
24 #define WINSTA_READSCREEN (0x200L)
25 #define WINSTA_WRITEATTRIBUTES (0x10L)
27 #define DF_ALLOWOTHERACCOUNTHOOK (0x1L)
28 #define DESKTOP_CREATEMENU (0x4L)
29 #define DESKTOP_CREATEWINDOW (0x2L)
30 #define DESKTOP_ENUMERATE (0x40L)
31 #define DESKTOP_HOOKCONTROL (0x8L)
32 #define DESKTOP_JOURNALPLAYBACK (0x20L)
33 #define DESKTOP_JOURNALRECORD (0x10L)
34 #define DESKTOP_READOBJECTS (0x1L)
35 #define DESKTOP_SWITCHDESKTOP (0x100L)
36 #define DESKTOP_WRITEOBJECTS (0x80L)
38 POBJECT_TYPE EXPORTED ExWindowStationObjectType
= NULL
;
39 POBJECT_TYPE EXPORTED ExDesktopObjectType
= NULL
;
41 static GENERIC_MAPPING ExpWindowStationMapping
= {
42 STANDARD_RIGHTS_READ
| WINSTA_ENUMDESKTOPS
| WINSTA_ENUMERATE
| WINSTA_READATTRIBUTES
| WINSTA_READSCREEN
,
43 STANDARD_RIGHTS_WRITE
| WINSTA_ACCESSCLIPBOARD
| WINSTA_CREATEDESKTOP
| WINSTA_WRITEATTRIBUTES
,
44 STANDARD_RIGHTS_EXECUTE
| WINSTA_ACCESSGLOBALATOMS
| WINSTA_EXITWINDOWS
,
45 STANDARD_RIGHTS_REQUIRED
| WINSTA_ACCESSCLIPBOARD
| WINSTA_ACCESSGLOBALATOMS
| WINSTA_CREATEDESKTOP
|
46 WINSTA_ENUMDESKTOPS
| WINSTA_ENUMERATE
| WINSTA_EXITWINDOWS
|
47 WINSTA_READATTRIBUTES
| WINSTA_READSCREEN
| WINSTA_WRITEATTRIBUTES
50 static GENERIC_MAPPING ExpDesktopMapping
= {
51 STANDARD_RIGHTS_READ
| DESKTOP_ENUMERATE
| DESKTOP_READOBJECTS
,
52 STANDARD_RIGHTS_WRITE
| DESKTOP_CREATEMENU
| DESKTOP_CREATEWINDOW
| DESKTOP_HOOKCONTROL
|
53 DESKTOP_JOURNALPLAYBACK
| DESKTOP_JOURNALRECORD
| DESKTOP_WRITEOBJECTS
,
54 STANDARD_RIGHTS_EXECUTE
| DESKTOP_SWITCHDESKTOP
,
55 STANDARD_RIGHTS_REQUIRED
| DESKTOP_CREATEMENU
| DESKTOP_CREATEWINDOW
| DESKTOP_ENUMERATE
|
56 DESKTOP_HOOKCONTROL
| DESKTOP_JOURNALPLAYBACK
| DESKTOP_JOURNALRECORD
|
57 DESKTOP_READOBJECTS
| DESKTOP_SWITCHDESKTOP
| DESKTOP_WRITEOBJECTS
60 /* FUNCTIONS ****************************************************************/
64 ExpWinStaObjectCreate(PVOID ObjectBody
,
67 struct _OBJECT_ATTRIBUTES
* ObjectAttributes
)
69 PWINSTATION_OBJECT WinSta
= (PWINSTATION_OBJECT
)ObjectBody
;
70 UNICODE_STRING UnicodeString
;
73 if (RemainingPath
== NULL
)
75 return STATUS_SUCCESS
;
78 if (wcschr((RemainingPath
+ 1), '\\') != NULL
)
80 return STATUS_UNSUCCESSFUL
;
83 RtlInitUnicodeString(&UnicodeString
, (RemainingPath
+ 1));
85 DPRINT("Creating window station (0x%X) Name (%wZ)\n", WinSta
, &UnicodeString
);
87 Status
= RtlpCreateUnicodeString(&WinSta
->Name
, UnicodeString
.Buffer
, NonPagedPool
);
88 if (!NT_SUCCESS(Status
))
93 KeInitializeSpinLock(&WinSta
->Lock
);
95 InitializeListHead(&WinSta
->DesktopListHead
);
98 WinSta
->AtomTable
= NULL
;
101 Status
= RtlCreateAtomTable(37, &WinSta
->AtomTable
);
102 if (!NT_SUCCESS(Status
))
104 RtlFreeUnicodeString(&WinSta
->Name
);
108 WinSta
->SystemMenuTemplate
= (HANDLE
)0;
110 DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta
->Name
);
112 return STATUS_SUCCESS
;
116 ExpWinStaObjectDelete(PVOID DeletedObject
)
118 PWINSTATION_OBJECT WinSta
= (PWINSTATION_OBJECT
)DeletedObject
;
120 DPRINT("Deleting window station (0x%X)\n", WinSta
);
122 RtlDestroyAtomTable(WinSta
->AtomTable
);
124 RtlFreeUnicodeString(&WinSta
->Name
);
128 ExpWinStaObjectFind(PWINSTATION_OBJECT WinStaObject
,
133 PDESKTOP_OBJECT CurrentObject
;
135 DPRINT("WinStaObject (0x%X) Name (%wS)\n", WinStaObject
, Name
);
142 Current
= WinStaObject
->DesktopListHead
.Flink
;
143 while (Current
!= &WinStaObject
->DesktopListHead
)
145 CurrentObject
= CONTAINING_RECORD(Current
, DESKTOP_OBJECT
, ListEntry
);
146 DPRINT("Scanning %wZ for %wS\n", &CurrentObject
->Name
, Name
);
147 if (Attributes
& OBJ_CASE_INSENSITIVE
)
149 if (_wcsicmp(CurrentObject
->Name
.Buffer
, Name
) == 0)
151 DPRINT("Found desktop at (0x%X)\n", CurrentObject
);
152 return CurrentObject
;
157 if (wcscmp(CurrentObject
->Name
.Buffer
, Name
) == 0)
159 DPRINT("Found desktop at (0x%X)\n", CurrentObject
);
160 return CurrentObject
;
163 Current
= Current
->Flink
;
166 DPRINT("Returning NULL\n");
172 ExpWinStaObjectParse(PVOID Object
,
174 PUNICODE_STRING FullPath
,
182 DPRINT("Object (0x%X) Path (0x%X) *Path (%wS)\n", Object
, Path
, *Path
);
186 if ((Path
== NULL
) || ((*Path
) == NULL
))
188 return STATUS_SUCCESS
;
191 End
= wcschr((*Path
) + 1, '\\');
194 DPRINT("Name contains illegal characters\n");
195 return STATUS_UNSUCCESSFUL
;
198 FoundObject
= ExpWinStaObjectFind(Object
, (*Path
) + 1, Attributes
);
199 if (FoundObject
== NULL
)
201 DPRINT("Name was not found\n");
202 return STATUS_UNSUCCESSFUL
;
205 Status
= ObReferenceObjectByPointer(
207 STANDARD_RIGHTS_REQUIRED
,
211 *NextObject
= FoundObject
;
218 ExpDesktopObjectCreate(PVOID ObjectBody
,
221 struct _OBJECT_ATTRIBUTES
* ObjectAttributes
)
223 PDESKTOP_OBJECT Desktop
= (PDESKTOP_OBJECT
)ObjectBody
;
224 UNICODE_STRING UnicodeString
;
226 if (RemainingPath
== NULL
)
228 return STATUS_SUCCESS
;
231 if (wcschr((RemainingPath
+ 1), '\\') != NULL
)
233 return STATUS_UNSUCCESSFUL
;
236 RtlInitUnicodeString(&UnicodeString
, (RemainingPath
+ 1));
238 DPRINT("Creating desktop (0x%X) Name (%wZ)\n", Desktop
, &UnicodeString
);
240 KeInitializeSpinLock(&Desktop
->Lock
);
242 Desktop
->WindowStation
= (PWINSTATION_OBJECT
)Parent
;
244 /* Put the desktop on the window station's list of associcated desktops */
245 ExInterlockedInsertTailList(
246 &Desktop
->WindowStation
->DesktopListHead
,
248 &Desktop
->WindowStation
->Lock
);
250 return RtlpCreateUnicodeString(&Desktop
->Name
, UnicodeString
.Buffer
, NonPagedPool
);
254 ExpDesktopObjectDelete(PVOID DeletedObject
)
256 PDESKTOP_OBJECT Desktop
= (PDESKTOP_OBJECT
)DeletedObject
;
259 DPRINT("Deleting desktop (0x%X)\n", Desktop
);
261 /* Remove the desktop from the window station's list of associcated desktops */
262 KeAcquireSpinLock(&Desktop
->WindowStation
->Lock
, &OldIrql
);
263 RemoveEntryList(&Desktop
->ListEntry
);
264 KeReleaseSpinLock(&Desktop
->WindowStation
->Lock
, OldIrql
);
266 RtlFreeUnicodeString(&Desktop
->Name
);
272 /* Create window station object type */
273 ExWindowStationObjectType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
274 if (ExWindowStationObjectType
== NULL
)
276 CPRINT("Could not create window station object type\n");
280 ExWindowStationObjectType
->Tag
= TAG('W', 'I', 'N', 'S');
281 ExWindowStationObjectType
->TotalObjects
= 0;
282 ExWindowStationObjectType
->TotalHandles
= 0;
283 ExWindowStationObjectType
->PeakObjects
= 0;
284 ExWindowStationObjectType
->PeakHandles
= 0;
285 ExWindowStationObjectType
->PagedPoolCharge
= 0;
286 ExWindowStationObjectType
->NonpagedPoolCharge
= sizeof(WINSTATION_OBJECT
);
287 ExWindowStationObjectType
->Mapping
= &ExpWindowStationMapping
;
288 ExWindowStationObjectType
->Dump
= NULL
;
289 ExWindowStationObjectType
->Open
= NULL
;
290 ExWindowStationObjectType
->Close
= NULL
;
291 ExWindowStationObjectType
->Delete
= ExpWinStaObjectDelete
;
292 ExWindowStationObjectType
->Parse
= ExpWinStaObjectParse
;
293 ExWindowStationObjectType
->Security
= NULL
;
294 ExWindowStationObjectType
->QueryName
= NULL
;
295 ExWindowStationObjectType
->OkayToClose
= NULL
;
296 ExWindowStationObjectType
->Create
= ExpWinStaObjectCreate
;
297 ExWindowStationObjectType
->DuplicationNotify
= NULL
;
298 RtlInitUnicodeString(&ExWindowStationObjectType
->TypeName
, L
"WindowStation");
300 ObpCreateTypeObject(ExWindowStationObjectType
);
302 /* Create desktop object type */
303 ExDesktopObjectType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
304 if (ExDesktopObjectType
== NULL
)
306 CPRINT("Could not create desktop object type\n");
310 ExDesktopObjectType
->Tag
= TAG('D', 'E', 'S', 'K');
311 ExDesktopObjectType
->TotalObjects
= 0;
312 ExDesktopObjectType
->TotalHandles
= 0;
313 ExDesktopObjectType
->PeakObjects
= 0;
314 ExDesktopObjectType
->PeakHandles
= 0;
315 ExDesktopObjectType
->PagedPoolCharge
= 0;
316 ExDesktopObjectType
->NonpagedPoolCharge
= sizeof(DESKTOP_OBJECT
);
317 ExDesktopObjectType
->Mapping
= &ExpDesktopMapping
;
318 ExDesktopObjectType
->Dump
= NULL
;
319 ExDesktopObjectType
->Open
= NULL
;
320 ExDesktopObjectType
->Close
= NULL
;
321 ExDesktopObjectType
->Delete
= ExpDesktopObjectDelete
;
322 ExDesktopObjectType
->Parse
= NULL
;
323 ExDesktopObjectType
->Security
= NULL
;
324 ExDesktopObjectType
->QueryName
= NULL
;
325 ExDesktopObjectType
->OkayToClose
= NULL
;
326 ExDesktopObjectType
->Create
= ExpDesktopObjectCreate
;
327 ExDesktopObjectType
->DuplicationNotify
= NULL
;
328 RtlInitUnicodeString(&ExDesktopObjectType
->TypeName
, L
"Desktop");
330 ObpCreateTypeObject(ExDesktopObjectType
);