mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +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,
|
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;
|
||||||
|
|
|
@ -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,
|
||||||
¤t,
|
¤t,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 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) \
|
#define HANDLE_TO_EX_HANDLE(handle) \
|
||||||
(LONG)(((LONG)(handle) >> 2) - 1)
|
(LONG)(((LONG)(handle) >> 2) - 1)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -1120,12 +1124,7 @@ 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 );
|
||||||
|
|
|
@ -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",¤t_obj->Body);
|
||||||
return(HEADER_TO_BODY(current_obj));
|
return(¤t_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",¤t_obj->Body);
|
||||||
return(HEADER_TO_BODY(current_obj));
|
return(¤t_obj->Body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current = current->Flink;
|
current = current->Flink;
|
||||||
|
@ -550,17 +551,43 @@ 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;
|
||||||
|
|
||||||
|
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 */
|
/* Set it up */
|
||||||
LocalObjectType->TypeInfo = *ObjectTypeInitializer;
|
LocalObjectType->TypeInfo = *ObjectTypeInitializer;
|
||||||
LocalObjectType->Name = *TypeName;
|
LocalObjectType->Name = *TypeName;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
¤t,
|
¤t,
|
||||||
|
@ -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,22 +892,35 @@ 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)
|
||||||
{
|
{
|
||||||
ObpReleaseCapturedAttributes(Header->ObjectCreateInfo);
|
ObpReleaseCapturedAttributes(Header->ObjectCreateInfo);
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue