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=25... ============================================================================== --- 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/o... ============================================================================== --- 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=254... ============================================================================== --- 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=... ============================================================================== --- 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=25... ============================================================================== --- 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 */