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); }
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; }
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; }
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; }
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; }
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); }
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; }
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; }
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; }
VOID NtdllBitmap::ClearAllBits() { assert(RtlClearAllBits != NULL); RtlClearAllBits(this); }
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); } } }
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; }