mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +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
|
||||
VOID
|
||||
ObpAcquireDirectoryLockShared(IN POBJECT_DIRECTORY Directory,
|
||||
IN POBP_LOOKUP_CONTEXT Context)
|
||||
{
|
||||
/* It's not, set lock flag */
|
||||
/* Update lock flag */
|
||||
Context->LockStateSignature = OBP_LOCK_STATE_PRE_ACQUISITION_SHARED;
|
||||
|
||||
/* Lock it */
|
||||
/* Acquire an shared directory lock */
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquirePushLockShared(&Directory->Lock);
|
||||
|
||||
|
@ -185,6 +196,17 @@ ObpAcquireDirectoryLockShared(IN POBJECT_DIRECTORY Directory,
|
|||
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
|
||||
VOID
|
||||
ObpAcquireDirectoryLockExclusive(IN POBJECT_DIRECTORY Directory,
|
||||
|
@ -197,14 +219,20 @@ ObpAcquireDirectoryLockExclusive(IN POBJECT_DIRECTORY Directory,
|
|||
KeEnterCriticalRegion();
|
||||
ExAcquirePushLockExclusive(&Directory->Lock);
|
||||
|
||||
/* Set the directory */
|
||||
Context->Directory = Directory;
|
||||
|
||||
/* Update lock settings */
|
||||
/* Update lock flag */
|
||||
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
|
||||
VOID
|
||||
ObpReleaseDirectoryLock(IN POBJECT_DIRECTORY Directory,
|
||||
|
@ -216,6 +244,15 @@ ObpReleaseDirectoryLock(IN POBJECT_DIRECTORY Directory,
|
|||
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
|
||||
VOID
|
||||
ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
|
||||
|
@ -227,6 +264,29 @@ ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
|
|||
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
|
||||
VOID
|
||||
ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context)
|
||||
|
@ -234,14 +294,14 @@ ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context)
|
|||
POBJECT_HEADER ObjectHeader;
|
||||
POBJECT_HEADER_NAME_INFO HeaderNameInfo;
|
||||
|
||||
/* Check if we had found an object */
|
||||
/* Check if we had an object */
|
||||
if (Context->Object)
|
||||
{
|
||||
/* Get the object name information */
|
||||
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Context->Object);
|
||||
HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
|
||||
|
||||
/* release the name information */
|
||||
/* Release the name information */
|
||||
ObpDereferenceNameInfo(HeaderNameInfo);
|
||||
|
||||
/* 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
|
||||
VOID
|
||||
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 */
|
||||
if (Context->DirectoryLocked)
|
||||
{
|
||||
/* Release the lock */
|
||||
/* Release the directory lock */
|
||||
ObpReleaseDirectoryLock(Context->Directory, Context);
|
||||
Context->Directory = NULL;
|
||||
Context->DirectoryLocked = FALSE;
|
||||
|
|
|
@ -573,7 +573,7 @@ NtQueryDirectoryObject(IN HANDLE DirectoryHandle,
|
|||
return Status;
|
||||
}
|
||||
|
||||
/* Lock directory in shared mode */
|
||||
/* Lock the directory in shared mode */
|
||||
ObpAcquireDirectoryLockShared(Directory, &LookupContext);
|
||||
|
||||
/* Start at position 0 */
|
||||
|
|
|
@ -386,11 +386,9 @@ ObPostPhase0:
|
|||
Status = NtClose(Handle);
|
||||
if (!NT_SUCCESS(Status)) return FALSE;
|
||||
|
||||
/* Initialize lookup context */
|
||||
/* Initialize the lookup context and lock it */
|
||||
ObpInitializeLookupContext(&Context);
|
||||
|
||||
/* Lock it */
|
||||
ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject, &Context);
|
||||
ObpAcquireLookupContextLock(&Context, ObpTypeDirectoryObject);
|
||||
|
||||
/* Loop the object types */
|
||||
ListHead = &ObpTypeObjectType->TypeList;
|
||||
|
|
|
@ -1093,8 +1093,8 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
|
|||
/* Check if we've already created the directory of types */
|
||||
if (ObpTypeDirectoryObject)
|
||||
{
|
||||
/* Acquire the directory lock */
|
||||
ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject, &Context);
|
||||
/* Lock the lookup context */
|
||||
ObpAcquireLookupContextLock(&Context, ObpTypeDirectoryObject);
|
||||
|
||||
/* Do the lookup */
|
||||
if (ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
||||
|
@ -1853,7 +1853,7 @@ NtSetInformationObject(IN HANDLE ObjectHandle,
|
|||
OBP_LOOKUP_CONTEXT LookupContext;
|
||||
ObpInitializeLookupContext(&LookupContext);
|
||||
|
||||
/* Set its session ID */
|
||||
/* Set the directory session ID */
|
||||
ObpAcquireDirectoryLockExclusive(Directory, &LookupContext);
|
||||
Directory->SessionId = PsGetCurrentProcessSessionId();
|
||||
ObpReleaseDirectoryLock(Directory, &LookupContext);
|
||||
|
|
|
@ -321,11 +321,9 @@ ObpDeleteNameCheck(IN PVOID Object)
|
|||
(ObjectNameInfo->Directory) &&
|
||||
!(ObjectHeader->Flags & OB_FLAG_PERMANENT))
|
||||
{
|
||||
/* Setup a lookup context */
|
||||
/* Setup a lookup context and lock it */
|
||||
ObpInitializeLookupContext(&Context);
|
||||
|
||||
/* Lock the directory */
|
||||
ObpAcquireDirectoryLockExclusive(ObjectNameInfo->Directory, &Context);
|
||||
ObpAcquireLookupContextLock(&Context, ObjectNameInfo->Directory);
|
||||
|
||||
/* Do the lookup */
|
||||
Object = ObpLookupEntryDirectory(ObjectNameInfo->Directory,
|
||||
|
@ -352,7 +350,7 @@ ObpDeleteNameCheck(IN PVOID 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);
|
||||
if ((ObjectNameInfo) &&
|
||||
(ObjectNameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE))
|
||||
|
@ -843,8 +841,8 @@ ParseFromRoot:
|
|||
/* Check if we are inserting an object */
|
||||
if (InsertObject)
|
||||
{
|
||||
/* Lock the directory */
|
||||
ObpAcquireDirectoryLockExclusive(Directory, LookupContext);
|
||||
/* Lock the lookup context */
|
||||
ObpAcquireLookupContextLock(LookupContext, Directory);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue