From a4504f3fa62b76780fc13e208b4caa5716747d2a Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 13 Oct 2003 20:53:42 +0000 Subject: [PATCH] - Cancel pending hive scynchronization upon shutdown. - Implemented NtSetInformationKey(). - Mark more modified blocks in NtCreateKey(). svn path=/trunk/; revision=6306 --- reactos/include/ddk/cmtypes.h | 19 ++++++--- reactos/include/ntos/zw.h | 18 ++++---- reactos/ntoskrnl/cm/cm.h | 11 ++--- reactos/ntoskrnl/cm/ntfunc.c | 75 ++++++++++++++++++++++++---------- reactos/ntoskrnl/cm/regfile.c | 59 ++++++++++++++------------ reactos/ntoskrnl/cm/registry.c | 9 +++- reactos/ntoskrnl/cm/regobj.c | 26 ++++++++---- 7 files changed, 141 insertions(+), 76 deletions(-) diff --git a/reactos/include/ddk/cmtypes.h b/reactos/include/ddk/cmtypes.h index 33346103ea4..c2a01d9ee8a 100644 --- a/reactos/include/ddk/cmtypes.h +++ b/reactos/include/ddk/cmtypes.h @@ -4,9 +4,7 @@ * Configuration Manager structures and typedefs */ -/* - * key query information class - */ +/* key query information class */ typedef enum _KEY_INFORMATION_CLASS { @@ -48,10 +46,19 @@ typedef struct _KEY_NODE_INFORMATION WCHAR Name[1]; } KEY_NODE_INFORMATION, *PKEY_NODE_INFORMATION; + /* key set information class */ -/* - * KeyWriteTimeInformation - */ + +typedef enum _KEY_SET_INFORMATION_CLASS +{ + KeyLastWriteTimeInformation +} KEY_SET_INFORMATION_CLASS; + +typedef struct _KEY_LAST_WRITE_TIME_INFORMATION +{ + LARGE_INTEGER LastWriteTime; +} KEY_LAST_WRITE_TIME_INFORMATION, *PKEY_LAST_WRITE_TIME_INFORMATION; + /* key value information class */ diff --git a/reactos/include/ntos/zw.h b/reactos/include/ntos/zw.h index 258debb6420..70219bbce5d 100755 --- a/reactos/include/ntos/zw.h +++ b/reactos/include/ntos/zw.h @@ -1,5 +1,5 @@ -/* $Id: zw.h,v 1.18 2003/10/04 17:10:55 ekohl Exp $ +/* $Id: zw.h,v 1.19 2003/10/13 20:52:31 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -4724,11 +4724,11 @@ NtRaiseHardError( * ARGUMENTS: * KeyHandle = Handle to the registry key * KeyInformationClass = Index to the a certain information structure. - Can be one of the following values: - - * KeyWriteTimeInformation KEY_WRITE_TIME_INFORMATION - - KeyInformation = Storage for the new information + * Can be one of the following values: + * + * KeyLastWriteTimeInformation KEY_LAST_WRITE_TIME_INFORMATION + * + * KeyInformation = Storage for the new information * KeyInformationLength = Size of the information strucure * RETURNS: Status */ @@ -4737,7 +4737,7 @@ NTSTATUS STDCALL NtSetInformationKey( IN HANDLE KeyHandle, - IN CINT KeyInformationClass, + IN KEY_SET_INFORMATION_CLASS KeyInformationClass, IN PVOID KeyInformation, IN ULONG KeyInformationLength ); @@ -5446,7 +5446,7 @@ ZwRaiseHardError( * KeyInformationClass = Index to the a certain information structure. Can be one of the following values: - * KeyWriteTimeInformation KEY_WRITE_TIME_INFORMATION + * KeyLastWriteTimeInformation KEY_LAST_WRITE_TIME_INFORMATION KeyInformation = Storage for the new information * KeyInformationLength = Size of the information strucure @@ -5457,7 +5457,7 @@ NTSTATUS STDCALL ZwSetInformationKey( IN HANDLE KeyHandle, - IN CINT KeyInformationClass, + IN KEY_SET_INFORMATION_CLASS KeyInformationClass, IN PVOID KeyInformation, IN ULONG KeyInformationLength ); diff --git a/reactos/ntoskrnl/cm/cm.h b/reactos/ntoskrnl/cm/cm.h index 149f00c83cf..3ca38ec6110 100644 --- a/reactos/ntoskrnl/cm/cm.h +++ b/reactos/ntoskrnl/cm/cm.h @@ -471,7 +471,7 @@ CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive, NTSTATUS CmiAddSubKey(IN PREGISTRY_HIVE RegistryHive, - IN PKEY_OBJECT Parent, + IN PKEY_OBJECT ParentKey, OUT PKEY_OBJECT SubKey, IN PUNICODE_STRING SubKeyName, IN ULONG TitleIndex, @@ -521,10 +521,11 @@ PHASH_TABLE_CELL HashBlock, ULONG Index); NTSTATUS -CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive, - PHASH_TABLE_CELL HashBlock, - PKEY_CELL NewKeyCell, - BLOCK_OFFSET NKBOffset); +CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive, + PHASH_TABLE_CELL HashCell, + BLOCK_OFFSET HashCellOffset, + PKEY_CELL NewKeyCell, + BLOCK_OFFSET NKBOffset); NTSTATUS CmiRemoveKeyFromHashTable(PREGISTRY_HIVE RegistryHive, diff --git a/reactos/ntoskrnl/cm/ntfunc.c b/reactos/ntoskrnl/cm/ntfunc.c index 65ebce8cb10..26777d97df0 100644 --- a/reactos/ntoskrnl/cm/ntfunc.c +++ b/reactos/ntoskrnl/cm/ntfunc.c @@ -1308,13 +1308,6 @@ NtSetValueKey(IN HANDLE KeyHandle, RtlCopyMemory(DataCell->Data, Data, DataSize); ValueCell->DataSize = DataSize; ValueCell->DataType = Type; - - /* Update time of heap */ - if (!IsNoFileHive(RegistryHive)) - { - NtQuerySystemTime(&pBin->DateModified); - } - CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset); } else { @@ -1359,18 +1352,14 @@ NtSetValueKey(IN HANDLE KeyHandle, } /* Mark link key */ - if ((_wcsicmp(ValueName->Buffer, L"SymbolicLinkValue") == 0) && - (Type == REG_LINK)) + if ((Type == REG_LINK) && + (_wcsicmp(ValueName->Buffer, L"SymbolicLinkValue") == 0)) { KeyCell->Flags |= REG_KEY_LINK_CELL; - CmiMarkBlockDirty(RegistryHive, KeyObject->KeyCellOffset); } - /* Update time of heap */ - if (!IsNoFileHive(RegistryHive) && CmiGetCell (RegistryHive, ValueCellOffset, &pBin)) - { - NtQuerySystemTime(&pBin->DateModified); - } + NtQuerySystemTime (&KeyCell->LastWriteTime); + CmiMarkBlockDirty (RegistryHive, KeyObject->KeyCellOffset); ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); @@ -1412,12 +1401,15 @@ NtDeleteValueKey (IN HANDLE KeyHandle, KeyObject->KeyCellOffset, ValueName); + NtQuerySystemTime (&KeyObject->KeyCell->LastWriteTime); + CmiMarkBlockDirty (KeyObject->RegistryHive, KeyObject->KeyCellOffset); + /* Release hive lock */ - ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ExReleaseResourceLite (&KeyObject->RegistryHive->HiveResource); - ObDereferenceObject(KeyObject); + ObDereferenceObject (KeyObject); - CmiSyncHives(); + CmiSyncHives (); return Status; } @@ -1788,12 +1780,53 @@ NtSaveKey (IN HANDLE KeyHandle, NTSTATUS STDCALL NtSetInformationKey (IN HANDLE KeyHandle, - IN CINT KeyInformationClass, + IN KEY_SET_INFORMATION_CLASS KeyInformationClass, IN PVOID KeyInformation, IN ULONG KeyInformationLength) { - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + PKEY_OBJECT KeyObject; + NTSTATUS Status; + + if (KeyInformationClass != KeyLastWriteTimeInformation) + return STATUS_INVALID_INFO_CLASS; + + if (KeyInformationLength != sizeof (KEY_LAST_WRITE_TIME_INFORMATION)) + return STATUS_INFO_LENGTH_MISMATCH; + + /* Verify that the handle is valid and is a registry key */ + Status = ObReferenceObjectByHandle (KeyHandle, + KEY_SET_VALUE, + CmiKeyType, + UserMode, + (PVOID *)&KeyObject, + NULL); + if (!NT_SUCCESS (Status)) + { + DPRINT ("ObReferenceObjectByHandle() failed with status %x\n", Status); + return Status; + } + + /* Acquire hive lock */ + ExAcquireResourceExclusiveLite (&KeyObject->RegistryHive->HiveResource, TRUE); + + VERIFY_KEY_OBJECT(KeyObject); + + KeyObject->KeyCell->LastWriteTime.QuadPart = + ((PKEY_LAST_WRITE_TIME_INFORMATION)KeyInformation)->LastWriteTime.QuadPart; + + CmiMarkBlockDirty (KeyObject->RegistryHive, + KeyObject->KeyCellOffset); + + /* Release hive lock */ + ExReleaseResourceLite (&KeyObject->RegistryHive->HiveResource); + + ObDereferenceObject (KeyObject); + + CmiSyncHives (); + + DPRINT ("NtSaveKey() done\n"); + + return STATUS_SUCCESS; } diff --git a/reactos/ntoskrnl/cm/regfile.c b/reactos/ntoskrnl/cm/regfile.c index 3475bb90814..8799e4f7174 100644 --- a/reactos/ntoskrnl/cm/regfile.c +++ b/reactos/ntoskrnl/cm/regfile.c @@ -2323,19 +2323,18 @@ CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive, NTSTATUS CmiAddSubKey(PREGISTRY_HIVE RegistryHive, - PKEY_OBJECT Parent, + PKEY_OBJECT ParentKey, PKEY_OBJECT SubKey, PUNICODE_STRING SubKeyName, ULONG TitleIndex, PUNICODE_STRING Class, ULONG CreateOptions) { - PHASH_TABLE_CELL NewHashBlock; PHASH_TABLE_CELL HashBlock; BLOCK_OFFSET NKBOffset; PKEY_CELL NewKeyCell; ULONG NewBlockSize; - PKEY_CELL KeyCell; + PKEY_CELL ParentKeyCell; PDATA_CELL ClassCell; NTSTATUS Status; USHORT NameSize; @@ -2343,9 +2342,9 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive, BOOLEAN Packable; ULONG i; - KeyCell = Parent->KeyCell; + ParentKeyCell = ParentKey->KeyCell; - VERIFY_KEY_CELL(KeyCell); + VERIFY_KEY_CELL(ParentKeyCell); /* Skip leading backslash */ if (SubKeyName->Buffer[0] == L'\\') @@ -2443,16 +2442,16 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive, SubKey->KeyCellOffset = NKBOffset; /* Don't modify hash table if key is located in a pointer-based hive and parent key is not */ - if (IsPointerHive(RegistryHive) && (!IsPointerHive(Parent->RegistryHive))) + if (IsPointerHive(RegistryHive) && (!IsPointerHive(ParentKey->RegistryHive))) { return(Status); } - if (KeyCell->HashTableOffset == (ULONG_PTR) -1) + if (ParentKeyCell->HashTableOffset == (ULONG_PTR) -1) { Status = CmiAllocateHashTableCell (RegistryHive, &HashBlock, - &KeyCell->HashTableOffset, + &ParentKeyCell->HashTableOffset, REG_INIT_HASH_TABLE_SIZE); if (!NT_SUCCESS(Status)) { @@ -2462,16 +2461,17 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive, else { HashBlock = CmiGetCell (RegistryHive, - KeyCell->HashTableOffset, + ParentKeyCell->HashTableOffset, NULL); if (HashBlock == NULL) { - DPRINT("CmiGetBlock() failed\n"); + DPRINT("CmiGetCell() failed\n"); return STATUS_UNSUCCESSFUL; } - if (((KeyCell->NumberOfSubKeys + 1) >= HashBlock->HashTableSize)) + if (((ParentKeyCell->NumberOfSubKeys + 1) >= HashBlock->HashTableSize)) { + PHASH_TABLE_CELL NewHashBlock; BLOCK_OFFSET HTOffset; /* Reallocate the hash table cell */ @@ -2492,21 +2492,25 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive, sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize); CmiDestroyCell (RegistryHive, HashBlock, - KeyCell->HashTableOffset); - KeyCell->HashTableOffset = HTOffset; + ParentKeyCell->HashTableOffset); + ParentKeyCell->HashTableOffset = HTOffset; HashBlock = NewHashBlock; } } Status = CmiAddKeyToHashTable(RegistryHive, HashBlock, + ParentKeyCell->HashTableOffset, NewKeyCell, NKBOffset); if (NT_SUCCESS(Status)) { - KeyCell->NumberOfSubKeys++; + ParentKeyCell->NumberOfSubKeys++; } + NtQuerySystemTime (&ParentKeyCell->LastWriteTime); + CmiMarkBlockDirty (RegistryHive, ParentKey->KeyCellOffset); + return(Status); } @@ -2533,7 +2537,7 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, NULL); if (ValueList == NULL) { - DPRINT("CmiGetBlock() failed\n"); + DPRINT("CmiGetCell() failed\n"); return STATUS_UNSUCCESSFUL; } @@ -2555,7 +2559,7 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, NULL); if (DataCell == NULL) { - DPRINT("CmiGetBlock() failed\n"); + DPRINT("CmiGetCell() failed\n"); return STATUS_UNSUCCESSFUL; } @@ -2594,7 +2598,7 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, NULL); if (HashBlock == NULL) { - DPRINT("CmiGetBlock() failed\n"); + DPRINT("CmiGetCell() failed\n"); return STATUS_UNSUCCESSFUL; } DPRINT("ParentKey HashBlock %p\n", HashBlock) @@ -2617,7 +2621,7 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, NULL); if (HashBlock == NULL) { - DPRINT("CmiGetBlock() failed\n"); + DPRINT("CmiGetCell() failed\n"); return STATUS_UNSUCCESSFUL; } DPRINT("SubKey HashBlock %p\n", HashBlock) @@ -2645,7 +2649,7 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, NULL); if (HashBlock == NULL) { - DPRINT("CmiGetBlock() failed\n"); + DPRINT("CmiGetCell() failed\n"); return STATUS_UNSUCCESSFUL; } DPRINT("ParentKey HashBlock %p\n", HashBlock) @@ -2994,24 +2998,26 @@ CmiGetKeyFromHashByIndex(PREGISTRY_HIVE RegistryHive, NTSTATUS CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive, - PHASH_TABLE_CELL HashBlock, + PHASH_TABLE_CELL HashCell, + BLOCK_OFFSET HashCellOffset, PKEY_CELL NewKeyCell, BLOCK_OFFSET NKBOffset) { ULONG i; - for (i = 0; i < HashBlock->HashTableSize; i++) + for (i = 0; i < HashCell->HashTableSize; i++) { - if (HashBlock->Table[i].KeyOffset == 0) + if (HashCell->Table[i].KeyOffset == 0) { - HashBlock->Table[i].KeyOffset = NKBOffset; - HashBlock->Table[i].HashValue = 0; + HashCell->Table[i].KeyOffset = NKBOffset; + HashCell->Table[i].HashValue = 0; if (NewKeyCell->Flags & REG_KEY_NAME_PACKED) { - RtlCopyMemory(&HashBlock->Table[i].HashValue, + RtlCopyMemory(&HashCell->Table[i].HashValue, NewKeyCell->Name, min(NewKeyCell->NameSize, sizeof(ULONG))); } + CmiMarkBlockDirty(RegistryHive, HashCellOffset); return STATUS_SUCCESS; } } @@ -3260,7 +3266,8 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive, else { RtlZeroMemory(NewCell, CellSize); - NewCell->CellSize = CellSize; + NewCell->CellSize = -CellSize; + *Cell = NewCell; if (CellOffset != NULL) *CellOffset = (BLOCK_OFFSET) NewCell; diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index 2dac6104f6f..177cc5b6d89 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -1,4 +1,4 @@ -/* $Id: registry.c,v 1.111 2003/10/12 17:05:44 hbirr Exp $ +/* $Id: registry.c,v 1.112 2003/10/13 20:53:42 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -980,6 +980,13 @@ CmShutdownRegistry(VOID) /* Stop automatic hive synchronization */ CmiHiveSyncEnabled = FALSE; + /* Cancel pending hive synchronization */ + if (CmiHiveSyncPending == TRUE) + { + KeCancelTimer(&CmiHiveSyncTimer); + CmiHiveSyncPending = FALSE; + } + /* Acquire hive list lock exclusively */ ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE); diff --git a/reactos/ntoskrnl/cm/regobj.c b/reactos/ntoskrnl/cm/regobj.c index be75552f972..d63824e2359 100644 --- a/reactos/ntoskrnl/cm/regobj.c +++ b/reactos/ntoskrnl/cm/regobj.c @@ -13,6 +13,7 @@ #include #include #include +#include #define NDEBUG #include @@ -269,13 +270,15 @@ CmiObjectCreate(PVOID ObjectBody, VOID STDCALL CmiObjectDelete(PVOID DeletedObject) { + PKEY_OBJECT ParentKeyObject; PKEY_OBJECT KeyObject; DPRINT("Delete key object (%p)\n", DeletedObject); KeyObject = (PKEY_OBJECT) DeletedObject; - - ObReferenceObject(KeyObject->ParentKey); + ParentKeyObject = KeyObject->ParentKey; + + ObReferenceObject (ParentKeyObject); if (!NT_SUCCESS(CmiRemoveKeyFromList(KeyObject))) { @@ -289,24 +292,31 @@ CmiObjectDelete(PVOID DeletedObject) DPRINT("delete really key\n"); CmiRemoveSubKey(KeyObject->RegistryHive, - KeyObject->ParentKey, + ParentKeyObject, KeyObject); - if (!IsNoFileHive(KeyObject->RegistryHive)) + NtQuerySystemTime (&ParentKeyObject->KeyCell->LastWriteTime); + CmiMarkBlockDirty (ParentKeyObject->RegistryHive, + ParentKeyObject->KeyCellOffset); + + if (!IsNoFileHive (KeyObject->RegistryHive) || + !IsNoFileHive (ParentKeyObject->RegistryHive)) { - CmiSyncHives(); + CmiSyncHives (); } } - ObDereferenceObject(KeyObject->ParentKey); + + ObDereferenceObject (ParentKeyObject); + if (KeyObject->NumberOfSubKeys) { - KEBUGCHECK(0); + KEBUGCHECK(REGISTRY_ERROR); } + if (KeyObject->SizeOfSubKeys) { ExFreePool(KeyObject->SubKeys); } - }