mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 14:30:57 +00:00
527f2f9057
* Create a branch for some evul shell experiments. svn path=/branches/shell-experiments/; revision=61927
220 lines
6.6 KiB
C
220 lines
6.6 KiB
C
/*
|
|
* PROJECT: ReactOS Kernel
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
* FILE: ntoskrnl/config/cmkeydel.c
|
|
* PURPOSE: Configuration Manager - Key Body Deletion
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include "ntoskrnl.h"
|
|
#define NDEBUG
|
|
#include "debug.h"
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
CmpMarkKeyDirty(IN PHHIVE Hive,
|
|
IN HCELL_INDEX Cell,
|
|
IN BOOLEAN CheckNoSubkeys)
|
|
{
|
|
PCELL_DATA CellData, ListData, SecurityData, ValueData;
|
|
ULONG i;
|
|
|
|
/* Get the cell data for our target */
|
|
CellData = HvGetCell(Hive, Cell);
|
|
if (!CellData) return FALSE;
|
|
|
|
/* Check if sanity checks requested */
|
|
if (CheckNoSubkeys)
|
|
{
|
|
/* Do them */
|
|
ASSERT(CellData->u.KeyNode.SubKeyCounts[Stable] == 0);
|
|
ASSERT(CellData->u.KeyNode.SubKeyCounts[Volatile] == 0);
|
|
}
|
|
|
|
/* If this is an exit hive, there's nothing to do */
|
|
if (CellData->u.KeyNode.Flags & KEY_HIVE_EXIT)
|
|
{
|
|
/* Release the cell and get out */
|
|
HvReleaseCell(Hive, Cell);
|
|
return TRUE;
|
|
}
|
|
|
|
/* Otherwise, mark it dirty and release it */
|
|
HvMarkCellDirty(Hive, Cell, FALSE);
|
|
HvReleaseCell(Hive, Cell);
|
|
|
|
/* Check if we have a class */
|
|
if (CellData->u.KeyNode.Class != HCELL_NIL)
|
|
{
|
|
/* Mark it dirty */
|
|
HvMarkCellDirty(Hive, CellData->u.KeyNode.Class, FALSE);
|
|
}
|
|
|
|
/* Check if we have security */
|
|
if (CellData->u.KeyNode.Security != HCELL_NIL)
|
|
{
|
|
/* Mark it dirty */
|
|
HvMarkCellDirty(Hive, CellData->u.KeyNode.Security, FALSE);
|
|
|
|
/* Get the security data and release it */
|
|
SecurityData = HvGetCell(Hive, CellData->u.KeyNode.Security);
|
|
if (!SecurityData) ASSERT(FALSE);
|
|
HvReleaseCell(Hive, CellData->u.KeyNode.Security);
|
|
|
|
/* Mark the security links dirty too */
|
|
HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Flink, FALSE);
|
|
HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Blink, FALSE);
|
|
}
|
|
|
|
/* Check if we have any values */
|
|
if (CellData->u.KeyNode.ValueList.Count > 0)
|
|
{
|
|
/* Dirty the value list */
|
|
HvMarkCellDirty(Hive, CellData->u.KeyNode.ValueList.List, FALSE);
|
|
|
|
/* Get the list data itself, and release it */
|
|
ListData = HvGetCell(Hive, CellData->u.KeyNode.ValueList.List);
|
|
if (!ListData) ASSERT(FALSE);
|
|
HvReleaseCell(Hive, CellData->u.KeyNode.ValueList.List);
|
|
|
|
/* Loop all values */
|
|
for (i = 0; i < CellData->u.KeyNode.ValueList.Count; i++)
|
|
{
|
|
/* Dirty each value */
|
|
HvMarkCellDirty(Hive, ListData->u.KeyList[i], FALSE);
|
|
|
|
/* Get the value data and release it */
|
|
ValueData = HvGetCell(Hive, ListData->u.KeyList[i]);
|
|
ASSERT(ValueData);
|
|
HvReleaseCell(Hive,ListData->u.KeyList[i]);
|
|
|
|
/* Mark the value data dirty too */
|
|
if (!CmpMarkValueDataDirty(Hive, &ValueData->u.KeyValue))
|
|
{
|
|
/* Failure */
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* If this is an entry hive, we're done */
|
|
if (CellData->u.KeyNode.Flags & KEY_HIVE_ENTRY) return TRUE;
|
|
|
|
/* Otherwise mark the index dirty too */
|
|
if (!CmpMarkIndexDirty(Hive, CellData->u.KeyNode.Parent, Cell))
|
|
{
|
|
/* Failure */
|
|
return FALSE;
|
|
}
|
|
|
|
/* Finally, mark the parent dirty */
|
|
HvMarkCellDirty(Hive, CellData->u.KeyNode.Parent, FALSE);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
CmpFreeKeyBody(IN PHHIVE Hive,
|
|
IN HCELL_INDEX Cell)
|
|
{
|
|
PCELL_DATA CellData;
|
|
|
|
/* Get the key node */
|
|
CellData = HvGetCell(Hive, Cell);
|
|
if (!CellData) ASSERT(FALSE);
|
|
|
|
/* Check if we can delete the child cells */
|
|
if (!(CellData->u.KeyNode.Flags & KEY_HIVE_EXIT))
|
|
{
|
|
/* Check if we have a security cell */
|
|
if (CellData->u.KeyNode.Security != HCELL_NIL)
|
|
{
|
|
/* Free the security cell */
|
|
HvFreeCell(Hive, CellData->u.KeyNode.Security);
|
|
}
|
|
|
|
/* Check if we have a class */
|
|
if (CellData->u.KeyNode.ClassLength > 0)
|
|
{
|
|
/* Free it */
|
|
HvFreeCell(Hive, CellData->u.KeyNode.Class);
|
|
}
|
|
}
|
|
|
|
/* Release and free the cell */
|
|
HvReleaseCell(Hive, Cell);
|
|
HvFreeCell(Hive, Cell);
|
|
return TRUE;
|
|
}
|
|
|
|
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;
|
|
}
|