36#define HCI_TO_HKEY(CellIndex) ((HKEY)(ULONG_PTR)(CellIndex))
38#define HKEY_TO_HCI(hKey) ((HCELL_INDEX)(ULONG_PTR)(hKey))
41#define GET_HHIVE(CmHive) (&((CmHive)->Hive))
42#define GET_HHIVE_FROM_HKEY(hKey) GET_HHIVE(CmSystemHive)
43#define GET_CM_KEY_NODE(hHive, hKey) ((PCM_KEY_NODE)HvGetCell(hHive, HKEY_TO_HCI(hKey)))
45#define GET_HBASE_BLOCK(ChunkBase) ((PHBASE_BLOCK)ChunkBase)
107#if !defined(_M_AMD64)
127 ERR(
"Failed to initialize the flat hive (Status 0x%lx)\n",
Status);
132#if !defined(_M_AMD64)
137 ERR(
"CmCheckRegistry detected problems with the loaded flat hive (check code %lu)\n", CmStatusCode);
146#if !defined(_M_AMD64)
195 PVOID LogDataVirtual;
196 PVOID LogDataPhysical;
206 ERR(
"Failed to open %s (ARC code %lu)\n", LogName,
Status);
214 ERR(
"Failed to get file information from %s (ARC code %lu)\n", LogName,
Status);
220 LogFileSize =
FileInfo.EndingAddress.LowPart;
221 if (LogFileSize == 0)
223 ERR(
"LogFileSize is 0, %s is corrupt\n", LogName);
230 MM_SIZE_TO_PAGES(LogFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT,
232 if (LogDataPhysical ==
NULL)
234 ERR(
"Failed to allocate memory for log data\n");
240 LogDataVirtual =
PaToVa(LogDataPhysical);
247 ERR(
"Failed to seek at %s (ARC code %lu)\n", LogName,
Status);
256 ERR(
"Failed to read %s (ARC code %lu)\n", LogName,
Status);
261 *LogData = LogDataVirtual;
306 ERR(
"Failed to read the hive log\n");
311 LogData =
VaToPa(LogData);
315 ERR(
"The hive log has corrupt base block\n");
321 WARN(
"Recovering the hive base block...\n");
369 ULONG BlockIndex, LogIndex;
370 PUCHAR BlockPtr, BlockDest;
382 ERR(
"Failed to read the hive log\n");
390 ERR(
"The hive log dirty signature could not be found\n");
399 for (; BlockIndex < StorageLength; ++BlockIndex)
470 ERR(
"Corrupted hive %p!\n", ChunkBase);
482 ERR(
"Failed to recover the hive header block\n");
488 ERR(
"Failed to recover the hive data\n");
497 ERR(
"Corrupted hive (despite recovery) %p\n", ChunkBase);
533 TRACE(
"RegInitCurrentControlSet\n");
537 LastKnownGood ?
L"LastKnownGood"
546 ERR(
"CmpFindControlSet('%wZ') failed\n", &ControlSetName);
568 if (RemainingPath->Length <
sizeof(
WCHAR))
575 NextElement->Buffer = RemainingPath->Buffer;
578 while ((RemainingPath->Length >=
sizeof(
WCHAR)) &&
579 (RemainingPath->Buffer[0] !=
'\\'))
582 RemainingPath->Buffer++;
583 RemainingPath->Length -=
sizeof(
WCHAR);
586 NextElement->Length = (
USHORT)(RemainingPath->Buffer - NextElement->Buffer) *
sizeof(
WCHAR);
587 NextElement->MaximumLength = NextElement->Length;
590 if (RemainingPath->Length >=
sizeof(
WCHAR))
593 ASSERT(RemainingPath->Buffer[0] ==
'\\');
594 RemainingPath->Buffer++;
595 RemainingPath->Length -=
sizeof(
WCHAR);
616 TRACE(
"RegEnumKey(%p, %lu, %p, %p->%u)\n",
627 TRACE(
"RegEnumKey index out of bounds (%d) in key (%.*s)\n",
658 if (*NameSize >= NameLength +
sizeof(
WCHAR))
663 *NameSize = NameLength +
sizeof(
WCHAR);
670 TRACE(
"RegEnumKey done -> %u, '%.*S'\n", *NameSize, *NameSize,
Name);
700 TRACE(
"RegOpenKey: absolute path\n");
703 RemainingPath.
Buffer[0] !=
'\\')
706 ERR(
"RegOpenKey: invalid path '%S' (%wZ)\n",
KeyName, &RemainingPath);
718 TRACE(
"RegOpenKey: %wZ / %wZ / %wZ\n", &SubKeyName1, &SubKeyName2, &SubKeyName3);
726 ERR(
"RegOpenKey: invalid path '%S' (%wZ)\n",
KeyName, &RemainingPath);
752 RemainingPath = TempPath;
761 TRACE(
"RegOpenKey: RemainingPath '%wZ'\n", &RemainingPath);
773 CellIndex = NextCellIndex;
806 *
Type = ValueCell->Type;
844 TRACE(
"RegQueryValue(%p, '%S', %p, %p, %p)\n",
857 TRACE(
"RegQueryValue value not found in key (%.*s)\n",
897 TRACE(
"RegEnumValue(%p, %lu, %S, %p, %p, %p, %p (%lu))\n",
910 ERR(
"RegEnumValue: index invalid\n");
942 if (*NameSize >= NameLength +
sizeof(
WCHAR))
947 *NameSize = NameLength +
sizeof(
WCHAR);
955 TRACE(
"RegEnumValue done -> %u, '%.*S'\n", *NameSize, *NameSize,
ValueName);
#define DBG_DEFAULT_CHANNEL(ch)
ARC_STATUS ArcClose(ULONG FileId)
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
ARC_STATUS ArcOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
FORCEINLINE VOID FrLdrHeapFree(PVOID MemoryPointer, ULONG Tag)
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
FORCEINLINE PVOID FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag)
static BOOLEAN RegRecoverHeaderHive(_Inout_ PVOID ChunkBase, _In_ PCSTR DirectoryPath, _In_ PCSTR LogName)
Recovers the header base block of a flat registry hive.
#define GET_CM_KEY_NODE(hHive, hKey)
static BOOLEAN GetNextPathElement(_Out_ PUNICODE_STRING NextElement, _Inout_ PUNICODE_STRING RemainingPath)
BOOLEAN RegInitCurrentControlSet(_In_ BOOLEAN LastKnownGood)
static VOID RepGetValueData(_In_ PHHIVE Hive, _In_ PCM_KEY_VALUE ValueCell, _Out_opt_ PULONG Type, _Out_opt_ PUCHAR Data, _Inout_opt_ PULONG DataSize)
#define GET_HBASE_BLOCK(ChunkBase)
VOID NTAPI CmpFree(IN PVOID Ptr, IN ULONG Quota)
static BOOLEAN RegLoadHiveLog(_In_ PCSTR DirectoryPath, _In_ ULONG LogFileOffset, _In_ PCSTR LogName, _Out_ PVOID *LogData)
Loads and reads a hive log at specified file offset.
#define GET_HHIVE(CmHive)
static PCMHIVE CmSystemHive
static HCELL_INDEX SystemRootCell
BOOLEAN RegImportBinaryHive(_In_ PVOID ChunkBase, _In_ ULONG ChunkSize, _In_ PCSTR SearchPath, _In_ BOOLEAN LoadAlternate)
Imports the SYSTEM binary hive from the registry base chunk that's been provided by the loader block.
HKEY CurrentControlSetKey
#define HCI_TO_HKEY(CellIndex)
PVOID NTAPI CmpAllocate(IN SIZE_T Size, IN BOOLEAN Paged, IN ULONG Tag)
static BOOLEAN RegInitializeHive(_In_ PCMHIVE CmHive, _In_ PVOID ChunkBase, _In_ BOOLEAN LoadAlternate)
Initializes a flat hive descriptor for the hive and validates the registry hive. Volatile data is pur...
#define GET_HHIVE_FROM_HKEY(hKey)
static BOOLEAN RegRecoverDataHive(_Inout_ PVOID ChunkBase, _In_ PCSTR DirectoryPath, _In_ PCSTR LogName)
Recovers the corrupt data of a primary flat registry hive.
#define HKEY_TO_HCI(hKey)
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
HCELL_INDEX NTAPI CmpFindControlSet(_In_ PHHIVE SystemHive, _In_ HCELL_INDEX RootCell, _In_ PCUNICODE_STRING SelectKeyName, _Out_ PBOOLEAN AutoSelect)
Finds the corresponding "HKLM\SYSTEM\ControlSetXXX" system control set registry key,...
CM_CHECK_REGISTRY_STATUS NTAPI CmCheckRegistry(_In_ PCMHIVE RegistryHive, _In_ ULONG Flags)
Checks the registry that is consistent and its contents valid and not corrupted. More specifically th...
struct _CELL_DATA * PCELL_DATA
struct _CM_KEY_NODE * PCM_KEY_NODE
struct _CM_KEY_VALUE * PCM_KEY_VALUE
#define CM_KEY_VALUE_SIGNATURE
#define CM_KEY_NODE_SIGNATURE
HCELL_INDEX NTAPI CmpFindSubKeyByNumber(IN PHHIVE Hive, IN PCM_KEY_NODE Node, IN ULONG Number)
HCELL_INDEX NTAPI CmpFindSubKeyByName(IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PCUNICODE_STRING SearchName)
#define HvReleaseCell(Hive, Cell)
BOOLEAN CMAPI HvpVerifyHiveHeader(_In_ PHBASE_BLOCK BaseBlock, _In_ ULONG FileType)
Validates the base block header of a registry file (hive or log).
ULONG CMAPI HvpHiveHeaderChecksum(PHBASE_BLOCK HiveHeader)
VOID NTAPI CmpCopyCompressedName(OUT PWCHAR Destination, IN ULONG DestinationLength, IN PWCHAR Source, IN ULONG SourceLength)
NTSTATUS CMAPI HvInitialize(PHHIVE RegistryHive, ULONG OperationType, ULONG HiveFlags, ULONG FileType, 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)
#define CM_CHECK_REGISTRY_VALIDATE_HIVE
HCELL_INDEX NTAPI CmpFindValueByName(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PCUNICODE_STRING Name)
PCELL_DATA NTAPI CmpValueToData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length)
#define CM_CHECK_REGISTRY_SUCCESS(StatusCode)
ULONG CM_CHECK_REGISTRY_STATUS
USHORT NTAPI CmpCompressedNameSize(IN PWCHAR Name, IN ULONG Length)
#define CM_CHECK_REGISTRY_BOOTLOADER_PURGE_VOLATILES
#define HvGetCell(Hive, Cell)
FORCEINLINE PVOID VaToPa(PVOID Va)
FORCEINLINE PVOID PaToVa(PVOID Pa)
#define NT_SUCCESS(StatCode)
#define ERROR_NO_MORE_ITEMS
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
#define HV_LOG_HEADER_SIZE
#define HFILE_TYPE_ALTERNATE
#define HFILE_TYPE_PRIMARY
#define HBOOT_BOOT_RECOVERED_BY_HIVE_LOG
#define HV_LOG_DIRTY_BLOCK
#define HBOOT_NO_BOOT_RECOVER
struct _HBASE_BLOCK * PHBASE_BLOCK
#define HV_LOG_DIRTY_SIGNATURE
#define ERROR_FILE_NOT_FOUND
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define UNREFERENCED_PARAMETER(P)
NTSTRSAFEAPI RtlStringCbCatA(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
HCELL_INDEX KeyList[ANYSIZE_ARRAY]
WCHAR Name[ANYSIZE_ARRAY]
WCHAR Name[ANYSIZE_ARRAY]
#define RTL_CONSTANT_STRING(s)
#define RtlCopyMemory(Destination, Source, Length)
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
_Must_inspect_result_ _In_opt_ WDFKEY ParentKey
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
#define ERROR_PATH_NOT_FOUND
_Inout_ PUCHAR _In_ PUCHAR _Out_ PUCHAR _Out_ PULONG ChunkSize