From 82b7a361af55fbde69917a812da8b268003a14e6 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Fri, 1 Mar 2002 00:47:40 +0000 Subject: [PATCH] Started implementing type objects. Some object manager cleanup. svn path=/trunk/; revision=2659 --- reactos/ntoskrnl/include/internal/ob.h | 18 +- reactos/ntoskrnl/lpc/close.c | 7 +- reactos/ntoskrnl/ob/namespc.c | 184 +++++++++++++++----- reactos/ntoskrnl/ob/object.c | 222 +++++++++++++------------ 4 files changed, 279 insertions(+), 152 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ob.h b/reactos/ntoskrnl/include/internal/ob.h index c6ce969562f..1e38f17a22f 100644 --- a/reactos/ntoskrnl/include/internal/ob.h +++ b/reactos/ntoskrnl/include/internal/ob.h @@ -22,7 +22,7 @@ typedef struct typedef PVOID POBJECT; typedef struct _DIRECTORY_OBJECT -{ +{ CSHORT Type; CSHORT Size; @@ -34,6 +34,16 @@ typedef struct _DIRECTORY_OBJECT } DIRECTORY_OBJECT, *PDIRECTORY_OBJECT; +typedef struct _TYPE_OBJECT +{ + CSHORT Type; + CSHORT Size; + + /* pointer to object type data */ + POBJECT_TYPE ObjectType; +} TYPE_OBJECT, *PTYPE_OBJECT; + + /* * Enumeration of object types */ @@ -66,7 +76,6 @@ VOID ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent, PWSTR Name); VOID ObpRemoveEntryDirectory(POBJECT_HEADER Header); -NTSTATUS ObPerformRetentionChecks(POBJECT_HEADER Header); NTSTATUS ObCreateHandle(struct _EPROCESS* Process, @@ -81,11 +90,12 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes, PVOID* ReturnedObject, PUNICODE_STRING RemainingPath, POBJECT_TYPE ObjectType); -ULONG ObGetReferenceCount(PVOID Object); -ULONG ObGetHandleCount(PVOID Object); VOID ObCloseAllHandles(struct _EPROCESS* Process); VOID ObDeleteHandleTable(struct _EPROCESS* Process); PVOID ObDeleteHandle(struct _EPROCESS* Process, HANDLE Handle); +NTSTATUS +ObpCreateTypeObject(POBJECT_TYPE ObjectType); + #endif /* __INCLUDE_INTERNAL_OBJMGR_H */ diff --git a/reactos/ntoskrnl/lpc/close.c b/reactos/ntoskrnl/lpc/close.c index 272c69631af..3ecbe878a9e 100644 --- a/reactos/ntoskrnl/lpc/close.c +++ b/reactos/ntoskrnl/lpc/close.c @@ -1,4 +1,4 @@ -/* $Id: close.c,v 1.7 2001/12/02 23:34:42 dwelch Exp $ +/* $Id: close.c,v 1.8 2002/03/01 00:47:21 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -12,7 +12,6 @@ /* INCLUDES *****************************************************************/ #include -#include #include #include @@ -44,7 +43,7 @@ NiClosePort (PVOID ObjectBody, ULONG HandleCount) * happened and disconnect this port. */ if (HandleCount == 0 && Port->State == EPORT_CONNECTED_CLIENT && - ObGetReferenceCount(Port) == 2) + ObGetObjectPointerCount(Port) == 2) { Message.MessageSize = sizeof(LPC_MESSAGE); Message.DataSize = 0; @@ -66,7 +65,7 @@ NiClosePort (PVOID ObjectBody, ULONG HandleCount) * don't actually notify the client until it attempts an operation. */ if (HandleCount == 0 && Port->State == EPORT_CONNECTED_SERVER && - ObGetReferenceCount(Port) == 2) + ObGetObjectPointerCount(Port) == 2) { Port->OtherPort->OtherPort = NULL; Port->OtherPort->State = EPORT_DISCONNECTED; diff --git a/reactos/ntoskrnl/ob/namespc.c b/reactos/ntoskrnl/ob/namespc.c index adabcb35a8f..04aa69e19c5 100644 --- a/reactos/ntoskrnl/ob/namespc.c +++ b/reactos/ntoskrnl/ob/namespc.c @@ -1,4 +1,4 @@ -/* $Id: namespc.c,v 1.28 2002/02/19 00:09:24 ekohl Exp $ +/* $Id: namespc.c,v 1.29 2002/03/01 00:47:40 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -23,6 +23,7 @@ /* GLOBALS ****************************************************************/ POBJECT_TYPE ObDirectoryType = NULL; +POBJECT_TYPE ObTypeObjectType = NULL; PDIRECTORY_OBJECT NameSpaceRoot = NULL; @@ -32,6 +33,12 @@ static GENERIC_MAPPING ObpDirectoryMapping = { STANDARD_RIGHTS_EXECUTE|DIRECTORY_QUERY|DIRECTORY_TRAVERSE, DIRECTORY_ALL_ACCESS}; +static GENERIC_MAPPING ObpTypeMapping = { + STANDARD_RIGHTS_READ, + STANDARD_RIGHTS_WRITE, + STANDARD_RIGHTS_EXECUTE, + 0x000F0001}; + /* FUNCTIONS **************************************************************/ NTSTATUS STDCALL @@ -106,13 +113,13 @@ DPRINT("Object %p\n", Object); * Status. */ NTSTATUS STDCALL -ObOpenObjectByName(POBJECT_ATTRIBUTES ObjectAttributes, - POBJECT_TYPE ObjectType, - PVOID ParseContext, - KPROCESSOR_MODE AccessMode, - ACCESS_MASK DesiredAccess, - PACCESS_STATE PassedAccessState, - PHANDLE Handle) +ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, + IN POBJECT_TYPE ObjectType, + IN OUT PVOID ParseContext, + IN KPROCESSOR_MODE AccessMode, + IN ACCESS_MASK DesiredAccess, + IN PACCESS_STATE PassedAccessState, + OUT PHANDLE Handle) { UNICODE_STRING RemainingPath; PVOID Object = NULL; @@ -316,40 +323,141 @@ ObpCreateDirectory(PVOID ObjectBody, return(STATUS_SUCCESS); } -VOID ObInit(VOID) + +VOID +ObInit(VOID) /* * FUNCTION: Initialize the object manager namespace */ { - ObDirectoryType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE)); - - ObDirectoryType->Tag = TAG('D', 'I', 'R', 'T'); - ObDirectoryType->TotalObjects = 0; - ObDirectoryType->TotalHandles = 0; - ObDirectoryType->MaxObjects = ULONG_MAX; - ObDirectoryType->MaxHandles = ULONG_MAX; - ObDirectoryType->PagedPoolCharge = 0; - ObDirectoryType->NonpagedPoolCharge = sizeof(DIRECTORY_OBJECT); - ObDirectoryType->Mapping = &ObpDirectoryMapping; - ObDirectoryType->Dump = NULL; - ObDirectoryType->Open = NULL; - ObDirectoryType->Close = NULL; - ObDirectoryType->Delete = NULL; - ObDirectoryType->Parse = ObpParseDirectory; - ObDirectoryType->Security = NULL; - ObDirectoryType->QueryName = NULL; - ObDirectoryType->OkayToClose = NULL; - ObDirectoryType->Create = ObpCreateDirectory; - ObDirectoryType->DuplicationNotify = NULL; - - RtlInitUnicodeString(&ObDirectoryType->TypeName, - L"Directory"); - - ObCreateObject(NULL, - STANDARD_RIGHTS_REQUIRED, - NULL, - ObDirectoryType, - (PVOID*)&NameSpaceRoot); + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING Name; + + /* create 'directory' object type */ + ObDirectoryType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE)); + + ObDirectoryType->Tag = TAG('D', 'I', 'R', 'T'); + ObDirectoryType->TotalObjects = 0; + ObDirectoryType->TotalHandles = 0; + ObDirectoryType->MaxObjects = ULONG_MAX; + ObDirectoryType->MaxHandles = ULONG_MAX; + ObDirectoryType->PagedPoolCharge = 0; + ObDirectoryType->NonpagedPoolCharge = sizeof(DIRECTORY_OBJECT); + ObDirectoryType->Mapping = &ObpDirectoryMapping; + ObDirectoryType->Dump = NULL; + ObDirectoryType->Open = NULL; + ObDirectoryType->Close = NULL; + ObDirectoryType->Delete = NULL; + ObDirectoryType->Parse = ObpParseDirectory; + ObDirectoryType->Security = NULL; + ObDirectoryType->QueryName = NULL; + ObDirectoryType->OkayToClose = NULL; + ObDirectoryType->Create = ObpCreateDirectory; + ObDirectoryType->DuplicationNotify = NULL; + + RtlInitUnicodeString(&ObDirectoryType->TypeName, + L"Directory"); + + /* create 'type' object type*/ + ObTypeObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE)); + + ObTypeObjectType->Tag = TAG('T', 'y', 'p', 'T'); + ObTypeObjectType->TotalObjects = 0; + ObTypeObjectType->TotalHandles = 0; + ObTypeObjectType->MaxObjects = ULONG_MAX; + ObTypeObjectType->MaxHandles = ULONG_MAX; + ObTypeObjectType->PagedPoolCharge = 0; + ObTypeObjectType->NonpagedPoolCharge = sizeof(TYPE_OBJECT); + ObTypeObjectType->Mapping = &ObpTypeMapping; + ObTypeObjectType->Dump = NULL; + ObTypeObjectType->Open = NULL; + ObTypeObjectType->Close = NULL; + ObTypeObjectType->Delete = NULL; + ObTypeObjectType->Parse = NULL; + ObTypeObjectType->Security = NULL; + ObTypeObjectType->QueryName = NULL; + ObTypeObjectType->OkayToClose = NULL; + ObTypeObjectType->Create = NULL; + ObTypeObjectType->DuplicationNotify = NULL; + + RtlInitUnicodeString(&ObTypeObjectType->TypeName, + L"ObjectType"); + + /* create root directory */ + ObCreateObject(NULL, + STANDARD_RIGHTS_REQUIRED, + NULL, + ObDirectoryType, + (PVOID*)&NameSpaceRoot); + + /* create '\ObjectTypes' directory */ + RtlInitUnicodeString(&Name, + L"\\ObjectTypes"); + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_PERMANENT, + NULL, + NULL); + ObCreateObject(NULL, + STANDARD_RIGHTS_REQUIRED, + &ObjectAttributes, + ObDirectoryType, + NULL); + + ObpCreateTypeObject(ObDirectoryType); + ObpCreateTypeObject(ObTypeObjectType); } + +NTSTATUS +ObpCreateTypeObject(POBJECT_TYPE ObjectType) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + WCHAR NameString[80]; + PTYPE_OBJECT TypeObject = NULL; + UNICODE_STRING Name; + HANDLE TypesDir; + NTSTATUS Status; + + RtlInitUnicodeString(&Name, + L"\\ObjectTypes"); + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenDirectoryObject(&TypesDir, + STANDARD_RIGHTS_REQUIRED, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + return(Status); + + DPRINT("ObjectType: %wZ\n", &ObjectType->TypeName); + wcscpy(NameString, L"\\"); + wcscat(NameString, ObjectType->TypeName.Buffer); + RtlInitUnicodeString(&Name, + NameString); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_PERMANENT, + TypesDir, + NULL); + Status = ObCreateObject(NULL, + STANDARD_RIGHTS_REQUIRED, + &ObjectAttributes, + ObTypeObjectType, + (PVOID*)&TypeObject); + if (NT_SUCCESS(Status)) + { + TypeObject->ObjectType = ObjectType; + } + + NtClose(TypesDir); + + return(STATUS_SUCCESS); +} + + /* EOF */ diff --git a/reactos/ntoskrnl/ob/object.c b/reactos/ntoskrnl/ob/object.c index 0d21e61793e..3c45b2bde13 100644 --- a/reactos/ntoskrnl/ob/object.c +++ b/reactos/ntoskrnl/ob/object.c @@ -1,4 +1,4 @@ -/* $Id: object.c,v 1.44 2002/02/23 23:08:58 ekohl Exp $ +/* $Id: object.c,v 1.45 2002/03/01 00:47:40 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -227,11 +227,11 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes, * RETURN VALUE */ NTSTATUS STDCALL -ObCreateObject(PHANDLE Handle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes, - POBJECT_TYPE Type, - PVOID *Object) +ObCreateObject(OUT PHANDLE Handle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN POBJECT_TYPE Type, + OUT PVOID *Object) { PVOID Parent = NULL; UNICODE_STRING RemainingPath; @@ -329,10 +329,10 @@ ObCreateObject(PHANDLE Handle, NTSTATUS STDCALL -ObReferenceObjectByPointer(PVOID ObjectBody, - ACCESS_MASK DesiredAccess, - POBJECT_TYPE ObjectType, - KPROCESSOR_MODE AccessMode) +ObReferenceObjectByPointer(IN PVOID Object, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_TYPE ObjectType, + IN KPROCESSOR_MODE AccessMode) /* * FUNCTION: Increments the pointer reference count for a given object * ARGUMENTS: @@ -343,37 +343,37 @@ ObReferenceObjectByPointer(PVOID ObjectBody, * RETURNS: Status */ { - POBJECT_HEADER ObjectHeader; + POBJECT_HEADER Header; -// DPRINT("ObReferenceObjectByPointer(ObjectBody %x, ObjectType %x)\n", -// ObjectBody,ObjectType); +// DPRINT("ObReferenceObjectByPointer(Object %x, ObjectType %x)\n", +// Object,ObjectType); - ObjectHeader = BODY_TO_HEADER(ObjectBody); + Header = BODY_TO_HEADER(Object); - if (ObjectType != NULL && ObjectHeader->ObjectType != ObjectType) + if (ObjectType != NULL && Header->ObjectType != ObjectType) { DPRINT("Failed %x (type was %x %S) should be %x %S\n", - ObjectHeader, - ObjectHeader->ObjectType, - ObjectHeader->ObjectType->TypeName.Buffer, + Header, + Header->ObjectType, + Header->ObjectType->TypeName.Buffer, ObjectType, ObjectType->TypeName.Buffer); return(STATUS_UNSUCCESSFUL); } - if (ObjectHeader->ObjectType == PsProcessType) + if (Header->ObjectType == PsProcessType) { DPRINT("Ref p 0x%x refcount %d type %x ", - ObjectBody, ObjectHeader->RefCount, PsProcessType); - DPRINT("eip %x\n", ((PULONG)&ObjectBody)[-1]); + Object, Header->RefCount, PsProcessType); + DPRINT("eip %x\n", ((PULONG)&Object)[-1]); } - if (ObjectHeader->ObjectType == PsThreadType) + if (Header->ObjectType == PsThreadType) { DPRINT("Deref t 0x%x with refcount %d type %x ", - ObjectBody, ObjectHeader->RefCount, PsThreadType); - DPRINT("eip %x\n", ((PULONG)&ObjectBody)[-1]); + Object, Header->RefCount, PsThreadType); + DPRINT("eip %x\n", ((PULONG)&Object)[-1]); } - ObjectHeader->RefCount++; + Header->RefCount++; return(STATUS_SUCCESS); } @@ -413,56 +413,43 @@ ObOpenObjectByPointer(IN POBJECT Object, } -NTSTATUS ObPerformRetentionChecks(POBJECT_HEADER Header) +static NTSTATUS +ObpPerformRetentionChecks(POBJECT_HEADER Header) { -// DPRINT("ObPerformRetentionChecks(Header %x), RefCount %d, HandleCount %d\n", -// Header,Header->RefCount,Header->HandleCount); - - if (Header->RefCount < 0) - { - CPRINT("Object %x/%x has invalid reference count (%d)\n", - Header, HEADER_TO_BODY(Header), Header->RefCount); - KeBugCheck(0); - } - if (Header->HandleCount < 0) - { - CPRINT("Object %x/%x has invalid handle count (%d)\n", - Header, HEADER_TO_BODY(Header), Header->HandleCount); - KeBugCheck(0); - } - - if (Header->RefCount == 0 && Header->HandleCount == 0 && - !Header->Permanent) - { - if (Header->ObjectType != NULL && - Header->ObjectType->Delete != NULL) - { - Header->ObjectType->Delete(HEADER_TO_BODY(Header)); - } - if (Header->Name.Buffer != NULL) - { - ObpRemoveEntryDirectory(Header); - RtlFreeUnicodeString( &Header->Name ); - } - DPRINT("ObPerformRetentionChecks() = Freeing object\n"); - ExFreePool(Header); - } - return(STATUS_SUCCESS); -} - - -ULONG ObGetReferenceCount(PVOID ObjectBody) -{ - POBJECT_HEADER Header = BODY_TO_HEADER(ObjectBody); - - return(Header->RefCount); -} - -ULONG ObGetHandleCount(PVOID ObjectBody) -{ - POBJECT_HEADER Header = BODY_TO_HEADER(ObjectBody); - - return(Header->HandleCount); +// DPRINT("ObPerformRetentionChecks(Header %x), RefCount %d, HandleCount %d\n", +// Header,Header->RefCount,Header->HandleCount); + + if (Header->RefCount < 0) + { + CPRINT("Object %x/%x has invalid reference count (%d)\n", + Header, HEADER_TO_BODY(Header), Header->RefCount); + KeBugCheck(0); + } + if (Header->HandleCount < 0) + { + CPRINT("Object %x/%x has invalid handle count (%d)\n", + Header, HEADER_TO_BODY(Header), Header->HandleCount); + KeBugCheck(0); + } + + if (Header->RefCount == 0 && + Header->HandleCount == 0 && + Header->Permanent == FALSE) + { + if (Header->ObjectType != NULL && + Header->ObjectType->Delete != NULL) + { + Header->ObjectType->Delete(HEADER_TO_BODY(Header)); + } + if (Header->Name.Buffer != NULL) + { + ObpRemoveEntryDirectory(Header); + RtlFreeUnicodeString(&Header->Name); + } + DPRINT("ObPerformRetentionChecks() = Freeing object\n"); + ExFreePool(Header); + } + return(STATUS_SUCCESS); } @@ -480,54 +467,77 @@ ULONG ObGetHandleCount(PVOID ObjectBody) * RETURN VALUE * None. */ -VOID FASTCALL ObfReferenceObject(PVOID Object) +VOID FASTCALL +ObfReferenceObject(IN PVOID Object) { - POBJECT_HEADER Header; + POBJECT_HEADER Header; - assert (Object); + assert(Object); - Header = BODY_TO_HEADER(Object); + Header = BODY_TO_HEADER(Object); - Header->RefCount++; + Header->RefCount++; - ObPerformRetentionChecks (Header); + ObpPerformRetentionChecks(Header); } -VOID FASTCALL ObfDereferenceObject (PVOID Object) -/* - * FUNCTION: Decrements a given object's reference count and performs - * retention checks - * ARGUMENTS: - * Object = Body of the object +/********************************************************************** + * NAME EXPORTED + * ObfDereferenceObject@4 + * + * DESCRIPTION + * Decrements a given object's reference count and performs + * retention checks. + * + * ARGUMENTS + * ObjectBody = Body of the object. + * + * RETURN VALUE + * None. */ +VOID FASTCALL +ObfDereferenceObject(IN PVOID Object) { - POBJECT_HEADER Header; - extern POBJECT_TYPE PsProcessType; + POBJECT_HEADER Header; + extern POBJECT_TYPE PsProcessType; - assert (Object); + assert(Object); - Header = BODY_TO_HEADER(Object); + Header = BODY_TO_HEADER(Object); - if (Header->ObjectType == PsProcessType) - { - DPRINT("Deref p 0x%x with refcount %d type %x ", - Object, Header->RefCount, PsProcessType); - DPRINT("eip %x\n", ((PULONG)&Object)[-1]); - } - if (Header->ObjectType == PsThreadType) - { - DPRINT("Deref t 0x%x with refcount %d type %x ", - Object, Header->RefCount, PsThreadType); - DPRINT("eip %x\n", ((PULONG)&Object)[-1]); - } - - Header->RefCount--; - - ObPerformRetentionChecks(Header); + if (Header->ObjectType == PsProcessType) + { + DPRINT("Deref p 0x%x with refcount %d type %x ", + Object, Header->RefCount, PsProcessType); + DPRINT("eip %x\n", ((PULONG)&Object)[-1]); + } + if (Header->ObjectType == PsThreadType) + { + DPRINT("Deref t 0x%x with refcount %d type %x ", + Object, Header->RefCount, PsThreadType); + DPRINT("eip %x\n", ((PULONG)&Object)[-1]); + } + + Header->RefCount--; + + ObpPerformRetentionChecks(Header); } +/********************************************************************** + * NAME EXPORTED + * ObGetObjectPointerCount@4 + * + * DESCRIPTION + * Retrieves the reference count of the given object. + * + * ARGUMENTS + * ObjectBody = Body of the object. + * + * RETURN VALUE + * Reference count. + */ ULONG STDCALL ObGetObjectPointerCount(PVOID Object) {