Exemple #1
0
VOID
HvFreeHivePartial(
    PHHIVE      Hive,
    HCELL_INDEX Start,
    HSTORAGE_TYPE Type
    )
/*++

Routine Description:

    Free the memory and associated maps for the end of a hive
    starting at Start.  The baseblock, hive, etc will not be touched.

Arguments:

    Hive - supplies a pointer to hive control structure for hive to
            partially free.

    Start - HCELL_INDEX of first bin to free, will free from this
            bin (inclusive) to the end of the hives stable storage.

    Type - Type of storage (Stable or Volatile) to be freed.

Return Value:

    NONE.

--*/
{
    PHMAP_DIRECTORY Dir;
    PHMAP_ENTRY     Me;
    HCELL_INDEX     Address;
    ULONG           StartTable;
    ULONG           Length;
    PHBIN           Bin;
    ULONG           Tables;
    ULONG           FirstBit;
    ULONG           LastBit;
    PFREE_HBIN      FreeBin;

    ASSERT(Hive->Flat == FALSE);
    ASSERT(Hive->ReadOnly == FALSE);

    Address = Start;
    Length = Hive->Storage[Type].Length;
    ASSERT(Address <= Length);

    if (Address == Length) {
        return;
    }

    //
    // Sweep through bin set
    //
    do {
        Me = HvpGetCellMap(Hive, Address + (Type*HCELL_TYPE_MASK));
        VALIDATE_CELL_MAP(__LINE__,Me,Hive,Address + (Type*HCELL_TYPE_MASK));
        if (Me->BinAddress & HMAP_DISCARDABLE) {
            FreeBin = (PFREE_HBIN)Me->BlockAddress;
            if (FreeBin->Flags & FREE_HBIN_DISCARDABLE) {
                CmpFree((PVOID)HBIN_BASE(Me->BinAddress), FreeBin->Size);
            } else {
                //
                // The bin has been freed, but quota is still charged.
                // Since the file will now shrink, the quota must be
                // returned here.
                //
                if( Me->BinAddress & HMAP_INPAGEDPOOL) {
                    //
                    // we charge quota only for bins in paged-pool
                    //
                    CmpReleaseGlobalQuota(FreeBin->Size);
                }
            }
            RemoveEntryList(&FreeBin->ListEntry);
            Address += FreeBin->Size;
            CmpFree(FreeBin, sizeof(FREE_HBIN));

        } else {
            Bin = (PHBIN)HBIN_BASE(Me->BinAddress);
            Address += HvpGetBinMemAlloc(Hive,Bin,Type);
            
            if( Me->BinAddress & HMAP_INPAGEDPOOL && HvpGetBinMemAlloc(Hive,Bin,Type) ) {
                //
                // free the bin only if it is allocated from paged pool
                //
                CmpFree(Bin, HvpGetBinMemAlloc(Hive,Bin,Type));
            }
        }
    } while (Address < Length);

    //
    // Free map table storage
    //
    Tables = (((Hive->Storage[Type].Length) / HBLOCK_SIZE) - 1) / HTABLE_SLOTS;
    Dir = Hive->Storage[Type].Map;
    if (Start > 0) {
        StartTable = ((Start-1) / HBLOCK_SIZE) / HTABLE_SLOTS;
    } else {
        StartTable = (ULONG)-1;
    }
    HvpFreeMap(Hive, Dir, StartTable+1, Tables);

    //
    // update hysteresis (eventually queue work item)
    //
    if( Type == Stable) {
        CmpUpdateSystemHiveHysteresis(Hive,(Start&(~HCELL_TYPE_MASK)),Hive->Storage[Type].Length);
    }

    Hive->Storage[Type].Length = (Start&(~HCELL_TYPE_MASK));

    if (Type==Stable) {
        //
        // Clear dirty vector for data past Hive->Storage[Stable].Length
        //
        FirstBit = Start / HSECTOR_SIZE;
        LastBit = Hive->DirtyVector.SizeOfBitMap;
        ASSERT(Hive->DirtyCount == RtlNumberOfSetBits(&Hive->DirtyVector));
        RtlClearBits(&Hive->DirtyVector, FirstBit, LastBit-FirstBit);
        Hive->DirtyCount = RtlNumberOfSetBits(&Hive->DirtyVector);
    }

    HvpAdjustHiveFreeDisplay(Hive,Hive->Storage[Type].Length,Type);

    return;
}
Exemple #2
0
VOID
HvFreeHive(
    PHHIVE Hive
    )
