[ros-diffs] [ion] 26757: - Fix critical bug in CmpCopyName, it wasn't compressing names at all. - Implement new cmlib routines: HvIsCellAllocated, Doesn't really work fully since we don't support mapped-file hives, but works for the kinds of hives we currently use. HvIsCellDirty, should work as expected. - Implement new cm routines: CmpMarkValueDataDirty, CmpFreeValueData, CmpFreeValue. There are generic so they can deal with Big, Small or Normal keys. - Implement CmpAddValueToList, CmpSetValueDataNew. - Add RtlCheckBit to winddk.h, it's inlined instead of being an actual function call.

ion at svn.reactos.org ion at svn.reactos.org
Sun May 13 18:58:55 CEST 2007


Author: ion
Date: Sun May 13 20:58:54 2007
New Revision: 26757

URL: http://svn.reactos.org/svn/reactos?rev=26757&view=rev
Log:
- Fix critical bug in CmpCopyName, it wasn't compressing names at all.
- Implement new cmlib routines: HvIsCellAllocated, Doesn't really work fully since we don't support mapped-file hives, but works for the kinds of hives we currently use. HvIsCellDirty, should work as expected.
- Implement new cm routines: CmpMarkValueDataDirty, CmpFreeValueData, CmpFreeValue. There are generic so they can deal with Big, Small or Normal keys.
- Implement CmpAddValueToList, CmpSetValueDataNew.
- Add RtlCheckBit to winddk.h, it's inlined instead of being an actual function call.

Modified:
    trunk/reactos/include/ddk/winddk.h
    trunk/reactos/lib/cmlib/cmlib.h
    trunk/reactos/lib/cmlib/hivecell.c
    trunk/reactos/lib/cmlib/hivedata.h
    trunk/reactos/ntoskrnl/config/cm.h
    trunk/reactos/ntoskrnl/config/cmname.c
    trunk/reactos/ntoskrnl/config/cmvalue.c

Modified: trunk/reactos/include/ddk/winddk.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/winddk.h?rev=26757&r1=26756&r2=26757&view=diff
==============================================================================
--- trunk/reactos/include/ddk/winddk.h (original)
+++ trunk/reactos/include/ddk/winddk.h Sun May 13 20:58:54 2007
@@ -4277,6 +4277,8 @@
   PULONG  Buffer;
 } RTL_BITMAP, *PRTL_BITMAP;
 
+#define RtlCheckBit(BMH,BP) (((((PLONG)(BMH)->Buffer)[(BP) / 32]) >> ((BP) % 32)) & 0x1)
+
 typedef struct _RTL_BITMAP_RUN {
     ULONG  StartingIndex;
     ULONG  NumberOfBits;
@@ -5806,12 +5808,14 @@
   IN ULONG  Base  OPTIONAL,
   IN OUT PULONG  Value);
 
+#if 0
 NTSYSAPI
 ULONG
 NTAPI
 RtlCheckBit(
   IN PRTL_BITMAP  BitMapHeader,
   IN ULONG  BitPosition);
+#endif
 
 NTSYSAPI
 NTSTATUS

Modified: trunk/reactos/lib/cmlib/cmlib.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/cmlib/cmlib.h?rev=26757&r1=26756&r2=26757&view=diff
==============================================================================
--- trunk/reactos/lib/cmlib/cmlib.h (original)
+++ trunk/reactos/lib/cmlib/cmlib.h Sun May 13 20:58:54 2007
@@ -183,6 +183,12 @@
    SIZE_T Size,
    HV_STORAGE_TYPE Storage);
 
+BOOLEAN CMAPI
+HvIsCellAllocated(
+    IN PHHIVE RegistryHive,
+    IN HCELL_INDEX CellIndex
+);
+
 HCELL_INDEX CMAPI
 HvReallocateCell(
    PHHIVE RegistryHive,
@@ -198,6 +204,12 @@
 HvMarkCellDirty(
    PHHIVE RegistryHive,
    HCELL_INDEX CellOffset);
+
+BOOLEAN CMAPI
+HvIsCellDirty(
+    IN PHHIVE Hive,
+    IN HCELL_INDEX Cell
+);
 
 BOOLEAN CMAPI
 HvSyncHive(

Modified: trunk/reactos/lib/cmlib/hivecell.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/cmlib/hivecell.c?rev=26757&r1=26756&r2=26757&view=diff
==============================================================================
--- trunk/reactos/lib/cmlib/hivecell.c (original)
+++ trunk/reactos/lib/cmlib/hivecell.c Sun May 13 20:58:54 2007
@@ -39,6 +39,32 @@
    }
 }
 
+BOOLEAN CMAPI
+HvIsCellAllocated(IN PHHIVE RegistryHive,
+                  IN HCELL_INDEX CellIndex)
+{
+    ULONG Type, Block;
+
+    /* If it's a flat hive, the cell is always allocated */
+    if (RegistryHive->Flat) return TRUE;
+
+    /* Otherwise, get the type and make sure it's valid */
+    Type = HvGetCellType(CellIndex);
+    if (((CellIndex % ~HCELL_TYPE_MASK) > RegistryHive->Storage[Type].Length) ||
+        (CellIndex % (RegistryHive->Version >= 2 ? 8 : 16)))
+    {
+        /* Invalid cell index */
+        return FALSE;
+    }
+
+    /* Try to get the cell block */
+    Block = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
+    if (RegistryHive->Storage[Type].BlockList[Block].Block) return TRUE;
+
+    /* No valid block, fail */
+    return FALSE;
+}
+
 PVOID CMAPI
 HvGetCell(
    PHHIVE RegistryHive,
@@ -92,6 +118,20 @@
 
    RtlSetBits(&RegistryHive->DirtyVector,
               CellBlock, CellLastBlock - CellBlock);
+}
+
+BOOLEAN CMAPI
+HvIsCellDirty(IN PHHIVE Hive,
+              IN HCELL_INDEX Cell)
+{
+    /* Sanity checks */
+    ASSERT(Hive->ReadOnly == FALSE);
+
+    /* Volatile cells are always "dirty" */
+    if (HvGetCellType(Cell) == HvVolatile) return TRUE;
+
+    /* Check if the dirty bit is set */
+    return RtlCheckBit(&Hive->DirtyVector, Cell / HV_BLOCK_SIZE);
 }
 
 static ULONG __inline CMAPI

Modified: trunk/reactos/lib/cmlib/hivedata.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/cmlib/hivedata.h?rev=26757&r1=26756&r2=26757&view=diff
==============================================================================
--- trunk/reactos/lib/cmlib/hivedata.h (original)
+++ trunk/reactos/lib/cmlib/hivedata.h Sun May 13 20:58:54 2007
@@ -39,6 +39,9 @@
 #define HCELL_TYPE_SHIFT               31
 #define HCELL_BLOCK_SHIFT              12
 #define HCELL_OFFSET_SHIFT             0
+
+#define HvGetCellType(Cell)             \
+    ((ULONG)((Cell & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT))
 
 #include <pshpack1.h>
 

Modified: trunk/reactos/ntoskrnl/config/cm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cm.h?rev=26757&r1=26756&r2=26757&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/config/cm.h (original)
+++ trunk/reactos/ntoskrnl/config/cm.h Sun May 13 20:58:54 2007
@@ -35,6 +35,13 @@
 #else
 #define CMTRACE(x, ...) DPRINT(__VA_ARGS__)
 #endif
+
+
+//
+// Hack since bigkeys are not yet supported
+//
+#define ASSERT_VALUE_BIG(h, s)                          \
+    ASSERTMSG("Big keys not supported!", !CmpIsKeyValueBig(h, s));
 
 //
 // Tag for all registry allocations
@@ -678,6 +685,8 @@
 extern KTIMER CmiWorkerTimer;
 VOID NTAPI CmiWorkerThread(IN PVOID Param);
 PVOID NTAPI CmpRosGetHardwareHive(OUT PULONG Length);
+NTSTATUS CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1, IN PVOID Argument2);
+VOID CmiSyncHives(VOID);
 #define HIVE_NO_FILE    0x00000002
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -1010,6 +1019,34 @@
     IN PHHIVE Hive,
     IN PCM_KEY_VALUE Value,
     OUT PULONG Length
+);
+
+NTSTATUS
+NTAPI
+CmpSetValueDataNew(
+    IN PHHIVE Hive,
+    IN PVOID Data,
+    IN ULONG DataSize,
+    IN ULONG StorageType,
+    IN HCELL_INDEX ValueCell,
+    OUT PHCELL_INDEX DataCell
+);
+
+NTSTATUS
+NTAPI
+CmpAddValueToList(
+    IN PHHIVE Hive,
+    IN HCELL_INDEX ValueCell,
+    IN ULONG Index,
+    IN ULONG Type,
+    IN OUT PCHILD_LIST ChildList
+);
+
+BOOLEAN
+NTAPI
+CmpFreeValue(
+    IN PHHIVE Hive,
+    IN HCELL_INDEX Cell
 );
 
 //

Modified: trunk/reactos/ntoskrnl/config/cmname.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmname.c?rev=26757&r1=26756&r2=26757&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmname.c (original)
+++ trunk/reactos/ntoskrnl/config/cmname.c Sun May 13 20:58:54 2007
@@ -45,7 +45,7 @@
         }
 
         /* Copy this character */
-        Destination[i] = Source->Buffer[i];
+        ((PCHAR)Destination)[i] = (CHAR)(Source->Buffer[i]);
     }
 
     /* Compressed name, return length */

Modified: trunk/reactos/ntoskrnl/config/cmvalue.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmvalue.c?rev=26757&r1=26756&r2=26757&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmvalue.c (original)
+++ trunk/reactos/ntoskrnl/config/cmvalue.c Sun May 13 20:58:54 2007
@@ -13,9 +13,87 @@
 #define NDEBUG
 #include "debug.h"
 
-/* GLOBALS *******************************************************************/
-
 /* FUNCTIONS *****************************************************************/
+
+BOOLEAN
+NTAPI
+CmpMarkValueDataDirty(IN PHHIVE Hive,
+                      IN PCM_KEY_VALUE Value)
+{
+    ULONG KeySize;
+    PAGED_CODE();
+
+    /* Make sure there's actually any data */
+    if (Value->Data != HCELL_NIL)
+    {
+        /* If this is a small key, there's no need to have it dirty */
+        if (CmpIsKeyValueSmall(&KeySize, Value->DataLength)) return TRUE;
+
+        /* Check if this is a big key */
+        ASSERT_VALUE_BIG(Hive, KeySize);
+
+        /* Normal value, just mark it dirty */
+        HvMarkCellDirty(Hive, Value->Data);
+    }
+
+    /* Operation complete */
+    return TRUE;
+}
+
+BOOLEAN
+NTAPI
+CmpFreeValueData(IN PHHIVE Hive,
+                 IN HCELL_INDEX DataCell,
+                 IN ULONG DataLength)
+{
+    ULONG KeySize;
+    PAGED_CODE();
+
+    /* If this is a small key, the data is built-in */
+    if (!CmpIsKeyValueSmall(&KeySize, DataLength))
+    {
+        /* If there's no data cell, there's nothing to do */
+        if (DataCell == HCELL_NIL) return TRUE;
+
+        /* Make sure the data cell is allocated */
+        ASSERT(HvIsCellAllocated(Hive, DataCell));
+
+        /* Unsupported value type */
+        ASSERT_VALUE_BIG(Hive, KeySize);
+
+        /* Normal value, just free the data cell */
+        HvFreeCell(Hive, DataCell);
+    }
+
+    /* Operation complete */
+    return TRUE;
+}
+
+BOOLEAN
+NTAPI
+CmpFreeValue(IN PHHIVE Hive,
+             IN HCELL_INDEX Cell)
+{
+    PCM_KEY_VALUE Value;
+    PAGED_CODE();
+
+    /* Get the cell data */
+    Value = (PCM_KEY_VALUE)HvGetCell(Hive, Cell);
+    if (!Value) ASSERT(FALSE);
+
+    /* Free it */
+    if (!CmpFreeValueData(Hive, Value->Data, Value->DataLength))
+    {
+        /* We failed to free the data, return failure */
+        HvReleaseCell(Hive, Cell);
+        return FALSE;
+    }
+
+    /* Release the cell and free it */
+    HvReleaseCell(Hive, Cell);
+    HvFreeCell(Hive, Cell);
+    return TRUE;
+}
 
 HCELL_INDEX
 NTAPI
@@ -67,13 +145,8 @@
         return TRUE;
     }
 
-    /* Check if this is a big cell */
-    if (CmpIsKeyValueBig(Hive, *Length))
-    {
-        /* FIXME: We don't support big cells */
-        DPRINT1("Unsupported cell type!\n");
-        while (TRUE);
-    }
+    /* Unsupported */
+    ASSERT_VALUE_BIG(Hive, *Length);
 
     /* Get the data from the cell */
     *Buffer = HvGetCell(Hive, Value->Data);
@@ -123,3 +196,114 @@
     /* Otherwise, return the cell data */
     return Buffer;
 }
+
+NTSTATUS
+NTAPI
+CmpAddValueToList(IN PHHIVE Hive,
+                  IN HCELL_INDEX ValueCell,
+                  IN ULONG Index,
+                  IN ULONG Type,
+                  IN OUT PCHILD_LIST ChildList)
+{
+    HCELL_INDEX ListCell;
+    ULONG ChildCount, Length, i;
+    PCELL_DATA CellData;
+    PAGED_CODE();
+
+    /* Sanity check */
+    ASSERT((((LONG)Index) >= 0) && (Index <= ChildList->Count));
+
+    /* Get the number of entries in the child list */
+    ChildCount = ChildList->Count;
+    ChildCount++;
+    if (ChildCount > 1)
+    {
+        /* The cell should be dirty at this point */
+        ASSERT(HvIsCellDirty(Hive, ChildList->List));
+
+        /* Check if we have less then 100 children */
+        if (ChildCount < 100)
+        {
+            /* Allocate just enough as requested */
+            Length = ChildCount * sizeof(HCELL_INDEX);
+        }
+        else
+        {
+            /* Otherwise, we have quite a few, so allocate a batch */
+            Length = ROUND_UP(ChildCount, 100) * sizeof(HCELL_INDEX);
+            if (Length > HBLOCK_SIZE)
+            {
+                /* But make sure we don't allocate beyond our block size */
+                Length = ROUND_UP(Length, HBLOCK_SIZE);
+            }
+        }
+
+        /* Perform the allocation */
+        ListCell = HvReallocateCell(Hive, ChildList->List, Length);
+    }
+    else
+    {
+        /* This is our first child, so allocate a single cell */
+        ListCell = HvAllocateCell(Hive, sizeof(HCELL_INDEX), Type);
+    }
+
+    /* Fail if we couldn't get a cell */
+    if (!ListCell) return STATUS_INSUFFICIENT_RESOURCES;
+
+    /* Set this cell as the child list's list cell */
+    ChildList->List = ListCell;
+
+    /* Get the actual key list memory */
+    CellData = HvGetCell(Hive, ListCell);
+    if (!CellData) ASSERT(FALSE);
+
+    /* Loop all the children */
+    for (i = ChildCount - 1; i > Index; i--)
+    {
+        /* Move them all down */
+        CellData->u.KeyList[i] = CellData->u.KeyList[i - 1];
+    }
+
+    /* Insert us on top now */
+    CellData->u.KeyList[Index] = ValueCell;
+    ChildList->Count = ChildCount;
+
+    /* Release the list cell and make sure the value cell is dirty */
+    HvReleaseCell(Hive, ListCell);
+    ASSERT(HvIsCellDirty(Hive, ValueCell));
+
+    /* We're done here */
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+CmpSetValueDataNew(IN PHHIVE Hive,
+                   IN PVOID Data,
+                   IN ULONG DataSize,
+                   IN ULONG StorageType,
+                   IN HCELL_INDEX ValueCell,
+                   OUT PHCELL_INDEX DataCell)
+{
+    PCELL_DATA CellData;
+    PAGED_CODE();
+    ASSERT(DataSize > CM_KEY_VALUE_SMALL);
+
+    /* Check if this is a big key */
+    ASSERT_VALUE_BIG(Hive, DataSize);
+
+    /* Allocate a data cell */
+    *DataCell = HvAllocateCell(Hive, DataSize, StorageType);
+    if (*DataCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
+
+    /* Get the actual data */
+    CellData = HvGetCell(Hive, *DataCell);
+    if (!CellData) ASSERT(FALSE);
+
+    /* Copy our buffer into it */
+    RtlCopyMemory(CellData, Data, DataSize);
+
+    /* All done */
+    return STATUS_SUCCESS;
+}
+




More information about the Ros-diffs mailing list