diff --git a/reactos/ntoskrnl/include/internal/ob_x.h b/reactos/ntoskrnl/include/internal/ob_x.h index 40ac7d2c597..b12e58dd1d1 100644 --- a/reactos/ntoskrnl/include/internal/ob_x.h +++ b/reactos/ntoskrnl/include/internal/ob_x.h @@ -15,6 +15,68 @@ #define OBP_LOCK_STATE_RELEASED 0xEEEE1234 #define OBP_LOCK_STATE_INITIALIZED 0xFFFF1234 +ULONG +FORCEINLINE +ObpSelectObjectLockSlot(IN POBJECT_HEADER ObjectHeader) +{ + /* We have 4 locks total, this will return a 0-index slot */ + return (((ULONG_PTR)ObjectHeader) >> 8) & 3; +} + +VOID +FORCEINLINE +ObpAcquireObjectLock(IN POBJECT_HEADER ObjectHeader) +{ + ULONG Slot; + POBJECT_TYPE ObjectType = ObjectHeader->Type; + + /* Sanity check */ + ASSERT(KeGetCurrentIrql() <= APC_LEVEL); + + /* Pick a slot */ + Slot = ObpSelectObjectLockSlot(ObjectHeader); + + /* Enter a critical region and acquire the resource */ + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&ObjectType->ObjectLocks[Slot], TRUE); +} + +VOID +FORCEINLINE +ObpAcquireObjectLockShared(IN POBJECT_HEADER ObjectHeader) +{ + ULONG Slot; + POBJECT_TYPE ObjectType = ObjectHeader->Type; + + /* Sanity check */ + ASSERT(KeGetCurrentIrql() <= APC_LEVEL); + + /* Pick a slot */ + Slot = ObpSelectObjectLockSlot(ObjectHeader); + + /* Enter a critical region and acquire the resource */ + KeEnterCriticalRegion(); + ExAcquireResourceSharedLite(&ObjectType->ObjectLocks[Slot], TRUE); +} + +VOID +FORCEINLINE +ObpReleaseObjectLock(IN POBJECT_HEADER ObjectHeader) +{ + ULONG Slot; + POBJECT_TYPE ObjectType = ObjectHeader->Type; + + /* Pick a slot */ + Slot = ObpSelectObjectLockSlot(ObjectHeader); + + /* Enter a critical region and acquire the resource */ + ExReleaseResourceLite(&ObjectType->ObjectLocks[Slot]); + KeLeaveCriticalRegion(); + + /* Sanity check */ + ASSERT(KeGetCurrentIrql() <= APC_LEVEL); +} + POBJECT_HEADER_NAME_INFO FORCEINLINE ObpAcquireNameInformation(IN POBJECT_HEADER ObjectHeader) diff --git a/reactos/ntoskrnl/ob/obhandle.c b/reactos/ntoskrnl/ob/obhandle.c index bdc2284da7f..ab84bb7b23b 100644 --- a/reactos/ntoskrnl/ob/obhandle.c +++ b/reactos/ntoskrnl/ob/obhandle.c @@ -495,8 +495,8 @@ ObpDecrementHandleCount(IN PVOID ObjectBody, ObjectHeader->HandleCount, ObjectHeader->PointerCount); - /* Lock the object type */ - ObpEnterObjectTypeMutex(ObjectType); + /* Lock the object */ + ObpAcquireObjectLock(ObjectHeader); /* Set default counts */ SystemHandleCount = ObjectHeader->HandleCount; @@ -571,7 +571,7 @@ ObpDecrementHandleCount(IN PVOID ObjectBody, } /* Release the lock */ - ObpLeaveObjectTypeMutex(ObjectType); + ObpReleaseObjectLock(ObjectHeader); /* Check if we have a close procedure */ if (ObjectType->TypeInfo.CloseProcedure) @@ -796,8 +796,8 @@ ObpIncrementHandleCount(IN PVOID Object, ProbeMode = AccessMode; } - /* Lock the object type */ - ObpEnterObjectTypeMutex(ObjectType); + /* Lock the object */ + ObpAcquireObjectLock(ObjectHeader); /* Charge quota and remove the creator info flag */ Status = ObpChargeQuotaForObject(ObjectHeader, ObjectType, &NewObject); @@ -922,7 +922,7 @@ ObpIncrementHandleCount(IN PVOID Object, } /* Release the lock */ - ObpLeaveObjectTypeMutex(ObjectType); + ObpReleaseObjectLock(ObjectHeader); /* Check if we have an open procedure */ Status = STATUS_SUCCESS; @@ -988,7 +988,7 @@ ObpIncrementHandleCount(IN PVOID Object, Quickie: /* Release lock and return */ - ObpLeaveObjectTypeMutex(ObjectType); + ObpReleaseObjectLock(ObjectHeader); return Status; } @@ -1049,7 +1049,7 @@ ObpIncrementUnnamedHandleCount(IN PVOID Object, ObjectHeader->PointerCount); /* Lock the object type */ - ObpEnterObjectTypeMutex(ObjectType); + ObpAcquireObjectLock(ObjectHeader); /* Charge quota and remove the creator info flag */ Status = ObpChargeQuotaForObject(ObjectHeader, ObjectType, &NewObject); @@ -1149,7 +1149,7 @@ ObpIncrementUnnamedHandleCount(IN PVOID Object, } /* Release the lock */ - ObpLeaveObjectTypeMutex(ObjectType); + ObpReleaseObjectLock(ObjectHeader); /* Check if we have an open procedure */ Status = STATUS_SUCCESS; @@ -1207,7 +1207,7 @@ ObpIncrementUnnamedHandleCount(IN PVOID Object, Quickie: /* Release lock and return */ - ObpLeaveObjectTypeMutex(ObjectType); + ObpReleaseObjectLock(ObjectHeader); return Status; } @@ -3093,8 +3093,8 @@ ObInsertObject(IN PVOID Object, } else { - /* Otherwise, lock the object type */ - ObpEnterObjectTypeMutex(ObjectType); + /* Otherwise, lock the object */ + ObpAcquireObjectLock(ObjectHeader); /* And charge quota for the process to make it appear as used */ RealStatus = ObpChargeQuotaForObject(ObjectHeader, @@ -3102,7 +3102,7 @@ ObInsertObject(IN PVOID Object, &IsNewObject); /* Release the lock */ - ObpLeaveObjectTypeMutex(ObjectType); + ObpReleaseObjectLock(ObjectHeader); /* Check if we failed and dereference the object if so */ if (!NT_SUCCESS(RealStatus)) ObDereferenceObject(Object); diff --git a/reactos/ntoskrnl/ob/oblife.c b/reactos/ntoskrnl/ob/oblife.c index 804fc3e03f0..063dbbc827d 100644 --- a/reactos/ntoskrnl/ob/oblife.c +++ b/reactos/ntoskrnl/ob/oblife.c @@ -262,8 +262,8 @@ ObpSetPermanentObject(IN PVOID ObjectBody, /* Get the header */ ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody); - /* Acquire object type lock */ - ObpEnterObjectTypeMutex(ObjectHeader->Type); + /* Acquire object lock */ + ObpAcquireObjectLock(ObjectHeader); /* Check what we're doing to it */ if (Permanent) @@ -272,7 +272,7 @@ ObpSetPermanentObject(IN PVOID ObjectBody, ObjectHeader->Flags |= OB_FLAG_PERMANENT; /* Release the lock */ - ObpLeaveObjectTypeMutex(ObjectHeader->Type); + ObpReleaseObjectLock(ObjectHeader); } else { @@ -280,7 +280,7 @@ ObpSetPermanentObject(IN PVOID ObjectBody, ObjectHeader->Flags &= ~OB_FLAG_PERMANENT; /* Release the lock */ - ObpLeaveObjectTypeMutex(ObjectHeader->Type); + ObpReleaseObjectLock(ObjectHeader); /* Check if we should delete the object now */ ObpDeleteNameCheck(ObjectBody); diff --git a/reactos/ntoskrnl/ob/oblink.c b/reactos/ntoskrnl/ob/oblink.c index 134906d799a..ba6c22bb7f8 100644 --- a/reactos/ntoskrnl/ob/oblink.c +++ b/reactos/ntoskrnl/ob/oblink.c @@ -503,9 +503,8 @@ NtQuerySymbolicLinkObject(IN HANDLE LinkHandle, NULL); if (NT_SUCCESS(Status)) { - /* Lock the object type */ - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite(&ObSymbolicLinkType->Mutex, TRUE); + /* Lock the object */ + ObpAcquireObjectLock(OBJECT_TO_OBJECT_HEADER(SymlinkObject)); /* * So here's the thing: If you specify a return length, then the @@ -549,9 +548,8 @@ NtQuerySymbolicLinkObject(IN HANDLE LinkHandle, } _SEH_END; - /* Unlock the object type and reference the object */ - ExReleaseResourceLite(&ObSymbolicLinkType->Mutex); - KeLeaveCriticalRegion(); + /* Unlock the object and reference the object */ + ObpReleaseObjectLock(OBJECT_TO_OBJECT_HEADER(SymlinkObject)); ObDereferenceObject(SymlinkObject); } diff --git a/reactos/ntoskrnl/ob/obname.c b/reactos/ntoskrnl/ob/obname.c index 32dec0809c0..20276657440 100644 --- a/reactos/ntoskrnl/ob/obname.c +++ b/reactos/ntoskrnl/ob/obname.c @@ -206,8 +206,8 @@ ObpDeleteNameCheck(IN PVOID Object) &Context); if (Object) { - /* Lock the object type */ - ObpEnterObjectTypeMutex(ObjectType); + /* Lock the object */ + ObpAcquireObjectLock(ObjectHeader); /* Make sure we can still delete the object */ if (!(ObjectHeader->HandleCount) && @@ -238,7 +238,7 @@ ObpDeleteNameCheck(IN PVOID Object) } /* Release the lock */ - ObpLeaveObjectTypeMutex(ObjectType); + ObpReleaseObjectLock(ObjectHeader); } /* Cleanup after lookup */