[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.

svn path=/trunk/; revision=25469
This commit is contained in:
Alex Ionescu 2007-01-15 20:24:40 +00:00
parent 4e9c7cf7e4
commit d591f751c7
5 changed files with 277 additions and 161 deletions

View file

@ -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)

View file

@ -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);
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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 */