|
|
Definition at line 448 of file hivecell.c.
Referenced by CmiAddSubKey(), CmpDoCreateChild(), CmpFreeKeyBody(), CmpFreeKeyByCell(), CmpFreeValue(), CmpFreeValueData(), CmpRemoveSubKey(), CmpRemoveValueFromList(), CmpSetValueKeyNew(), CmpSplitLeaf(), HvReallocateCell(), and RegSetValueExW().
{
PHCELL Free;
PHCELL Neighbor;
PHBIN Bin;
ULONG CellType;
ULONG CellBlock;
ASSERT(RegistryHive->ReadOnly == FALSE);
CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx\n",
__FUNCTION__, RegistryHive, CellIndex);
Free = HvpGetCellHeader(RegistryHive, CellIndex);
ASSERT(Free->Size < 0);
Free->Size = -Free->Size;
CellType = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
Bin = (PHBIN)RegistryHive->Storage[CellType].BlockList[CellBlock].BinAddress;
if ((CellIndex & ~HCELL_TYPE_MASK) + Free->Size <
Bin->FileOffset + Bin->Size)
{
Neighbor = (PHCELL)((ULONG_PTR)Free + Free->Size);
if (Neighbor->Size > 0)
{
HvpRemoveFree(RegistryHive, Neighbor,
((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK));
Free->Size += Neighbor->Size;
}
}
Neighbor = (PHCELL)(Bin + 1);
while (Neighbor < Free)
{
if (Neighbor->Size > 0)
{
if ((ULONG_PTR)Neighbor + Neighbor->Size == (ULONG_PTR)Free)
{
HCELL_INDEX NeighborCellIndex =
(HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
Bin->FileOffset) | (CellIndex & HCELL_TYPE_MASK);
if (HvpComputeFreeListIndex(Neighbor->Size) !=
HvpComputeFreeListIndex(Neighbor->Size + Free->Size))
{
HvpRemoveFree(RegistryHive, Neighbor, NeighborCellIndex);
Neighbor->Size += Free->Size;
HvpAddFree(RegistryHive, Neighbor, NeighborCellIndex);
}
else
Neighbor->Size += Free->Size;
if (CellType == Stable)
HvMarkCellDirty(RegistryHive, NeighborCellIndex, FALSE);
return;
}
Neighbor = (PHCELL)((ULONG_PTR)Neighbor + Neighbor->Size);
}
else
{
Neighbor = (PHCELL)((ULONG_PTR)Neighbor - Neighbor->Size);
}
}
HvpAddFree(RegistryHive, Free, CellIndex);
if (CellType == Stable)
HvMarkCellDirty(RegistryHive, CellIndex, FALSE);
}
|