diff --git a/reactos/ntoskrnl/cm/regobj.c b/reactos/ntoskrnl/cm/regobj.c index e72faabefa6..06c36c2043f 100644 --- a/reactos/ntoskrnl/cm/regobj.c +++ b/reactos/ntoskrnl/cm/regobj.c @@ -27,6 +27,121 @@ CmiGetLinkTarget(PEREGISTRY_HIVE RegistryHive, 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 @@ CmFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo, 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) diff --git a/reactos/ntoskrnl/include/internal/ob_x.h b/reactos/ntoskrnl/include/internal/ob_x.h index c768d3e373b..bd566678390 100644 --- a/reactos/ntoskrnl/include/internal/ob_x.h +++ b/reactos/ntoskrnl/include/internal/ob_x.h @@ -15,48 +15,58 @@ #define OBP_LOCK_STATE_RELEASED 0xEEEE1234 #define OBP_LOCK_STATE_INITIALIZED 0xFFFF1234 -ULONG +POBJECT_HEADER_NAME_INFO FORCEINLINE -ObpIncrementQueryReference(IN POBJECT_HEADER ObjectHeader, - IN POBJECT_HEADER_NAME_INFO ObjectNameInfo) +ObpAcquireNameInformation(IN POBJECT_HEADER ObjectHeader) { + POBJECT_HEADER_NAME_INFO ObjectNameInfo; ULONG NewValue, References; - /* Get the number of references */ - NewValue = ObjectNameInfo->QueryReferences; - while ((NewValue != 0) && (References = NewValue)) - { - /* 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); - } + /* Make sure we have name information at all */ + ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader); + if (!ObjectNameInfo) return NULL; - /* Done looping */ - NewValue = ObjectNameInfo->QueryReferences; - break; - } + /* Get the number of references */ + References = ObjectNameInfo->QueryReferences; + for (;;) + { + /* Check if the count is 0 and fail if so */ + if (!References) return NULL; + + /* Increment the number of references */ + NewValue = InterlockedCompareExchange((PLONG)&ObjectNameInfo-> + QueryReferences, + References + 1, + References); + if (NewValue == References) break; + + /* We failed, try again */ + References = NewValue; } - /* Return the number of references */ - return 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 -ObpDecrementQueryReference(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo) +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 @@ ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context) 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 @@ ObpCleanupDirectoryLookup(IN POBP_LOOKUP_CONTEXT Context) { /* Release the lock */ ObpReleaseDirectoryLock(Context->Directory, Context); + Context->Directory = NULL; + Context->DirectoryLocked = FALSE; } /* Clear the context */ - Context->Directory = NULL; - Context->DirectoryLocked = FALSE; ObpReleaseLookupContextObject(Context); } diff --git a/reactos/ntoskrnl/ob/obdir.c b/reactos/ntoskrnl/ob/obdir.c index 5ec63bcaf08..882a439a62c 100644 --- a/reactos/ntoskrnl/ob/obdir.c +++ b/reactos/ntoskrnl/ob/obdir.c @@ -220,45 +220,24 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, /* 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; - - /* 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); - } - - /* Reference the object being looked up */ - ObReferenceObject(FoundObject); - - /* Check if the directory was locked */ - if (!Context->DirectoryLocked) - { - /* Release the lock */ - ObpReleaseDirectoryLock(Directory, Context); - } + goto Quickie; } else { @@ -278,11 +257,34 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, } Quickie: + /* Check if we inserted an object */ + if (FoundObject) + { + /* Get the object name information */ + ObjectHeader = OBJECT_TO_OBJECT_HEADER(FoundObject); + ObpAcquireNameInformation(ObjectHeader); + + /* Reference the object being looked up */ + ObReferenceObject(FoundObject); + + /* Check if the directory was locked */ + if (!Context->DirectoryLocked) + { + /* Release the lock */ + ObpReleaseDirectoryLock(Directory, Context); + } + } + /* 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 @@ ObpDeleteEntryDirectory(POBP_LOOKUP_CONTEXT Context) *--*/ 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 @@ NtOpenDirectoryObject (OUT PHANDLE DirectoryHandle, Status = _SEH_GetExceptionCode(); } _SEH_END; - - /* If we failed, return the error */ if(!NT_SUCCESS(Status)) return Status; } @@ -389,13 +389,13 @@ NtOpenDirectoryObject (OUT PHANDLE DirectoryHandle, 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 @@ NtQueryDirectoryObject(IN HANDLE DirectoryHandle, 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 @@ NtQueryDirectoryObject(IN HANDLE DirectoryHandle, 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 @@ NtQueryDirectoryObject(IN HANDLE DirectoryHandle, Status = _SEH_GetExceptionCode(); } _SEH_END; - - /* Return the exception to caller if we failed */ if(!NT_SUCCESS(Status)) return Status; } else if (!RestartScan) @@ -531,6 +533,9 @@ NtQueryDirectoryObject(IN HANDLE DirectoryHandle, return Status; } + /* Lock directory in shared mode */ + ObpAcquireDirectoryLockShared(Directory, &LookupContext); + /* Start at position 0 */ DirectoryInfo = (POBJECT_DIRECTORY_INFORMATION)LocalBuffer; TotalLength = sizeof(OBJECT_DIRECTORY_INFORMATION); @@ -691,6 +696,9 @@ Quickie: } _SEH_END; + /* Unlock the directory */ + ObpReleaseDirectoryLock(Directory, &LookupContext); + /* Dereference the directory and free our buffer */ ObDereferenceObject(Directory); ExFreePool(LocalBuffer); @@ -726,7 +734,7 @@ NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, 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 @@ NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, Status = _SEH_GetExceptionCode(); } _SEH_END; - - /* If we failed, return the error */ if(!NT_SUCCESS(Status)) return Status; } @@ -760,30 +766,33 @@ NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, 0, 0, (PVOID*)&Directory); - if(NT_SUCCESS(Status)) + 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 { - /* 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; - } + /* 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; diff --git a/reactos/ntoskrnl/ob/obhandle.c b/reactos/ntoskrnl/ob/obhandle.c index a5e74317500..fc980051f3f 100644 --- a/reactos/ntoskrnl/ob/obhandle.c +++ b/reactos/ntoskrnl/ob/obhandle.c @@ -2693,7 +2693,6 @@ ObInsertObject(IN PVOID Object, { /* 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 @@ ObInsertObject(IN PVOID Object, /* 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 @@ ObInsertObject(IN PVOID Object, { /* Assume failure */ *Handle = NULL; + ObjectHeader->ObjectCreateInfo = NULL; /* Create the handle */ Status = ObpCreateUnnamedHandle(Object, @@ -2750,10 +2739,9 @@ ObInsertObject(IN PVOID Object, /* 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 @@ ObInsertObject(IN PVOID Object, if (!NT_SUCCESS(Status)) { /* Fail */ - if (ObjectNameInfo) ObpDecrementQueryReference(ObjectNameInfo); + ObpReleaseNameInformation(ObjectNameInfo); ObDereferenceObject(Object); return Status; } @@ -2793,7 +2781,7 @@ ObInsertObject(IN PVOID Object, if (!NT_SUCCESS(Status)) { /* Fail */ - if (ObjectNameInfo) ObpDecrementQueryReference(ObjectNameInfo); + ObpReleaseNameInformation(ObjectNameInfo); ObDereferenceObject(Object); return Status; } @@ -2855,7 +2843,7 @@ ObInsertObject(IN PVOID Object, 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 @@ ObInsertObject(IN PVOID Object, /* 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 @@ ObInsertObject(IN PVOID Object, } /* Remove a query reference */ - if (ObjectNameInfo) ObpDecrementQueryReference(ObjectNameInfo); + ObpReleaseNameInformation(ObjectNameInfo); /* Remove the extra keep-alive reference */ ObDereferenceObject(Object); @@ -3078,7 +3074,8 @@ NtDuplicateObject(IN HANDLE SourceProcessHandle, 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 @@ NtDuplicateObject(IN HANDLE SourceProcessHandle, Status = _SEH_GetExceptionCode(); } _SEH_END; - - /* Fail if the pointer was invalid */ if (!NT_SUCCESS(Status)) return Status; } @@ -3168,7 +3163,7 @@ NtDuplicateObject(IN HANDLE SourceProcessHandle, hTarget, TargetProcessHandle, Status); - ObDereferenceObject(Target); + if (Target) ObDereferenceObject(Target); ObDereferenceObject(SourceProcess); return Status; } diff --git a/reactos/ntoskrnl/ob/obname.c b/reactos/ntoskrnl/ob/obname.c index afa422a346f..345b6df21d0 100644 --- a/reactos/ntoskrnl/ob/obname.c +++ b/reactos/ntoskrnl/ob/obname.c @@ -170,20 +170,9 @@ ObpDeleteNameCheck(IN PVOID Object) /* 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, * and if the object isn't a permanent object. @@ -225,21 +214,14 @@ ObpDeleteNameCheck(IN PVOID Object) ObpDeleteSymbolicLinkName(Object); } - /* Add a query reference */ - 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 */ + ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader); if ((ObjectNameInfo) && (ObjectNameInfo->QueryReferences & 0x40000000)) { - /* Add deletion flag */ + /* Remove protection flag */ InterlockedExchangeAdd((PLONG)&ObjectNameInfo->QueryReferences, - 0xC0000000); + -0x40000000); } /* Get the directory */ @@ -254,13 +236,13 @@ ObpDeleteNameCheck(IN PVOID Object) 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 @@ ObpDeleteNameCheck(IN PVOID Object) else { /* Remove the reference we added */ - if (ObjectNameInfo) ObpDecrementQueryReference(ObjectNameInfo); + ObpReleaseNameInformation(ObjectNameInfo); } } @@ -313,11 +295,15 @@ ObpLookupObjectName(IN HANDLE RootHandle, Status = STATUS_SUCCESS; Object = NULL; - /* Check if case-insensitivity is forced */ - if ((ObpCaseInsensitive) || (ObjectType->TypeInfo.CaseInsensitive)) + /* Check if case-insensitivity is checked */ + if (ObpCaseInsensitive) { - /* Add the flag to disable case sensitivity */ - Attributes |= OBJ_CASE_INSENSITIVE; + /* 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 */