[SDK][CMLIB] Implement CmCheckRegistry and validation private helpers

CmCheckRegistry is a function that provides the necessary validation checks for a registry hive. This function usually comes into action when logs have been replayed for example, or when a registry hive internals have changed such as when saving a key, loading a key, etc.

This commit implements the whole Check Registry infrastructure (cmcheck.c) in CMLIB library for ease of usage and wide accessibility across parts of the OS. In addition, two more functions for registry checks are also implemented -- HvValidateHive and HvValidateBin.

Instead of having the CmCheckRegistry implementation in the kernel, it's better to have it in the Configuration Manager library instead (aka CMLIB). The benefits of having it in the library are the following:

- CmCheckRegistry can be used in FreeLdr to fix the SYSTEM hive
- It can be used on-demand in the kernel
- It can be used for offline registry repair tools
- It makes the underlying CmCheckRegistry implementation code debug-able in user mode

CORE-9195
CORE-6762
This commit is contained in:
George Bișoc 2022-10-26 19:41:59 +02:00
parent 54c552392f
commit f33da480af
No known key found for this signature in database
GPG key ID: 688C4FBE25D7DEF6
6 changed files with 1807 additions and 42 deletions

View file

@ -1,27 +0,0 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmcheck.c
* PURPOSE: Configuration Manager - Hive and Key Validation
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
ULONG
NTAPI
CmCheckRegistry(IN PCMHIVE RegistryHive,
IN ULONG Flags)
{
/* FIXME: HACK! */
DPRINT1("CmCheckRegistry(0x%p, %lu) is UNIMPLEMENTED!\n", RegistryHive, Flags);
return 0;
}

View file

@ -595,16 +595,6 @@ CmpCompareNewValueDataAgainstKCBCache(
IN ULONG DataSize
);
//
// Registry Validation Functions
//
ULONG
NTAPI
CmCheckRegistry(
IN PCMHIVE Hive,
IN ULONG Flags
);
//
// Hive List Routines
//

View file

