mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 02:10:07 +00:00
[FREELDR]
Make FreeLdr fully using the CMLIB library. CORE-10802 #resolve CORE-10793 svn path=/trunk/; revision=70604
This commit is contained in:
parent
660ad50bae
commit
17c6bfd956
|
@ -29,23 +29,46 @@ static PCMHIVE CmHive;
|
||||||
static PCM_KEY_NODE RootKeyNode;
|
static PCM_KEY_NODE RootKeyNode;
|
||||||
static HKEY CurrentControlSetKey;
|
static HKEY CurrentControlSetKey;
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
NTAPI
|
||||||
|
CmpAllocate(
|
||||||
|
IN SIZE_T Size,
|
||||||
|
IN BOOLEAN Paged,
|
||||||
|
IN ULONG Tag)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(Paged);
|
||||||
|
UNREFERENCED_PARAMETER(Tag);
|
||||||
|
|
||||||
|
return FrLdrTempAlloc(Size, Tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
CmpFree(
|
||||||
|
IN PVOID Ptr,
|
||||||
|
IN ULONG Quota)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(Quota);
|
||||||
|
FrLdrTempFree(Ptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
RegImportBinaryHive(
|
RegImportBinaryHive(
|
||||||
_In_ PCHAR ChunkBase,
|
_In_ PVOID ChunkBase,
|
||||||
_In_ ULONG ChunkSize)
|
_In_ ULONG ChunkSize)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
TRACE("RegImportBinaryHive(%p, 0x%lx)\n", ChunkBase, ChunkSize);
|
TRACE("RegImportBinaryHive(%p, 0x%lx)\n", ChunkBase, ChunkSize);
|
||||||
|
|
||||||
/* Allocate and initialize the hive */
|
/* Allocate and initialize the hive */
|
||||||
CmHive = FrLdrTempAlloc(sizeof(CMHIVE), 'eviH');
|
CmHive = CmpAllocate(sizeof(CMHIVE), FALSE, 'eviH');
|
||||||
Status = HvInitialize(&CmHive->Hive,
|
Status = HvInitialize(&CmHive->Hive,
|
||||||
HINIT_FLAT,
|
HINIT_FLAT, // HINIT_MEMORY_INPLACE
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
ChunkBase,
|
ChunkBase,
|
||||||
NULL,
|
CmpAllocate,
|
||||||
NULL,
|
CmpFree,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -54,24 +77,18 @@ RegImportBinaryHive(
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
FrLdrTempFree(CmHive, 'eviH');
|
CmpFree(CmHive, 0);
|
||||||
ERR("Invalid hive Signature!\n");
|
ERR("Corrupted hive %p!\n", ChunkBase);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the root key node */
|
/* Save the root key node */
|
||||||
RootKeyNode = HvGetCell(&CmHive->Hive, CmHive->Hive.BaseBlock->RootCell);
|
RootKeyNode = (PCM_KEY_NODE)HvGetCell(&CmHive->Hive, CmHive->Hive.BaseBlock->RootCell);
|
||||||
|
|
||||||
TRACE("RegImportBinaryHive done\n");
|
TRACE("RegImportBinaryHive done\n");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
|
||||||
RegInitializeRegistry(VOID)
|
|
||||||
{
|
|
||||||
/* Nothing to do */
|
|
||||||
}
|
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
RegInitCurrentControlSet(
|
RegInitCurrentControlSet(
|
||||||
_In_ BOOLEAN LastKnownGood)
|
_In_ BOOLEAN LastKnownGood)
|
||||||
|
@ -203,62 +220,6 @@ GetNextPathElement(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
PCM_KEY_NODE
|
|
||||||
RegpFindSubkeyInIndex(
|
|
||||||
_In_ PHHIVE Hive,
|
|
||||||
_In_ PCM_KEY_INDEX IndexCell,
|
|
||||||
_In_ PUNICODE_STRING SubKeyName)
|
|
||||||
{
|
|
||||||
PCM_KEY_NODE SubKeyNode;
|
|
||||||
ULONG i;
|
|
||||||
TRACE("RegpFindSubkeyInIndex('%wZ')\n", SubKeyName);
|
|
||||||
|
|
||||||
/* Check the cell type */
|
|
||||||
if ((IndexCell->Signature == CM_KEY_INDEX_ROOT) ||
|
|
||||||
(IndexCell->Signature == CM_KEY_INDEX_LEAF))
|
|
||||||
{
|
|
||||||
ASSERT(FALSE);
|
|
||||||
|
|
||||||
/* Enumerate subindex cells */
|
|
||||||
for (i = 0; i < IndexCell->Count; i++)
|
|
||||||
{
|
|
||||||
/* Get the subindex cell and call the function recursively */
|
|
||||||
PCM_KEY_INDEX SubIndexCell = HvGetCell(Hive, IndexCell->List[i]);
|
|
||||||
|
|
||||||
SubKeyNode = RegpFindSubkeyInIndex(Hive, SubIndexCell, SubKeyName);
|
|
||||||
if (SubKeyNode != NULL)
|
|
||||||
{
|
|
||||||
return SubKeyNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((IndexCell->Signature == CM_KEY_FAST_LEAF) ||
|
|
||||||
(IndexCell->Signature == CM_KEY_HASH_LEAF))
|
|
||||||
{
|
|
||||||
/* Directly enumerate subkey nodes */
|
|
||||||
PCM_KEY_FAST_INDEX HashCell = (PCM_KEY_FAST_INDEX)IndexCell;
|
|
||||||
for (i = 0; i < HashCell->Count; i++)
|
|
||||||
{
|
|
||||||
SubKeyNode = HvGetCell(Hive, HashCell->List[i].Cell);
|
|
||||||
ASSERT(SubKeyNode->Signature == CM_KEY_NODE_SIGNATURE);
|
|
||||||
|
|
||||||
TRACE(" RegpFindSubkeyInIndex: checking '%.*s'\n",
|
|
||||||
SubKeyNode->NameLength, SubKeyNode->Name);
|
|
||||||
if (CmCompareKeyName(SubKeyNode, SubKeyName, TRUE))
|
|
||||||
{
|
|
||||||
return SubKeyNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ASSERT(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
RegEnumKey(
|
RegEnumKey(
|
||||||
_In_ HKEY Key,
|
_In_ HKEY Key,
|
||||||
|
@ -269,8 +230,9 @@ RegEnumKey(
|
||||||
{
|
{
|
||||||
PHHIVE Hive = &CmHive->Hive;
|
PHHIVE Hive = &CmHive->Hive;
|
||||||
PCM_KEY_NODE KeyNode, SubKeyNode;
|
PCM_KEY_NODE KeyNode, SubKeyNode;
|
||||||
PCM_KEY_INDEX IndexCell;
|
HCELL_INDEX CellIndex;
|
||||||
PCM_KEY_FAST_INDEX HashCell;
|
USHORT NameLength;
|
||||||
|
|
||||||
TRACE("RegEnumKey(%p, %lu, %p, %p->%u)\n",
|
TRACE("RegEnumKey(%p, %lu, %p, %p->%u)\n",
|
||||||
Key, Index, Name, NameSize, NameSize ? *NameSize : 0);
|
Key, Index, Name, NameSize, NameSize ? *NameSize : 0);
|
||||||
|
|
||||||
|
@ -278,40 +240,52 @@ RegEnumKey(
|
||||||
KeyNode = (PCM_KEY_NODE)Key;
|
KeyNode = (PCM_KEY_NODE)Key;
|
||||||
ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
|
ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
|
||||||
|
|
||||||
/* Check if the index is valid */
|
CellIndex = CmpFindSubKeyByNumber(Hive, KeyNode, Index);
|
||||||
if ((KeyNode->SubKeyCounts[Stable] == 0) ||
|
if (CellIndex == HCELL_NIL)
|
||||||
(Index >= KeyNode->SubKeyCounts[Stable]))
|
|
||||||
{
|
{
|
||||||
TRACE("RegEnumKey index out of bounds\n");
|
TRACE("RegEnumKey index out of bounds (%d) in key (%.*s)\n",
|
||||||
|
Index, KeyNode->NameLength, KeyNode->Name);
|
||||||
return ERROR_NO_MORE_ITEMS;
|
return ERROR_NO_MORE_ITEMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the index cell */
|
/* Get the value cell */
|
||||||
IndexCell = HvGetCell(Hive, KeyNode->SubKeyLists[Stable]);
|
SubKeyNode = (PCM_KEY_NODE)HvGetCell(Hive, CellIndex);
|
||||||
TRACE("IndexCell: %x, SubKeyCounts: %x\n", IndexCell, KeyNode->SubKeyCounts[Stable]);
|
ASSERT(SubKeyNode != NULL);
|
||||||
|
ASSERT(SubKeyNode->Signature == CM_KEY_NODE_SIGNATURE);
|
||||||
|
|
||||||
/* Check the cell type */
|
if (SubKeyNode->Flags & KEY_COMP_NAME)
|
||||||
if ((IndexCell->Signature == CM_KEY_FAST_LEAF) ||
|
|
||||||
(IndexCell->Signature == CM_KEY_HASH_LEAF))
|
|
||||||
{
|
{
|
||||||
/* Get the value cell */
|
NameLength = CmpCompressedNameSize(SubKeyNode->Name, SubKeyNode->NameLength);
|
||||||
HashCell = (PCM_KEY_FAST_INDEX)IndexCell;
|
|
||||||
SubKeyNode = HvGetCell(Hive, HashCell->List[Index].Cell);
|
/* Compressed name */
|
||||||
|
CmpCopyCompressedName(Name,
|
||||||
|
*NameSize,
|
||||||
|
SubKeyNode->Name,
|
||||||
|
SubKeyNode->NameLength);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ASSERT(FALSE);
|
NameLength = SubKeyNode->NameLength;
|
||||||
|
|
||||||
|
/* Normal name */
|
||||||
|
RtlCopyMemory(Name, SubKeyNode->Name,
|
||||||
|
min(*NameSize, SubKeyNode->NameLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
*NameSize = CmCopyKeyName(SubKeyNode, Name, *NameSize);
|
if (*NameSize >= NameLength + sizeof(WCHAR))
|
||||||
|
{
|
||||||
|
Name[NameLength / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*NameSize = NameLength + sizeof(WCHAR);
|
||||||
|
|
||||||
|
/**/HvReleaseCell(Hive, CellIndex);/**/
|
||||||
|
|
||||||
if (SubKey != NULL)
|
if (SubKey != NULL)
|
||||||
{
|
|
||||||
*SubKey = (HKEY)SubKeyNode;
|
*SubKey = (HKEY)SubKeyNode;
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("RegEnumKey done -> %u, '%.*s'\n", *NameSize, *NameSize, Name);
|
TRACE("RegEnumKey done -> %u, '%.*S'\n", *NameSize, *NameSize, Name);
|
||||||
return STATUS_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
|
@ -324,7 +298,7 @@ RegOpenKey(
|
||||||
UNICODE_STRING CurrentControlSet = RTL_CONSTANT_STRING(L"CurrentControlSet");
|
UNICODE_STRING CurrentControlSet = RTL_CONSTANT_STRING(L"CurrentControlSet");
|
||||||
PHHIVE Hive = &CmHive->Hive;
|
PHHIVE Hive = &CmHive->Hive;
|
||||||
PCM_KEY_NODE KeyNode;
|
PCM_KEY_NODE KeyNode;
|
||||||
PCM_KEY_INDEX IndexCell;
|
HCELL_INDEX CellIndex;
|
||||||
TRACE("RegOpenKey(%p, '%S', %p)\n", ParentKey, KeyName, Key);
|
TRACE("RegOpenKey(%p, '%S', %p)\n", ParentKey, KeyName, Key);
|
||||||
|
|
||||||
/* Initialize the remaining path name */
|
/* Initialize the remaining path name */
|
||||||
|
@ -400,27 +374,22 @@ RegOpenKey(
|
||||||
{
|
{
|
||||||
TRACE("RegOpenKey: next element '%wZ'\n", &SubKeyName);
|
TRACE("RegOpenKey: next element '%wZ'\n", &SubKeyName);
|
||||||
|
|
||||||
/* Check if there is any subkey */
|
|
||||||
if (KeyNode->SubKeyCounts[Stable] == 0)
|
|
||||||
{
|
|
||||||
return ERROR_PATH_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the top level index cell */
|
|
||||||
IndexCell = HvGetCell(Hive, KeyNode->SubKeyLists[Stable]);
|
|
||||||
|
|
||||||
/* Get the next sub key */
|
/* Get the next sub key */
|
||||||
KeyNode = RegpFindSubkeyInIndex(Hive, IndexCell, &SubKeyName);
|
CellIndex = CmpFindSubKeyByName(Hive, KeyNode, &SubKeyName);
|
||||||
if (KeyNode == NULL)
|
if (CellIndex == HCELL_NIL)
|
||||||
{
|
{
|
||||||
|
ERR("Did not find sub key '%wZ' (full %S)\n", &SubKeyName, KeyName);
|
||||||
ERR("Did not find sub key '%wZ' (full %S)\n", &RemainingPath, KeyName);
|
|
||||||
return ERROR_PATH_NOT_FOUND;
|
return ERROR_PATH_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the found key */
|
||||||
|
KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, CellIndex);
|
||||||
|
ASSERT(KeyNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("RegOpenKey done\n");
|
|
||||||
*Key = (HKEY)KeyNode;
|
*Key = (HKEY)KeyNode;
|
||||||
|
|
||||||
|
TRACE("RegOpenKey done\n");
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,40 +403,27 @@ RepGetValueData(
|
||||||
_Inout_opt_ ULONG* DataSize)
|
_Inout_opt_ ULONG* DataSize)
|
||||||
{
|
{
|
||||||
ULONG DataLength;
|
ULONG DataLength;
|
||||||
|
PVOID DataCell;
|
||||||
|
|
||||||
/* Does the caller want the type? */
|
/* Does the caller want the type? */
|
||||||
if (Type != NULL)
|
if (Type != NULL)
|
||||||
{
|
|
||||||
*Type = ValueCell->Type;
|
*Type = ValueCell->Type;
|
||||||
}
|
|
||||||
|
|
||||||
/* Does the caller provide DataSize? */
|
/* Does the caller provide DataSize? */
|
||||||
if (DataSize != NULL)
|
if (DataSize != NULL)
|
||||||
{
|
{
|
||||||
/* Get the data length */
|
// NOTE: CmpValueToData doesn't support big data (the function will
|
||||||
DataLength = ValueCell->DataLength & ~CM_KEY_VALUE_SPECIAL_SIZE;
|
// bugcheck if so), FreeLdr is not supposed to read such data.
|
||||||
|
// If big data is needed, use instead CmpGetValueData.
|
||||||
|
// CmpGetValueData(Hive, ValueCell, DataSize, &DataCell, ...);
|
||||||
|
DataCell = CmpValueToData(Hive, ValueCell, &DataLength);
|
||||||
|
|
||||||
/* Does the caller want the data? */
|
/* Does the caller want the data? */
|
||||||
if ((Data != NULL) && (*DataSize != 0))
|
if ((Data != NULL) && (*DataSize != 0))
|
||||||
{
|
{
|
||||||
/* Check where the data is stored */
|
RtlCopyMemory(Data,
|
||||||
if ((DataLength <= sizeof(HCELL_INDEX)) &&
|
DataCell,
|
||||||
(ValueCell->DataLength & CM_KEY_VALUE_SPECIAL_SIZE))
|
min(*DataSize, DataLength));
|
||||||
{
|
|
||||||
/* The data member contains the data */
|
|
||||||
RtlCopyMemory(Data,
|
|
||||||
&ValueCell->Data,
|
|
||||||
min(*DataSize, DataLength));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* The data member contains the data cell index */
|
|
||||||
PVOID DataCell = HvGetCell(Hive, ValueCell->Data);
|
|
||||||
RtlCopyMemory(Data,
|
|
||||||
DataCell,
|
|
||||||
min(*DataSize, ValueCell->DataLength));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the actual data length */
|
/* Return the actual data length */
|
||||||
|
@ -486,9 +442,9 @@ RegQueryValue(
|
||||||
PHHIVE Hive = &CmHive->Hive;
|
PHHIVE Hive = &CmHive->Hive;
|
||||||
PCM_KEY_NODE KeyNode;
|
PCM_KEY_NODE KeyNode;
|
||||||
PCM_KEY_VALUE ValueCell;
|
PCM_KEY_VALUE ValueCell;
|
||||||
PVALUE_LIST_CELL ValueListCell;
|
HCELL_INDEX CellIndex;
|
||||||
UNICODE_STRING ValueNameString;
|
UNICODE_STRING ValueNameString;
|
||||||
ULONG i;
|
|
||||||
TRACE("RegQueryValue(%p, '%S', %p, %p, %p)\n",
|
TRACE("RegQueryValue(%p, '%S', %p, %p, %p)\n",
|
||||||
Key, ValueName, Type, Data, DataSize);
|
Key, ValueName, Type, Data, DataSize);
|
||||||
|
|
||||||
|
@ -496,54 +452,50 @@ RegQueryValue(
|
||||||
KeyNode = (PCM_KEY_NODE)Key;
|
KeyNode = (PCM_KEY_NODE)Key;
|
||||||
ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
|
ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
|
||||||
|
|
||||||
/* Check if there are any values */
|
|
||||||
if (KeyNode->ValueList.Count == 0)
|
|
||||||
{
|
|
||||||
TRACE("RegQueryValue no values in key (%.*s)\n",
|
|
||||||
KeyNode->NameLength, KeyNode->Name);
|
|
||||||
return ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize value name string */
|
/* Initialize value name string */
|
||||||
RtlInitUnicodeString(&ValueNameString, ValueName);
|
RtlInitUnicodeString(&ValueNameString, ValueName);
|
||||||
|
CellIndex = CmpFindValueByName(Hive, KeyNode, &ValueNameString);
|
||||||
ValueListCell = (PVALUE_LIST_CELL)HvGetCell(Hive, KeyNode->ValueList.List);
|
if (CellIndex == HCELL_NIL)
|
||||||
TRACE("ValueListCell: %x\n", ValueListCell);
|
|
||||||
|
|
||||||
/* Loop all values */
|
|
||||||
for (i = 0; i < KeyNode->ValueList.Count; i++)
|
|
||||||
{
|
{
|
||||||
/* Get the subkey node and check the name */
|
TRACE("RegQueryValue value not found in key (%.*s)\n",
|
||||||
ValueCell = HvGetCell(Hive, ValueListCell->ValueOffset[i]);
|
KeyNode->NameLength, KeyNode->Name);
|
||||||
|
return ERROR_FILE_NOT_FOUND;
|
||||||
/* Compare the value name */
|
|
||||||
TRACE("checking %.*s\n", ValueCell->NameLength, ValueCell->Name);
|
|
||||||
if (CmCompareKeyValueName(ValueCell, &ValueNameString, TRUE))
|
|
||||||
{
|
|
||||||
RepGetValueData(Hive, ValueCell, Type, Data, DataSize);
|
|
||||||
TRACE("RegQueryValue success\n");
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("RegQueryValue value not found\n");
|
/* Get the value cell */
|
||||||
return ERROR_INVALID_PARAMETER;
|
ValueCell = (PCM_KEY_VALUE)HvGetCell(Hive, CellIndex);
|
||||||
|
ASSERT(ValueCell != NULL);
|
||||||
|
|
||||||
|
RepGetValueData(Hive, ValueCell, Type, Data, DataSize);
|
||||||
|
|
||||||
|
HvReleaseCell(Hive, CellIndex);
|
||||||
|
|
||||||
|
TRACE("RegQueryValue success\n");
|
||||||
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: This function is currently unused in FreeLdr; however it is kept here
|
||||||
|
* as an implementation reference of RegEnumValue using CMLIB that may be used
|
||||||
|
* elsewhere in ReactOS.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
LONG
|
LONG
|
||||||
RegEnumValue(
|
RegEnumValue(
|
||||||
_In_ HKEY Key,
|
_In_ HKEY Key,
|
||||||
_In_ ULONG Index,
|
_In_ ULONG Index,
|
||||||
_Out_ PWCHAR ValueName,
|
_Out_ PWCHAR ValueName,
|
||||||
_Inout_ ULONG* NameSize,
|
_Inout_ ULONG* NameSize,
|
||||||
_Out_ ULONG* Type,
|
_Out_opt_ ULONG* Type,
|
||||||
_Out_ PUCHAR Data,
|
_Out_opt_ PUCHAR Data,
|
||||||
_Inout_ ULONG* DataSize)
|
_Inout_opt_ ULONG* DataSize)
|
||||||
{
|
{
|
||||||
PHHIVE Hive = &CmHive->Hive;
|
PHHIVE Hive = &CmHive->Hive;
|
||||||
PCM_KEY_NODE KeyNode;
|
PCM_KEY_NODE KeyNode;
|
||||||
|
PCELL_DATA ValueListCell;
|
||||||
PCM_KEY_VALUE ValueCell;
|
PCM_KEY_VALUE ValueCell;
|
||||||
PVALUE_LIST_CELL ValueListCell;
|
USHORT NameLength;
|
||||||
|
|
||||||
TRACE("RegEnumValue(%p, %lu, %S, %p, %p, %p, %p (%lu))\n",
|
TRACE("RegEnumValue(%p, %lu, %S, %p, %p, %p, %p (%lu))\n",
|
||||||
Key, Index, ValueName, NameSize, Type, Data, DataSize, *DataSize);
|
Key, Index, ValueName, NameSize, Type, Data, DataSize, *DataSize);
|
||||||
|
|
||||||
|
@ -553,40 +505,55 @@ RegEnumValue(
|
||||||
|
|
||||||
/* Check if the index is valid */
|
/* Check if the index is valid */
|
||||||
if ((KeyNode->ValueList.Count == 0) ||
|
if ((KeyNode->ValueList.Count == 0) ||
|
||||||
|
(KeyNode->ValueList.List == HCELL_NIL) ||
|
||||||
(Index >= KeyNode->ValueList.Count))
|
(Index >= KeyNode->ValueList.Count))
|
||||||
{
|
{
|
||||||
ERR("RegEnumValue: index invalid\n");
|
ERR("RegEnumValue: index invalid\n");
|
||||||
return ERROR_NO_MORE_ITEMS;
|
return ERROR_NO_MORE_ITEMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueListCell = (PVALUE_LIST_CELL)HvGetCell(Hive, KeyNode->ValueList.List);
|
ValueListCell = (PCELL_DATA)HvGetCell(Hive, KeyNode->ValueList.List);
|
||||||
TRACE("ValueListCell: %x\n", ValueListCell);
|
ASSERT(ValueListCell != NULL);
|
||||||
|
|
||||||
/* Get the value cell */
|
/* Get the value cell */
|
||||||
ValueCell = HvGetCell(Hive, ValueListCell->ValueOffset[Index]);
|
ValueCell = (PCM_KEY_VALUE)HvGetCell(Hive, ValueListCell->KeyList[Index]);
|
||||||
ASSERT(ValueCell != NULL);
|
ASSERT(ValueCell != NULL);
|
||||||
|
ASSERT(ValueCell->Signature == CM_KEY_VALUE_SIGNATURE);
|
||||||
|
|
||||||
if (NameSize != NULL)
|
if (ValueCell->Flags & VALUE_COMP_NAME)
|
||||||
{
|
{
|
||||||
*NameSize = CmCopyKeyValueName(ValueCell, ValueName, *NameSize);
|
NameLength = CmpCompressedNameSize(ValueCell->Name, ValueCell->NameLength);
|
||||||
|
|
||||||
|
/* Compressed name */
|
||||||
|
CmpCopyCompressedName(ValueName,
|
||||||
|
*NameSize,
|
||||||
|
ValueCell->Name,
|
||||||
|
ValueCell->NameLength);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NameLength = ValueCell->NameLength;
|
||||||
|
|
||||||
|
/* Normal name */
|
||||||
|
RtlCopyMemory(ValueName, ValueCell->Name,
|
||||||
|
min(*NameSize, ValueCell->NameLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*NameSize >= NameLength + sizeof(WCHAR))
|
||||||
|
{
|
||||||
|
ValueName[NameLength / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*NameSize = NameLength + sizeof(WCHAR);
|
||||||
|
|
||||||
RepGetValueData(Hive, ValueCell, Type, Data, DataSize);
|
RepGetValueData(Hive, ValueCell, Type, Data, DataSize);
|
||||||
|
|
||||||
if (DataSize != NULL)
|
HvReleaseCell(Hive, ValueListCell->KeyList[Index]);
|
||||||
{
|
HvReleaseCell(Hive, KeyNode->ValueList.List);
|
||||||
if ((Data != NULL) && (*DataSize != 0))
|
|
||||||
{
|
|
||||||
RtlCopyMemory(Data,
|
|
||||||
&ValueCell->Data,
|
|
||||||
min(*DataSize, ValueCell->DataLength));
|
|
||||||
}
|
|
||||||
|
|
||||||
*DataSize = ValueCell->DataLength;
|
TRACE("RegEnumValue done -> %u, '%.*S'\n", *NameSize, *NameSize, ValueName);
|
||||||
}
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
TRACE("RegEnumValue done\n");
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -23,9 +23,6 @@
|
||||||
|
|
||||||
typedef HANDLE HKEY, *PHKEY;
|
typedef HANDLE HKEY, *PHKEY;
|
||||||
|
|
||||||
VOID
|
|
||||||
RegInitializeRegistry(VOID);
|
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
RegInitCurrentControlSet(BOOLEAN LastKnownGood);
|
RegInitCurrentControlSet(BOOLEAN LastKnownGood);
|
||||||
|
|
||||||
|
@ -42,13 +39,6 @@ RegOpenKey(HKEY ParentKey,
|
||||||
PCWSTR KeyName,
|
PCWSTR KeyName,
|
||||||
PHKEY Key);
|
PHKEY Key);
|
||||||
|
|
||||||
LONG
|
|
||||||
RegSetValue(HKEY Key,
|
|
||||||
PCWSTR ValueName,
|
|
||||||
ULONG Type,
|
|
||||||
PCSTR Data,
|
|
||||||
ULONG DataSize);
|
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
RegQueryValue(HKEY Key,
|
RegQueryValue(HKEY Key,
|
||||||
PCWSTR ValueName,
|
PCWSTR ValueName,
|
||||||
|
@ -66,7 +56,7 @@ RegEnumValue(HKEY Key,
|
||||||
ULONG* DataSize);
|
ULONG* DataSize);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
RegImportBinaryHive(PCHAR ChunkBase,
|
RegImportBinaryHive(PVOID ChunkBase,
|
||||||
ULONG ChunkSize);
|
ULONG ChunkSize);
|
||||||
|
|
||||||
#endif /* __REGISTRY_H */
|
#endif /* __REGISTRY_H */
|
||||||
|
|
|
@ -133,11 +133,8 @@ BOOLEAN WinLdrInitSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||||
if (!Success)
|
if (!Success)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// Initialize in-memory registry
|
|
||||||
RegInitializeRegistry();
|
|
||||||
|
|
||||||
// Import what was loaded
|
// Import what was loaded
|
||||||
Success = RegImportBinaryHive((PCHAR)VaToPa(LoaderBlock->RegistryBase), LoaderBlock->RegistryLength);
|
Success = RegImportBinaryHive(VaToPa(LoaderBlock->RegistryBase), LoaderBlock->RegistryLength);
|
||||||
if (!Success)
|
if (!Success)
|
||||||
{
|
{
|
||||||
UiMessageBox("Importing binary hive failed!");
|
UiMessageBox("Importing binary hive failed!");
|
||||||
|
|
Loading…
Reference in a new issue