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=2…
==============================================================================
--- 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/…
==============================================================================
--- 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=25…
==============================================================================
--- 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=2…
==============================================================================
--- 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 */