diff --git a/reactos/ntoskrnl/cm/cm.h b/reactos/ntoskrnl/cm/cm.h index 958add5dfaf..394d5c41df9 100644 --- a/reactos/ntoskrnl/cm/cm.h +++ b/reactos/ntoskrnl/cm/cm.h @@ -464,8 +464,9 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive, NTSTATUS CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, - IN PKEY_CELL KeyCell, - IN PUNICODE_STRING ValueName); + IN PKEY_CELL KeyCell, + IN BLOCK_OFFSET KeyCellOffset, + IN PUNICODE_STRING ValueName); NTSTATUS CmiAllocateHashTableBlock(IN PREGISTRY_HIVE RegistryHive, diff --git a/reactos/ntoskrnl/cm/ntfunc.c b/reactos/ntoskrnl/cm/ntfunc.c index 4aeb552e7ff..8d0a3166bc3 100644 --- a/reactos/ntoskrnl/cm/ntfunc.c +++ b/reactos/ntoskrnl/cm/ntfunc.c @@ -162,7 +162,7 @@ NtCreateKey(OUT PHANDLE KeyHandle, { 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, @@ -1394,7 +1394,7 @@ NtSetValueKey(IN HANDLE KeyHandle, if (!NT_SUCCESS(Status)) return(Status); - /* Acquire hive lock */ + /* Acquire hive lock exclucively */ ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE); VERIFY_KEY_OBJECT(KeyObject); @@ -1424,6 +1424,10 @@ NtSetValueKey(IN HANDLE KeyHandle, ValueName, &ValueCell, &VBOffset); + if (NT_SUCCESS(Status)) + { + CmiMarkBlockDirty(RegistryHive, VBOffset); + } } if (!NT_SUCCESS(Status)) @@ -1453,6 +1457,7 @@ NtSetValueKey(IN HANDLE KeyHandle, ValueCell->DataSize = DataSize | 0x80000000; ValueCell->DataType = Type; RtlMoveMemory(&ValueCell->DataOffset, Data, DataSize); + CmiMarkBlockDirty(RegistryHive, VBOffset); } else if (DataSize <= (ULONG) (ValueCell->DataSize & 0x7fffffff)) { @@ -1469,6 +1474,7 @@ NtSetValueKey(IN HANDLE KeyHandle, { ZwQuerySystemTime((PTIME) &pBin->DateModified); } + CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset); } else { @@ -1508,6 +1514,7 @@ NtSetValueKey(IN HANDLE KeyHandle, ValueCell->DataType = Type; CmiReleaseBlock(RegistryHive, NewDataCell); ValueCell->DataOffset = NewOffset; + CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset); } /* Mark link key */ @@ -1515,6 +1522,7 @@ NtSetValueKey(IN HANDLE KeyHandle, (Type == REG_LINK)) { KeyCell->Type = REG_LINK_KEY_CELL_TYPE; + CmiMarkBlockDirty(RegistryHive, KeyObject->BlockOffset); } /* Update time of heap */ @@ -1560,6 +1568,7 @@ NtDeleteValueKey(IN HANDLE KeyHandle, Status = CmiDeleteValueFromKey(KeyObject->RegistryHive, KeyObject->KeyCell, + KeyObject->BlockOffset, ValueName); /* Release hive lock */ diff --git a/reactos/ntoskrnl/cm/regfile.c b/reactos/ntoskrnl/cm/regfile.c index fe6c5680962..ea673944517 100644 --- a/reactos/ntoskrnl/cm/regfile.c +++ b/reactos/ntoskrnl/cm/regfile.c @@ -1432,6 +1432,13 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, 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 */ @@ -1441,6 +1448,8 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, SubKey->BlockOffset = -1; SubKey->KeyCell = NULL; + /* FIXME: Merge free blocks within the Bin */ + return(STATUS_SUCCESS); } @@ -1617,6 +1626,7 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive, NTSTATUS CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, IN PKEY_CELL KeyCell, + IN BLOCK_OFFSET KeyCellOffset, IN PUNICODE_STRING ValueName) { PVALUE_LIST_CELL ValueListCell; @@ -1662,6 +1672,21 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, CmiReleaseBlock(RegistryHive, ValueListCell); + if (KeyCell->NumberOfValues == 0) + { + CmiDestroyBlock(RegistryHive, + ValueListCell, + KeyCell->ValuesOffset); + } + else + { + CmiMarkBlockDirty(RegistryHive, + KeyCell->ValuesOffset); + } + + CmiMarkBlockDirty(RegistryHive, + KeyCellOffset); + return STATUS_SUCCESS; } @@ -1808,7 +1833,7 @@ CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive, NewValueCell->Flags |= REG_VALUE_NAME_PACKED; } else - { + { /* Copy the value name */ RtlCopyMemory(NewValueCell->Name, ValueName->Buffer, @@ -1836,8 +1861,8 @@ CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive, 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); @@ -2261,7 +2286,8 @@ CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive, 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,