Skip to content

Commit

Permalink
[NTOS:CM] Flush the dirty data to disk if the SYSTEM hive has been re…
Browse files Browse the repository at this point in the history
…covered by FreeLdr

If FreeLdr performed recovery against the SYSTEM hive with a log, all of its data is only present in volatile memory thus dirty. So the kernel is responsible to flush all the data that's been recovered within the SYSTEM hive into the backing storage.
  • Loading branch information
GeoB99 committed Oct 28, 2023
1 parent 1bf10c3 commit f07a854
Showing 1 changed file with 26 additions and 18 deletions.
44 changes: 26 additions & 18 deletions ntoskrnl/config/cmsysini.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit f07a854

Please sign in to comment.