mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 19:22:58 +00:00
- 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. svn path=/trunk/; revision=26757
This commit is contained in:
parent
75685e5dd4
commit
779a784f15
7 changed files with 290 additions and 10 deletions
|
@ -4277,6 +4277,8 @@ typedef struct _RTL_BITMAP {
|
||||||
PULONG Buffer;
|
PULONG Buffer;
|
||||||
} RTL_BITMAP, *PRTL_BITMAP;
|
} RTL_BITMAP, *PRTL_BITMAP;
|
||||||
|
|
||||||
|
#define RtlCheckBit(BMH,BP) (((((PLONG)(BMH)->Buffer)[(BP) / 32]) >> ((BP) % 32)) & 0x1)
|
||||||
|
|
||||||
typedef struct _RTL_BITMAP_RUN {
|
typedef struct _RTL_BITMAP_RUN {
|
||||||
ULONG StartingIndex;
|
ULONG StartingIndex;
|
||||||
ULONG NumberOfBits;
|
ULONG NumberOfBits;
|
||||||
|
@ -5806,12 +5808,14 @@ RtlCharToInteger(
|
||||||
IN ULONG Base OPTIONAL,
|
IN ULONG Base OPTIONAL,
|
||||||
IN OUT PULONG Value);
|
IN OUT PULONG Value);
|
||||||
|
|
||||||
|
#if 0
|
||||||
NTSYSAPI
|
NTSYSAPI
|
||||||
ULONG
|
ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlCheckBit(
|
RtlCheckBit(
|
||||||
IN PRTL_BITMAP BitMapHeader,
|
IN PRTL_BITMAP BitMapHeader,
|
||||||
IN ULONG BitPosition);
|
IN ULONG BitPosition);
|
||||||
|
#endif
|
||||||
|
|
||||||
NTSYSAPI
|
NTSYSAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -183,6 +183,12 @@ HvAllocateCell(
|
||||||
SIZE_T Size,
|
SIZE_T Size,
|
||||||
HV_STORAGE_TYPE Storage);
|
HV_STORAGE_TYPE Storage);
|
||||||
|
|
||||||
|
BOOLEAN CMAPI
|
||||||
|
HvIsCellAllocated(
|
||||||
|
IN PHHIVE RegistryHive,
|
||||||
|
IN HCELL_INDEX CellIndex
|
||||||
|
);
|
||||||
|
|
||||||
HCELL_INDEX CMAPI
|
HCELL_INDEX CMAPI
|
||||||
HvReallocateCell(
|
HvReallocateCell(
|
||||||
PHHIVE RegistryHive,
|
PHHIVE RegistryHive,
|
||||||
|
@ -199,6 +205,12 @@ HvMarkCellDirty(
|
||||||
PHHIVE RegistryHive,
|
PHHIVE RegistryHive,
|
||||||
HCELL_INDEX CellOffset);
|
HCELL_INDEX CellOffset);
|
||||||
|
|
||||||
|
BOOLEAN CMAPI
|
||||||
|
HvIsCellDirty(
|
||||||
|
IN PHHIVE Hive,
|
||||||
|
IN HCELL_INDEX Cell
|
||||||
|
);
|
||||||
|
|
||||||
BOOLEAN CMAPI
|
BOOLEAN CMAPI
|
||||||
HvSyncHive(
|
HvSyncHive(
|
||||||
PHHIVE RegistryHive);
|
PHHIVE RegistryHive);
|
||||||
|
|
|
@ -39,6 +39,32 @@ HvpGetCellHeader(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
PVOID CMAPI
|
||||||
HvGetCell(
|
HvGetCell(
|
||||||
PHHIVE RegistryHive,
|
PHHIVE RegistryHive,
|
||||||
|
@ -94,6 +120,20 @@ HvMarkCellDirty(
|
||||||
CellBlock, CellLastBlock - CellBlock);
|
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
|
static ULONG __inline CMAPI
|
||||||
HvpComputeFreeListIndex(
|
HvpComputeFreeListIndex(
|
||||||
ULONG Size)
|
ULONG Size)
|
||||||
|
|
|
@ -40,6 +40,9 @@ typedef ULONG HCELL_INDEX, *PHCELL_INDEX;
|
||||||
#define HCELL_BLOCK_SHIFT 12
|
#define HCELL_BLOCK_SHIFT 12
|
||||||
#define HCELL_OFFSET_SHIFT 0
|
#define HCELL_OFFSET_SHIFT 0
|
||||||
|
|
||||||
|
#define HvGetCellType(Cell) \
|
||||||
|
((ULONG)((Cell & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT))
|
||||||
|
|
||||||
#include <pshpack1.h>
|
#include <pshpack1.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -36,6 +36,13 @@
|
||||||
#define CMTRACE(x, ...) DPRINT(__VA_ARGS__)
|
#define CMTRACE(x, ...) DPRINT(__VA_ARGS__)
|
||||||
#endif
|
#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
|
// Tag for all registry allocations
|
||||||
//
|
//
|
||||||
|
@ -678,6 +685,8 @@ extern LIST_ENTRY CmiKeyObjectListHead, CmiConnectedHiveList;
|
||||||
extern KTIMER CmiWorkerTimer;
|
extern KTIMER CmiWorkerTimer;
|
||||||
VOID NTAPI CmiWorkerThread(IN PVOID Param);
|
VOID NTAPI CmiWorkerThread(IN PVOID Param);
|
||||||
PVOID NTAPI CmpRosGetHardwareHive(OUT PULONG Length);
|
PVOID NTAPI CmpRosGetHardwareHive(OUT PULONG Length);
|
||||||
|
NTSTATUS CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1, IN PVOID Argument2);
|
||||||
|
VOID CmiSyncHives(VOID);
|
||||||
#define HIVE_NO_FILE 0x00000002
|
#define HIVE_NO_FILE 0x00000002
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -1012,6 +1021,34 @@ CmpValueToData(
|
||||||
OUT PULONG Length
|
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
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Boot Routines
|
// Boot Routines
|
||||||
//
|
//
|
||||||
|
|
|
@ -45,7 +45,7 @@ CmpCopyName(IN PHHIVE Hive,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy this character */
|
/* Copy this character */
|
||||||
Destination[i] = Source->Buffer[i];
|
((PCHAR)Destination)[i] = (CHAR)(Source->Buffer[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compressed name, return length */
|
/* Compressed name, return length */
|
||||||
|
|
|
@ -13,10 +13,88 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* 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
|
HCELL_INDEX
|
||||||
NTAPI
|
NTAPI
|
||||||
CmpFindValueByName(IN PHHIVE Hive,
|
CmpFindValueByName(IN PHHIVE Hive,
|
||||||
|
@ -67,13 +145,8 @@ CmpGetValueData(IN PHHIVE Hive,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if this is a big cell */
|
/* Unsupported */
|
||||||
if (CmpIsKeyValueBig(Hive, *Length))
|
ASSERT_VALUE_BIG(Hive, *Length);
|
||||||
{
|
|
||||||
/* FIXME: We don't support big cells */
|
|
||||||
DPRINT1("Unsupported cell type!\n");
|
|
||||||
while (TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the data from the cell */
|
/* Get the data from the cell */
|
||||||
*Buffer = HvGetCell(Hive, Value->Data);
|
*Buffer = HvGetCell(Hive, Value->Data);
|
||||||
|
@ -123,3 +196,114 @@ CmpValueToData(IN PHHIVE Hive,
|
||||||
/* Otherwise, return the cell data */
|
/* Otherwise, return the cell data */
|
||||||
return Buffer;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue