diff --git a/ntoskrnl/config/cmsysini.c b/ntoskrnl/config/cmsysini.c index b918790f914c2..a64906823aa68 100644 --- a/ntoskrnl/config/cmsysini.c +++ b/ntoskrnl/config/cmsysini.c @@ -1377,29 +1377,37 @@ CmpLoadHiveThread(IN PVOID StartContext) //ASSERT(FALSE); //} - /* - * Force a write of the primary or alternate hive if they are - * created for the first time, or if the alternate no longer - * matches with the primary. - */ - CmpHasAlternateHiveDiverged(&FileName, - CmHive, - AlternateHandle, - &HasAltHiveDiverged); - if (HasAltHiveDiverged || - PrimaryDisposition == FILE_CREATED || - AlternateDisposition == FILE_CREATED) + /* FreeLdr has recovered the hive with a log, we must do a flush */ + if (CmHive->Hive.BaseBlock->BootRecover == HBOOT_BOOT_RECOVERED_BY_HIVE_LOG) { - if (!HvWriteHive((PHHIVE)CmHive)) + DPRINT1("FreeLdr recovered the hive (hive 0x%p). Attempt syncing...\n", CmHive); + RtlSetAllBits(&CmHive->Hive.DirtyVector); + CmHive->Hive.DirtyCount = CmHive->Hive.DirtyVector.SizeOfBitMap; + HvSyncHive((PHHIVE)CmHive); + } + else + { + /* + * Force a write of the primary or alternate hive if they are + * created for the first time, or if the alternate no longer + * matches with the primary. + */ + CmpHasAlternateHiveDiverged(&FileName, + CmHive, + AlternateHandle, + &HasAltHiveDiverged); + if (HasAltHiveDiverged || + PrimaryDisposition == FILE_CREATED || + AlternateDisposition == FILE_CREATED) { - DPRINT1("Failed to write to hive\n"); - goto Exit; + if (!HvWriteHive((PHHIVE)CmHive)) + { + DPRINT1("Failed to write to hive\n"); + goto Exit; + } } } - /* Another thing we don't support is NTLDR-recovery */ - if (CmHive->Hive.BaseBlock->BootRecover) ASSERT(FALSE); - /* Finally, set our allocated hive to the same hive we've had */ CmpMachineHiveList[i].CmHive2 = CmHive; ASSERT(CmpMachineHiveList[i].CmHive == CmpMachineHiveList[i].CmHive2);