示例#1
0
void
Test_RtlClearAllBits(void)
{
    RTL_BITMAP BitMapHeader;
    ULONG *Buffer;
    ULONG BufferSize = 2 * sizeof(*Buffer);

    Buffer = AllocateGuarded(BufferSize);
    RtlInitializeBitMap(&BitMapHeader, Buffer, 19);
    memset(Buffer, 0xcc, BufferSize);
    RtlClearAllBits(&BitMapHeader);
    ok_hex(Buffer[0], 0x00000000);
    ok_hex(Buffer[1], 0xcccccccc);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 0);
    memset(Buffer, 0xcc, BufferSize);
    RtlClearAllBits(&BitMapHeader);
    ok_hex(Buffer[0], 0xcccccccc);
    ok_hex(Buffer[1], 0xcccccccc);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 64);
    memset(Buffer, 0xcc, BufferSize);
    RtlClearAllBits(&BitMapHeader);
    ok_hex(Buffer[0], 0x00000000);
    ok_hex(Buffer[1], 0x00000000);
    FreeGuarded(Buffer);
}
示例#2
0
BOOLEAN CMAPI
HvSyncHive(
   PHHIVE RegistryHive)
{
   ASSERT(RegistryHive->ReadOnly == FALSE);

   if (RtlFindSetBits(&RegistryHive->DirtyVector, 1, 0) == ~0U)
   {
      return TRUE;
   }

   /* Update hive header modification time */
   KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);

   /* Update log file */
   if (!HvpWriteLog(RegistryHive))
   {
      return FALSE;
   }

   /* Update hive file */
   if (!HvpWriteHive(RegistryHive, TRUE))
   {
      return FALSE;
   }

   /* Clear dirty bitmap. */
   RtlClearAllBits(&RegistryHive->DirtyVector);
   RegistryHive->DirtyCount = 0;

   return TRUE;
}
示例#3
0
INIT_FUNCTION
NTSTATUS
NTAPI
InitTimerImpl(VOID)
{
   ULONG BitmapBytes;

   ExInitializeFastMutex(&Mutex);

   BitmapBytes = ROUND_UP(NUM_WINDOW_LESS_TIMERS, sizeof(ULONG) * 8) / 8;
   WindowLessTimersBitMapBuffer = ExAllocatePoolWithTag(NonPagedPool, BitmapBytes, TAG_TIMERBMP);
   if (WindowLessTimersBitMapBuffer == NULL)
   {
      return STATUS_UNSUCCESSFUL;
   }

   RtlInitializeBitMap(&WindowLessTimersBitMap,
                       WindowLessTimersBitMapBuffer,
                       BitmapBytes * 8);

   /* yes we need this, since ExAllocatePoolWithTag isn't supposed to zero out allocated memory */
   RtlClearAllBits(&WindowLessTimersBitMap);

   ExInitializeResourceLite(&TimerLock);
   InitializeListHead(&TimersListHead);

   return STATUS_SUCCESS;
}
示例#4
0
文件: ports.c 项目: GYGit/reactos
NTSTATUS PortsStartup( PPORT_SET PortSet,
		   UINT StartingPort,
		   UINT PortsToManage ) {
    PortSet->StartingPort = StartingPort;
    PortSet->PortsToOversee = PortsToManage;

    PortSet->ProtoBitBuffer =
	ExAllocatePoolWithTag( NonPagedPool, (PortSet->PortsToOversee + 7) / 8,
                               PORT_SET_TAG );
    if(!PortSet->ProtoBitBuffer) return STATUS_INSUFFICIENT_RESOURCES;
    RtlInitializeBitMap( &PortSet->ProtoBitmap,
			 PortSet->ProtoBitBuffer,
			 PortSet->PortsToOversee );
    RtlClearAllBits( &PortSet->ProtoBitmap );
    KeInitializeSpinLock( &PortSet->Lock );
    return STATUS_SUCCESS;
}
示例#5
0
文件: gdipool.c 项目: RPG-7/reactos
static
PGDI_POOL_SECTION
GdiPoolAllocateSection(PGDI_POOL pPool)
{
    PGDI_POOL_SECTION pSection;
    PVOID pvBaseAddress;
    SIZE_T cjSize;
    NTSTATUS status;

    /* Allocate a section object */
    cjSize = sizeof(GDI_POOL_SECTION) + pPool->cSlotsPerSection / sizeof(ULONG);
    pSection = EngAllocMem(0, cjSize, pPool->ulTag);
    if (!pSection)
    {
        return NULL;
    }

    /* Reserve user mode memory */
    cjSize = GDI_POOL_ALLOCATION_GRANULARITY;
    pvBaseAddress = NULL;
    status = ZwAllocateVirtualMemory(NtCurrentProcess(),
                                     &pvBaseAddress,
                                     0,
                                     &cjSize,
                                     MEM_RESERVE,
                                     PAGE_READWRITE);
    if (!NT_SUCCESS(status))
    {
        EngFreeMem(pSection);
        return NULL;
    }

    /* Initialize the section */
    pSection->pvBaseAddress = pvBaseAddress;
    pSection->ulCommitBitmap = 0;
    pSection->cAllocCount = 0;
    RtlInitializeBitMap(&pSection->bitmap,
                        pSection->aulBits,
                        pPool->cSlotsPerSection);
    RtlClearAllBits(&pSection->bitmap);

    /* Return the section */
    return pSection;
}
示例#6
0
VOID test_bitmap()
{
	Pool		pool;
	ULONG		Bitmap_Size, Index;
	PULONG		Bitmap_Buffer;

	// Initialize
	Bitmap_Size = 13; // Number of bits
	Bitmap_Buffer = ExAllocatePoolWithTag (
		NonPagedPool,
		(ULONG)(((Bitmap_Size/8+1)/sizeof(ULONG) + 1)* sizeof(ULONG)),
		BITMAP_TAG
	);
	RtlInitializeBitMap(
		&pool.Bitmap, 
		(PULONG)(Bitmap_Buffer),
		(ULONG)(Bitmap_Size)
	);
	RtlClearAllBits(&pool.Bitmap);

	for (Index = 0; Index < 10; Index++)
		RtlSetBit(&pool.Bitmap, Index);
	if (RtlAreBitsSet(&pool.Bitmap, 0, 10) == TRUE)
		DbgPrint("bitmap: bit[0..9] is set\r\n");

	if (RtlCheckBit(&pool.Bitmap, 10))
		DbgPrint("bitmap: bit[10] is set\r\n");
	if (RtlCheckBit(&pool.Bitmap, 1024)) //Warning! Return 1 here
		DbgPrint("bitmap: bit[1024] is set\r\n");

	Index = 0;
	do
	{
		Index = RtlFindClearBitsAndSet (
			&pool.Bitmap,
			1, //NumberToFind
			Index //HintIndex
		);
		DbgPrint("%d\n", Index);
	}while (Index != -1);

	// Free
	ExFreePoolWithTag(pool.Bitmap.Buffer, BITMAP_TAG);
}
示例#7
0
VOID
MiCheckPfn (
            )

/*++

Routine Description:

    This routine checks each physical page in the PFN database to ensure
    it is in the proper state.

Arguments:

    None.

Return Value:

    None.

Environment:

    Kernel mode, APCs disabled.

--*/

{
    PMMPFN Pfn1;
    PFN_NUMBER Link, Previous;
    ULONG i;
    PMMPTE PointerPte;
    KIRQL PreviousIrql;
    KIRQL OldIrql;
    USHORT ValidCheck[4];
    USHORT ValidPage[4];
    PMMPFN PfnX;

    ValidCheck[0] = ValidCheck[1] = ValidCheck[2] = ValidCheck[3] = 0;
    ValidPage[0] = ValidPage[1] = ValidPage[2] = ValidPage[3] = 0;

    if (CheckPfnBitMap == NULL) {
        MiCreateBitMap ( &CheckPfnBitMap, MmNumberOfPhysicalPages, NonPagedPool);
    }
    RtlClearAllBits (CheckPfnBitMap);

    //
    // Walk free list.
    //

    KeRaiseIrql (APC_LEVEL, &PreviousIrql);
    LOCK_PFN (OldIrql);

    Previous = MM_EMPTY_LIST;
    Link = MmFreePageListHead.Flink;
    for (i=0; i < MmFreePageListHead.Total; i++) {
        if (Link == MM_EMPTY_LIST) {
            DbgPrint("free list total count wrong\n");
            UNLOCK_PFN (OldIrql);
            KeLowerIrql (PreviousIrql);
            return;
        }
        RtlSetBits (CheckPfnBitMap, (ULONG)Link, 1L);
        Pfn1 = MI_PFN_ELEMENT(Link);
        if (Pfn1->u3.e2.ReferenceCount != 0) {
            DbgPrint("non zero reference count on free list\n");
            MiFormatPfn(Pfn1);

        }
        if (Pfn1->u3.e1.PageLocation != FreePageList) {
            DbgPrint("page location not freelist\n");
            MiFormatPfn(Pfn1);
        }
        if (Pfn1->u2.Blink != Previous) {
            DbgPrint("bad blink on free list\n");
            MiFormatPfn(Pfn1);
        }
        Previous = Link;
        Link = Pfn1->u1.Flink;

    }
    if (Link != MM_EMPTY_LIST) {
            DbgPrint("free list total count wrong\n");
            Pfn1 = MI_PFN_ELEMENT(Link);
            MiFormatPfn(Pfn1);
    }

    //
    // Walk zeroed list.
    //

    Previous = MM_EMPTY_LIST;
    Link = MmZeroedPageListHead.Flink;
    for (i=0; i < MmZeroedPageListHead.Total; i++) {
        if (Link == MM_EMPTY_LIST) {
            DbgPrint("zero list total count wrong\n");
            UNLOCK_PFN (OldIrql);
            KeLowerIrql (PreviousIrql);
            return;
        }
        RtlSetBits (CheckPfnBitMap, (ULONG)Link, 1L);
        Pfn1 = MI_PFN_ELEMENT(Link);
        if (Pfn1->u3.e2.ReferenceCount != 0) {
            DbgPrint("non zero reference count on zero list\n");
            MiFormatPfn(Pfn1);

        }
        if (Pfn1->u3.e1.PageLocation != ZeroedPageList) {
            DbgPrint("page location not zerolist\n");
            MiFormatPfn(Pfn1);
        }
        if (Pfn1->u2.Blink != Previous) {
            DbgPrint("bad blink on zero list\n");
            MiFormatPfn(Pfn1);
        }
        Previous = Link;
        Link = Pfn1->u1.Flink;

    }
    if (Link != MM_EMPTY_LIST) {
            DbgPrint("zero list total count wrong\n");
            Pfn1 = MI_PFN_ELEMENT(Link);
            MiFormatPfn(Pfn1);
    }

    //
    // Walk Bad list.
    //
    Previous = MM_EMPTY_LIST;
    Link = MmBadPageListHead.Flink;
    for (i=0; i < MmBadPageListHead.Total; i++) {
        if (Link == MM_EMPTY_LIST) {
            DbgPrint("Bad list total count wrong\n");
            UNLOCK_PFN (OldIrql);
            KeLowerIrql (PreviousIrql);
            return;
        }
        RtlSetBits (CheckPfnBitMap, (ULONG)Link, 1L);
        Pfn1 = MI_PFN_ELEMENT(Link);
        if (Pfn1->u3.e2.ReferenceCount != 0) {
            DbgPrint("non zero reference count on Bad list\n");
            MiFormatPfn(Pfn1);

        }
        if (Pfn1->u3.e1.PageLocation != BadPageList) {
            DbgPrint("page location not Badlist\n");
            MiFormatPfn(Pfn1);
        }
        if (Pfn1->u2.Blink != Previous) {
            DbgPrint("bad blink on Bad list\n");
            MiFormatPfn(Pfn1);
        }
        Previous = Link;
        Link = Pfn1->u1.Flink;

    }
    if (Link != MM_EMPTY_LIST) {
            DbgPrint("Bad list total count wrong\n");
            Pfn1 = MI_PFN_ELEMENT(Link);
            MiFormatPfn(Pfn1);
    }

    //
    // Walk Standby list.
    //

    Previous = MM_EMPTY_LIST;
    Link = MmStandbyPageListHead.Flink;
    for (i=0; i < MmStandbyPageListHead.Total; i++) {
        if (Link == MM_EMPTY_LIST) {
            DbgPrint("Standby list total count wrong\n");
            UNLOCK_PFN (OldIrql);
            KeLowerIrql (PreviousIrql);
            return;
        }
        RtlSetBits (CheckPfnBitMap, (ULONG)Link, 1L);
        Pfn1 = MI_PFN_ELEMENT(Link);
        if (Pfn1->u3.e2.ReferenceCount != 0) {
            DbgPrint("non zero reference count on Standby list\n");
            MiFormatPfn(Pfn1);

        }
        if (Pfn1->u3.e1.PageLocation != StandbyPageList) {
            DbgPrint("page location not Standbylist\n");
            MiFormatPfn(Pfn1);
        }
        if (Pfn1->u2.Blink != Previous) {
            DbgPrint("bad blink on Standby list\n");
            MiFormatPfn(Pfn1);
        }

        //
        // Check to see if referenced PTE is okay.
        //
        if (MI_IS_PFN_DELETED (Pfn1)) {
            DbgPrint("Invalid pteaddress in standby list\n");
            MiFormatPfn(Pfn1);

        } else {

            OldIrql = 99;
            if ((Pfn1->u3.e1.PrototypePte == 1) &&
                            (MmIsAddressValid (Pfn1->PteAddress))) {
                PointerPte = Pfn1->PteAddress;
            } else {
                PointerPte = MiMapPageInHyperSpace(Pfn1->PteFrame,
                                                   &OldIrql);
                PointerPte = (PMMPTE)((ULONG_PTR)PointerPte +
                                    MiGetByteOffset(Pfn1->PteAddress));
            }
            if (MI_GET_PAGE_FRAME_FROM_TRANSITION_PTE (PointerPte) != Link) {
                DbgPrint("Invalid PFN - PTE address is wrong in standby list\n");
                MiFormatPfn(Pfn1);
                MiFormatPte(PointerPte);
            }
            if (PointerPte->u.Soft.Transition == 0) {
                DbgPrint("Pte not in transition for page on standby list\n");
                MiFormatPfn(Pfn1);
                MiFormatPte(PointerPte);
            }
            if (OldIrql != 99) {
                MiUnmapPageInHyperSpace (OldIrql);
                OldIrql = 99;
            }

        }

        Previous = Link;
        Link = Pfn1->u1.Flink;

    }
    if (Link != MM_EMPTY_LIST) {
            DbgPrint("Standby list total count wrong\n");
            Pfn1 = MI_PFN_ELEMENT(Link);
            MiFormatPfn(Pfn1);
    }

    //
    // Walk Modified list.
    //

    Previous = MM_EMPTY_LIST;
    Link = MmModifiedPageListHead.Flink;
    for (i=0; i < MmModifiedPageListHead.Total; i++) {
        if (Link == MM_EMPTY_LIST) {
            DbgPrint("Modified list total count wrong\n");
            UNLOCK_PFN (OldIrql);
            KeLowerIrql (PreviousIrql);
            return;
        }
        RtlSetBits (CheckPfnBitMap, (ULONG)Link, 1L);
        Pfn1 = MI_PFN_ELEMENT(Link);
        if (Pfn1->u3.e2.ReferenceCount != 0) {
            DbgPrint("non zero reference count on Modified list\n");
            MiFormatPfn(Pfn1);

        }
        if (Pfn1->u3.e1.PageLocation != ModifiedPageList) {
            DbgPrint("page location not Modifiedlist\n");
            MiFormatPfn(Pfn1);
        }
        if (Pfn1->u2.Blink != Previous) {
            DbgPrint("bad blink on Modified list\n");
            MiFormatPfn(Pfn1);
        }
        //
        // Check to see if referenced PTE is okay.
        //
        if (MI_IS_PFN_DELETED (Pfn1)) {
            DbgPrint("Invalid pteaddress in modified list\n");
            MiFormatPfn(Pfn1);

        } else {

            if ((Pfn1->u3.e1.PrototypePte == 1) &&
                            (MmIsAddressValid (Pfn1->PteAddress))) {
                PointerPte = Pfn1->PteAddress;
            } else {
                PointerPte = MiMapPageInHyperSpace(Pfn1->PteFrame, &OldIrql);
                PointerPte = (PMMPTE)((ULONG_PTR)PointerPte +
                                    MiGetByteOffset(Pfn1->PteAddress));
            }

            if (MI_GET_PAGE_FRAME_FROM_TRANSITION_PTE (PointerPte) != Link) {
                DbgPrint("Invalid PFN - PTE address is wrong in modified list\n");
                MiFormatPfn(Pfn1);
                MiFormatPte(PointerPte);
            }
            if (PointerPte->u.Soft.Transition == 0) {
                DbgPrint("Pte not in transition for page on modified list\n");
                MiFormatPfn(Pfn1);
                MiFormatPte(PointerPte);
            }

            if (OldIrql != 99) {
                MiUnmapPageInHyperSpace (OldIrql);
                OldIrql = 99;
            }
        }

        Previous = Link;
        Link = Pfn1->u1.Flink;

    }
    if (Link != MM_EMPTY_LIST) {
            DbgPrint("Modified list total count wrong\n");
            Pfn1 = MI_PFN_ELEMENT(Link);
            MiFormatPfn(Pfn1);
    }
    //
    // All non active pages have been scanned.  Locate the
    // active pages and make sure they are consistent.
    //

    //
    // set bit zero as page zero is reserved for now
    //

    RtlSetBits (CheckPfnBitMap, 0L, 1L);

    Link = RtlFindClearBitsAndSet (CheckPfnBitMap, 1L, 0);
    while (Link != 0xFFFFFFFF) {
        Pfn1 = MI_PFN_ELEMENT (Link);

        //
        // Make sure the PTE address is okay
        //

        if ((Pfn1->PteAddress >= (PMMPTE)HYPER_SPACE)
                && (Pfn1->u3.e1.PrototypePte == 0)) {
            DbgPrint("pfn with illegal pte address\n");
            MiFormatPfn(Pfn1);
            break;
        }

        if (Pfn1->PteAddress < (PMMPTE)PTE_BASE) {
            DbgPrint("pfn with illegal pte address\n");
            MiFormatPfn(Pfn1);
            break;
        }

#if defined(_IA64_)

        //
        // ignore PTEs mapped to IA64 kernel BAT.
        //

        if (MI_IS_PHYSICAL_ADDRESS(MiGetVirtualAddressMappedByPte(Pfn1->PteAddress))) {

            goto NoCheck;
        }
#endif // _IA64_

#ifdef _ALPHA_

        //
        // ignore ptes mapped to ALPHA's 32-bit superpage.
        //

        if ((Pfn1->PteAddress > (PMMPTE)(ULONG_PTR)0xc0100000) &&
            (Pfn1->PteAddress < (PMMPTE)(ULONG_PTR)0xc0180000)) {

            goto NoCheck;
        }
#endif //ALPHA

        //
        // Check to make sure the referenced PTE is for this page.
        //

        if ((Pfn1->u3.e1.PrototypePte == 1) &&
                            (MmIsAddressValid (Pfn1->PteAddress))) {
            PointerPte = Pfn1->PteAddress;
        } else {
            PointerPte = MiMapPageInHyperSpace(Pfn1->PteFrame, &OldIrql);
            PointerPte = (PMMPTE)((ULONG_PTR)PointerPte +
                                    MiGetByteOffset(Pfn1->PteAddress));
        }

        if (MI_GET_PAGE_FRAME_FROM_PTE (PointerPte) != Link) {
            DbgPrint("Invalid PFN - PTE address is wrong in active list\n");
            MiFormatPfn(Pfn1);
            MiFormatPte(PointerPte);
        }
        if (PointerPte->u.Hard.Valid == 0) {
            //
            // if the page is a page table page it could be out of
            // the working set yet a transition page is keeping it
            // around in memory (ups the share count).
            //

            if ((Pfn1->PteAddress < (PMMPTE)PDE_BASE) ||
                (Pfn1->PteAddress > (PMMPTE)PDE_TOP)) {

                DbgPrint("Pte not valid for page on active list\n");
                MiFormatPfn(Pfn1);
                MiFormatPte(PointerPte);
            }
        }

        if (Pfn1->u3.e2.ReferenceCount != 1) {
            DbgPrint("refcount not 1\n");
            MiFormatPfn(Pfn1);
        }


        //
        // Check to make sure the PTE count for the frame is okay.
        //

        if (Pfn1->u3.e1.PrototypePte == 1) {
            PfnX = MI_PFN_ELEMENT(Pfn1->PteFrame);
            for (i = 0; i < 4; i++) {
                if (ValidPage[i] == 0) {
                    ValidPage[i] = (USHORT)Pfn1->PteFrame;
                }
                if (ValidPage[i] == (USHORT)Pfn1->PteFrame) {
                    ValidCheck[i] += 1;
                    break;
                }
            }
        }
        if (OldIrql != 99) {
            MiUnmapPageInHyperSpace (OldIrql);
            OldIrql = 99;
        }

#if defined(_ALPHA_) || defined(_IA64_)
NoCheck:
#endif
        Link = RtlFindClearBitsAndSet (CheckPfnBitMap, 1L, 0);

    }

    for (i = 0; i < 4; i++) {
        if (ValidPage[i] == 0) {
            break;
        }
        PfnX = MI_PFN_ELEMENT(ValidPage[i]);
    }

    UNLOCK_PFN (OldIrql);
    KeLowerIrql (PreviousIrql);
    return;

}
示例#8
0
NTSTATUS
HvInitializeHive(
    PHHIVE                  Hive,
    ULONG                   OperationType,
    ULONG                   HiveFlags,
    ULONG                   FileType,
    PVOID                   HiveData OPTIONAL,
    PALLOCATE_ROUTINE       AllocateRoutine,
    PFREE_ROUTINE           FreeRoutine,
    PFILE_SET_SIZE_ROUTINE  FileSetSizeRoutine,
    PFILE_WRITE_ROUTINE     FileWriteRoutine,
    PFILE_READ_ROUTINE      FileReadRoutine,
    PFILE_FLUSH_ROUTINE     FileFlushRoutine,
    ULONG                   Cluster,
    PUNICODE_STRING         FileName OPTIONAL
)
/*++

Routine Description:

    Initialize a hive.

    Core HHive fields are always initializeed.

    File calls WILL be made BEFORE this call returns.

    Caller is expected to create/open files and store file handles
    in a way that can be derived from the hive pointer.

    Three kinds of initialization can be done, selected by OperationType:

        HINIT_CREATE

            Create a new hive from scratch.  Will have 0 storage.
            [Used to do things like create HARDWARE hive and for parts
             of SaveKey and RestoreKey]


        HINIT_MEMORY_INPLACE

            Build a hive control structure which allows read only
            access to a contiguous in-memory image of a hive.
            No part of the image will be copied, but a map will
            be made.
            [Used by osloader.]


        HINIT_FLAT

            Support very limited (read-only, no checking code) operation
            against a hive image.


        HINIT_MEMORY

            Create a new hive, using a hive image already in memory,
            at address supplied by pointer HiveData.  The data will
            be copied.  Caller is expected to free HiveData.
            [Used for SYSTEM hive]


        HINIT_FILE

            Create a hive, reading its data from a file.  Recovery processing
            via log file will be done if a log is available.  If a log
            is recovered, flush and clear operation will proceed.


        HINIT_MAPFILE

            Create a hive, reading its data from a file.  Data reading is
            done by mapping views of the file in the system cache.


  NOTE:   The HHive is not a completely opaque structure, because it
            is really only used by a limited set of code.  Do not assume
            that only this routine sets all of these values.


Arguments:

    Hive - supplies a pointer to hive control structure to be initialized
            to describe this hive.

    OperationType - specifies whether to create a new hive from scratch,
            from a memory image, or by reading a file from disk.

    HiveFlags - HIVE_VOLATILE - Entire hive is to be volatile, regardless
                                   of the types of cells allocated
                HIVE_NO_LAZY_FLUSH - Data in this hive is never written
                                   to disk except by an explicit FlushKey

    FileType - HFILE_TYPE_*, HFILE_TYPE_LOG set up for logging support respectively.

    HiveData - if present, supplies a pointer to an in memory image of
            from which to init the hive.  Only useful when OperationType
            is set to HINIT_MEMORY.

    AllocateRoutine - supplies a pointer to routine called to allocate
                        memory.  WILL be called before this routine returns.

    FreeRoutine - supplies a pointer to routine called to free memory.
                   CAN be called before this routine returns.

    FileSetSizeRoutine - supplies a pointer to a routine used to set the
                         size of a file. CAN be called before this
                         routine returns.

    FileWriteRoutine - supplies a pointer to routine called to write memory
                        to a file.

    FileReadRoutine - supplies a pointer to routine called to read from
                        a file into memory. CAN be called before this
                        routine returns.

    FileFlushRoutine - supplies a pointer to routine called to flush a file.

    Cluster - clustering factor in HSECTOR_SIZE units.  (i.e.  Size of
            physical sector in media / HSECTOR_SIZE.  1 for 512 byte
            physical sectors (or smaller), 2 for 1024, 4 for 2048, etc.
            (Numbers greater than 8 won't work.)

    FileName - some path like "...\system32\config\system", last
                32 or so characters will be copied into baseblock
                (and thus to disk) as a debugging aid.  May be null.


Return Value:

    NTSTATUS code.

--*/
{
    BOOLEAN         UseForIo;
    PHBASE_BLOCK    BaseBlock = NULL;
    NTSTATUS        Status;
    ULONG           i;
    ULONG           Alignment;

    CmKdPrintEx((DPFLTR_CONFIG_ID,CML_INIT,"HvInitializeHive:\n"));
    CmKdPrintEx((DPFLTR_CONFIG_ID,CML_INIT,"\tHive=%p\n", Hive));

    //
    // reject invalid parameter combinations
    //
    if ( (! ARGUMENT_PRESENT(HiveData)) &&
            ((OperationType == HINIT_MEMORY) ||
             (OperationType == HINIT_FLAT) ||
             (OperationType == HINIT_MEMORY_INPLACE))
       )
    {
        return STATUS_INVALID_PARAMETER;
    }

    if ( ! ((OperationType == HINIT_CREATE) ||
            (OperationType == HINIT_MEMORY) ||
            (OperationType == HINIT_MEMORY_INPLACE) ||
            (OperationType == HINIT_FLAT) ||
            (OperationType == HINIT_FILE) ||
            (OperationType == HINIT_MAPFILE))
       )
    {
        return STATUS_INVALID_PARAMETER;
    }


    //
    // static and global control values
    //
    Hive->Signature = HHIVE_SIGNATURE;

    Hive->Allocate = AllocateRoutine;
    Hive->Free = FreeRoutine;
    Hive->FileSetSize = FileSetSizeRoutine;
    Hive->FileWrite = FileWriteRoutine;
    Hive->FileRead = FileReadRoutine;
    Hive->FileFlush = FileFlushRoutine;

    Hive->Log = (BOOLEAN)((FileType == HFILE_TYPE_LOG) ? TRUE : FALSE);

    if (Hive->Log  && (HiveFlags & HIVE_VOLATILE)) {
        return STATUS_INVALID_PARAMETER;
    }

    Hive->HiveFlags = HiveFlags;

    if ((Cluster == 0) || (Cluster > HSECTOR_COUNT)) {
        return STATUS_INVALID_PARAMETER;
    }
    Hive->Cluster = Cluster;

    Hive->RefreshCount = 0;

    Hive->StorageTypeCount = HTYPE_COUNT;


    Hive->Storage[Volatile].Length = 0;
    Hive->Storage[Volatile].Map = NULL;
    Hive->Storage[Volatile].SmallDir = NULL;
    Hive->Storage[Volatile].Guard = (ULONG)-1;
    Hive->Storage[Volatile].FreeSummary = 0;
    InitializeListHead(&Hive->Storage[Volatile].FreeBins);
    for (i = 0; i < HHIVE_FREE_DISPLAY_SIZE; i++) {
        RtlInitializeBitMap(&(Hive->Storage[Volatile].FreeDisplay[i].Display), NULL, 0);
        Hive->Storage[Volatile].FreeDisplay[i].RealVectorSize = 0;
    }

    Hive->Storage[Stable].Length = 0;
    Hive->Storage[Stable].Map = NULL;
    Hive->Storage[Stable].SmallDir = NULL;
    Hive->Storage[Stable].Guard = (ULONG)-1;
    Hive->Storage[Stable].FreeSummary = 0;
    InitializeListHead(&Hive->Storage[Stable].FreeBins);
    for (i = 0; i < HHIVE_FREE_DISPLAY_SIZE; i++) {
        RtlInitializeBitMap(&(Hive->Storage[Stable].FreeDisplay[i].Display), NULL, 0);
        Hive->Storage[Stable].FreeDisplay[i].RealVectorSize = 0;
    }

    RtlInitializeBitMap(&(Hive->DirtyVector), NULL, 0);
    Hive->DirtyCount = 0;
    Hive->DirtyAlloc = 0;
    Hive->DirtyFlag = FALSE;
    Hive->LogSize = 0;
    Hive->BaseBlockAlloc = sizeof(HBASE_BLOCK);

    Hive->GetCellRoutine = HvpGetCellPaged;
    Hive->ReleaseCellRoutine = NULL;
    Hive->Flat = FALSE;
    Hive->ReadOnly = FALSE;
    UseForIo = (BOOLEAN)!(Hive->HiveFlags & HIVE_VOLATILE);

    //
    // new create case
    //
    if (OperationType == HINIT_CREATE) {

        BaseBlock = (PHBASE_BLOCK)((Hive->Allocate)(Hive->BaseBlockAlloc, UseForIo,CM_FIND_LEAK_TAG11));
        if (BaseBlock == NULL) {
            return STATUS_INSUFFICIENT_RESOURCES;
        }
        //
        // Make sure the buffer we got back is cluster-aligned. If not, try
        // harder to get an aligned buffer.
        //
        Alignment = Cluster * HSECTOR_SIZE - 1;
        if (((ULONG_PTR)BaseBlock & Alignment) != 0) {
            (Hive->Free)(BaseBlock, Hive->BaseBlockAlloc);
            BaseBlock = (PHBASE_BLOCK)((Hive->Allocate)(PAGE_SIZE, TRUE,CM_FIND_LEAK_TAG12));
            if (BaseBlock == NULL) {
                return STATUS_INSUFFICIENT_RESOURCES;
            }
            Hive->BaseBlockAlloc = PAGE_SIZE;
        }

        BaseBlock->Signature = HBASE_BLOCK_SIGNATURE;
        BaseBlock->Sequence1 = 1;
        BaseBlock->Sequence2 = 1;
        BaseBlock->TimeStamp.HighPart = 0;
        BaseBlock->TimeStamp.LowPart = 0;
        BaseBlock->Major = HSYS_MAJOR;
        BaseBlock->Minor = HSYS_MINOR;
        BaseBlock->Type = HFILE_TYPE_PRIMARY;
        BaseBlock->Format = HBASE_FORMAT_MEMORY;
        BaseBlock->RootCell = HCELL_NIL;
        BaseBlock->Length = 0;
        BaseBlock->Cluster = Cluster;
        BaseBlock->CheckSum = 0;
        HvpFillFileName(BaseBlock, FileName);
        Hive->BaseBlock = BaseBlock;
        Hive->Version = HSYS_MINOR;
        Hive->BaseBlock->BootType = 0;

        return STATUS_SUCCESS;
    }

    //
    // flat image case
    //
    if (OperationType == HINIT_FLAT) {
        Hive->BaseBlock = (PHBASE_BLOCK)HiveData;
        Hive->Version = Hive->BaseBlock->Minor;
        Hive->Flat = TRUE;
        Hive->ReadOnly = TRUE;
        Hive->GetCellRoutine = HvpGetCellFlat;
        Hive->Storage[Stable].Length = Hive->BaseBlock->Length;
        Hive->StorageTypeCount = 1;
        Hive->BaseBlock->BootType = 0;

        return STATUS_SUCCESS;
    }

    //
    // readonly image case
    //
    if (OperationType == HINIT_MEMORY_INPLACE) {
        BaseBlock = (PHBASE_BLOCK)HiveData;

        if ( (BaseBlock->Signature != HBASE_BLOCK_SIGNATURE)    ||
                (BaseBlock->Type != HFILE_TYPE_PRIMARY)            ||
                (BaseBlock->Major != HSYS_MAJOR)                   ||
                (BaseBlock->Minor > HSYS_MINOR_SUPPORTED)          ||
                (BaseBlock->Format != HBASE_FORMAT_MEMORY)         ||
                (BaseBlock->Sequence1 != BaseBlock->Sequence2)     ||
                (HvpHeaderCheckSum(BaseBlock) !=
                 (BaseBlock->CheckSum))
           )
        {
            return STATUS_REGISTRY_CORRUPT;
        }

        Hive->BaseBlock = BaseBlock;
        Hive->Version = BaseBlock->Minor;
        Hive->ReadOnly = TRUE;
        Hive->StorageTypeCount = 1;
        Hive->BaseBlock->BootType = 0;
        Status = HvpAdjustHiveFreeDisplay(Hive,BaseBlock->Length,Stable);
        if( !NT_SUCCESS(Status) ) {
            return Status;
        }

        if ( !NT_SUCCESS(HvpBuildMap(
                             Hive,
                             (PUCHAR)HiveData + HBLOCK_SIZE
                         )))
        {
            return STATUS_REGISTRY_CORRUPT;
        }

        return(STATUS_SUCCESS);
    }

    //
    // memory copy case
    //
    if (OperationType == HINIT_MEMORY) {
        BaseBlock = (PHBASE_BLOCK)HiveData;

        if ( (BaseBlock->Signature != HBASE_BLOCK_SIGNATURE)    ||
                (BaseBlock->Type != HFILE_TYPE_PRIMARY)            ||
                (BaseBlock->Format != HBASE_FORMAT_MEMORY)         ||
                (BaseBlock->Major != HSYS_MAJOR)                   ||
                (BaseBlock->Minor > HSYS_MINOR_SUPPORTED)          ||
                (HvpHeaderCheckSum(BaseBlock) !=
                 (BaseBlock->CheckSum))
           )
        {
            return STATUS_REGISTRY_CORRUPT;
        }

        Hive->BaseBlock = (PHBASE_BLOCK)((Hive->Allocate)(Hive->BaseBlockAlloc, UseForIo,CM_FIND_LEAK_TAG13));
        if (Hive->BaseBlock==NULL) {
            return(STATUS_INSUFFICIENT_RESOURCES);
        }
        //
        // Make sure the buffer we got back is cluster-aligned. If not, try
        // harder to get an aligned buffer.
        //
        Alignment = Cluster * HSECTOR_SIZE - 1;
        if (((ULONG_PTR)Hive->BaseBlock & Alignment) != 0) {
            (Hive->Free)(Hive->BaseBlock, Hive->BaseBlockAlloc);
            Hive->BaseBlock = (PHBASE_BLOCK)((Hive->Allocate)(PAGE_SIZE, TRUE,CM_FIND_LEAK_TAG14));
            if (Hive->BaseBlock == NULL) {
                return (STATUS_INSUFFICIENT_RESOURCES);
            }
            Hive->BaseBlockAlloc = PAGE_SIZE;
        }
        RtlCopyMemory(Hive->BaseBlock, BaseBlock, HSECTOR_SIZE);
        Hive->BaseBlock->BootRecover = BaseBlock->BootRecover;
        Hive->BaseBlock->BootType = BaseBlock->BootType;

        Hive->Version = Hive->BaseBlock->Minor;

        Status = HvpAdjustHiveFreeDisplay(Hive,BaseBlock->Length,Stable);
        if( !NT_SUCCESS(Status) ) {
            (Hive->Free)(Hive->BaseBlock, Hive->BaseBlockAlloc);
            Hive->BaseBlock = NULL;
            return Status;
        }

        if ( !NT_SUCCESS(HvpBuildMapAndCopy(Hive,
                                            (PUCHAR)HiveData + HBLOCK_SIZE))) {

            (Hive->Free)(Hive->BaseBlock, Hive->BaseBlockAlloc);
            Hive->BaseBlock = NULL;
            return STATUS_REGISTRY_CORRUPT;
        }

        HvpFillFileName(Hive->BaseBlock, FileName);


        return(STATUS_SUCCESS);
    }

    //
    // file read case
    //
    if (OperationType == HINIT_FILE) {

        CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BIN_MAP,"HvInitializeHive(%wZ,HINIT_FILE) :\n", FileName));
        //
        // get the file image (possible recovered via log) into memory
        //
        Status = HvLoadHive(Hive);
        if ((Status != STATUS_SUCCESS) && (Status != STATUS_REGISTRY_RECOVERED)) {
            return Status;
        }

        CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BIN_MAP,"\n"));

        if (Status == STATUS_REGISTRY_RECOVERED) {

            //
            // We have a good hive, with a log, and a dirty map,
            // all set up.  Only problem is that we need to flush
            // the file so the log can be cleared and new writes
            // posted against the hive.  Since we know we have
            // a good log in hand, we just write the hive image.
            //
            if ( ! HvpDoWriteHive(Hive, HFILE_TYPE_PRIMARY)) {
                //
                // Clean up the bins already allocated
                //
                HvpFreeAllocatedBins( Hive );

                return STATUS_REGISTRY_IO_FAILED;
            }

            //
            // If we get here, we have recovered the hive, and
            // written it out to disk correctly.  So we clear
            // the log here.
            //
            RtlClearAllBits(&(Hive->DirtyVector));
            Hive->DirtyCount = 0;
            (Hive->FileSetSize)(Hive, HFILE_TYPE_LOG, 0,0);
            Hive->LogSize = 0;
        }

        //
        // slam debug name data into base block
        //
        HvpFillFileName(Hive->BaseBlock, FileName);

        return STATUS_SUCCESS;
    }

    //
    // file map case
    //
    if (OperationType == HINIT_MAPFILE) {

        Hive->GetCellRoutine = HvpGetCellMapped;
        Hive->ReleaseCellRoutine = HvpReleaseCellMapped;

        CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BIN_MAP,"HvInitializeHive(%wZ,HINIT_MAPFILE) :\n", FileName));

        Status = HvMapHive(Hive);
        if ((Status != STATUS_SUCCESS) && (Status != STATUS_REGISTRY_RECOVERED)) {
            return Status;
        }

        CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BIN_MAP,"\n"));

        if (Status == STATUS_REGISTRY_RECOVERED) {

            //
            // We have a good hive, with a log, and a dirty map,
            // all set up.  Only problem is that we need to flush
            // the file so the log can be cleared and new writes
            // posted against the hive.  Since we know we have
            // a good log in hand, we just write the hive image.
            //
            if ( ! HvpDoWriteHive(Hive, HFILE_TYPE_PRIMARY)) {
                //
                // Clean up the bins already allocated
                //
                HvpFreeAllocatedBins( Hive );

                return STATUS_REGISTRY_IO_FAILED;
            }

            //
            // If we get here, we have recovered the hive, and
            // written it out to disk correctly.  So we clear
            // the log here.
            //
            RtlClearAllBits(&(Hive->DirtyVector));
            Hive->DirtyCount = 0;
            (Hive->FileSetSize)(Hive, HFILE_TYPE_LOG, 0,0);
            Hive->LogSize = 0;
        }

        //
        // slam debug name data into base block
        //
        HvpFillFileName(Hive->BaseBlock, FileName);

        return STATUS_SUCCESS;
    }

    return STATUS_INVALID_PARAMETER;
}
示例#9
0
VOID
SpGetSupportedAdapterControlFunctions(
    PADAPTER_EXTENSION Adapter
    )
/*++

Routine Description:

    This routine will query the miniport to determine which adapter control 
    types are supported for the specified adapter.  The 
    SupportedAdapterControlBitmap in the adapter extension will be updated with
    the data returned by the miniport.  These flags are used to determine 
    what functionality (for power management and such) the miniport will support
    
Arguments:    

    Adapter - the adapter to query
    
Return Value:

    none
    
--*/        

{
    UCHAR buffer[sizeof(SCSI_SUPPORTED_CONTROL_TYPE_LIST) + 
                 (sizeof(BOOLEAN) * (ScsiAdapterControlMax + 1))];

    PSCSI_SUPPORTED_CONTROL_TYPE_LIST typeList = 
        (PSCSI_SUPPORTED_CONTROL_TYPE_LIST) &buffer;

    SCSI_ADAPTER_CONTROL_STATUS status;

    PAGED_CODE();

    RtlInitializeBitMap(&(Adapter->SupportedControlBitMap), 
                        Adapter->SupportedControlBits,
                        ScsiAdapterControlMax);

    RtlClearAllBits(&(Adapter->SupportedControlBitMap));

    if((Adapter->HwAdapterControl == NULL) || 
       (Adapter->IsPnp == FALSE))  {

        //
        // Adapter control is not supported by the miniport or the miniport 
        // isn't pnp (in which case it's not supported by scsiport) - the 
        // supported array has already been cleared so we can just quit now.
        //
        return;
    }

    RtlZeroMemory(typeList, (sizeof(SCSI_SUPPORTED_CONTROL_TYPE_LIST) + 
                             sizeof(BOOLEAN) * (ScsiAdapterControlMax + 1)));

    typeList->MaxControlType = ScsiAdapterControlMax;

#if DBG
    typeList->SupportedTypeList[ScsiAdapterControlMax] = 0x63;
#endif

    status = Adapter->HwAdapterControl(Adapter->HwDeviceExtension,
                                       ScsiQuerySupportedControlTypes,
                                       typeList);

//    ASSERT(status != ScsiAdapterControlNotSupported);

    if(status == ScsiAdapterControlSuccess) {
        ULONG i;

        ASSERT(typeList->SupportedTypeList[ScsiAdapterControlMax] == 0x63);

        for(i = 0; i < ScsiAdapterControlMax; i++) {
            if(typeList->SupportedTypeList[i] == TRUE) {
                RtlSetBits(&(Adapter->SupportedControlBitMap),
                           i,
                           1);
            }
        }
    }
    return;
}
示例#10
0
VOID NtdllBitmap::ClearAllBits()
{
	assert(RtlClearAllBits != NULL);
	RtlClearAllBits(this);
}
示例#11
0
VOID EtGpuMonitorInitialization(
    VOID
)
{
    if (PhGetIntegerSetting(SETTING_NAME_ENABLE_GPU_MONITOR))
    {
        EtpGpuAdapterList = PhCreateList(4);

        if (EtpInitializeD3DStatistics())
            EtGpuEnabled = TRUE;
    }

    if (EtGpuEnabled)
    {
        ULONG sampleCount;
        ULONG i;
        ULONG j;
        PPH_STRING bitmapString;
        D3DKMT_QUERYSTATISTICS queryStatistics;

        sampleCount = PhGetIntegerSetting(L"SampleCount");
        PhInitializeCircularBuffer_FLOAT(&EtGpuNodeHistory, sampleCount);
        PhInitializeCircularBuffer_ULONG(&EtMaxGpuNodeHistory, sampleCount);
        PhInitializeCircularBuffer_FLOAT(&EtMaxGpuNodeUsageHistory, sampleCount);
        PhInitializeCircularBuffer_ULONG(&EtGpuDedicatedHistory, sampleCount);
        PhInitializeCircularBuffer_ULONG(&EtGpuSharedHistory, sampleCount);

        EtGpuNodesTotalRunningTimeDelta = PhAllocate(sizeof(PH_UINT64_DELTA) * EtGpuTotalNodeCount);
        memset(EtGpuNodesTotalRunningTimeDelta, 0, sizeof(PH_UINT64_DELTA) * EtGpuTotalNodeCount);
        EtGpuNodesHistory = PhAllocate(sizeof(PH_CIRCULAR_BUFFER_FLOAT) * EtGpuTotalNodeCount);

        for (i = 0; i < EtGpuTotalNodeCount; i++)
        {
            PhInitializeCircularBuffer_FLOAT(&EtGpuNodesHistory[i], sampleCount);
        }

        PhRegisterCallback(
            &PhProcessesUpdatedEvent,
            EtGpuProcessesUpdatedCallback,
            NULL,
            &ProcessesUpdatedCallbackRegistration
        );

        // Load the node bitmap.

        bitmapString = PhGetStringSetting(SETTING_NAME_GPU_NODE_BITMAP);

        if (!(bitmapString->Length & 3) && bitmapString->Length / 4 <= BYTES_NEEDED_FOR_BITS(EtGpuTotalNodeCount))
        {
            PhHexStringToBuffer(&bitmapString->sr, (PUCHAR)EtGpuNodeBitMapBuffer);
            EtGpuNodeBitMapBitsSet = RtlNumberOfSetBits(&EtGpuNodeBitMap);
        }

        PhDereferenceObject(bitmapString);

        // Fix up the node bitmap if the current node count differs from what we've seen.
        if (EtGpuTotalNodeCount != PhGetIntegerSetting(SETTING_NAME_GPU_LAST_NODE_COUNT))
        {
            ULONG maxContextSwitch = 0;
            ULONG maxContextSwitchNodeIndex = 0;

            RtlClearAllBits(&EtGpuNodeBitMap);
            EtGpuNodeBitMapBitsSet = 0;

            for (i = 0; i < EtpGpuAdapterList->Count; i++)
            {
                PETP_GPU_ADAPTER gpuAdapter = EtpGpuAdapterList->Items[i];

                for (j = 0; j < gpuAdapter->NodeCount; j++)
                {
                    memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS));
                    queryStatistics.Type = D3DKMT_QUERYSTATISTICS_NODE;
                    queryStatistics.AdapterLuid = gpuAdapter->AdapterLuid;
                    queryStatistics.QueryNode.NodeId = j;

                    if (NT_SUCCESS(D3DKMTQueryStatistics(&queryStatistics)))
                    {
                        // The numbers below are quite arbitrary.
                        if (queryStatistics.QueryResult.NodeInformation.GlobalInformation.RunningTime.QuadPart != 0 &&
                                queryStatistics.QueryResult.NodeInformation.GlobalInformation.ContextSwitch > 10000)
                        {
                            RtlSetBits(&EtGpuNodeBitMap, gpuAdapter->FirstNodeIndex + j, 1);
                            EtGpuNodeBitMapBitsSet++;
                        }

                        if (maxContextSwitch < queryStatistics.QueryResult.NodeInformation.GlobalInformation.ContextSwitch)
                        {
                            maxContextSwitch = queryStatistics.QueryResult.NodeInformation.GlobalInformation.ContextSwitch;
                            maxContextSwitchNodeIndex = gpuAdapter->FirstNodeIndex + j;
                        }
                    }
                }
            }

            // Just in case
            if (EtGpuNodeBitMapBitsSet == 0)
            {
                RtlSetBits(&EtGpuNodeBitMap, maxContextSwitchNodeIndex, 1);
                EtGpuNodeBitMapBitsSet = 1;
            }

            PhSetIntegerSetting(SETTING_NAME_GPU_LAST_NODE_COUNT, EtGpuTotalNodeCount);
        }
    }
}
示例#12
0
NTSTATUS CMAPI
HvpInitializeMemoryHive(
   PHHIVE Hive,
   PVOID ChunkBase)
{
   SIZE_T BlockIndex;
   PHBIN Bin, NewBin;
   ULONG i;
   ULONG BitmapSize;
   PULONG BitmapBuffer;
   SIZE_T ChunkSize;

   ChunkSize = ((PHBASE_BLOCK)ChunkBase)->Length;
   DPRINT("ChunkSize: %lx\n", ChunkSize);

   if (ChunkSize < sizeof(HBASE_BLOCK) ||
       !HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase))
   {
      DPRINT1("Registry is corrupt: ChunkSize %lu < sizeof(HBASE_BLOCK) %lu, "
          "or HvpVerifyHiveHeader() failed\n", ChunkSize, (SIZE_T)sizeof(HBASE_BLOCK));
      return STATUS_REGISTRY_CORRUPT;
   }

   Hive->BaseBlock = Hive->Allocate(sizeof(HBASE_BLOCK), FALSE, TAG_CM);
   if (Hive->BaseBlock == NULL)
   {
      return STATUS_NO_MEMORY;
   }
   RtlCopyMemory(Hive->BaseBlock, ChunkBase, sizeof(HBASE_BLOCK));

   /*
    * Build a block list from the in-memory chunk and copy the data as
    * we go.
    */

   Hive->Storage[Stable].Length = (ULONG)(ChunkSize / HV_BLOCK_SIZE);
   Hive->Storage[Stable].BlockList =
      Hive->Allocate(Hive->Storage[Stable].Length *
                     sizeof(HMAP_ENTRY), FALSE, TAG_CM);
   if (Hive->Storage[Stable].BlockList == NULL)
   {
      DPRINT1("Allocating block list failed\n");
      Hive->Free(Hive->BaseBlock, 0);
      return STATUS_NO_MEMORY;
   }

   for (BlockIndex = 0; BlockIndex < Hive->Storage[Stable].Length; )
   {
      Bin = (PHBIN)((ULONG_PTR)ChunkBase + (BlockIndex + 1) * HV_BLOCK_SIZE);
      if (Bin->Signature != HV_BIN_SIGNATURE ||
          (Bin->Size % HV_BLOCK_SIZE) != 0)
      {
         DPRINT1("Invalid bin at BlockIndex %lu, Signature 0x%x, Size 0x%x\n",
                 (unsigned long)BlockIndex, (unsigned)Bin->Signature, (unsigned)Bin->Size);
         Hive->Free(Hive->BaseBlock, 0);
         Hive->Free(Hive->Storage[Stable].BlockList, 0);
         return STATUS_REGISTRY_CORRUPT;
      }

      NewBin = Hive->Allocate(Bin->Size, TRUE, TAG_CM);
      if (NewBin == NULL)
      {
         Hive->Free(Hive->BaseBlock, 0);
         Hive->Free(Hive->Storage[Stable].BlockList, 0);
         return STATUS_NO_MEMORY;
      }

      Hive->Storage[Stable].BlockList[BlockIndex].BinAddress = (ULONG_PTR)NewBin;
      Hive->Storage[Stable].BlockList[BlockIndex].BlockAddress = (ULONG_PTR)NewBin;

      RtlCopyMemory(NewBin, Bin, Bin->Size);

      if (Bin->Size > HV_BLOCK_SIZE)
      {
         for (i = 1; i < Bin->Size / HV_BLOCK_SIZE; i++)
         {
            Hive->Storage[Stable].BlockList[BlockIndex + i].BinAddress = (ULONG_PTR)NewBin;
            Hive->Storage[Stable].BlockList[BlockIndex + i].BlockAddress =
               ((ULONG_PTR)NewBin + (i * HV_BLOCK_SIZE));
         }
      }

      BlockIndex += Bin->Size / HV_BLOCK_SIZE;
   }

   if (HvpCreateHiveFreeCellList(Hive))
   {
      HvpFreeHiveBins(Hive);
      Hive->Free(Hive->BaseBlock, 0);
      return STATUS_NO_MEMORY;
   }

   BitmapSize = ROUND_UP(Hive->Storage[Stable].Length,
                         sizeof(ULONG) * 8) / 8;
   BitmapBuffer = (PULONG)Hive->Allocate(BitmapSize, TRUE, TAG_CM);
   if (BitmapBuffer == NULL)
   {
      HvpFreeHiveBins(Hive);
      Hive->Free(Hive->BaseBlock, 0);
      return STATUS_NO_MEMORY;
   }

   RtlInitializeBitMap(&Hive->DirtyVector, BitmapBuffer, BitmapSize * 8);
   RtlClearAllBits(&Hive->DirtyVector);

   return STATUS_SUCCESS;
}