Author: fireball
Date: Tue Dec 18 13:13:45 2007
New Revision: 31299
URL:
http://svn.reactos.org/svn/reactos?rev=31299&view=rev
Log:
Filip Navara <xnavara at volny dot cz> 's christmas gift
- Fix certain cases of deallocation inside registry hives.
- Add debug output in case of a problem in HvpRemoveFree.
Modified:
trunk/reactos/lib/cmlib/hivecell.c
Modified: trunk/reactos/lib/cmlib/hivecell.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/cmlib/hivecell.c?rev=3…
==============================================================================
--- trunk/reactos/lib/cmlib/hivecell.c (original)
+++ trunk/reactos/lib/cmlib/hivecell.c Tue Dec 18 13:13:45 2007
@@ -205,7 +205,7 @@
PHCELL_INDEX FreeCellData;
PHCELL_INDEX pFreeCellOffset;
HSTORAGE_TYPE Storage;
- ULONG Index;
+ ULONG Index, FreeListIndex;
ASSERT(RegistryHive->ReadOnly == FALSE);
@@ -223,6 +223,24 @@
}
pFreeCellOffset = FreeCellData;
}
+
+ /* Something bad happened, print a useful trace info and bugcheck */
+ CMLTRACE(CMLIB_HCELL_DEBUG, "-- beginning of HvpRemoveFree trace --\n");
+ CMLTRACE(CMLIB_HCELL_DEBUG, "block we are about to free: %08x\n",
CellIndex);
+ CMLTRACE(CMLIB_HCELL_DEBUG, "chosen free list index: %d\n", Index);
+ for (FreeListIndex = 0; FreeListIndex < 24; FreeListIndex++)
+ {
+ CMLTRACE(CMLIB_HCELL_DEBUG, "free list [%d]: ", FreeListIndex);
+ pFreeCellOffset =
&RegistryHive->Storage[Storage].FreeDisplay[FreeListIndex];
+ while (*pFreeCellOffset != HCELL_NIL)
+ {
+ CMLTRACE(CMLIB_HCELL_DEBUG, "%08x ", *pFreeCellOffset);
+ FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
+ pFreeCellOffset = FreeCellData;
+ }
+ CMLTRACE(CMLIB_HCELL_DEBUG, "\n");
+ }
+ CMLTRACE(CMLIB_HCELL_DEBUG, "-- end of HvpRemoveFree trace --\n");
ASSERT(FALSE);
}
@@ -466,11 +484,23 @@
{
if ((ULONG_PTR)Neighbor + Neighbor->Size == (ULONG_PTR)Free)
{
- Neighbor->Size += Free->Size;
+ 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,
- (HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
- Bin->FileOffset), FALSE);
+ HvMarkCellDirty(RegistryHive, NeighborCellIndex, FALSE);
+
return;
}
Neighbor = (PHCELL)((ULONG_PTR)Neighbor + Neighbor->Size);