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=3…
==============================================================================
--- 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?…
==============================================================================
--- 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 */