NTSTATUS BiInitializeAndValidateHive ( _In_ PBI_KEY_HIVE Hive ) { ULONG HiveSize; NTSTATUS Status; /* Make sure the hive is at least the size of a base block */ if (Hive->HiveSize < sizeof(HBASE_BLOCK)) { return STATUS_REGISTRY_CORRUPT; } /* Make sure that the base block accurately describes the size of the hive */ HiveSize = Hive->BaseBlock->Length + sizeof(HBASE_BLOCK); if ((HiveSize < sizeof(HBASE_BLOCK)) || (HiveSize > Hive->HiveSize)) { return STATUS_REGISTRY_CORRUPT; } /* Initialize a flat memory hive */ RtlZeroMemory(&Hive->Hive, sizeof(Hive->Hive)); Status = HvInitialize(&Hive->Hive.Hive, HINIT_FLAT, 0, 0, Hive->BaseBlock, CmpAllocate, CmpFree, NULL, NULL, NULL, NULL, 0, NULL); if (NT_SUCCESS(Status)) { /* Cleanup volatile/old data */ CmPrepareHive(&Hive->Hive.Hive); // CmCheckRegistry Status = STATUS_SUCCESS; } /* Return the final status */ return Status; }
NTSTATUS CMAPI HvInitialize( PHHIVE RegistryHive, ULONG Operation, ULONG HiveType, ULONG HiveFlags, PVOID HiveData OPTIONAL, PALLOCATE_ROUTINE Allocate, PFREE_ROUTINE Free, PFILE_SET_SIZE_ROUTINE FileSetSize, PFILE_WRITE_ROUTINE FileWrite, PFILE_READ_ROUTINE FileRead, PFILE_FLUSH_ROUTINE FileFlush, ULONG Cluster OPTIONAL, PCUNICODE_STRING FileName OPTIONAL) { NTSTATUS Status; PHHIVE Hive = RegistryHive; UNREFERENCED_PARAMETER(HiveType); /* * Create a new hive structure that will hold all the maintenance data. */ RtlZeroMemory(Hive, sizeof(HHIVE)); Hive->Allocate = Allocate; Hive->Free = Free; Hive->FileRead = FileRead; Hive->FileWrite = FileWrite; Hive->FileSetSize = FileSetSize; Hive->FileFlush = FileFlush; Hive->StorageTypeCount = HTYPE_COUNT; Hive->Cluster = 1; Hive->Version = HSYS_MINOR; Hive->HiveFlags = HiveFlags &~ HIVE_NOLAZYFLUSH; switch (Operation) { case HINIT_CREATE: Status = HvpCreateHive(Hive, FileName); break; case HINIT_MEMORY: Status = HvpInitializeMemoryHive(Hive, HiveData); break; case HINIT_FLAT: Status = HvpInitializeMemoryInplaceHive(Hive, HiveData); break; case HINIT_FILE: { /* HACK of doom: Cluster is actually the file size. */ Status = HvLoadHive(Hive, Cluster); if ((Status != STATUS_SUCCESS) && (Status != STATUS_REGISTRY_RECOVERED)) { /* Unrecoverable failure */ return Status; } /* Check for previous damage */ ASSERT(Status != STATUS_REGISTRY_RECOVERED); break; } default: /* FIXME: A better return status value is needed */ Status = STATUS_NOT_IMPLEMENTED; ASSERT(FALSE); } if (!NT_SUCCESS(Status)) return Status; if (Operation != HINIT_CREATE) CmPrepareHive(Hive); return Status; }