ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

hivecell.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:   registry manipulation library
00003  * LICENSE:   GPL - See COPYING in the top level directory
00004  * COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
00005  *            Copyright 2001 - 2005 Eric Kohl
00006  */
00007 
00008 #include "cmlib.h"
00009 #define NDEBUG
00010 #include <debug.h>
00011 
00012 static __inline PHCELL CMAPI
00013 HvpGetCellHeader(
00014    PHHIVE RegistryHive,
00015    HCELL_INDEX CellIndex)
00016 {
00017    PVOID Block;
00018 
00019    CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx\n",
00020        __FUNCTION__, RegistryHive, CellIndex);
00021 
00022    ASSERT(CellIndex != HCELL_NIL);
00023    if (!RegistryHive->Flat)
00024    {
00025       ULONG CellType;
00026       ULONG CellBlock;
00027       ULONG CellOffset;
00028 
00029       CellType = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
00030       CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
00031       CellOffset = (CellIndex & HCELL_OFFSET_MASK) >> HCELL_OFFSET_SHIFT;
00032       ASSERT(CellBlock < RegistryHive->Storage[CellType].Length);
00033       Block = (PVOID)RegistryHive->Storage[CellType].BlockList[CellBlock].BlockAddress;
00034       ASSERT(Block != NULL);
00035       return (PVOID)((ULONG_PTR)Block + CellOffset);
00036    }
00037    else
00038    {
00039       ASSERT((CellIndex & HCELL_TYPE_MASK) == Stable);
00040       return (PVOID)((ULONG_PTR)RegistryHive->BaseBlock + HV_BLOCK_SIZE +
00041                      CellIndex);
00042    }
00043 }
00044 
00045 BOOLEAN CMAPI
00046 HvIsCellAllocated(IN PHHIVE RegistryHive,
00047                   IN HCELL_INDEX CellIndex)
00048 {
00049    ULONG Type, Block;
00050 
00051    /* If it's a flat hive, the cell is always allocated */
00052    if (RegistryHive->Flat)
00053       return TRUE;
00054 
00055    /* Otherwise, get the type and make sure it's valid */
00056    Type = HvGetCellType(CellIndex);
00057    Block = HvGetCellBlock(CellIndex);
00058    if (Block >= RegistryHive->Storage[Type].Length)
00059       return FALSE;
00060 
00061    /* Try to get the cell block */
00062    if (RegistryHive->Storage[Type].BlockList[Block].BlockAddress)
00063       return TRUE;
00064 
00065    /* No valid block, fail */
00066    return FALSE;
00067 }
00068 
00069 PVOID CMAPI
00070 HvGetCell(
00071    PHHIVE RegistryHive,
00072    HCELL_INDEX CellIndex)
00073 {
00074    return (PVOID)(HvpGetCellHeader(RegistryHive, CellIndex) + 1);
00075 }
00076 
00077 static __inline LONG CMAPI
00078 HvpGetCellFullSize(
00079    PHHIVE RegistryHive,
00080    PVOID Cell)
00081 {
00082    UNREFERENCED_PARAMETER(RegistryHive);
00083    return ((PHCELL)Cell - 1)->Size;
00084 }
00085 
00086 LONG CMAPI
00087 HvGetCellSize(IN PHHIVE Hive,
00088               IN PVOID Address)
00089 {
00090    PHCELL CellHeader;
00091    LONG Size;
00092 
00093    UNREFERENCED_PARAMETER(Hive);
00094 
00095    CellHeader = (PHCELL)Address - 1;
00096    Size = CellHeader->Size * -1;
00097    Size -= sizeof(HCELL);
00098    return Size;
00099 }
00100 
00101 BOOLEAN CMAPI
00102 HvMarkCellDirty(
00103    PHHIVE RegistryHive,
00104    HCELL_INDEX CellIndex,
00105    BOOLEAN HoldingLock)
00106 {
00107    ULONG CellBlock;
00108    ULONG CellLastBlock;
00109 
00110    ASSERT(RegistryHive->ReadOnly == FALSE);
00111 
00112    CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx, HoldingLock %b\n",
00113        __FUNCTION__, RegistryHive, CellIndex, HoldingLock);
00114 
00115    if ((CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT != Stable)
00116       return TRUE;
00117 
00118    CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
00119    CellLastBlock = ((CellIndex + HV_BLOCK_SIZE - 1) & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
00120 
00121    RtlSetBits(&RegistryHive->DirtyVector,
00122               CellBlock, CellLastBlock - CellBlock);
00123    return TRUE;
00124 }
00125 
00126 BOOLEAN CMAPI
00127 HvIsCellDirty(IN PHHIVE Hive,
00128               IN HCELL_INDEX Cell)
00129 {
00130    BOOLEAN IsDirty = FALSE;
00131 
00132    /* Sanity checks */
00133    ASSERT(Hive->ReadOnly == FALSE);
00134 
00135    /* Volatile cells are always "dirty" */
00136    if (HvGetCellType(Cell) == Volatile)
00137       return TRUE;
00138 
00139    /* Check if the dirty bit is set */
00140    if (RtlCheckBit(&Hive->DirtyVector, Cell / HV_BLOCK_SIZE))
00141        IsDirty = TRUE;
00142 
00143    /* Return result as boolean*/
00144    return IsDirty;
00145 }
00146 
00147 static __inline ULONG CMAPI
00148 HvpComputeFreeListIndex(
00149    ULONG Size)
00150 {
00151    ULONG Index;
00152    static CCHAR FindFirstSet[256] = {
00153       0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
00154       4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00155       5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00156       5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00157       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00158       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00159       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00160       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00161       7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00162       7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00163       7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00164       7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00165       7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00166       7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00167       7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00168       7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
00169 
00170    Index = (Size >> 3) - 1;
00171    if (Index >= 16)
00172    {
00173       if (Index > 255)
00174          Index = 23;
00175       else
00176          Index = FindFirstSet[Index] + 7;
00177    }
00178 
00179    return Index;
00180 }
00181 
00182 static NTSTATUS CMAPI
00183 HvpAddFree(
00184    PHHIVE RegistryHive,
00185    PHCELL FreeBlock,
00186    HCELL_INDEX FreeIndex)
00187 {
00188    PHCELL_INDEX FreeBlockData;
00189    HSTORAGE_TYPE Storage;
00190    ULONG Index;
00191 
00192    ASSERT(RegistryHive != NULL);
00193    ASSERT(FreeBlock != NULL);
00194 
00195    Storage = (FreeIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
00196    Index = HvpComputeFreeListIndex((ULONG)FreeBlock->Size);
00197 
00198    FreeBlockData = (PHCELL_INDEX)(FreeBlock + 1);
00199    *FreeBlockData = RegistryHive->Storage[Storage].FreeDisplay[Index];
00200    RegistryHive->Storage[Storage].FreeDisplay[Index] = FreeIndex;
00201 
00202    /* FIXME: Eventually get rid of free bins. */
00203 
00204    return STATUS_SUCCESS;
00205 }
00206 
00207 static VOID CMAPI
00208 HvpRemoveFree(
00209    PHHIVE RegistryHive,
00210    PHCELL CellBlock,
00211    HCELL_INDEX CellIndex)
00212 {
00213    PHCELL_INDEX FreeCellData;
00214    PHCELL_INDEX pFreeCellOffset;
00215    HSTORAGE_TYPE Storage;
00216    ULONG Index, FreeListIndex;
00217 
00218    ASSERT(RegistryHive->ReadOnly == FALSE);
00219 
00220    Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
00221    Index = HvpComputeFreeListIndex((ULONG)CellBlock->Size);
00222 
00223    pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
00224    while (*pFreeCellOffset != HCELL_NIL)
00225    {
00226       FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
00227       if (*pFreeCellOffset == CellIndex)
00228       {
00229          *pFreeCellOffset = *FreeCellData;
00230          return;
00231       }
00232       pFreeCellOffset = FreeCellData;
00233    }
00234 
00235    /* Something bad happened, print a useful trace info and bugcheck */
00236    CMLTRACE(CMLIB_HCELL_DEBUG, "-- beginning of HvpRemoveFree trace --\n");
00237    CMLTRACE(CMLIB_HCELL_DEBUG, "block we are about to free: %08x\n", CellIndex);
00238    CMLTRACE(CMLIB_HCELL_DEBUG, "chosen free list index: %d\n", Index);
00239    for (FreeListIndex = 0; FreeListIndex < 24; FreeListIndex++)
00240    {
00241       CMLTRACE(CMLIB_HCELL_DEBUG, "free list [%d]: ", FreeListIndex);
00242       pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[FreeListIndex];
00243       while (*pFreeCellOffset != HCELL_NIL)
00244       {
00245          CMLTRACE(CMLIB_HCELL_DEBUG, "%08x ", *pFreeCellOffset);
00246          FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
00247          pFreeCellOffset = FreeCellData;
00248       }
00249       CMLTRACE(CMLIB_HCELL_DEBUG, "\n");
00250    }
00251    CMLTRACE(CMLIB_HCELL_DEBUG, "-- end of HvpRemoveFree trace --\n");
00252 
00253    ASSERT(FALSE);
00254 }
00255 
00256 static HCELL_INDEX CMAPI
00257 HvpFindFree(
00258    PHHIVE RegistryHive,
00259    ULONG Size,
00260    HSTORAGE_TYPE Storage)
00261 {
00262    PHCELL_INDEX FreeCellData;
00263    HCELL_INDEX FreeCellOffset;
00264    PHCELL_INDEX pFreeCellOffset;
00265    ULONG Index;
00266 
00267    for (Index = HvpComputeFreeListIndex(Size); Index < 24; Index++)
00268    {
00269       pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
00270       while (*pFreeCellOffset != HCELL_NIL)
00271       {
00272          FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
00273          if ((ULONG)HvpGetCellFullSize(RegistryHive, FreeCellData) >= Size)
00274          {
00275             FreeCellOffset = *pFreeCellOffset;
00276             *pFreeCellOffset = *FreeCellData;
00277             return FreeCellOffset;
00278          }
00279          pFreeCellOffset = FreeCellData;
00280       }
00281    }
00282 
00283    return HCELL_NIL;
00284 }
00285 
00286 NTSTATUS CMAPI
00287 HvpCreateHiveFreeCellList(
00288    PHHIVE Hive)
00289 {
00290    HCELL_INDEX BlockOffset;
00291    PHCELL FreeBlock;
00292    ULONG BlockIndex;
00293    ULONG FreeOffset;
00294    PHBIN Bin;
00295    NTSTATUS Status;
00296    ULONG Index;
00297 
00298    /* Initialize the free cell list */
00299    for (Index = 0; Index < 24; Index++)
00300    {
00301       Hive->Storage[Stable].FreeDisplay[Index] = HCELL_NIL;
00302       Hive->Storage[Volatile].FreeDisplay[Index] = HCELL_NIL;
00303    }
00304 
00305    BlockOffset = 0;
00306    BlockIndex = 0;
00307    while (BlockIndex < Hive->Storage[Stable].Length)
00308    {
00309       Bin = (PHBIN)Hive->Storage[Stable].BlockList[BlockIndex].BinAddress;
00310 
00311       /* Search free blocks and add to list */
00312       FreeOffset = sizeof(HBIN);
00313       while (FreeOffset < Bin->Size)
00314       {
00315          FreeBlock = (PHCELL)((ULONG_PTR)Bin + FreeOffset);
00316          if (FreeBlock->Size > 0)
00317          {
00318             Status = HvpAddFree(Hive, FreeBlock, Bin->FileOffset + FreeOffset);
00319             if (!NT_SUCCESS(Status))
00320                return Status;
00321 
00322             FreeOffset += FreeBlock->Size;
00323          }
00324          else
00325          {
00326             FreeOffset -= FreeBlock->Size;
00327          }
00328       }
00329 
00330       BlockIndex += Bin->Size / HV_BLOCK_SIZE;
00331       BlockOffset += Bin->Size;
00332    }
00333 
00334    return STATUS_SUCCESS;
00335 }
00336 
00337 HCELL_INDEX CMAPI
00338 HvAllocateCell(
00339    PHHIVE RegistryHive,
00340    ULONG Size,
00341    HSTORAGE_TYPE Storage,
00342    HCELL_INDEX Vicinity)
00343 {
00344    PHCELL FreeCell;
00345    HCELL_INDEX FreeCellOffset;
00346    PHCELL NewCell;
00347    PHBIN Bin;
00348 
00349    ASSERT(RegistryHive->ReadOnly == FALSE);
00350 
00351    CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, Size %x, %s, Vicinity %08lx\n",
00352        __FUNCTION__, RegistryHive, Size, (Storage == 0) ? "Stable" : "Volatile", Vicinity);
00353 
00354    /* Round to 16 bytes multiple. */
00355    Size = ROUND_UP(Size + sizeof(HCELL), 16);
00356 
00357    /* First search in free blocks. */
00358    FreeCellOffset = HvpFindFree(RegistryHive, Size, Storage);
00359 
00360    /* If no free cell was found we need to extend the hive file. */
00361    if (FreeCellOffset == HCELL_NIL)
00362    {
00363       Bin = HvpAddBin(RegistryHive, Size, Storage);
00364       if (Bin == NULL)
00365          return HCELL_NIL;
00366       FreeCellOffset = Bin->FileOffset + sizeof(HBIN);
00367       FreeCellOffset |= Storage << HCELL_TYPE_SHIFT;
00368    }
00369 
00370    FreeCell = HvpGetCellHeader(RegistryHive, FreeCellOffset);
00371 
00372    /* Split the block in two parts */
00373 
00374    /* The free block that is created has to be at least
00375       sizeof(HCELL) + sizeof(HCELL_INDEX) big, so that free
00376       cell list code can work. Moreover we round cell sizes
00377       to 16 bytes, so creating a smaller block would result in
00378       a cell that would never be allocated. */
00379    if ((ULONG)FreeCell->Size > Size + 16)
00380    {
00381       NewCell = (PHCELL)((ULONG_PTR)FreeCell + Size);
00382       NewCell->Size = FreeCell->Size - Size;
00383       FreeCell->Size = Size;
00384       HvpAddFree(RegistryHive, NewCell, FreeCellOffset + Size);
00385       if (Storage == Stable)
00386          HvMarkCellDirty(RegistryHive, FreeCellOffset + Size, FALSE);
00387    }
00388 
00389    if (Storage == Stable)
00390       HvMarkCellDirty(RegistryHive, FreeCellOffset, FALSE);
00391    FreeCell->Size = -FreeCell->Size;
00392    RtlZeroMemory(FreeCell + 1, Size - sizeof(HCELL));
00393 
00394    CMLTRACE(CMLIB_HCELL_DEBUG, "%s - CellIndex %08lx\n",
00395        __FUNCTION__, FreeCellOffset);
00396 
00397    return FreeCellOffset;
00398 }
00399 
00400 HCELL_INDEX CMAPI
00401 HvReallocateCell(
00402    PHHIVE RegistryHive,
00403    HCELL_INDEX CellIndex,
00404    ULONG Size)
00405 {
00406    PVOID OldCell;
00407    PVOID NewCell;
00408    LONG OldCellSize;
00409    HCELL_INDEX NewCellIndex;
00410    HSTORAGE_TYPE Storage;
00411 
00412    ASSERT(CellIndex != HCELL_NIL);
00413 
00414    CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx, Size %x\n",
00415        __FUNCTION__, RegistryHive, CellIndex, Size);
00416 
00417    Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
00418 
00419    OldCell = HvGetCell(RegistryHive, CellIndex);
00420    OldCellSize = HvGetCellSize(RegistryHive, OldCell);
00421    ASSERT(OldCellSize > 0);
00422 
00423    /*
00424     * If new data size is larger than the current, destroy current
00425     * data block and allocate a new one.
00426     *
00427     * FIXME: Merge with adjacent free cell if possible.
00428     * FIXME: Implement shrinking.
00429     */
00430    if (Size > (ULONG)OldCellSize)
00431    {
00432       NewCellIndex = HvAllocateCell(RegistryHive, Size, Storage, HCELL_NIL);
00433       if (NewCellIndex == HCELL_NIL)
00434          return HCELL_NIL;
00435 
00436       NewCell = HvGetCell(RegistryHive, NewCellIndex);
00437       RtlCopyMemory(NewCell, OldCell, (SIZE_T)OldCellSize);
00438 
00439       HvFreeCell(RegistryHive, CellIndex);
00440 
00441       return NewCellIndex;
00442    }
00443 
00444    return CellIndex;
00445 }
00446 
00447 VOID CMAPI
00448 HvFreeCell(
00449    PHHIVE RegistryHive,
00450    HCELL_INDEX CellIndex)
00451 {
00452    PHCELL Free;
00453    PHCELL Neighbor;
00454    PHBIN Bin;
00455    ULONG CellType;
00456    ULONG CellBlock;
00457 
00458    ASSERT(RegistryHive->ReadOnly == FALSE);
00459 
00460    CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx\n",
00461        __FUNCTION__, RegistryHive, CellIndex);
00462 
00463    Free = HvpGetCellHeader(RegistryHive, CellIndex);
00464 
00465    ASSERT(Free->Size < 0);
00466 
00467    Free->Size = -Free->Size;
00468 
00469    CellType = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
00470    CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
00471 
00472    /* FIXME: Merge free blocks */
00473    Bin = (PHBIN)RegistryHive->Storage[CellType].BlockList[CellBlock].BinAddress;
00474 
00475    if ((CellIndex & ~HCELL_TYPE_MASK) + Free->Size <
00476        Bin->FileOffset + Bin->Size)
00477    {
00478       Neighbor = (PHCELL)((ULONG_PTR)Free + Free->Size);
00479       if (Neighbor->Size > 0)
00480       {
00481          HvpRemoveFree(RegistryHive, Neighbor,
00482                        ((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
00483                        Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK));
00484          Free->Size += Neighbor->Size;
00485       }
00486    }
00487 
00488    Neighbor = (PHCELL)(Bin + 1);
00489    while (Neighbor < Free)
00490    {
00491       if (Neighbor->Size > 0)
00492       {
00493          if ((ULONG_PTR)Neighbor + Neighbor->Size == (ULONG_PTR)Free)
00494          {
00495             HCELL_INDEX NeighborCellIndex =
00496                (HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
00497                Bin->FileOffset) | (CellIndex & HCELL_TYPE_MASK);
00498 
00499             if (HvpComputeFreeListIndex(Neighbor->Size) !=
00500                 HvpComputeFreeListIndex(Neighbor->Size + Free->Size))
00501             {
00502                HvpRemoveFree(RegistryHive, Neighbor, NeighborCellIndex);
00503                Neighbor->Size += Free->Size;
00504                HvpAddFree(RegistryHive, Neighbor, NeighborCellIndex);
00505             }
00506             else
00507                Neighbor->Size += Free->Size;
00508 
00509             if (CellType == Stable)
00510                HvMarkCellDirty(RegistryHive, NeighborCellIndex, FALSE);
00511 
00512             return;
00513          }
00514          Neighbor = (PHCELL)((ULONG_PTR)Neighbor + Neighbor->Size);
00515       }
00516       else
00517       {
00518          Neighbor = (PHCELL)((ULONG_PTR)Neighbor - Neighbor->Size);
00519       }
00520    }
00521 
00522    /* Add block to the list of free blocks */
00523    HvpAddFree(RegistryHive, Free, CellIndex);
00524 
00525    if (CellType == Stable)
00526       HvMarkCellDirty(RegistryHive, CellIndex, FALSE);
00527 }
00528 
00529 BOOLEAN
00530 CMAPI
00531 HvTrackCellRef(PHV_TRACK_CELL_REF CellRef,
00532                PHHIVE Hive,
00533                HCELL_INDEX Cell)
00534 {
00535     /* Sanity checks */
00536     ASSERT(CellRef);
00537     ASSERT(Hive );
00538     ASSERT(Cell != HCELL_NIL);
00539 
00540     /* Less than 4? */
00541     if (CellRef->StaticCount < STATIC_CELL_PAIR_COUNT)
00542     {
00543         /* Add reference */
00544         CellRef->StaticArray[CellRef->StaticCount].Hive = Hive;
00545         CellRef->StaticArray[CellRef->StaticCount].Cell = Cell;
00546         CellRef->StaticCount++;
00547         return TRUE;
00548     }
00549 
00550     /* FIXME: TODO */
00551     DPRINT1("ERROR: Too many references\n");
00552     while (TRUE);
00553     return FALSE;
00554 }
00555 
00556 VOID
00557 CMAPI
00558 HvReleaseFreeCellRefArray(PHV_TRACK_CELL_REF CellRef)
00559 {
00560     ULONG i;
00561     ASSERT(CellRef);
00562 
00563     /* Any references? */
00564     if (CellRef->StaticCount > 0)
00565     {
00566         /* Sanity check */
00567         ASSERT(CellRef->StaticCount <= STATIC_CELL_PAIR_COUNT);
00568 
00569         /* Loop them */
00570         for (i = 0; i < CellRef->StaticCount;i++)
00571         {
00572             /* Release them */
00573             HvReleaseCell(CellRef->StaticArray[i].Hive,
00574                           CellRef->StaticArray[i].Cell);
00575         }
00576 
00577         /* Free again */
00578         CellRef->StaticCount = 0;
00579     }
00580 }

Generated on Sat May 26 2012 04:34:52 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.