Author: fireball Date: Fri Nov 23 17:15:04 2007 New Revision: 30694
URL: http://svn.reactos.org/svn/reactos?rev=30694&view=rev Log: - Major cleanup of code inside CmiConnectHive: - Don't derefernece the parent key since we need to keep a reference to it - Set the hive dirty flag to clean after a connect - Simplify code - Move code as part of CmpLinkHivetoMAster - Use new function CmpCreateLinkNode instead of CmpDoCreate - Fix some asserts in CmpCreateLinkNode since we don't lock the KCB yet.
Modified: trunk/reactos/ntoskrnl/cm/cm.h trunk/reactos/ntoskrnl/cm/registry.c trunk/reactos/ntoskrnl/config/cm.h trunk/reactos/ntoskrnl/config/cmparse.c
Modified: trunk/reactos/ntoskrnl/cm/cm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/cm.h?rev=30694&... ============================================================================== --- trunk/reactos/ntoskrnl/cm/cm.h (original) +++ trunk/reactos/ntoskrnl/cm/cm.h Fri Nov 23 17:15:04 2007 @@ -86,26 +86,9 @@ VOID CmiAddKeyToList(IN PKEY_OBJECT ParentKey, IN PKEY_OBJECT NewKey); - -NTSTATUS -CmiLoadHive(POBJECT_ATTRIBUTES KeyObjectAttributes, - PCUNICODE_STRING FileName, - ULONG Flags); - -NTSTATUS -CmiScanKeyForValue(IN PCMHIVE RegistryHive, - IN PCM_KEY_NODE KeyCell, - IN PUNICODE_STRING ValueName, - OUT PCM_KEY_VALUE *ValueCell, - OUT HCELL_INDEX *VBOffset); - VOID NTAPI CmpLazyFlush(VOID); - -NTSTATUS -CmiConnectHive(POBJECT_ATTRIBUTES KeyObjectAttributes, - PCMHIVE RegistryHive);
NTSTATUS CmiInitHives(BOOLEAN SetupBoot);
Modified: trunk/reactos/ntoskrnl/cm/registry.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/registry.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/cm/registry.c (original) +++ trunk/reactos/ntoskrnl/cm/registry.c Fri Nov 23 17:15:04 2007 @@ -92,6 +92,7 @@ /* Insert it into the global list (we don't have KCBs here) */ InsertTailList(&CmiKeyObjectListHead, &KeyObject->KeyBodyList);
+ /* Release hive lock */ ExReleaseResourceLite(&CmpRegistryLock); KeLeaveCriticalRegion(); } @@ -105,8 +106,16 @@ IN PSECURITY_DESCRIPTOR SecurityDescriptor) { OBJECT_ATTRIBUTES ObjectAttributes; - - /* Don't do anything if we don't actually have a hive */ + UNICODE_STRING RemainingPath; + PKEY_OBJECT ParentKey; + PKEY_OBJECT NewKey; + NTSTATUS Status; + UNICODE_STRING ObjectName; + OBJECT_CREATE_INFORMATION ObjectCreateInfo; + CM_PARSE_CONTEXT ParseContext = {0}; + PAGED_CODE(); + + /* TEMPHACK: Don't do anything if we don't actually have a hive */ if (Allocate) return STATUS_SUCCESS;
/* Setup the object attributes */ @@ -115,40 +124,24 @@ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, RootDirectory, SecurityDescriptor); - - /* Connect the hive */ - return CmiConnectHive(&ObjectAttributes, RegistryHive); -} - -NTSTATUS -CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes, - IN PCMHIVE RegistryHive) -{ - UNICODE_STRING RemainingPath; - PKEY_OBJECT ParentKey; - PKEY_OBJECT NewKey; - NTSTATUS Status; - PWSTR SubName; - UNICODE_STRING ObjectName; - OBJECT_CREATE_INFORMATION ObjectCreateInfo; - - DPRINT("CmiConnectHive(%p, %p) called.\n", - KeyObjectAttributes, RegistryHive); - + + /* Setup the parse context */ + ParseContext.CreateLink = TRUE; + ParseContext.CreateOperation = TRUE; + ParseContext.ChildHive.KeyHive = &RegistryHive->Hive; + + /* Because of CmCreateRootNode, ReactOS Hack */ + ParseContext.ChildHive.KeyCell = RegistryHive->Hive.BaseBlock->RootCell; + /* Capture all the info */ - DPRINT("Capturing Create Info\n"); - Status = ObpCaptureObjectAttributes(KeyObjectAttributes, + Status = ObpCaptureObjectAttributes(&ObjectAttributes, KernelMode, FALSE, &ObjectCreateInfo, &ObjectName); - - if (!NT_SUCCESS(Status)) - { - DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status); - return Status; - } - + if (!NT_SUCCESS(Status)) return Status; + + /* Do the parse */ Status = CmFindObject(&ObjectCreateInfo, &ObjectName, (PVOID*)&ParentKey, @@ -156,93 +149,72 @@ CmpKeyObjectType, NULL, NULL); - /* Yields a new reference */ - ObpReleaseCapturedAttributes(&ObjectCreateInfo); - + + /* Let go of captured attributes and name */ + ObpReleaseCapturedAttributes(&ObjectCreateInfo); if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName); + + /* Get out of here if we failed */ + if (!NT_SUCCESS(Status)) return Status; + + /* Scan for no name */ + if (!(RemainingPath.Length) || (RemainingPath.Buffer[0] == UNICODE_NULL)) + { + /* Fail */ + ObDereferenceObject(ParentKey); + return STATUS_OBJECT_NAME_NOT_FOUND; + } + + /* Scan for leading backslash */ + while ((RemainingPath.Length) && + (*RemainingPath.Buffer == OBJ_NAME_PATH_SEPARATOR)) + { + /* Ignore it */ + RemainingPath.Length -= sizeof(WCHAR); + RemainingPath.MaximumLength -= sizeof(WCHAR); + RemainingPath.Buffer++; + } + + /* Create the link node */ + Status = CmpCreateLinkNode(ParentKey->KeyControlBlock->KeyHive, + ParentKey->KeyControlBlock->KeyCell, + NULL, + RemainingPath, + KernelMode, + REG_OPTION_VOLATILE, + &ParseContext, + ParentKey->KeyControlBlock, + (PVOID*)&NewKey); if (!NT_SUCCESS(Status)) { + /* Failed */ + DPRINT1("CmpLinkHiveToMaster failed: %lx\n", Status); + ObDereferenceObject(ParentKey); return Status; } - - DPRINT ("RemainingPath %wZ\n", &RemainingPath); - - if ((RemainingPath.Buffer == NULL) || (RemainingPath.Buffer[0] == 0)) - { - ObDereferenceObject (ParentKey); - RtlFreeUnicodeString(&RemainingPath); - return STATUS_OBJECT_NAME_COLLISION; - } - - /* Ignore leading backslash */ - SubName = RemainingPath.Buffer; - if (*SubName == L'\') - SubName++; - - /* If RemainingPath contains \ we must return error - because CmiConnectHive() can not create trees */ - if (wcschr (SubName, L'\') != NULL) - { - ObDereferenceObject (ParentKey); - RtlFreeUnicodeString(&RemainingPath); - return STATUS_OBJECT_NAME_NOT_FOUND; - } - - DPRINT("RemainingPath %wZ ParentKey %p\n", - &RemainingPath, ParentKey); - - DPRINT ("SubName %S\n", SubName); - - /* Create the key */ - Status = CmpDoCreate(ParentKey->KeyControlBlock->KeyHive, - ParentKey->KeyControlBlock->KeyCell, - NULL, - &RemainingPath, - KernelMode, - NULL, - REG_OPTION_VOLATILE, - ParentKey->KeyControlBlock, - NULL, - (PVOID*)&NewKey); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CmiAddSubKey() failed (Status %lx)\n", Status); - ObDereferenceObject (NewKey); - ObDereferenceObject (ParentKey); - return STATUS_INSUFFICIENT_RESOURCES; - } - - NewKey->KeyControlBlock->KeyCell = RegistryHive->Hive.BaseBlock->RootCell; - NewKey->KeyControlBlock->KeyHive = &RegistryHive->Hive; - - Status = RtlpCreateUnicodeString(&NewKey->Name, - SubName, NonPagedPool); - RtlFreeUnicodeString(&RemainingPath); - if (!NT_SUCCESS(Status)) - { - DPRINT1("RtlpCreateUnicodeString() failed (Status %lx)\n", Status); - ObDereferenceObject (NewKey); - ObDereferenceObject (ParentKey); - return STATUS_INSUFFICIENT_RESOURCES; - } - + /* Free the create information */ ObpFreeAndReleaseCapturedAttributes(OBJECT_TO_OBJECT_HEADER(NewKey)->ObjectCreateInfo); OBJECT_TO_OBJECT_HEADER(NewKey)->ObjectCreateInfo = NULL; - - /* FN1 */ - ObReferenceObject (NewKey); - - CmiAddKeyToList (ParentKey, NewKey); - ObDereferenceObject (ParentKey); - - VERIFY_KEY_OBJECT(NewKey); - - /* We're holding a pointer to the parent key .. We must keep it - * referenced */ - /* Note: Do not dereference NewKey here! */ - - return STATUS_SUCCESS; + + /* Mark the hive as clean */ + RegistryHive->Hive.DirtyFlag = FALSE; + + /* Update KCB information */ + NewKey->KeyControlBlock->KeyCell = RegistryHive->Hive.BaseBlock->RootCell; + NewKey->KeyControlBlock->KeyHive = &RegistryHive->Hive; + + /* Build the key name */ + RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, + &RemainingPath, + &NewKey->Name); + + /* Reference the new key */ + ObReferenceObject(NewKey); + + /* Link this key to the parent */ + CmiAddKeyToList(ParentKey, NewKey); + return STATUS_SUCCESS; }
static NTSTATUS
Modified: trunk/reactos/ntoskrnl/config/cm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cm.h?rev=30... ============================================================================== --- trunk/reactos/ntoskrnl/config/cm.h (original) +++ trunk/reactos/ntoskrnl/config/cm.h Fri Nov 23 17:15:04 2007 @@ -455,10 +455,10 @@ ULONG CreateOptions; ULONG Disposition; CM_KEY_REFERENCE ChildHive; + HANDLE PredefinedHandle; BOOLEAN CreateLink; - BOOLEAN Flag2; - HANDLE PredefinedHandle; - ULONG PostActions; + BOOLEAN CreateOperation; + PCMHIVE OriginatingPoint; } CM_PARSE_CONTEXT, *PCM_PARSE_CONTEXT;
// @@ -1016,6 +1016,20 @@ IN ULONG CreateOptions, IN PCM_KEY_CONTROL_BLOCK ParentKcb, IN PCMHIVE OriginatingHive OPTIONAL, + OUT PVOID *Object +); + +NTSTATUS +NTAPI +CmpCreateLinkNode( + IN PHHIVE Hive, + IN HCELL_INDEX Cell, + IN PACCESS_STATE AccessState, + IN UNICODE_STRING Name, + IN KPROCESSOR_MODE AccessMode, + IN ULONG CreateOptions, + IN PCM_PARSE_CONTEXT Context, + IN PCM_KEY_CONTROL_BLOCK ParentKcb, OUT PVOID *Object );
Modified: trunk/reactos/ntoskrnl/config/cmparse.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmparse.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/config/cmparse.c (original) +++ trunk/reactos/ntoskrnl/config/cmparse.c Fri Nov 23 17:15:04 2007 @@ -444,14 +444,14 @@ }
/* If we have a KCB, make sure it's locked */ - ASSERT(CmpIsKcbLockedExclusive(*CachedKcb)); - - /* Create the KCB */ + //ASSERT(CmpIsKcbLockedExclusive(*CachedKcb)); + + /* Create the KCB. FIXME: Use lock flag */ Kcb = CmpCreateKeyControlBlock(Hive, Cell, Node, *CachedKcb, 0, KeyName); if (!Kcb) return STATUS_INSUFFICIENT_RESOURCES;
/* Make sure it's also locked, and set the pointer */ - ASSERT(CmpIsKcbLockedExclusive(Kcb)); + //ASSERT(CmpIsKcbLockedExclusive(Kcb)); *CachedKcb = Kcb;
/* Allocate the key object */