mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Use ERESOURCE instead of spinlock to protect the hive list.
Use worker thread to run hive flush routine at dispatch level. - Changes by Hartmut Birr! Delete a key's hash block when the key is deleted. Update pointers and offsets in a key object when the key cell is deleted. svn path=/trunk/; revision=4134
This commit is contained in:
parent
0430d6bf60
commit
848ea5c2e0
4 changed files with 121 additions and 68 deletions
|
@ -332,7 +332,7 @@ extern POBJECT_TYPE CmiKeyType;
|
|||
extern KSPIN_LOCK CmiKeyListLock;
|
||||
|
||||
extern LIST_ENTRY CmiHiveListHead;
|
||||
extern KSPIN_LOCK CmiHiveListLock;
|
||||
extern ERESOURCE CmiHiveListLock;
|
||||
|
||||
|
||||
VOID
|
||||
|
|
|
@ -143,6 +143,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
|||
CreateOptions);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Release hive lock */
|
||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
ObDereferenceObject(KeyObject);
|
||||
ObDereferenceObject(Object);
|
||||
|
@ -171,6 +172,8 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
|||
|
||||
CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
|
||||
|
||||
VERIFY_KEY_OBJECT(KeyObject);
|
||||
|
||||
/* Release hive lock */
|
||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
|
||||
|
@ -180,8 +183,6 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
|||
if (Disposition)
|
||||
*Disposition = REG_CREATED_NEW_KEY;
|
||||
|
||||
VERIFY_KEY_OBJECT(KeyObject);
|
||||
|
||||
CmiSyncHives();
|
||||
|
||||
return Status;
|
||||
|
@ -197,6 +198,7 @@ NtDeleteKey(IN HANDLE KeyHandle)
|
|||
DPRINT("KeyHandle %x\n", KeyHandle);
|
||||
|
||||
/* Verify that the handle is valid and is a registry key */
|
||||
CHECKPOINT1;
|
||||
Status = ObReferenceObjectByHandle(KeyHandle,
|
||||
KEY_WRITE,
|
||||
CmiKeyType,
|
||||
|
@ -205,28 +207,32 @@ NtDeleteKey(IN HANDLE KeyHandle)
|
|||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return(Status);
|
||||
}
|
||||
|
||||
CHECKPOINT1;
|
||||
/* Acquire hive lock */
|
||||
ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
||||
CHECKPOINT1;
|
||||
|
||||
VERIFY_KEY_OBJECT(KeyObject);
|
||||
|
||||
/* Set the marked for delete bit in the key object */
|
||||
KeyObject->Flags |= KO_MARKED_FOR_DELETE;
|
||||
CHECKPOINT1;
|
||||
|
||||
/* Release hive lock */
|
||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
|
||||
DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
|
||||
DPRINT1("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
|
||||
|
||||
/* Dereference the object */
|
||||
ObDereferenceObject(KeyObject);
|
||||
if(KeyObject->RegistryHive != KeyObject->ParentKey->RegistryHive)
|
||||
ObDereferenceObject(KeyObject);
|
||||
|
||||
DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
|
||||
DPRINT1("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
|
||||
|
||||
/*
|
||||
* Note:
|
||||
|
|
|
@ -809,7 +809,6 @@ CmiCreateRegistryHive(PWSTR Filename,
|
|||
BOOLEAN CreateNew)
|
||||
{
|
||||
PREGISTRY_HIVE Hive;
|
||||
KIRQL oldlvl;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("CmiCreateRegistryHive(Filename %S)\n", Filename);
|
||||
|
@ -851,10 +850,14 @@ CmiCreateRegistryHive(PWSTR Filename,
|
|||
|
||||
ExInitializeResourceLite(&Hive->HiveResource);
|
||||
|
||||
/* Acquire hive list lock exclusively */
|
||||
ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE);
|
||||
|
||||
/* Add the new hive to the hive list */
|
||||
KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
||||
InsertHeadList(&CmiHiveListHead, &Hive->HiveList);
|
||||
KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
||||
|
||||
/* Release hive list lock */
|
||||
ExReleaseResourceLite(&CmiHiveListLock);
|
||||
|
||||
VERIFY_REGISTRY_HIVE(Hive);
|
||||
|
||||
|
@ -869,12 +872,14 @@ CmiCreateRegistryHive(PWSTR Filename,
|
|||
NTSTATUS
|
||||
CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive)
|
||||
{
|
||||
KIRQL oldlvl;
|
||||
/* Acquire hive list lock exclusively */
|
||||
ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE);
|
||||
|
||||
/* Remove hive from hive list */
|
||||
KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
||||
RemoveEntryList(&RegistryHive->HiveList);
|
||||
KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
||||
|
||||
/* Release hive list lock */
|
||||
ExReleaseResourceLite(&CmiHiveListLock);
|
||||
|
||||
|
||||
/* FIXME: Remove attached keys and values */
|
||||
|
@ -1385,46 +1390,56 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive,
|
|||
DPRINT1("CmiRemoveSubKey() called\n");
|
||||
|
||||
/* Remove the key from the parent key's hash block */
|
||||
HashBlock = CmiGetBlock(RegistryHive,
|
||||
ParentKey->KeyCell->HashTableOffset,
|
||||
NULL);
|
||||
if (HashBlock != NULL)
|
||||
if (ParentKey->KeyCell->HashTableOffset != -1)
|
||||
{
|
||||
CmiRemoveKeyFromHashTable(RegistryHive,
|
||||
HashBlock,
|
||||
SubKey->BlockOffset);
|
||||
CmiMarkBlockDirty(RegistryHive,
|
||||
ParentKey->KeyCell->HashTableOffset);
|
||||
DPRINT1("ParentKey HashTableOffset %lx\n", ParentKey->KeyCell->HashTableOffset)
|
||||
HashBlock = CmiGetBlock(RegistryHive,
|
||||
ParentKey->KeyCell->HashTableOffset,
|
||||
NULL);
|
||||
DPRINT1("ParentKey HashBlock %p\n", HashBlock)
|
||||
if (HashBlock != NULL)
|
||||
{
|
||||
CmiRemoveKeyFromHashTable(RegistryHive,
|
||||
HashBlock,
|
||||
SubKey->BlockOffset);
|
||||
CmiMarkBlockDirty(RegistryHive,
|
||||
ParentKey->KeyCell->HashTableOffset);
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove the key's hash block */
|
||||
DPRINT1("HashTableOffset %lx\n", SubKey->KeyCell->HashTableOffset)
|
||||
if (SubKey->KeyCell->HashTableOffset != 0)
|
||||
if (SubKey->KeyCell->HashTableOffset != -1)
|
||||
{
|
||||
DPRINT1("SubKey HashTableOffset %lx\n", SubKey->KeyCell->HashTableOffset)
|
||||
HashBlock = CmiGetBlock(RegistryHive,
|
||||
SubKey->KeyCell->HashTableOffset,
|
||||
NULL);
|
||||
DPRINT1("HashBlock %p\n", HashBlock)
|
||||
DPRINT1("SubKey HashBlock %p\n", HashBlock)
|
||||
if (HashBlock != NULL)
|
||||
{
|
||||
CmiDestroyBlock(RegistryHive,
|
||||
HashBlock,
|
||||
SubKey->KeyCell->HashTableOffset);
|
||||
SubKey->KeyCell->HashTableOffset = -1;
|
||||
}
|
||||
SubKey->KeyCell->HashTableOffset = 0;
|
||||
}
|
||||
|
||||
CHECKPOINT1;
|
||||
/* Remove the key from the parent key's hash block */
|
||||
ParentKey->KeyCell->NumberOfSubKeys--;
|
||||
CmiMarkBlockDirty(RegistryHive,
|
||||
ParentKey->BlockOffset);
|
||||
/* Decrement the number of the parent key's sub keys */
|
||||
if (ParentKey != NULL)
|
||||
{
|
||||
DPRINT1("ParentKey %p\n", ParentKey)
|
||||
ParentKey->KeyCell->NumberOfSubKeys--;
|
||||
NtQuerySystemTime((PTIME)&ParentKey->KeyCell->LastWriteTime);
|
||||
CmiMarkBlockDirty(RegistryHive,
|
||||
ParentKey->BlockOffset);
|
||||
}
|
||||
|
||||
CHECKPOINT1;
|
||||
/* Destroy key cell */
|
||||
CmiDestroyBlock(RegistryHive,
|
||||
SubKey->KeyCell,
|
||||
SubKey->BlockOffset);
|
||||
SubKey->BlockOffset = -1;
|
||||
SubKey->KeyCell = NULL;
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: registry.c,v 1.82 2003/02/09 11:57:14 ekohl Exp $
|
||||
/* $Id: registry.c,v 1.83 2003/02/10 21:24:45 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -35,7 +35,7 @@ PREGISTRY_HIVE CmiVolatileHive = NULL;
|
|||
KSPIN_LOCK CmiKeyListLock;
|
||||
|
||||
LIST_ENTRY CmiHiveListHead;
|
||||
KSPIN_LOCK CmiHiveListLock;
|
||||
ERESOURCE CmiHiveListLock;
|
||||
|
||||
volatile BOOLEAN CmiHiveSyncEnabled = FALSE;
|
||||
volatile BOOLEAN CmiHiveSyncPending = FALSE;
|
||||
|
@ -157,37 +157,37 @@ CmiCheckValues(BOOLEAN Verbose,
|
|||
Index = 0;
|
||||
while (TRUE)
|
||||
{
|
||||
BufferSize = sizeof(KEY_NODE_INFORMATION) + 4096;
|
||||
ValueInfo = ExAllocatePool(PagedPool, BufferSize);
|
||||
BufferSize = sizeof(KEY_NODE_INFORMATION) + 4096;
|
||||
ValueInfo = ExAllocatePool(PagedPool, BufferSize);
|
||||
|
||||
Status = NtEnumerateValueKey(Key,
|
||||
Index,
|
||||
KeyNodeInformation,
|
||||
ValueInfo,
|
||||
BufferSize,
|
||||
&ResultSize);
|
||||
Status = NtEnumerateValueKey(Key,
|
||||
Index,
|
||||
KeyNodeInformation,
|
||||
ValueInfo,
|
||||
BufferSize,
|
||||
&ResultSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(ValueInfo);
|
||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
{
|
||||
ExFreePool(ValueInfo);
|
||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
wcsncpy(Name,
|
||||
ValueInfo->Name,
|
||||
ValueInfo->NameLength / sizeof(WCHAR));
|
||||
ValueInfo->Name,
|
||||
ValueInfo->NameLength / sizeof(WCHAR));
|
||||
|
||||
if (Verbose)
|
||||
{
|
||||
DbgPrint("Value: %S\n", Name);
|
||||
}
|
||||
{
|
||||
DbgPrint("Value: %S\n", Name);
|
||||
}
|
||||
|
||||
/* FIXME: Check info. */
|
||||
|
||||
ExFreePool(ValueInfo);
|
||||
|
||||
Index++;
|
||||
Index++;
|
||||
}
|
||||
|
||||
assert(NT_SUCCESS(Status));
|
||||
|
@ -264,7 +264,7 @@ CmInitializeRegistry(VOID)
|
|||
PKEY_OBJECT NewKey;
|
||||
HANDLE KeyHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
|
||||
/* Initialize the Key object type */
|
||||
CmiKeyType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
|
||||
assert(CmiKeyType);
|
||||
|
@ -289,7 +289,7 @@ CmInitializeRegistry(VOID)
|
|||
|
||||
/* Initialize the hive list */
|
||||
InitializeListHead(&CmiHiveListHead);
|
||||
KeInitializeSpinLock(&CmiHiveListLock);
|
||||
ExInitializeResourceLite(&CmiHiveListLock);
|
||||
|
||||
/* Build volatile registry store */
|
||||
Status = CmiCreateRegistryHive(NULL, &CmiVolatileHive, FALSE);
|
||||
|
@ -845,7 +845,7 @@ CmiInitHives(BOOLEAN SetUpBoot)
|
|||
}
|
||||
wcscat(ConfigPath, L"\\system32\\config");
|
||||
|
||||
DPRINT1("ConfigPath: %S\n", ConfigPath);
|
||||
DPRINT("ConfigPath: %S\n", ConfigPath);
|
||||
|
||||
EndPtr = ConfigPath + wcslen(ConfigPath);
|
||||
|
||||
|
@ -944,14 +944,15 @@ CmShutdownRegistry(VOID)
|
|||
{
|
||||
PREGISTRY_HIVE Hive;
|
||||
PLIST_ENTRY Entry;
|
||||
// KIRQL oldlvl;
|
||||
|
||||
DPRINT1("CmShutdownRegistry() called\n");
|
||||
|
||||
/* Stop automatic hive synchronization */
|
||||
CmiHiveSyncEnabled = FALSE;
|
||||
|
||||
// KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
||||
/* Acquire hive list lock exclusively */
|
||||
ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE);
|
||||
|
||||
Entry = CmiHiveListHead.Flink;
|
||||
while (Entry != &CmiHiveListHead)
|
||||
{
|
||||
|
@ -976,27 +977,27 @@ CmShutdownRegistry(VOID)
|
|||
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
// KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
||||
|
||||
DPRINT1("CmShutdownRegistry() called\n");
|
||||
/* Release hive list lock */
|
||||
ExReleaseResourceLite(&CmiHiveListLock);
|
||||
|
||||
DPRINT1("CmShutdownRegistry() done\n");
|
||||
}
|
||||
|
||||
|
||||
static VOID STDCALL
|
||||
CmiHiveSyncDpcRoutine(PKDPC Dpc,
|
||||
PVOID DeferredContext,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
VOID STDCALL
|
||||
CmiHiveSyncRoutine(PVOID DeferredContext)
|
||||
{
|
||||
PREGISTRY_HIVE Hive;
|
||||
PLIST_ENTRY Entry;
|
||||
KIRQL oldlvl;
|
||||
|
||||
DPRINT1("CmiHiveSyncDpcRoutine() called\n");
|
||||
DPRINT1("CmiHiveSyncRoutine() called\n");
|
||||
|
||||
CmiHiveSyncPending = FALSE;
|
||||
|
||||
KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
||||
/* Acquire hive list lock exclusively */
|
||||
ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE);
|
||||
|
||||
Entry = CmiHiveListHead.Flink;
|
||||
while (Entry != &CmiHiveListHead)
|
||||
{
|
||||
|
@ -1017,7 +1018,38 @@ CmiHiveSyncDpcRoutine(PKDPC Dpc,
|
|||
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
||||
|
||||
/* Release hive list lock */
|
||||
ExReleaseResourceLite(&CmiHiveListLock);
|
||||
|
||||
DPRINT("DeferredContext %x\n", DeferredContext);
|
||||
ExFreePool(DeferredContext);
|
||||
}
|
||||
|
||||
|
||||
static VOID STDCALL
|
||||
CmiHiveSyncDpcRoutine(PKDPC Dpc,
|
||||
PVOID DeferredContext,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
{
|
||||
PWORK_QUEUE_ITEM WorkQueueItem;
|
||||
|
||||
WorkQueueItem = ExAllocatePool(NonPagedPool,
|
||||
sizeof(WORK_QUEUE_ITEM));
|
||||
if (WorkQueueItem == NULL)
|
||||
{
|
||||
DbgPrint("Failed to allocate work item\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ExInitializeWorkItem(WorkQueueItem,
|
||||
CmiHiveSyncRoutine,
|
||||
WorkQueueItem);
|
||||
|
||||
DPRINT("DeferredContext %x\n", WorkQueueItem);
|
||||
ExQueueWorkItem(WorkQueueItem,
|
||||
CriticalWorkQueue);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue