- Fix some small formatting issues.
[reactos.git] / reactos / ntoskrnl / ex / win32k.c
index 0bfbbb9..0b5bd5d 100644 (file)
 /*
- *  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 */