[CMLIB]: Implement the dynamic array of the hive cell reference tracker.

svn path=/trunk/; revision=75158
This commit is contained in:
Hermès Bélusca-Maïto 2017-06-20 23:11:53 +00:00
parent 05bae83b22
commit 903ac43860
2 changed files with 97 additions and 19 deletions

View file

@ -451,15 +451,15 @@ HvWriteHive(
BOOLEAN BOOLEAN
CMAPI CMAPI
HvTrackCellRef( HvTrackCellRef(
PHV_TRACK_CELL_REF CellRef, IN OUT PHV_TRACK_CELL_REF CellRef,
PHHIVE Hive, IN PHHIVE Hive,
HCELL_INDEX Cell IN HCELL_INDEX Cell
); );
VOID VOID
CMAPI CMAPI
HvReleaseFreeCellRefArray( HvReleaseFreeCellRefArray(
PHV_TRACK_CELL_REF CellRef IN OUT PHV_TRACK_CELL_REF CellRef
); );
/* /*

View file

@ -519,54 +519,132 @@ HvFreeCell(
HvMarkCellDirty(RegistryHive, CellIndex, FALSE); HvMarkCellDirty(RegistryHive, CellIndex, FALSE);
} }
#define CELL_REF_INCREMENT 10
BOOLEAN BOOLEAN
CMAPI CMAPI
HvTrackCellRef(PHV_TRACK_CELL_REF CellRef, HvTrackCellRef(
PHHIVE Hive, IN OUT PHV_TRACK_CELL_REF CellRef,
HCELL_INDEX Cell) IN PHHIVE Hive,
IN HCELL_INDEX Cell)
{ {
PHV_HIVE_CELL_PAIR NewCellArray;
PAGED_CODE();
/* Sanity checks */ /* Sanity checks */
ASSERT(CellRef); ASSERT(CellRef);
ASSERT(Hive ); ASSERT(Hive);
ASSERT(Cell != HCELL_NIL); ASSERT(Cell != HCELL_NIL);
/* Less than 4? */ /* NOTE: The hive cell is already referenced! */
/* Less than 4? Use the static array */
if (CellRef->StaticCount < STATIC_CELL_PAIR_COUNT) if (CellRef->StaticCount < STATIC_CELL_PAIR_COUNT)
{ {
/* Add reference */ /* Add the reference */
CellRef->StaticArray[CellRef->StaticCount].Hive = Hive; CellRef->StaticArray[CellRef->StaticCount].Hive = Hive;
CellRef->StaticArray[CellRef->StaticCount].Cell = Cell; CellRef->StaticArray[CellRef->StaticCount].Cell = Cell;
CellRef->StaticCount++; CellRef->StaticCount++;
return TRUE; return TRUE;
} }
/* FIXME: TODO */ DPRINT("HvTrackCellRef: Static array full, use dynamic array.\n");
ASSERTMSG("ERROR: Too many references\n", FALSE);
return FALSE; /* Sanity checks */
if (CellRef->Max == 0)
{
/* The dynamic array must not have been allocated already */
ASSERT(CellRef->CellArray == NULL);
ASSERT(CellRef->Count == 0);
}
else
{
/* The dynamic array must be allocated */
ASSERT(CellRef->CellArray);
}
ASSERT(CellRef->Count <= CellRef->Max);
if (CellRef->Count == CellRef->Max)
{
/* Allocate a new reference table */
NewCellArray = ExAllocatePoolWithTag(PagedPool, (CellRef->Max + CELL_REF_INCREMENT) * sizeof(HV_HIVE_CELL_PAIR), TAG_CM);
if (!NewCellArray)
{
DPRINT1("HvTrackCellRef: Cannot reallocate the reference table.\n");
/* We failed, dereference the hive cell */
HvReleaseCell(Hive, Cell);
return FALSE;
}
/* Free the old reference table and use the new one */
if (CellRef->CellArray)
{
/* Copy the handles from the old table to the new one */
RtlCopyMemory(NewCellArray,
CellRef->CellArray,
CellRef->Max * sizeof(HV_HIVE_CELL_PAIR));
ExFreePoolWithTag(CellRef->CellArray, TAG_CM);
}
CellRef->CellArray = NewCellArray;
CellRef->Max += CELL_REF_INCREMENT;
}
// ASSERT(CellRef->Count < CellRef->Max);
/* Add the reference */
CellRef->CellArray[CellRef->Count].Hive = Hive;
CellRef->CellArray[CellRef->Count].Cell = Cell;
CellRef->Count++;
return TRUE;
} }
VOID VOID
CMAPI CMAPI
HvReleaseFreeCellRefArray(PHV_TRACK_CELL_REF CellRef) HvReleaseFreeCellRefArray(
IN OUT PHV_TRACK_CELL_REF CellRef)
{ {
ULONG i; ULONG i;
PAGED_CODE();
ASSERT(CellRef); ASSERT(CellRef);
/* Any references? */ /* Any references in the static array? */
if (CellRef->StaticCount > 0) if (CellRef->StaticCount > 0)
{ {
/* Sanity check */ /* Sanity check */
ASSERT(CellRef->StaticCount <= STATIC_CELL_PAIR_COUNT); ASSERT(CellRef->StaticCount <= STATIC_CELL_PAIR_COUNT);
/* Loop them */ /* Loop over them and release them */
for (i = 0; i < CellRef->StaticCount;i++) for (i = 0; i < CellRef->StaticCount; i++)
{ {
/* Release them */
HvReleaseCell(CellRef->StaticArray[i].Hive, HvReleaseCell(CellRef->StaticArray[i].Hive,
CellRef->StaticArray[i].Cell); CellRef->StaticArray[i].Cell);
} }
/* Free again */ /* We can reuse the static array */
CellRef->StaticCount = 0; CellRef->StaticCount = 0;
} }
/* Any references in the dynamic array? */
if (CellRef->Count > 0)
{
/* Sanity checks */
ASSERT(CellRef->Count <= CellRef->Max);
ASSERT(CellRef->CellArray);
/* Loop over them and release them */
for (i = 0; i < CellRef->Count; i++)
{
HvReleaseCell(CellRef->CellArray[i].Hive,
CellRef->CellArray[i].Cell);
}
/* We can reuse the dynamic array */
ExFreePoolWithTag(CellRef->CellArray, TAG_CM);
CellRef->CellArray = NULL;
CellRef->Count = CellRef->Max = 0;
}
} }