[NTOS]: Fix a bit the CmUnloadKey() function:

- When a hive is unloaded, we *must* set the HIVE_IS_UNLOADING flag before doing anything else (as other code in Cm depends on this);
- If we don't force a hive unload, we *must* check whether there are other opened handles to keys inside this hive, and if so, we must fail.
  If this is a force-unload however, we *must* invalidate/close all the opened handles to keys inside this hive, BUT this is left UNIMPLEMENTED at the moment (and therefore expect the already existing problems linked to this to still happen).
- Move the HvFree(Hive); call at the very end, just before deleting the Cm hive, and as is done in CmpDestroyHive().

svn path=/trunk/; revision=75066
This commit is contained in:
Hermès Bélusca-Maïto 2017-06-16 21:06:04 +00:00
parent 3c50fb3900
commit 3112a6b342

View file

@ -2198,6 +2198,27 @@ CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
return STATUS_INVALID_PARAMETER;
}
/* Mark this hive as being unloaded */
Hive->HiveFlags |= HIVE_IS_UNLOADING;
/* Search for any opened keys in this hive, and take an appropriate action */
if (Kcb->RefCount > 1)
{
if (Flags != REG_FORCE_UNLOAD)
{
if (CmCountOpenSubKeys(Kcb, FALSE) != 0)
{
/* There are open subkeys but we don't force hive unloading, fail */
Hive->HiveFlags &= ~HIVE_IS_UNLOADING;
return STATUS_CANNOT_DELETE;
}
}
else
{
DPRINT1("CmUnloadKey: Force unloading is UNIMPLEMENTED, expect dangling KCBs problems!\n");
}
}
/* Flush the hive */
CmFlushKey(Kcb, TRUE);
@ -2206,9 +2227,8 @@ CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
{
DPRINT("CmpUnlinkHiveFromMaster() failed!\n");
/* Remove the unloading flag */
/* Remove the unloading flag and return failure */
Hive->HiveFlags &= ~HIVE_IS_UNLOADING;
return STATUS_INSUFFICIENT_RESOURCES;
}
@ -2243,9 +2263,6 @@ CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
/* Destroy the view list */
CmpDestroyHiveViewList(CmHive);
/* Free the hive storage */
HvFree(Hive);
/* Delete the flusher lock */
ExDeleteResourceLite(CmHive->FlusherLock);
ExFreePoolWithTag(CmHive->FlusherLock, TAG_CMHIVE);
@ -2253,6 +2270,9 @@ CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
/* Delete the view lock */
ExFreePoolWithTag(CmHive->ViewLock, TAG_CMHIVE);
/* Free the hive storage */
HvFree(Hive);
/* Free the hive */
CmpFree(CmHive, TAG_CM);