reactos/reactos/ntoskrnl/ex/win32k.c
Eric Kohl 908cf73ea4 Create type objects for all object types.
svn path=/trunk/; revision=6262
2003-10-07 14:08:43 +00:00

325 lines
8.8 KiB
C

/*
* 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 <limits.h>
#include <ddk/ntddk.h>
#include <internal/ex.h>
#include <internal/ob.h>
#include <wchar.h>
#define NDEBUG
#include <internal/debug.h>
/* 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;
}
WinSta->SystemMenuTemplate = (HANDLE)0;
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");
ObpCreateTypeObject(ExWindowStationObjectType);
/* 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");
ObpCreateTypeObject(ExDesktopObjectType);
}
/* EOF */