/*
- * 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.
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/ex/win32k.c
+ * PURPOSE: Executive Win32 Object Support (Desktop/WinStation)
+ * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
-/*
- * 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 <limits.h>
-#include <ddk/ntddk.h>
-#include <internal/ex.h>
-#include <wchar.h>
+#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, ExpWin32kInit)
+#endif
+
/* DATA **********************************************************************/
-POBJECT_TYPE EXPORTED ExWindowStationObjectType = NULL;
-POBJECT_TYPE EXPORTED ExDesktopObjectType = NULL;
+POBJECT_TYPE ExWindowStationObjectType = NULL;
+POBJECT_TYPE ExDesktopObjectType = NULL;
-static GENERIC_MAPPING ExpWindowStationMapping = {
- FILE_GENERIC_READ,
- FILE_GENERIC_WRITE,
- FILE_GENERIC_EXECUTE,
- FILE_ALL_ACCESS };
+static GENERIC_MAPPING ExpWindowStationMapping =
+{
+ STANDARD_RIGHTS_READ,
+ STANDARD_RIGHTS_WRITE,
+ STANDARD_RIGHTS_EXECUTE,
+ STANDARD_RIGHTS_REQUIRED
+};
-static GENERIC_MAPPING ExpDesktopMapping = {
- FILE_GENERIC_READ,
- FILE_GENERIC_WRITE,
- FILE_GENERIC_EXECUTE,
- FILE_ALL_ACCESS };
+static GENERIC_MAPPING ExpDesktopMapping =
+{
+ STANDARD_RIGHTS_READ,
+ STANDARD_RIGHTS_WRITE,
+ STANDARD_RIGHTS_EXECUTE,
+ STANDARD_RIGHTS_REQUIRED
+};
+
+OB_OPEN_METHOD ExpWindowStationObjectOpen = NULL;
+OB_PARSE_METHOD ExpWindowStationObjectParse = NULL;
+OB_DELETE_METHOD ExpWindowStationObjectDelete = NULL;
+OB_FIND_METHOD ExpWindowStationObjectFind = NULL;
+OB_CREATE_METHOD ExpDesktopObjectCreate = NULL;
+OB_DELETE_METHOD ExpDesktopObjectDelete = NULL;
/* FUNCTIONS ****************************************************************/
-
-NTSTATUS STDCALL
-ExpWinStaObjectCreate(PVOID ObjectBody,
- PVOID Parent,
- PWSTR RemainingPath,
- struct _OBJECT_ATTRIBUTES* ObjectAttributes)
+NTSTATUS
+STDCALL
+ExpWinStaObjectOpen(OB_OPEN_REASON Reason,
+ PVOID ObjectBody,
+ PEPROCESS Process,
+ ULONG HandleCount,
+ ACCESS_MASK GrantedAccess)
{
- 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;
- }
-
- WinSta->SystemMenuTemplate = (HANDLE)0;
-
- DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta->Name);
-
- return STATUS_SUCCESS;
+ /* Call the Registered Callback */
+ return ExpWindowStationObjectOpen(Reason,
+ ObjectBody,
+ Process,
+ HandleCount,
+ GrantedAccess);
}
-VOID STDCALL
+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);
+ /* Call the Registered Callback */
+ ExpWindowStationObjectDelete(DeletedObject);
}
PVOID
-ExpWinStaObjectFind(PWINSTATION_OBJECT WinStaObject,
- PWSTR Name,
- ULONG Attributes)
+STDCALL
+ExpWinStaObjectFind(PVOID 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;
+ /* Call the Registered Callback */
+ return ExpWindowStationObjectFind(WinStaObject,
+ Name,
+ Attributes);
}
-NTSTATUS STDCALL
+NTSTATUS
+STDCALL
ExpWinStaObjectParse(PVOID Object,
- PVOID *NextObject,
- PUNICODE_STRING FullPath,
- PWSTR *Path,
- ULONG Attributes)
+ 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;
+ /* Call the Registered Callback */
+ return ExpWindowStationObjectParse(Object,
+ NextObject,
+ FullPath,
+ Path,
+ Attributes);
}
-NTSTATUS STDCALL
-ExpDesktopObjectCreate(PVOID ObjectBody,
- PVOID Parent,
- PWSTR RemainingPath,
- struct _OBJECT_ATTRIBUTES* ObjectAttributes)
+NTSTATUS
+STDCALL
+ExpDesktopCreate(PVOID ObjectBody,
+ PVOID Parent,
+ PWSTR RemainingPath,
+ POBJECT_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);
+ /* Call the Registered Callback */
+ return ExpDesktopObjectCreate(ObjectBody,
+ Parent,
+ RemainingPath,
+ ObjectAttributes);
}
-VOID STDCALL
-ExpDesktopObjectDelete(PVOID DeletedObject)
+VOID
+STDCALL
+ExpDesktopDelete(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);
+ /* Call the Registered Callback */
+ ExpDesktopObjectDelete(DeletedObject);
}
VOID
+INIT_FUNCTION
+STDCALL
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");
+ OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
+ UNICODE_STRING Name;
+ DPRINT("Creating Win32 Object Types\n");
+
+ /* Create the window station Object Type */
+ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
+ RtlInitUnicodeString(&Name, L"WindowStation");
+ ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
+ ObjectTypeInitializer.GenericMapping = ExpWindowStationMapping;
+ ObjectTypeInitializer.PoolType = NonPagedPool;
+ ObjectTypeInitializer.OpenProcedure = ExpWinStaObjectOpen;
+ ObjectTypeInitializer.DeleteProcedure = ExpWinStaObjectDelete;
+ ObjectTypeInitializer.ParseProcedure = ExpWinStaObjectParse;
+ ObpCreateTypeObject(&ObjectTypeInitializer,
+ &Name,
+ &ExWindowStationObjectType);
+
+ /* Create desktop object type */
+ RtlInitUnicodeString(&Name, L"Desktop");
+ ObjectTypeInitializer.GenericMapping = ExpDesktopMapping;
+ ObjectTypeInitializer.OpenProcedure = NULL;
+ ObjectTypeInitializer.DeleteProcedure = ExpDesktopDelete;
+ ObjectTypeInitializer.ParseProcedure = NULL;
+ ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ExDesktopObjectType);
}
/* EOF */