mirror of
https://github.com/reactos/reactos.git
synced 2025-07-27 20:32:18 +00:00
- Set OBJ_OPENLINK invalid for core object types.
- Initialize symbolic link in-line with other core object types. - Use the SePublicDefaultUnrestrictedSd directly instead of building another SD. - Create core directory objects with Nt* functions instead of Ob*, to insure full accounting and error-handling. - Create core objects with OBJ_CASE_INSENSITIVE. - Fix the huge ObInit hack which was manually inserting Directory and Type object types in the type directory, and now loop the type list. Now we don't skip the Process, Token, Thread, Job, Section types anymore. - Support Quota Information during object allocation and deallocation isntead of ignoring it. - Use interlocked decrement when touching the object type (since it's a shared structure. We don't use the lock yet, but we won't for this anyways, since it's a simple lockable operation). - Use the right object key when freeing the object. - Modify the allocation function for a more optimized way of allocating objects instead of having to keep track of two sets of variables. - Add various accounting variables. - Make sure to properly handle allocations without object create info (ie, for object types). Now they get creator info and name info (which allowed us to cleanp the hack in ObInit). - Add checks to see if Quota informatio is needed. - Clear CreatorBackTraceIndex during allocation. - Remove CreatorUniqueProcess hack from back when the idle thread was NULL. - Do not zero out the header during allocation anymore, since this slows down the routine (instead, simply zero out the 2 fields that are NULL). - Locate and clearly display that the fact we zero objects on creation is a HACK that needs to be fixed. (The Token code makes this assumption). - Update HighWaterNumberOfObjects when needed. - If caller didn't give pool charges, use the one from the object type. - Clear the Total/HighWater* values for newly created object types instead of using random values. - Properly typecast the WCHAR tag as CHAR. - Insert each new object type in the ObTypeObjectType Type List. - Set the Index member of each new object type and insert each new object type in the ObpObjectTypes array. This is crucial for object type enumeration when implemented. - Fixup the way we insert new object types into the tree. Allow failure and don't return a type if we couldn't insert it, and only reference the type directory object if it actually exists. - Move DOS Devices\"??" initialization in its own routine and fix it: - Use Nt APIs for all operations instead of raw I/O. - Create GLOBALROOT link to \ - Create \??\Global link to \?? svn path=/trunk/; revision=24568
This commit is contained in:
parent
c4a6f8d938
commit
51a79c26bd
6 changed files with 494 additions and 236 deletions
|
@ -425,7 +425,7 @@ ExpLoadInitialProcess(IN PHANDLE ProcessHandle,
|
||||||
/* Create the environment string */
|
/* Create the environment string */
|
||||||
RtlInitEmptyUnicodeString(&Environment,
|
RtlInitEmptyUnicodeString(&Environment,
|
||||||
ProcessParameters->Environment,
|
ProcessParameters->Environment,
|
||||||
Size);
|
(USHORT)Size);
|
||||||
|
|
||||||
/* Append the DLL path to it */
|
/* Append the DLL path to it */
|
||||||
RtlAppendUnicodeToString(&Environment, L"Path=" );
|
RtlAppendUnicodeToString(&Environment, L"Path=" );
|
||||||
|
|
|
@ -112,8 +112,8 @@ ObpLookupEntryDirectory(
|
||||||
//
|
//
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
ObInitSymbolicLinkImplementation(
|
ObpDeleteSymbolicLink(
|
||||||
VOID
|
IN PVOID ObjectBody
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -219,17 +219,6 @@ ObpReapObject(
|
||||||
IN PVOID Unused
|
IN PVOID Unused
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
ObDereferenceDeviceMap(IN PEPROCESS Process);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
ObInheritDeviceMap(
|
|
||||||
IN PEPROCESS Parent,
|
|
||||||
IN PEPROCESS Process
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ObpSetPermanentObject(
|
ObpSetPermanentObject(
|
||||||
|
@ -245,10 +234,35 @@ ObpDeleteNameCheck(
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
ObClearProcessHandleTable(IN PEPROCESS Process);
|
ObClearProcessHandleTable(
|
||||||
|
IN PEPROCESS Process
|
||||||
|
);
|
||||||
|
|
||||||
/* Security descriptor cache functions */
|
//
|
||||||
|
// DOS Devices Functions
|
||||||
|
//
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
ObDereferenceDeviceMap(
|
||||||
|
IN PEPROCESS Process
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
ObInheritDeviceMap(
|
||||||
|
IN PEPROCESS Parent,
|
||||||
|
IN PEPROCESS Process
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ObpCreateDosDevicesDirectory(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Security descriptor cache functions
|
||||||
|
//
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
ObpInitSdCache(
|
ObpInitSdCache(
|
||||||
|
|
|
@ -37,6 +37,14 @@ GENERIC_MAPPING ObpDirectoryMapping =
|
||||||
DIRECTORY_ALL_ACCESS
|
DIRECTORY_ALL_ACCESS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GENERIC_MAPPING ObpSymbolicLinkMapping =
|
||||||
|
{
|
||||||
|
STANDARD_RIGHTS_READ | SYMBOLIC_LINK_QUERY,
|
||||||
|
STANDARD_RIGHTS_WRITE,
|
||||||
|
STANDARD_RIGHTS_EXECUTE | SYMBOLIC_LINK_QUERY,
|
||||||
|
SYMBOLIC_LINK_ALL_ACCESS
|
||||||
|
};
|
||||||
|
|
||||||
PDEVICE_MAP ObSystemDeviceMap = NULL;
|
PDEVICE_MAP ObSystemDeviceMap = NULL;
|
||||||
ULONG ObpTraceLevel = OB_HANDLE_DEBUG | OB_REFERENCE_DEBUG;
|
ULONG ObpTraceLevel = OB_HANDLE_DEBUG | OB_REFERENCE_DEBUG;
|
||||||
|
|
||||||
|
@ -124,12 +132,15 @@ ObInit(VOID)
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
UNICODE_STRING Name;
|
UNICODE_STRING Name;
|
||||||
SECURITY_DESCRIPTOR SecurityDescriptor;
|
|
||||||
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
|
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
|
||||||
OBP_LOOKUP_CONTEXT Context;
|
OBP_LOOKUP_CONTEXT Context;
|
||||||
UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\DosDevices");
|
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||||
|
PLIST_ENTRY ListHead, NextEntry;
|
||||||
|
POBJECT_HEADER Header;
|
||||||
|
POBJECT_HEADER_CREATOR_INFO CreatorInfo;
|
||||||
|
POBJECT_HEADER_NAME_INFO NameInfo;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Check if this is actually Phase 1 initialization */
|
/* Check if this is actually Phase 1 initialization */
|
||||||
if (ObpInitializationPhase != 0) goto ObPostPhase0;
|
if (ObpInitializationPhase != 0) goto ObPostPhase0;
|
||||||
|
@ -184,12 +195,11 @@ ObInit(VOID)
|
||||||
ObjectTypeInitializer.PoolType = NonPagedPool;
|
ObjectTypeInitializer.PoolType = NonPagedPool;
|
||||||
ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
|
ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
|
||||||
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE);
|
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE);
|
||||||
|
ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
|
||||||
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObTypeObjectType);
|
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObTypeObjectType);
|
||||||
|
|
||||||
/* Create the Directory Type */
|
/* Create the Directory Type */
|
||||||
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
|
|
||||||
RtlInitUnicodeString(&Name, L"Directory");
|
RtlInitUnicodeString(&Name, L"Directory");
|
||||||
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
|
|
||||||
ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
|
ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
|
||||||
ObjectTypeInitializer.UseDefaultObject = FALSE;
|
ObjectTypeInitializer.UseDefaultObject = FALSE;
|
||||||
ObjectTypeInitializer.MaintainTypeList = FALSE;
|
ObjectTypeInitializer.MaintainTypeList = FALSE;
|
||||||
|
@ -197,6 +207,16 @@ ObInit(VOID)
|
||||||
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY);
|
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY);
|
||||||
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObDirectoryType);
|
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObDirectoryType);
|
||||||
|
|
||||||
|
/* Create 'symbolic link' object type */
|
||||||
|
RtlInitUnicodeString(&Name, L"SymbolicLink");
|
||||||
|
ObjectTypeInitializer.DefaultNonPagedPoolCharge =
|
||||||
|
sizeof(OBJECT_SYMBOLIC_LINK);
|
||||||
|
ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping;
|
||||||
|
ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS;
|
||||||
|
ObjectTypeInitializer.ParseProcedure = ObpParseSymbolicLink;
|
||||||
|
ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink;
|
||||||
|
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObSymbolicLinkType);
|
||||||
|
|
||||||
/* Phase 0 initialization complete */
|
/* Phase 0 initialization complete */
|
||||||
ObpInitializationPhase++;
|
ObpInitializationPhase++;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -206,105 +226,102 @@ ObPostPhase0:
|
||||||
/* Re-initialize lookaside lists */
|
/* Re-initialize lookaside lists */
|
||||||
ObInit2();
|
ObInit2();
|
||||||
|
|
||||||
/* Create security descriptor */
|
/* Initialize Object Types directory attributes */
|
||||||
RtlCreateSecurityDescriptor(&SecurityDescriptor,
|
RtlInitUnicodeString(&Name, L"\\");
|
||||||
SECURITY_DESCRIPTOR_REVISION1);
|
|
||||||
RtlSetOwnerSecurityDescriptor(&SecurityDescriptor,
|
|
||||||
SeAliasAdminsSid,
|
|
||||||
FALSE);
|
|
||||||
RtlSetGroupSecurityDescriptor(&SecurityDescriptor,
|
|
||||||
SeLocalSystemSid,
|
|
||||||
FALSE);
|
|
||||||
RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
|
|
||||||
TRUE,
|
|
||||||
SePublicDefaultDacl,
|
|
||||||
FALSE);
|
|
||||||
|
|
||||||
/* Create root directory */
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&Name,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
|
||||||
NULL,
|
NULL,
|
||||||
OBJ_PERMANENT,
|
SePublicDefaultUnrestrictedSd);
|
||||||
NULL,
|
|
||||||
&SecurityDescriptor);
|
|
||||||
ObCreateObject(KernelMode,
|
|
||||||
ObDirectoryType,
|
|
||||||
&ObjectAttributes,
|
|
||||||
KernelMode,
|
|
||||||
NULL,
|
|
||||||
sizeof(OBJECT_DIRECTORY),
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
(PVOID*)&NameSpaceRoot);
|
|
||||||
ObInsertObject((PVOID)NameSpaceRoot,
|
|
||||||
NULL,
|
|
||||||
DIRECTORY_ALL_ACCESS,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
/* Create '\ObjectTypes' directory */
|
/* Create the directory */
|
||||||
|
Status = NtCreateDirectoryObject(&Handle,
|
||||||
|
DIRECTORY_ALL_ACCESS,
|
||||||
|
&ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status)) return FALSE;
|
||||||
|
|
||||||
|
/* Get a handle to it */
|
||||||
|
Status = ObReferenceObjectByHandle(Handle,
|
||||||
|
0,
|
||||||
|
ObDirectoryType,
|
||||||
|
KernelMode,
|
||||||
|
(PVOID*)&NameSpaceRoot,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status)) return FALSE;
|
||||||
|
|
||||||
|
/* Close the extra handle */
|
||||||
|
Status = NtClose(Handle);
|
||||||
|
if (!NT_SUCCESS(Status)) return FALSE;
|
||||||
|
|
||||||
|
/* Initialize Object Types directory attributes */
|
||||||
RtlInitUnicodeString(&Name, L"\\ObjectTypes");
|
RtlInitUnicodeString(&Name, L"\\ObjectTypes");
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
&Name,
|
&Name,
|
||||||
OBJ_PERMANENT,
|
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
|
||||||
NULL,
|
|
||||||
&SecurityDescriptor);
|
|
||||||
ObCreateObject(KernelMode,
|
|
||||||
ObDirectoryType,
|
|
||||||
&ObjectAttributes,
|
|
||||||
KernelMode,
|
|
||||||
NULL,
|
|
||||||
sizeof(OBJECT_DIRECTORY),
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
(PVOID*)&ObpTypeDirectoryObject);
|
|
||||||
ObInsertObject((PVOID)ObpTypeDirectoryObject,
|
|
||||||
NULL,
|
|
||||||
DIRECTORY_ALL_ACCESS,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
/* Insert the two objects we already created but couldn't add */
|
|
||||||
/* NOTE: Uses TypeList & Creator Info in OB 2.0 */
|
|
||||||
Context.Directory = ObpTypeDirectoryObject;
|
|
||||||
Context.DirectoryLocked = TRUE;
|
|
||||||
if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
|
||||||
&OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(ObTypeObjectType))->Name,
|
|
||||||
OBJ_CASE_INSENSITIVE,
|
|
||||||
FALSE,
|
|
||||||
&Context))
|
|
||||||
{
|
|
||||||
ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, OBJECT_TO_OBJECT_HEADER(ObTypeObjectType));
|
|
||||||
}
|
|
||||||
if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
|
||||||
&OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(ObDirectoryType))->Name,
|
|
||||||
OBJ_CASE_INSENSITIVE,
|
|
||||||
FALSE,
|
|
||||||
&Context))
|
|
||||||
{
|
|
||||||
ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, OBJECT_TO_OBJECT_HEADER(ObDirectoryType));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create 'symbolic link' object type */
|
|
||||||
ObInitSymbolicLinkImplementation();
|
|
||||||
|
|
||||||
/* Create the '\??' directory */
|
|
||||||
RtlInitUnicodeString(&Name, L"\\??");
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
&Name,
|
|
||||||
0,
|
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
ZwCreateDirectoryObject(&Handle, 0, &ObjectAttributes);
|
|
||||||
|
|
||||||
/* Create link from '\DosDevices' to '\??' directory */
|
/* Create the directory */
|
||||||
RtlInitUnicodeString(&Name, L"\\??");
|
Status = NtCreateDirectoryObject(&Handle,
|
||||||
IoCreateSymbolicLink(&LinkName, &Name);
|
DIRECTORY_ALL_ACCESS,
|
||||||
|
&ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status)) return FALSE;
|
||||||
|
|
||||||
/* FIXME: Hack Hack! */
|
/* Get a handle to it */
|
||||||
ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ObSystemDeviceMap), TAG('O', 'b', 'D', 'm'));
|
Status = ObReferenceObjectByHandle(Handle,
|
||||||
RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap));
|
0,
|
||||||
|
ObDirectoryType,
|
||||||
|
KernelMode,
|
||||||
|
(PVOID*)&ObpTypeDirectoryObject,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status)) return FALSE;
|
||||||
|
|
||||||
|
/* Close the extra handle */
|
||||||
|
Status = NtClose(Handle);
|
||||||
|
if (!NT_SUCCESS(Status)) return FALSE;
|
||||||
|
|
||||||
|
/* Loop the object types */
|
||||||
|
ListHead = &ObTypeObjectType->TypeList;
|
||||||
|
NextEntry = ListHead->Flink;
|
||||||
|
while (ListHead != NextEntry)
|
||||||
|
{
|
||||||
|
/* Get the creator info from the list */
|
||||||
|
CreatorInfo = CONTAINING_RECORD(NextEntry,
|
||||||
|
OBJECT_HEADER_CREATOR_INFO,
|
||||||
|
TypeList);
|
||||||
|
|
||||||
|
/* Recover the header and the name header from the creator info */
|
||||||
|
Header = (POBJECT_HEADER)(CreatorInfo + 1);
|
||||||
|
NameInfo = OBJECT_HEADER_TO_NAME_INFO(Header);
|
||||||
|
|
||||||
|
/* Make sure we have a name, and aren't inserted yet */
|
||||||
|
if ((NameInfo) && !(NameInfo->Directory))
|
||||||
|
{
|
||||||
|
/* Set up the context for the insert */
|
||||||
|
Context.Directory = ObpTypeDirectoryObject;
|
||||||
|
Context.DirectoryLocked = TRUE;
|
||||||
|
|
||||||
|
/* Do the initial lookup to setup the context */
|
||||||
|
if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
||||||
|
&NameInfo->Name,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
FALSE,
|
||||||
|
&Context))
|
||||||
|
{
|
||||||
|
/* Insert this object type */
|
||||||
|
ObpInsertEntryDirectory(ObpTypeDirectoryObject,
|
||||||
|
&Context,
|
||||||
|
Header);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move to the next entry */
|
||||||
|
NextEntry = NextEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize DOS Devices Directory and related Symbolic Links */
|
||||||
|
Status = ObpCreateDosDevicesDirectory();
|
||||||
|
if (!NT_SUCCESS(Status)) return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,10 @@ NPAGED_LOOKASIDE_LIST ObpNmLookasideList, ObpCiLookasideList;
|
||||||
WORK_QUEUE_ITEM ObpReaperWorkItem;
|
WORK_QUEUE_ITEM ObpReaperWorkItem;
|
||||||
volatile PVOID ObpReaperList;
|
volatile PVOID ObpReaperList;
|
||||||
|
|
||||||
|
ULONG ObpObjectsCreated, ObpObjectsWithName, ObpObjectsWithPoolQuota;
|
||||||
|
ULONG ObpObjectsWithHandleDB, ObpObjectsWithCreatorInfo;
|
||||||
|
POBJECT_TYPE ObpObjectTypes[32];
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -39,6 +43,8 @@ ObpDeallocateObject(IN PVOID Object)
|
||||||
POBJECT_HEADER_HANDLE_INFO HandleInfo;
|
POBJECT_HEADER_HANDLE_INFO HandleInfo;
|
||||||
POBJECT_HEADER_NAME_INFO NameInfo;
|
POBJECT_HEADER_NAME_INFO NameInfo;
|
||||||
POBJECT_HEADER_CREATOR_INFO CreatorInfo;
|
POBJECT_HEADER_CREATOR_INFO CreatorInfo;
|
||||||
|
POBJECT_HEADER_QUOTA_INFO QuotaInfo;
|
||||||
|
ULONG PagedPoolCharge, NonPagedPoolCharge;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Get the header and assume this is what we'll free */
|
/* Get the header and assume this is what we'll free */
|
||||||
|
@ -59,6 +65,13 @@ ObpDeallocateObject(IN PVOID Object)
|
||||||
{
|
{
|
||||||
HeaderLocation = HandleInfo;
|
HeaderLocation = HandleInfo;
|
||||||
}
|
}
|
||||||
|
if ((QuotaInfo = OBJECT_HEADER_TO_QUOTA_INFO(Header)))
|
||||||
|
{
|
||||||
|
HeaderLocation = QuotaInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decrease the total */
|
||||||
|
InterlockedDecrement(&ObjectType->TotalNumberOfObjects);
|
||||||
|
|
||||||
/* Check if we have create info */
|
/* Check if we have create info */
|
||||||
if (Header->Flags & OB_FLAG_CREATE_INFO)
|
if (Header->Flags & OB_FLAG_CREATE_INFO)
|
||||||
|
@ -71,6 +84,34 @@ ObpDeallocateObject(IN PVOID Object)
|
||||||
Header->ObjectCreateInfo = NULL;
|
Header->ObjectCreateInfo = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Check if it has a quota block */
|
||||||
|
if (Header->QuotaBlockCharged)
|
||||||
|
{
|
||||||
|
/* Check if we have quota information */
|
||||||
|
if (QuotaInfo)
|
||||||
|
{
|
||||||
|
/* Get charges from quota information */
|
||||||
|
PagedPoolCharge = QuotaInfo->PagedPoolCharge +
|
||||||
|
QuotaInfo->SecurityDescriptorCharge;
|
||||||
|
NonPagedPoolCharge = QuotaInfo->NonPagedPoolCharge;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Get charges from object type */
|
||||||
|
PagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge;
|
||||||
|
NonPagedPoolCharge = ObjectType->
|
||||||
|
TypeInfo.DefaultNonPagedPoolCharge;
|
||||||
|
|
||||||
|
/* Add the SD charge too */
|
||||||
|
if (Header->Flags & OB_FLAG_SECURITY) PagedPoolCharge += 2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Should be returning quota */
|
||||||
|
DPRINT("Quotas: %lx %lx\n", PagedPoolCharge, NonPagedPoolCharge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if a handle database was active */
|
/* Check if a handle database was active */
|
||||||
if ((HandleInfo) && !(Header->Flags & OB_FLAG_SINGLE_PROCESS))
|
if ((HandleInfo) && !(Header->Flags & OB_FLAG_SINGLE_PROCESS))
|
||||||
|
@ -89,11 +130,7 @@ ObpDeallocateObject(IN PVOID Object)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the object using the same allocation tag */
|
/* Free the object using the same allocation tag */
|
||||||
ExFreePoolWithTag(HeaderLocation,
|
ExFreePoolWithTag(HeaderLocation, ObjectType->Key);
|
||||||
ObjectType ? TAG('T', 'j', 'b', 'O') : ObjectType->Key);
|
|
||||||
|
|
||||||
/* Decrease the total */
|
|
||||||
ObjectType->TotalNumberOfObjects--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -134,6 +171,7 @@ ObpDeleteObject(IN PVOID Object)
|
||||||
/* Check if we have a security descriptor */
|
/* Check if we have a security descriptor */
|
||||||
if (Header->SecurityDescriptor)
|
if (Header->SecurityDescriptor)
|
||||||
{
|
{
|
||||||
|
/* Call the security procedure to delete it */
|
||||||
ObjectType->TypeInfo.SecurityProcedure(Object,
|
ObjectType->TypeInfo.SecurityProcedure(Object,
|
||||||
DeleteSecurityDescriptor,
|
DeleteSecurityDescriptor,
|
||||||
0,
|
0,
|
||||||
|
@ -247,9 +285,7 @@ ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName,
|
||||||
/* First Probe the String */
|
/* First Probe the String */
|
||||||
ProbeForReadUnicodeString(ObjectName);
|
ProbeForReadUnicodeString(ObjectName);
|
||||||
LocalName = *ObjectName;
|
LocalName = *ObjectName;
|
||||||
ProbeForRead(LocalName.Buffer,
|
ProbeForRead(LocalName.Buffer, LocalName.Length, sizeof(WCHAR));
|
||||||
LocalName.Length,
|
|
||||||
sizeof(WCHAR));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -311,6 +347,7 @@ ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName,
|
||||||
}
|
}
|
||||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
{
|
{
|
||||||
|
/* Handle exception and free the string buffer */
|
||||||
Status = _SEH_GetExceptionCode();
|
Status = _SEH_GetExceptionCode();
|
||||||
if (StringBuffer) ExFreePool(StringBuffer);
|
if (StringBuffer) ExFreePool(StringBuffer);
|
||||||
}
|
}
|
||||||
|
@ -461,59 +498,125 @@ ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
IN POBJECT_HEADER *ObjectHeader)
|
IN POBJECT_HEADER *ObjectHeader)
|
||||||
{
|
{
|
||||||
POBJECT_HEADER Header;
|
POBJECT_HEADER Header;
|
||||||
BOOLEAN HasHandleInfo = FALSE;
|
ULONG QuotaSize, HandleSize, NameSize, CreatorSize;
|
||||||
BOOLEAN HasNameInfo = FALSE;
|
|
||||||
BOOLEAN HasCreatorInfo = FALSE;
|
|
||||||
POBJECT_HEADER_HANDLE_INFO HandleInfo;
|
POBJECT_HEADER_HANDLE_INFO HandleInfo;
|
||||||
POBJECT_HEADER_NAME_INFO NameInfo;
|
POBJECT_HEADER_NAME_INFO NameInfo;
|
||||||
POBJECT_HEADER_CREATOR_INFO CreatorInfo;
|
POBJECT_HEADER_CREATOR_INFO CreatorInfo;
|
||||||
|
POBJECT_HEADER_QUOTA_INFO QuotaInfo;
|
||||||
POOL_TYPE PoolType;
|
POOL_TYPE PoolType;
|
||||||
ULONG FinalSize = ObjectSize;
|
ULONG FinalSize;
|
||||||
ULONG Tag;
|
ULONG Tag;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* If we don't have an Object Type yet, force NonPaged */
|
/* Accounting */
|
||||||
if (!ObjectType)
|
ObpObjectsCreated++;
|
||||||
|
|
||||||
|
/* Check if we don't have an Object Type yet */
|
||||||
|
if (!ObjectType)
|
||||||
{
|
{
|
||||||
|
/* Use default tag and non-paged pool */
|
||||||
PoolType = NonPagedPool;
|
PoolType = NonPagedPool;
|
||||||
Tag = TAG('O', 'b', 'j', 'T');
|
Tag = TAG('O', 'b', 'j', 'T');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Use the pool and tag given */
|
||||||
PoolType = ObjectType->TypeInfo.PoolType;
|
PoolType = ObjectType->TypeInfo.PoolType;
|
||||||
Tag = ObjectType->Key;
|
Tag = ObjectType->Key;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the Object has a name */
|
/* Check if we have no create information (ie: we're an object type) */
|
||||||
if (ObjectName->Buffer)
|
if (!ObjectCreateInfo)
|
||||||
{
|
{
|
||||||
FinalSize += sizeof(OBJECT_HEADER_NAME_INFO);
|
/* Use defaults */
|
||||||
HasNameInfo = TRUE;
|
QuotaSize = HandleSize = 0;
|
||||||
|
NameSize = sizeof(OBJECT_HEADER_NAME_INFO);
|
||||||
|
CreatorSize = sizeof(OBJECT_HEADER_CREATOR_INFO);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (ObjectType)
|
|
||||||
{
|
{
|
||||||
/* Check if the Object maintains handle counts */
|
/* Check if we have quota */
|
||||||
|
if ((ObjectCreateInfo->PagedPoolCharge !=
|
||||||
|
ObjectType->TypeInfo.DefaultPagedPoolCharge) ||
|
||||||
|
(ObjectCreateInfo->NonPagedPoolCharge !=
|
||||||
|
ObjectType->TypeInfo.DefaultNonPagedPoolCharge) ||
|
||||||
|
(ObjectCreateInfo->SecurityDescriptorCharge > 2000) ||
|
||||||
|
(ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE))
|
||||||
|
{
|
||||||
|
/* Set quota size */
|
||||||
|
QuotaSize = sizeof(OBJECT_HEADER_QUOTA_INFO);
|
||||||
|
ObpObjectsWithPoolQuota++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No Quota */
|
||||||
|
QuotaSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we have a handle database */
|
||||||
if (ObjectType->TypeInfo.MaintainHandleCount)
|
if (ObjectType->TypeInfo.MaintainHandleCount)
|
||||||
{
|
{
|
||||||
FinalSize += sizeof(OBJECT_HEADER_HANDLE_INFO);
|
/* Set handle database size */
|
||||||
HasHandleInfo = TRUE;
|
HandleSize = sizeof(OBJECT_HEADER_HANDLE_INFO);
|
||||||
|
ObpObjectsWithHandleDB++;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Check if the Object maintains type lists */
|
|
||||||
if (ObjectType->TypeInfo.MaintainTypeList)
|
|
||||||
{
|
{
|
||||||
FinalSize += sizeof(OBJECT_HEADER_CREATOR_INFO);
|
/* None */
|
||||||
HasCreatorInfo = TRUE;
|
HandleSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the Object has a name */
|
||||||
|
if (ObjectName->Buffer)
|
||||||
|
{
|
||||||
|
/* Set name size */
|
||||||
|
NameSize = sizeof(OBJECT_HEADER_NAME_INFO);
|
||||||
|
ObpObjectsWithName++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No name */
|
||||||
|
NameSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the Object maintains type lists */
|
||||||
|
if (ObjectType->TypeInfo.MaintainTypeList)
|
||||||
|
{
|
||||||
|
/* Set owner/creator size */
|
||||||
|
CreatorSize = sizeof(OBJECT_HEADER_CREATOR_INFO);
|
||||||
|
ObpObjectsWithCreatorInfo++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No info */
|
||||||
|
CreatorSize = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set final header size */
|
||||||
|
FinalSize = QuotaSize +
|
||||||
|
HandleSize +
|
||||||
|
NameSize +
|
||||||
|
CreatorSize +
|
||||||
|
FIELD_OFFSET(OBJECT_HEADER, Body);
|
||||||
|
|
||||||
/* Allocate memory for the Object and Header */
|
/* Allocate memory for the Object and Header */
|
||||||
Header = ExAllocatePoolWithTag(PoolType, FinalSize, Tag);
|
Header = ExAllocatePoolWithTag(PoolType, FinalSize + ObjectSize, Tag);
|
||||||
if (!Header) return STATUS_INSUFFICIENT_RESOURCES;
|
if (!Header) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* Initialize quota info */
|
||||||
|
if (QuotaSize)
|
||||||
|
{
|
||||||
|
QuotaInfo = (POBJECT_HEADER_QUOTA_INFO)Header;
|
||||||
|
QuotaInfo->PagedPoolCharge = ObjectCreateInfo->PagedPoolCharge;
|
||||||
|
QuotaInfo->NonPagedPoolCharge = ObjectCreateInfo->NonPagedPoolCharge;
|
||||||
|
QuotaInfo->SecurityDescriptorCharge = ObjectCreateInfo->SecurityDescriptorCharge;
|
||||||
|
QuotaInfo->ExclusiveProcess = NULL;
|
||||||
|
Header = (POBJECT_HEADER)(QuotaInfo + 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize Handle Info */
|
/* Initialize Handle Info */
|
||||||
if (HasHandleInfo)
|
if (HandleSize)
|
||||||
{
|
{
|
||||||
HandleInfo = (POBJECT_HEADER_HANDLE_INFO)Header;
|
HandleInfo = (POBJECT_HEADER_HANDLE_INFO)Header;
|
||||||
HandleInfo->SingleEntry.HandleCount = 0;
|
HandleInfo->SingleEntry.HandleCount = 0;
|
||||||
|
@ -521,7 +624,7 @@ ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the Object Name Info */
|
/* Initialize the Object Name Info */
|
||||||
if (HasNameInfo)
|
if (NameSize)
|
||||||
{
|
{
|
||||||
NameInfo = (POBJECT_HEADER_NAME_INFO)Header;
|
NameInfo = (POBJECT_HEADER_NAME_INFO)Header;
|
||||||
NameInfo->Name = *ObjectName;
|
NameInfo->Name = *ObjectName;
|
||||||
|
@ -530,59 +633,104 @@ ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize Creator Info */
|
/* Initialize Creator Info */
|
||||||
if (HasCreatorInfo)
|
if (CreatorSize)
|
||||||
{
|
{
|
||||||
CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)Header;
|
CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)Header;
|
||||||
CreatorInfo->CreatorUniqueProcess = PsGetCurrentProcess() ?
|
CreatorInfo->CreatorBackTraceIndex = 0;
|
||||||
PsGetCurrentProcessId() : 0;
|
CreatorInfo->CreatorUniqueProcess = PsGetCurrentProcessId();
|
||||||
InitializeListHead(&CreatorInfo->TypeList);
|
InitializeListHead(&CreatorInfo->TypeList);
|
||||||
Header = (POBJECT_HEADER)(CreatorInfo + 1);
|
Header = (POBJECT_HEADER)(CreatorInfo + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the object header */
|
/* Check for quota information */
|
||||||
RtlZeroMemory(Header, ObjectSize);
|
if (QuotaSize)
|
||||||
Header->PointerCount = 1;
|
{
|
||||||
Header->Type = ObjectType;
|
/* Set the offset */
|
||||||
|
Header->QuotaInfoOffset = (UCHAR)(QuotaSize +
|
||||||
|
HandleSize +
|
||||||
|
NameSize +
|
||||||
|
CreatorSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No offset */
|
||||||
|
Header->QuotaInfoOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for handle information */
|
||||||
|
if (HandleSize)
|
||||||
|
{
|
||||||
|
/* Set the offset */
|
||||||
|
Header->HandleInfoOffset = (UCHAR)(HandleSize +
|
||||||
|
NameSize +
|
||||||
|
CreatorSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No offset */
|
||||||
|
Header->HandleInfoOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for name information */
|
||||||
|
if (NameSize)
|
||||||
|
{
|
||||||
|
/* Set the offset */
|
||||||
|
Header->NameInfoOffset = (UCHAR)(NameSize + CreatorSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No Name */
|
||||||
|
Header->NameInfoOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the new object flag */
|
||||||
Header->Flags = OB_FLAG_CREATE_INFO;
|
Header->Flags = OB_FLAG_CREATE_INFO;
|
||||||
|
|
||||||
|
/* Remember if we have creator info */
|
||||||
|
if (CreatorSize) Header->Flags |= OB_FLAG_CREATOR_INFO;
|
||||||
|
|
||||||
|
/* Remember if we have handle info */
|
||||||
|
if (HandleSize) Header->Flags |= OB_FLAG_SINGLE_PROCESS;
|
||||||
|
|
||||||
|
/* Initialize the object header */
|
||||||
|
Header->PointerCount = 1;
|
||||||
|
Header->HandleCount = 0;
|
||||||
|
Header->Type = ObjectType;
|
||||||
Header->ObjectCreateInfo = ObjectCreateInfo;
|
Header->ObjectCreateInfo = ObjectCreateInfo;
|
||||||
|
Header->SecurityDescriptor = NULL;
|
||||||
|
|
||||||
/* Set the Offsets for the Info */
|
/* Check if this is a permanent object */
|
||||||
if (HasHandleInfo)
|
|
||||||
{
|
|
||||||
Header->HandleInfoOffset = HasNameInfo *
|
|
||||||
sizeof(OBJECT_HEADER_NAME_INFO) +
|
|
||||||
sizeof(OBJECT_HEADER_HANDLE_INFO) +
|
|
||||||
HasCreatorInfo *
|
|
||||||
sizeof(OBJECT_HEADER_CREATOR_INFO);
|
|
||||||
|
|
||||||
/* Set the flag so we know when freeing */
|
|
||||||
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))
|
||||||
{
|
{
|
||||||
/* Set the needed flag so we can check */
|
/* Set the needed flag so we can check */
|
||||||
Header->Flags |= OB_FLAG_PERMANENT;
|
Header->Flags |= OB_FLAG_PERMANENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if this is an exclusive object */
|
||||||
if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE))
|
if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE))
|
||||||
{
|
{
|
||||||
/* Set the needed flag so we can check */
|
/* Set the needed flag so we can check */
|
||||||
Header->Flags |= OB_FLAG_EXCLUSIVE;
|
Header->Flags |= OB_FLAG_EXCLUSIVE;
|
||||||
}
|
}
|
||||||
if (PreviousMode == KernelMode)
|
|
||||||
|
/* Set kernel-mode flag */
|
||||||
|
if (PreviousMode == KernelMode) Header->Flags |= OB_FLAG_KERNEL_MODE;
|
||||||
|
|
||||||
|
/* Check if we have a type */
|
||||||
|
if (ObjectType)
|
||||||
{
|
{
|
||||||
/* Set the kernel flag */
|
/* Increase the number of objects of this type */
|
||||||
Header->Flags |= OB_FLAG_KERNEL_MODE;
|
ObjectType->TotalNumberOfObjects++;
|
||||||
|
|
||||||
|
/* Update the high water */
|
||||||
|
ObjectType->HighWaterNumberOfObjects = max(ObjectType->
|
||||||
|
TotalNumberOfObjects,
|
||||||
|
ObjectType->
|
||||||
|
HighWaterNumberOfObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Increase the number of objects of this type */
|
/* OMG-Hack-Of-Doom */
|
||||||
if (ObjectType) ObjectType->TotalNumberOfObjects++;
|
RtlZeroMemory(&Header->Body, ObjectSize);
|
||||||
|
|
||||||
/* Return Header */
|
/* Return Header */
|
||||||
*ObjectHeader = Header;
|
*ObjectHeader = Header;
|
||||||
|
@ -593,7 +741,7 @@ ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL,
|
||||||
IN POBJECT_TYPE Type,
|
IN POBJECT_TYPE Type,
|
||||||
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||||
IN KPROCESSOR_MODE AccessMode,
|
IN KPROCESSOR_MODE AccessMode,
|
||||||
|
@ -616,22 +764,36 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
||||||
|
|
||||||
/* Capture all the info */
|
/* Capture all the info */
|
||||||
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
||||||
ObjectAttributesAccessMode,
|
ProbeMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
ObjectCreateInfo,
|
ObjectCreateInfo,
|
||||||
&ObjectName);
|
&ObjectName);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Validate attributes */
|
/* Validate attributes */
|
||||||
if (Type->TypeInfo.InvalidAttributes &
|
if (Type->TypeInfo.InvalidAttributes & ObjectCreateInfo->Attributes)
|
||||||
ObjectCreateInfo->Attributes)
|
|
||||||
{
|
{
|
||||||
/* Fail */
|
/* Fail */
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Save the pool charges */
|
/* Check if we have a paged charge */
|
||||||
|
if (!PagedPoolCharge)
|
||||||
|
{
|
||||||
|
/* Save it */
|
||||||
|
PagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for nonpaged charge */
|
||||||
|
if (!NonPagedPoolCharge)
|
||||||
|
{
|
||||||
|
/* Save it */
|
||||||
|
NonPagedPoolCharge = ObjectType->
|
||||||
|
TypeInfo.DefaultNonPagedPoolCharge;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the pool charges */
|
||||||
ObjectCreateInfo->PagedPoolCharge = PagedPoolCharge;
|
ObjectCreateInfo->PagedPoolCharge = PagedPoolCharge;
|
||||||
ObjectCreateInfo->NonPagedPoolCharge = NonPagedPoolCharge;
|
ObjectCreateInfo->NonPagedPoolCharge = NonPagedPoolCharge;
|
||||||
|
|
||||||
|
@ -639,7 +801,7 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
||||||
Status = ObpAllocateObject(ObjectCreateInfo,
|
Status = ObpAllocateObject(ObjectCreateInfo,
|
||||||
&ObjectName,
|
&ObjectName,
|
||||||
Type,
|
Type,
|
||||||
ObjectSize + sizeof(OBJECT_HEADER),
|
ObjectSize,
|
||||||
AccessMode,
|
AccessMode,
|
||||||
&Header);
|
&Header);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
|
@ -652,7 +814,7 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
||||||
{
|
{
|
||||||
/* Do the privilege check */
|
/* Do the privilege check */
|
||||||
if (!SeSinglePrivilegeCheck(SeCreatePermanentPrivilege,
|
if (!SeSinglePrivilegeCheck(SeCreatePermanentPrivilege,
|
||||||
ObjectAttributesAccessMode))
|
ProbeMode))
|
||||||
{
|
{
|
||||||
/* Fail */
|
/* Fail */
|
||||||
ObpDeallocateObject(*Object);
|
ObpDeallocateObject(*Object);
|
||||||
|
@ -691,6 +853,7 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
|
||||||
PWCHAR p;
|
PWCHAR p;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
UNICODE_STRING ObjectName;
|
UNICODE_STRING ObjectName;
|
||||||
|
POBJECT_HEADER_CREATOR_INFO CreatorInfo;
|
||||||
|
|
||||||
/* Verify parameters */
|
/* Verify parameters */
|
||||||
if (!(TypeName) ||
|
if (!(TypeName) ||
|
||||||
|
@ -752,7 +915,7 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
|
||||||
Status = ObpAllocateObject(NULL,
|
Status = ObpAllocateObject(NULL,
|
||||||
&ObjectName,
|
&ObjectName,
|
||||||
ObTypeObjectType,
|
ObTypeObjectType,
|
||||||
sizeof(OBJECT_TYPE) + sizeof(OBJECT_HEADER),
|
sizeof(OBJECT_TYPE),
|
||||||
KernelMode,
|
KernelMode,
|
||||||
(POBJECT_HEADER*)&Header);
|
(POBJECT_HEADER*)&Header);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -767,21 +930,30 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
|
||||||
LocalObjectType->Name = ObjectName;
|
LocalObjectType->Name = ObjectName;
|
||||||
Header->Flags |= OB_FLAG_KERNEL_MODE | OB_FLAG_PERMANENT;
|
Header->Flags |= OB_FLAG_KERNEL_MODE | OB_FLAG_PERMANENT;
|
||||||
|
|
||||||
|
/* Clear accounting data */
|
||||||
|
LocalObjectType->TotalNumberOfObjects =
|
||||||
|
LocalObjectType->TotalNumberOfHandles =
|
||||||
|
LocalObjectType->HighWaterNumberOfObjects =
|
||||||
|
LocalObjectType->HighWaterNumberOfHandles = 0;
|
||||||
|
|
||||||
/* Check if this is the first Object Type */
|
/* Check if this is the first Object Type */
|
||||||
if (!ObTypeObjectType)
|
if (!ObTypeObjectType)
|
||||||
{
|
{
|
||||||
|
/* It is, so set this as the type object */
|
||||||
ObTypeObjectType = LocalObjectType;
|
ObTypeObjectType = LocalObjectType;
|
||||||
Header->Type = ObTypeObjectType;
|
Header->Type = ObTypeObjectType;
|
||||||
|
|
||||||
|
/* Set the hard-coded key and object count */
|
||||||
LocalObjectType->TotalNumberOfObjects = 1;
|
LocalObjectType->TotalNumberOfObjects = 1;
|
||||||
LocalObjectType->Key = TAG('O', 'b', 'j', 'T');
|
LocalObjectType->Key = TAG('O', 'b', 'j', 'T');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Set Tag */
|
/* Set Tag */
|
||||||
Tag[0] = TypeName->Buffer[0];
|
Tag[0] = (CHAR)TypeName->Buffer[0];
|
||||||
Tag[1] = TypeName->Buffer[1];
|
Tag[1] = (CHAR)TypeName->Buffer[1];
|
||||||
Tag[2] = TypeName->Buffer[2];
|
Tag[2] = (CHAR)TypeName->Buffer[2];
|
||||||
Tag[3] = TypeName->Buffer[3];
|
Tag[3] = (CHAR)TypeName->Buffer[3];
|
||||||
LocalObjectType->Key = *(PULONG)Tag;
|
LocalObjectType->Key = *(PULONG)Tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -797,9 +969,10 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate how much space our header'll take up */
|
/* Calculate how much space our header'll take up */
|
||||||
HeaderSize = sizeof(OBJECT_HEADER) + sizeof(OBJECT_HEADER_NAME_INFO) +
|
HeaderSize = sizeof(OBJECT_HEADER) +
|
||||||
|
sizeof(OBJECT_HEADER_NAME_INFO) +
|
||||||
(ObjectTypeInitializer->MaintainHandleCount ?
|
(ObjectTypeInitializer->MaintainHandleCount ?
|
||||||
sizeof(OBJECT_HEADER_HANDLE_INFO) : 0);
|
sizeof(OBJECT_HEADER_HANDLE_INFO) : 0);
|
||||||
|
|
||||||
/* Check the pool type */
|
/* Check the pool type */
|
||||||
if (ObjectTypeInitializer->PoolType == NonPagedPool)
|
if (ObjectTypeInitializer->PoolType == NonPagedPool)
|
||||||
|
@ -846,17 +1019,37 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
|
||||||
ExInitializeResourceLite(&LocalObjectType->Mutex);
|
ExInitializeResourceLite(&LocalObjectType->Mutex);
|
||||||
InitializeListHead(&LocalObjectType->TypeList);
|
InitializeListHead(&LocalObjectType->TypeList);
|
||||||
|
|
||||||
/* Check if we're actually creating the directory object itself */
|
/* Get creator info and insert it into the type list */
|
||||||
if (ObpTypeDirectoryObject)
|
CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(Header);
|
||||||
|
if (CreatorInfo) InsertTailList(&ObTypeObjectType->TypeList,
|
||||||
|
&CreatorInfo->TypeList);
|
||||||
|
|
||||||
|
/* Set the index and the entry into the object type array */
|
||||||
|
LocalObjectType->Index = ObTypeObjectType->TotalNumberOfObjects;
|
||||||
|
if (LocalObjectType->Index < 32)
|
||||||
{
|
{
|
||||||
/* Insert it into the Object Directory */
|
/* It fits, insert it */
|
||||||
ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, Header);
|
ObpObjectTypes[LocalObjectType->Index - 1] = LocalObjectType;
|
||||||
ObReferenceObject(ObpTypeDirectoryObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the object type and creations tatus */
|
/* Check if we're actually creating the directory object itself */
|
||||||
*ObjectType = LocalObjectType;
|
if (!(ObpTypeDirectoryObject) ||
|
||||||
return Status;
|
(ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, Header)))
|
||||||
|
{
|
||||||
|
/* Check if the type directory exists */
|
||||||
|
if (ObpTypeDirectoryObject)
|
||||||
|
{
|
||||||
|
/* Reference it */
|
||||||
|
ObReferenceObject(ObpTypeDirectoryObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the object type and success */
|
||||||
|
*ObjectType = LocalObjectType;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we got here, then we failed */
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
|
@ -878,7 +1071,7 @@ NTAPI
|
||||||
ObMakeTemporaryObject(IN PVOID ObjectBody)
|
ObMakeTemporaryObject(IN PVOID ObjectBody)
|
||||||
{
|
{
|
||||||
/* Call the internal API */
|
/* Call the internal API */
|
||||||
ObpSetPermanentObject (ObjectBody, FALSE);
|
ObpSetPermanentObject(ObjectBody, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
|
|
|
@ -21,6 +21,82 @@ POBJECT_DIRECTORY ObpTypeDirectoryObject = NULL;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ObpCreateDosDevicesDirectory(VOID)
|
||||||
|
{
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
UNICODE_STRING Name, LinkName;
|
||||||
|
HANDLE Handle, SymHandle;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Create the '\??' directory */
|
||||||
|
RtlInitUnicodeString(&Name, L"\\??");
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&Name,
|
||||||
|
OBJ_PERMANENT,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
Status = NtCreateDirectoryObject(&Handle,
|
||||||
|
DIRECTORY_ALL_ACCESS,
|
||||||
|
&ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status)) return FALSE;
|
||||||
|
|
||||||
|
/* Initialize the GLOBALROOT path */
|
||||||
|
RtlInitUnicodeString(&LinkName, L"GLOBALROOT");
|
||||||
|
RtlInitUnicodeString(&Name, L"");
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&LinkName,
|
||||||
|
OBJ_PERMANENT,
|
||||||
|
Handle,
|
||||||
|
NULL);
|
||||||
|
Status = NtCreateSymbolicLinkObject(&SymHandle,
|
||||||
|
SYMBOLIC_LINK_ALL_ACCESS,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&Name);
|
||||||
|
if (NT_SUCCESS(Status)) NtClose(SymHandle);
|
||||||
|
|
||||||
|
/* Link \??\Global to \?? */
|
||||||
|
RtlInitUnicodeString(&LinkName, L"Global");
|
||||||
|
RtlInitUnicodeString(&Name, L"\\??");
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&LinkName,
|
||||||
|
OBJ_PERMANENT,
|
||||||
|
Handle,
|
||||||
|
NULL);
|
||||||
|
Status = NtCreateSymbolicLinkObject(&SymHandle,
|
||||||
|
SYMBOLIC_LINK_ALL_ACCESS,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&Name);
|
||||||
|
if (NT_SUCCESS(Status)) NtClose(SymHandle);
|
||||||
|
|
||||||
|
/* Close the directory handle */
|
||||||
|
NtClose(Handle);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
/* Create link from '\DosDevices' to '\??' directory */
|
||||||
|
RtlCreateUnicodeString(&LinkName, L"\\DosDevices");
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&LinkName,
|
||||||
|
OBJ_PERMANENT,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
Status = NtCreateSymbolicLinkObject(&SymHandle,
|
||||||
|
SYMBOLIC_LINK_ALL_ACCESS,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&Name);
|
||||||
|
if (NT_SUCCESS(Status)) NtClose(SymHandle);
|
||||||
|
|
||||||
|
/* FIXME: Hack Hack! */
|
||||||
|
ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
|
sizeof(*ObSystemDeviceMap),
|
||||||
|
TAG('O', 'b', 'D', 'm'));
|
||||||
|
RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap));
|
||||||
|
|
||||||
|
/* Return status */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
ObDereferenceDeviceMap(IN PEPROCESS Process)
|
ObDereferenceDeviceMap(IN PEPROCESS Process)
|
||||||
|
|
|
@ -21,14 +21,6 @@
|
||||||
|
|
||||||
POBJECT_TYPE ObSymbolicLinkType = NULL;
|
POBJECT_TYPE ObSymbolicLinkType = NULL;
|
||||||
|
|
||||||
static GENERIC_MAPPING ObpSymbolicLinkMapping =
|
|
||||||
{
|
|
||||||
STANDARD_RIGHTS_READ | SYMBOLIC_LINK_QUERY,
|
|
||||||
STANDARD_RIGHTS_WRITE,
|
|
||||||
STANDARD_RIGHTS_EXECUTE | SYMBOLIC_LINK_QUERY,
|
|
||||||
SYMBOLIC_LINK_ALL_ACCESS
|
|
||||||
};
|
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
|
@ -181,40 +173,6 @@ ObpParseSymbolicLink(IN PVOID ParsedObject,
|
||||||
return STATUS_REPARSE;
|
return STATUS_REPARSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*++
|
|
||||||
* @name ObInitSymbolicLinkImplementation
|
|
||||||
*
|
|
||||||
* The ObInitSymbolicLinkImplementation routine <FILLMEIN>
|
|
||||||
*
|
|
||||||
* @param None.
|
|
||||||
*
|
|
||||||
* @return None.
|
|
||||||
*
|
|
||||||
* @remarks None.
|
|
||||||
*
|
|
||||||
*--*/
|
|
||||||
VOID
|
|
||||||
INIT_FUNCTION
|
|
||||||
NTAPI
|
|
||||||
ObInitSymbolicLinkImplementation(VOID)
|
|
||||||
{
|
|
||||||
UNICODE_STRING Name;
|
|
||||||
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
|
|
||||||
|
|
||||||
/* Initialize the Directory type */
|
|
||||||
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
|
|
||||||
RtlInitUnicodeString(&Name, L"SymbolicLink");
|
|
||||||
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
|
|
||||||
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_SYMBOLIC_LINK);
|
|
||||||
ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping;
|
|
||||||
ObjectTypeInitializer.PoolType = NonPagedPool;
|
|
||||||
ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS;
|
|
||||||
ObjectTypeInitializer.UseDefaultObject = TRUE;
|
|
||||||
ObjectTypeInitializer.ParseProcedure = ObpParseSymbolicLink;
|
|
||||||
ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink;
|
|
||||||
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObSymbolicLinkType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS **********************************************************/
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue