mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Fix memory leaks in object manager, use tags and use some more public types
svn path=/trunk/; revision=15486
This commit is contained in:
parent
ef8d82998d
commit
1d899ce8b3
13 changed files with 354 additions and 195 deletions
|
@ -63,6 +63,34 @@ typedef NTSTATUS STDCALL_FUNC
|
|||
PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||
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
|
||||
{
|
||||
struct _DIRECTORY_OBJECT *Directory;
|
||||
|
|
|
@ -122,14 +122,14 @@ CmpFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
|
|||
CurrentHeader = BODY_TO_HEADER(CurrentObject);
|
||||
|
||||
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");
|
||||
break;
|
||||
}
|
||||
Status = CurrentHeader->ObjectType->TypeInfo.ParseProcedure(CurrentObject,
|
||||
Status = CurrentHeader->Type->TypeInfo.ParseProcedure(CurrentObject,
|
||||
&NextObject,
|
||||
&PathString,
|
||||
¤t,
|
||||
|
|
|
@ -512,7 +512,7 @@ CmiObjectQueryName (PVOID ObjectBody,
|
|||
else
|
||||
{
|
||||
/* 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,
|
||||
MAX_PATH * sizeof(WCHAR),
|
||||
&LocalReturnLength);
|
||||
|
|
|
@ -16,45 +16,46 @@
|
|||
|
||||
struct _EPROCESS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CSHORT Type;
|
||||
CSHORT Size;
|
||||
} COMMON_BODY_HEADER, *PCOMMON_BODY_HEADER;
|
||||
|
||||
typedef PVOID POBJECT;
|
||||
|
||||
typedef struct _OBJECT_HEADER
|
||||
/*
|
||||
* PURPOSE: Header for every object managed by the object manager
|
||||
*/
|
||||
typedef struct _QUAD
|
||||
{
|
||||
POBJECT_HEADER_NAME_INFO NameInfo;
|
||||
LIST_ENTRY Entry;
|
||||
LONG RefCount;
|
||||
LONG HandleCount;
|
||||
BOOLEAN Permanent;
|
||||
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;
|
||||
union {
|
||||
LONGLONG UseThisFieldToCopy;
|
||||
float DoNotUseThisField;
|
||||
};
|
||||
} QUAD, *PQUAD;
|
||||
|
||||
#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;
|
||||
|
||||
|
||||
typedef struct _DIRECTORY_OBJECT
|
||||
{
|
||||
CSHORT Type;
|
||||
|
@ -92,13 +93,19 @@ enum
|
|||
OBJTYP_MAX,
|
||||
};
|
||||
|
||||
#define HEADER_TO_BODY(objhdr) \
|
||||
(PVOID)((ULONG_PTR)objhdr + sizeof(OBJECT_HEADER) - sizeof(COMMON_BODY_HEADER))
|
||||
|
||||
#define BODY_TO_HEADER(objbdy) \
|
||||
CONTAINING_RECORD(&(((PCOMMON_BODY_HEADER)objbdy)->Type), OBJECT_HEADER, Type)
|
||||
CONTAINING_RECORD((objbdy), OBJECT_HEADER, Body)
|
||||
|
||||
#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)-sizeof(COMMON_BODY_HEADER))
|
||||
#define OBJECT_ALLOC_SIZE(ObjectSize) ((ObjectSize)+sizeof(OBJECT_HEADER))
|
||||
|
||||
#define HANDLE_TO_EX_HANDLE(handle) \
|
||||
(LONG)(((LONG)(handle) >> 2) - 1)
|
||||
|
|
|
@ -63,14 +63,14 @@ IopCreateFile(PVOID ObjectBody,
|
|||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
ParentObjectType = BODY_TO_HEADER(Parent)->ObjectType;
|
||||
ParentObjectType = BODY_TO_HEADER(Parent)->Type;
|
||||
|
||||
if (ParentObjectType != IoDeviceObjectType &&
|
||||
ParentObjectType != IoFileObjectType)
|
||||
{
|
||||
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)->ObjectType->Name.Buffer,
|
||||
BODY_TO_HEADER(Parent)->Type->Name.Buffer,
|
||||
RemainingPath);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
@ -870,7 +870,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
|
|||
{
|
||||
return Status;
|
||||
}
|
||||
if (BODY_TO_HEADER(DeviceObject)->ObjectType != IoDeviceObjectType)
|
||||
if (BODY_TO_HEADER(DeviceObject)->Type != IoDeviceObjectType)
|
||||
{
|
||||
ObDereferenceObject (DeviceObject);
|
||||
return STATUS_OBJECT_NAME_COLLISION;
|
||||
|
@ -904,7 +904,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
|
|||
}
|
||||
}
|
||||
RtlMapGenericMask(&DesiredAccess,
|
||||
&BODY_TO_HEADER(FileObject)->ObjectType->TypeInfo.GenericMapping);
|
||||
&BODY_TO_HEADER(FileObject)->Type->TypeInfo.GenericMapping);
|
||||
|
||||
Status = ObInsertObject ((PVOID)FileObject,
|
||||
NULL,
|
||||
|
|
|
@ -799,14 +799,14 @@ KiIsObjectWaitable(PVOID Object)
|
|||
POBJECT_HEADER Header;
|
||||
Header = BODY_TO_HEADER(Object);
|
||||
|
||||
if (Header->ObjectType == ExEventObjectType ||
|
||||
Header->ObjectType == IoCompletionType ||
|
||||
Header->ObjectType == ExMutantObjectType ||
|
||||
Header->ObjectType == ExSemaphoreObjectType ||
|
||||
Header->ObjectType == ExTimerType ||
|
||||
Header->ObjectType == PsProcessType ||
|
||||
Header->ObjectType == PsThreadType ||
|
||||
Header->ObjectType == IoFileObjectType) {
|
||||
if (Header->Type == ExEventObjectType ||
|
||||
Header->Type == IoCompletionType ||
|
||||
Header->Type == ExMutantObjectType ||
|
||||
Header->Type == ExSemaphoreObjectType ||
|
||||
Header->Type == ExTimerType ||
|
||||
Header->Type == PsProcessType ||
|
||||
Header->Type == PsThreadType ||
|
||||
Header->Type == IoFileObjectType) {
|
||||
|
||||
return TRUE;
|
||||
|
||||
|
|
|
@ -253,11 +253,11 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
|
|||
EntryHeader = CONTAINING_RECORD(ListEntry, OBJECT_HEADER, Entry);
|
||||
|
||||
/* calculate the size of the required buffer space for this entry */
|
||||
Name = (EntryHeader->NameInfo->Name.Length != 0 ? &EntryHeader->NameInfo->Name : NULL);
|
||||
Type = &EntryHeader->ObjectType->Name;
|
||||
Name = (HEADER_TO_OBJECT_NAME(EntryHeader)->Name.Length != 0 ? &HEADER_TO_OBJECT_NAME(EntryHeader)->Name : NULL);
|
||||
Type = &EntryHeader->Type->Name;
|
||||
EntrySize = sizeof(OBJECT_DIRECTORY_INFORMATION) +
|
||||
((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)
|
||||
{
|
||||
|
|
|
@ -60,19 +60,24 @@ static VOID
|
|||
ObpDecrementHandleCount(PVOID ObjectBody)
|
||||
{
|
||||
POBJECT_HEADER ObjectHeader = BODY_TO_HEADER(ObjectBody);
|
||||
DPRINT("Header: %x\n", ObjectHeader);
|
||||
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) &&
|
||||
(ObjectHeader->ObjectType->TypeInfo.CloseProcedure != NULL))
|
||||
if ((ObjectHeader->Type != NULL) &&
|
||||
(ObjectHeader->Type->TypeInfo.CloseProcedure != NULL))
|
||||
{
|
||||
/* the handle count should be decremented but we pass the previous value
|
||||
to the callback */
|
||||
ObjectHeader->ObjectType->TypeInfo.CloseProcedure(ObjectBody, NewHandleCount + 1);
|
||||
ObjectHeader->Type->TypeInfo.CloseProcedure(ObjectBody, NewHandleCount + 1);
|
||||
}
|
||||
|
||||
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.
|
||||
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);
|
||||
Body = HEADER_TO_BODY(ObjectHeader);
|
||||
Body = &ObjectHeader->Body;
|
||||
|
||||
ObpDecrementHandleCount(Body);
|
||||
|
||||
|
@ -276,7 +281,7 @@ ObDuplicateObject(PEPROCESS SourceProcess,
|
|||
}
|
||||
|
||||
ObjectHeader = EX_HTE_TO_HDR(SourceHandleEntry);
|
||||
ObjectBody = HEADER_TO_BODY(ObjectHeader);
|
||||
ObjectBody = &ObjectHeader->Body;
|
||||
|
||||
NewHandleEntry.u1.Object = SourceHandleEntry->u1.Object;
|
||||
if(InheritHandle)
|
||||
|
@ -295,7 +300,7 @@ ObDuplicateObject(PEPROCESS SourceProcess,
|
|||
if (DesiredAccess & GENERIC_ANY)
|
||||
{
|
||||
RtlMapGenericMask(&DesiredAccess,
|
||||
&ObjectHeader->ObjectType->TypeInfo.GenericMapping);
|
||||
&ObjectHeader->Type->TypeInfo.GenericMapping);
|
||||
}
|
||||
NewHandleEntry.u2.GrantedAccess = DesiredAccess;
|
||||
}
|
||||
|
@ -524,7 +529,7 @@ DeleteHandleCallback(PHANDLE_TABLE HandleTable,
|
|||
PAGED_CODE();
|
||||
|
||||
ObjectHeader = EX_OBJ_TO_HDR(Object);
|
||||
ObjectBody = HEADER_TO_BODY(ObjectHeader);
|
||||
ObjectBody = &ObjectHeader->Body;
|
||||
|
||||
ObpDecrementHandleCount(ObjectBody);
|
||||
}
|
||||
|
@ -545,7 +550,7 @@ DuplicateHandleCallback(PHANDLE_TABLE HandleTable,
|
|||
ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry);
|
||||
if(InterlockedIncrement(&ObjectHeader->HandleCount) == 1)
|
||||
{
|
||||
ObReferenceObject(HEADER_TO_BODY(ObjectHeader));
|
||||
ObReferenceObject(&ObjectHeader->Body);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -631,7 +636,7 @@ ObpCreateHandle(PEPROCESS Process,
|
|||
if (GrantedAccess & GENERIC_ANY)
|
||||
{
|
||||
RtlMapGenericMask(&GrantedAccess,
|
||||
&ObjectHeader->ObjectType->TypeInfo.GenericMapping);
|
||||
&ObjectHeader->Type->TypeInfo.GenericMapping);
|
||||
}
|
||||
|
||||
NewEntry.u1.Object = ObjectHeader;
|
||||
|
@ -822,13 +827,13 @@ ObReferenceObjectByHandle(HANDLE Handle,
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
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,
|
||||
HandleEntry);
|
||||
|
@ -842,7 +847,7 @@ ObReferenceObjectByHandle(HANDLE Handle,
|
|||
if (DesiredAccess & GENERIC_ANY)
|
||||
{
|
||||
RtlMapGenericMask(&DesiredAccess,
|
||||
&BODY_TO_HEADER(ObjectBody)->ObjectType->TypeInfo.GenericMapping);
|
||||
&BODY_TO_HEADER(ObjectBody)->Type->TypeInfo.GenericMapping);
|
||||
}
|
||||
|
||||
GrantedAccess = HandleEntry->u2.GrantedAccess;
|
||||
|
@ -963,7 +968,7 @@ ObInsertObject(IN PVOID Object,
|
|||
DPRINT("ObInsertObject: %x\n", Object);
|
||||
Header = BODY_TO_HEADER(Object);
|
||||
ObjectCreateInfo = Header->ObjectCreateInfo;
|
||||
ObjectNameInfo = Header->NameInfo;
|
||||
ObjectNameInfo = HEADER_TO_OBJECT_NAME(Header);
|
||||
|
||||
/* First try to find the Object */
|
||||
if (ObjectNameInfo && ObjectNameInfo->Name.Buffer)
|
||||
|
@ -1000,10 +1005,9 @@ ObInsertObject(IN PVOID Object,
|
|||
RtlInitUnicodeString(&RemainingPath, NULL);
|
||||
}
|
||||
|
||||
if (FoundHeader && FoundHeader->ObjectType == ObDirectoryType &&
|
||||
if (FoundHeader && FoundHeader->Type == ObDirectoryType &&
|
||||
RemainingPath.Buffer)
|
||||
{
|
||||
DPRINT("Adding to Object Directory\n");
|
||||
ObpAddEntryDirectory(FoundObject, Header, NULL);
|
||||
ObjectAttached = TRUE;
|
||||
|
||||
|
@ -1013,7 +1017,7 @@ ObInsertObject(IN PVOID Object,
|
|||
PWSTR BufferPos = RemainingPath.Buffer;
|
||||
|
||||
NewName = ExAllocatePool(NonPagedPool, RemainingPath.MaximumLength);
|
||||
ObjectNameInfo = Header->NameInfo;
|
||||
ObjectNameInfo = HEADER_TO_OBJECT_NAME(Header);
|
||||
|
||||
if (BufferPos[0] == L'\\')
|
||||
{
|
||||
|
@ -1028,36 +1032,36 @@ ObInsertObject(IN PVOID Object,
|
|||
DPRINT("Name: %S\n", ObjectNameInfo->Name.Buffer);
|
||||
}
|
||||
|
||||
if ((Header->ObjectType == IoFileObjectType) ||
|
||||
(Header->ObjectType == ExDesktopObjectType) ||
|
||||
(Header->ObjectType->TypeInfo.OpenProcedure != NULL))
|
||||
if ((Header->Type == IoFileObjectType) ||
|
||||
(Header->Type == ExDesktopObjectType) ||
|
||||
(Header->Type->TypeInfo.OpenProcedure != NULL))
|
||||
{
|
||||
DPRINT("About to call Open Routine\n");
|
||||
if (Header->ObjectType == IoFileObjectType)
|
||||
if (Header->Type == IoFileObjectType)
|
||||
{
|
||||
/* TEMPORARY HACK. DO NOT TOUCH -- Alex */
|
||||
DPRINT("Calling IopCreateFile: %x\n", FoundObject);
|
||||
Status = IopCreateFile(HEADER_TO_BODY(Header),
|
||||
Status = IopCreateFile(&Header->Body,
|
||||
FoundObject,
|
||||
RemainingPath.Buffer,
|
||||
ObjectCreateInfo);
|
||||
DPRINT("Called IopCreateFile: %x\n", Status);
|
||||
|
||||
}
|
||||
else if (Header->ObjectType == ExDesktopObjectType)
|
||||
else if (Header->Type == ExDesktopObjectType)
|
||||
{
|
||||
/* TEMPORARY HACK. DO NOT TOUCH -- Alex */
|
||||
DPRINT("Calling ExpDesktopCreate\n");
|
||||
Status = ExpDesktopCreate(HEADER_TO_BODY(Header),
|
||||
Status = ExpDesktopCreate(&Header->Body,
|
||||
FoundObject,
|
||||
RemainingPath.Buffer,
|
||||
ObjectCreateInfo);
|
||||
}
|
||||
else if (Header->ObjectType->TypeInfo.OpenProcedure != NULL)
|
||||
else if (Header->Type->TypeInfo.OpenProcedure != NULL)
|
||||
{
|
||||
DPRINT("Calling %x\n", Header->ObjectType->TypeInfo.OpenProcedure);
|
||||
Status = Header->ObjectType->TypeInfo.OpenProcedure(ObCreateHandle,
|
||||
HEADER_TO_BODY(Header),
|
||||
DPRINT("Calling %x\n", Header->Type->TypeInfo.OpenProcedure);
|
||||
Status = Header->Type->TypeInfo.OpenProcedure(ObCreateHandle,
|
||||
&Header->Body,
|
||||
NULL,
|
||||
0,
|
||||
0);
|
||||
|
@ -1088,19 +1092,19 @@ ObInsertObject(IN PVOID Object,
|
|||
Status = SeAssignSecurity((FoundHeader != NULL) ? FoundHeader->SecurityDescriptor : NULL,
|
||||
(ObjectCreateInfo != NULL) ? ObjectCreateInfo->SecurityDescriptor : NULL,
|
||||
&NewSecurityDescriptor,
|
||||
(Header->ObjectType == ObDirectoryType),
|
||||
(Header->Type == ObDirectoryType),
|
||||
&SubjectContext,
|
||||
&Header->ObjectType->TypeInfo.GenericMapping,
|
||||
&Header->Type->TypeInfo.GenericMapping,
|
||||
PagedPool);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NewSecurityDescriptor %p\n", NewSecurityDescriptor);
|
||||
|
||||
if (Header->ObjectType->TypeInfo.SecurityProcedure != NULL)
|
||||
if (Header->Type->TypeInfo.SecurityProcedure != NULL)
|
||||
{
|
||||
/* Call the security method */
|
||||
Status = Header->ObjectType->TypeInfo.SecurityProcedure(HEADER_TO_BODY(Header),
|
||||
Status = Header->Type->TypeInfo.SecurityProcedure(&Header->Body,
|
||||
AssignSecurityDescriptor,
|
||||
0,
|
||||
NewSecurityDescriptor,
|
||||
|
@ -1120,12 +1124,7 @@ ObInsertObject(IN PVOID Object,
|
|||
|
||||
DPRINT("Security Complete\n");
|
||||
SeReleaseSubjectContext(&SubjectContext);
|
||||
|
||||
/* We can delete the Create Info now */
|
||||
Header->ObjectCreateInfo = NULL;
|
||||
ObpReleaseCapturedAttributes(ObjectCreateInfo);
|
||||
ExFreePool(ObjectCreateInfo);
|
||||
|
||||
|
||||
/* Create the Handle */
|
||||
/* HACKHACK: Because of ROS's incorrect startup, this can be called
|
||||
* without a valid Process until I finalize the startup patch,
|
||||
|
@ -1137,14 +1136,19 @@ ObInsertObject(IN PVOID Object,
|
|||
if (Handle != NULL)
|
||||
{
|
||||
Status = ObpCreateHandle(PsGetCurrentProcess(),
|
||||
HEADER_TO_BODY(Header),
|
||||
&Header->Body,
|
||||
DesiredAccess,
|
||||
Header->Inherit,
|
||||
ObjectCreateInfo->Attributes & OBJ_INHERIT,
|
||||
Handle);
|
||||
DPRINT("handle Created: %d. refcount. handlecount %d %d\n",
|
||||
*Handle, Header->RefCount, Header->HandleCount);
|
||||
}
|
||||
|
||||
/* We can delete the Create Info now */
|
||||
Header->ObjectCreateInfo = NULL;
|
||||
ObpReleaseCapturedAttributes(ObjectCreateInfo);
|
||||
ExFreePool(ObjectCreateInfo);
|
||||
|
||||
DPRINT("Status %x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
@ -1227,7 +1231,7 @@ ObpGetNextHandleByProcessCount(PSYSTEM_HANDLE_TABLE_ENTRY_INFO pshi,
|
|||
|
||||
// pshi->GrantedAccess;
|
||||
// pshi->Object;
|
||||
// pshi->ObjectTypeIndex;
|
||||
// pshi->TypeIndex;
|
||||
// pshi->HandleAttributes;
|
||||
|
||||
// KeReleaseSpinLock( &Process->HandleTable.ListLock, oldIrql );
|
||||
|
|
|
@ -256,7 +256,8 @@ ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
|
|||
{
|
||||
KIRQL oldlvl;
|
||||
|
||||
Header->NameInfo->Directory = Parent;
|
||||
ASSERT(HEADER_TO_OBJECT_NAME(Header));
|
||||
HEADER_TO_OBJECT_NAME(Header)->Directory = Parent;
|
||||
|
||||
KeAcquireSpinLock(&Parent->Lock, &oldlvl);
|
||||
InsertTailList(&Parent->head, &Header->Entry);
|
||||
|
@ -276,13 +277,13 @@ ObpRemoveEntryDirectory(POBJECT_HEADER 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)
|
||||
{
|
||||
RemoveEntryList(&(Header->Entry));
|
||||
Header->Entry.Flink = Header->Entry.Blink = NULL;
|
||||
}
|
||||
KeReleaseSpinLock(&(Header->NameInfo->Directory->Lock),oldlvl);
|
||||
KeReleaseSpinLock(&(HEADER_TO_OBJECT_NAME(Header)->Directory->Lock),oldlvl);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -324,26 +325,26 @@ ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject,
|
|||
}
|
||||
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)))
|
||||
{
|
||||
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 (_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));
|
||||
return(HEADER_TO_BODY(current_obj));
|
||||
DPRINT("Found it %x\n",¤t_obj->Body);
|
||||
return(¤t_obj->Body);
|
||||
}
|
||||
}
|
||||
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));
|
||||
return(HEADER_TO_BODY(current_obj));
|
||||
DPRINT("Found it %x\n",¤t_obj->Body);
|
||||
return(¤t_obj->Body);
|
||||
}
|
||||
}
|
||||
current = current->Flink;
|
||||
|
@ -550,17 +551,43 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
|
|||
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 */
|
||||
if (!ObTypeObjectType)
|
||||
{
|
||||
ObTypeObjectType = LocalObjectType;
|
||||
Header->ObjectType = ObTypeObjectType;
|
||||
Header->Type = ObTypeObjectType;
|
||||
LocalObjectType->Key = TAG('O', 'b', 'j', 'T');
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
ANSI_STRING Tag;
|
||||
ULONG i;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: Generate Tag */
|
||||
|
||||
/* Set it up */
|
||||
LocalObjectType->TypeInfo = *ObjectTypeInitializer;
|
||||
LocalObjectType->Name = *TypeName;
|
||||
|
|
|
@ -122,13 +122,13 @@ NtQueryObject (IN HANDLE ObjectHandle,
|
|||
BasicInfo->Attributes = HandleInfo.HandleAttributes;
|
||||
BasicInfo->GrantedAccess = HandleInfo.GrantedAccess;
|
||||
BasicInfo->HandleCount = ObjectHeader->HandleCount;
|
||||
BasicInfo->PointerCount = ObjectHeader->RefCount;
|
||||
BasicInfo->PointerCount = ObjectHeader->PointerCount;
|
||||
BasicInfo->PagedPoolUsage = 0; /* FIXME*/
|
||||
BasicInfo->NonPagedPoolUsage = 0; /* FIXME*/
|
||||
BasicInfo->NameInformationLength = 0; /* FIXME*/
|
||||
BasicInfo->TypeInformationLength = 0; /* FIXME*/
|
||||
BasicInfo->SecurityDescriptorLength = 0; /* FIXME*/
|
||||
if (ObjectHeader->ObjectType == ObSymbolicLinkType)
|
||||
if (ObjectHeader->Type == ObSymbolicLinkType)
|
||||
{
|
||||
BasicInfo->CreateTime.QuadPart =
|
||||
((PSYMLINK_OBJECT)Object)->CreateTime.QuadPart;
|
||||
|
@ -169,10 +169,10 @@ NtQueryObject (IN HANDLE ObjectHandle,
|
|||
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?
|
||||
typeinfo->TotalHandles = ObjectHeader-> HandleCount;
|
||||
typeinfo->ReferenceCount = ObjectHeader -> RefCount;
|
||||
typeinfo->ReferenceCount = ObjectHeader -> PointerCount;
|
||||
}
|
||||
#endif
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
|
@ -223,9 +223,9 @@ ObpSetPermanentObject (IN PVOID ObjectBody, IN BOOLEAN Permanent)
|
|||
POBJECT_HEADER ObjectHeader;
|
||||
|
||||
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 */
|
||||
ObpRemoveEntryDirectory(ObjectHeader);
|
||||
|
|
|
@ -379,14 +379,14 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
|||
CurrentHeader = BODY_TO_HEADER(CurrentObject);
|
||||
|
||||
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");
|
||||
break;
|
||||
}
|
||||
Status = CurrentHeader->ObjectType->TypeInfo.ParseProcedure(CurrentObject,
|
||||
Status = CurrentHeader->Type->TypeInfo.ParseProcedure(CurrentObject,
|
||||
&NextObject,
|
||||
&PathString,
|
||||
¤t,
|
||||
|
@ -461,27 +461,27 @@ ObQueryNameString (IN PVOID Object,
|
|||
|
||||
ObjectHeader = BODY_TO_HEADER(Object);
|
||||
|
||||
if (ObjectHeader->ObjectType != NULL &&
|
||||
ObjectHeader->ObjectType->TypeInfo.QueryNameProcedure != NULL)
|
||||
if (ObjectHeader->Type != NULL &&
|
||||
ObjectHeader->Type->TypeInfo.QueryNameProcedure != NULL)
|
||||
{
|
||||
DPRINT ("Calling %x\n", ObjectHeader->ObjectType->TypeInfo.QueryNameProcedure);
|
||||
Status = ObjectHeader->ObjectType->TypeInfo.QueryNameProcedure (Object,
|
||||
DPRINT ("Calling %x\n", ObjectHeader->Type->TypeInfo.QueryNameProcedure);
|
||||
Status = ObjectHeader->Type->TypeInfo.QueryNameProcedure (Object,
|
||||
ObjectNameInfo,
|
||||
Length,
|
||||
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");
|
||||
|
||||
if (ObjectHeader->NameInfo->Directory == NameSpaceRoot)
|
||||
if (HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory == NameSpaceRoot)
|
||||
{
|
||||
DPRINT ("Reached the root directory\n");
|
||||
ObjectNameInfo->Name.Length = 0;
|
||||
ObjectNameInfo->Name.Buffer[0] = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else if (ObjectHeader->NameInfo->Directory != NULL)
|
||||
else if (HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory != NULL)
|
||||
{
|
||||
LocalInfo = ExAllocatePool (NonPagedPool,
|
||||
sizeof(OBJECT_NAME_INFORMATION) +
|
||||
|
@ -489,7 +489,7 @@ ObQueryNameString (IN PVOID Object,
|
|||
if (LocalInfo == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
Status = ObQueryNameString (ObjectHeader->NameInfo->Directory,
|
||||
Status = ObQueryNameString (HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory,
|
||||
LocalInfo,
|
||||
MAX_PATH * sizeof(WCHAR),
|
||||
&LocalReturnLength);
|
||||
|
@ -508,14 +508,14 @@ ObQueryNameString (IN PVOID Object,
|
|||
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,
|
||||
L"\\");
|
||||
if (!NT_SUCCESS (Status))
|
||||
return Status;
|
||||
|
||||
Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
|
||||
&ObjectHeader->NameInfo->Name);
|
||||
&HEADER_TO_OBJECT_NAME(ObjectHeader)->Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -549,8 +549,14 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
|||
POBJECT_HEADER *ObjectHeader)
|
||||
{
|
||||
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;
|
||||
ULONG FinalSize = ObjectSize;
|
||||
ULONG Tag;
|
||||
|
||||
/* If we don't have an Object Type yet, force NonPaged */
|
||||
|
@ -566,35 +572,104 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
|||
Tag = ObjectType->Key;
|
||||
}
|
||||
|
||||
/* Allocate memory for the Object */
|
||||
Header = ExAllocatePoolWithTag(PoolType, ObjectSize, Tag);
|
||||
DPRINT("Checking ObjectName: %x\n", ObjectName);
|
||||
/* 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) {
|
||||
DPRINT1("Not enough memory!\n");
|
||||
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 */
|
||||
RtlZeroMemory(Header, ObjectSize);
|
||||
DPRINT("Initalizing header %p\n", Header);
|
||||
DPRINT("Initalized header %p\n", Header);
|
||||
Header->HandleCount = 0;
|
||||
Header->RefCount = 1;
|
||||
Header->ObjectType = ObjectType;
|
||||
Header->PointerCount = 1;
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
Header->NameInfo = ObjectNameInfo;
|
||||
Header->ObjectCreateInfo = ObjectCreateInfo;
|
||||
|
||||
/* Return Header */
|
||||
|
@ -663,7 +738,7 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
|||
{
|
||||
/* Return the Object */
|
||||
DPRINT("Returning Object\n");
|
||||
*Object = HEADER_TO_BODY(Header);
|
||||
*Object = &Header->Body;
|
||||
|
||||
/* Return to caller, leave the Capture Info Alive for ObInsert */
|
||||
return Status;
|
||||
|
@ -707,43 +782,43 @@ ObReferenceObjectByPointer(IN PVOID 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",
|
||||
Header,
|
||||
Header->ObjectType,
|
||||
&BODY_TO_HEADER(Header->ObjectType)->NameInfo,
|
||||
Header->Type,
|
||||
&BODY_TO_HEADER(Header->Type)->NameInfo,
|
||||
ObjectType,
|
||||
&BODY_TO_HEADER(ObjectType)->NameInfo);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if (Header->ObjectType == PsProcessType)
|
||||
if (Header->Type == PsProcessType)
|
||||
{
|
||||
DPRINT("Ref p 0x%x refcount %d type %x ",
|
||||
Object, Header->RefCount, PsProcessType);
|
||||
DPRINT("Ref p 0x%x PointerCount %d type %x ",
|
||||
Object, Header->PointerCount, PsProcessType);
|
||||
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 ",
|
||||
Object, Header->RefCount, PsThreadType);
|
||||
DPRINT("Deref t 0x%x with PointerCount %d type %x ",
|
||||
Object, Header->PointerCount, PsThreadType);
|
||||
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;
|
||||
}
|
||||
if (Header->ObjectType == PsThreadType)
|
||||
if (Header->Type == PsThreadType)
|
||||
{
|
||||
return STATUS_THREAD_IS_TERMINATING;
|
||||
}
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
if (1 == InterlockedIncrement(&Header->RefCount) && !Header->Permanent)
|
||||
if (1 == InterlockedIncrement(&Header->PointerCount) && !(Header->Flags & OB_FLAG_PERMANENT))
|
||||
{
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
|
@ -794,6 +869,11 @@ ObOpenObjectByPointer(IN POBJECT Object,
|
|||
static NTSTATUS
|
||||
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);
|
||||
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
|
||||
{
|
||||
|
@ -801,10 +881,10 @@ ObpDeleteObject(POBJECT_HEADER Header)
|
|||
KEBUGCHECK(0);
|
||||
}
|
||||
|
||||
if (Header->ObjectType != NULL &&
|
||||
Header->ObjectType->TypeInfo.DeleteProcedure != NULL)
|
||||
if (Header->Type != NULL &&
|
||||
Header->Type->TypeInfo.DeleteProcedure != NULL)
|
||||
{
|
||||
Header->ObjectType->TypeInfo.DeleteProcedure(HEADER_TO_BODY(Header));
|
||||
Header->Type->TypeInfo.DeleteProcedure(&Header->Body);
|
||||
}
|
||||
|
||||
if (Header->SecurityDescriptor != NULL)
|
||||
|
@ -812,22 +892,35 @@ ObpDeleteObject(POBJECT_HEADER Header)
|
|||
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)
|
||||
{
|
||||
ObpReleaseCapturedAttributes(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");
|
||||
ExFreePool(Header);
|
||||
ExFreePool(HeaderLocation);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
@ -843,7 +936,7 @@ ObpDeleteObjectWorkRoutine (IN PVOID Parameter)
|
|||
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); /* We need PAGED_CODE somewhere... */
|
||||
|
||||
/* Turn this on when we have ExFreePoolWithTag
|
||||
Tag = Params->ObjectHeader->ObjectType->Tag; */
|
||||
Tag = Params->ObjectHeader->Type->Tag; */
|
||||
ObpDeleteObject(Params->ObjectHeader);
|
||||
ExFreePool(Params);
|
||||
/* ExFreePoolWithTag(Params, Tag); */
|
||||
|
@ -852,14 +945,14 @@ ObpDeleteObjectWorkRoutine (IN PVOID Parameter)
|
|||
|
||||
STATIC NTSTATUS
|
||||
ObpDeleteObjectDpcLevel(IN POBJECT_HEADER ObjectHeader,
|
||||
IN LONG OldRefCount)
|
||||
IN LONG OldPointerCount)
|
||||
{
|
||||
#if 0
|
||||
if (ObjectHeader->RefCount < 0)
|
||||
if (ObjectHeader->PointerCount < 0)
|
||||
{
|
||||
CPRINT("Object %p/%p has invalid reference count (%d)\n",
|
||||
ObjectHeader, HEADER_TO_BODY(ObjectHeader),
|
||||
ObjectHeader->RefCount);
|
||||
ObjectHeader->PointerCount);
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
|
||||
|
@ -890,7 +983,7 @@ ObpDeleteObjectDpcLevel(IN POBJECT_HEADER ObjectHeader,
|
|||
Params = (PRETENTION_CHECK_PARAMS)
|
||||
ExAllocatePoolWithTag(NonPagedPoolMustSucceed,
|
||||
sizeof(RETENTION_CHECK_PARAMS),
|
||||
ObjectHeader->ObjectType->Key);
|
||||
ObjectHeader->Type->Key);
|
||||
Params->ObjectHeader = ObjectHeader;
|
||||
ExInitializeWorkItem(&Params->WorkItem,
|
||||
ObpDeleteObjectWorkRoutine,
|
||||
|
@ -937,7 +1030,7 @@ ObfReferenceObject(IN PVOID Object)
|
|||
Header = BODY_TO_HEADER(Object);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
@ -964,28 +1057,28 @@ VOID FASTCALL
|
|||
ObfDereferenceObject(IN PVOID Object)
|
||||
{
|
||||
POBJECT_HEADER Header;
|
||||
LONG NewRefCount;
|
||||
LONG NewPointerCount;
|
||||
BOOL Permanent;
|
||||
|
||||
ASSERT(Object);
|
||||
|
||||
/* Extract the object header. */
|
||||
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
|
||||
last reference.
|
||||
*/
|
||||
NewRefCount = InterlockedDecrement(&Header->RefCount);
|
||||
DPRINT("ObfDereferenceObject(0x%x)==%d\n", Object, NewRefCount);
|
||||
ASSERT(NewRefCount >= 0);
|
||||
NewPointerCount = InterlockedDecrement(&Header->PointerCount);
|
||||
DPRINT("ObfDereferenceObject(0x%x)==%d\n", Object, NewPointerCount);
|
||||
ASSERT(NewPointerCount >= 0);
|
||||
|
||||
/* Check whether the object can now be deleted. */
|
||||
if (NewRefCount == 0 &&
|
||||
if (NewPointerCount == 0 &&
|
||||
!Permanent)
|
||||
{
|
||||
ObpDeleteObjectDpcLevel(Header, NewRefCount);
|
||||
ObpDeleteObjectDpcLevel(Header, NewPointerCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1065,7 +1158,7 @@ ObGetObjectPointerCount(PVOID Object)
|
|||
ASSERT(Object);
|
||||
Header = BODY_TO_HEADER(Object);
|
||||
|
||||
return Header->RefCount;
|
||||
return Header->PointerCount;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -79,10 +79,10 @@ ObGetObjectSecurity(IN PVOID Object,
|
|||
PAGED_CODE();
|
||||
|
||||
Header = BODY_TO_HEADER(Object);
|
||||
if (Header->ObjectType == NULL)
|
||||
if (Header->Type == NULL)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
if (Header->ObjectType->TypeInfo.SecurityProcedure == NULL)
|
||||
if (Header->Type->TypeInfo.SecurityProcedure == NULL)
|
||||
{
|
||||
ObpReferenceCachedSecurityDescriptor(Header->SecurityDescriptor);
|
||||
*SecurityDescriptor = Header->SecurityDescriptor;
|
||||
|
@ -92,7 +92,7 @@ ObGetObjectSecurity(IN PVOID Object,
|
|||
|
||||
/* Get the security descriptor size */
|
||||
Length = 0;
|
||||
Status = Header->ObjectType->TypeInfo.SecurityProcedure(Object,
|
||||
Status = Header->Type->TypeInfo.SecurityProcedure(Object,
|
||||
QuerySecurityDescriptor,
|
||||
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
|
||||
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
|
||||
|
@ -108,7 +108,7 @@ ObGetObjectSecurity(IN PVOID Object,
|
|||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* Query security descriptor */
|
||||
Status = Header->ObjectType->TypeInfo.SecurityProcedure(Object,
|
||||
Status = Header->Type->TypeInfo.SecurityProcedure(Object,
|
||||
QuerySecurityDescriptor,
|
||||
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
|
||||
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
|
||||
|
@ -180,17 +180,17 @@ NtQuerySecurityObject(IN HANDLE Handle,
|
|||
}
|
||||
|
||||
Header = BODY_TO_HEADER(Object);
|
||||
if (Header->ObjectType == NULL)
|
||||
if (Header->Type == NULL)
|
||||
{
|
||||
DPRINT1("Invalid object type\n");
|
||||
ObDereferenceObject(Object);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (Header->ObjectType->TypeInfo.SecurityProcedure != NULL)
|
||||
if (Header->Type->TypeInfo.SecurityProcedure != NULL)
|
||||
{
|
||||
*ResultLength = Length;
|
||||
Status = Header->ObjectType->TypeInfo.SecurityProcedure(Object,
|
||||
Status = Header->Type->TypeInfo.SecurityProcedure(Object,
|
||||
QuerySecurityDescriptor,
|
||||
SecurityInformation,
|
||||
SecurityDescriptor,
|
||||
|
@ -252,16 +252,16 @@ NtSetSecurityObject(IN HANDLE Handle,
|
|||
}
|
||||
|
||||
Header = BODY_TO_HEADER(Object);
|
||||
if (Header->ObjectType == NULL)
|
||||
if (Header->Type == NULL)
|
||||
{
|
||||
DPRINT1("Invalid object type\n");
|
||||
ObDereferenceObject(Object);
|
||||
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,
|
||||
SecurityInformation,
|
||||
SecurityDescriptor,
|
||||
|
|
|
@ -91,7 +91,7 @@ NtWaitForMultipleObjects(IN ULONG ObjectCount,
|
|||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
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;
|
||||
i++;
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ NtWaitForSingleObject(IN HANDLE ObjectHandle,
|
|||
if (!KiIsObjectWaitable(ObjectPtr))
|
||||
{
|
||||
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;
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue