mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 00:45:24 +00:00
[NTOS:CM] Implement more support for force-unloading registry hives.
CORE-13448 CORE-10705
This commit is contained in:
parent
16752875db
commit
d61c00c252
3 changed files with 64 additions and 12 deletions
|
@ -2221,7 +2221,7 @@ CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
||||||
{
|
{
|
||||||
if (Flags != REG_FORCE_UNLOAD)
|
if (Flags != REG_FORCE_UNLOAD)
|
||||||
{
|
{
|
||||||
if (CmCountOpenSubKeys(Kcb, FALSE) != 0)
|
if (CmpEnumerateOpenSubKeys(Kcb, FALSE, FALSE) != 0)
|
||||||
{
|
{
|
||||||
/* There are open subkeys but we don't force hive unloading, fail */
|
/* There are open subkeys but we don't force hive unloading, fail */
|
||||||
Hive->HiveFlags &= ~HIVE_IS_UNLOADING;
|
Hive->HiveFlags &= ~HIVE_IS_UNLOADING;
|
||||||
|
@ -2230,7 +2230,13 @@ CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT1("CmUnloadKey: Force unloading is UNIMPLEMENTED, expect dangling KCBs problems!\n");
|
DPRINT1("CmUnloadKey: Force unloading is HALF-IMPLEMENTED, expect dangling KCBs problems!\n");
|
||||||
|
if (CmpEnumerateOpenSubKeys(Kcb, TRUE, TRUE) != 0)
|
||||||
|
{
|
||||||
|
/* There are open subkeys that we cannot force to unload, fail */
|
||||||
|
Hive->HiveFlags &= ~HIVE_IS_UNLOADING;
|
||||||
|
return STATUS_CANNOT_DELETE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2247,6 +2253,10 @@ CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Flush any notifications if we force hive unloading */
|
||||||
|
if (Flags == REG_FORCE_UNLOAD)
|
||||||
|
CmpFlushNotifiesOnKeyBodyList(Kcb, TRUE); // Lock is already held
|
||||||
|
|
||||||
/* Clean up information we have on the subkey */
|
/* Clean up information we have on the subkey */
|
||||||
CmpCleanUpSubKeyInfo(Kcb->ParentKcb);
|
CmpCleanUpSubKeyInfo(Kcb->ParentKcb);
|
||||||
|
|
||||||
|
@ -2272,6 +2282,10 @@ CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
||||||
/* Remove the hive from the hive file list */
|
/* Remove the hive from the hive file list */
|
||||||
CmpRemoveFromHiveFileList(CmHive);
|
CmpRemoveFromHiveFileList(CmHive);
|
||||||
|
|
||||||
|
/**
|
||||||
|
** NOTE:
|
||||||
|
** The following code is mostly equivalent to what we "call" CmpDestroyHive()
|
||||||
|
**/
|
||||||
/* Destroy the security descriptor cache */
|
/* Destroy the security descriptor cache */
|
||||||
CmpDestroySecurityCache(CmHive);
|
CmpDestroySecurityCache(CmHive);
|
||||||
|
|
||||||
|
@ -2296,8 +2310,10 @@ CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
CmCountOpenSubKeys(IN PCM_KEY_CONTROL_BLOCK RootKcb,
|
CmpEnumerateOpenSubKeys(
|
||||||
IN BOOLEAN RemoveEmptyCacheEntries)
|
IN PCM_KEY_CONTROL_BLOCK RootKcb,
|
||||||
|
IN BOOLEAN RemoveEmptyCacheEntries,
|
||||||
|
IN BOOLEAN DereferenceOpenedEntries)
|
||||||
{
|
{
|
||||||
PCM_KEY_HASH Entry;
|
PCM_KEY_HASH Entry;
|
||||||
PCM_KEY_CONTROL_BLOCK CachedKcb;
|
PCM_KEY_CONTROL_BLOCK CachedKcb;
|
||||||
|
@ -2306,9 +2322,9 @@ CmCountOpenSubKeys(IN PCM_KEY_CONTROL_BLOCK RootKcb,
|
||||||
ULONG i, j;
|
ULONG i, j;
|
||||||
ULONG SubKeys = 0;
|
ULONG SubKeys = 0;
|
||||||
|
|
||||||
DPRINT("CmCountOpenSubKeys() called\n");
|
DPRINT("CmpEnumerateOpenSubKeys() called\n");
|
||||||
|
|
||||||
/* The root key is the only referenced key. There are no refereced sub keys. */
|
/* The root key is the only referenced key. There are no referenced sub keys. */
|
||||||
if (RootKcb->RefCount == 1)
|
if (RootKcb->RefCount == 1)
|
||||||
{
|
{
|
||||||
DPRINT("Open sub keys: 0\n");
|
DPRINT("Open sub keys: 0\n");
|
||||||
|
@ -2347,10 +2363,43 @@ CmCountOpenSubKeys(IN PCM_KEY_CONTROL_BLOCK RootKcb,
|
||||||
|
|
||||||
if (CachedKcb->RefCount > 0)
|
if (CachedKcb->RefCount > 0)
|
||||||
{
|
{
|
||||||
|
DPRINT1("Found a sub key pointing to '%.*s', RefCount = %u\n",
|
||||||
|
CachedKcb->NameBlock->NameLength, CachedKcb->NameBlock->Name,
|
||||||
|
CachedKcb->RefCount);
|
||||||
|
|
||||||
|
/* If we dereference opened KCBs, don't touch read-only keys */
|
||||||
|
if (DereferenceOpenedEntries &&
|
||||||
|
!(CachedKcb->ExtFlags & CM_KCB_READ_ONLY_KEY))
|
||||||
|
{
|
||||||
|
/* Registry needs to be locked down */
|
||||||
|
CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK();
|
||||||
|
|
||||||
|
/* Flush any notifications */
|
||||||
|
CmpFlushNotifiesOnKeyBodyList(CachedKcb, TRUE); // Lock is already held
|
||||||
|
|
||||||
|
/* Clean up information we have on the subkey */
|
||||||
|
CmpCleanUpSubKeyInfo(CachedKcb->ParentKcb);
|
||||||
|
|
||||||
|
/* Get and cache the next cache entry */
|
||||||
|
// Entry = Entry->NextHash;
|
||||||
|
Entry = CachedKcb->NextHash;
|
||||||
|
|
||||||
|
/* Set the KCB in delete mode and remove it */
|
||||||
|
CachedKcb->Delete = TRUE;
|
||||||
|
CmpRemoveKeyControlBlock(CachedKcb);
|
||||||
|
|
||||||
|
/* Clear the cell */
|
||||||
|
CachedKcb->KeyCell = HCELL_NIL;
|
||||||
|
|
||||||
|
/* Restart with the next cache entry */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Else, the key cannot be dereferenced, and we count it as in use */
|
||||||
|
|
||||||
/* Count the current hash entry if it is in use */
|
/* Count the current hash entry if it is in use */
|
||||||
SubKeys++;
|
SubKeys++;
|
||||||
}
|
}
|
||||||
else if ((CachedKcb->RefCount == 0) && (RemoveEmptyCacheEntries != FALSE))
|
else if ((CachedKcb->RefCount == 0) && RemoveEmptyCacheEntries)
|
||||||
{
|
{
|
||||||
/* Remove the current key from the delayed close list */
|
/* Remove the current key from the delayed close list */
|
||||||
CmpRemoveFromDelayedClose(CachedKcb);
|
CmpRemoveFromDelayedClose(CachedKcb);
|
||||||
|
@ -2370,7 +2419,9 @@ CmCountOpenSubKeys(IN PCM_KEY_CONTROL_BLOCK RootKcb,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Open sub keys: %u\n", SubKeys);
|
if (SubKeys > 0)
|
||||||
|
DPRINT1("Open sub keys: %u\n", SubKeys);
|
||||||
|
|
||||||
return SubKeys;
|
return SubKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1542,8 +1542,8 @@ NtQueryOpenSubKeys(IN POBJECT_ATTRIBUTES TargetKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call the internal API */
|
/* Call the internal API */
|
||||||
*HandleCount = CmCountOpenSubKeys(KeyBody->KeyControlBlock,
|
*HandleCount = CmpEnumerateOpenSubKeys(KeyBody->KeyControlBlock,
|
||||||
FALSE);
|
FALSE, FALSE);
|
||||||
|
|
||||||
/* Unlock the registry */
|
/* Unlock the registry */
|
||||||
CmpUnlockRegistry();
|
CmpUnlockRegistry();
|
||||||
|
|
|
@ -1357,9 +1357,10 @@ CmUnloadKey(
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
CmCountOpenSubKeys(
|
CmpEnumerateOpenSubKeys(
|
||||||
IN PCM_KEY_CONTROL_BLOCK RootKcb,
|
IN PCM_KEY_CONTROL_BLOCK RootKcb,
|
||||||
IN BOOLEAN RemoveEmptyCacheEntries
|
IN BOOLEAN RemoveEmptyCacheEntries,
|
||||||
|
IN BOOLEAN DereferenceOpenedEntries
|
||||||
);
|
);
|
||||||
|
|
||||||
HCELL_INDEX
|
HCELL_INDEX
|
||||||
|
|
Loading…
Reference in a new issue