[ros-diffs] [ion] 25469: [12 bug fixes]: - Isolate FuckedUpCm version of ObpLookupDirectoryObject into CmpLookupDirectoryObject to avoid name info leak. - Rename ObpIncrementQueryReference to ObpAcquireNameInformation and ObpDecrementQueryReference to ObpReleaseNameInformation and make some changes to make calling a lot easier. - Fixup reference increment loop in above function. - Fix incorrect check for defer delete flag instead of query references flag. - Only clear the directory/directory lock flag in ObpCleanupDirectoryLookup if the directory was actually locked. - Fix lock logic in ObpLookupDirectoryEntry. - Properly handle the case when lookup occurs after an existing object, avoid name information leak and reference leak. - Hold shared lock inside NtQuerydirectoryObject. - Properly initiailize the directory object in NtCreateDirectoryObject. - Clear create info before creating the unnamed handle in ObInsertObject. - Only dereference the target process if we actually have one in NtDuplicateObject. - Don't double-reference the name information in ObpDeleteNameCheck, thus avoiding another leak. - Fix object case sensitivity check in ObpLookupObjectName.

ion at svn.reactos.org ion at svn.reactos.org
Mon Jan 15 21:24:41 CET 2007


Author: ion
Date: Mon Jan 15 23:24:40 2007
New Revision: 25469

URL: http://svn.reactos.org/svn/reactos?rev=25469&view=rev
Log:
[12 bug fixes]:
- Isolate FuckedUpCm version of ObpLookupDirectoryObject into CmpLookupDirectoryObject to avoid name info leak.
- Rename ObpIncrementQueryReference to ObpAcquireNameInformation and ObpDecrementQueryReference to ObpReleaseNameInformation and make some changes to make calling a lot easier.
- Fixup reference increment loop in above function.
- Fix incorrect check for defer delete flag instead of query references flag.
- Only clear the directory/directory lock flag in ObpCleanupDirectoryLookup if the directory was actually locked.
- Fix lock logic in ObpLookupDirectoryEntry.
- Properly handle the case when lookup occurs after an existing object, avoid name information leak and reference leak.
- Hold shared lock inside NtQuerydirectoryObject.
- Properly initiailize the directory object in NtCreateDirectoryObject.
- Clear create info before creating the unnamed handle in ObInsertObject.
- Only dereference the target process if we actually have one in NtDuplicateObject.
- Don't double-reference the name information in ObpDeleteNameCheck, thus avoiding another leak.
- Fix object case sensitivity check in ObpLookupObjectName.

Modified:
    trunk/reactos/ntoskrnl/cm/regobj.c
    trunk/reactos/ntoskrnl/include/internal/ob_x.h
    trunk/reactos/ntoskrnl/ob/obdir.c
    trunk/reactos/ntoskrnl/ob/obhandle.c
    trunk/reactos/ntoskrnl/ob/obname.c

Modified: trunk/reactos/ntoskrnl/cm/regobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/regobj.c?rev=25469&r1=25468&r2=25469&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/cm/regobj.c (original)
+++ trunk/reactos/ntoskrnl/cm/regobj.c Mon Jan 15 23:24:40 2007
@@ -27,6 +27,121 @@
 		 PUNICODE_STRING TargetPath);
 
 /* FUNCTONS *****************************************************************/
