{
KeyObject->KeyCell->ParentKeyOffset = -1;
KeyObject->KeyCell->SecurityKeyOffset = -1;
- /* This key must rest in memory unless it is deleted
+ /* This key must remain in memory unless it is deleted
or file is unloaded */
ObReferenceObjectByPointer(KeyObject,
STANDARD_RIGHTS_REQUIRED,
if (!NT_SUCCESS(Status))
return(Status);
- /* Acquire hive lock */
+ /* Acquire hive lock exclucively */
ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
VERIFY_KEY_OBJECT(KeyObject);
ValueName,
&ValueCell,
&VBOffset);
+ if (NT_SUCCESS(Status))
+ {
+ CmiMarkBlockDirty(RegistryHive, VBOffset);
+ }
}
if (!NT_SUCCESS(Status))
ValueCell->DataSize = DataSize | 0x80000000;
ValueCell->DataType = Type;
RtlMoveMemory(&ValueCell->DataOffset, Data, DataSize);
+ CmiMarkBlockDirty(RegistryHive, VBOffset);
}
else if (DataSize <= (ULONG) (ValueCell->DataSize & 0x7fffffff))
{
{
ZwQuerySystemTime((PTIME) &pBin->DateModified);
}
+ CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset);
}
else
{
ValueCell->DataType = Type;
CmiReleaseBlock(RegistryHive, NewDataCell);
ValueCell->DataOffset = NewOffset;
+ CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset);
}
/* Mark link key */
(Type == REG_LINK))
{
KeyCell->Type = REG_LINK_KEY_CELL_TYPE;
+ CmiMarkBlockDirty(RegistryHive, KeyObject->BlockOffset);
}
/* Update time of heap */
Status = CmiDeleteValueFromKey(KeyObject->RegistryHive,
KeyObject->KeyCell,
+ KeyObject->BlockOffset,
ValueName);
/* Release hive lock */
NtQuerySystemTime((PTIME)&ParentKey->KeyCell->LastWriteTime);
CmiMarkBlockDirty(RegistryHive,
ParentKey->BlockOffset);
+
+ /* Remove the parent key's hash table */
+ if (ParentKey->KeyCell->NumberOfSubKeys == 0)
+ {
+ DPRINT1("FIXME: Remove parent key hash table\n")
+
+ }
}
/* Destroy key cell */
SubKey->BlockOffset = -1;
SubKey->KeyCell = NULL;
+ /* FIXME: Merge free blocks within the Bin */
+
return(STATUS_SUCCESS);
}
NTSTATUS
CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell,
+ IN BLOCK_OFFSET KeyCellOffset,
IN PUNICODE_STRING ValueName)
{
PVALUE_LIST_CELL ValueListCell;
CmiReleaseBlock(RegistryHive, ValueListCell);
+ if (KeyCell->NumberOfValues == 0)
+ {
+ CmiDestroyBlock(RegistryHive,
+ ValueListCell,
+ KeyCell->ValuesOffset);
+ }
+ else
+ {
+ CmiMarkBlockDirty(RegistryHive,
+ KeyCell->ValuesOffset);
+ }
+
+ CmiMarkBlockDirty(RegistryHive,
+ KeyCellOffset);
+
return STATUS_SUCCESS;
}
NewValueCell->Flags |= REG_VALUE_NAME_PACKED;
}
else
- {
+ {
/* Copy the value name */
RtlCopyMemory(NewValueCell->Name,
ValueName->Buffer,
VERIFY_VALUE_CELL(ValueCell);
- /* First, release datas: */
- if (ValueCell->DataSize > 0)
+ /* First, release data: */
+ if (ValueCell->DataSize > 4)
{
pBlock = CmiGetBlock(RegistryHive, ValueCell->DataOffset, &pBin);
Status = CmiDestroyBlock(RegistryHive, pBlock, ValueCell->DataOffset);
Index = (ULONG)BlockOffset / 4096;
- DPRINT1("CmiMarkBlockDirty(Offset 0x%lx) Index %lu\n", (ULONG)BlockOffset, Index);
+ DPRINT1("CmiMarkBlockDirty(Offset 0x%lx) Index %lu\n",
+ (ULONG)BlockOffset, Index);
RegistryHive->HiveDirty = TRUE;
RtlSetBits(&RegistryHive->DirtyBitMap,