@ -48,7 +48,6 @@ list(APPEND SOURCE
${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmalloc.c
${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmapi.c
${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmboot.c
${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmcheck.c
${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmconfig.c
${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmcontrl.c
${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmdata.c

View file

@ -4,6 +4,7 @@ add_definitions(
-DNASSERT)
list(APPEND SOURCE
cmcheck.c
cminit.c
cmheal.c
cmindex.c

1718
sdk/lib/cmlib/cmcheck.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -205,13 +205,77 @@
#endif
#endif
#define TAG_CM ' MC'
#define TAG_KCB 'bkMC'
#define TAG_CMHIVE 'vHMC'
#define TAG_CMSD 'DSMC'
#define TAG_CM ' MC'
#define TAG_KCB 'bkMC'
#define TAG_CMHIVE 'vHMC'
#define TAG_CMSD 'DSMC'
#define TAG_REGISTRY_STACK 'sRMC'
#define CMAPI NTAPI
//
// Check Registry status type definition
//
typedef ULONG CM_CHECK_REGISTRY_STATUS;
//
// Check Registry flags
//
#define CM_CHECK_REGISTRY_DONT_PURGE_VOLATILES 0x0
#define CM_CHECK_REGISTRY_PURGE_VOLATILES 0x2
#define CM_CHECK_REGISTRY_BOOTLOADER_PURGE_VOLATILES 0x4
#define CM_CHECK_REGISTRY_VALIDATE_HIVE 0x8
#define CM_CHECK_REGISTRY_FIX_HIVE 0x10
//
// Check Registry status codes
//
#define CM_CHECK_REGISTRY_GOOD 0
#define CM_CHECK_REGISTRY_INVALID_PARAMETER 1
#define CM_CHECK_REGISTRY_SD_INVALID 2
#define CM_CHECK_REGISTRY_HIVE_CORRUPT_SIGNATURE 3
#define CM_CHECK_REGISTRY_BIN_SIZE_OR_OFFSET_CORRUPT 4
#define CM_CHECK_REGISTRY_BIN_SIGNATURE_HEADER_CORRUPT 5
#define CM_CHECK_REGISTRY_BAD_FREE_CELL 6
#define CM_CHECK_REGISTRY_BAD_ALLOC_CELL 7
#define CM_CHECK_REGISTRY_ALLOCATE_MEM_STACK_FAIL 8
#define CM_CHECK_REGISTRY_ROOT_CELL_NOT_FOUND 9
#define CM_CHECK_REGISTRY_BAD_LEXICOGRAPHICAL_ORDER 10
#define CM_CHECK_REGISTRY_NODE_NOT_FOUND 11
#define CM_CHECK_REGISTRY_SUBKEY_NOT_FOUND 12
#define CM_CHECK_REGISTRY_TREE_TOO_MANY_LEVELS 13
#define CM_CHECK_REGISTRY_KEY_CELL_NOT_ALLOCATED 14
#define CM_CHECK_REGISTRY_CELL_DATA_NOT_FOUND 15
#define CM_CHECK_REGISTRY_CELL_SIZE_NOT_SANE 16
#define CM_CHECK_REGISTRY_KEY_NAME_LENGTH_ZERO 17
#define CM_CHECK_REGISTRY_KEY_TOO_BIG_THAN_CELL 18
#define CM_CHECK_REGISTRY_BAD_KEY_NODE_PARENT 19
#define CM_CHECK_REGISTRY_BAD_KEY_NODE_SIGNATURE 20
#define CM_CHECK_REGISTRY_KEY_CLASS_UNALLOCATED 21
#define CM_CHECK_REGISTRY_VALUE_LIST_UNALLOCATED 22
#define CM_CHECK_REGISTRY_VALUE_LIST_DATA_NOT_FOUND 23
#define CM_CHECK_REGISTRY_VALUE_LIST_SIZE_NOT_SANE 24
#define CM_CHECK_REGISTRY_VALUE_CELL_NIL 25
#define CM_CHECK_REGISTRY_VALUE_CELL_UNALLOCATED 26
#define CM_CHECK_REGISTRY_VALUE_CELL_DATA_NOT_FOUND 27
#define CM_CHECK_REGISTRY_VALUE_CELL_SIZE_NOT_SANE 28
#define CM_CHECK_REGISTRY_CORRUPT_VALUE_DATA 29
#define CM_CHECK_REGISTRY_DATA_CELL_NOT_ALLOCATED 30
#define CM_CHECK_REGISTRY_BAD_KEY_VALUE_SIGNATURE 31
#define CM_CHECK_REGISTRY_STABLE_KEYS_ON_VOLATILE 32
#define CM_CHECK_REGISTRY_SUBKEYS_LIST_UNALLOCATED 33
#define CM_CHECK_REGISTRY_CORRUPT_SUBKEYS_INDEX 34
#define CM_CHECK_REGISTRY_BAD_SUBKEY_COUNT 35
#define CM_CHECK_REGISTRY_KEY_INDEX_CELL_UNALLOCATED 36
#define CM_CHECK_REGISTRY_CORRUPT_LEAF_ON_ROOT 37
#define CM_CHECK_REGISTRY_CORRUPT_LEAF_SIGNATURE 38
#define CM_CHECK_REGISTRY_CORRUPT_KEY_INDEX_SIGNATURE 39
//
// Check Registry success macro
//
#define CM_CHECK_REGISTRY_SUCCESS(StatusCode) ((ULONG)(StatusCode) == CM_CHECK_REGISTRY_GOOD)
#include <wine/unicode.h>
#include <wchar.h>
#include "hivedata.h"
@ -570,6 +634,26 @@ CmPrepareHive(
/* NT-style Public Cm functions */
//
// Check Registry Routines
//
CM_CHECK_REGISTRY_STATUS
NTAPI
HvValidateBin(
_In_ PHHIVE Hive,
_In_ PHBIN Bin);
CM_CHECK_REGISTRY_STATUS
NTAPI
HvValidateHive(
_In_ PHHIVE Hive);
CM_CHECK_REGISTRY_STATUS
NTAPI
CmCheckRegistry(
_In_ PCMHIVE RegistryHive,
_In_ ULONG Flags);
//
// Cell Index Routines
//