NTSTATUS NTAPI CmpFreeKeyByCell(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN BOOLEAN Unlink) { PCELL_DATA CellData, ParentData, ListData; ULONG i; BOOLEAN Result; /* Mark the entire key dirty */ CmpMarkKeyDirty(Hive, Cell ,TRUE); /* Get the target node and release it */ CellData = HvGetCell(Hive, Cell); if (!CellData) ASSERT(FALSE); HvReleaseCell(Hive, Cell); /* Make sure we don't have subkeys */ ASSERT((CellData->u.KeyNode.SubKeyCounts[Stable] + CellData->u.KeyNode.SubKeyCounts[Volatile]) == 0); /* Check if we have to unlink */ if (Unlink) { /* Remove the subkey */ Result = CmpRemoveSubKey(Hive, CellData->u.KeyNode.Parent, Cell); if (!Result) return STATUS_INSUFFICIENT_RESOURCES; /* Get the parent node and release it */ ParentData = HvGetCell(Hive, CellData->u.KeyNode.Parent); if (!ParentData) ASSERT(FALSE); HvReleaseCell(Hive, CellData->u.KeyNode.Parent); /* Check if the parent node has no more subkeys */ if (!(ParentData->u.KeyNode.SubKeyCounts[Stable] + ParentData->u.KeyNode.SubKeyCounts[Volatile])) { /* Then free the cached name/class lengths */ ParentData->u.KeyNode.MaxNameLen = 0; ParentData->u.KeyNode.MaxClassLen = 0; } } /* Check if we have any values */ if (CellData->u.KeyNode.ValueList.Count > 0) { /* Get the value list and release it */ ListData = HvGetCell(Hive, CellData->u.KeyNode.ValueList.List); 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 */ if (!CmpFreeValue(Hive, ListData->u.KeyList[i])) ASSERT(FALSE); } /* Free the value list */ HvFreeCell(Hive, CellData->u.KeyNode.ValueList.List); } /* Free the key body itself, and then return our status */ if (!CmpFreeKeyBody(Hive, Cell)) return STATUS_INSUFFICIENT_RESOURCES; return STATUS_SUCCESS; }
NTSTATUS NTAPI CmpFreeKeyByCell(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN BOOLEAN Unlink) { PCM_KEY_NODE CellData, ParentData; PCELL_DATA ListData; ULONG i; BOOLEAN Result; /* Mark the entire key dirty */ CmpMarkKeyDirty(Hive, Cell, TRUE); /* Get the target node and release it */ CellData = HvGetCell(Hive, Cell); if (!CellData) ASSERT(FALSE); HvReleaseCell(Hive, Cell); /* Make sure we don't have subkeys */ ASSERT(CellData->SubKeyCounts[Stable] + CellData->SubKeyCounts[Volatile] == 0); /* Check if we have to unlink */ if (Unlink) { /* Remove the subkey */ Result = CmpRemoveSubKey(Hive, CellData->Parent, Cell); if (!Result) return STATUS_INSUFFICIENT_RESOURCES; /* Get the parent node and release it */ ParentData = HvGetCell(Hive, CellData->Parent); if (!ParentData) ASSERT(FALSE); HvReleaseCell(Hive, CellData->Parent); /* Check if the parent node has no more subkeys */ if (ParentData->SubKeyCounts[Stable] + ParentData->SubKeyCounts[Volatile] == 0) { /* Then free the cached name/class lengths */ ParentData->MaxNameLen = 0; ParentData->MaxClassLen = 0; } } // TODO: Handle predefined keys (Flags: KEY_PREDEF_HANDLE) /* If this is an exit node, we don't have values */ if (!(CellData->Flags & KEY_HIVE_EXIT)) { /* Check if we have any values */ if (CellData->ValueList.Count > 0) { /* Get the value list and release it */ 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 key security descriptor */ CmpFreeSecurityDescriptor(Hive, Cell); } /* Free the key body itself, and then return our status */ if (!CmpFreeKeyBody(Hive, Cell)) return STATUS_INSUFFICIENT_RESOURCES; return STATUS_SUCCESS; }