https://git.reactos.org/?p=reactos.git;a=commitdiff;h=93d8a1b7b194a7a155b4a…
commit 93d8a1b7b194a7a155b4ad0205051248a94fd3a2
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Tue Mar 22 04:16:22 2022 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Apr 17 04:57:40 2022 +0200
[FREELDR:NTLDR] Adapt the registry code to access from outside the underlying HHIVE
and HCELL_INDEX (needed for cmboot).
---
boot/freeldr/freeldr/ntldr/registry.c | 97 +++++++++++++++++++++++------------
boot/freeldr/freeldr/ntldr/registry.h | 3 ++
2 files changed, 67 insertions(+), 33 deletions(-)
diff --git a/boot/freeldr/freeldr/ntldr/registry.c
b/boot/freeldr/freeldr/ntldr/registry.c
index ea68cc340dc..132309eb6d1 100644
--- a/boot/freeldr/freeldr/ntldr/registry.c
+++ b/boot/freeldr/freeldr/ntldr/registry.c
@@ -25,9 +25,15 @@
#include <debug.h>
DBG_DEFAULT_CHANNEL(REGISTRY);
-static PCMHIVE CmHive;
-static PCM_KEY_NODE RootKeyNode;
-HKEY CurrentControlSetKey;
+static PCMHIVE CmSystemHive;
+static HCELL_INDEX SystemRootCell;
+
+PHHIVE SystemHive = NULL;
+HKEY CurrentControlSetKey = NULL;
+
+#define GET_HHIVE(CmHive) (&((CmHive)->Hive))
+#define GET_HHIVE_FROM_HKEY(hKey) GET_HHIVE(CmSystemHive)
+#define GET_CM_KEY_NODE(hHive, hKey) ((PCM_KEY_NODE)HvGetCell(hHive,
(HCELL_INDEX)hKey))
PVOID
NTAPI
@@ -37,9 +43,7 @@ CmpAllocate(
IN ULONG Tag)
{
UNREFERENCED_PARAMETER(Paged);
- UNREFERENCED_PARAMETER(Tag);
-
- return FrLdrTempAlloc(Size, Tag);
+ return FrLdrHeapAlloc(Size, Tag);
}
VOID
@@ -49,7 +53,7 @@ CmpFree(
IN ULONG Quota)
{
UNREFERENCED_PARAMETER(Quota);
- FrLdrTempFree(Ptr, 0);
+ FrLdrHeapFree(Ptr, 0);
}
BOOLEAN
@@ -58,12 +62,13 @@ RegImportBinaryHive(
_In_ ULONG ChunkSize)
{
NTSTATUS Status;
+ PCM_KEY_NODE KeyNode;
TRACE("RegImportBinaryHive(%p, 0x%lx)\n", ChunkBase, ChunkSize);
/* Allocate and initialize the hive */
- CmHive = CmpAllocate(sizeof(CMHIVE), FALSE, 'eviH');
- Status = HvInitialize(&CmHive->Hive,
+ CmSystemHive = FrLdrTempAlloc(sizeof(CMHIVE), 'eviH');
+ Status = HvInitialize(GET_HHIVE(CmSystemHive),
HINIT_FLAT, // HINIT_MEMORY_INPLACE
0,
0,
@@ -79,12 +84,20 @@ RegImportBinaryHive(
if (!NT_SUCCESS(Status))
{
ERR("Corrupted hive %p!\n", ChunkBase);
- CmpFree(CmHive, 0);
+ FrLdrTempFree(CmSystemHive, 'eviH');
return FALSE;
}
/* Save the root key node */
- RootKeyNode = (PCM_KEY_NODE)HvGetCell(&CmHive->Hive,
CmHive->Hive.BaseBlock->RootCell);
+ SystemHive = GET_HHIVE(CmSystemHive);
+ SystemRootCell = SystemHive->BaseBlock->RootCell;
+ ASSERT(SystemRootCell != HCELL_NIL);
+
+ /* Verify it is accessible */
+ KeyNode = (PCM_KEY_NODE)HvGetCell(SystemHive, SystemRootCell);
+ ASSERT(KeyNode);
+ ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
+ HvReleaseCell(SystemHive, SystemRootCell);
TRACE("RegImportBinaryHive done\n");
return TRUE;
@@ -237,7 +250,7 @@ RegEnumKey(
_Inout_ PULONG NameSize,
_Out_opt_ PHKEY SubKey)
{
- PHHIVE Hive = &CmHive->Hive;
+ PHHIVE Hive = GET_HHIVE_FROM_HKEY(Key);
PCM_KEY_NODE KeyNode, SubKeyNode;
HCELL_INDEX CellIndex;
USHORT NameLength;
@@ -246,7 +259,8 @@ RegEnumKey(
Key, Index, Name, NameSize, NameSize ? *NameSize : 0);
/* Get the key node */
- KeyNode = (PCM_KEY_NODE)Key;
+ KeyNode = GET_CM_KEY_NODE(Hive, Key);
+ ASSERT(KeyNode);
ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
CellIndex = CmpFindSubKeyByNumber(Hive, KeyNode, Index);
@@ -254,8 +268,10 @@ RegEnumKey(
{
TRACE("RegEnumKey index out of bounds (%d) in key (%.*s)\n",
Index, KeyNode->NameLength, KeyNode->Name);
+ HvReleaseCell(Hive, (HCELL_INDEX)Key);
return ERROR_NO_MORE_ITEMS;
}
+ HvReleaseCell(Hive, (HCELL_INDEX)Key);
/* Get the value cell */
SubKeyNode = (PCM_KEY_NODE)HvGetCell(Hive, CellIndex);
@@ -288,12 +304,10 @@ RegEnumKey(
*NameSize = NameLength + sizeof(WCHAR);
- /**/HvReleaseCell(Hive, CellIndex);/**/
+ HvReleaseCell(Hive, CellIndex);
if (SubKey != NULL)
- *SubKey = (HKEY)SubKeyNode;
- // else
- // RegCloseKey((HKEY)SubKeyNode);
+ *SubKey = (HKEY)CellIndex;
TRACE("RegEnumKey done -> %u, '%.*S'\n", *NameSize, *NameSize,
Name);
return ERROR_SUCCESS;
@@ -307,7 +321,7 @@ RegOpenKey(
{
UNICODE_STRING RemainingPath, SubKeyName;
UNICODE_STRING CurrentControlSet =
RTL_CONSTANT_STRING(L"CurrentControlSet");
- PHHIVE Hive = &CmHive->Hive;
+ PHHIVE Hive = (ParentKey ? GET_HHIVE_FROM_HKEY(ParentKey) :
GET_HHIVE(CmSystemHive));
PCM_KEY_NODE KeyNode;
HCELL_INDEX CellIndex;
@@ -316,11 +330,8 @@ RegOpenKey(
/* Initialize the remaining path name */
RtlInitUnicodeString(&RemainingPath, KeyName);
- /* Get the parent key node */
- KeyNode = (PCM_KEY_NODE)ParentKey;
-
/* Check if we have a parent key */
- if (KeyNode == NULL)
+ if (ParentKey == NULL)
{
UNICODE_STRING SubKeyName1, SubKeyName2, SubKeyName3;
UNICODE_STRING RegistryPath = RTL_CONSTANT_STRING(L"Registry");
@@ -358,13 +369,16 @@ RegOpenKey(
}
/* Use the root key */
- KeyNode = RootKeyNode;
+ CellIndex = SystemRootCell;
+ }
+ else
+ {
+ /* Use the parent key */
+ CellIndex = (HCELL_INDEX)ParentKey;
}
-
- ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
/* Check if this is the root key */
- if (KeyNode == RootKeyNode)
+ if (CellIndex == SystemRootCell)
{
UNICODE_STRING TempPath = RemainingPath;
@@ -375,20 +389,29 @@ RegOpenKey(
if (RtlEqualUnicodeString(&SubKeyName, &CurrentControlSet, TRUE))
{
/* Use the CurrentControlSetKey and update the remaining path */
- KeyNode = (PCM_KEY_NODE)CurrentControlSetKey;
+ CellIndex = (HCELL_INDEX)CurrentControlSetKey;
RemainingPath = TempPath;
}
}
+ /* Get the key node */
+ KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, CellIndex);
+ ASSERT(KeyNode);
+ ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
+
TRACE("RegOpenKey: RemainingPath '%wZ'\n", &RemainingPath);
/* Loop while there are path elements */
while (GetNextPathElement(&SubKeyName, &RemainingPath))
{
+ HCELL_INDEX NextCellIndex;
+
TRACE("RegOpenKey: next element '%wZ'\n", &SubKeyName);
/* Get the next sub key */
- CellIndex = CmpFindSubKeyByName(Hive, KeyNode, &SubKeyName);
+ NextCellIndex = CmpFindSubKeyByName(Hive, KeyNode, &SubKeyName);
+ HvReleaseCell(Hive, CellIndex);
+ CellIndex = NextCellIndex;
if (CellIndex == HCELL_NIL)
{
WARN("Did not find sub key '%wZ' (full: %S)\n",
&SubKeyName, KeyName);
@@ -398,9 +421,11 @@ RegOpenKey(
/* Get the found key */
KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, CellIndex);
ASSERT(KeyNode);
+ ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
}
- *Key = (HKEY)KeyNode;
+ HvReleaseCell(Hive, CellIndex);
+ *Key = (HKEY)CellIndex;
TRACE("RegOpenKey done\n");
return ERROR_SUCCESS;
@@ -452,7 +477,7 @@ RegQueryValue(
_Out_opt_ PUCHAR Data,
_Inout_opt_ PULONG DataSize)
{
- PHHIVE Hive = &CmHive->Hive;
+ PHHIVE Hive = GET_HHIVE_FROM_HKEY(Key);
PCM_KEY_NODE KeyNode;
PCM_KEY_VALUE ValueCell;
HCELL_INDEX CellIndex;
@@ -462,7 +487,8 @@ RegQueryValue(
Key, ValueName, Type, Data, DataSize);
/* Get the key node */
- KeyNode = (PCM_KEY_NODE)Key;
+ KeyNode = GET_CM_KEY_NODE(Hive, Key);
+ ASSERT(KeyNode);
ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
/* Initialize value name string */
@@ -472,8 +498,10 @@ RegQueryValue(
{
TRACE("RegQueryValue value not found in key (%.*s)\n",
KeyNode->NameLength, KeyNode->Name);
+ HvReleaseCell(Hive, (HCELL_INDEX)Key);
return ERROR_FILE_NOT_FOUND;
}
+ HvReleaseCell(Hive, (HCELL_INDEX)Key);
/* Get the value cell */
ValueCell = (PCM_KEY_VALUE)HvGetCell(Hive, CellIndex);
@@ -503,7 +531,7 @@ RegEnumValue(
_Out_opt_ PUCHAR Data,
_Inout_opt_ PULONG DataSize)
{
- PHHIVE Hive = &CmHive->Hive;
+ PHHIVE Hive = GET_HHIVE_FROM_HKEY(Key);
PCM_KEY_NODE KeyNode;
PCELL_DATA ValueListCell;
PCM_KEY_VALUE ValueCell;
@@ -513,7 +541,8 @@ RegEnumValue(
Key, Index, ValueName, NameSize, Type, Data, DataSize, *DataSize);
/* Get the key node */
- KeyNode = (PCM_KEY_NODE)Key;
+ KeyNode = GET_CM_KEY_NODE(Hive, Key);
+ ASSERT(KeyNode);
ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
/* Check if the index is valid */
@@ -522,6 +551,7 @@ RegEnumValue(
(Index >= KeyNode->ValueList.Count))
{
ERR("RegEnumValue: index invalid\n");
+ HvReleaseCell(Hive, (HCELL_INDEX)Key);
return ERROR_NO_MORE_ITEMS;
}
@@ -563,6 +593,7 @@ RegEnumValue(
HvReleaseCell(Hive, ValueListCell->KeyList[Index]);
HvReleaseCell(Hive, KeyNode->ValueList.List);
+ HvReleaseCell(Hive, (HCELL_INDEX)Key);
TRACE("RegEnumValue done -> %u, '%.*S'\n", *NameSize, *NameSize,
ValueName);
return ERROR_SUCCESS;
diff --git a/boot/freeldr/freeldr/ntldr/registry.h
b/boot/freeldr/freeldr/ntldr/registry.h
index 0743be4866e..028f75042d6 100644
--- a/boot/freeldr/freeldr/ntldr/registry.h
+++ b/boot/freeldr/freeldr/ntldr/registry.h
@@ -21,6 +21,8 @@
#ifndef __REGISTRY_H
#define __REGISTRY_H
+#include <cmlib.h>
+
typedef HANDLE HKEY, *PHKEY;
BOOLEAN
@@ -32,6 +34,7 @@ LONG
RegInitCurrentControlSet(
_In_ BOOLEAN LastKnownGood);
+extern PHHIVE SystemHive;
extern HKEY CurrentControlSetKey;
/*