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