- 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
return STATUS_UNSUCCESSFUL;
}
return STATUS_UNSUCCESSFUL;
}
+ /* 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,
CmiDestroyCell (RegistryHive,
- ValueCell,
- ValueList->ValueOffset[i]);
+ DataCell,
+ ValueCell->DataOffset);
+
+ /* Destroy value cell */
+ CmiDestroyCell (RegistryHive,
+ ValueCell,
+ ValueList->ValueOffset[i]);
}
/* Destroy value list cell */
}
/* Destroy value list cell */
SubKey->KeyCell->NumberOfValues = 0;
SubKey->KeyCell->ValueListOffset = (BLOCK_OFFSET)-1;
SubKey->KeyCell->NumberOfValues = 0;
SubKey->KeyCell->ValueListOffset = (BLOCK_OFFSET)-1;
+
+ CmiMarkBlockDirty(RegistryHive,
+ SubKey->KeyCellOffset);
}
/* Remove the key from the parent key's hash block */
}
/* Remove the key from the parent key's hash block */
SubKey->KeyCell = NULL;
SubKey->KeyCellOffset = (BLOCK_OFFSET)-1;
SubKey->KeyCell = NULL;
SubKey->KeyCellOffset = (BLOCK_OFFSET)-1;
- return(STATUS_SUCCESS);
+ DPRINT("CmiRemoveSubKey() done\n");
+
+ return STATUS_SUCCESS;
else if (KeyCell->NumberOfValues >=
(((ULONG)ABS_VALUE(ValueListCell->CellSize) - sizeof(VALUE_LIST_CELL)) / sizeof(BLOCK_OFFSET)))
{
else if (KeyCell->NumberOfValues >=
(((ULONG)ABS_VALUE(ValueListCell->CellSize) - sizeof(VALUE_LIST_CELL)) / sizeof(BLOCK_OFFSET)))
{
CellSize = sizeof(VALUE_LIST_CELL) +
((KeyCell->NumberOfValues + REG_VALUE_LIST_CELL_MULTIPLE) * sizeof(BLOCK_OFFSET));
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,
Status = CmiAllocateCell (RegistryHive,
CellSize,
(PVOID) &NewValueListCell,
{
PVALUE_LIST_CELL ValueListCell;
PVALUE_CELL CurValueCell;
{
PVALUE_LIST_CELL ValueListCell;
PVALUE_CELL CurValueCell;
+ ULONG i;
+ NTSTATUS Status;
ValueListCell = CmiGetCell (RegistryHive, KeyCell->ValueListOffset, NULL);
ValueListCell = CmiGetCell (RegistryHive, KeyCell->ValueListOffset, NULL);
if (ValueListCell == NULL)
{
if (ValueListCell == NULL)
{
- DPRINT("CmiGetBlock() failed\n");
+ DPRINT1("CmiGetBlock() failed\n");
CurValueCell = CmiGetCell (RegistryHive, ValueListCell->ValueOffset[i], NULL);
if (CurValueCell == NULL)
{
CurValueCell = CmiGetCell (RegistryHive, ValueListCell->ValueOffset[i], NULL);
if (CurValueCell == NULL)
{
- DPRINT("CmiGetBlock() failed\n");
+ DPRINT1("CmiGetBlock() failed\n");
return STATUS_UNSUCCESSFUL;
}
return STATUS_UNSUCCESSFUL;
}
- if ((CurValueCell != NULL) &&
- CmiComparePackedNames(ValueName,
+ if (CmiComparePackedNames(ValueName,
CurValueCell->Name,
CurValueCell->NameSize,
(BOOLEAN)((CurValueCell->Flags & REG_VALUE_NAME_PACKED) ? TRUE : FALSE)))
{
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[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;
+ }
- 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_OBJECT_NAME_NOT_FOUND;
NTSTATUS
CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive,
PVALUE_CELL ValueCell,
NTSTATUS
CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive,
PVALUE_CELL ValueCell,
+ BLOCK_OFFSET ValueCellOffset)
- 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))
{
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;
}
return STATUS_UNSUCCESSFUL;
}
- Status = CmiDestroyCell (RegistryHive, pBlock, ValueCell->DataOffset);
+ Status = CmiDestroyCell (RegistryHive, DataCell, ValueCell->DataOffset);
if (!NT_SUCCESS(Status))
{
if (!NT_SUCCESS(Status))
{
}
/* Update time of heap */
if (!IsNoFileHive(RegistryHive))
}
/* Update time of heap */
if (!IsNoFileHive(RegistryHive))
- NtQuerySystemTime(&pBin->DateModified);
+ NtQuerySystemTime(&Bin->DateModified);
}
/* Destroy the value cell */
}
/* Destroy the value cell */
- Status = CmiDestroyCell (RegistryHive, ValueCell, VBOffset);
+ Status = CmiDestroyCell (RegistryHive, ValueCell, ValueCellOffset);
/* Update time of heap */
/* Update time of heap */
- if (!IsNoFileHive(RegistryHive) && CmiGetCell (RegistryHive, VBOffset, &pBin))
+ if (!IsNoFileHive(RegistryHive) && CmiGetCell (RegistryHive, ValueCellOffset, &Bin))
- NtQuerySystemTime(&pBin->DateModified);
+ NtQuerySystemTime(&Bin->DateModified);