Started implementing type objects.

Some object manager cleanup.

svn path=/trunk/; revision=2659
This commit is contained in:
Eric Kohl 2002-03-01 00:47:40 +00:00
parent 3accb67df3
commit 82b7a361af
4 changed files with 279 additions and 152 deletions

View file

@ -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 */

View file

@ -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 <ddk/ntddk.h>
#include <internal/ob.h>
#include <internal/port.h>
#include <internal/dbg.h>
@ -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;

View file

@ -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 */

View file

@ -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)
{