From 6dea234022e626bf044f32dc1b79c0874dd52705 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 5 Dec 2007 22:30:33 +0000 Subject: [PATCH] - Save hive flags instead of ignoring them (but ignore no lazy flush for now). - Get rid of CmiKeyObjectListHead and code that was adding/removing entries into it, it wasn't used for anything. - Change the stupid subkey array (which caused pool fragmentation and slow-downs) with a linked-list version, since we never used the array for random indexing (the point of an array vs a linked list). - Link key object children to parent key control blocks so that KCBs now own PKEY_OBJECTs (will help with parsing later). - Get rid of CmiAddKeyToList since this is just an InsertTailList now. - Remove ReactOS hacks in flush code. - Do full parallel hive loading code in normal boot too, not just in cd-rom boot: CmpSetFileSize was causing the problem to happen so it's been disabled for now; this allowed removal of multiple ReactOS hacks. - Use the "Allocate" flag during linking instead of hard-coding FALSE, since this also works now. - Set HIVE_NOLAZYFLUSH to newly create hives since this is required for later. - Remove CmiConnectedHiveList since it's not used for anything. svn path=/trunk/; revision=31030 --- reactos/lib/cmlib/hiveinit.c | 1 + reactos/ntoskrnl/cm/cm.h | 5 --- reactos/ntoskrnl/cm/ntfunc.c | 2 +- reactos/ntoskrnl/cm/regobj.c | 70 ++++++------------------------ reactos/ntoskrnl/config/cm.h | 9 +--- reactos/ntoskrnl/config/cmapi.c | 35 --------------- reactos/ntoskrnl/config/cmparse.c | 8 ---- reactos/ntoskrnl/config/cmsysini.c | 55 ++++++++--------------- 8 files changed, 34 insertions(+), 151 deletions(-) diff --git a/reactos/lib/cmlib/hiveinit.c b/reactos/lib/cmlib/hiveinit.c index ec1031574de..8ac65567594 100644 --- a/reactos/lib/cmlib/hiveinit.c +++ b/reactos/lib/cmlib/hiveinit.c @@ -460,6 +460,7 @@ HvInitialize( Hive->StorageTypeCount = HTYPE_COUNT; Hive->Cluster = 1; Hive->Version = HSYS_MINOR; + Hive->HiveFlags = HiveFlags &~ HIVE_NOLAZYFLUSH; switch (Operation) { diff --git a/reactos/ntoskrnl/cm/cm.h b/reactos/ntoskrnl/cm/cm.h index aa2ee94d8ea..da1b4dfc6fa 100644 --- a/reactos/ntoskrnl/cm/cm.h +++ b/reactos/ntoskrnl/cm/cm.h @@ -4,14 +4,9 @@ #include "ntoskrnl/config/cm.h" extern POBJECT_TYPE CmpKeyObjectType; -extern KSPIN_LOCK CmiKeyListLock; extern ERESOURCE CmpRegistryLock; extern EX_PUSH_LOCK CmpHiveListHeadLock; -NTSTATUS -CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1, - IN PVOID Argument2); - #define VERIFY_BIN_HEADER(x) ASSERT(x->HeaderId == REG_BIN_ID) #define VERIFY_KEY_CELL(x) ASSERT(x->Signature == CM_KEY_NODE_SIGNATURE) #define VERIFY_ROOT_KEY_CELL(x) ASSERT(x->Signature == CM_KEY_NODE_SIGNATURE) diff --git a/reactos/ntoskrnl/cm/ntfunc.c b/reactos/ntoskrnl/cm/ntfunc.c index 6c2681dd39a..b46d2f499b2 100644 --- a/reactos/ntoskrnl/cm/ntfunc.c +++ b/reactos/ntoskrnl/cm/ntfunc.c @@ -175,7 +175,7 @@ NtCreateKey(OUT PHANDLE KeyHandle, KeyObject->KeyControlBlock->ValueCache.Count = Node->ValueList.Count; /* Link child to parent */ - CmiAddKeyToList(Parent, KeyObject); + CmiAddKeyToList(Parent->KeyControlBlock, KeyObject); /* Create the actual handle to the object */ Status = CmpCreateHandle(KeyObject, diff --git a/reactos/ntoskrnl/cm/regobj.c b/reactos/ntoskrnl/cm/regobj.c index 7e5a5123da9..d03c8c3820b 100644 --- a/reactos/ntoskrnl/cm/regobj.c +++ b/reactos/ntoskrnl/cm/regobj.c @@ -17,7 +17,6 @@ #include "cm.h" -extern LIST_ENTRY CmiKeyObjectListHead; extern ULONG CmiTimer; static NTSTATUS @@ -440,22 +439,18 @@ Next: /* Preconditions: Must be called with CmpRegistryLock held. */ NTSTATUS -CmiScanKeyList(PKEY_OBJECT Parent, +CmiScanKeyList(PCM_KEY_CONTROL_BLOCK Parent, PCUNICODE_STRING KeyName, ULONG Attributes, PKEY_OBJECT* ReturnedObject) { PKEY_OBJECT CurKey = NULL; - ULONG Index; - - DPRINT("Scanning key list for: %wZ (Parent: %wZ)\n", - KeyName, &Parent->Name); - - /* FIXME: if list maintained in alphabetic order, use dichotomic search */ - /* (a binary search) */ - for (Index=0; Index < Parent->SubKeyCounts; Index++) + PLIST_ENTRY NextEntry; + + NextEntry = Parent->KeyBodyListHead.Flink; + while (NextEntry != &Parent->KeyBodyListHead) { - CurKey = Parent->SubKeys[Index]; + CurKey = CONTAINING_RECORD(NextEntry, KEY_OBJECT, KeyBodyEntry); if (Attributes & OBJ_CASE_INSENSITIVE) { DPRINT("Comparing %wZ and %wZ\n", KeyName, &CurKey->Name); @@ -473,9 +468,11 @@ CmiScanKeyList(PKEY_OBJECT Parent, break; } } + + NextEntry = NextEntry->Flink; } - if (Index < Parent->SubKeyCounts) + if (NextEntry != &Parent->KeyBodyListHead) { if (CurKey->KeyControlBlock->Delete) { @@ -588,7 +585,7 @@ CmpParseKey(IN PVOID ParsedObject, KeEnterCriticalRegion(); ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE); - Status = CmiScanKeyList(ParsedKey, + Status = CmiScanKeyList(ParsedKey->KeyControlBlock, &KeyName, Attributes, &FoundObject); @@ -722,9 +719,8 @@ CmpParseKey(IN PVOID ParsedObject, FoundObject->KeyControlBlock = Kcb; ASSERT(FoundObject->KeyControlBlock->KeyHive == ParsedKey->KeyControlBlock->KeyHive); - InsertTailList(&CmiKeyObjectListHead, &FoundObject->KeyBodyList); RtlpCreateUnicodeString(&FoundObject->Name, KeyName.Buffer, NonPagedPool); - CmiAddKeyToList(ParsedKey, FoundObject); + CmiAddKeyToList(ParsedKey->KeyControlBlock, FoundObject); DPRINT("Created object 0x%p\n", FoundObject); } else @@ -784,9 +780,6 @@ CmpParseKey(IN PVOID ParsedObject, } } - RemoveEntryList(&FoundObject->KeyBodyList); - InsertHeadList(&CmiKeyObjectListHead, &FoundObject->KeyBodyList); - ExReleaseResourceLite(&CmpRegistryLock); KeLeaveCriticalRegion(); @@ -831,16 +824,10 @@ CmpDeleteKeyObject(PVOID DeletedObject) KeEnterCriticalRegion(); ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE); - RemoveEntryList(&KeyObject->KeyBodyList); RtlFreeUnicodeString(&KeyObject->Name); ASSERT((KeyObject->KeyControlBlock->Delete) == FALSE); - if (KeyObject->SizeOfSubKeys) - { - ExFreePool(KeyObject->SubKeys); - } - ExReleaseResourceLite(&CmpRegistryLock); KeLeaveCriticalRegion(); PostOperationInfo.Status = STATUS_SUCCESS; @@ -917,41 +904,10 @@ CmpQueryKeyName(PVOID ObjectBody, } VOID -CmiAddKeyToList(PKEY_OBJECT ParentKey, +CmiAddKeyToList(PCM_KEY_CONTROL_BLOCK ParentKey, PKEY_OBJECT NewKey) { - DPRINT("ParentKey %.08x\n", ParentKey); - - if (ParentKey->SizeOfSubKeys <= ParentKey->SubKeyCounts) - { - PKEY_OBJECT *tmpSubKeys = ExAllocatePool(NonPagedPool, - (ParentKey->SubKeyCounts + 1) * sizeof(ULONG)); - - if (ParentKey->SubKeyCounts > 0) - { - RtlCopyMemory (tmpSubKeys, - ParentKey->SubKeys, - ParentKey->SubKeyCounts * sizeof(ULONG)); - } - - if (ParentKey->SubKeys) - ExFreePool(ParentKey->SubKeys); - - ParentKey->SubKeys = tmpSubKeys; - ParentKey->SizeOfSubKeys = ParentKey->SubKeyCounts + 1; - } - - /* FIXME: Please maintain the list in alphabetic order */ - /* to allow a dichotomic search */ - ParentKey->SubKeys[ParentKey->SubKeyCounts++] = NewKey; - - DPRINT("Reference parent key: 0x%p\n", ParentKey); - - ObReferenceObjectByPointer(ParentKey, - STANDARD_RIGHTS_REQUIRED, - CmpKeyObjectType, - KernelMode); - //NewKey->ParentKey = ParentKey; + InsertTailList(&ParentKey->KeyBodyListHead, &NewKey->KeyBodyEntry); } static NTSTATUS diff --git a/reactos/ntoskrnl/config/cm.h b/reactos/ntoskrnl/config/cm.h index 787935ed2e2..0074901d318 100644 --- a/reactos/ntoskrnl/config/cm.h +++ b/reactos/ntoskrnl/config/cm.h @@ -202,8 +202,6 @@ typedef struct _CM_KEY_BODY struct _CM_KEY_CONTROL_BLOCK *KeyControlBlock; struct _CM_NOTIFY_BLOCK *NotifyBlock; HANDLE ProcessID; - ULONG Callers; - PVOID CallerAddress[10]; LIST_ENTRY KeyBodyList; } CM_KEY_BODY, *PCM_KEY_BODY; @@ -496,11 +494,8 @@ typedef struct _KEY_OBJECT { ULONG Type; UNICODE_STRING Name; - LIST_ENTRY KeyBodyList; - ULONG SubKeyCounts; - ULONG SizeOfSubKeys; - struct _KEY_OBJECT **SubKeys; PCM_KEY_CONTROL_BLOCK KeyControlBlock; + LIST_ENTRY KeyBodyEntry; } KEY_OBJECT, *PKEY_OBJECT; NTSTATUS NTAPI @@ -513,7 +508,7 @@ CmFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo, IN PVOID ParseContext); NTSTATUS CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1, IN PVOID Argument2); VOID -CmiAddKeyToList(IN PKEY_OBJECT ParentKey, +CmiAddKeyToList(IN PCM_KEY_CONTROL_BLOCK ParentKey, IN PKEY_OBJECT NewKey); /////////////////////////////////////////////////////////////////////////////// diff --git a/reactos/ntoskrnl/config/cmapi.c b/reactos/ntoskrnl/config/cmapi.c index d56ce62494a..98da5c0baa5 100644 --- a/reactos/ntoskrnl/config/cmapi.c +++ b/reactos/ntoskrnl/config/cmapi.c @@ -39,26 +39,9 @@ CmpDoFlushAll(IN BOOLEAN ForceFlush) Hive = CONTAINING_RECORD(NextEntry, CMHIVE, HiveList); if (!(Hive->Hive.HiveFlags & HIVE_NOLAZYFLUSH)) { - /* Find out why this is needed? [Aleksey] */ - ULONG Disposition; - CmpOpenHiveFiles(&Hive->FileFullPath, - L".LOG", - &Hive->FileHandles[HFILE_TYPE_PRIMARY], - &Hive->FileHandles[HFILE_TYPE_LOG], - &Disposition, - &Disposition, - FALSE, - FALSE, - TRUE, - NULL); - /* Do the sync */ Status = HvSyncHive(&Hive->Hive); if (!NT_SUCCESS(Status)) Result = FALSE; - - /* ReactOS requires this */ - ZwClose(Hive->FileHandles[HFILE_TYPE_PRIMARY]); - ZwClose(Hive->FileHandles[HFILE_TYPE_LOG]); } /* Try the next entry */ @@ -1170,30 +1153,12 @@ CmFlushKey(IN PCM_KEY_CONTROL_BLOCK Kcb, } else { - ULONG Disposition; - - /* ReactOS Requires this */ - CmpOpenHiveFiles(&CmHive->FileFullPath, - L".LOG", - &CmHive->FileHandles[HFILE_TYPE_PRIMARY], - &CmHive->FileHandles[HFILE_TYPE_LOG], - &Disposition, - &Disposition, - FALSE, - FALSE, - TRUE, - NULL); - /* Flush only this hive */ if (!HvSyncHive(Hive)) { /* Fail */ Status = STATUS_REGISTRY_IO_FAILED; } - - /* ReactOS requires this */ - ZwClose(CmHive->FileHandles[HFILE_TYPE_PRIMARY]); - ZwClose(CmHive->FileHandles[HFILE_TYPE_LOG]); } /* Return the status */ diff --git a/reactos/ntoskrnl/config/cmparse.c b/reactos/ntoskrnl/config/cmparse.c index af9ccae9ba4..989ef79dee8 100644 --- a/reactos/ntoskrnl/config/cmparse.c +++ b/reactos/ntoskrnl/config/cmparse.c @@ -230,10 +230,6 @@ CmpDoCreateChild(IN PHHIVE Hive, /* Now fill out the Cm object */ KeyBody->KeyControlBlock = Kcb; - KeyBody->SubKeyCounts = 0; - KeyBody->SubKeys = NULL; - KeyBody->SizeOfSubKeys = 0; - InsertTailList(&CmiKeyObjectListHead, &KeyBody->KeyBodyList); Quickie: /* Check if we got here because of failure */ @@ -488,10 +484,6 @@ CmpDoOpen(IN PHHIVE Hive, /* Get the key body and fill it out */ KeyBody = (PKEY_OBJECT)(*Object); KeyBody->KeyControlBlock = Kcb; - KeyBody->SubKeyCounts = 0; - KeyBody->SubKeys = NULL; - KeyBody->SizeOfSubKeys = 0; - InsertTailList(&CmiKeyObjectListHead, &KeyBody->KeyBodyList); } else { diff --git a/reactos/ntoskrnl/config/cmsysini.c b/reactos/ntoskrnl/config/cmsysini.c index 1c269e54ffe..20df632322d 100644 --- a/reactos/ntoskrnl/config/cmsysini.c +++ b/reactos/ntoskrnl/config/cmsysini.c @@ -17,8 +17,6 @@ POBJECT_TYPE CmpKeyObjectType; PCMHIVE CmiVolatileHive; LIST_ENTRY CmpHiveListHead; ERESOURCE CmpRegistryLock; -LIST_ENTRY CmiKeyObjectListHead; -LIST_ENTRY CmiConnectedHiveList; KGUARDED_MUTEX CmpSelfHealQueueLock; LIST_ENTRY CmpSelfHealQueueListHead; KEVENT CmpLoadWorkerEvent; @@ -184,10 +182,6 @@ CmpInitHiveFromFile(IN PCUNICODE_STRING HiveName, NewHive->FileFullPath.MaximumLength = HiveName->MaximumLength; } - /* ROS: Close the hive files */ - ZwClose(FileHandle); - if (LogHandle) ZwClose(LogHandle); - /* Return success */ return STATUS_SUCCESS; } @@ -530,8 +524,8 @@ CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName, /* We have one */ ParseContext.ChildHive.KeyCell = RegistryHive->Hive.BaseBlock->RootCell; } - - DPRINT1("Ready to parse\n"); + + /* Create the link node */ Status = ObOpenObjectByName(&ObjectAttributes, CmpKeyObjectType, KernelMode, @@ -539,8 +533,6 @@ CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName, KEY_READ | KEY_WRITE, (PVOID)&ParseContext, &KeyHandle); - DPRINT1("Parse done: %lx\n", Status); - //while (TRUE); /* Capture all the info */ Status = ObpCaptureObjectAttributes(&ObjectAttributes, @@ -622,7 +614,7 @@ CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName, ObReferenceObject(NewKey); /* Link this key to the parent */ - CmiAddKeyToList(ParentKey, NewKey); + CmiAddKeyToList(ParentKey->KeyControlBlock, NewKey); return STATUS_SUCCESS; } @@ -670,7 +662,7 @@ CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock) ((PHBASE_BLOCK)HiveBase)->Length = LoaderBlock->RegistryLength; Status = CmpInitializeHive((PCMHIVE*)&SystemHive, HINIT_MEMORY, - 0, //HIVE_NOLAZYFLUSH, + HIVE_NOLAZYFLUSH, HFILE_TYPE_LOG, HiveBase, NULL, @@ -915,14 +907,8 @@ CmpCreateRegistryRoot(VOID) RootKey->ProcessID = PsGetCurrentProcessId(); #else RtlpCreateUnicodeString(&RootKey->Name, L"Registry", NonPagedPool); - RootKey->SubKeyCounts = 0; - RootKey->SubKeys = NULL; - RootKey->SizeOfSubKeys = 0; #endif - /* Insert it into the object list head */ - InsertTailList(&CmiKeyObjectListHead, &RootKey->KeyBodyList); - /* Insert the key into the namespace */ Status = ObInsertObject(RootKey, NULL, @@ -1023,8 +1009,8 @@ CmpLoadHiveThread(IN PVOID StartContext) { WCHAR FileBuffer[MAX_PATH], RegBuffer[MAX_PATH], ConfigPath[MAX_PATH]; UNICODE_STRING TempName, FileName, RegName; - ULONG FileStart, RegStart, i, ErrorResponse, ClusterSize, WorkerCount; - ULONG PrimaryDisposition, SecondaryDisposition, Length; + ULONG FileStart, RegStart, i, ErrorResponse, WorkerCount, Length; + ULONG PrimaryDisposition, SecondaryDisposition, ClusterSize; PCMHIVE CmHive; HANDLE PrimaryHandle, LogHandle; NTSTATUS Status = STATUS_SUCCESS; @@ -1101,13 +1087,12 @@ CmpLoadHiveThread(IN PVOID StartContext) } else { - if (ExpInTextModeSetup) { - /* We already have a hive, is it volatile? */ CmHive = CmpMachineHiveList[i].CmHive; + /* We already have a hive, is it volatile? */ if (!(CmHive->Hive.HiveFlags & HIVE_VOLATILE)) { DPRINT1("[HiveLoad]: Open from file %wZ\n", &FileName); - + /* It's now, open the hive file and log */ Status = CmpOpenHiveFiles(&FileName, L".LOG", @@ -1137,31 +1122,31 @@ CmpLoadHiveThread(IN PVOID StartContext) /* Save the file handles. This should remove our sync hacks */ CmHive->FileHandles[HFILE_TYPE_LOG] = LogHandle; CmHive->FileHandles[HFILE_TYPE_PRIMARY] = PrimaryHandle; - + /* Allow lazy flushing since the handles are there -- remove sync hacks */ //ASSERT(CmHive->Hive.HiveFlags & HIVE_NOLAZYFLUSH); CmHive->Hive.HiveFlags &= ~HIVE_NOLAZYFLUSH; - + /* Get the real size of the hive */ Length = CmHive->Hive.Storage[Stable].Length + HBLOCK_SIZE; - + /* Check if the cluster size doesn't match */ if (CmHive->Hive.Cluster != ClusterSize) ASSERT(FALSE); /* Set the file size */ - if (!CmpFileSetSize((PHHIVE)CmHive, HFILE_TYPE_PRIMARY, Length, Length)) + //if (!CmpFileSetSize((PHHIVE)CmHive, HFILE_TYPE_PRIMARY, Length, Length)) { /* This shouldn't fail */ - ASSERT(FALSE); + //ASSERT(FALSE); } - + /* Another thing we don't support is NTLDR-recovery */ if (CmHive->Hive.BaseBlock->BootRecover) ASSERT(FALSE); /* Finally, set our allocated hive to the same hive we've had */ CmpMachineHiveList[i].CmHive2 = CmHive; ASSERT(CmpMachineHiveList[i].CmHive == CmpMachineHiveList[i].CmHive2); - }} + } } /* We're done */ @@ -1289,7 +1274,7 @@ CmpInitializeHiveList(IN USHORT Flag) Status = CmpLinkHiveToMaster(&RegName, NULL, CmpMachineHiveList[i].CmHive2, - FALSE, //CmpMachineHiveList[i].Allocate, + CmpMachineHiveList[i].Allocate, SecurityDescriptor); if (Status != STATUS_SUCCESS) { @@ -1368,12 +1353,6 @@ CmInitSystem1(VOID) /* Save the current process and lock the registry */ CmpSystemProcess = PsGetCurrentProcess(); -#if 1 - /* OLD CM: Initialize the key object list */ - InitializeListHead(&CmiKeyObjectListHead); - InitializeListHead(&CmiConnectedHiveList); -#endif - /* Create the key object types */ Status = CmpCreateObjectTypes(); if (!NT_SUCCESS(Status)) @@ -1475,7 +1454,7 @@ CmInitSystem1(VOID) ((PHBASE_BLOCK)BaseAddress)->Length = Length; Status = CmpInitializeHive((PCMHIVE*)&HardwareHive, HINIT_MEMORY, //HINIT_CREATE, - HIVE_VOLATILE, + HIVE_VOLATILE | HIVE_NOLAZYFLUSH, HFILE_TYPE_PRIMARY, BaseAddress, // NULL, NULL,