mirror of
https://github.com/reactos/reactos.git
synced 2025-07-05 04:01:23 +00:00
[NTOS:OB] Clarify and fix the usage of the Obp*DirectoryLock*() and ObpReleaseLookupContextObject() functions.
- Disentangle the usage of ObpAcquireDirectoryLockExclusive() when it's used only for accessing a directory structure, or as part of a lookup operation. The Obp*DirectoryLock*() -- both shared and exclusive -- functions are only for locking an OB directory, for reading or writing its structure members. When performing lookup operations (insertions/deletions of entries within a directory), use a ObpAcquireLookupContextLock() function that exclusively locks the directory and saves extra lock state, that can be used by ObpReleaseLookupContextObject() for cleanup. - Add documentation for these functions.
This commit is contained in:
parent
19cdb521d2
commit
4c63ed5a7a
5 changed files with 93 additions and 29 deletions
|
@ -169,15 +169,26 @@ ObpDereferenceNameInfo(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Locks a directory for shared access.
|
||||||
|
* Used for reading members of the directory object.
|
||||||
|
*
|
||||||
|
* @param[in] Directory
|
||||||
|
* The directory to lock.
|
||||||
|
*
|
||||||
|
* @param[in] Context
|
||||||
|
* The lookup lock context.
|
||||||
|
*/
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
VOID
|
VOID
|
||||||
ObpAcquireDirectoryLockShared(IN POBJECT_DIRECTORY Directory,
|
ObpAcquireDirectoryLockShared(IN POBJECT_DIRECTORY Directory,
|
||||||
IN POBP_LOOKUP_CONTEXT Context)
|
IN POBP_LOOKUP_CONTEXT Context)
|
||||||
{
|
{
|
||||||
/* It's not, set lock flag */
|
/* Update lock flag */
|
||||||
Context->LockStateSignature = OBP_LOCK_STATE_PRE_ACQUISITION_SHARED;
|
Context->LockStateSignature = OBP_LOCK_STATE_PRE_ACQUISITION_SHARED;
|
||||||
|
|
||||||
/* Lock it */
|
/* Acquire an shared directory lock */
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
ExAcquirePushLockShared(&Directory->Lock);
|
ExAcquirePushLockShared(&Directory->Lock);
|
||||||
|
|
||||||
|
@ -185,6 +196,17 @@ ObpAcquireDirectoryLockShared(IN POBJECT_DIRECTORY Directory,
|
||||||
Context->LockStateSignature = OBP_LOCK_STATE_POST_ACQUISITION_SHARED;
|
Context->LockStateSignature = OBP_LOCK_STATE_POST_ACQUISITION_SHARED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Locks a directory for exclusive access.
|
||||||
|
* Used for writing/reading members of the directory object.
|
||||||
|
*
|
||||||
|
* @param[in] Directory
|
||||||
|
* The directory to lock.
|
||||||
|
*
|
||||||
|
* @param[in] Context
|
||||||
|
* The lookup lock context.
|
||||||
|
*/
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
VOID
|
VOID
|
||||||
ObpAcquireDirectoryLockExclusive(IN POBJECT_DIRECTORY Directory,
|
ObpAcquireDirectoryLockExclusive(IN POBJECT_DIRECTORY Directory,
|
||||||
|
@ -197,14 +219,20 @@ ObpAcquireDirectoryLockExclusive(IN POBJECT_DIRECTORY Directory,
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
ExAcquirePushLockExclusive(&Directory->Lock);
|
ExAcquirePushLockExclusive(&Directory->Lock);
|
||||||
|
|
||||||
/* Set the directory */
|
/* Update lock flag */
|
||||||
Context->Directory = Directory;
|
|
||||||
|
|
||||||
/* Update lock settings */
|
|
||||||
Context->LockStateSignature = OBP_LOCK_STATE_POST_ACQUISITION_EXCLUSIVE;
|
Context->LockStateSignature = OBP_LOCK_STATE_POST_ACQUISITION_EXCLUSIVE;
|
||||||
Context->DirectoryLocked = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Unlocks a previously shared or exclusively locked directory.
|
||||||
|
*
|
||||||
|
* @param[in] Directory
|
||||||
|
* The directory to unlock.
|
||||||
|
*
|
||||||
|
* @param[in] Context
|
||||||
|
* The lookup lock context.
|
||||||
|
*/
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
VOID
|
VOID
|
||||||
ObpReleaseDirectoryLock(IN POBJECT_DIRECTORY Directory,
|
ObpReleaseDirectoryLock(IN POBJECT_DIRECTORY Directory,
|
||||||
|
@ -216,6 +244,15 @@ ObpReleaseDirectoryLock(IN POBJECT_DIRECTORY Directory,
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Initializes a new object directory lookup context.
|
||||||
|
* Used for lookup operations (insertions/deletions) in a directory.
|
||||||
|
* Employed in conjunction with the directory locking functions.
|
||||||
|
*
|
||||||
|
* @param[in] Context
|
||||||
|
* The new lookup context to initialize.
|
||||||
|
*/
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
VOID
|
VOID
|
||||||
ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
|
ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
|
||||||
|
@ -227,6 +264,29 @@ ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
|
||||||
Context->LockStateSignature = OBP_LOCK_STATE_INITIALIZED;
|
Context->LockStateSignature = OBP_LOCK_STATE_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Locks an object directory lookup context for performing
|
||||||
|
* lookup operations (insertions/deletions) in a directory.
|
||||||
|
* The directory is locked for exclusive access.
|
||||||
|
*
|
||||||
|
* @param[in] Context
|
||||||
|
* The lookup context to lock.
|
||||||
|
*
|
||||||
|
* @param[in] Directory
|
||||||
|
* The directory on which the lookup context applies.
|
||||||
|
*/
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
ObpAcquireLookupContextLock(IN POBP_LOOKUP_CONTEXT Context,
|
||||||
|
IN POBJECT_DIRECTORY Directory)
|
||||||
|
{
|
||||||
|
/* Acquire an exclusive directory lock and save its lock state */
|
||||||
|
ObpAcquireDirectoryLockExclusive(Directory, Context);
|
||||||
|
Context->Directory = Directory;
|
||||||
|
Context->DirectoryLocked = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
VOID
|
VOID
|
||||||
ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context)
|
ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context)
|
||||||
|
@ -234,14 +294,14 @@ ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context)
|
||||||
POBJECT_HEADER ObjectHeader;
|
POBJECT_HEADER ObjectHeader;
|
||||||
POBJECT_HEADER_NAME_INFO HeaderNameInfo;
|
POBJECT_HEADER_NAME_INFO HeaderNameInfo;
|
||||||
|
|
||||||
/* Check if we had found an object */
|
/* Check if we had an object */
|
||||||
if (Context->Object)
|
if (Context->Object)
|
||||||
{
|
{
|
||||||
/* Get the object name information */
|
/* Get the object name information */
|
||||||
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Context->Object);
|
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Context->Object);
|
||||||
HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
|
HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
|
||||||
|
|
||||||
/* release the name information */
|
/* Release the name information */
|
||||||
ObpDereferenceNameInfo(HeaderNameInfo);
|
ObpDereferenceNameInfo(HeaderNameInfo);
|
||||||
|
|
||||||
/* Dereference the object */
|
/* Dereference the object */
|
||||||
|
@ -250,6 +310,14 @@ ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Releases an initialized object directory lookup context.
|
||||||
|
* Unlocks it if necessary, and dereferences the underlying object.
|
||||||
|
*
|
||||||
|
* @param[in] Context
|
||||||
|
* The lookup context to release.
|
||||||
|
*/
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
VOID
|
VOID
|
||||||
ObpReleaseLookupContext(IN POBP_LOOKUP_CONTEXT Context)
|
ObpReleaseLookupContext(IN POBP_LOOKUP_CONTEXT Context)
|
||||||
|
@ -257,7 +325,7 @@ ObpReleaseLookupContext(IN POBP_LOOKUP_CONTEXT Context)
|
||||||
/* Check if we came back with the directory locked */
|
/* Check if we came back with the directory locked */
|
||||||
if (Context->DirectoryLocked)
|
if (Context->DirectoryLocked)
|
||||||
{
|
{
|
||||||
/* Release the lock */
|
/* Release the directory lock */
|
||||||
ObpReleaseDirectoryLock(Context->Directory, Context);
|
ObpReleaseDirectoryLock(Context->Directory, Context);
|
||||||
Context->Directory = NULL;
|
Context->Directory = NULL;
|
||||||
Context->DirectoryLocked = FALSE;
|
Context->DirectoryLocked = FALSE;
|
||||||
|
|
|
@ -573,7 +573,7 @@ NtQueryDirectoryObject(IN HANDLE DirectoryHandle,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock directory in shared mode */
|
/* Lock the directory in shared mode */
|
||||||
ObpAcquireDirectoryLockShared(Directory, &LookupContext);
|
ObpAcquireDirectoryLockShared(Directory, &LookupContext);
|
||||||
|
|
||||||
/* Start at position 0 */
|
/* Start at position 0 */
|
||||||
|
|
|
@ -386,11 +386,9 @@ ObPostPhase0:
|
||||||
Status = NtClose(Handle);
|
Status = NtClose(Handle);
|
||||||
if (!NT_SUCCESS(Status)) return FALSE;
|
if (!NT_SUCCESS(Status)) return FALSE;
|
||||||
|
|
||||||
/* Initialize lookup context */
|
/* Initialize the lookup context and lock it */
|
||||||
ObpInitializeLookupContext(&Context);
|
ObpInitializeLookupContext(&Context);
|
||||||
|
ObpAcquireLookupContextLock(&Context, ObpTypeDirectoryObject);
|
||||||
/* Lock it */
|
|
||||||
ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject, &Context);
|
|
||||||
|
|
||||||
/* Loop the object types */
|
/* Loop the object types */
|
||||||
ListHead = &ObpTypeObjectType->TypeList;
|
ListHead = &ObpTypeObjectType->TypeList;
|
||||||
|
|
|
@ -1093,8 +1093,8 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
|
||||||
/* Check if we've already created the directory of types */
|
/* Check if we've already created the directory of types */
|
||||||
if (ObpTypeDirectoryObject)
|
if (ObpTypeDirectoryObject)
|
||||||
{
|
{
|
||||||
/* Acquire the directory lock */
|
/* Lock the lookup context */
|
||||||
ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject, &Context);
|
ObpAcquireLookupContextLock(&Context, ObpTypeDirectoryObject);
|
||||||
|
|
||||||
/* Do the lookup */
|
/* Do the lookup */
|
||||||
if (ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
if (ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
||||||
|
@ -1853,7 +1853,7 @@ NtSetInformationObject(IN HANDLE ObjectHandle,
|
||||||
OBP_LOOKUP_CONTEXT LookupContext;
|
OBP_LOOKUP_CONTEXT LookupContext;
|
||||||
ObpInitializeLookupContext(&LookupContext);
|
ObpInitializeLookupContext(&LookupContext);
|
||||||
|
|
||||||
/* Set its session ID */
|
/* Set the directory session ID */
|
||||||
ObpAcquireDirectoryLockExclusive(Directory, &LookupContext);
|
ObpAcquireDirectoryLockExclusive(Directory, &LookupContext);
|
||||||
Directory->SessionId = PsGetCurrentProcessSessionId();
|
Directory->SessionId = PsGetCurrentProcessSessionId();
|
||||||
ObpReleaseDirectoryLock(Directory, &LookupContext);
|
ObpReleaseDirectoryLock(Directory, &LookupContext);
|
||||||
|
|
|
@ -321,11 +321,9 @@ ObpDeleteNameCheck(IN PVOID Object)
|
||||||
(ObjectNameInfo->Directory) &&
|
(ObjectNameInfo->Directory) &&
|
||||||
!(ObjectHeader->Flags & OB_FLAG_PERMANENT))
|
!(ObjectHeader->Flags & OB_FLAG_PERMANENT))
|
||||||
{
|
{
|
||||||
/* Setup a lookup context */
|
/* Setup a lookup context and lock it */
|
||||||
ObpInitializeLookupContext(&Context);
|
ObpInitializeLookupContext(&Context);
|
||||||
|
ObpAcquireLookupContextLock(&Context, ObjectNameInfo->Directory);
|
||||||
/* Lock the directory */
|
|
||||||
ObpAcquireDirectoryLockExclusive(ObjectNameInfo->Directory, &Context);
|
|
||||||
|
|
||||||
/* Do the lookup */
|
/* Do the lookup */
|
||||||
Object = ObpLookupEntryDirectory(ObjectNameInfo->Directory,
|
Object = ObpLookupEntryDirectory(ObjectNameInfo->Directory,
|
||||||
|
@ -352,7 +350,7 @@ ObpDeleteNameCheck(IN PVOID Object)
|
||||||
ObpDeleteSymbolicLinkName(Object);
|
ObpDeleteSymbolicLinkName(Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the kernel exclusive is set */
|
/* Check if the kernel exclusive flag is set */
|
||||||
ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
|
ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
|
||||||
if ((ObjectNameInfo) &&
|
if ((ObjectNameInfo) &&
|
||||||
(ObjectNameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE))
|
(ObjectNameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE))
|
||||||
|
@ -843,8 +841,8 @@ ParseFromRoot:
|
||||||
/* Check if we are inserting an object */
|
/* Check if we are inserting an object */
|
||||||
if (InsertObject)
|
if (InsertObject)
|
||||||
{
|
{
|
||||||
/* Lock the directory */
|
/* Lock the lookup context */
|
||||||
ObpAcquireDirectoryLockExclusive(Directory, LookupContext);
|
ObpAcquireLookupContextLock(LookupContext, Directory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue