[MKHIVE] Simplify CmiAddValueKey() by using CmpAddValueToList().
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 14 Oct 2018 13:14:52 +0000 (15:14 +0200)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 14 Oct 2018 13:59:50 +0000 (15:59 +0200)
sdk/tools/mkhive/cmi.c
sdk/tools/mkhive/cmi.h
sdk/tools/mkhive/registry.c

index 34f8580..6856cd1 100644 (file)
@@ -21,7 +21,8 @@
  * PROJECT:         ReactOS hive maker
  * FILE:            tools/mkhive/cmi.c
  * PURPOSE:         Registry file manipulation routines
- * PROGRAMMER:      Hervé Poussineau
+ * PROGRAMMERS:     Hervé Poussineau
+ *                  Hermès Bélusca-Maïto
  */
 
 #define NDEBUG
@@ -343,62 +344,17 @@ NTSTATUS
 CmiAddValueKey(
     IN PCMHIVE RegistryHive,
     IN PCM_KEY_NODE Parent,
+    IN ULONG ChildIndex,
     IN PCUNICODE_STRING ValueName,
     OUT PCM_KEY_VALUE *pValueCell,
     OUT HCELL_INDEX *pValueCellOffset)
 {
-    PCELL_DATA ValueListCell;
+    NTSTATUS Status;
+    HSTORAGE_TYPE Storage;
     PCM_KEY_VALUE NewValueCell;
-    HCELL_INDEX ValueListCellOffset;
     HCELL_INDEX NewValueCellOffset;
-    ULONG CellSize;
-    HSTORAGE_TYPE Storage;
-
-#ifndef FIELD_SIZE
-#define FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
-#endif
 
     Storage = (Parent->Flags & KEY_IS_VOLATILE) ? Volatile : Stable;
-    if (Parent->ValueList.List == HCELL_NIL)
-    {
-        /* Allocate some room for the value list */
-        CellSize = FIELD_SIZE(CELL_DATA, u.KeyList) + (3 * sizeof(HCELL_INDEX));
-        ValueListCellOffset = HvAllocateCell(&RegistryHive->Hive, CellSize, Storage, HCELL_NIL);
-        if (ValueListCellOffset == HCELL_NIL)
-            return STATUS_INSUFFICIENT_RESOURCES;
-
-        ValueListCell = (PCELL_DATA)HvGetCell(&RegistryHive->Hive, ValueListCellOffset);
-        if (!ValueListCell)
-        {
-            HvFreeCell(&RegistryHive->Hive, ValueListCellOffset);
-            return STATUS_UNSUCCESSFUL;
-        }
-
-        Parent->ValueList.List = ValueListCellOffset;
-    }
-    else
-    {
-        ValueListCell = (PCELL_DATA)HvGetCell(&RegistryHive->Hive, Parent->ValueList.List);
-        if (!ValueListCell)
-            return STATUS_UNSUCCESSFUL;
-
-        CellSize = ABS_VALUE(HvGetCellSize(&RegistryHive->Hive, ValueListCell));
-
-        if (Parent->ValueList.Count >= CellSize / sizeof(HCELL_INDEX))
-        {
-            CellSize *= 2;
-            ValueListCellOffset = HvReallocateCell(&RegistryHive->Hive, Parent->ValueList.List, CellSize);
-            if (ValueListCellOffset == HCELL_NIL)
-                return STATUS_INSUFFICIENT_RESOURCES;
-
-            ValueListCell = (PCELL_DATA)HvGetCell(&RegistryHive->Hive, ValueListCellOffset);
-            if (!ValueListCell)
-                return STATUS_UNSUCCESSFUL;
-
-            Parent->ValueList.List = ValueListCellOffset;
-        }
-    }
-
 
     NewValueCellOffset = HvAllocateCell(&RegistryHive->Hive,
                                FIELD_OFFSET(CM_KEY_VALUE, Name) +
@@ -438,15 +394,35 @@ CmiAddValueKey(
     NewValueCell->DataLength = 0;
     NewValueCell->Data = HCELL_NIL;
 
+    HvMarkCellDirty(&RegistryHive->Hive, NewValueCellOffset, FALSE);
 
-    ValueListCell->u.KeyList[Parent->ValueList.Count] = NewValueCellOffset;
-    Parent->ValueList.Count++;
+    /* Check if we already have a value list */
+    if (Parent->ValueList.Count)
+    {
+        /* Then make sure it's valid and dirty it */
+        ASSERT(Parent->ValueList.List != HCELL_NIL);
+        HvMarkCellDirty(&RegistryHive->Hive, Parent->ValueList.List, FALSE);
+    }
 
-    HvMarkCellDirty(&RegistryHive->Hive, Parent->ValueList.List, FALSE);
-    HvMarkCellDirty(&RegistryHive->Hive, NewValueCellOffset, FALSE);
+    /* Add this value cell to the child list */
+    Status = CmpAddValueToList(&RegistryHive->Hive,
+                               NewValueCellOffset,
+                               ChildIndex,
+                               Storage,
+                               &Parent->ValueList);
 
-    *pValueCell = NewValueCell;
-    *pValueCellOffset = NewValueCellOffset;
+    /* If we failed, free the entire cell, including the data */
+    if (!NT_SUCCESS(Status))
+    {
+        /* Overwrite the status with a known one */
+        CmpFreeValue(&RegistryHive->Hive, NewValueCellOffset);
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+    }
+    else
+    {
+        *pValueCell = NewValueCell;
+        *pValueCellOffset = NewValueCellOffset;
+    }
 
-    return STATUS_SUCCESS;
+    return Status;
 }
index 2d17623..88611c2 100644 (file)
@@ -50,6 +50,7 @@ NTSTATUS
 CmiAddValueKey(
     IN PCMHIVE RegistryHive,
     IN PCM_KEY_NODE Parent,
+    IN ULONG ChildIndex,
     IN PCUNICODE_STRING ValueName,
     OUT PCM_KEY_VALUE *pValueCell,
     OUT HCELL_INDEX *pValueCellOffset);
index cd238dc..432b3df 100644 (file)
@@ -557,6 +557,7 @@ RegSetValueExW(
     PHHIVE Hive;
     PCM_KEY_NODE KeyNode; // ParentNode
     PCM_KEY_VALUE ValueCell;
+    ULONG ChildIndex;
     HCELL_INDEX CellIndex;
     UNICODE_STRING ValueNameString;
 
@@ -600,12 +601,24 @@ RegSetValueExW(
 
     /* Initialize value name string */
     RtlInitUnicodeString(&ValueNameString, lpValueName);
-    CellIndex = CmpFindValueByName(Hive, KeyNode, &ValueNameString);
+    if (!CmpFindNameInList(Hive,
+                           &KeyNode->ValueList,
+                           &ValueNameString,
+                           &ChildIndex,
+                           &CellIndex))
+    {
+        /* Sanity check */
+        ASSERT(CellIndex == HCELL_NIL);
+        /* Fail */
+        // Status = STATUS_INSUFFICIENT_RESOURCES;
+        return ERROR_UNSUCCESSFUL;
+    }
     if (CellIndex == HCELL_NIL)
     {
         /* The value doesn't exist, create a new one */
         Status = CmiAddValueKey(Key->RegistryHive,
                                 KeyNode,
+                                ChildIndex,
                                 &ValueNameString,
                                 &ValueCell,
                                 &CellIndex);