#define NDEBUG
#include <internal/debug.h>
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, ObInit)
+#endif
+
+
+extern ULONG NtGlobalFlag;
/* GLOBALS ****************************************************************/
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,
PVOID Object = NULL;
UNICODE_STRING RemainingPath;
UNICODE_STRING ObjectName;
- OBJECT_ATTRIBUTES ObjectAttributes;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
NTSTATUS Status;
PAGED_CODE();
- InitializeObjectAttributes(&ObjectAttributes,
- ObjectPath,
- Attributes | OBJ_OPENIF,
- NULL,
- NULL);
-
- /* Capture all the info */
- DPRINT("Capturing Create Info\n");
- Status = ObpCaptureObjectAttributes(&ObjectAttributes,
- AccessMode,
- ObjectType,
- &ObjectCreateInfo,
- &ObjectName);
+ /* Capture the name */
+ DPRINT("Capturing Name\n");
+ Status = ObpCaptureObjectName(&ObjectName, ObjectPath, AccessMode);
if (!NT_SUCCESS(Status))
{
- DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", 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,
+ &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);
}
Status = ObFindObject(&ObjectCreateInfo,
- &ObjectName,
+ &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;
}
- DPRINT("OBject: %x, Remaining Path: %wZ\n", Object, &RemainingPath);
+ DPRINT("OBject: %x, Remaining Path: %wZ\n", Object, &RemainingPath);
if (Object == NULL)
{
RtlFreeUnicodeString(&RemainingPath);
- ObpReleaseCapturedAttributes(&ObjectCreateInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return STATUS_UNSUCCESSFUL;
}
if (RemainingPath.Buffer != NULL)
Status =STATUS_OBJECT_PATH_NOT_FOUND;
RtlFreeUnicodeString(&RemainingPath);
ObDereferenceObject(Object);
- ObpReleaseCapturedAttributes(&ObjectCreateInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return Status;
}
ObDereferenceObject(Object);
RtlFreeUnicodeString(&RemainingPath);
- ObpReleaseCapturedAttributes(&ObjectCreateInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return Status;
}
}
VOID
+NTAPI
ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
POBJECT_HEADER Header,
PWSTR Name)
{
KIRQL oldlvl;
- Header->NameInfo->Directory = Parent;
+ ASSERT(HEADER_TO_OBJECT_NAME(Header));
+ HEADER_TO_OBJECT_NAME(Header)->Directory = Parent;
KeAcquireSpinLock(&Parent->Lock, &oldlvl);
InsertTailList(&Parent->head, &Header->Entry);
VOID
+NTAPI
ObpRemoveEntryDirectory(POBJECT_HEADER Header)
/*
* FUNCTION: Remove an entry from a namespace directory
DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header);
- KeAcquireSpinLock(&(Header->NameInfo->Directory->Lock),&oldlvl);
+ KeAcquireSpinLock(&(HEADER_TO_OBJECT_NAME(Header)->Directory->Lock),&oldlvl);
if (Header->Entry.Flink && Header->Entry.Blink)
{
RemoveEntryList(&(Header->Entry));
Header->Entry.Flink = Header->Entry.Blink = NULL;
}
- KeReleaseSpinLock(&(Header->NameInfo->Directory->Lock),oldlvl);
+ KeReleaseSpinLock(&(HEADER_TO_OBJECT_NAME(Header)->Directory->Lock),oldlvl);
}
NTSTATUS
}
if (Name[0]=='.' && Name[1]=='.' && Name[2]==0)
{
- return(BODY_TO_HEADER(DirectoryObject)->NameInfo->Directory);
+ return(HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(DirectoryObject))->Directory);
}
while (current!=(&(DirectoryObject->head)))
{
current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry);
- DPRINT(" Scanning: %S for: %S\n",current_obj->NameInfo->Name.Buffer, Name);
+ DPRINT(" Scanning: %S for: %S\n",HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name);
if (Attributes & OBJ_CASE_INSENSITIVE)
{
- if (_wcsicmp(current_obj->NameInfo->Name.Buffer, Name)==0)
+ if (_wcsicmp(HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name)==0)
{
- DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
- return(HEADER_TO_BODY(current_obj));
+ DPRINT("Found it %x\n",¤t_obj->Body);
+ return(¤t_obj->Body);
}
}
else
{
- if ( wcscmp(current_obj->NameInfo->Name.Buffer, Name)==0)
+ if ( wcscmp(HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name)==0)
{
- DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
- return(HEADER_TO_BODY(current_obj));
+ DPRINT("Found it %x\n",¤t_obj->Body);
+ return(¤t_obj->Body);
}
}
current = current->Flink;
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'\\';
/* 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));
{
POBJECT_HEADER Header;
POBJECT_TYPE LocalObjectType;
+ ULONG HeaderSize;
NTSTATUS Status;
DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", TypeName);
return Status;
}
- LocalObjectType = HEADER_TO_BODY(Header);
+ LocalObjectType = (POBJECT_TYPE)&Header->Body;
+ DPRINT("Local ObjectType: %p Header: %p \n", LocalObjectType, Header);
/* Check if this is the first Object Type */
if (!ObTypeObjectType)
{
ObTypeObjectType = LocalObjectType;
- Header->ObjectType = ObTypeObjectType;
+ Header->Type = ObTypeObjectType;
+ LocalObjectType->Key = TAG('O', 'b', 'j', 'T');
}
-
- /* FIXME: Generate Tag */
+ 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;
+
+ /* These two flags need to be manually set up */
+ Header->Flags |= OB_FLAG_KERNEL_MODE | OB_FLAG_PERMANENT;
+
+ /* 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);
+
+ /* 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;
+ }
+
+ /* Select the Wait Object */
+ if (LocalObjectType->TypeInfo.UseDefaultObject)
+ {
+ /* Add the SYNCHRONIZE access mask since it's waitable */
+ LocalObjectType->TypeInfo.ValidAccessMask |= SYNCHRONIZE;
+
+ /* 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);
+
/* Insert it into the Object Directory */
if (ObpTypeDirectoryObject)
{
ObpAddEntryDirectory(ObpTypeDirectoryObject, Header, TypeName->Buffer);
ObReferenceObject(ObpTypeDirectoryObject);
}
-
+
*ObjectType = LocalObjectType;
return Status;
}