/*++

Routine Description:

    Free all of the pieces of a hive.

Arguments:

    Hive - supplies a pointer to hive control structure for hive to free.
            this structure itself will NOT be freed, but everything it
            points to will.

Return Value:

    NONE.

--*/
{
    PHMAP_DIRECTORY Dir;
    PHMAP_ENTRY     Me;
    HCELL_INDEX     Address;
    ULONG           Type;
    ULONG           Length;
    PHBIN           Bin;
    ULONG           Tables;
    PFREE_HBIN      FreeBin;

    ASSERT(Hive->Flat == FALSE);
    ASSERT(Hive->ReadOnly == FALSE);
    ASSERT(Stable == 0);
    ASSERT(Volatile == 1);

    CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BIN_MAP,"HvFreeHive(%ws) :\n", Hive->BaseBlock->FileName));
    //
    // Iterate through both types of storage
    //
    for (Type = 0; Type <= Volatile; Type++) {

        Address = HCELL_TYPE_MASK * Type;
        Length = Hive->Storage[Type].Length + (HCELL_TYPE_MASK * Type);

        if( Hive->Storage[Type].Map && (Length > (HCELL_TYPE_MASK * Type)) ) {

            //
            // Sweep through bin set
            //
            do {
                Me = HvpGetCellMap(Hive, Address);
                VALIDATE_CELL_MAP(__LINE__,Me,Hive,Address);
                    if (Me->BinAddress & HMAP_DISCARDABLE) {
                        //
                        // hbin is either discarded or discardable, check the tombstone
                        //
                        FreeBin = (PFREE_HBIN)Me->BlockAddress;
                        Address += FreeBin->Size;
                        if (FreeBin->Flags & FREE_HBIN_DISCARDABLE) {
                            CmpFree((PHBIN)HBIN_BASE(Me->BinAddress), FreeBin->Size);
                        } else if(Me->BinAddress & HMAP_INPAGEDPOOL) {
                            //
                            // The bin has been freed, but quota is still charged.
                            // Since the hive is being freed, the quota must be
                            // returned here.
                            //
                            CmpReleaseGlobalQuota(FreeBin->Size);
                        }

                        CmpFree(FreeBin, sizeof(FREE_HBIN));
                    } else {
                        if( Me->BinAddress & HMAP_INPAGEDPOOL ) {
                            ASSERT( Me->BinAddress & HMAP_INPAGEDPOOL );

                            Bin = (PHBIN)HBIN_BASE(Me->BinAddress);
                            Address += HvpGetBinMemAlloc(Hive,Bin,Type);
#if DBG
                            if( Type == Stable ) {
                                CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BIN_MAP,"HvFreeHive: BinAddress = 0x%p\t Size = 0x%lx\n", Bin, HvpGetBinMemAlloc(Hive,Bin,Type)));
                            }
#endif

                            //
                            // free the actual bin only if it is allocated from paged pool
                            //
                            if(HvpGetBinMemAlloc(Hive,Bin,Type)) {
                                CmpFree(Bin, HvpGetBinMemAlloc(Hive,Bin,Type));
                            }
                        } else {
                            //
                            // bin was mapped into view; advance carefully
                            //
                            Address += HBLOCK_SIZE;
                        }

                    }
            } while (Address < Length);

            //
            // Free map table storage
            //
            ASSERT(Hive->Storage[Type].Length != (HCELL_TYPE_MASK * Type));
            Tables = (((Hive->Storage[Type].Length) / HBLOCK_SIZE)-1) / HTABLE_SLOTS;
            Dir = Hive->Storage[Type].Map;
            HvpFreeMap(Hive, Dir, 0, Tables);

            if (Tables > 0) {
                CmpFree(Hive->Storage[Type].Map, sizeof(HMAP_DIRECTORY));  // free dir if it exists
            }
        }
        Hive->Storage[Type].Length = 0;
    }

    CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BIN_MAP,"\n"));
    //
    // Free the base block
    //
    (Hive->Free)(Hive->BaseBlock,Hive->BaseBlockAlloc);
    Hive->BaseBlock = NULL;
    
    //
    // Free the dirty vector
    //
    if (Hive->DirtyVector.Buffer != NULL) {
        CmpFree((PVOID)(Hive->DirtyVector.Buffer), Hive->DirtyAlloc);
    }

    HvpFreeHiveFreeDisplay(Hive);
    LogHiveFree(Hive);
    return;
}
Exemple #3
0
ULONG
HvCheckHive(
    PHHIVE  Hive,
    PULONG  Storage OPTIONAL
    )
