From 23a709ca5f102a548a3cbc99b3f086467e2ea57b Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 25 Sep 2004 15:25:28 +0000 Subject: [PATCH] - CmiAddValueToKey(): Double the size of the value list cell when it is completely filled. This prevents fragmentation if a key got lots of values. - CmiDeleteValueFromKey(): Fix corruption of the value list cell when a value is removed from the list. - Rename the variable VBOffset to ValueCellOffset. svn path=/trunk/; revision=11047 --- reactos/ntoskrnl/cm/regfile.c | 161 +++++++++++++++++++--------------- 1 file changed, 89 insertions(+), 72 deletions(-) diff --git a/reactos/ntoskrnl/cm/regfile.c b/reactos/ntoskrnl/cm/regfile.c index fbe0c74de02..bebaf3bbefc 100644 --- a/reactos/ntoskrnl/cm/regfile.c +++ b/reactos/ntoskrnl/cm/regfile.c @@ -2611,43 +2611,43 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, return STATUS_UNSUCCESSFUL; } - if (ValueList != NULL) + /* Enumerate all values */ + for (i = 0; i < SubKey->KeyCell->NumberOfValues; i++) { - /* Enumerate all values */ - for (i = 0; i < SubKey->KeyCell->NumberOfValues; i++) + /* Get pointer to value cell */ + ValueCell = CmiGetCell(RegistryHive, + ValueList->ValueOffset[i], + NULL); + if (ValueCell == NULL) { - /* Get pointer to value cell */ - ValueCell = CmiGetCell (RegistryHive, - ValueList->ValueOffset[i], - NULL); - if (ValueCell != NULL) + DPRINT("CmiGetCell() failed\n"); + return STATUS_UNSUCCESSFUL; + } + + if (ValueCell->DataSize > sizeof(BLOCK_OFFSET)) + { + DataCell = CmiGetCell (RegistryHive, + ValueCell->DataOffset, + NULL); + if (DataCell == NULL) { - if (ValueCell->DataSize > sizeof(BLOCK_OFFSET)) - { - DataCell = CmiGetCell (RegistryHive, - ValueCell->DataOffset, - NULL); - if (DataCell == NULL) - { - DPRINT("CmiGetCell() failed\n"); - return STATUS_UNSUCCESSFUL; - } - - if (DataCell != NULL) - { - /* Destroy data cell */ - CmiDestroyCell (RegistryHive, - DataCell, - ValueCell->DataOffset); - } - } - - /* Destroy value cell */ + DPRINT("CmiGetCell() failed\n"); + return STATUS_UNSUCCESSFUL; + } + + if (DataCell != NULL) + { + /* Destroy data cell */ CmiDestroyCell (RegistryHive, - ValueCell, - ValueList->ValueOffset[i]); + DataCell, + ValueCell->DataOffset); } } + + /* Destroy value cell */ + CmiDestroyCell (RegistryHive, + ValueCell, + ValueList->ValueOffset[i]); } /* Destroy value list cell */ @@ -2657,6 +2657,9 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, SubKey->KeyCell->NumberOfValues = 0; SubKey->KeyCell->ValueListOffset = (BLOCK_OFFSET)-1; + + CmiMarkBlockDirty(RegistryHive, + SubKey->KeyCellOffset); } /* Remove the key from the parent key's hash block */ @@ -2744,7 +2747,9 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, SubKey->KeyCell = NULL; SubKey->KeyCellOffset = (BLOCK_OFFSET)-1; - return(STATUS_SUCCESS); + DPRINT("CmiRemoveSubKey() done\n"); + + return STATUS_SUCCESS; } @@ -2894,8 +2899,11 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive, else if (KeyCell->NumberOfValues >= (((ULONG)ABS_VALUE(ValueListCell->CellSize) - sizeof(VALUE_LIST_CELL)) / sizeof(BLOCK_OFFSET))) { +#if 0 CellSize = sizeof(VALUE_LIST_CELL) + ((KeyCell->NumberOfValues + REG_VALUE_LIST_CELL_MULTIPLE) * sizeof(BLOCK_OFFSET)); +#endif + CellSize = 2 * (ULONG)ABS_VALUE(ValueListCell->CellSize); Status = CmiAllocateCell (RegistryHive, CellSize, (PVOID) &NewValueListCell, @@ -2954,13 +2962,13 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, { PVALUE_LIST_CELL ValueListCell; PVALUE_CELL CurValueCell; - ULONG i; + ULONG i; + NTSTATUS Status; ValueListCell = CmiGetCell (RegistryHive, KeyCell->ValueListOffset, NULL); - if (ValueListCell == NULL) { - DPRINT("CmiGetBlock() failed\n"); + DPRINT1("CmiGetBlock() failed\n"); return STATUS_SUCCESS; } @@ -2971,50 +2979,58 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, CurValueCell = CmiGetCell (RegistryHive, ValueListCell->ValueOffset[i], NULL); if (CurValueCell == NULL) { - DPRINT("CmiGetBlock() failed\n"); + DPRINT1("CmiGetBlock() failed\n"); return STATUS_UNSUCCESSFUL; } - if ((CurValueCell != NULL) && - CmiComparePackedNames(ValueName, + if (CmiComparePackedNames(ValueName, CurValueCell->Name, CurValueCell->NameSize, (BOOLEAN)((CurValueCell->Flags & REG_VALUE_NAME_PACKED) ? TRUE : FALSE))) { - CmiDestroyValueCell(RegistryHive, CurValueCell, ValueListCell->ValueOffset[i]); + Status = CmiDestroyValueCell(RegistryHive, + CurValueCell, + ValueListCell->ValueOffset[i]); + if (CurValueCell == NULL) + { + DPRINT1("CmiDestroyValueCell() failed\n"); + return Status; + } - if ((KeyCell->NumberOfValues - 1) < i) + if (i < (KeyCell->NumberOfValues - 1)) { - RtlCopyMemory(&ValueListCell->ValueOffset[i], + RtlMoveMemory(&ValueListCell->ValueOffset[i], &ValueListCell->ValueOffset[i + 1], sizeof(BLOCK_OFFSET) * (KeyCell->NumberOfValues - 1 - i)); } + ValueListCell->ValueOffset[KeyCell->NumberOfValues - 1] = 0; + + + KeyCell->NumberOfValues--; + + if (KeyCell->NumberOfValues == 0) + { + CmiDestroyCell(RegistryHive, + ValueListCell, + KeyCell->ValueListOffset); + KeyCell->ValueListOffset = -1; + } else { - RtlZeroMemory(&ValueListCell->ValueOffset[i], sizeof(BLOCK_OFFSET)); + CmiMarkBlockDirty(RegistryHive, + KeyCell->ValueListOffset); } - KeyCell->NumberOfValues -= 1; - break; - } - } + CmiMarkBlockDirty(RegistryHive, + KeyCellOffset); - if (KeyCell->NumberOfValues == 0) - { - CmiDestroyCell (RegistryHive, - ValueListCell, - KeyCell->ValueListOffset); - } - else - { - CmiMarkBlockDirty(RegistryHive, - KeyCell->ValueListOffset); + return STATUS_SUCCESS; + } } - CmiMarkBlockDirty(RegistryHive, - KeyCellOffset); + DPRINT("Couldn't find the desired value\n"); - return STATUS_SUCCESS; + return STATUS_OBJECT_NAME_NOT_FOUND; } @@ -3189,44 +3205,45 @@ CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive, NTSTATUS CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive, PVALUE_CELL ValueCell, - BLOCK_OFFSET VBOffset) + BLOCK_OFFSET ValueCellOffset) { NTSTATUS Status; - PVOID pBlock; - PHBIN pBin; + PVOID DataCell; + PHBIN Bin; - DPRINT("CmiDestroyValueCell(Cell %p Offset %lx)\n", ValueCell, VBOffset); + DPRINT("CmiDestroyValueCell(Cell %p Offset %lx)\n", + ValueCell, ValueCellOffset); VERIFY_VALUE_CELL(ValueCell); /* Destroy the data cell */ if (ValueCell->DataSize > sizeof(BLOCK_OFFSET)) { - pBlock = CmiGetCell (RegistryHive, ValueCell->DataOffset, &pBin); - if (pBlock == NULL) + DataCell = CmiGetCell (RegistryHive, ValueCell->DataOffset, &Bin); + if (DataCell == NULL) { - DPRINT("CmiGetBlock() failed\n"); + DPRINT("CmiGetCell() failed\n"); return STATUS_UNSUCCESSFUL; } - Status = CmiDestroyCell (RegistryHive, pBlock, ValueCell->DataOffset); + Status = CmiDestroyCell (RegistryHive, DataCell, ValueCell->DataOffset); if (!NT_SUCCESS(Status)) { - return Status; + return Status; } /* Update time of heap */ if (!IsNoFileHive(RegistryHive)) - NtQuerySystemTime(&pBin->DateModified); + NtQuerySystemTime(&Bin->DateModified); } /* Destroy the value cell */ - Status = CmiDestroyCell (RegistryHive, ValueCell, VBOffset); + Status = CmiDestroyCell (RegistryHive, ValueCell, ValueCellOffset); /* Update time of heap */ - if (!IsNoFileHive(RegistryHive) && CmiGetCell (RegistryHive, VBOffset, &pBin)) + if (!IsNoFileHive(RegistryHive) && CmiGetCell (RegistryHive, ValueCellOffset, &Bin)) { - NtQuerySystemTime(&pBin->DateModified); + NtQuerySystemTime(&Bin->DateModified); } return Status; -- 2.17.1