Author: hbelusca Date: Tue Jun 20 23:11:53 2017 New Revision: 75158
URL: http://svn.reactos.org/svn/reactos?rev=75158&view=rev Log: [CMLIB]: Implement the dynamic array of the hive cell reference tracker.
Modified: trunk/reactos/sdk/lib/cmlib/cmlib.h trunk/reactos/sdk/lib/cmlib/hivecell.c
Modified: trunk/reactos/sdk/lib/cmlib/cmlib.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/cmlib/cmlib.h?rev=7... ============================================================================== --- trunk/reactos/sdk/lib/cmlib/cmlib.h [iso-8859-1] (original) +++ trunk/reactos/sdk/lib/cmlib/cmlib.h [iso-8859-1] Tue Jun 20 23:11:53 2017 @@ -451,15 +451,15 @@ BOOLEAN CMAPI HvTrackCellRef( - PHV_TRACK_CELL_REF CellRef, - PHHIVE Hive, - HCELL_INDEX Cell + IN OUT PHV_TRACK_CELL_REF CellRef, + IN PHHIVE Hive, + IN HCELL_INDEX Cell );
VOID CMAPI HvReleaseFreeCellRefArray( - PHV_TRACK_CELL_REF CellRef + IN OUT PHV_TRACK_CELL_REF CellRef );
/*
Modified: trunk/reactos/sdk/lib/cmlib/hivecell.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/cmlib/hivecell.c?re... ============================================================================== --- trunk/reactos/sdk/lib/cmlib/hivecell.c [iso-8859-1] (original) +++ trunk/reactos/sdk/lib/cmlib/hivecell.c [iso-8859-1] Tue Jun 20 23:11:53 2017 @@ -519,54 +519,132 @@ HvMarkCellDirty(RegistryHive, CellIndex, FALSE); }
+ +#define CELL_REF_INCREMENT 10 + BOOLEAN CMAPI -HvTrackCellRef(PHV_TRACK_CELL_REF CellRef, - PHHIVE Hive, - HCELL_INDEX Cell) -{ +HvTrackCellRef( + IN OUT PHV_TRACK_CELL_REF CellRef, + IN PHHIVE Hive, + IN HCELL_INDEX Cell) +{ + PHV_HIVE_CELL_PAIR NewCellArray; + + PAGED_CODE(); + /* Sanity checks */ ASSERT(CellRef); - ASSERT(Hive ); + ASSERT(Hive); 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) { - /* Add reference */ + /* Add the reference */ CellRef->StaticArray[CellRef->StaticCount].Hive = Hive; CellRef->StaticArray[CellRef->StaticCount].Cell = Cell; CellRef->StaticCount++; return TRUE; }
- /* FIXME: TODO */ - ASSERTMSG("ERROR: Too many references\n", FALSE); - return FALSE; + DPRINT("HvTrackCellRef: Static array full, use dynamic array.\n"); + + /* 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 CMAPI -HvReleaseFreeCellRefArray(PHV_TRACK_CELL_REF CellRef) +HvReleaseFreeCellRefArray( + IN OUT PHV_TRACK_CELL_REF CellRef) { ULONG i; + + PAGED_CODE(); + ASSERT(CellRef);
- /* Any references? */ + /* Any references in the static array? */ if (CellRef->StaticCount > 0) { /* Sanity check */ ASSERT(CellRef->StaticCount <= STATIC_CELL_PAIR_COUNT);
- /* Loop them */ - for (i = 0; i < CellRef->StaticCount;i++) - { - /* Release them */ + /* Loop over them and release them */ + for (i = 0; i < CellRef->StaticCount; i++) + { HvReleaseCell(CellRef->StaticArray[i].Hive, CellRef->StaticArray[i].Cell); }
- /* Free again */ + /* We can reuse the static array */ 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; + } +}