- 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.

svn path=/trunk/; revision=30694
This commit is contained in:
Aleksey Bragin 2007-11-23 14:15:04 +00:00
parent 06220aab9e
commit 6896e0c290
4 changed files with 99 additions and 130 deletions

View file

@ -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);

View file

@ -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

View file

@ -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
//

View file

@ -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 */