Author: tkreuzer
Date: Sun Jan 12 21:37:29 2014
New Revision: 61595
URL:
http://svn.reactos.org/svn/reactos?rev=61595&view=rev
Log:
[FREELDR]
Completely rewrite the registry code.
The old code was first loading the system hive and parsing it, duplicating each and every
key and value into a custom freeldr specific registry format and used the latter to access
the data. This was extremely slow when larger hive files (the one from a normal win 2003
installation is 2.5 MB vs 250kb in reactos) were imported. The new code uses the hive data
directly. It's less code, faster and uses much less memory.
In the same move, refactor some mkhive code and move it into cmlib to be shared with
freeldr.
Added:
trunk/reactos/boot/freeldr/freeldr/reactos/registry.c (with props)
trunk/reactos/lib/cmlib/cmtools.c (with props)
Removed:
trunk/reactos/boot/freeldr/freeldr/reactos/binhive.c
Modified:
trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt
trunk/reactos/lib/cmlib/CMakeLists.txt
trunk/reactos/lib/cmlib/cmdata.h
trunk/reactos/lib/cmlib/cmlib.h
trunk/reactos/tools/mkhive/cmi.c
trunk/reactos/tools/mkhive/mkhive.h
Modified: trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/CMake…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt [iso-8859-1] Sun Jan 12 21:37:29
2014
@@ -62,7 +62,6 @@
reactos/registry.c
reactos/arcname.c
reactos/archwsup.c
- reactos/binhive.c
ui/directui.c
ui/gui.c
ui/minitui.c
Removed: trunk/reactos/boot/freeldr/freeldr/reactos/binhive.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/react…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/reactos/binhive.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/reactos/binhive.c (removed)
@@ -1,343 +0,0 @@
-/*
- * FreeLoader
- *
- * Copyright (C) 2001 Rex Jolliff
- * Copyright (C) 2001 Eric Kohl
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <freeldr.h>
-#include <cmlib.h>
-#include <debug.h>
-
-#define REG_DATA_SIZE_MASK 0x7FFFFFFF
-#define REG_DATA_IN_OFFSET 0x80000000
-
-DBG_DEFAULT_CHANNEL(REGISTRY);
-
-/* FUNCTIONS ****************************************************************/
-
-static
-PVOID
-NTAPI
-CmpAllocate (SIZE_T Size, BOOLEAN Paged, ULONG Tag)
-{
- return FrLdrHeapAllocateEx(FrLdrDefaultHeap, Size, Tag);
-}
-
-
-static
-VOID
-NTAPI
-CmpFree (PVOID Ptr, IN ULONG Quota)
-{
- FrLdrHeapFreeEx(FrLdrDefaultHeap, Ptr, 0);
-}
-
-static
-BOOLEAN
-RegImportValue (
- PHHIVE Hive,
- PCM_KEY_VALUE ValueCell,
- FRLDRHKEY Key)
-{
- PVOID DataCell;
- PWCHAR wName;
- LONG Error;
- ULONG DataLength;
- ULONG i;
-
- if (ValueCell->Signature != CM_KEY_VALUE_SIGNATURE)
- {
- ERR("Invalid key cell!\n");
- return FALSE;
- }
-
- if (ValueCell->Flags & VALUE_COMP_NAME)
- {
- wName = FrLdrTempAlloc((ValueCell->NameLength + 1) * sizeof(WCHAR),
TAG_REG_NAME);
- for (i = 0; i < ValueCell->NameLength; i++)
- {
- wName[i] = ((PCHAR)ValueCell->Name)[i];
- }
- wName[ValueCell->NameLength] = 0;
- }
- else
- {
- wName = FrLdrTempAlloc(ValueCell->NameLength + sizeof(WCHAR), TAG_REG_NAME);
- memcpy(wName, ValueCell->Name, ValueCell->NameLength);
- wName[ValueCell->NameLength / sizeof(WCHAR)] = 0;
- }
-
- DataLength = ValueCell->DataLength & REG_DATA_SIZE_MASK;
-
- TRACE("ValueName: '%S'\n", wName);
- TRACE("DataLength: %u\n", DataLength);
-
- if (DataLength <= sizeof(HCELL_INDEX) && (ValueCell->DataLength &
REG_DATA_IN_OFFSET))
- {
- Error = RegSetValue(Key,
- wName,
- ValueCell->Type,
- (PCHAR)&ValueCell->Data,
- DataLength);
- if (Error != ERROR_SUCCESS)
- {
- ERR("RegSetValue() failed!\n");
- FrLdrTempFree(wName, TAG_REG_NAME);
- return FALSE;
- }
- }
- else
- {
- DataCell = (PVOID)HvGetCell(Hive, ValueCell->Data);
- TRACE("DataCell: %x\n", DataCell);
-
- Error = RegSetValue(Key,
- wName,
- ValueCell->Type,
- DataCell,
- DataLength);
-
- if (Error != ERROR_SUCCESS)
- {
- ERR("RegSetValue() failed!\n");
- FrLdrTempFree(wName, TAG_REG_NAME);
- return FALSE;
- }
- }
-
- FrLdrTempFree(wName, TAG_REG_NAME);
-
- return TRUE;
-}
-
-static
-BOOLEAN
-RegImportSubKey(
- PHHIVE Hive,
- PCM_KEY_NODE KeyCell,
- FRLDRHKEY ParentKey);
-
-static
-BOOLEAN
-RegImportIndexSubKey(
- PHHIVE Hive,
- PCM_KEY_INDEX IndexCell,
- FRLDRHKEY ParentKey)
-{
- ULONG i;
-
- TRACE("IndexCell: %x\n", IndexCell);
-
- /* Enumerate and add subkeys */
- if ((IndexCell->Signature == CM_KEY_INDEX_ROOT) ||
- (IndexCell->Signature == CM_KEY_INDEX_LEAF))
- {
- for (i = 0; i < IndexCell->Count; i++)
- {
- PCM_KEY_INDEX SubIndexCell = HvGetCell(Hive, IndexCell->List[i]);
- if (!RegImportIndexSubKey(Hive, SubIndexCell, ParentKey))
- return FALSE;
- }
- }
- else if ((IndexCell->Signature == CM_KEY_FAST_LEAF) ||
- (IndexCell->Signature == CM_KEY_HASH_LEAF))
- {
- PCM_KEY_FAST_INDEX HashCell = (PCM_KEY_FAST_INDEX)IndexCell;
- for (i = 0; i < HashCell->Count; i++)
- {
- PCM_KEY_NODE SubKeyCell = HvGetCell(Hive, HashCell->List[i].Cell);
- if (!RegImportSubKey(Hive, SubKeyCell, ParentKey))
- return FALSE;
- }
- }
- else
- {
- ASSERT(FALSE);
- }
-
- return TRUE;
-}
-
-
-static
-BOOLEAN
-RegImportSubKey(
- PHHIVE Hive,
- PCM_KEY_NODE KeyCell,
- FRLDRHKEY ParentKey)
-{
- PCM_KEY_INDEX IndexCell;
- PVALUE_LIST_CELL ValueListCell;
- PCM_KEY_VALUE ValueCell = NULL;
- PWCHAR wName;
- FRLDRHKEY SubKey;
- LONG Error;
- ULONG i;
-
- TRACE("KeyCell: %x\n", KeyCell);
- TRACE("KeyCell->Signature: %x\n", KeyCell->Signature);
- if (KeyCell->Signature != CM_KEY_NODE_SIGNATURE)
- {
- ERR("Invalid key cell Signature!\n");
- return FALSE;
- }
-
- if (KeyCell->Flags & KEY_COMP_NAME)
- {
- wName = FrLdrTempAlloc((KeyCell->NameLength + 1) * sizeof(WCHAR),
TAG_REG_NAME);
- for (i = 0; i < KeyCell->NameLength; i++)
- {
- wName[i] = ((PCHAR)KeyCell->Name)[i];
- }
- wName[KeyCell->NameLength] = 0;
- }
- else
- {
- wName = FrLdrTempAlloc(KeyCell->NameLength + sizeof(WCHAR), TAG_REG_NAME);
- memcpy(wName, KeyCell->Name, KeyCell->NameLength);
- wName[KeyCell->NameLength / sizeof(WCHAR)] = 0;
- }
-
- TRACE("KeyName: '%S'\n", wName);
-
- /* Create new sub key */
- Error = RegCreateKey(ParentKey, wName, &SubKey);
- FrLdrTempFree(wName, TAG_REG_NAME);
- if (Error != ERROR_SUCCESS)
- {
- ERR("RegCreateKey() failed!\n");
- return FALSE;
- }
- TRACE("Subkeys: %u\n", KeyCell->SubKeyCounts);
- TRACE("Values: %u\n", KeyCell->ValueList.Count);
-
- /* Enumerate and add values */
- if (KeyCell->ValueList.Count > 0)
- {
- ValueListCell = (PVALUE_LIST_CELL)HvGetCell(Hive, KeyCell->ValueList.List);
- TRACE("ValueListCell: %x\n", ValueListCell);
-
- for (i = 0; i < KeyCell->ValueList.Count; i++)
- {
- TRACE("ValueOffset[%d]: %x\n", i,
ValueListCell->ValueOffset[i]);
-
- ValueCell = (PCM_KEY_VALUE) HvGetCell (Hive,
ValueListCell->ValueOffset[i]);
-
- TRACE("ValueCell[%d]: %x\n", i, ValueCell);
-
- if (!RegImportValue(Hive, ValueCell, SubKey))
- return FALSE;
- }
- }
-
- /* Enumerate and add subkeys */
- if (KeyCell->SubKeyCounts[Stable] > 0)
- {
- IndexCell = HvGetCell (Hive, KeyCell->SubKeyLists[Stable]);
-
- if (!RegImportIndexSubKey(Hive, IndexCell, SubKey))
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-BOOLEAN
-RegImportBinaryHive(
- PCHAR ChunkBase,
- ULONG ChunkSize)
-{
- PCM_KEY_NODE KeyCell;
- PCM_KEY_FAST_INDEX HashCell;
- PCM_KEY_NODE SubKeyCell;
- FRLDRHKEY SystemKey;
- ULONG i;
- LONG Error;
- PCMHIVE CmHive;
- PHHIVE Hive;
- NTSTATUS Status;
-
- TRACE("RegImportBinaryHive(%x, %u) called\n", ChunkBase, ChunkSize);
-
- CmHive = CmpAllocate(sizeof(CMHIVE), TRUE, 0);
- Status = HvInitialize(&CmHive->Hive,
- HINIT_FLAT,
- 0,
- 0,
- ChunkBase,
- CmpAllocate,
- CmpFree,
- NULL,
- NULL,
- NULL,
- NULL,
- 1,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- CmpFree(CmHive, 0);
- ERR("Invalid hive Signature!\n");
- return FALSE;
- }
-
- Hive = &CmHive->Hive;
- KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, Hive->BaseBlock->RootCell);
- TRACE("KeyCell: %x\n", KeyCell);
- TRACE("KeyCell->Signature: %x\n", KeyCell->Signature);
- if (KeyCell->Signature != CM_KEY_NODE_SIGNATURE)
- {
- ERR("Invalid key cell Signature!\n");
- return FALSE;
- }
-
- TRACE("Subkeys: %u\n", KeyCell->SubKeyCounts);
- TRACE("Values: %u\n", KeyCell->ValueList.Count);
-
- /* Open 'System' key */
- Error = RegOpenKey(NULL, L"\\Registry\\Machine\\SYSTEM", &SystemKey);
- if (Error != ERROR_SUCCESS)
- {
- ERR("Failed to open 'system' key!\n");
- return FALSE;
- }
-
- /* Enumerate and add subkeys */
- if (KeyCell->SubKeyCounts[Stable] > 0)
- {
- HashCell = (PCM_KEY_FAST_INDEX)HvGetCell(Hive, KeyCell->SubKeyLists[Stable]);
- TRACE("HashCell: %x\n", HashCell);
- TRACE("SubKeyCounts: %x\n", KeyCell->SubKeyCounts[Stable]);
-
- for (i = 0; i < KeyCell->SubKeyCounts[Stable]; i++)
- {
- TRACE("Cell[%d]: %x\n", i, HashCell->List[i].Cell);
-
- SubKeyCell = (PCM_KEY_NODE)HvGetCell(Hive, HashCell->List[i].Cell);
-
- TRACE("SubKeyCell[%d]: %x\n", i, SubKeyCell);
-
- if (!RegImportSubKey(Hive, SubKeyCell, SystemKey))
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-/* EOF */
Added: trunk/reactos/boot/freeldr/freeldr/reactos/registry.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/react…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/reactos/registry.c (added)
+++ trunk/reactos/boot/freeldr/freeldr/reactos/registry.c [iso-8859-1] Sun Jan 12 21:37:29
2014
@@ -0,0 +1,589 @@
+/*
+ * FreeLoader
+ *
+ * Copyright (C) 2001, 2002 Timo Kreuzer <timo.kreuzer(a)reactos.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <freeldr.h>
+#include <cmlib.h>
+#include <debug.h>
+
+DBG_DEFAULT_CHANNEL(REGISTRY);
+
+static PCMHIVE CmHive;
+static PCM_KEY_NODE RootKeyNode;
+static FRLDRHKEY CurrentControlSetKey;
+
+BOOLEAN
+RegImportBinaryHive(
+ _In_ PCHAR ChunkBase,
+ _In_ ULONG ChunkSize)
+{
+ NTSTATUS Status;
+ TRACE("RegImportBinaryHive(%p, 0x%lx)\n", ChunkBase, ChunkSize);
+
+ /* Allocate and initialize the hive */
+ CmHive = FrLdrTempAlloc(sizeof(CMHIVE), 'eviH');
+ Status = HvInitialize(&CmHive->Hive,
+ HINIT_FLAT,
+ 0,
+ 0,
+ ChunkBase,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 1,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ CmpFree(CmHive, 0);
+ ERR("Invalid hive Signature!\n");
+ return FALSE;
+ }
+
+ /* Save the root key node */
+ RootKeyNode = HvGetCell(&CmHive->Hive, Hive->BaseBlock->RootCell);
+
+ TRACE("RegImportBinaryHive done\n");
+ return TRUE;
+}
+
+VOID
+RegInitializeRegistry(VOID)
+{
+ /* Nothing to do */
+}
+
+
+LONG
+RegInitCurrentControlSet(
+ _In_ BOOLEAN LastKnownGood)
+{
+ WCHAR ControlSetKeyName[80];
+ FRLDRHKEY SelectKey;
+ FRLDRHKEY SystemKey;
+ ULONG CurrentSet = 0;
+ ULONG DefaultSet = 0;
+ ULONG LastKnownGoodSet = 0;
+ ULONG DataSize;
+ LONG Error;
+ TRACE("RegInitCurrentControlSet\n");
+
+ Error = RegOpenKey(NULL,
+ L"\\Registry\\Machine\\SYSTEM\\Select",
+ &SelectKey);
+ if (Error != ERROR_SUCCESS)
+ {
+ ERR("RegOpenKey() failed (Error %u)\n", (int)Error);
+ return Error;
+ }
+
+ DataSize = sizeof(ULONG);
+ Error = RegQueryValue(SelectKey,
+ L"Default",
+ NULL,
+ (PUCHAR)&DefaultSet,
+ &DataSize);
+ if (Error != ERROR_SUCCESS)
+ {
+ ERR("RegQueryValue('Default') failed (Error %u)\n",
(int)Error);
+ return Error;
+ }
+
+ DataSize = sizeof(ULONG);
+ Error = RegQueryValue(SelectKey,
+ L"LastKnownGood",
+ NULL,
+ (PUCHAR)&LastKnownGoodSet,
+ &DataSize);
+ if (Error != ERROR_SUCCESS)
+ {
+ ERR("RegQueryValue('Default') failed (Error %u)\n",
(int)Error);
+ return Error;
+ }
+
+ CurrentSet = (LastKnownGood == TRUE) ? LastKnownGoodSet : DefaultSet;
+ wcscpy(ControlSetKeyName, L"ControlSet");
+ switch(CurrentSet)
+ {
+ case 1:
+ wcscat(ControlSetKeyName, L"001");
+ break;
+ case 2:
+ wcscat(ControlSetKeyName, L"002");
+ break;
+ case 3:
+ wcscat(ControlSetKeyName, L"003");
+ break;
+ case 4:
+ wcscat(ControlSetKeyName, L"004");
+ break;
+ case 5:
+ wcscat(ControlSetKeyName, L"005");
+ break;
+ }
+
+ Error = RegOpenKey(NULL,
+ L"\\Registry\\Machine\\SYSTEM",
+ &SystemKey);
+ if (Error != ERROR_SUCCESS)
+ {
+ ERR("RegOpenKey(SystemKey) failed (Error %lu)\n", Error);
+ return Error;
+ }
+
+ Error = RegOpenKey(SystemKey,
+ ControlSetKeyName,
+ &CurrentControlSetKey);
+ if (Error != ERROR_SUCCESS)
+ {
+ ERR("RegOpenKey(CurrentControlSetKey) failed (Error %lu)\n", Error);
+ return Error;
+ }
+
+ TRACE("RegInitCurrentControlSet done\n");
+ return ERROR_SUCCESS;
+}
+
+static
+BOOLEAN
+GetNextPathElement(
+ _Out_ PUNICODE_STRING NextElement,
+ _Inout_ PUNICODE_STRING RemainingPath)
+{
+ /* Check if there are any characters left */
+ if (RemainingPath->Length < sizeof(WCHAR))
+ {
+ /* Nothing left, bail out early */
+ return FALSE;
+ }
+
+ /* The next path elements starts with the remaining path */
+ NextElement->Buffer = RemainingPath->Buffer;
+
+ /* Loop until the path element ends */
+ while ((RemainingPath->Length >= sizeof(WCHAR)) &&
+ (RemainingPath->Buffer[0] != '\\'))
+ {
+ /* Skip this character */
+ RemainingPath->Buffer++;
+ RemainingPath->Length -= sizeof(WCHAR);
+ }
+
+ NextElement->Length = (RemainingPath->Buffer - NextElement->Buffer) *
sizeof(WCHAR);
+ NextElement->MaximumLength = NextElement->Length;
+
+ /* Check if the path element ended with a path separator */
+ if (RemainingPath->Length >= sizeof(WCHAR))
+ {
+ /* Skip the path separator */
+ ASSERT(RemainingPath->Buffer[0] == '\\');
+ RemainingPath->Buffer++;
+ RemainingPath->Length -= sizeof(WCHAR);
+ }
+
+ /* Return whether we got any characters */
+ 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;
+}
+
+// FIXME: optionally return the subkey node/handle as optimization
+LONG
+RegEnumKey(
+ _In_ FRLDRHKEY Key,
+ _In_ ULONG Index,
+ _Out_ PWCHAR Name,
+ _Inout_ ULONG* NameSize)
+{
+ PHHIVE Hive = &CmHive->Hive;
+ PCM_KEY_NODE KeyNode, SubKeyNode;
+ PCM_KEY_INDEX IndexCell;
+ PCM_KEY_FAST_INDEX HashCell;
+ TRACE("RegEnumKey(%p, %lu, %p, %p->%u)\n",
+ Key, Index, Name, NameSize, NameSize ? *NameSize : 0);
+
+ /* Get the key node */
+ KeyNode = (PCM_KEY_NODE)Key;
+ ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
+
+ /* Check if the index is valid */
+ if ((KeyNode->SubKeyCounts[Stable] == 0) ||
+ (Index >= KeyNode->SubKeyCounts[Stable]))
+ {
+ TRACE("RegEnumKey index out of bounds\n");
+ return ERROR_NO_MORE_ITEMS;
+ }
+
+ /* Get the index cell */
+ IndexCell = HvGetCell(Hive, KeyNode->SubKeyLists[Stable]);
+ TRACE("IndexCell: %x, SubKeyCounts: %x\n", IndexCell,
KeyNode->SubKeyCounts[Stable]);
+
+ /* Check the cell type */
+ if ((IndexCell->Signature == CM_KEY_FAST_LEAF) ||
+ (IndexCell->Signature == CM_KEY_HASH_LEAF))
+ {
+ /* Get the value cell */
+ HashCell = (PCM_KEY_FAST_INDEX)IndexCell;
+ SubKeyNode = HvGetCell(Hive, HashCell->List[Index].Cell);
+ }
+ else
+ {
+ ASSERT(FALSE);
+ }
+
+ *NameSize = CmCopyKeyName(SubKeyNode, Name, *NameSize);
+
+ TRACE("RegEnumKey done -> %u, '%.*s'\n", *NameSize, *NameSize,
Name);
+ return STATUS_SUCCESS;
+}
+
+LONG
+RegOpenKey(
+ _In_ FRLDRHKEY ParentKey,
+ _In_z_ PCWSTR KeyName,
+ _Out_ PFRLDRHKEY Key)
+{
+ UNICODE_STRING RemainingPath, SubKeyName;
+ UNICODE_STRING RegistryStartPath =
RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\SYSTEM");
+ UNICODE_STRING CurrentControlSet =
RTL_CONSTANT_STRING(L"CurrentControlSet");
+ PHHIVE Hive = &CmHive->Hive;
+ PCM_KEY_NODE KeyNode;
+ PCM_KEY_INDEX IndexCell;
+ TRACE("RegOpenKey(%p, '%S', %p)\n", ParentKey, KeyName, Key);
+
+ /* 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)
+ {
+ UNICODE_STRING SubKeyName1, SubKeyName2, SubKeyName3;
+ UNICODE_STRING RegistryPath = RTL_CONSTANT_STRING(L"Registry");
+ UNICODE_STRING MachinePath = RTL_CONSTANT_STRING(L"MACHINE");
+ UNICODE_STRING SystemPath = RTL_CONSTANT_STRING(L"SYSTEM");
+ TRACE("RegOpenKey: absolute path\n");
+
+ if ((RemainingPath.Length < sizeof(WCHAR)) ||
+ RemainingPath.Buffer[0] != '\\')
+ {
+ /* The key path is not absolute */
+ ERR("RegOpenKey: invalid path '%S' (%wZ)\n", KeyName,
&RemainingPath);
+ return ERROR_PATH_NOT_FOUND;
+ }
+
+ /* Skip initial path separator */
+ RemainingPath.Buffer++;
+ RemainingPath.Length -= sizeof(WCHAR);
+
+ /* Get the first 3 path elements */
+ GetNextPathElement(&SubKeyName1, &RemainingPath);
+ GetNextPathElement(&SubKeyName2, &RemainingPath);
+ GetNextPathElement(&SubKeyName3, &RemainingPath);
+ TRACE("RegOpenKey: %wZ / %wZ / %wZ\n", &SubKeyName1,
&SubKeyName2, &SubKeyName3);
+
+ /* Check if we have the correct path */
+ if (!RtlEqualUnicodeString(&SubKeyName1, &RegistryPath, TRUE) ||
+ !RtlEqualUnicodeString(&SubKeyName2, &MachinePath, TRUE) ||
+ !RtlEqualUnicodeString(&SubKeyName3, &SystemPath, TRUE))
+ {
+ /* The key path is not inside HKLM\Machine\System */
+ ERR("RegOpenKey: invalid path '%S' (%wZ)\n", KeyName,
&RemainingPath);
+ return ERROR_PATH_NOT_FOUND;
+ }
+
+ /* Use the root key */
+ KeyNode = RootKeyNode;
+ }
+
+ ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
+
+ /* Check if this is the root key */
+ if (KeyNode == RootKeyNode)
+ {
+ UNICODE_STRING TempPath = RemainingPath;
+
+ /* Get the first path element */
+ GetNextPathElement(&SubKeyName, &TempPath);
+
+ /* Check if this is CurrentControlSet */
+ if (RtlEqualUnicodeString(&SubKeyName, &CurrentControlSet, TRUE))
+ {
+ /* Use the CurrentControlSetKey and update the remaining path */
+ KeyNode = (PCM_KEY_NODE)CurrentControlSetKey;
+ RemainingPath = TempPath;
+ }
+ }
+
+ TRACE("RegOpenKey: RemainingPath '%wZ'\n", &RemainingPath);
+
+ /* Loop while there are path elements */
+ while (GetNextPathElement(&SubKeyName, &RemainingPath))
+ {
+ 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 */
+ KeyNode = RegpFindSubkeyInIndex(Hive, IndexCell, &SubKeyName);
+ if (KeyNode == NULL)
+ {
+
+ ERR("Did not find sub key '%wZ' (full %S)\n",
&RemainingPath, KeyName);
+ return ERROR_PATH_NOT_FOUND;
+ }
+ }
+
+ TRACE("RegOpenKey done\n");
+ *Key = (FRLDRHKEY)KeyNode;
+ return ERROR_SUCCESS;
+}
+
+static
+VOID
+RepGetValueData(
+ _In_ PHHIVE Hive,
+ _In_ PCM_KEY_VALUE ValueCell,
+ _Out_opt_ ULONG* Type,
+ _Out_opt_ PUCHAR Data,
+ _Inout_opt_ ULONG* DataSize)
+{
+ ULONG DataLength;
+
+ /* Does the caller want the type? */
+ if (Type != NULL)
+ {
+ *Type = ValueCell->Type;
+ }
+
+ /* Does the caller provide DataSize? */
+ if (DataSize != NULL)
+ {
+ /* Get the data length */
+ DataLength = ValueCell->DataLength & REG_DATA_SIZE_MASK;
+
+ /* Does the caller want the data? */
+ if ((Data != NULL) && (*DataSize != 0))
+ {
+ /* Check where the data is stored */
+ if ((DataLength <= sizeof(HCELL_INDEX)) &&
+ (ValueCell->DataLength & REG_DATA_IN_OFFSET))
+ {
+ /* 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 */
+ *DataSize = DataLength;
+ }
+}
+
+LONG
+RegQueryValue(
+ _In_ FRLDRHKEY Key,
+ _In_z_ PCWSTR ValueName,
+ _Out_opt_ ULONG* Type,
+ _Out_opt_ PUCHAR Data,
+ _Inout_opt_ ULONG* DataSize)
+{
+ PHHIVE Hive = &CmHive->Hive;
+ PCM_KEY_NODE KeyNode;
+ PCM_KEY_VALUE ValueCell;
+ PVALUE_LIST_CELL ValueListCell;
+ UNICODE_STRING ValueNameString;
+ ULONG i;
+ TRACE("RegQueryValue(%p, '%S', %p, %p, %p)\n",
+ Key, ValueName, Type, Data, DataSize);
+
+ /* Get the key node */
+ KeyNode = (PCM_KEY_NODE)Key;
+ 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 */
+ RtlInitUnicodeString(&ValueNameString, ValueName);
+
+ ValueListCell = (PVALUE_LIST_CELL)HvGetCell(Hive, KeyNode->ValueList.List);
+ TRACE("ValueListCell: %x\n", ValueListCell);
+
+ /* Loop all values */
+ for (i = 0; i < KeyNode->ValueList.Count; i++)
+ {
+ /* Get the subkey node and check the name */
+ ValueCell = HvGetCell(Hive, ValueListCell->ValueOffset[i]);
+
+ /* 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");
+ return ERROR_INVALID_PARAMETER;
+}
+
+
+LONG
+RegEnumValue(
+ _In_ FRLDRHKEY Key,
+ _In_ ULONG Index,
+ _Out_ PWCHAR ValueName,
+ _Inout_ ULONG* NameSize,
+ _Out_ ULONG* Type,
+ _Out_ PUCHAR Data,
+ _Inout_ ULONG* DataSize)
+{
+ PHHIVE Hive = &CmHive->Hive;
+ PCM_KEY_NODE KeyNode;
+ PCM_KEY_VALUE ValueCell;
+ PVALUE_LIST_CELL ValueListCell;
+ TRACE("RegEnumValue(%p, %lu, %S, %p, %p, %p, %p (%lu))\n",
+ Key, Index, ValueName, NameSize, Type, Data, DataSize, *DataSize);
+
+ /* Get the key node */
+ KeyNode = (PCM_KEY_NODE)Key;
+ ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
+
+ /* Check if the index is valid */
+ if ((KeyNode->ValueList.Count == 0) ||
+ (Index >= KeyNode->ValueList.Count))
+ {
+ ERR("RegEnumValue: index invalid\n");
+ return ERROR_NO_MORE_ITEMS;
+ }
+
+ ValueListCell = (PVALUE_LIST_CELL)HvGetCell(Hive, KeyNode->ValueList.List);
+ TRACE("ValueListCell: %x\n", ValueListCell);
+
+ /* Get the value cell */
+ ValueCell = HvGetCell(Hive, ValueListCell->ValueOffset[Index]);
+ ASSERT(ValueCell != NULL);
+
+ if (NameSize != NULL)
+ {
+ *NameSize = CmCopyKeyValueName(ValueCell, ValueName, *NameSize);
+ }
+
+ RepGetValueData(Hive, ValueCell, Type, Data, DataSize);
+
+ if (DataSize != NULL)
+ {
+ if ((Data != NULL) && (*DataSize != 0))
+ {
+ RtlCopyMemory(Data,
+ &ValueCell->Data,
+ min(*DataSize, ValueCell->DataLength));
+ }
+
+ *DataSize = ValueCell->DataLength;
+ }
+
+ TRACE("RegEnumValue done\n");
+ return STATUS_SUCCESS;
+}
+
+/* EOF */
Propchange: trunk/reactos/boot/freeldr/freeldr/reactos/registry.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/lib/cmlib/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/cmlib/CMakeLists.txt?r…
==============================================================================
--- trunk/reactos/lib/cmlib/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/lib/cmlib/CMakeLists.txt [iso-8859-1] Sun Jan 12 21:37:29 2014
@@ -6,6 +6,7 @@
list(APPEND SOURCE
cminit.c
+ cmtools.c
hivebin.c
hivecell.c
hiveinit.c
Modified: trunk/reactos/lib/cmlib/cmdata.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/cmlib/cmdata.h?rev=615…
==============================================================================
--- trunk/reactos/lib/cmlib/cmdata.h [iso-8859-1] (original)
+++ trunk/reactos/lib/cmlib/cmdata.h [iso-8859-1] Sun Jan 12 21:37:29 2014
@@ -11,6 +11,8 @@
#define REG_INIT_HASH_TABLE_SIZE 3
#define REG_EXTEND_HASH_TABLE_SIZE 4
#define REG_VALUE_LIST_CELL_MULTIPLE 4
+#define REG_DATA_SIZE_MASK 0x7FFFFFFF
+#define REG_DATA_IN_OFFSET 0x80000000
//
// Key Types
Modified: trunk/reactos/lib/cmlib/cmlib.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/cmlib/cmlib.h?rev=6159…
==============================================================================
--- trunk/reactos/lib/cmlib/cmlib.h [iso-8859-1] (original)
+++ trunk/reactos/lib/cmlib/cmlib.h [iso-8859-1] Sun Jan 12 21:37:29 2014
@@ -14,6 +14,11 @@
#include <typedefs.h>
#include <stdio.h>
#include <string.h>
+
+ #ifdef _WIN32
+ #define strncasecmp _strnicmp
+ #define strcasecmp _stricmp
+ #endif//_WIN32
// Definitions copied from <ntstatus.h>
// We only want to include host headers, so we define them manually
@@ -312,6 +317,49 @@
CmPrepareHive(
PHHIVE RegistryHive);
+BOOLEAN
+NTAPI
+CmCompareHash(
+ IN PCUNICODE_STRING KeyName,
+ IN PCHAR HashString,
+ IN BOOLEAN CaseInsensitive);
+
+BOOLEAN
+NTAPI
+CmComparePackedNames(
+ IN PCUNICODE_STRING Name,
+ IN PVOID NameBuffer,
+ IN USHORT NameBufferSize,
+ IN BOOLEAN NamePacked,
+ IN BOOLEAN CaseInsensitive);
+
+BOOLEAN
+NTAPI
+CmCompareKeyName(
+ IN PCM_KEY_NODE KeyCell,
+ IN PCUNICODE_STRING KeyName,
+ IN BOOLEAN CaseInsensitive);
+
+BOOLEAN
+NTAPI
+CmCompareKeyValueName(
+ IN PCM_KEY_VALUE ValueCell,
+ IN PCUNICODE_STRING KeyName,
+ IN BOOLEAN CaseInsensitive);
+
+ULONG
+NTAPI
+CmCopyKeyName(
+ IN PCM_KEY_NODE KeyNode,
+ _Out_ PWCHAR KeyNameBuffer,
+ _Inout_ ULONG BufferLength);
+
+ULONG
+NTAPI
+CmCopyKeyValueName(
+ _In_ PCM_KEY_VALUE ValueCell,
+ _Out_ PWCHAR ValueNameBuffer,
+ _Inout_ ULONG BufferLength);
BOOLEAN
CMAPI
Added: trunk/reactos/lib/cmlib/cmtools.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/cmlib/cmtools.c?rev=61…
==============================================================================
--- trunk/reactos/lib/cmlib/cmtools.c (added)
+++ trunk/reactos/lib/cmlib/cmtools.c [iso-8859-1] Sun Jan 12 21:37:29 2014
@@ -0,0 +1,222 @@
+/*
+ * PROJECT: registry manipulation library
+ * LICENSE: GPL - See COPYING in the top level directory
+ * COPYRIGHT: Copyright 2005 Filip Navara <navaraf(a)reactos.org>
+ * Copyright 2001 - 2005 Eric Kohl
+ */
+
+#include "cmlib.h"
+#define NDEBUG
+#include <debug.h>
+
+BOOLEAN
+NTAPI
+CmCompareHash(
+ IN PCUNICODE_STRING KeyName,
+ IN PCHAR HashString,
+ IN BOOLEAN CaseInsensitive)
+{
+ CHAR Buffer[4];
+
+ Buffer[0] = (KeyName->Length >= 2) ? (CHAR)KeyName->Buffer[0] : 0;
+ Buffer[1] = (KeyName->Length >= 4) ? (CHAR)KeyName->Buffer[1] : 0;
+ Buffer[2] = (KeyName->Length >= 6) ? (CHAR)KeyName->Buffer[2] : 0;
+ Buffer[3] = (KeyName->Length >= 8) ? (CHAR)KeyName->Buffer[3] : 0;
+
+ if (CaseInsensitive)
+ {
+ return (strncasecmp(Buffer, HashString, 4) == 0);
+ }
+ else
+ {
+ return (strncmp(Buffer, HashString, 4) == 0);
+ }
+}
+
+BOOLEAN
+NTAPI
+CmComparePackedNames(
+ IN PCUNICODE_STRING CompareName,
+ IN PVOID Name,
+ IN USHORT NameLength,
+ IN BOOLEAN NamePacked,
+ IN BOOLEAN CaseInsensitive)
+{
+ ULONG i;
+
+ if (NamePacked == TRUE)
+ {
+ PUCHAR PackedName = (PUCHAR)Name;
+
+ if (CompareName->Length != NameLength * sizeof(WCHAR))
+ {
+ //DPRINT1("Length doesn'T match %lu / %lu\n",
CompareName->Length, NameLength);
+ return FALSE;
+ }
+
+ if (CaseInsensitive)
+ {
+ for (i = 0; i < CompareName->Length / sizeof(WCHAR); i++)
+ {
+ //DbgPrint("%c/%c,",
+ // RtlUpcaseUnicodeChar(CompareName->Buffer[i]),
+ // RtlUpcaseUnicodeChar(PackedName[i]));
+ if (RtlUpcaseUnicodeChar(CompareName->Buffer[i]) !=
+ RtlUpcaseUnicodeChar(PackedName[i]))
+ {
+ //DbgPrint("\nFailed!\n");
+ return FALSE;
+ }
+ }
+ //DbgPrint("\nSuccess!\n");
+ }
+ else
+ {
+ for (i = 0; i < CompareName->Length / sizeof(WCHAR); i++)
+ {
+ if (CompareName->Buffer[i] != PackedName[i])
+ return FALSE;
+ }
+ }
+
+ }
+ else
+ {
+ PWCHAR UnicodeName = (PWCHAR)Name;
+
+ if (CompareName->Length != NameLength)
+ return FALSE;
+
+ if (CaseInsensitive)
+ {
+ for (i = 0; i < CompareName->Length / sizeof(WCHAR); i++)
+ {
+ if (RtlUpcaseUnicodeChar(CompareName->Buffer[i]) !=
+ RtlUpcaseUnicodeChar(UnicodeName[i]))
+ return FALSE;
+ }
+ }
+ else
+ {
+ for (i = 0; i < CompareName->Length / sizeof(WCHAR); i++)
+ {
+ if (CompareName->Buffer[i] != UnicodeName[i])
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+BOOLEAN
+NTAPI
+CmCompareKeyName(
+ IN PCM_KEY_NODE KeyNode,
+ IN PCUNICODE_STRING KeyName,
+ IN BOOLEAN CaseInsensitive)
+{
+ ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
+ return CmComparePackedNames(KeyName,
+ KeyNode->Name,
+ KeyNode->NameLength,
+ (KeyNode->Flags & KEY_COMP_NAME) ? TRUE : FALSE,
+ CaseInsensitive);
+}
+
+BOOLEAN
+NTAPI
+CmCompareKeyValueName(
+ IN PCM_KEY_VALUE ValueCell,
+ IN PCUNICODE_STRING ValueName,
+ IN BOOLEAN CaseInsensitive)
+{
+ ASSERT(ValueCell->Signature == CM_KEY_VALUE_SIGNATURE);
+ return CmComparePackedNames(ValueName,
+ ValueCell->Name,
+ ValueCell->NameLength,
+ (ValueCell->Flags & VALUE_COMP_NAME) ? TRUE :
FALSE,
+ CaseInsensitive);
+}
+
+ULONG
+NTAPI
+CmCopyPackedName(
+ _Out_ PWCHAR Buffer,
+ _In_ ULONG BufferLength,
+ _In_ PVOID Name,
+ _In_ USHORT NameLength,
+ _In_ BOOLEAN NamePacked)
+{
+ ULONG CharCount, i;
+ ASSERT(Name != 0);
+ ASSERT(NameLength != 0);
+
+ if (NamePacked == TRUE)
+ {
+ NameLength *= sizeof(WCHAR);
+ CharCount = min(BufferLength, NameLength) / sizeof(WCHAR);
+
+ if (Buffer != NULL)
+ {
+ PUCHAR PackedName = (PUCHAR)Name;
+
+ for (i = 0; i < CharCount; i++)
+ {
+ Buffer[i] = PackedName[i];
+ }
+ }
+ }
+ else
+ {
+ CharCount = min(BufferLength, NameLength) / sizeof(WCHAR);
+
+ if (Buffer != NULL)
+ {
+ PWCHAR UnicodeName = (PWCHAR)Name;
+
+ for (i = 0; i < CharCount; i++)
+ {
+ Buffer[i] = UnicodeName[i];
+ }
+ }
+ }
+
+ if (BufferLength >= NameLength + sizeof(UNICODE_NULL))
+ {
+ Buffer[NameLength / sizeof(WCHAR)] = '\0';
+ }
+
+ return NameLength + sizeof(WCHAR);
+}
+
+ULONG
+NTAPI
+CmCopyKeyName(
+ IN PCM_KEY_NODE KeyNode,
+ _Out_ PWCHAR KeyNameBuffer,
+ _Inout_ ULONG BufferLength)
+{
+ ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
+ return CmCopyPackedName(KeyNameBuffer,
+ BufferLength,
+ KeyNode->Name,
+ KeyNode->NameLength,
+ (KeyNode->Flags & KEY_COMP_NAME) ? TRUE : FALSE);
+}
+
+ULONG
+NTAPI
+CmCopyKeyValueName(
+ _In_ PCM_KEY_VALUE ValueCell,
+ _Out_ PWCHAR ValueNameBuffer,
+ _Inout_ ULONG BufferLength)
+{
+ ASSERT(ValueCell->Signature == CM_KEY_VALUE_SIGNATURE);
+ return CmCopyPackedName(ValueNameBuffer,
+ BufferLength,
+ ValueCell->Name,
+ ValueCell->NameLength,
+ (ValueCell->Flags & VALUE_COMP_NAME) ? TRUE : FALSE);
+}
Propchange: trunk/reactos/lib/cmlib/cmtools.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/tools/mkhive/cmi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/mkhive/cmi.c?rev=615…
==============================================================================
--- trunk/reactos/tools/mkhive/cmi.c [iso-8859-1] (original)
+++ trunk/reactos/tools/mkhive/cmi.c [iso-8859-1] Sun Jan 12 21:37:29 2014
@@ -442,82 +442,6 @@
return (strncasecmp(Buffer, HashString, 4) == 0);
}
-static BOOLEAN
-CmiCompareKeyNames(
- IN PCUNICODE_STRING KeyName,
- IN PCM_KEY_NODE KeyCell)
-{
- PWCHAR UnicodeName;
- USHORT i;
-
- if (KeyCell->Flags & KEY_COMP_NAME)
- {
- if (KeyName->Length != KeyCell->NameLength * sizeof(WCHAR))
- return FALSE;
-
- for (i = 0; i < KeyCell->NameLength; i++)
- {
- if (KeyName->Buffer[i] != ((PCHAR)KeyCell->Name)[i])
- return FALSE;
- }
- }
- else
- {
- if (KeyName->Length != KeyCell->NameLength)
- return FALSE;
-
- UnicodeName = (PWCHAR)KeyCell->Name;
- for (i = 0; i < KeyCell->NameLength / sizeof(WCHAR); i++)
- {
- if (KeyName->Buffer[i] != UnicodeName[i])
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-static BOOLEAN
-CmiCompareKeyNamesI(
- IN PCUNICODE_STRING KeyName,
- IN PCM_KEY_NODE KeyCell)
-{
- PWCHAR UnicodeName;
- USHORT i;
-
- DPRINT("Flags: %hx\n", KeyCell->Flags);
-
- if (KeyCell->Flags & KEY_COMP_NAME)
- {
- if (KeyName->Length != KeyCell->NameLength * sizeof(WCHAR))
- return FALSE;
-
- /* FIXME: use _strnicmp */
- for (i = 0; i < KeyCell->NameLength; i++)
- {
- if (RtlUpcaseUnicodeChar(KeyName->Buffer[i]) !=
- RtlUpcaseUnicodeChar(((PCHAR)KeyCell->Name)[i]))
- return FALSE;
- }
- }
- else
- {
- if (KeyName->Length != KeyCell->NameLength)
- return FALSE;
-
- UnicodeName = (PWCHAR)KeyCell->Name;
- /* FIXME: use _strnicmp */
- for (i = 0; i < KeyCell->NameLength / sizeof(WCHAR); i++)
- {
- if (RtlUpcaseUnicodeChar(KeyName->Buffer[i]) !=
- RtlUpcaseUnicodeChar(UnicodeName[i]))
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
NTSTATUS
CmiScanForSubKey(
IN PCMHIVE RegistryHive,
@@ -529,6 +453,7 @@
{
PCM_KEY_FAST_INDEX HashBlock;
PCM_KEY_NODE CurSubKeyCell;
+ BOOLEAN CaseInsensitive;
ULONG Storage;
ULONG i;
@@ -537,6 +462,7 @@
ASSERT(RegistryHive);
*pSubKeyCell = NULL;
+ CaseInsensitive = (Attributes & OBJ_CASE_INSENSITIVE) != 0;
for (Storage = Stable; Storage < HTYPE_COUNT; Storage++)
{
@@ -553,40 +479,20 @@
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
{
- if (Attributes & OBJ_CASE_INSENSITIVE)
- {
- if ((HashBlock->List[i].HashKey == 0
- || CmiCompareHashI(SubKeyName, (PCHAR)&HashBlock->List[i].HashKey)))
- {
- CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (
- &RegistryHive->Hive,
- HashBlock->List[i].Cell);
-
- if (CmiCompareKeyNamesI(SubKeyName, CurSubKeyCell))
- {
- *pSubKeyCell = CurSubKeyCell;
- *pBlockOffset = HashBlock->List[i].Cell;
- return STATUS_SUCCESS;
- }
- }
- }
- else
- {
- if ((HashBlock->List[i].HashKey == 0
- || CmiCompareHash(SubKeyName, (PCHAR)&HashBlock->List[i].HashKey)))
- {
- CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (
- &RegistryHive->Hive,
- HashBlock->List[i].Cell);
-
- if (CmiCompareKeyNames(SubKeyName, CurSubKeyCell))
- {
- *pSubKeyCell = CurSubKeyCell;
- *pBlockOffset = HashBlock->List[i].Cell;
- return STATUS_SUCCESS;
- }
- }
- }
+ if ((HashBlock->List[i].HashKey == 0) ||
+ (CmCompareHash(SubKeyName, (PCHAR)&HashBlock->List[i].HashKey,
CaseInsensitive)))
+ {
+ CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (
+ &RegistryHive->Hive,
+ HashBlock->List[i].Cell);
+
+ if (CmCompareKeyName(CurSubKeyCell, SubKeyName, CaseInsensitive))
+ {
+ *pSubKeyCell = CurSubKeyCell;
+ *pBlockOffset = HashBlock->List[i].Cell;
+ return STATUS_SUCCESS;
+ }
+ }
}
}
@@ -754,44 +660,6 @@
return STATUS_SUCCESS;
}
-static BOOLEAN
-CmiComparePackedNames(
- IN PCUNICODE_STRING Name,
- IN PUCHAR NameBuffer,
- IN USHORT NameBufferSize,
- IN BOOLEAN NamePacked)
-{
- PWCHAR UNameBuffer;
- ULONG i;
-
- if (NamePacked == TRUE)
- {
- if (Name->Length != NameBufferSize * sizeof(WCHAR))
- return FALSE;
-
- for (i = 0; i < Name->Length / sizeof(WCHAR); i++)
- {
- if (RtlUpcaseUnicodeChar(Name->Buffer[i]) !=
RtlUpcaseUnicodeChar((WCHAR)NameBuffer[i]))
- return FALSE;
- }
- }
- else
- {
- if (Name->Length != NameBufferSize)
- return FALSE;
-
- UNameBuffer = (PWCHAR)NameBuffer;
-
- for (i = 0; i < Name->Length / sizeof(WCHAR); i++)
- {
- if (RtlUpcaseUnicodeChar(Name->Buffer[i]) != RtlUpcaseUnicodeChar(UNameBuffer[i]))
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
NTSTATUS
CmiScanForValueKey(
IN PCMHIVE RegistryHive,
@@ -823,11 +691,11 @@
&RegistryHive->Hive,
ValueListCell->ValueOffset[i]);
- if (CmiComparePackedNames(
- ValueName,
- (PUCHAR)CurValueCell->Name,
- CurValueCell->NameLength,
- (BOOLEAN)((CurValueCell->Flags & VALUE_COMP_NAME) ? TRUE : FALSE)))
+ if (CmComparePackedNames(ValueName,
+ (PUCHAR)CurValueCell->Name,
+ CurValueCell->NameLength,
+ (CurValueCell->Flags & VALUE_COMP_NAME) ? TRUE :
FALSE,
+ TRUE))
{
*pValueCell = CurValueCell;
*pValueCellOffset = ValueListCell->ValueOffset[i];
Modified: trunk/reactos/tools/mkhive/mkhive.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/mkhive/mkhive.h?rev=…
==============================================================================
--- trunk/reactos/tools/mkhive/mkhive.h [iso-8859-1] (original)
+++ trunk/reactos/tools/mkhive/mkhive.h [iso-8859-1] Sun Jan 12 21:37:29 2014
@@ -130,13 +130,6 @@
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
-#ifdef _WIN32
-#define strncasecmp _strnicmp
-#define strcasecmp _stricmp
-#else
-#include <string.h>
-#endif//_WIN32
-
#ifndef _MSC_VER
#define _In_
#define _Out_