Fix memory leaks in object manager, use tags and use some more public types

svn path=/trunk/; revision=15486
This commit is contained in:
Alex Ionescu 2005-05-24 21:21:34 +00:00
parent ef8d82998d
commit 1d899ce8b3
13 changed files with 354 additions and 195 deletions

View file

@ -63,6 +63,34 @@ typedef NTSTATUS STDCALL_FUNC
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG BufferLength); PULONG BufferLength);
typedef struct _OBJECT_HANDLE_COUNT_ENTRY
{
struct _EPROCESS *Process;
ULONG HandleCount;
} OBJECT_HANDLE_COUNT_ENTRY, *POBJECT_HANDLE_COUNT_ENTRY;
typedef struct _OBJECT_HANDLE_COUNT_DATABASE
{
ULONG CountEntries;
POBJECT_HANDLE_COUNT_ENTRY HandleCountEntries[1];
} OBJECT_HANDLE_COUNT_DATABASE, *POBJECT_HANDLE_COUNT_DATABASE;
typedef struct _OBJECT_HEADER_HANDLE_INFO
{
union {
POBJECT_HANDLE_COUNT_DATABASE HandleCountDatabase;
OBJECT_HANDLE_COUNT_ENTRY SingleEntry;
};
} OBJECT_HEADER_HANDLE_INFO, *POBJECT_HEADER_HANDLE_INFO;
typedef struct _OBJECT_HEADER_CREATOR_INFO
{
LIST_ENTRY TypeList;
PVOID CreatorUniqueProcess;
USHORT CreatorBackTraceIndex;
USHORT Reserved;
} OBJECT_HEADER_CREATOR_INFO, *POBJECT_HEADER_CREATOR_INFO;
typedef struct _OBJECT_HEADER_NAME_INFO typedef struct _OBJECT_HEADER_NAME_INFO
{ {
struct _DIRECTORY_OBJECT *Directory; struct _DIRECTORY_OBJECT *Directory;

View file

@ -122,14 +122,14 @@ CmpFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
CurrentHeader = BODY_TO_HEADER(CurrentObject); CurrentHeader = BODY_TO_HEADER(CurrentObject);
DPRINT("Current ObjectType %wZ\n", DPRINT("Current ObjectType %wZ\n",
&CurrentHeader->ObjectType->TypeName); &CurrentHeader->Type->TypeName);
if (CurrentHeader->ObjectType->TypeInfo.ParseProcedure == NULL) if (CurrentHeader->Type->TypeInfo.ParseProcedure == NULL)
{ {
DPRINT("Current object can't parse\n"); DPRINT("Current object can't parse\n");
break; break;
} }
Status = CurrentHeader->ObjectType->TypeInfo.ParseProcedure(CurrentObject, Status = CurrentHeader->Type->TypeInfo.ParseProcedure(CurrentObject,
&NextObject, &NextObject,
&PathString, &PathString,
&current, &current,

View file

@ -512,7 +512,7 @@ CmiObjectQueryName (PVOID ObjectBody,
else else
{ {
/* KeyObject is the root key */ /* KeyObject is the root key */
Status = ObQueryNameString (BODY_TO_HEADER(KeyObject)->NameInfo->Directory, Status = ObQueryNameString (HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(KeyObject))->Directory,
LocalInfo, LocalInfo,
MAX_PATH * sizeof(WCHAR), MAX_PATH * sizeof(WCHAR),
&LocalReturnLength); &LocalReturnLength);

View file

@ -16,45 +16,46 @@
struct _EPROCESS; struct _EPROCESS;
typedef struct
{
CSHORT Type;
CSHORT Size;
} COMMON_BODY_HEADER, *PCOMMON_BODY_HEADER;
typedef PVOID POBJECT; typedef PVOID POBJECT;
typedef struct _OBJECT_HEADER typedef struct _QUAD
/*
* PURPOSE: Header for every object managed by the object manager
*/
{ {
POBJECT_HEADER_NAME_INFO NameInfo; union {
LIST_ENTRY Entry; LONGLONG UseThisFieldToCopy;
LONG RefCount; float DoNotUseThisField;
LONG HandleCount; };
BOOLEAN Permanent; } QUAD, *PQUAD;
BOOLEAN Inherit;
POBJECT_TYPE ObjectType;
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
PSECURITY_DESCRIPTOR SecurityDescriptor;
/*
* PURPOSE: Object type
* NOTE: This overlaps the first member of the object body
*/
CSHORT Type;
/*
* PURPOSE: Object size
* NOTE: This overlaps the second member of the object body
*/
CSHORT Size;
#define OB_FLAG_CREATE_INFO 0x01 // has OBJECT_CREATE_INFO
#define OB_FLAG_KERNEL_MODE 0x02 // created by kernel
#define OB_FLAG_CREATOR_INFO 0x04 // has OBJECT_CREATOR_INFO
#define OB_FLAG_EXCLUSIVE 0x08 // OBJ_EXCLUSIVE
#define OB_FLAG_PERMANENT 0x10 // OBJ_PERMANENT
#define OB_FLAG_SECURITY 0x20 // has security descriptor
#define OB_FLAG_SINGLE_PROCESS 0x40 // no HandleDBList
/* Will be moved to public headers once "Entry" is gone */
typedef struct _OBJECT_HEADER
{
LIST_ENTRY Entry;
LONG PointerCount;
union {
LONG HandleCount;
PVOID NextToFree;
};
POBJECT_TYPE Type;
UCHAR NameInfoOffset;
UCHAR HandleInfoOffset;
UCHAR QuotaInfoOffset;
UCHAR Flags;
union {
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
PVOID QuotaBlockCharged;
};
PSECURITY_DESCRIPTOR SecurityDescriptor;
QUAD Body;
} OBJECT_HEADER, *POBJECT_HEADER; } OBJECT_HEADER, *POBJECT_HEADER;
typedef struct _DIRECTORY_OBJECT typedef struct _DIRECTORY_OBJECT
{ {
CSHORT Type; CSHORT Type;
@ -92,13 +93,19 @@ enum
OBJTYP_MAX, OBJTYP_MAX,
}; };
#define HEADER_TO_BODY(objhdr) \
(PVOID)((ULONG_PTR)objhdr + sizeof(OBJECT_HEADER) - sizeof(COMMON_BODY_HEADER))
#define BODY_TO_HEADER(objbdy) \ #define BODY_TO_HEADER(objbdy) \
CONTAINING_RECORD(&(((PCOMMON_BODY_HEADER)objbdy)->Type), OBJECT_HEADER, Type) CONTAINING_RECORD((objbdy), OBJECT_HEADER, Body)
#define OBJECT_ALLOC_SIZE(ObjectSize) ((ObjectSize)+sizeof(OBJECT_HEADER)-sizeof(COMMON_BODY_HEADER)) #define HEADER_TO_OBJECT_NAME(objhdr) ((POBJECT_HEADER_NAME_INFO) \
(!(objhdr)->NameInfoOffset ? NULL: ((PCHAR)(objhdr) - (objhdr)->NameInfoOffset)))
#define HEADER_TO_HANDLE_INFO(objhdr) ((POBJECT_HEADER_HANDLE_INFO) \
(!(objhdr)->HandleInfoOffset ? NULL: ((PCHAR)(objhdr) - (objhdr)->HandleInfoOffset)))
#define HEADER_TO_CREATOR_INFO(objhdr) ((POBJECT_HEADER_CREATOR_INFO) \
(!((objhdr)->Flags & OB_FLAG_CREATOR_INFO) ? NULL: ((PCHAR)(objhdr) - sizeof(OBJECT_HEADER_CREATOR_INFO))))
#define OBJECT_ALLOC_SIZE(ObjectSize) ((ObjectSize)+sizeof(OBJECT_HEADER))
#define HANDLE_TO_EX_HANDLE(handle) \ #define HANDLE_TO_EX_HANDLE(handle) \
(LONG)(((LONG)(handle) >> 2) - 1) (LONG)(((LONG)(handle) >> 2) - 1)

View file

@ -63,14 +63,14 @@ IopCreateFile(PVOID ObjectBody,
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
ParentObjectType = BODY_TO_HEADER(Parent)->ObjectType; ParentObjectType = BODY_TO_HEADER(Parent)->Type;
if (ParentObjectType != IoDeviceObjectType && if (ParentObjectType != IoDeviceObjectType &&
ParentObjectType != IoFileObjectType) ParentObjectType != IoFileObjectType)
{ {
DPRINT("Parent [%wZ] is a %S which is neither a file type nor a device type ; remaining path = %S\n", DPRINT("Parent [%wZ] is a %S which is neither a file type nor a device type ; remaining path = %S\n",
&BODY_TO_HEADER(Parent)->NameInfo->Name, &BODY_TO_HEADER(Parent)->NameInfo->Name,
BODY_TO_HEADER(Parent)->ObjectType->Name.Buffer, BODY_TO_HEADER(Parent)->Type->Name.Buffer,
RemainingPath); RemainingPath);
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
@ -870,7 +870,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
{ {
return Status; return Status;
} }
if (BODY_TO_HEADER(DeviceObject)->ObjectType != IoDeviceObjectType) if (BODY_TO_HEADER(DeviceObject)->Type != IoDeviceObjectType)
{ {
ObDereferenceObject (DeviceObject); ObDereferenceObject (DeviceObject);
return STATUS_OBJECT_NAME_COLLISION; return STATUS_OBJECT_NAME_COLLISION;
@ -904,7 +904,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
} }
} }
RtlMapGenericMask(&DesiredAccess, RtlMapGenericMask(&DesiredAccess,
&BODY_TO_HEADER(FileObject)->ObjectType->TypeInfo.GenericMapping); &BODY_TO_HEADER(FileObject)->Type->TypeInfo.GenericMapping);
Status = ObInsertObject ((PVOID)FileObject, Status = ObInsertObject ((PVOID)FileObject,
NULL, NULL,

View file

@ -799,14 +799,14 @@ KiIsObjectWaitable(PVOID Object)
POBJECT_HEADER Header; POBJECT_HEADER Header;
Header = BODY_TO_HEADER(Object); Header = BODY_TO_HEADER(Object);
if (Header->ObjectType == ExEventObjectType || if (Header->Type == ExEventObjectType ||
Header->ObjectType == IoCompletionType || Header->Type == IoCompletionType ||
Header->ObjectType == ExMutantObjectType || Header->Type == ExMutantObjectType ||
Header->ObjectType == ExSemaphoreObjectType || Header->Type == ExSemaphoreObjectType ||
Header->ObjectType == ExTimerType || Header->Type == ExTimerType ||
Header->ObjectType == PsProcessType || Header->Type == PsProcessType ||
Header->ObjectType == PsThreadType || Header->Type == PsThreadType ||
Header->ObjectType == IoFileObjectType) { Header->Type == IoFileObjectType) {
return TRUE; return TRUE;

View file

@ -253,11 +253,11 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
EntryHeader = CONTAINING_RECORD(ListEntry, OBJECT_HEADER, Entry); EntryHeader = CONTAINING_RECORD(ListEntry, OBJECT_HEADER, Entry);
/* calculate the size of the required buffer space for this entry */ /* calculate the size of the required buffer space for this entry */
Name = (EntryHeader->NameInfo->Name.Length != 0 ? &EntryHeader->NameInfo->Name : NULL); Name = (HEADER_TO_OBJECT_NAME(EntryHeader)->Name.Length != 0 ? &HEADER_TO_OBJECT_NAME(EntryHeader)->Name : NULL);
Type = &EntryHeader->ObjectType->Name; Type = &EntryHeader->Type->Name;
EntrySize = sizeof(OBJECT_DIRECTORY_INFORMATION) + EntrySize = sizeof(OBJECT_DIRECTORY_INFORMATION) +
((Name != NULL) ? ((ULONG)Name->Length + sizeof(WCHAR)) : 0) + ((Name != NULL) ? ((ULONG)Name->Length + sizeof(WCHAR)) : 0) +
(ULONG)EntryHeader->ObjectType->Name.Length + sizeof(WCHAR); (ULONG)EntryHeader->Type->Name.Length + sizeof(WCHAR);
if(RequiredSize + EntrySize <= BufferLength) if(RequiredSize + EntrySize <= BufferLength)
{ {

View file

@ -60,19 +60,24 @@ static VOID
ObpDecrementHandleCount(PVOID ObjectBody) ObpDecrementHandleCount(PVOID ObjectBody)
{ {
POBJECT_HEADER ObjectHeader = BODY_TO_HEADER(ObjectBody); POBJECT_HEADER ObjectHeader = BODY_TO_HEADER(ObjectBody);
DPRINT("Header: %x\n", ObjectHeader);
LONG NewHandleCount = InterlockedDecrement(&ObjectHeader->HandleCount); LONG NewHandleCount = InterlockedDecrement(&ObjectHeader->HandleCount);
DPRINT("NewHandleCount: %x\n", NewHandleCount);
DPRINT("HEADER_TO_OBJECT_NAME: %x\n", HEADER_TO_OBJECT_NAME(ObjectHeader));
if ((ObjectHeader->ObjectType != NULL) && if ((ObjectHeader->Type != NULL) &&
(ObjectHeader->ObjectType->TypeInfo.CloseProcedure != NULL)) (ObjectHeader->Type->TypeInfo.CloseProcedure != NULL))
{ {
/* the handle count should be decremented but we pass the previous value /* the handle count should be decremented but we pass the previous value
to the callback */ to the callback */
ObjectHeader->ObjectType->TypeInfo.CloseProcedure(ObjectBody, NewHandleCount + 1); ObjectHeader->Type->TypeInfo.CloseProcedure(ObjectBody, NewHandleCount + 1);
} }
if(NewHandleCount == 0) if(NewHandleCount == 0)
{ {
if(ObjectHeader->NameInfo->Directory != NULL && !ObjectHeader->Permanent) if(HEADER_TO_OBJECT_NAME(ObjectHeader) &&
HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory != NULL &&
!(ObjectHeader->Flags & OB_FLAG_PERMANENT))
{ {
/* delete the object from the namespace when the last handle got closed. /* delete the object from the namespace when the last handle got closed.
Only do this if it's actually been inserted into the namespace and Only do this if it's actually been inserted into the namespace and
@ -215,7 +220,7 @@ ObpDeleteHandle(PHANDLE_TABLE HandleTable,
} }
ObjectHeader = EX_HTE_TO_HDR(HandleEntry); ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
Body = HEADER_TO_BODY(ObjectHeader); Body = &ObjectHeader->Body;
ObpDecrementHandleCount(Body); ObpDecrementHandleCount(Body);
@ -276,7 +281,7 @@ ObDuplicateObject(PEPROCESS SourceProcess,
} }
ObjectHeader = EX_HTE_TO_HDR(SourceHandleEntry); ObjectHeader = EX_HTE_TO_HDR(SourceHandleEntry);
ObjectBody = HEADER_TO_BODY(ObjectHeader); ObjectBody = &ObjectHeader->Body;
NewHandleEntry.u1.Object = SourceHandleEntry->u1.Object; NewHandleEntry.u1.Object = SourceHandleEntry->u1.Object;
if(InheritHandle) if(InheritHandle)
@ -295,7 +300,7 @@ ObDuplicateObject(PEPROCESS SourceProcess,
if (DesiredAccess & GENERIC_ANY) if (DesiredAccess & GENERIC_ANY)
{ {
RtlMapGenericMask(&DesiredAccess, RtlMapGenericMask(&DesiredAccess,
&ObjectHeader->ObjectType->TypeInfo.GenericMapping); &ObjectHeader->Type->TypeInfo.GenericMapping);
} }
NewHandleEntry.u2.GrantedAccess = DesiredAccess; NewHandleEntry.u2.GrantedAccess = DesiredAccess;
} }
@ -524,7 +529,7 @@ DeleteHandleCallback(PHANDLE_TABLE HandleTable,
PAGED_CODE(); PAGED_CODE();
ObjectHeader = EX_OBJ_TO_HDR(Object); ObjectHeader = EX_OBJ_TO_HDR(Object);
ObjectBody = HEADER_TO_BODY(ObjectHeader); ObjectBody = &ObjectHeader->Body;
ObpDecrementHandleCount(ObjectBody); ObpDecrementHandleCount(ObjectBody);
} }
@ -545,7 +550,7 @@ DuplicateHandleCallback(PHANDLE_TABLE HandleTable,
ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry); ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry);
if(InterlockedIncrement(&ObjectHeader->HandleCount) == 1) if(InterlockedIncrement(&ObjectHeader->HandleCount) == 1)
{ {
ObReferenceObject(HEADER_TO_BODY(ObjectHeader)); ObReferenceObject(&ObjectHeader->Body);
} }
} }
@ -631,7 +636,7 @@ ObpCreateHandle(PEPROCESS Process,
if (GrantedAccess & GENERIC_ANY) if (GrantedAccess & GENERIC_ANY)
{ {
RtlMapGenericMask(&GrantedAccess, RtlMapGenericMask(&GrantedAccess,
&ObjectHeader->ObjectType->TypeInfo.GenericMapping); &ObjectHeader->Type->TypeInfo.GenericMapping);
} }
NewEntry.u1.Object = ObjectHeader; NewEntry.u1.Object = ObjectHeader;
@ -822,13 +827,13 @@ ObReferenceObjectByHandle(HANDLE Handle,
} }
ObjectHeader = EX_HTE_TO_HDR(HandleEntry); ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
ObjectBody = HEADER_TO_BODY(ObjectHeader); ObjectBody = &ObjectHeader->Body;
DPRINT("locked1: ObjectHeader: 0x%x [HT:0x%x]\n", ObjectHeader, HandleTable); DPRINT("locked1: ObjectHeader: 0x%x [HT:0x%x]\n", ObjectHeader, HandleTable);
if (ObjectType != NULL && ObjectType != ObjectHeader->ObjectType) if (ObjectType != NULL && ObjectType != ObjectHeader->Type)
{ {
DPRINT("ObjectType mismatch: %wZ vs %wZ (handle 0x%x)\n", &ObjectType->TypeName, ObjectHeader->ObjectType ? &ObjectHeader->ObjectType->TypeName : NULL, Handle); DPRINT("ObjectType mismatch: %wZ vs %wZ (handle 0x%x)\n", &ObjectType->TypeName, ObjectHeader->Type ? &ObjectHeader->Type->TypeName : NULL, Handle);
ExUnlockHandleTableEntry(HandleTable, ExUnlockHandleTableEntry(HandleTable,
HandleEntry); HandleEntry);
@ -842,7 +847,7 @@ ObReferenceObjectByHandle(HANDLE Handle,
if (DesiredAccess & GENERIC_ANY) if (DesiredAccess & GENERIC_ANY)
{ {
RtlMapGenericMask(&DesiredAccess, RtlMapGenericMask(&DesiredAccess,
&BODY_TO_HEADER(ObjectBody)->ObjectType->TypeInfo.GenericMapping); &BODY_TO_HEADER(ObjectBody)->Type->TypeInfo.GenericMapping);
} }
GrantedAccess = HandleEntry->u2.GrantedAccess; GrantedAccess = HandleEntry->u2.GrantedAccess;
@ -963,7 +968,7 @@ ObInsertObject(IN PVOID Object,
DPRINT("ObInsertObject: %x\n", Object); DPRINT("ObInsertObject: %x\n", Object);
Header = BODY_TO_HEADER(Object); Header = BODY_TO_HEADER(Object);
ObjectCreateInfo = Header->ObjectCreateInfo; ObjectCreateInfo = Header->ObjectCreateInfo;
ObjectNameInfo = Header->NameInfo; ObjectNameInfo = HEADER_TO_OBJECT_NAME(Header);
/* First try to find the Object */ /* First try to find the Object */
if (ObjectNameInfo && ObjectNameInfo->Name.Buffer) if (ObjectNameInfo && ObjectNameInfo->Name.Buffer)
@ -1000,10 +1005,9 @@ ObInsertObject(IN PVOID Object,
RtlInitUnicodeString(&RemainingPath, NULL); RtlInitUnicodeString(&RemainingPath, NULL);
} }
if (FoundHeader && FoundHeader->ObjectType == ObDirectoryType && if (FoundHeader && FoundHeader->Type == ObDirectoryType &&
RemainingPath.Buffer) RemainingPath.Buffer)
{ {
DPRINT("Adding to Object Directory\n");
ObpAddEntryDirectory(FoundObject, Header, NULL); ObpAddEntryDirectory(FoundObject, Header, NULL);
ObjectAttached = TRUE; ObjectAttached = TRUE;
@ -1013,7 +1017,7 @@ ObInsertObject(IN PVOID Object,
PWSTR BufferPos = RemainingPath.Buffer; PWSTR BufferPos = RemainingPath.Buffer;
NewName = ExAllocatePool(NonPagedPool, RemainingPath.MaximumLength); NewName = ExAllocatePool(NonPagedPool, RemainingPath.MaximumLength);
ObjectNameInfo = Header->NameInfo; ObjectNameInfo = HEADER_TO_OBJECT_NAME(Header);
if (BufferPos[0] == L'\\') if (BufferPos[0] == L'\\')
{ {
@ -1028,36 +1032,36 @@ ObInsertObject(IN PVOID Object,
DPRINT("Name: %S\n", ObjectNameInfo->Name.Buffer); DPRINT("Name: %S\n", ObjectNameInfo->Name.Buffer);
} }
if ((Header->ObjectType == IoFileObjectType) || if ((Header->Type == IoFileObjectType) ||
(Header->ObjectType == ExDesktopObjectType) || (Header->Type == ExDesktopObjectType) ||
(Header->ObjectType->TypeInfo.OpenProcedure != NULL)) (Header->Type->TypeInfo.OpenProcedure != NULL))
{ {
DPRINT("About to call Open Routine\n"); DPRINT("About to call Open Routine\n");
if (Header->ObjectType == IoFileObjectType) if (Header->Type == IoFileObjectType)
{ {
/* TEMPORARY HACK. DO NOT TOUCH -- Alex */ /* TEMPORARY HACK. DO NOT TOUCH -- Alex */
DPRINT("Calling IopCreateFile: %x\n", FoundObject); DPRINT("Calling IopCreateFile: %x\n", FoundObject);
Status = IopCreateFile(HEADER_TO_BODY(Header), Status = IopCreateFile(&Header->Body,
FoundObject, FoundObject,
RemainingPath.Buffer, RemainingPath.Buffer,
ObjectCreateInfo); ObjectCreateInfo);
DPRINT("Called IopCreateFile: %x\n", Status); DPRINT("Called IopCreateFile: %x\n", Status);
} }
else if (Header->ObjectType == ExDesktopObjectType) else if (Header->Type == ExDesktopObjectType)
{ {
/* TEMPORARY HACK. DO NOT TOUCH -- Alex */ /* TEMPORARY HACK. DO NOT TOUCH -- Alex */
DPRINT("Calling ExpDesktopCreate\n"); DPRINT("Calling ExpDesktopCreate\n");
Status = ExpDesktopCreate(HEADER_TO_BODY(Header), Status = ExpDesktopCreate(&Header->Body,
FoundObject, FoundObject,
RemainingPath.Buffer, RemainingPath.Buffer,
ObjectCreateInfo); ObjectCreateInfo);
} }
else if (Header->ObjectType->TypeInfo.OpenProcedure != NULL) else if (Header->Type->TypeInfo.OpenProcedure != NULL)
{ {
DPRINT("Calling %x\n", Header->ObjectType->TypeInfo.OpenProcedure); DPRINT("Calling %x\n", Header->Type->TypeInfo.OpenProcedure);
Status = Header->ObjectType->TypeInfo.OpenProcedure(ObCreateHandle, Status = Header->Type->TypeInfo.OpenProcedure(ObCreateHandle,
HEADER_TO_BODY(Header), &Header->Body,
NULL, NULL,
0, 0,
0); 0);
@ -1088,19 +1092,19 @@ ObInsertObject(IN PVOID Object,
Status = SeAssignSecurity((FoundHeader != NULL) ? FoundHeader->SecurityDescriptor : NULL, Status = SeAssignSecurity((FoundHeader != NULL) ? FoundHeader->SecurityDescriptor : NULL,
(ObjectCreateInfo != NULL) ? ObjectCreateInfo->SecurityDescriptor : NULL, (ObjectCreateInfo != NULL) ? ObjectCreateInfo->SecurityDescriptor : NULL,
&NewSecurityDescriptor, &NewSecurityDescriptor,
(Header->ObjectType == ObDirectoryType), (Header->Type == ObDirectoryType),
&SubjectContext, &SubjectContext,
&Header->ObjectType->TypeInfo.GenericMapping, &Header->Type->TypeInfo.GenericMapping,
PagedPool); PagedPool);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
DPRINT("NewSecurityDescriptor %p\n", NewSecurityDescriptor); DPRINT("NewSecurityDescriptor %p\n", NewSecurityDescriptor);
if (Header->ObjectType->TypeInfo.SecurityProcedure != NULL) if (Header->Type->TypeInfo.SecurityProcedure != NULL)
{ {
/* Call the security method */ /* Call the security method */
Status = Header->ObjectType->TypeInfo.SecurityProcedure(HEADER_TO_BODY(Header), Status = Header->Type->TypeInfo.SecurityProcedure(&Header->Body,
AssignSecurityDescriptor, AssignSecurityDescriptor,
0, 0,
NewSecurityDescriptor, NewSecurityDescriptor,
@ -1121,11 +1125,6 @@ ObInsertObject(IN PVOID Object,
DPRINT("Security Complete\n"); DPRINT("Security Complete\n");
SeReleaseSubjectContext(&SubjectContext); SeReleaseSubjectContext(&SubjectContext);
/* We can delete the Create Info now */
Header->ObjectCreateInfo = NULL;
ObpReleaseCapturedAttributes(ObjectCreateInfo);
ExFreePool(ObjectCreateInfo);
/* Create the Handle */ /* Create the Handle */
/* HACKHACK: Because of ROS's incorrect startup, this can be called /* HACKHACK: Because of ROS's incorrect startup, this can be called
* without a valid Process until I finalize the startup patch, * without a valid Process until I finalize the startup patch,
@ -1137,14 +1136,19 @@ ObInsertObject(IN PVOID Object,
if (Handle != NULL) if (Handle != NULL)
{ {
Status = ObpCreateHandle(PsGetCurrentProcess(), Status = ObpCreateHandle(PsGetCurrentProcess(),
HEADER_TO_BODY(Header), &Header->Body,
DesiredAccess, DesiredAccess,
Header->Inherit, ObjectCreateInfo->Attributes & OBJ_INHERIT,
Handle); Handle);
DPRINT("handle Created: %d. refcount. handlecount %d %d\n", DPRINT("handle Created: %d. refcount. handlecount %d %d\n",
*Handle, Header->RefCount, Header->HandleCount); *Handle, Header->RefCount, Header->HandleCount);
} }
/* We can delete the Create Info now */
Header->ObjectCreateInfo = NULL;
ObpReleaseCapturedAttributes(ObjectCreateInfo);
ExFreePool(ObjectCreateInfo);
DPRINT("Status %x\n", Status); DPRINT("Status %x\n", Status);
return Status; return Status;
} }
@ -1227,7 +1231,7 @@ ObpGetNextHandleByProcessCount(PSYSTEM_HANDLE_TABLE_ENTRY_INFO pshi,
// pshi->GrantedAccess; // pshi->GrantedAccess;
// pshi->Object; // pshi->Object;
// pshi->ObjectTypeIndex; // pshi->TypeIndex;
// pshi->HandleAttributes; // pshi->HandleAttributes;
// KeReleaseSpinLock( &Process->HandleTable.ListLock, oldIrql ); // KeReleaseSpinLock( &Process->HandleTable.ListLock, oldIrql );

View file

@ -256,7 +256,8 @@ ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
{ {
KIRQL oldlvl; KIRQL oldlvl;
Header->NameInfo->Directory = Parent; ASSERT(HEADER_TO_OBJECT_NAME(Header));
HEADER_TO_OBJECT_NAME(Header)->Directory = Parent;
KeAcquireSpinLock(&Parent->Lock, &oldlvl); KeAcquireSpinLock(&Parent->Lock, &oldlvl);
InsertTailList(&Parent->head, &Header->Entry); InsertTailList(&Parent->head, &Header->Entry);
@ -276,13 +277,13 @@ ObpRemoveEntryDirectory(POBJECT_HEADER Header)
DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header); DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header);
KeAcquireSpinLock(&(Header->NameInfo->Directory->Lock),&oldlvl); KeAcquireSpinLock(&(HEADER_TO_OBJECT_NAME(Header)->Directory->Lock),&oldlvl);
if (Header->Entry.Flink && Header->Entry.Blink) if (Header->Entry.Flink && Header->Entry.Blink)
{ {
RemoveEntryList(&(Header->Entry)); RemoveEntryList(&(Header->Entry));
Header->Entry.Flink = Header->Entry.Blink = NULL; Header->Entry.Flink = Header->Entry.Blink = NULL;
} }
KeReleaseSpinLock(&(Header->NameInfo->Directory->Lock),oldlvl); KeReleaseSpinLock(&(HEADER_TO_OBJECT_NAME(Header)->Directory->Lock),oldlvl);
} }
NTSTATUS NTSTATUS
@ -324,26 +325,26 @@ ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject,
} }
if (Name[0]=='.' && Name[1]=='.' && Name[2]==0) if (Name[0]=='.' && Name[1]=='.' && Name[2]==0)
{ {
return(BODY_TO_HEADER(DirectoryObject)->NameInfo->Directory); return(HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(DirectoryObject))->Directory);
} }
while (current!=(&(DirectoryObject->head))) while (current!=(&(DirectoryObject->head)))
{ {
current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry); current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry);
DPRINT(" Scanning: %S for: %S\n",current_obj->NameInfo->Name.Buffer, Name); DPRINT(" Scanning: %S for: %S\n",HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name);
if (Attributes & OBJ_CASE_INSENSITIVE) if (Attributes & OBJ_CASE_INSENSITIVE)
{ {
if (_wcsicmp(current_obj->NameInfo->Name.Buffer, Name)==0) if (_wcsicmp(HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name)==0)
{ {
DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj)); DPRINT("Found it %x\n",&current_obj->Body);
return(HEADER_TO_BODY(current_obj)); return(&current_obj->Body);
} }
} }
else else
{ {
if ( wcscmp(current_obj->NameInfo->Name.Buffer, Name)==0) if ( wcscmp(HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name)==0)
{ {
DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj)); DPRINT("Found it %x\n",&current_obj->Body);
return(HEADER_TO_BODY(current_obj)); return(&current_obj->Body);
} }
} }
current = current->Flink; current = current->Flink;
@ -550,16 +551,42 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
return Status; return Status;
} }
LocalObjectType = HEADER_TO_BODY(Header); LocalObjectType = (POBJECT_TYPE)&Header->Body;
DPRINT("Local ObjectType: %p Header: %p \n", LocalObjectType, Header);
/* Check if this is the first Object Type */ /* Check if this is the first Object Type */
if (!ObTypeObjectType) if (!ObTypeObjectType)
{ {
ObTypeObjectType = LocalObjectType; ObTypeObjectType = LocalObjectType;
Header->ObjectType = ObTypeObjectType; Header->Type = ObTypeObjectType;
LocalObjectType->Key = TAG('O', 'b', 'j', 'T');
} }
else
{
#if 0
ANSI_STRING Tag;
ULONG i;
/* FIXME: Generate Tag */ DPRINT1("Convert: %wZ \n", TypeName);
Status = RtlUnicodeStringToAnsiString(&Tag, TypeName, TRUE);
DPRINT1("Convert done\n");
if (NT_SUCCESS(Status))
{
/* Add spaces if needed */
for (i = 3; i >= Tag.Length; i--) Tag.Buffer[i] = ' ';
/* Use the first four letters */
LocalObjectType->Key = *(PULONG)Tag.Buffer;
ExFreePool(Tag.Buffer);
}
else
#endif
{
/* Some weird problem. Use Unicode name */
LocalObjectType->Key = *(PULONG)TypeName->Buffer;
Status = STATUS_SUCCESS;
}
}
/* Set it up */ /* Set it up */
LocalObjectType->TypeInfo = *ObjectTypeInitializer; LocalObjectType->TypeInfo = *ObjectTypeInitializer;

View file

@ -122,13 +122,13 @@ NtQueryObject (IN HANDLE ObjectHandle,
BasicInfo->Attributes = HandleInfo.HandleAttributes; BasicInfo->Attributes = HandleInfo.HandleAttributes;
BasicInfo->GrantedAccess = HandleInfo.GrantedAccess; BasicInfo->GrantedAccess = HandleInfo.GrantedAccess;
BasicInfo->HandleCount = ObjectHeader->HandleCount; BasicInfo->HandleCount = ObjectHeader->HandleCount;
BasicInfo->PointerCount = ObjectHeader->RefCount; BasicInfo->PointerCount = ObjectHeader->PointerCount;
BasicInfo->PagedPoolUsage = 0; /* FIXME*/ BasicInfo->PagedPoolUsage = 0; /* FIXME*/
BasicInfo->NonPagedPoolUsage = 0; /* FIXME*/ BasicInfo->NonPagedPoolUsage = 0; /* FIXME*/
BasicInfo->NameInformationLength = 0; /* FIXME*/ BasicInfo->NameInformationLength = 0; /* FIXME*/
BasicInfo->TypeInformationLength = 0; /* FIXME*/ BasicInfo->TypeInformationLength = 0; /* FIXME*/
BasicInfo->SecurityDescriptorLength = 0; /* FIXME*/ BasicInfo->SecurityDescriptorLength = 0; /* FIXME*/
if (ObjectHeader->ObjectType == ObSymbolicLinkType) if (ObjectHeader->Type == ObSymbolicLinkType)
{ {
BasicInfo->CreateTime.QuadPart = BasicInfo->CreateTime.QuadPart =
((PSYMLINK_OBJECT)Object)->CreateTime.QuadPart; ((PSYMLINK_OBJECT)Object)->CreateTime.QuadPart;
@ -169,10 +169,10 @@ NtQueryObject (IN HANDLE ObjectHandle,
break; break;
} }
RtlCopyUnicodeString(&typeinfo->Type,&ObjectHeader->ObjectType->TypeName); RtlCopyUnicodeString(&typeinfo->Type,&ObjectHeader->Type->TypeName);
//This should be info from the object header, not the object type, right? //This should be info from the object header, not the object type, right?
typeinfo->TotalHandles = ObjectHeader-> HandleCount; typeinfo->TotalHandles = ObjectHeader-> HandleCount;
typeinfo->ReferenceCount = ObjectHeader -> RefCount; typeinfo->ReferenceCount = ObjectHeader -> PointerCount;
} }
#endif #endif
Status = STATUS_NOT_IMPLEMENTED; Status = STATUS_NOT_IMPLEMENTED;
@ -223,9 +223,9 @@ ObpSetPermanentObject (IN PVOID ObjectBody, IN BOOLEAN Permanent)
POBJECT_HEADER ObjectHeader; POBJECT_HEADER ObjectHeader;
ObjectHeader = BODY_TO_HEADER(ObjectBody); ObjectHeader = BODY_TO_HEADER(ObjectBody);
ObjectHeader->Permanent = Permanent; ObjectHeader->Flags |= OB_FLAG_PERMANENT;
if (ObjectHeader->HandleCount == 0 && !Permanent && ObjectHeader->NameInfo->Directory) if (ObjectHeader->HandleCount == 0 && !Permanent && HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory)
{ {
/* Remove the object from the namespace */ /* Remove the object from the namespace */
ObpRemoveEntryDirectory(ObjectHeader); ObpRemoveEntryDirectory(ObjectHeader);

View file

@ -379,14 +379,14 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
CurrentHeader = BODY_TO_HEADER(CurrentObject); CurrentHeader = BODY_TO_HEADER(CurrentObject);
DPRINT("Current ObjectType %wZ\n", DPRINT("Current ObjectType %wZ\n",
&CurrentHeader->ObjectType->Name); &CurrentHeader->Type->Name);
if (CurrentHeader->ObjectType->TypeInfo.ParseProcedure == NULL) if (CurrentHeader->Type->TypeInfo.ParseProcedure == NULL)
{ {
DPRINT("Current object can't parse\n"); DPRINT("Current object can't parse\n");
break; break;
} }
Status = CurrentHeader->ObjectType->TypeInfo.ParseProcedure(CurrentObject, Status = CurrentHeader->Type->TypeInfo.ParseProcedure(CurrentObject,
&NextObject, &NextObject,
&PathString, &PathString,
&current, &current,
@ -461,27 +461,27 @@ ObQueryNameString (IN PVOID Object,
ObjectHeader = BODY_TO_HEADER(Object); ObjectHeader = BODY_TO_HEADER(Object);
if (ObjectHeader->ObjectType != NULL && if (ObjectHeader->Type != NULL &&
ObjectHeader->ObjectType->TypeInfo.QueryNameProcedure != NULL) ObjectHeader->Type->TypeInfo.QueryNameProcedure != NULL)
{ {
DPRINT ("Calling %x\n", ObjectHeader->ObjectType->TypeInfo.QueryNameProcedure); DPRINT ("Calling %x\n", ObjectHeader->Type->TypeInfo.QueryNameProcedure);
Status = ObjectHeader->ObjectType->TypeInfo.QueryNameProcedure (Object, Status = ObjectHeader->Type->TypeInfo.QueryNameProcedure (Object,
ObjectNameInfo, ObjectNameInfo,
Length, Length,
ReturnLength); ReturnLength);
} }
else if (ObjectHeader->NameInfo->Name.Length > 0 && ObjectHeader->NameInfo->Name.Buffer != NULL) else if (HEADER_TO_OBJECT_NAME(ObjectHeader)->Name.Length > 0 && HEADER_TO_OBJECT_NAME(ObjectHeader)->Name.Buffer != NULL)
{ {
DPRINT ("Object does not have a 'QueryName' function\n"); DPRINT ("Object does not have a 'QueryName' function\n");
if (ObjectHeader->NameInfo->Directory == NameSpaceRoot) if (HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory == NameSpaceRoot)
{ {
DPRINT ("Reached the root directory\n"); DPRINT ("Reached the root directory\n");
ObjectNameInfo->Name.Length = 0; ObjectNameInfo->Name.Length = 0;
ObjectNameInfo->Name.Buffer[0] = 0; ObjectNameInfo->Name.Buffer[0] = 0;
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
else if (ObjectHeader->NameInfo->Directory != NULL) else if (HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory != NULL)
{ {
LocalInfo = ExAllocatePool (NonPagedPool, LocalInfo = ExAllocatePool (NonPagedPool,
sizeof(OBJECT_NAME_INFORMATION) + sizeof(OBJECT_NAME_INFORMATION) +
@ -489,7 +489,7 @@ ObQueryNameString (IN PVOID Object,
if (LocalInfo == NULL) if (LocalInfo == NULL)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
Status = ObQueryNameString (ObjectHeader->NameInfo->Directory, Status = ObQueryNameString (HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory,
LocalInfo, LocalInfo,
MAX_PATH * sizeof(WCHAR), MAX_PATH * sizeof(WCHAR),
&LocalReturnLength); &LocalReturnLength);
@ -508,14 +508,14 @@ ObQueryNameString (IN PVOID Object,
return Status; return Status;
} }
DPRINT ("Object path %wZ\n", &ObjectHeader->NameInfo->Name); DPRINT ("Object path %wZ\n", &HEADER_TO_OBJECT_NAME(ObjectHeader)->Name);
Status = RtlAppendUnicodeToString (&ObjectNameInfo->Name, Status = RtlAppendUnicodeToString (&ObjectNameInfo->Name,
L"\\"); L"\\");
if (!NT_SUCCESS (Status)) if (!NT_SUCCESS (Status))
return Status; return Status;
Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name, Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
&ObjectHeader->NameInfo->Name); &HEADER_TO_OBJECT_NAME(ObjectHeader)->Name);
} }
else else
{ {
@ -549,8 +549,14 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
POBJECT_HEADER *ObjectHeader) POBJECT_HEADER *ObjectHeader)
{ {
POBJECT_HEADER Header; POBJECT_HEADER Header;
POBJECT_HEADER_NAME_INFO ObjectNameInfo; BOOLEAN HasHandleInfo = FALSE;
BOOLEAN HasNameInfo = FALSE;
BOOLEAN HasCreatorInfo = FALSE;
POBJECT_HEADER_HANDLE_INFO HandleInfo;
POBJECT_HEADER_NAME_INFO NameInfo;
POBJECT_HEADER_CREATOR_INFO CreatorInfo;
POOL_TYPE PoolType; POOL_TYPE PoolType;
ULONG FinalSize = ObjectSize;
ULONG Tag; ULONG Tag;
/* If we don't have an Object Type yet, force NonPaged */ /* If we don't have an Object Type yet, force NonPaged */
@ -566,35 +572,104 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
Tag = ObjectType->Key; Tag = ObjectType->Key;
} }
/* Allocate memory for the Object */ DPRINT("Checking ObjectName: %x\n", ObjectName);
Header = ExAllocatePoolWithTag(PoolType, ObjectSize, Tag); /* Check if the Object has a name */
if (ObjectName->Buffer)
{
FinalSize += sizeof(OBJECT_HEADER_NAME_INFO);
HasNameInfo = TRUE;
}
if (ObjectType)
{
/* Check if the Object maintains handle counts */
DPRINT("Checking ObjectType->TypeInfo: %x\n", &ObjectType->TypeInfo);
if (ObjectType->TypeInfo.MaintainHandleCount)
{
FinalSize += sizeof(OBJECT_HEADER_HANDLE_INFO);
HasHandleInfo = TRUE;
}
/* Check if the Object maintains type lists */
if (ObjectType->TypeInfo.MaintainTypeList)
{
FinalSize += sizeof(OBJECT_HEADER_CREATOR_INFO);
HasCreatorInfo = TRUE;
}
}
/* Allocate memory for the Object and Header */
DPRINT("Allocating: %x %x\n", FinalSize, Tag);
Header = ExAllocatePoolWithTag(PoolType, FinalSize, Tag);
if (!Header) { if (!Header) {
DPRINT1("Not enough memory!\n"); DPRINT1("Not enough memory!\n");
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
/* Initialize Handle Info */
if (HasHandleInfo)
{
HandleInfo = (POBJECT_HEADER_HANDLE_INFO)Header;
DPRINT("Info: %x\n", HandleInfo);
HandleInfo->SingleEntry.HandleCount = 0;
Header = (POBJECT_HEADER)(HandleInfo + 1);
}
/* Initialize the Object Name Info */
if (HasNameInfo)
{
NameInfo = (POBJECT_HEADER_NAME_INFO)Header;
DPRINT("Info: %x %wZ\n", NameInfo, ObjectName);
NameInfo->Name = *ObjectName;
NameInfo->Directory = NULL;
Header = (POBJECT_HEADER)(NameInfo + 1);
}
/* Initialize Creator Info */
if (HasCreatorInfo)
{
CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)Header;
DPRINT("Info: %x\n", CreatorInfo);
/* FIXME: Needs Alex's Init patch
* CreatorInfo->CreatorUniqueProcess = PsGetCurrentProcessId();
*/
InitializeListHead(&CreatorInfo->TypeList);
Header = (POBJECT_HEADER)(CreatorInfo + 1);
}
/* Initialize the object header */ /* Initialize the object header */
RtlZeroMemory(Header, ObjectSize); RtlZeroMemory(Header, ObjectSize);
DPRINT("Initalizing header %p\n", Header); DPRINT("Initalized header %p\n", Header);
Header->HandleCount = 0; Header->HandleCount = 0;
Header->RefCount = 1; Header->PointerCount = 1;
Header->ObjectType = ObjectType; Header->Type = ObjectType;
Header->Flags = OB_FLAG_CREATE_INFO;
/* Set the Offsets for the Info */
if (HasHandleInfo)
{
Header->HandleInfoOffset = HasNameInfo * sizeof(OBJECT_HEADER_NAME_INFO) +
sizeof(OBJECT_HEADER_HANDLE_INFO) +
HasCreatorInfo * sizeof(OBJECT_HEADER_CREATOR_INFO);
Header->Flags |= OB_FLAG_SINGLE_PROCESS;
}
if (HasNameInfo)
{
Header->NameInfoOffset = sizeof(OBJECT_HEADER_NAME_INFO) +
HasCreatorInfo * sizeof(OBJECT_HEADER_CREATOR_INFO);
}
if (HasCreatorInfo) Header->Flags |= OB_FLAG_CREATOR_INFO;
if (ObjectCreateInfo && ObjectCreateInfo->Attributes & OBJ_PERMANENT) if (ObjectCreateInfo && ObjectCreateInfo->Attributes & OBJ_PERMANENT)
{ {
Header->Permanent = TRUE; Header->Flags |= OB_FLAG_PERMANENT;
} }
if (ObjectCreateInfo && ObjectCreateInfo->Attributes & OBJ_INHERIT) if (ObjectCreateInfo && ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE)
{ {
Header->Inherit = TRUE; Header->Flags |= OB_FLAG_EXCLUSIVE;
} }
/* Initialize the Object Name Info [part of header in OB 2.0] */
ObjectNameInfo = ExAllocatePool(PoolType, ObjectSize);
ObjectNameInfo->Name = *ObjectName;
ObjectNameInfo->Directory = NULL;
/* Link stuff to Object Header */ /* Link stuff to Object Header */
Header->NameInfo = ObjectNameInfo;
Header->ObjectCreateInfo = ObjectCreateInfo; Header->ObjectCreateInfo = ObjectCreateInfo;
/* Return Header */ /* Return Header */
@ -663,7 +738,7 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
{ {
/* Return the Object */ /* Return the Object */
DPRINT("Returning Object\n"); DPRINT("Returning Object\n");
*Object = HEADER_TO_BODY(Header); *Object = &Header->Body;
/* Return to caller, leave the Capture Info Alive for ObInsert */ /* Return to caller, leave the Capture Info Alive for ObInsert */
return Status; return Status;
@ -707,43 +782,43 @@ ObReferenceObjectByPointer(IN PVOID Object,
Header = BODY_TO_HEADER(Object); Header = BODY_TO_HEADER(Object);
if (ObjectType != NULL && Header->ObjectType != ObjectType) if (ObjectType != NULL && Header->Type != ObjectType)
{ {
DPRINT("Failed %p (type was %x %wZ) should be %x %wZ\n", DPRINT("Failed %p (type was %x %wZ) should be %x %wZ\n",
Header, Header,
Header->ObjectType, Header->Type,
&BODY_TO_HEADER(Header->ObjectType)->NameInfo, &BODY_TO_HEADER(Header->Type)->NameInfo,
ObjectType, ObjectType,
&BODY_TO_HEADER(ObjectType)->NameInfo); &BODY_TO_HEADER(ObjectType)->NameInfo);
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
if (Header->ObjectType == PsProcessType) if (Header->Type == PsProcessType)
{ {
DPRINT("Ref p 0x%x refcount %d type %x ", DPRINT("Ref p 0x%x PointerCount %d type %x ",
Object, Header->RefCount, PsProcessType); Object, Header->PointerCount, PsProcessType);
DPRINT("eip %x\n", ((PULONG)&Object)[-1]); DPRINT("eip %x\n", ((PULONG)&Object)[-1]);
} }
if (Header->ObjectType == PsThreadType) if (Header->Type == PsThreadType)
{ {
DPRINT("Deref t 0x%x with refcount %d type %x ", DPRINT("Deref t 0x%x with PointerCount %d type %x ",
Object, Header->RefCount, PsThreadType); Object, Header->PointerCount, PsThreadType);
DPRINT("eip %x\n", ((PULONG)&Object)[-1]); DPRINT("eip %x\n", ((PULONG)&Object)[-1]);
} }
if (Header->RefCount == 0 && !Header->Permanent) if (Header->PointerCount == 0 && !(Header->Flags & OB_FLAG_PERMANENT))
{ {
if (Header->ObjectType == PsProcessType) if (Header->Type == PsProcessType)
{ {
return STATUS_PROCESS_IS_TERMINATING; return STATUS_PROCESS_IS_TERMINATING;
} }
if (Header->ObjectType == PsThreadType) if (Header->Type == PsThreadType)
{ {
return STATUS_THREAD_IS_TERMINATING; return STATUS_THREAD_IS_TERMINATING;
} }
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
if (1 == InterlockedIncrement(&Header->RefCount) && !Header->Permanent) if (1 == InterlockedIncrement(&Header->PointerCount) && !(Header->Flags & OB_FLAG_PERMANENT))
{ {
KEBUGCHECK(0); KEBUGCHECK(0);
} }
@ -794,6 +869,11 @@ ObOpenObjectByPointer(IN POBJECT Object,
static NTSTATUS static NTSTATUS
ObpDeleteObject(POBJECT_HEADER Header) ObpDeleteObject(POBJECT_HEADER Header)
{ {
PVOID HeaderLocation = Header;
POBJECT_HEADER_HANDLE_INFO HandleInfo;
POBJECT_HEADER_NAME_INFO NameInfo;
POBJECT_HEADER_CREATOR_INFO CreatorInfo;
DPRINT("ObpDeleteObject(Header %p)\n", Header); DPRINT("ObpDeleteObject(Header %p)\n", Header);
if (KeGetCurrentIrql() != PASSIVE_LEVEL) if (KeGetCurrentIrql() != PASSIVE_LEVEL)
{ {
@ -801,10 +881,10 @@ ObpDeleteObject(POBJECT_HEADER Header)
KEBUGCHECK(0); KEBUGCHECK(0);
} }
if (Header->ObjectType != NULL && if (Header->Type != NULL &&
Header->ObjectType->TypeInfo.DeleteProcedure != NULL) Header->Type->TypeInfo.DeleteProcedure != NULL)
{ {
Header->ObjectType->TypeInfo.DeleteProcedure(HEADER_TO_BODY(Header)); Header->Type->TypeInfo.DeleteProcedure(&Header->Body);
} }
if (Header->SecurityDescriptor != NULL) if (Header->SecurityDescriptor != NULL)
@ -812,13 +892,12 @@ ObpDeleteObject(POBJECT_HEADER Header)
ObpRemoveSecurityDescriptor(Header->SecurityDescriptor); ObpRemoveSecurityDescriptor(Header->SecurityDescriptor);
} }
if (Header->NameInfo) if (HEADER_TO_OBJECT_NAME(Header))
{ {
if(Header->NameInfo->Name.Buffer) if(HEADER_TO_OBJECT_NAME(Header)->Name.Buffer)
{ {
ExFreePool(Header->NameInfo->Name.Buffer); ExFreePool(HEADER_TO_OBJECT_NAME(Header)->Name.Buffer);
} }
ExFreePool(Header->NameInfo);
} }
if (Header->ObjectCreateInfo) if (Header->ObjectCreateInfo)
{ {
@ -826,8 +905,22 @@ ObpDeleteObject(POBJECT_HEADER Header)
ExFreePool(Header->ObjectCreateInfo); ExFreePool(Header->ObjectCreateInfo);
} }
/* To find the header, walk backwards from how we allocated */
if ((CreatorInfo = HEADER_TO_CREATOR_INFO(Header)))
{
HeaderLocation = CreatorInfo;
}
if ((NameInfo = HEADER_TO_OBJECT_NAME(Header)))
{
HeaderLocation = NameInfo;
}
if ((HandleInfo = HEADER_TO_HANDLE_INFO(Header)))
{
HeaderLocation = HandleInfo;
}
DPRINT("ObPerformRetentionChecks() = Freeing object\n"); DPRINT("ObPerformRetentionChecks() = Freeing object\n");
ExFreePool(Header); ExFreePool(HeaderLocation);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -843,7 +936,7 @@ ObpDeleteObjectWorkRoutine (IN PVOID Parameter)
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); /* We need PAGED_CODE somewhere... */ ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); /* We need PAGED_CODE somewhere... */
/* Turn this on when we have ExFreePoolWithTag /* Turn this on when we have ExFreePoolWithTag
Tag = Params->ObjectHeader->ObjectType->Tag; */ Tag = Params->ObjectHeader->Type->Tag; */
ObpDeleteObject(Params->ObjectHeader); ObpDeleteObject(Params->ObjectHeader);
ExFreePool(Params); ExFreePool(Params);
/* ExFreePoolWithTag(Params, Tag); */ /* ExFreePoolWithTag(Params, Tag); */
@ -852,14 +945,14 @@ ObpDeleteObjectWorkRoutine (IN PVOID Parameter)
STATIC NTSTATUS STATIC NTSTATUS
ObpDeleteObjectDpcLevel(IN POBJECT_HEADER ObjectHeader, ObpDeleteObjectDpcLevel(IN POBJECT_HEADER ObjectHeader,
IN LONG OldRefCount) IN LONG OldPointerCount)
{ {
#if 0 #if 0
if (ObjectHeader->RefCount < 0) if (ObjectHeader->PointerCount < 0)
{ {
CPRINT("Object %p/%p has invalid reference count (%d)\n", CPRINT("Object %p/%p has invalid reference count (%d)\n",
ObjectHeader, HEADER_TO_BODY(ObjectHeader), ObjectHeader, HEADER_TO_BODY(ObjectHeader),
ObjectHeader->RefCount); ObjectHeader->PointerCount);
KEBUGCHECK(0); KEBUGCHECK(0);
} }
@ -890,7 +983,7 @@ ObpDeleteObjectDpcLevel(IN POBJECT_HEADER ObjectHeader,
Params = (PRETENTION_CHECK_PARAMS) Params = (PRETENTION_CHECK_PARAMS)
ExAllocatePoolWithTag(NonPagedPoolMustSucceed, ExAllocatePoolWithTag(NonPagedPoolMustSucceed,
sizeof(RETENTION_CHECK_PARAMS), sizeof(RETENTION_CHECK_PARAMS),
ObjectHeader->ObjectType->Key); ObjectHeader->Type->Key);
Params->ObjectHeader = ObjectHeader; Params->ObjectHeader = ObjectHeader;
ExInitializeWorkItem(&Params->WorkItem, ExInitializeWorkItem(&Params->WorkItem,
ObpDeleteObjectWorkRoutine, ObpDeleteObjectWorkRoutine,
@ -937,7 +1030,7 @@ ObfReferenceObject(IN PVOID Object)
Header = BODY_TO_HEADER(Object); Header = BODY_TO_HEADER(Object);
/* No one should be referencing an object once we are deleting it. */ /* No one should be referencing an object once we are deleting it. */
if (InterlockedIncrement(&Header->RefCount) == 1 && !Header->Permanent) if (InterlockedIncrement(&Header->PointerCount) == 1 && !(Header->Flags & OB_FLAG_PERMANENT))
{ {
KEBUGCHECK(0); KEBUGCHECK(0);
} }
@ -964,28 +1057,28 @@ VOID FASTCALL
ObfDereferenceObject(IN PVOID Object) ObfDereferenceObject(IN PVOID Object)
{ {
POBJECT_HEADER Header; POBJECT_HEADER Header;
LONG NewRefCount; LONG NewPointerCount;
BOOL Permanent; BOOL Permanent;
ASSERT(Object); ASSERT(Object);
/* Extract the object header. */ /* Extract the object header. */
Header = BODY_TO_HEADER(Object); Header = BODY_TO_HEADER(Object);
Permanent = Header->Permanent; Permanent = Header->Flags & OB_FLAG_PERMANENT;
/* /*
Drop our reference and get the new count so we can tell if this was the Drop our reference and get the new count so we can tell if this was the
last reference. last reference.
*/ */
NewRefCount = InterlockedDecrement(&Header->RefCount); NewPointerCount = InterlockedDecrement(&Header->PointerCount);
DPRINT("ObfDereferenceObject(0x%x)==%d\n", Object, NewRefCount); DPRINT("ObfDereferenceObject(0x%x)==%d\n", Object, NewPointerCount);
ASSERT(NewRefCount >= 0); ASSERT(NewPointerCount >= 0);
/* Check whether the object can now be deleted. */ /* Check whether the object can now be deleted. */
if (NewRefCount == 0 && if (NewPointerCount == 0 &&
!Permanent) !Permanent)
{ {
ObpDeleteObjectDpcLevel(Header, NewRefCount); ObpDeleteObjectDpcLevel(Header, NewPointerCount);
} }
} }
@ -1065,7 +1158,7 @@ ObGetObjectPointerCount(PVOID Object)
ASSERT(Object); ASSERT(Object);
Header = BODY_TO_HEADER(Object); Header = BODY_TO_HEADER(Object);
return Header->RefCount; return Header->PointerCount;
} }

View file

@ -79,10 +79,10 @@ ObGetObjectSecurity(IN PVOID Object,
PAGED_CODE(); PAGED_CODE();
Header = BODY_TO_HEADER(Object); Header = BODY_TO_HEADER(Object);
if (Header->ObjectType == NULL) if (Header->Type == NULL)
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
if (Header->ObjectType->TypeInfo.SecurityProcedure == NULL) if (Header->Type->TypeInfo.SecurityProcedure == NULL)
{ {
ObpReferenceCachedSecurityDescriptor(Header->SecurityDescriptor); ObpReferenceCachedSecurityDescriptor(Header->SecurityDescriptor);
*SecurityDescriptor = Header->SecurityDescriptor; *SecurityDescriptor = Header->SecurityDescriptor;
@ -92,7 +92,7 @@ ObGetObjectSecurity(IN PVOID Object,
/* Get the security descriptor size */ /* Get the security descriptor size */
Length = 0; Length = 0;
Status = Header->ObjectType->TypeInfo.SecurityProcedure(Object, Status = Header->Type->TypeInfo.SecurityProcedure(Object,
QuerySecurityDescriptor, QuerySecurityDescriptor,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
@ -108,7 +108,7 @@ ObGetObjectSecurity(IN PVOID Object,
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
/* Query security descriptor */ /* Query security descriptor */
Status = Header->ObjectType->TypeInfo.SecurityProcedure(Object, Status = Header->Type->TypeInfo.SecurityProcedure(Object,
QuerySecurityDescriptor, QuerySecurityDescriptor,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
@ -180,17 +180,17 @@ NtQuerySecurityObject(IN HANDLE Handle,
} }
Header = BODY_TO_HEADER(Object); Header = BODY_TO_HEADER(Object);
if (Header->ObjectType == NULL) if (Header->Type == NULL)
{ {
DPRINT1("Invalid object type\n"); DPRINT1("Invalid object type\n");
ObDereferenceObject(Object); ObDereferenceObject(Object);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
if (Header->ObjectType->TypeInfo.SecurityProcedure != NULL) if (Header->Type->TypeInfo.SecurityProcedure != NULL)
{ {
*ResultLength = Length; *ResultLength = Length;
Status = Header->ObjectType->TypeInfo.SecurityProcedure(Object, Status = Header->Type->TypeInfo.SecurityProcedure(Object,
QuerySecurityDescriptor, QuerySecurityDescriptor,
SecurityInformation, SecurityInformation,
SecurityDescriptor, SecurityDescriptor,
@ -252,16 +252,16 @@ NtSetSecurityObject(IN HANDLE Handle,
} }
Header = BODY_TO_HEADER(Object); Header = BODY_TO_HEADER(Object);
if (Header->ObjectType == NULL) if (Header->Type == NULL)
{ {
DPRINT1("Invalid object type\n"); DPRINT1("Invalid object type\n");
ObDereferenceObject(Object); ObDereferenceObject(Object);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
if (Header->ObjectType->TypeInfo.SecurityProcedure != NULL) if (Header->Type->TypeInfo.SecurityProcedure != NULL)
{ {
Status = Header->ObjectType->TypeInfo.SecurityProcedure(Object, Status = Header->Type->TypeInfo.SecurityProcedure(Object,
SetSecurityDescriptor, SetSecurityDescriptor,
SecurityInformation, SecurityInformation,
SecurityDescriptor, SecurityDescriptor,

View file

@ -91,7 +91,7 @@ NtWaitForMultipleObjects(IN ULONG ObjectCount,
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
DPRINT1("Waiting for object type '%wZ' is not supported\n", DPRINT1("Waiting for object type '%wZ' is not supported\n",
&BODY_TO_HEADER(ObjectPtrArray[i])->ObjectType->Name); &BODY_TO_HEADER(ObjectPtrArray[i])->Type->Name);
Status = STATUS_HANDLE_NOT_WAITABLE; Status = STATUS_HANDLE_NOT_WAITABLE;
i++; i++;
} }
@ -178,7 +178,7 @@ NtWaitForSingleObject(IN HANDLE ObjectHandle,
if (!KiIsObjectWaitable(ObjectPtr)) if (!KiIsObjectWaitable(ObjectPtr))
{ {
DPRINT1("Waiting for object type '%wZ' is not supported\n", DPRINT1("Waiting for object type '%wZ' is not supported\n",
&BODY_TO_HEADER(ObjectPtr)->ObjectType->Name); &BODY_TO_HEADER(ObjectPtr)->Type->Name);
Status = STATUS_HANDLE_NOT_WAITABLE; Status = STATUS_HANDLE_NOT_WAITABLE;
} }
else else