/* * ReactOS kernel * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * PROJECT: ReactOS kernel * FILE: kernel/ex/win32k.c * PURPOSE: Executive Win32 subsystem support * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * UPDATE HISTORY: * 04-06-2001 CSH Created */ #include #include #include #include #define NDEBUG #include /* DATA **********************************************************************/ POBJECT_TYPE EXPORTED ExWindowStationObjectType = NULL; POBJECT_TYPE EXPORTED ExDesktopObjectType = NULL; static GENERIC_MAPPING ExpWindowStationMapping = { FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS }; static GENERIC_MAPPING ExpDesktopMapping = { FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS }; /* FUNCTIONS ****************************************************************/ NTSTATUS STDCALL ExpWinStaObjectCreate(PVOID ObjectBody, PVOID Parent, PWSTR RemainingPath, struct _OBJECT_ATTRIBUTES* ObjectAttributes) { PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)ObjectBody; UNICODE_STRING UnicodeString; NTSTATUS Status; if (RemainingPath == NULL) { return STATUS_SUCCESS; } if (wcschr((RemainingPath + 1), '\\') != NULL) { return STATUS_UNSUCCESSFUL; } RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1)); DPRINT("Creating window station (0x%X) Name (%wZ)\n", WinSta, &UnicodeString); Status = RtlCreateUnicodeString(&WinSta->Name, UnicodeString.Buffer); if (!NT_SUCCESS(Status)) { return Status; } KeInitializeSpinLock(&WinSta->Lock); InitializeListHead(&WinSta->DesktopListHead); #if 1 WinSta->AtomTable = NULL; #endif Status = RtlCreateAtomTable(37, &WinSta->AtomTable); if (!NT_SUCCESS(Status)) { RtlFreeUnicodeString(&WinSta->Name); return Status; } DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta->Name); return STATUS_SUCCESS; } VOID STDCALL ExpWinStaObjectDelete(PVOID DeletedObject) { PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)DeletedObject; DPRINT("Deleting window station (0x%X)\n", WinSta); RtlDestroyAtomTable(WinSta->AtomTable); RtlFreeUnicodeString(&WinSta->Name); } PVOID ExpWinStaObjectFind(PWINSTATION_OBJECT WinStaObject, PWSTR Name, ULONG Attributes) { PLIST_ENTRY Current; PDESKTOP_OBJECT CurrentObject; DPRINT("WinStaObject (0x%X) Name (%wS)\n", WinStaObject, Name); if (Name[0] == 0) { return NULL; } Current = WinStaObject->DesktopListHead.Flink; while (Current != &WinStaObject->DesktopListHead) { CurrentObject = CONTAINING_RECORD(Current, DESKTOP_OBJECT, ListEntry); DPRINT("Scanning %wZ for %wS\n", &CurrentObject->Name, Name); if (Attributes & OBJ_CASE_INSENSITIVE) { if (_wcsicmp(CurrentObject->Name.Buffer, Name) == 0) { DPRINT("Found desktop at (0x%X)\n", CurrentObject); return CurrentObject; } } else { if (wcscmp(CurrentObject->Name.Buffer, Name) == 0) { DPRINT("Found desktop at (0x%X)\n", CurrentObject); return CurrentObject; } } Current = Current->Flink; } DPRINT("Returning NULL\n"); return NULL; } NTSTATUS STDCALL ExpWinStaObjectParse(PVOID Object, PVOID *NextObject, PUNICODE_STRING FullPath, PWSTR *Path, ULONG Attributes) { PVOID FoundObject; NTSTATUS Status; PWSTR End; DPRINT("Object (0x%X) Path (0x%X) *Path (%wS)\n", Object, Path, *Path); *NextObject = NULL; if ((Path == NULL) || ((*Path) == NULL)) { return STATUS_SUCCESS; } End = wcschr((*Path) + 1, '\\'); if (End != NULL) { DPRINT("Name contains illegal characters\n"); return STATUS_UNSUCCESSFUL; } FoundObject = ExpWinStaObjectFind(Object, (*Path) + 1, Attributes); if (FoundObject == NULL) { DPRINT("Name was not found\n"); return STATUS_UNSUCCESSFUL; } Status = ObReferenceObjectByPointer( FoundObject, STANDARD_RIGHTS_REQUIRED, NULL, UserMode); *Path = NULL; return Status; } NTSTATUS STDCALL ExpDesktopObjectCreate(PVOID ObjectBody, PVOID Parent, PWSTR RemainingPath, struct _OBJECT_ATTRIBUTES* ObjectAttributes) { PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)ObjectBody; UNICODE_STRING UnicodeString; if (RemainingPath == NULL) { return STATUS_SUCCESS; } if (wcschr((RemainingPath + 1), '\\') != NULL) { return STATUS_UNSUCCESSFUL; } RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1)); DPRINT("Creating desktop (0x%X) Name (%wZ)\n", Desktop, &UnicodeString); KeInitializeSpinLock(&Desktop->Lock); Desktop->WindowStation = (PWINSTATION_OBJECT)Parent; /* Put the desktop on the window station's list of associcated desktops */ ExInterlockedInsertTailList( &Desktop->WindowStation->DesktopListHead, &Desktop->ListEntry, &Desktop->WindowStation->Lock); return RtlCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer); } VOID STDCALL ExpDesktopObjectDelete(PVOID DeletedObject) { PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject; KIRQL OldIrql; DPRINT("Deleting desktop (0x%X)\n", Desktop); /* Remove the desktop from the window station's list of associcated desktops */ KeAcquireSpinLock(&Desktop->WindowStation->Lock, &OldIrql); RemoveEntryList(&Desktop->ListEntry); KeReleaseSpinLock(&Desktop->WindowStation->Lock, OldIrql); RtlFreeUnicodeString(&Desktop->Name); } VOID ExpWin32kInit(VOID) { /* Create window station object type */ ExWindowStationObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); if (ExWindowStationObjectType == NULL) { CPRINT("Could not create window station object type\n"); KeBugCheck(0); } ExWindowStationObjectType->Tag = TAG('W', 'I', 'N', 'S'); ExWindowStationObjectType->TotalObjects = 0; ExWindowStationObjectType->TotalHandles = 0; ExWindowStationObjectType->MaxObjects = ULONG_MAX; ExWindowStationObjectType->MaxHandles = ULONG_MAX; ExWindowStationObjectType->PagedPoolCharge = 0; ExWindowStationObjectType->NonpagedPoolCharge = sizeof(WINSTATION_OBJECT); ExWindowStationObjectType->Mapping = &ExpWindowStationMapping; ExWindowStationObjectType->Dump = NULL; ExWindowStationObjectType->Open = NULL; ExWindowStationObjectType->Close = NULL; ExWindowStationObjectType->Delete = ExpWinStaObjectDelete; ExWindowStationObjectType->Parse = ExpWinStaObjectParse; ExWindowStationObjectType->Security = NULL; ExWindowStationObjectType->QueryName = NULL; ExWindowStationObjectType->OkayToClose = NULL; ExWindowStationObjectType->Create = ExpWinStaObjectCreate; ExWindowStationObjectType->DuplicationNotify = NULL; RtlInitUnicodeStringFromLiteral(&ExWindowStationObjectType->TypeName, L"WindowStation"); /* Create desktop object type */ ExDesktopObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); if (ExDesktopObjectType == NULL) { CPRINT("Could not create desktop object type\n"); KeBugCheck(0); } ExDesktopObjectType->Tag = TAG('D', 'E', 'S', 'K'); ExDesktopObjectType->TotalObjects = 0; ExDesktopObjectType->TotalHandles = 0; ExDesktopObjectType->MaxObjects = ULONG_MAX; ExDesktopObjectType->MaxHandles = ULONG_MAX; ExDesktopObjectType->PagedPoolCharge = 0; ExDesktopObjectType->NonpagedPoolCharge = sizeof(DESKTOP_OBJECT); ExDesktopObjectType->Mapping = &ExpDesktopMapping; ExDesktopObjectType->Dump = NULL; ExDesktopObjectType->Open = NULL; ExDesktopObjectType->Close = NULL; ExDesktopObjectType->Delete = ExpDesktopObjectDelete; ExDesktopObjectType->Parse = NULL; ExDesktopObjectType->Security = NULL; ExDesktopObjectType->QueryName = NULL; ExDesktopObjectType->OkayToClose = NULL; ExDesktopObjectType->Create = ExpDesktopObjectCreate; ExDesktopObjectType->DuplicationNotify = NULL; RtlInitUnicodeStringFromLiteral(&ExDesktopObjectType->TypeName, L"Desktop"); } /* EOF */