mirror of
https://github.com/reactos/reactos.git
synced 2026-05-30 23:33:24 +08:00
[NTOS:CM] Lock the cached KCB before removing it from cache entries
- Annotate the CmpEnumerateOpenSubKeys function with SAL2 - When removing an orphaned cached KCB, ensure that it is locked before clearing it from cache table entries
This commit is contained in:
@@ -2242,7 +2242,7 @@ CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
||||
{
|
||||
if (Flags != REG_FORCE_UNLOAD)
|
||||
{
|
||||
if (CmpEnumerateOpenSubKeys(Kcb, FALSE, FALSE) != 0)
|
||||
if (CmpEnumerateOpenSubKeys(Kcb, FALSE, FALSE, FALSE) != 0)
|
||||
{
|
||||
/* There are open subkeys but we don't force hive unloading, fail */
|
||||
Hive->HiveFlags &= ~HIVE_IS_UNLOADING;
|
||||
@@ -2252,7 +2252,7 @@ CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
||||
else
|
||||
{
|
||||
DPRINT1("CmUnloadKey: Force unloading is HALF-IMPLEMENTED, expect dangling KCBs problems!\n");
|
||||
if (CmpEnumerateOpenSubKeys(Kcb, TRUE, TRUE) != 0)
|
||||
if (CmpEnumerateOpenSubKeys(Kcb, TRUE, TRUE, TRUE) != 0)
|
||||
{
|
||||
/* There are open subkeys that we cannot force to unload, fail */
|
||||
Hive->HiveFlags &= ~HIVE_IS_UNLOADING;
|
||||
@@ -2340,9 +2340,10 @@ CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
||||
ULONG
|
||||
NTAPI
|
||||
CmpEnumerateOpenSubKeys(
|
||||
IN PCM_KEY_CONTROL_BLOCK RootKcb,
|
||||
IN BOOLEAN RemoveEmptyCacheEntries,
|
||||
IN BOOLEAN DereferenceOpenedEntries)
|
||||
_In_ PCM_KEY_CONTROL_BLOCK RootKcb,
|
||||
_In_ BOOLEAN LockHeldExclusively,
|
||||
_In_ BOOLEAN RemoveEmptyCacheEntries,
|
||||
_In_ BOOLEAN DereferenceOpenedEntries)
|
||||
{
|
||||
PCM_KEY_HASH Entry;
|
||||
PCM_KEY_CONTROL_BLOCK CachedKcb;
|
||||
@@ -2430,11 +2431,20 @@ CmpEnumerateOpenSubKeys(
|
||||
}
|
||||
else if ((CachedKcb->RefCount == 0) && RemoveEmptyCacheEntries)
|
||||
{
|
||||
/* Lock the cached KCB of subkey before removing it from cache entries */
|
||||
if (!LockHeldExclusively)
|
||||
CmpAcquireKcbLockExclusive(CachedKcb);
|
||||
|
||||
/* Remove the current key from the delayed close list */
|
||||
CmpRemoveFromDelayedClose(CachedKcb);
|
||||
|
||||
/* Remove the current cache entry */
|
||||
CmpCleanUpKcbCacheWithLock(CachedKcb, TRUE);
|
||||
// Lock is either held by ourselves or registry is locked exclusively
|
||||
CmpCleanUpKcbCacheWithLock(CachedKcb, LockHeldExclusively);
|
||||
|
||||
/* Unlock the cached KCB if it was done by ourselves */
|
||||
if (!LockHeldExclusively)
|
||||
CmpReleaseKcbLock(CachedKcb);
|
||||
|
||||
/* Restart, because the hash list has changed */
|
||||
Entry = CmpCacheTable[i].Entry;
|
||||
|
||||
@@ -1565,7 +1565,7 @@ NtQueryOpenSubKeys(IN POBJECT_ATTRIBUTES TargetKey,
|
||||
|
||||
/* Call the internal API */
|
||||
SubKeys = CmpEnumerateOpenSubKeys(KeyBody->KeyControlBlock,
|
||||
FALSE, FALSE);
|
||||
TRUE, FALSE, FALSE);
|
||||
|
||||
/* Unlock the registry */
|
||||
CmpUnlockRegistry();
|
||||
|
||||
@@ -1333,9 +1333,10 @@ CmUnloadKey(
|
||||
ULONG
|
||||
NTAPI
|
||||
CmpEnumerateOpenSubKeys(
|
||||
IN PCM_KEY_CONTROL_BLOCK RootKcb,
|
||||
IN BOOLEAN RemoveEmptyCacheEntries,
|
||||
IN BOOLEAN DereferenceOpenedEntries
|
||||
_In_ PCM_KEY_CONTROL_BLOCK RootKcb,
|
||||
_In_ BOOLEAN LockHeldExclusively,
|
||||
_In_ BOOLEAN RemoveEmptyCacheEntries,
|
||||
_In_ BOOLEAN DereferenceOpenedEntries
|
||||
);
|
||||
|
||||
HCELL_INDEX
|
||||
|
||||
Reference in New Issue
Block a user