- Fix some comments.
- Simplify code.
- Add a missing check for hive exit nodes when deleting cells.

svn path=/trunk/; revision=70706
This commit is contained in:
Hermès Bélusca-Maïto 2016-02-10 22:18:20 +00:00
parent 4191c57d0f
commit 1eb1638e2e

View file

@ -20,7 +20,9 @@ CmpMarkKeyDirty(IN PHHIVE Hive,
IN HCELL_INDEX Cell, IN HCELL_INDEX Cell,
IN BOOLEAN CheckNoSubkeys) IN BOOLEAN CheckNoSubkeys)
{ {
PCELL_DATA CellData, ListData, SecurityData, ValueData; PCM_KEY_NODE CellData;
PCM_KEY_SECURITY SecurityData;
PCELL_DATA ListData, ValueData;
ULONG i; ULONG i;
/* Get the cell data for our target */ /* Get the cell data for our target */
@ -31,12 +33,12 @@ CmpMarkKeyDirty(IN PHHIVE Hive,
if (CheckNoSubkeys) if (CheckNoSubkeys)
{ {
/* Do them */ /* Do them */
ASSERT(CellData->u.KeyNode.SubKeyCounts[Stable] == 0); ASSERT(CellData->SubKeyCounts[Stable] == 0);
ASSERT(CellData->u.KeyNode.SubKeyCounts[Volatile] == 0); ASSERT(CellData->SubKeyCounts[Volatile] == 0);
} }
/* If this is an exit hive, there's nothing to do */ /* If this is an exit node, there's nothing to do */
if (CellData->u.KeyNode.Flags & KEY_HIVE_EXIT) if (CellData->Flags & KEY_HIVE_EXIT)
{ {
/* Release the cell and get out */ /* Release the cell and get out */
HvReleaseCell(Hive, Cell); HvReleaseCell(Hive, Cell);
@ -48,41 +50,42 @@ CmpMarkKeyDirty(IN PHHIVE Hive,
HvReleaseCell(Hive, Cell); HvReleaseCell(Hive, Cell);
/* Check if we have a class */ /* Check if we have a class */
if (CellData->u.KeyNode.Class != HCELL_NIL) if (CellData->Class != HCELL_NIL)
{ {
/* Mark it dirty */ /* Mark it dirty */
HvMarkCellDirty(Hive, CellData->u.KeyNode.Class, FALSE); HvMarkCellDirty(Hive, CellData->Class, FALSE);
} }
/* Check if we have security */ /* Check if we have security */
if (CellData->u.KeyNode.Security != HCELL_NIL) if (CellData->Security != HCELL_NIL)
{ {
/* Mark it dirty */ /* Mark it dirty */
HvMarkCellDirty(Hive, CellData->u.KeyNode.Security, FALSE); HvMarkCellDirty(Hive, CellData->Security, FALSE);
/* Get the security data and release it */ /* Get the security data and release it */
SecurityData = HvGetCell(Hive, CellData->u.KeyNode.Security); SecurityData = HvGetCell(Hive, CellData->Security);
if (!SecurityData) ASSERT(FALSE); if (!SecurityData) ASSERT(FALSE);
HvReleaseCell(Hive, CellData->u.KeyNode.Security); HvReleaseCell(Hive, CellData->Security);
/* Mark the security links dirty too */ /* Mark the security links dirty too */
HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Flink, FALSE); HvMarkCellDirty(Hive, SecurityData->Flink, FALSE);
HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Blink, FALSE); HvMarkCellDirty(Hive, SecurityData->Blink, FALSE);
} }
// TODO: Handle predefined keys (Flags: KEY_PREDEF_HANDLE)
/* Check if we have any values */ /* Check if we have any values */
if (CellData->u.KeyNode.ValueList.Count > 0) if (CellData->ValueList.Count > 0)
{ {
/* Dirty the value list */ /* Dirty the value list */
HvMarkCellDirty(Hive, CellData->u.KeyNode.ValueList.List, FALSE); HvMarkCellDirty(Hive, CellData->ValueList.List, FALSE);
/* Get the list data itself, and release it */ /* Get the list data itself, and release it */
ListData = HvGetCell(Hive, CellData->u.KeyNode.ValueList.List); ListData = HvGetCell(Hive, CellData->ValueList.List);
if (!ListData) ASSERT(FALSE); if (!ListData) ASSERT(FALSE);
HvReleaseCell(Hive, CellData->u.KeyNode.ValueList.List); HvReleaseCell(Hive, CellData->ValueList.List);
/* Loop all values */ /* Loop all values */
for (i = 0; i < CellData->u.KeyNode.ValueList.Count; i++) for (i = 0; i < CellData->ValueList.Count; i++)
{ {
/* Dirty each value */ /* Dirty each value */
HvMarkCellDirty(Hive, ListData->u.KeyList[i], FALSE); HvMarkCellDirty(Hive, ListData->u.KeyList[i], FALSE);
@ -101,18 +104,18 @@ CmpMarkKeyDirty(IN PHHIVE Hive,
} }
} }
/* If this is an entry hive, we're done */ /* If this is an entry node, we're done */
if (CellData->u.KeyNode.Flags & KEY_HIVE_ENTRY) return TRUE; if (CellData->Flags & KEY_HIVE_ENTRY) return TRUE;
/* Otherwise mark the index dirty too */ /* Otherwise mark the index dirty too */
if (!CmpMarkIndexDirty(Hive, CellData->u.KeyNode.Parent, Cell)) if (!CmpMarkIndexDirty(Hive, CellData->Parent, Cell))
{ {
/* Failure */ /* Failure */
return FALSE; return FALSE;
} }
/* Finally, mark the parent dirty */ /* Finally, mark the parent dirty */
HvMarkCellDirty(Hive, CellData->u.KeyNode.Parent, FALSE); HvMarkCellDirty(Hive, CellData->Parent, FALSE);
return TRUE; return TRUE;
} }
@ -121,27 +124,27 @@ NTAPI
CmpFreeKeyBody(IN PHHIVE Hive, CmpFreeKeyBody(IN PHHIVE Hive,
IN HCELL_INDEX Cell) IN HCELL_INDEX Cell)
{ {
PCELL_DATA CellData; PCM_KEY_NODE CellData;
/* Get the key node */ /* Get the key node */
CellData = HvGetCell(Hive, Cell); CellData = HvGetCell(Hive, Cell);
if (!CellData) ASSERT(FALSE); if (!CellData) ASSERT(FALSE);
/* Check if we can delete the child cells */ /* Check if we can delete the child cells */
if (!(CellData->u.KeyNode.Flags & KEY_HIVE_EXIT)) if (!(CellData->Flags & KEY_HIVE_EXIT))
{ {
/* Check if we have a security cell */ /* Check if we have a security cell */
if (CellData->u.KeyNode.Security != HCELL_NIL) if (CellData->Security != HCELL_NIL)
{ {
/* Free the security cell */ /* Free the security cell */
HvFreeCell(Hive, CellData->u.KeyNode.Security); HvFreeCell(Hive, CellData->Security);
} }
/* Check if we have a class */ /* Check if we have a class */
if (CellData->u.KeyNode.ClassLength > 0) if (CellData->ClassLength > 0)
{ {
/* Free it */ /* Free it */
HvFreeCell(Hive, CellData->u.KeyNode.Class); HvFreeCell(Hive, CellData->Class);
} }
} }
@ -157,12 +160,13 @@ CmpFreeKeyByCell(IN PHHIVE Hive,
IN HCELL_INDEX Cell, IN HCELL_INDEX Cell,
IN BOOLEAN Unlink) IN BOOLEAN Unlink)
{ {
PCELL_DATA CellData, ParentData, ListData; PCM_KEY_NODE CellData, ParentData;
PCELL_DATA ListData;
ULONG i; ULONG i;
BOOLEAN Result; BOOLEAN Result;
/* Mark the entire key dirty */ /* Mark the entire key dirty */
CmpMarkKeyDirty(Hive, Cell ,TRUE); CmpMarkKeyDirty(Hive, Cell, TRUE);
/* Get the target node and release it */ /* Get the target node and release it */
CellData = HvGetCell(Hive, Cell); CellData = HvGetCell(Hive, Cell);
@ -170,53 +174,56 @@ CmpFreeKeyByCell(IN PHHIVE Hive,
HvReleaseCell(Hive, Cell); HvReleaseCell(Hive, Cell);
/* Make sure we don't have subkeys */ /* Make sure we don't have subkeys */
ASSERT((CellData->u.KeyNode.SubKeyCounts[Stable] + ASSERT(CellData->SubKeyCounts[Stable] + CellData->SubKeyCounts[Volatile] == 0);
CellData->u.KeyNode.SubKeyCounts[Volatile]) == 0);
/* Check if we have to unlink */ /* Check if we have to unlink */
if (Unlink) if (Unlink)
{ {
/* Remove the subkey */ /* Remove the subkey */
Result = CmpRemoveSubKey(Hive, CellData->u.KeyNode.Parent, Cell); Result = CmpRemoveSubKey(Hive, CellData->Parent, Cell);
if (!Result) return STATUS_INSUFFICIENT_RESOURCES; if (!Result) return STATUS_INSUFFICIENT_RESOURCES;
/* Get the parent node and release it */ /* Get the parent node and release it */
ParentData = HvGetCell(Hive, CellData->u.KeyNode.Parent); ParentData = HvGetCell(Hive, CellData->Parent);
if (!ParentData) ASSERT(FALSE); if (!ParentData) ASSERT(FALSE);
HvReleaseCell(Hive, CellData->u.KeyNode.Parent); HvReleaseCell(Hive, CellData->Parent);
/* Check if the parent node has no more subkeys */ /* Check if the parent node has no more subkeys */
if (!(ParentData->u.KeyNode.SubKeyCounts[Stable] + if (ParentData->SubKeyCounts[Stable] + ParentData->SubKeyCounts[Volatile] == 0)
ParentData->u.KeyNode.SubKeyCounts[Volatile]))
{ {
/* Then free the cached name/class lengths */ /* Then free the cached name/class lengths */
ParentData->u.KeyNode.MaxNameLen = 0; ParentData->MaxNameLen = 0;
ParentData->u.KeyNode.MaxClassLen = 0; ParentData->MaxClassLen = 0;
} }
} }
/* Check if we have any values */ // TODO: Handle predefined keys (Flags: KEY_PREDEF_HANDLE)
if (CellData->u.KeyNode.ValueList.Count > 0) /* If this is an exit node, we don't have values */
if (!(CellData->Flags & KEY_HIVE_EXIT))
{ {
/* Get the value list and release it */ /* Check if we have any values */
ListData = HvGetCell(Hive, CellData->u.KeyNode.ValueList.List); if (CellData->ValueList.Count > 0)
if (!ListData) ASSERT(FALSE);
HvReleaseCell(Hive, CellData->u.KeyNode.ValueList.List);
/* Loop every value */
for (i = 0; i < CellData->u.KeyNode.ValueList.Count; i++)
{ {
/* Free it */ /* Get the value list and release it */
if (!CmpFreeValue(Hive, ListData->u.KeyList[i])) ASSERT(FALSE); ListData = HvGetCell(Hive, CellData->ValueList.List);
if (!ListData) ASSERT(FALSE);
HvReleaseCell(Hive, CellData->ValueList.List);
/* Loop every value */
for (i = 0; i < CellData->ValueList.Count; i++)
{
/* Free it */
if (!CmpFreeValue(Hive, ListData->u.KeyList[i])) ASSERT(FALSE);
}
/* Free the value list */
HvFreeCell(Hive, CellData->ValueList.List);
} }
/* Free the value list */ /* FIXME: This leaks the security desriptor! */
HvFreeCell(Hive, CellData->u.KeyNode.ValueList.List); DPRINT("Potentially leaking key security descriptor. Please call CmpFreeSecurityDescriptor\n");
} }
/* FIXME: This leaks the security desriptor! */
DPRINT("Potentially leaking key security descriptor. Please call CmpFreeSecurityDescriptor\n");
/* Free the key body itself, and then return our status */ /* Free the key body itself, and then return our status */
if (!CmpFreeKeyBody(Hive, Cell)) return STATUS_INSUFFICIENT_RESOURCES; if (!CmpFreeKeyBody(Hive, Cell)) return STATUS_INSUFFICIENT_RESOURCES;
return STATUS_SUCCESS; return STATUS_SUCCESS;