diff --git a/reactos/ntoskrnl/cm/cm.h b/reactos/ntoskrnl/cm/cm.h index c11fc72b1df..e14ec295620 100644 --- a/reactos/ntoskrnl/cm/cm.h +++ b/reactos/ntoskrnl/cm/cm.h @@ -86,27 +86,10 @@ CmUnRegisterCallback(IN LARGE_INTEGER Cookie); 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); diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index 654c4db41aa..c42e4a3ae89 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -92,6 +92,7 @@ EnlistKeyBodyWithKeyObject(IN PKEY_OBJECT KeyObject, /* 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 @@ CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName, IN PSECURITY_DESCRIPTOR SecurityDescriptor) { OBJECT_ATTRIBUTES ObjectAttributes; + 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(); - /* Don't do anything if we don't actually have a hive */ + /* 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 @@ CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName, 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 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes, CmpKeyObjectType, NULL, NULL); - /* Yields a new reference */ - ObpReleaseCapturedAttributes(&ObjectCreateInfo); - + + /* Let go of captured attributes and name */ + ObpReleaseCapturedAttributes(&ObjectCreateInfo); if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName); - if (!NT_SUCCESS(Status)) + + /* 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)) { - 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); + /* Fail */ + ObDereferenceObject(ParentKey); 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); + + /* 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)) { - DPRINT1("CmiAddSubKey() failed (Status %lx)\n", Status); - ObDereferenceObject (NewKey); - ObDereferenceObject (ParentKey); - return STATUS_INSUFFICIENT_RESOURCES; + /* Failed */ + DPRINT1("CmpLinkHiveToMaster failed: %lx\n", Status); + ObDereferenceObject(ParentKey); + return Status; } - - 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 diff --git a/reactos/ntoskrnl/config/cm.h b/reactos/ntoskrnl/config/cm.h index 40dfa8e1ee5..7c3e7956fb5 100644 --- a/reactos/ntoskrnl/config/cm.h +++ b/reactos/ntoskrnl/config/cm.h @@ -455,10 +455,10 @@ typedef struct _CM_PARSE_CONTEXT ULONG CreateOptions; ULONG Disposition; CM_KEY_REFERENCE ChildHive; - BOOLEAN CreateLink; - BOOLEAN Flag2; HANDLE PredefinedHandle; - ULONG PostActions; + BOOLEAN CreateLink; + BOOLEAN CreateOperation; + PCMHIVE OriginatingPoint; } CM_PARSE_CONTEXT, *PCM_PARSE_CONTEXT; // @@ -1019,6 +1019,20 @@ CmpDoCreate( 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 +); + // // Cell Index Routines // diff --git a/reactos/ntoskrnl/config/cmparse.c b/reactos/ntoskrnl/config/cmparse.c index 15aaa4e2466..6de5784550a 100644 --- a/reactos/ntoskrnl/config/cmparse.c +++ b/reactos/ntoskrnl/config/cmparse.c @@ -444,14 +444,14 @@ CmpDoOpen(IN PHHIVE Hive, } /* If we have a KCB, make sure it's locked */ - ASSERT(CmpIsKcbLockedExclusive(*CachedKcb)); + //ASSERT(CmpIsKcbLockedExclusive(*CachedKcb)); - /* Create the KCB */ + /* 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 */