+
+PVOID
+NTAPI
+CmpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory,
+                        IN PUNICODE_STRING Name,
+                        IN ULONG Attributes,
+                        IN UCHAR SearchShadow,
+                        IN POBP_LOOKUP_CONTEXT Context)
+{
+    BOOLEAN CaseInsensitive = FALSE;
+    POBJECT_HEADER_NAME_INFO HeaderNameInfo;
+    ULONG HashValue;
+    ULONG HashIndex;
+    LONG TotalChars;
+    WCHAR CurrentChar;
+    POBJECT_DIRECTORY_ENTRY *AllocatedEntry;
+    POBJECT_DIRECTORY_ENTRY *LookupBucket;
+    POBJECT_DIRECTORY_ENTRY CurrentEntry;
+    PVOID FoundObject = NULL;
+    PWSTR Buffer;
+    PAGED_CODE();
+
+    /* Always disable this until we have DOS Device Maps */
+    SearchShadow = FALSE;
+
+    /* Fail if we don't have a directory or name */
+    if (!(Directory) || !(Name)) goto Quickie;
+
+    /* Get name information */
+    TotalChars = Name->Length / sizeof(WCHAR);
+    Buffer = Name->Buffer;
+
+    /* Fail if the name is empty */
+    if (!(Buffer) || !(TotalChars)) goto Quickie;
+
+    /* Set up case-sensitivity */
+    if (Attributes & OBJ_CASE_INSENSITIVE) CaseInsensitive = TRUE;
+
+    /* Create the Hash */
+    for (HashValue = 0; TotalChars; TotalChars--)
+    {
+        /* Go to the next Character */
+        CurrentChar = *Buffer++;
+
+        /* Prepare the Hash */
+        HashValue += (HashValue << 1) + (HashValue >> 1);
+
+        /* Create the rest based on the name */
+        if (CurrentChar < 'a') HashValue += CurrentChar;
+        else if (CurrentChar > 'z') HashValue += RtlUpcaseUnicodeChar(CurrentChar);
+        else HashValue += (CurrentChar - ('a'-'A'));
+    }
+
+    /* Merge it with our number of hash buckets */
+    HashIndex = HashValue % 37;
+
+    /* Save the result */
+    Context->HashValue = HashValue;
+    Context->HashIndex = (USHORT)HashIndex;
+
+    /* Get the root entry and set it as our lookup bucket */
+    AllocatedEntry = &Directory->HashBuckets[HashIndex];
+    LookupBucket = AllocatedEntry;
+
+    /* Start looping */
+    while ((CurrentEntry = *AllocatedEntry))
+    {
+        /* Do the hashes match? */
+        if (CurrentEntry->HashValue == HashValue)
+        {
+            /* Make sure that it has a name */
+            ASSERT(OBJECT_TO_OBJECT_HEADER(CurrentEntry->Object)->NameInfoOffset != 0);
+
+            /* Get the name information */
+            HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(CurrentEntry->Object));
+
+            /* Do the names match? */
+            if ((Name->Length == HeaderNameInfo->Name.Length) &&
+                (RtlEqualUnicodeString(Name, &HeaderNameInfo->Name, CaseInsensitive)))
+            {
+                break;
+            }
+        }
+
+        /* Move to the next entry */
+        AllocatedEntry = &CurrentEntry->ChainLink;
+    }
+
+    /* Check if we still have an entry */
+    if (CurrentEntry)
+    {
+        /* Set this entry as the first, to speed up incoming insertion */
+        if (AllocatedEntry != LookupBucket)
+        {
+            /* Set the Current Entry */
+            *AllocatedEntry = CurrentEntry->ChainLink;
+
+            /* Link to the old Hash Entry */
+            CurrentEntry->ChainLink = *LookupBucket;
+
+            /* Set the new Hash Entry */
+            *LookupBucket = CurrentEntry;
+        }
+
+        /* Save the found object */
+        FoundObject = CurrentEntry->Object;
+        if (!FoundObject) goto Quickie;
+    }
+
+Quickie:
+    /* Return the object we found */
+    Context->Object = FoundObject;
+    return FoundObject;
+}
+
 NTSTATUS
 NTAPI
 CmFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
@@ -137,9 +252,10 @@
             if (End != NULL) *End = 0;
 
             RtlInitUnicodeString(&StartUs, Start);
+            ObpInitializeDirectoryLookup(&Context);
             Context.DirectoryLocked = TRUE;
             Context.Directory = CurrentObject;
-            FoundObject = ObpLookupEntryDirectory(CurrentObject, &StartUs, Attributes, FALSE, &Context);
+            FoundObject = CmpLookupEntryDirectory(CurrentObject, &StartUs, Attributes, FALSE, &Context);
             if (FoundObject == NULL)
             {
                 if (End != NULL)

Modified: trunk/reactos/ntoskrnl/include/internal/ob_x.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ob_x.h?rev=25469&r1=25468&r2=25469&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ob_x.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ob_x.h Mon Jan 15 23:24:40 2007
@@ -15,48 +15,58 @@
 #define OBP_LOCK_STATE_RELEASED                     0xEEEE1234
 #define OBP_LOCK_STATE_INITIALIZED                  0xFFFF1234
 
-ULONG
-FORCEINLINE
-ObpIncrementQueryReference(IN POBJECT_HEADER ObjectHeader,
-                           IN POBJECT_HEADER_NAME_INFO ObjectNameInfo)
-{
+POBJECT_HEADER_NAME_INFO
+FORCEINLINE
+ObpAcquireNameInformation(IN POBJECT_HEADER ObjectHeader)
+{
+    POBJECT_HEADER_NAME_INFO ObjectNameInfo;
     ULONG NewValue, References;
 
+    /* Make sure we have name information at all */
+    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
+    if (!ObjectNameInfo) return NULL;
+
     /* Get the number of references */
-    NewValue = ObjectNameInfo->QueryReferences;
-    while ((NewValue != 0) && (References = NewValue))
-    {
+    References = ObjectNameInfo->QueryReferences;
+    for (;;)
+    {
+        /* Check if the count is 0 and fail if so */
+        if (!References) return NULL;
+
         /* Increment the number of references */
-        if (InterlockedCompareExchange((PLONG)&ObjectNameInfo->QueryReferences,
-                                       NewValue + 1,
-                                       NewValue) == References)
-        {
-            /* Check if the object is to be deferred deleted */
-            if (ObjectHeader->Flags & OB_FLAG_DEFER_DELETE)
-            {
-                /* FIXME: Unhandled*/
-                DbgPrint("OB: Unhandled path\n");
-                KEBUGCHECK(0);
-            }
-
-            /* Done looping */
-            NewValue = ObjectNameInfo->QueryReferences;
-            break;
-        }
-    }
-
-    /* Return the number of references */
-    return NewValue;
-}
-
-VOID
-FORCEINLINE
-ObpDecrementQueryReference(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo)
+        NewValue = InterlockedCompareExchange((PLONG)&ObjectNameInfo->
+                                              QueryReferences,
+                                              References + 1,
+                                              References);
+        if (NewValue == References) break;
+
+        /* We failed, try again */
+        References = NewValue;
+    }
+
+    /* Check for magic flag */
+    if (ObjectNameInfo->QueryReferences & 0x80000000)
+    {
+        /* FIXME: Unhandled*/
+        DbgPrint("OB: Unhandled path\n");
+        KEBUGCHECK(0);
+    }
+
+    /* Return the name information */
+    return ObjectNameInfo;
+}
+
+VOID
+FORCEINLINE
+ObpReleaseNameInformation(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo)
 {
     POBJECT_DIRECTORY Directory;
 
+    /* Bail out if there's no info at all */
+    if (!HeaderNameInfo) return;
+
     /* Remove a query reference and check if it was the last one */
-    if (!InterlockedExchangeAdd((PLONG)&HeaderNameInfo->QueryReferences, -1))
+    if (!InterlockedDecrement((PLONG)&HeaderNameInfo->QueryReferences))
     {
         /* Check if we have a name */
         if (HeaderNameInfo->Name.Buffer)
@@ -149,8 +159,8 @@
         ObjectHeader = OBJECT_TO_OBJECT_HEADER(Context->Object);
         HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
 
-        /* Check if we do have name information */
-        if (HeaderNameInfo) ObpDecrementQueryReference(HeaderNameInfo);
+        /* release the name information */
+        ObpReleaseNameInformation(HeaderNameInfo);
 
         /* Dereference the object */
         ObDereferenceObject(Context->Object);
@@ -167,11 +177,11 @@
     {
         /* Release the lock */
         ObpReleaseDirectoryLock(Context->Directory, Context);
+        Context->Directory = NULL;
+        Context->DirectoryLocked = FALSE;
     }
 
     /* Clear the context  */
-    Context->Directory = NULL;
-    Context->DirectoryLocked = FALSE;
     ObpReleaseLookupContextObject(Context);
 }
 

Modified: trunk/reactos/ntoskrnl/ob/obdir.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obdir.c?rev=25469&r1=25468&r2=25469&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obdir.c (original)
+++ trunk/reactos/ntoskrnl/ob/obdir.c Mon Jan 15 23:24:40 2007
@@ -220,35 +220,49 @@
         /* Set this entry as the first, to speed up incoming insertion */
         if (AllocatedEntry != LookupBucket)
         {
-            /* Check if the directory was locked */
-            if (!Context->DirectoryLocked)
+            /* Check if the directory was locked or convert the lock */
+            if ((Context->DirectoryLocked) ||
+                (ExConvertPushLockSharedToExclusive(&Directory->Lock)))
             {
-                /* Convert the lock from shared to exclusive */
-                ExConvertPushLockSharedToExclusive(&Directory->Lock);
+                /* Set the Current Entry */
+                *AllocatedEntry = CurrentEntry->ChainLink;
+
+                /* Link to the old Hash Entry */
+                CurrentEntry->ChainLink = *LookupBucket;
+
+                /* Set the new Hash Entry */
+                *LookupBucket = CurrentEntry;
             }
-
-            /* Set the Current Entry */
-            *AllocatedEntry = CurrentEntry->ChainLink;
-
-            /* Link to the old Hash Entry */
-            CurrentEntry->ChainLink = *LookupBucket;
-
-            /* Set the new Hash Entry */
-            *LookupBucket = CurrentEntry;
         }
 
         /* Save the found object */
         FoundObject = CurrentEntry->Object;
-        if (!FoundObject) goto Quickie;
-
+        goto Quickie;
+    }
+    else
+    {
+        /* Check if the directory was locked */
+        if (!Context->DirectoryLocked)
+        {
+            /* Release the lock */
+            ObpReleaseDirectoryLock(Directory, Context);
+        }
+
+        /* Check if we should scan the shadow directory */
+        if ((SearchShadow) && (Directory->DeviceMap))
+        {
+            /* FIXME: We don't support this yet */
+            KEBUGCHECK(0);
+        }
+    }
+
+Quickie:
+    /* Check if we inserted an object */
+    if (FoundObject)
+    {
         /* Get the object name information */
         ObjectHeader = OBJECT_TO_OBJECT_HEADER(FoundObject);
-        HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
-        if (HeaderNameInfo)
-        {
-            /* Add a query reference */
-            ObpIncrementQueryReference(ObjectHeader, HeaderNameInfo);
-        }
+        ObpAcquireNameInformation(ObjectHeader);
 
         /* Reference the object being looked up */
         ObReferenceObject(FoundObject);
@@ -260,29 +274,17 @@
             ObpReleaseDirectoryLock(Directory, Context);
         }
     }
-    else
-    {
-        /* Check if the directory was locked */
-        if (!Context->DirectoryLocked)
-        {
-            /* Release the lock */
-            ObpReleaseDirectoryLock(Directory, Context);
-        }
-
-        /* Check if we should scan the shadow directory */
-        if ((SearchShadow) && (Directory->DeviceMap))
-        {
-            /* FIXME: We don't support this yet */
-            KEBUGCHECK(0);
-        }
-    }
-
-Quickie:
+
     /* Check if we found an object already */
     if (Context->Object)
     {
         /* We already did a lookup, so remove this object's query reference */
-        //ObpDecrementQueryReference(Context->Object);
+        ObjectHeader = OBJECT_TO_OBJECT_HEADER(Context->Object);
+        HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
+        ObpReleaseNameInformation(HeaderNameInfo);
+
+        /* Also dereference the object itself */
+        ObDereferenceObject(Context->Object);
     }
 
     /* Return the object we found */
@@ -354,17 +356,17 @@
 *--*/
 NTSTATUS
 NTAPI
-NtOpenDirectoryObject (OUT PHANDLE DirectoryHandle,
-                       IN ACCESS_MASK DesiredAccess,
-                       IN POBJECT_ATTRIBUTES ObjectAttributes)
+NtOpenDirectoryObject(OUT PHANDLE DirectoryHandle,
+                      IN ACCESS_MASK DesiredAccess,
+                      IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-    HANDLE hDirectory;
+    HANDLE Directory;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
     PAGED_CODE();
 
     /* Check if we need to do any probing */
-    if(PreviousMode != KernelMode)
+    if (PreviousMode != KernelMode)
     {
         _SEH_TRY
         {
@@ -377,8 +379,6 @@
             Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-
-        /* If we failed, return the error */
         if(!NT_SUCCESS(Status)) return Status;
     }
 
@@ -389,13 +389,13 @@
                                 NULL,
                                 DesiredAccess,
                                 NULL,
-                                &hDirectory);
-    if(NT_SUCCESS(Status))
+                                &Directory);
+    if (NT_SUCCESS(Status))
     {
         _SEH_TRY
         {
             /* Write back the handle to the caller */
-            *DirectoryHandle = hDirectory;
+            *DirectoryHandle = Directory;
         }
         _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
         {
@@ -476,10 +476,14 @@
     POBJECT_HEADER_NAME_INFO ObjectNameInfo;
     UNICODE_STRING Name;
     PWSTR p;
+    OBP_LOOKUP_CONTEXT LookupContext;
     PAGED_CODE();
 
+    /* Initialize lookup */
+    ObpInitializeDirectoryLookup(&LookupContext);
+
     /* Check if we need to do any probing */
-    if(PreviousMode != KernelMode)
+    if (PreviousMode != KernelMode)
     {
         _SEH_TRY
         {
@@ -491,7 +495,7 @@
             if (!RestartScan) SkipEntries = *Context;
 
             /* Probe the return length if the caller specified one */
-            if(ReturnLength) ProbeForWriteUlong(ReturnLength);
+            if (ReturnLength) ProbeForWriteUlong(ReturnLength);
         }
         _SEH_HANDLE
         {
@@ -499,8 +503,6 @@
             Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-
-        /* Return the exception to caller if we failed */
         if(!NT_SUCCESS(Status)) return Status;
     }
     else if (!RestartScan)
@@ -530,6 +532,9 @@
         ExFreePool(LocalBuffer);
         return Status;
     }
+
+    /* Lock directory in shared mode */
+    ObpAcquireDirectoryLockShared(Directory, &LookupContext);
 
     /* Start at position 0 */
     DirectoryInfo = (POBJECT_DIRECTORY_INFORMATION)LocalBuffer;
@@ -691,6 +696,9 @@
     }
     _SEH_END;
 
+    /* Unlock the directory */
+    ObpReleaseDirectoryLock(Directory, &LookupContext);
+
     /* Dereference the directory and free our buffer */
     ObDereferenceObject(Directory);
     ExFreePool(LocalBuffer);
@@ -726,7 +734,7 @@
                         IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
     POBJECT_DIRECTORY Directory;
-    HANDLE hDirectory;
+    HANDLE NewHandle;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
     PAGED_CODE();
@@ -745,8 +753,6 @@
             Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-
-        /* If we failed, return the error */
         if(!NT_SUCCESS(Status)) return Status;
     }
 
@@ -760,30 +766,33 @@
                             0,
                             0,
                             (PVOID*)&Directory);
-    if(NT_SUCCESS(Status))
-    {
-        /* Insert it into the handle table */
-        Status = ObInsertObject((PVOID)Directory,
-                                NULL,
-                                DesiredAccess,
-                                0,
-                                NULL,
-                                &hDirectory);
-        if(NT_SUCCESS(Status))
-        {
-            _SEH_TRY
-            {
-                /* Return the handle back to the caller */
-                *DirectoryHandle = hDirectory;
-            }
-            _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
-            {
-                /* Get the exception code */
-                Status = _SEH_GetExceptionCode();
-            }
-            _SEH_END;
-        }
-    }
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Setup the object */
+    RtlZeroMemory(Directory, sizeof(OBJECT_DIRECTORY));
+    ExInitializePushLock((PULONG_PTR)&Directory->Lock);
+    Directory->SessionId = -1;
+
+    /* Insert it into the handle table */
+    Status = ObInsertObject((PVOID)Directory,
+                            NULL,
+                            DesiredAccess,
+                            0,
+                            NULL,
+                            &NewHandle);
+
+    /* Enter SEH to protect write */
+    _SEH_TRY
+    {
+        /* Return the handle back to the caller */
+        *DirectoryHandle = NewHandle;
+    }
+    _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+    {
+        /* Get the exception code */
+        Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
 
     /* Return status to caller */
     return Status;

Modified: trunk/reactos/ntoskrnl/ob/obhandle.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obhandle.c?rev=25469&r1=25468&r2=25469&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obhandle.c (original)
+++ trunk/reactos/ntoskrnl/ob/obhandle.c Mon Jan 15 23:24:40 2007
@@ -2693,7 +2693,6 @@
     {
         /* Display warning and break into debugger */
         DPRINT1("OB: Attempting to insert existing object %08x\n", Object);
-        KEBUGCHECK(0);
         DbgBreakPoint();
 
         /* Allow debugger to continue */
@@ -2703,22 +2702,11 @@
 
     /* Get the create and name info, as well as the object type */
     ObjectCreateInfo = ObjectHeader->ObjectCreateInfo;
-    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
+    ObjectNameInfo = ObpAcquireNameInformation(ObjectHeader);
     ObjectType = ObjectHeader->Type;
-
-    /* Check if we have name information */
-    if (ObjectNameInfo)
-    {
-        /* Add a query reference */
-        if (!ObpIncrementQueryReference(ObjectHeader, ObjectNameInfo))
-        {
-            /* There are no query references, so the name info is invalid */
-            ObjectNameInfo = NULL;
-        }
-    }
+    ObjectName = NULL;
 
     /* Check if this is an named object */
-    ObjectName = NULL;
     if ((ObjectNameInfo) && (ObjectNameInfo->Name.Buffer))
     {
         /* Get the object name */
@@ -2738,6 +2726,7 @@
     {
         /* Assume failure */
         *Handle = NULL;
+        ObjectHeader->ObjectCreateInfo = NULL;
 
         /* Create the handle */
         Status = ObpCreateUnnamedHandle(Object,
@@ -2750,10 +2739,9 @@
 
         /* Free the create information */
         ObpFreeAndReleaseCapturedAttributes(ObjectCreateInfo);
-        ObjectHeader->ObjectCreateInfo = NULL;
-
-        /* Remove a query reference if we added one */
-        if (ObjectNameInfo) ObpDecrementQueryReference(ObjectNameInfo);
+
+        /* Release the object name information */
+        ObpReleaseNameInformation(ObjectNameInfo);
 
         /* Remove the extra keep-alive reference */
         ObDereferenceObject(Object);
@@ -2779,7 +2767,7 @@
         if (!NT_SUCCESS(Status))
         {
             /* Fail */
-            if (ObjectNameInfo) ObpDecrementQueryReference(ObjectNameInfo);
+            ObpReleaseNameInformation(ObjectNameInfo);
             ObDereferenceObject(Object);
             return Status;
         }
@@ -2793,7 +2781,7 @@
     if (!NT_SUCCESS(Status))
     {
         /* Fail */
-        if (ObjectNameInfo) ObpDecrementQueryReference(ObjectNameInfo);
+        ObpReleaseNameInformation(ObjectNameInfo);
         ObDereferenceObject(Object);
         return Status;
     }
@@ -2855,7 +2843,7 @@
             ObpCleanupDirectoryLookup(&Context);
 
             /* Remove query reference that we added */
-            if (ObjectNameInfo) ObpDecrementQueryReference(ObjectNameInfo);
+            ObpReleaseNameInformation(ObjectNameInfo);
 
             /* Dereference the object and delete the access state */
             ObDereferenceObject(Object);
@@ -2922,11 +2910,19 @@
         /* Check if anything until now failed */
         if (!NT_SUCCESS(Status))
         {
-            /* Cleanup lookup context */
+            /* Check if the directory was added */
+            if (Context.DirectoryLocked)
+            {
+                /* Weird case where we need to do a manual delete */
+                DPRINT1("Unhandled path\n");
+                KEBUGCHECK(0);
+            }
+
+            /* Cleanup the lookup */
             ObpCleanupDirectoryLookup(&Context);
 
             /* Remove query reference that we added */
-            if (ObjectNameInfo) ObpDecrementQueryReference(ObjectNameInfo);
+            ObpReleaseNameInformation(ObjectNameInfo);
 
             /* Dereference the object and delete the access state */
             ObDereferenceObject(Object);
@@ -2971,7 +2967,7 @@
         }
 
         /* Remove a query reference */
-        if (ObjectNameInfo) ObpDecrementQueryReference(ObjectNameInfo);
+        ObpReleaseNameInformation(ObjectNameInfo);
 
         /* Remove the extra keep-alive reference */
         ObDereferenceObject(Object);
@@ -3078,7 +3074,8 @@
             SourceProcessHandle,
             TargetProcessHandle);
 
-    if((TargetHandle) && (PreviousMode != KernelMode))
+    /* Check if we have a target handle */
+    if ((TargetHandle) && (PreviousMode != KernelMode))
     {
         /* Enter SEH */
         _SEH_TRY
@@ -3092,8 +3089,6 @@
             Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-
-        /* Fail if the pointer was invalid */
         if (!NT_SUCCESS(Status)) return Status;
     }
 
@@ -3168,7 +3163,7 @@
             hTarget,
             TargetProcessHandle,
             Status);
-    ObDereferenceObject(Target);
+    if (Target) ObDereferenceObject(Target);
     ObDereferenceObject(SourceProcess);
     return Status;
 }

Modified: trunk/reactos/ntoskrnl/ob/obname.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obname.c?rev=25469&r1=25468&r2=25469&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obname.c (original)
+++ trunk/reactos/ntoskrnl/ob/obname.c Mon Jan 15 23:24:40 2007
@@ -170,19 +170,8 @@
 
     /* Get object structures */
     ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
-    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
+    ObjectNameInfo = ObpAcquireNameInformation(ObjectHeader);
     ObjectType = ObjectHeader->Type;
-
-    /* Check if we have a name information structure */
-    if (ObjectNameInfo)
-    {
-        /* Add a query reference */
-        if (!ObpIncrementQueryReference(ObjectHeader, ObjectNameInfo))
-        {
-            /* No references, so the name info is invalid */
-            ObjectNameInfo = NULL;
-        }
-    }
 
     /*
      * Check if the handle count is 0, if the object is named,
@@ -225,21 +214,14 @@
                     ObpDeleteSymbolicLinkName(Object);
                 }
 
-                /* Add a query reference */
+                /* Check if the magic protection flag is set */
                 ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
-                if (!ObpIncrementQueryReference(ObjectHeader, ObjectNameInfo))
-                {
-                    /* No references, so the name info is invalid */
-                    ObjectNameInfo = NULL;
-                }
-
-                /* Check if the magic protection flag is set */
                 if ((ObjectNameInfo) &&
                     (ObjectNameInfo->QueryReferences & 0x40000000))
                 {
-                    /* Add deletion flag */
+                    /* Remove protection flag */
                     InterlockedExchangeAdd((PLONG)&ObjectNameInfo->QueryReferences,
-                                           0xC0000000);
+                                           -0x40000000);
                 }
 
                 /* Get the directory */
@@ -254,13 +236,13 @@
         ObpCleanupDirectoryLookup(&Context);
 
         /* Remove another query reference since we added one on top */
-        ObpDecrementQueryReference(ObjectNameInfo);
+        ObpReleaseNameInformation(ObjectNameInfo);
 
         /* Check if we were inserted in a directory */
         if (Directory)
         {
             /* We were, so first remove the extra reference we had added */
-            ObpDecrementQueryReference(ObjectNameInfo);
+            ObpReleaseNameInformation(ObjectNameInfo);
 
             /* Now dereference the object as well */
             ObDereferenceObject(Object);
@@ -269,7 +251,7 @@
     else
     {
         /* Remove the reference we added */
-        if (ObjectNameInfo) ObpDecrementQueryReference(ObjectNameInfo);
+        ObpReleaseNameInformation(ObjectNameInfo);
     }
 }
 
@@ -313,11 +295,15 @@
     Status = STATUS_SUCCESS;
     Object = NULL;
 
-    /* Check if case-insensitivity is forced */
-    if ((ObpCaseInsensitive) || (ObjectType->TypeInfo.CaseInsensitive))
-    {
-        /* Add the flag to disable case sensitivity */
-        Attributes |= OBJ_CASE_INSENSITIVE;
+    /* Check if case-insensitivity is checked */
+    if (ObpCaseInsensitive)
+    {
+        /* Check if the object type requests this */
+        if (!(ObjectType) || (ObjectType->TypeInfo.CaseInsensitive))
+        {
+            /* Add the flag to disable case sensitivity */
+            Attributes |= OBJ_CASE_INSENSITIVE;
+        }
     }
 
     /* Check if this is a access checks are being forced */




More information about the Ros-diffs mailing list