- Cancel pending hive scynchronization upon shutdown.

- Implemented NtSetInformationKey().
- Mark more modified blocks in NtCreateKey().

svn path=/trunk/; revision=6306
This commit is contained in:
Eric Kohl
2003-10-13 20:53:42 +00:00
parent 1992cfebcb
commit a4504f3fa6
7 changed files with 141 additions and 76 deletions
+13 -6
View File
@@ -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 */
+9 -9
View File
@@ -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
);
+6 -5
View File
@@ -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,
+54 -21
View File
@@ -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;
}
+33 -26
View File
@@ -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;
+8 -1
View File
@@ -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);
+18 -8
View File
@@ -13,6 +13,7 @@
#include <internal/ob.h>
#include <internal/registry.h>
#include <ntos/minmax.h>
#include <reactos/bugcodes.h>
#define NDEBUG
#include <internal/debug.h>
@@ -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);
}
}