* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ob/namespc.c
* PURPOSE: Manages the system namespace
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
#define NDEBUG
#include <internal/debug.h>
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, ObInit)
+#endif
+
+
+extern ULONG NtGlobalFlag;
/* GLOBALS ****************************************************************/
POBJECT_TYPE ObTypeObjectType = NULL;
PDIRECTORY_OBJECT NameSpaceRoot = NULL;
+PDIRECTORY_OBJECT ObpTypeDirectoryObject = NULL;
/* FIXME: Move this somewhere else once devicemap support is in */
PDEVICE_MAP ObSystemDeviceMap = NULL;
+KEVENT ObpDefaultObject;
static GENERIC_MAPPING ObpDirectoryMapping = {
STANDARD_RIGHTS_READ|DIRECTORY_QUERY|DIRECTORY_TRAVERSE,
STANDARD_RIGHTS_EXECUTE,
0x000F0001};
+NTSTATUS
+STDCALL
+ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
+ PUNICODE_STRING ObjectName,
+ POBJECT_TYPE ObjectType,
+ ULONG ObjectSize,
+ POBJECT_HEADER *ObjectHeader);
+
/* FUNCTIONS **************************************************************/
/*
{
PVOID Object = NULL;
UNICODE_STRING RemainingPath;
- OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING ObjectName;
+ OBJECT_CREATE_INFORMATION ObjectCreateInfo;
NTSTATUS Status;
-
+
PAGED_CODE();
- InitializeObjectAttributes(&ObjectAttributes,
- ObjectPath,
- Attributes | OBJ_OPENIF,
- NULL,
- NULL);
- Status = ObFindObject(&ObjectAttributes,
+ /* Capture the name */
+ DPRINT("Capturing Name\n");
+ Status = ObpCaptureObjectName(&ObjectName, ObjectPath, AccessMode);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ObpCaptureObjectName() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ /*
+ * Create a fake ObjectCreateInfo structure. Note that my upcoming
+ * ObFindObject refactoring will remove the need for this hack.
+ */
+ ObjectCreateInfo.RootDirectory = NULL;
+ ObjectCreateInfo.Attributes = Attributes;
+
+ Status = ObFindObject(&ObjectCreateInfo,
+ &ObjectName,
&Object,
&RemainingPath,
ObjectType);
+
+ if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+
if (!NT_SUCCESS(Status))
{
return(Status);
}
-CHECKPOINT;
-DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath.Buffer, Object);
+ DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath.Buffer, Object);
if (RemainingPath.Buffer != NULL || Object == NULL)
{
-CHECKPOINT;
-DPRINT("Object %p\n", Object);
+ DPRINT("Object %p\n", Object);
*ObjectPtr = NULL;
RtlFreeUnicodeString (&RemainingPath);
return(STATUS_OBJECT_NAME_NOT_FOUND);
/**********************************************************************
* NAME EXPORTED
* ObOpenObjectByName
- *
+ *
* DESCRIPTION
* Obtain a handle to an existing object.
- *
+ *
* ARGUMENTS
* ObjectAttributes
* ...
{
UNICODE_STRING RemainingPath;
PVOID Object = NULL;
+ UNICODE_STRING ObjectName;
+ OBJECT_CREATE_INFORMATION ObjectCreateInfo;
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT("ObOpenObjectByName(...)\n");
- Status = ObFindObject(ObjectAttributes,
+ /* Capture all the info */
+ DPRINT("Capturing Create Info\n");
+ Status = ObpCaptureObjectAttributes(ObjectAttributes,
+ AccessMode,
+ ObjectType,
+ &ObjectCreateInfo,
+ &ObjectName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ Status = ObFindObject(&ObjectCreateInfo,
+ &ObjectName,
&Object,
&RemainingPath,
ObjectType);
+ ObpReleaseCapturedAttributes(&ObjectCreateInfo);
+ if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
if (!NT_SUCCESS(Status))
{
DPRINT("ObFindObject() failed (Status %lx)\n", Status);
return Status;
}
- if (RemainingPath.Buffer != NULL ||
- Object == NULL)
+ DPRINT("OBject: %x, Remaining Path: %wZ\n", Object, &RemainingPath);
+ if (Object == NULL)
{
- RtlFreeUnicodeString(&RemainingPath);
- return STATUS_UNSUCCESSFUL;
+ RtlFreeUnicodeString(&RemainingPath);
+ return STATUS_UNSUCCESSFUL;
}
-
- Status = ObCreateHandle(PsGetCurrentProcess(),
+ if (RemainingPath.Buffer != NULL)
+ {
+ if (wcschr(RemainingPath.Buffer + 1, L'\\') == NULL)
+ Status = STATUS_OBJECT_NAME_NOT_FOUND;
+ else
+ Status =STATUS_OBJECT_PATH_NOT_FOUND;
+ RtlFreeUnicodeString(&RemainingPath);
+ ObDereferenceObject(Object);
+ return Status;
+ }
+
+ Status = ObpCreateHandle(PsGetCurrentProcess(),
Object,
DesiredAccess,
FALSE,
PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo)
{
//KIRQL OldIrql ;
-
+
/*
* FIXME: This is an ugly hack for now, to always return the System Device Map
* instead of returning the Process Device Map. Not important yet since we don't use it
*/
-
+
/* FIXME: Acquire the DeviceMap Spinlock */
// KeAcquireSpinLock(DeviceMap->Lock, &OldIrql);
-
+
/* Make a copy */
DeviceMapInfo->Query.DriveMap = ObSystemDeviceMap->DriveMap;
RtlMoveMemory(DeviceMapInfo->Query.DriveType, ObSystemDeviceMap->DriveType, sizeof(ObSystemDeviceMap->DriveType));
-
+
/* FIXME: Release the DeviceMap Spinlock */
// KeReleasepinLock(DeviceMap->Lock, OldIrql);
-}
-
+}
+
VOID
+NTAPI
ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
POBJECT_HEADER Header,
PWSTR Name)
{
KIRQL oldlvl;
- RtlpCreateUnicodeString(&Header->Name, Name, NonPagedPool);
- Header->Parent = Parent;
+ ASSERT(HEADER_TO_OBJECT_NAME(Header));
+ HEADER_TO_OBJECT_NAME(Header)->Directory = Parent;
KeAcquireSpinLock(&Parent->Lock, &oldlvl);
InsertTailList(&Parent->head, &Header->Entry);
VOID
+NTAPI
ObpRemoveEntryDirectory(POBJECT_HEADER Header)
/*
* FUNCTION: Remove an entry from a namespace directory
DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header);
- KeAcquireSpinLock(&(Header->Parent->Lock),&oldlvl);
- RemoveEntryList(&(Header->Entry));
- KeReleaseSpinLock(&(Header->Parent->Lock),oldlvl);
+ KeAcquireSpinLock(&(HEADER_TO_OBJECT_NAME(Header)->Directory->Lock),&oldlvl);
+ if (Header->Entry.Flink && Header->Entry.Blink)
+ {
+ RemoveEntryList(&(Header->Entry));
+ Header->Entry.Flink = Header->Entry.Blink = NULL;
+ }
+ KeReleaseSpinLock(&(HEADER_TO_OBJECT_NAME(Header)->Directory->Lock),oldlvl);
}
+NTSTATUS
+STDCALL
+ObpCreateDirectory(OB_OPEN_REASON Reason,
+ PVOID ObjectBody,
+ PEPROCESS Process,
+ ULONG HandleCount,
+ ACCESS_MASK GrantedAccess)
+{
+ PDIRECTORY_OBJECT Directory = ObjectBody;
+
+ if (Reason == ObCreateHandle)
+ {
+ InitializeListHead(&Directory->head);
+ KeInitializeSpinLock(&Directory->Lock);
+ }
+
+ return STATUS_SUCCESS;
+}
PVOID
ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject,
POBJECT_HEADER current_obj;
DPRINT("ObFindEntryDirectory(dir %x, name %S)\n",DirectoryObject, Name);
-
+
if (Name[0]==0)
{
return(DirectoryObject);
}
if (Name[0]=='.' && Name[1]=='.' && Name[2]==0)
{
- return(BODY_TO_HEADER(DirectoryObject)->Parent);
+ return(HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(DirectoryObject))->Directory);
}
while (current!=(&(DirectoryObject->head)))
{
current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry);
- DPRINT(" Scanning: %S for: %S\n",current_obj->Name.Buffer, Name);
+ DPRINT(" Scanning: %S for: %S\n",HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name);
if (Attributes & OBJ_CASE_INSENSITIVE)
{
- if (_wcsicmp(current_obj->Name.Buffer, Name)==0)
+ if (_wcsicmp(HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name)==0)
{
- DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
- return(HEADER_TO_BODY(current_obj));
+ DPRINT("Found it %x\n",¤t_obj->Body);
+ return(¤t_obj->Body);
}
}
else
{
- if ( wcscmp(current_obj->Name.Buffer, Name)==0)
+ if ( wcscmp(HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name)==0)
{
- DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
- return(HEADER_TO_BODY(current_obj));
+ DPRINT("Found it %x\n",¤t_obj->Body);
+ return(¤t_obj->Body);
}
}
current = current->Flink;
PWSTR Start;
PWSTR End;
PVOID FoundObject;
+ KIRQL oldlvl;
DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %S)\n",
Object,Path,*Path);
*End = 0;
}
+ KeAcquireSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), &oldlvl);
FoundObject = ObpFindEntryDirectory(Object, Start, Attributes);
if (FoundObject == NULL)
{
+ KeReleaseSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), oldlvl);
if (End != NULL)
{
*End = L'\\';
STANDARD_RIGHTS_REQUIRED,
NULL,
UserMode);
-
+ KeReleaseSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), oldlvl);
if (End != NULL)
{
*End = L'\\';
return STATUS_SUCCESS;
}
-
-NTSTATUS STDCALL
-ObpCreateDirectory(PVOID ObjectBody,
- PVOID Parent,
- PWSTR RemainingPath,
- POBJECT_ATTRIBUTES ObjectAttributes)
+VOID
+INIT_FUNCTION
+ObInit(VOID)
{
- PDIRECTORY_OBJECT DirectoryObject = (PDIRECTORY_OBJECT)ObjectBody;
-
- DPRINT("ObpCreateDirectory(ObjectBody %x, Parent %x, RemainingPath %S)\n",
- ObjectBody, Parent, RemainingPath);
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING Name;
+ SECURITY_DESCRIPTOR SecurityDescriptor;
+ OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
+
+ /* Initialize the security descriptor cache */
+ ObpInitSdCache();
+
+ /* Initialize the Default Event */
+ KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE );
+
+ /* Create the Type Type */
+ DPRINT("Creating Type Type\n");
+ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
+ RtlInitUnicodeString(&Name, L"Type");
+ ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
+ ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS;
+ ObjectTypeInitializer.UseDefaultObject = TRUE;
+ ObjectTypeInitializer.MaintainTypeList = TRUE;
+ ObjectTypeInitializer.PoolType = NonPagedPool;
+ ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
+ ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE);
+ ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObTypeObjectType);
+
+ /* Create the Directory Type */
+ DPRINT("Creating Directory Type\n");
+ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
+ RtlInitUnicodeString(&Name, L"Directory");
+ ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
+ ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
+ ObjectTypeInitializer.UseDefaultObject = FALSE;
+ ObjectTypeInitializer.OpenProcedure = ObpCreateDirectory;
+ ObjectTypeInitializer.ParseProcedure = ObpParseDirectory;
+ ObjectTypeInitializer.MaintainTypeList = FALSE;
+ ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
+ ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DIRECTORY_OBJECT);
+ ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObDirectoryType);
+
+ /* Create security descriptor */
+ RtlCreateSecurityDescriptor(&SecurityDescriptor,
+ SECURITY_DESCRIPTOR_REVISION1);
+ RtlSetOwnerSecurityDescriptor(&SecurityDescriptor,
+ SeAliasAdminsSid,
+ FALSE);
+ RtlSetGroupSecurityDescriptor(&SecurityDescriptor,
+ SeLocalSystemSid,
+ FALSE);
+ RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
+ TRUE,
+ SePublicDefaultDacl,
+ FALSE);
+
+ /* Create root directory */
+ DPRINT("Creating Root Directory\n");
+ InitializeObjectAttributes(&ObjectAttributes,
+ NULL,
+ OBJ_PERMANENT,
+ NULL,
+ &SecurityDescriptor);
+ ObCreateObject(KernelMode,
+ ObDirectoryType,
+ &ObjectAttributes,
+ KernelMode,
+ NULL,
+ sizeof(DIRECTORY_OBJECT),
+ 0,
+ 0,
+ (PVOID*)&NameSpaceRoot);
+ ObInsertObject((PVOID)NameSpaceRoot,
+ NULL,
+ DIRECTORY_ALL_ACCESS,
+ 0,
+ NULL,
+ NULL);
+
+ /* Create '\ObjectTypes' directory */
+ RtlInitUnicodeString(&Name, L"\\ObjectTypes");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_PERMANENT,
+ NULL,
+ &SecurityDescriptor);
+ ObCreateObject(KernelMode,
+ ObDirectoryType,
+ &ObjectAttributes,
+ KernelMode,
+ NULL,
+ sizeof(DIRECTORY_OBJECT),
+ 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 */
+ ObpAddEntryDirectory(ObpTypeDirectoryObject, BODY_TO_HEADER(ObTypeObjectType), NULL);
+ ObpAddEntryDirectory(ObpTypeDirectoryObject, BODY_TO_HEADER(ObDirectoryType), NULL);
+
+ /* Create 'symbolic link' object type */
+ ObInitSymbolicLinkImplementation();
+
+ /* FIXME: Hack Hack! */
+ ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ObSystemDeviceMap), TAG('O', 'b', 'D', 'm'));
+ RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap));
+}
- if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
+NTSTATUS
+STDCALL
+ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
+ PUNICODE_STRING TypeName,
+ POBJECT_TYPE *ObjectType)
+{
+ POBJECT_HEADER Header;
+ POBJECT_TYPE LocalObjectType;
+ ULONG HeaderSize;
+ NTSTATUS Status;
+
+ DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", TypeName);
+
+ /* Allocate the Object */
+ Status = ObpAllocateObject(NULL,
+ TypeName,
+ ObTypeObjectType,
+ OBJECT_ALLOC_SIZE(sizeof(OBJECT_TYPE)),
+ &Header);
+ if (!NT_SUCCESS(Status))
{
- return(STATUS_UNSUCCESSFUL);
+ DPRINT1("ObpAllocateObject failed!\n");
+ return Status;
+ }
+
+ LocalObjectType = (POBJECT_TYPE)&Header->Body;
+ DPRINT("Local ObjectType: %p Header: %p \n", LocalObjectType, Header);
+
+ /* Check if this is the first Object Type */
+ if (!ObTypeObjectType)
+ {
+ ObTypeObjectType = LocalObjectType;
+ Header->Type = ObTypeObjectType;
+ LocalObjectType->Key = TAG('O', 'b', 'j', 'T');
+ }
+ else
+ {
+ CHAR Tag[4];
+ Tag[0] = TypeName->Buffer[0];
+ Tag[1] = TypeName->Buffer[1];
+ Tag[2] = TypeName->Buffer[2];
+ Tag[3] = TypeName->Buffer[3];
+
+ /* Set Tag */
+ DPRINT("Convert: %s \n", Tag);
+ LocalObjectType->Key = *(PULONG)Tag;
}
+
+ /* Set it up */
+ LocalObjectType->TypeInfo = *ObjectTypeInitializer;
+ LocalObjectType->Name = *TypeName;
+ LocalObjectType->TypeInfo.PoolType = ObjectTypeInitializer->PoolType;
- InitializeListHead(&DirectoryObject->head);
- KeInitializeSpinLock(&DirectoryObject->Lock);
+ /* These two flags need to be manually set up */
+ Header->Flags |= OB_FLAG_KERNEL_MODE | OB_FLAG_PERMANENT;
- return(STATUS_SUCCESS);
-}
+ /* Check if we have to maintain a type list */
+ if (NtGlobalFlag & FLG_MAINTAIN_OBJECT_TYPELIST)
+ {
+ /* Enable support */
+ LocalObjectType->TypeInfo.MaintainTypeList = TRUE;
+ }
+ /* Calculate how much space our header'll take up */
+ HeaderSize = sizeof(OBJECT_HEADER) + sizeof(OBJECT_HEADER_NAME_INFO) +
+ (ObjectTypeInitializer->MaintainHandleCount ?
+ sizeof(OBJECT_HEADER_HANDLE_INFO) : 0);
-VOID INIT_FUNCTION
-ObInit(VOID)
-/*
- * FUNCTION: Initialize the object manager namespace
- */
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING Name;
- SECURITY_DESCRIPTOR SecurityDescriptor;
+ /* Update the Pool Charges */
+ if (ObjectTypeInitializer->PoolType == NonPagedPool)
+ {
+ LocalObjectType->TypeInfo.DefaultNonPagedPoolCharge += HeaderSize;
+ }
+ else
+ {
+ LocalObjectType->TypeInfo.DefaultPagedPoolCharge += HeaderSize;
+ }
+
+ /* All objects types need a security procedure */
+ if (!ObjectTypeInitializer->SecurityProcedure)
+ {
+ LocalObjectType->TypeInfo.SecurityProcedure = SeDefaultObjectMethod;
+ }
- /* Initialize the security descriptor cache */
- ObpInitSdCache();
+ /* Select the Wait Object */
+ if (LocalObjectType->TypeInfo.UseDefaultObject)
+ {
+ /* Add the SYNCHRONIZE access mask since it's waitable */
+ LocalObjectType->TypeInfo.ValidAccessMask |= SYNCHRONIZE;
- /* create 'directory' object type */
- ObDirectoryType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-
- ObDirectoryType->Tag = TAG('D', 'I', 'R', 'T');
- ObDirectoryType->TotalObjects = 0;
- ObDirectoryType->TotalHandles = 0;
- ObDirectoryType->PeakObjects = 0;
- ObDirectoryType->PeakHandles = 0;
- ObDirectoryType->PagedPoolCharge = 0;
- ObDirectoryType->NonpagedPoolCharge = sizeof(DIRECTORY_OBJECT);
- ObDirectoryType->Mapping = &ObpDirectoryMapping;
- ObDirectoryType->Dump = NULL;
- ObDirectoryType->Open = NULL;
- ObDirectoryType->Close = NULL;
- ObDirectoryType->Delete = NULL;
- ObDirectoryType->Parse = ObpParseDirectory;
- ObDirectoryType->Security = NULL;
- ObDirectoryType->QueryName = NULL;
- ObDirectoryType->OkayToClose = NULL;
- ObDirectoryType->Create = ObpCreateDirectory;
- ObDirectoryType->DuplicationNotify = NULL;
-
- RtlInitUnicodeString(&ObDirectoryType->TypeName,
- L"Directory");
-
- /* create 'type' object type*/
- ObTypeObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-
- ObTypeObjectType->Tag = TAG('T', 'y', 'p', 'T');
- ObTypeObjectType->TotalObjects = 0;
- ObTypeObjectType->TotalHandles = 0;
- ObTypeObjectType->PeakObjects = 0;
- ObTypeObjectType->PeakHandles = 0;
- ObTypeObjectType->PagedPoolCharge = 0;
- ObTypeObjectType->NonpagedPoolCharge = sizeof(TYPE_OBJECT);
- ObTypeObjectType->Mapping = &ObpTypeMapping;
- ObTypeObjectType->Dump = NULL;
- ObTypeObjectType->Open = NULL;
- ObTypeObjectType->Close = NULL;
- ObTypeObjectType->Delete = NULL;
- ObTypeObjectType->Parse = NULL;
- ObTypeObjectType->Security = NULL;
- ObTypeObjectType->QueryName = NULL;
- ObTypeObjectType->OkayToClose = NULL;
- ObTypeObjectType->Create = NULL;
- ObTypeObjectType->DuplicationNotify = NULL;
-
- RtlInitUnicodeString(&ObTypeObjectType->TypeName,
- L"ObjectType");
-
- /* Create security descriptor */
- RtlCreateSecurityDescriptor(&SecurityDescriptor,
- SECURITY_DESCRIPTOR_REVISION1);
-
- RtlSetOwnerSecurityDescriptor(&SecurityDescriptor,
- SeAliasAdminsSid,
- FALSE);
-
- RtlSetGroupSecurityDescriptor(&SecurityDescriptor,
- SeLocalSystemSid,
- FALSE);
-
- RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
- TRUE,
- SePublicDefaultDacl,
- FALSE);
-
- /* Create root directory */
- InitializeObjectAttributes(&ObjectAttributes,
- NULL,
- OBJ_PERMANENT,
- NULL,
- &SecurityDescriptor);
- ObCreateObject(KernelMode,
- ObDirectoryType,
- &ObjectAttributes,
- KernelMode,
- NULL,
- sizeof(DIRECTORY_OBJECT),
- 0,
- 0,
- (PVOID*)&NameSpaceRoot);
-
- /* Create '\ObjectTypes' directory */
- RtlRosInitUnicodeStringFromLiteral(&Name,
- L"\\ObjectTypes");
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- OBJ_PERMANENT,
- NULL,
- &SecurityDescriptor);
- ObCreateObject(KernelMode,
- ObDirectoryType,
- &ObjectAttributes,
- KernelMode,
- NULL,
- sizeof(DIRECTORY_OBJECT),
- 0,
- 0,
- NULL);
-
- ObpCreateTypeObject(ObDirectoryType);
- ObpCreateTypeObject(ObTypeObjectType);
-
- /* Create 'symbolic link' object type */
- ObInitSymbolicLinkImplementation();
-
- /* FIXME: Hack Hack! */
- ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ObSystemDeviceMap), TAG('O', 'b', 'D', 'm'));
- RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap));
-}
+ /* Use the "Default Object", a simple event */
+ LocalObjectType->DefaultObject = &ObpDefaultObject;
+ }
+ /* Special system objects get an optimized hack so they can be waited on */
+ else if (TypeName->Length == 8 && !wcscmp(TypeName->Buffer, L"File"))
+ {
+ LocalObjectType->DefaultObject = (PVOID)FIELD_OFFSET(FILE_OBJECT, Event);
+ }
+ /* FIXME: When LPC stops sucking, add a hack for Waitable Ports */
+ else
+ {
+ /* No default Object */
+ LocalObjectType->DefaultObject = NULL;
+ }
+ /* Initialize Object Type components */
+ ExInitializeResourceLite(&LocalObjectType->Mutex);
+ InitializeListHead(&LocalObjectType->TypeList);
-NTSTATUS
-ObpCreateTypeObject(POBJECT_TYPE ObjectType)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- WCHAR NameString[120];
- PTYPE_OBJECT TypeObject = NULL;
- UNICODE_STRING Name;
- NTSTATUS Status;
-
- DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", &ObjectType->TypeName);
- wcscpy(NameString, L"\\ObjectTypes\\");
- wcscat(NameString, ObjectType->TypeName.Buffer);
- RtlInitUnicodeString(&Name,
- NameString);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- OBJ_PERMANENT,
- NULL,
- NULL);
- Status = ObCreateObject(KernelMode,
- ObTypeObjectType,
- &ObjectAttributes,
- KernelMode,
- NULL,
- sizeof(TYPE_OBJECT),
- 0,
- 0,
- (PVOID*)&TypeObject);
- if (NT_SUCCESS(Status))
+ /* Insert it into the Object Directory */
+ if (ObpTypeDirectoryObject)
{
- TypeObject->ObjectType = ObjectType;
+ ObpAddEntryDirectory(ObpTypeDirectoryObject, Header, TypeName->Buffer);
+ ObReferenceObject(ObpTypeDirectoryObject);
}
- return(STATUS_SUCCESS);
-}
+ *ObjectType = LocalObjectType;
+ return Status;
+}
/* EOF */