Fix merge r65567.
[reactos.git] / ntoskrnl / ob / oblife.c
index 5b47274..1edc2ff 100644 (file)
@@ -1027,11 +1027,11 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
     POBJECT_TYPE LocalObjectType;
     ULONG HeaderSize;
     NTSTATUS Status;
-    CHAR Tag[4];
     OBP_LOOKUP_CONTEXT Context;
     PWCHAR p;
     ULONG i;
     UNICODE_STRING ObjectName;
+    ANSI_STRING AnsiName;
     POBJECT_HEADER_CREATOR_INFO CreatorInfo;
 
     /* Verify parameters */
@@ -1136,12 +1136,22 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
     }
     else
     {
-        /* Set Tag */
-        Tag[0] = (CHAR)TypeName->Buffer[0];
-        Tag[1] = (CHAR)TypeName->Buffer[1];
-        Tag[2] = (CHAR)TypeName->Buffer[2];
-        Tag[3] = (CHAR)TypeName->Buffer[3];
-        LocalObjectType->Key = *(PULONG)Tag;
+        /* Convert the tag to ASCII */
+        Status = RtlUnicodeStringToAnsiString(&AnsiName, TypeName, TRUE);
+        if (NT_SUCCESS(Status))
+        {
+            /* For every missing character, use a space */
+            for (i = 3; i >= AnsiName.Length; i--) AnsiName.Buffer[i] = ' ';
+
+            /* Set the key and free the converted name */
+            LocalObjectType->Key = *(PULONG)AnsiName.Buffer;
+            RtlFreeAnsiString(&AnsiName);
+        }
+        else
+        {
+            /* Just copy the characters */
+            LocalObjectType->Key = *(PULONG)TypeName->Buffer;
+        }
     }
 
     /* Set up the type information */
@@ -1217,15 +1227,25 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
     InitializeListHead(&LocalObjectType->TypeList);
 
     /* Lock the object type */
-    ObpEnterObjectTypeMutex(LocalObjectType);
+    ObpEnterObjectTypeMutex(ObpTypeObjectType);
 
     /* Get creator info and insert it into the type list */
     CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(Header);
-    if (CreatorInfo) InsertTailList(&ObpTypeObjectType->TypeList,
-                                    &CreatorInfo->TypeList);
+    if (CreatorInfo)
+    {
+        InsertTailList(&ObpTypeObjectType->TypeList,
+                       &CreatorInfo->TypeList);
+
+        /* CORE-8423: Avoid inserting this a second time if someone creates a
+         * handle to the object type (bug in Windows 2003) */
+        Header->Flags &= ~OB_FLAG_CREATE_INFO;
+    }
 
     /* Set the index and the entry into the object type array */
     LocalObjectType->Index = ObpTypeObjectType->TotalNumberOfObjects;
+
+    NT_ASSERT(LocalObjectType->Index != 0);
+
     if (LocalObjectType->Index < 32)
     {
         /* It fits, insert it */
@@ -1233,7 +1253,7 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
     }
 
     /* Release the object type */
-    ObpLeaveObjectTypeMutex(LocalObjectType);
+    ObpLeaveObjectTypeMutex(ObpTypeObjectType);
 
     /* Check if we're actually creating the directory object itself */
     if (!(ObpTypeDirectoryObject) ||
@@ -1259,6 +1279,24 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
     return STATUS_INSUFFICIENT_RESOURCES;
 }
 
+VOID
+NTAPI
+ObDeleteCapturedInsertInfo(IN PVOID Object)
+{
+    POBJECT_HEADER ObjectHeader;
+    PAGED_CODE();
+
+    /* Check if there is anything to free */
+    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
+    if ((ObjectHeader->Flags & OB_FLAG_CREATE_INFO) &&
+        (ObjectHeader->ObjectCreateInfo != NULL))
+    {
+        /* Free the create info */
+        ObpFreeObjectCreateInformation(ObjectHeader->ObjectCreateInfo);
+        ObjectHeader->ObjectCreateInfo = NULL;
+    }
+}
+
 VOID
 NTAPI
 ObpDeleteObjectType(IN PVOID Object)
@@ -1419,7 +1457,7 @@ NtQueryObject(IN HANDLE ObjectHandle,
     POBJECT_HEADER ObjectHeader = NULL;
     POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags;
     POBJECT_BASIC_INFORMATION BasicInfo;
-    ULONG InfoLength;
+    ULONG InfoLength = 0;
     PVOID Object = NULL;
     NTSTATUS Status;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
@@ -1605,7 +1643,7 @@ NtQueryObject(IN HANDLE ObjectHandle,
     _SEH2_END;
 
     /* Dereference the object if we had referenced it */
-    if (Object) ObDereferenceObject (Object);
+    if (Object) ObDereferenceObject(Object);
 
     /* Return status */
     return Status;
@@ -1645,91 +1683,128 @@ NtSetInformationObject(IN HANDLE ObjectHandle,
     OBP_SET_HANDLE_ATTRIBUTES_CONTEXT Context;
     PVOID ObjectTable;
     KAPC_STATE ApcState;
+    POBJECT_DIRECTORY Directory;
+    KPROCESSOR_MODE PreviousMode;
     BOOLEAN AttachedToProcess = FALSE;
     PAGED_CODE();
 
     /* Validate the information class */
-    if (ObjectInformationClass != ObjectHandleFlagInformation)
+    switch (ObjectInformationClass)
     {
-        /* Invalid class */
-        return STATUS_INVALID_INFO_CLASS;
-    }
+        case ObjectHandleFlagInformation:
 
-    /* Validate the length */
-    if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION))
-    {
-        /* Invalid length */
-        return STATUS_INFO_LENGTH_MISMATCH;
-    }
+            /* Validate the length */
+            if (Length != sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION))
+            {
+                /* Invalid length */
+                return STATUS_INFO_LENGTH_MISMATCH;
+            }
 
-    /* Save the previous mode */
-    Context.PreviousMode = ExGetPreviousMode();
+            /* Save the previous mode */
+            Context.PreviousMode = ExGetPreviousMode();
 
-    /* Check if we were called from user mode */
-    if (Context.PreviousMode != KernelMode)
-    {
-        /* Enter SEH */
-        _SEH2_TRY
-        {
-            /* Probe and capture the attribute buffer */
-            ProbeForRead(ObjectInformation,
-                         sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION),
-                         sizeof(BOOLEAN));
-            Context.Information = *(POBJECT_HANDLE_ATTRIBUTE_INFORMATION)
-                                    ObjectInformation;
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            /* Return the exception code */
-            _SEH2_YIELD(return _SEH2_GetExceptionCode());
-        }
-        _SEH2_END;
-    }
-    else
-    {
-        /* Just copy the buffer directly */
-        Context.Information = *(POBJECT_HANDLE_ATTRIBUTE_INFORMATION)
-                                ObjectInformation;
-    }
+            /* Check if we were called from user mode */
+            if (Context.PreviousMode != KernelMode)
+            {
+                /* Enter SEH */
+                _SEH2_TRY
+                {
+                    /* Probe and capture the attribute buffer */
+                    ProbeForRead(ObjectInformation,
+                                 sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION),
+                                 sizeof(BOOLEAN));
+                    Context.Information = *(POBJECT_HANDLE_ATTRIBUTE_INFORMATION)
+                                            ObjectInformation;
+                }
+                _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+                {
+                    /* Return the exception code */
+                    _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                }
+                _SEH2_END;
+            }
+            else
+            {
+                /* Just copy the buffer directly */
+                Context.Information = *(POBJECT_HANDLE_ATTRIBUTE_INFORMATION)
+                                        ObjectInformation;
+            }
 
-    /* Check if this is a kernel handle */
-    if (ObIsKernelHandle(ObjectHandle, Context.PreviousMode))
-    {
-        /* Get the actual handle */
-        ObjectHandle = ObKernelHandleToHandle(ObjectHandle);
-        ObjectTable = ObpKernelHandleTable;
+            /* Check if this is a kernel handle */
+            if (ObpIsKernelHandle(ObjectHandle, Context.PreviousMode))
+            {
+                /* Get the actual handle */
+                ObjectHandle = ObKernelHandleToHandle(ObjectHandle);
+                ObjectTable = ObpKernelHandleTable;
 
-        /* Check if we're not in the system process */
-        if (PsGetCurrentProcess() != PsInitialSystemProcess)
-        {
-            /* Attach to it */
-            KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState);
-            AttachedToProcess = TRUE;
-        }
-    }
-    else
-    {
-        /* Use the current table */
-        ObjectTable = PsGetCurrentProcess()->ObjectTable;
-    }
+                /* Check if we're not in the system process */
+                if (PsGetCurrentProcess() != PsInitialSystemProcess)
+                {
+                    /* Attach to it */
+                    KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState);
+                    AttachedToProcess = TRUE;
+                }
+            }
+            else
+            {
+                /* Use the current table */
+                ObjectTable = PsGetCurrentProcess()->ObjectTable;
+            }
 
-    /* Change the handle attributes */
-    if (!ExChangeHandle(ObjectTable,
-                        ObjectHandle,
-                        ObpSetHandleAttributes,
-                        (ULONG_PTR)&Context))
-    {
-        /* Some failure */
-        Status = STATUS_ACCESS_DENIED;
-    }
-    else
-    {
-        /* We are done */
-        Status = STATUS_SUCCESS;
+            /* Change the handle attributes */
+            if (!ExChangeHandle(ObjectTable,
+                                ObjectHandle,
+                                ObpSetHandleAttributes,
+                                (ULONG_PTR)&Context))
+            {
+                /* Some failure */
+                Status = STATUS_ACCESS_DENIED;
+            }
+            else
+            {
+                /* We are done */
+                Status = STATUS_SUCCESS;
+            }
+
+            /* De-attach if we were attached, and return status */
+            if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
+            break;
+
+        case ObjectSessionInformation:
+
+            /* Only a system process can do this */
+            PreviousMode = ExGetPreviousMode();
+            if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
+            {
+                /* Fail */
+                DPRINT1("Privilege not held\n");
+                Status = STATUS_PRIVILEGE_NOT_HELD;
+            }
+            else
+            {
+                /* Get the object directory */
+                Status = ObReferenceObjectByHandle(ObjectHandle,
+                                                   0,
+                                                   ObDirectoryType,
+                                                   PreviousMode,
+                                                   (PVOID*)&Directory,
+                                                   NULL);
+                if (NT_SUCCESS(Status))
+                {
+                    /* FIXME: Missng locks */
+                    /* Set its session ID */
+                    Directory->SessionId = PsGetCurrentProcessSessionId();
+                    ObDereferenceObject(Directory);
+                }
+            }
+            break;
+
+        default:
+            /* Unsupported class */
+            Status = STATUS_INVALID_INFO_CLASS;
+            break;
     }
 
-    /* De-attach if we were attached, and return status */
-    if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
     return Status;
 }