/*++

Routine Description:

    Check the consistency of a hive.  Apply CheckBin to bins, make sure
    all pointers in the cell map point to correct places.

Arguments:

    Hive - supplies a pointer to the hive control structure for the
            hive of interest.

    Storage - supplies adddress of ULONG to receive size of allocated user data

Return Value:

    0 if Hive is OK.  Error return indicator if not.  Error value
    comes from one of the check procedures.

    RANGE:  2000 - 2999

--*/
{
    HCELL_INDEX p;
    ULONG       Length;
    ULONG       localstorage = 0;
    PHMAP_ENTRY t;
    PHBIN       Bin;
    ULONG   i;
    ULONG   rc;
    PFREE_HBIN  FreeBin;

    HvCheckHiveDebug.Hive = Hive;
    HvCheckHiveDebug.Status = 0;
    HvCheckHiveDebug.Space = (ULONG)-1;
    HvCheckHiveDebug.MapPoint = HCELL_NIL;
    HvCheckHiveDebug.BinPoint = 0;

    p = 0;


    //
    // one pass for Stable space, one pass for Volatile
    //
    for (i = 0; i <= Volatile; i++) {
        Length = Hive->Storage[i].Length;

        //
        // for each bin in the space
        //
        while (p < Length) {
            t = HvpGetCellMap(Hive, p);
            if (t == NULL) {
                KdPrint(("HvCheckHive:"));
                KdPrint(("\tBin@:%08lx invalid\n", Bin));
                HvCheckHiveDebug.Status = 2005;
                HvCheckHiveDebug.Space = i;
                HvCheckHiveDebug.MapPoint = p;
                return 2005;
            }


            if ((t->BinAddress & HMAP_DISCARDABLE) == 0) {

                Bin = (PHBIN)((t->BinAddress) & HMAP_BASE);

                //
                // bin header valid?
                //
                if ( (Bin->Size > Length)                           ||
                     (Bin->Signature != HBIN_SIGNATURE)             ||
                     (Bin->FileOffset != p)
                   )
                {
                    KdPrint(("HvCheckHive:"));
                    KdPrint(("\tBin@:%08lx invalid\n", Bin));
                    HvCheckHiveDebug.Status = 2010;
                    HvCheckHiveDebug.Space = i;
                    HvCheckHiveDebug.MapPoint = p;
                    HvCheckHiveDebug.BinPoint = Bin;
                    return 2010;
                }

                //
                // structure inside the bin valid?
                //
                rc = HvCheckBin(Hive, Bin, &localstorage);
                if (rc != 0) {
                    HvCheckHiveDebug.Status = rc;
                    HvCheckHiveDebug.Space = i;
                    HvCheckHiveDebug.MapPoint = p;
                    HvCheckHiveDebug.BinPoint = Bin;
                    return rc;
                }

                p = (ULONG)p + Bin->Size;

            } else {
                //
                // Bin is not present, skip it and advance to the next one.
                //
                FreeBin = (PFREE_HBIN)t->BlockAddress;
                p+=FreeBin->Size;
            }
        }

        p = 0x80000000;     // Beginning of Volatile space
    }

    if (ARGUMENT_PRESENT(Storage)) {
        *Storage = localstorage;
    }
    return 0;
}