mirror of
https://github.com/reactos/reactos.git
synced 2024-07-05 04:06:22 +00:00
- 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:
parent
06220aab9e
commit
6896e0c290
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
@ -116,39 +125,23 @@ CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName,
|
|||
RootDirectory,
|
||||
SecurityDescriptor);
|
||||
|
||||
/* Connect the hive */
|
||||
return CmiConnectHive(&ObjectAttributes, RegistryHive);
|
||||
}
|
||||
/* Setup the parse context */
|
||||
ParseContext.CreateLink = TRUE;
|
||||
ParseContext.CreateOperation = TRUE;
|
||||
ParseContext.ChildHive.KeyHive = &RegistryHive->Hive;
|
||||
|
||||
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);
|
||||
/* 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)) return Status;
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Do the parse */
|
||||
Status = CmFindObject(&ObjectCreateInfo,
|
||||
&ObjectName,
|
||||
(PVOID*)&ParentKey,
|
||||
|
@ -156,92 +149,71 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
|
|||
CmpKeyObjectType,
|
||||
NULL,
|
||||
NULL);
|
||||
/* Yields a new reference */
|
||||
|
||||
/* 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);
|
||||
if (!NT_SUCCESS(Status))
|
||||
/* Scan for leading backslash */
|
||||
while ((RemainingPath.Length) &&
|
||||
(*RemainingPath.Buffer == OBJ_NAME_PATH_SEPARATOR))
|
||||
{
|
||||
DPRINT1("CmiAddSubKey() failed (Status %lx)\n", Status);
|
||||
ObDereferenceObject (NewKey);
|
||||
ObDereferenceObject (ParentKey);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
/* Ignore it */
|
||||
RemainingPath.Length -= sizeof(WCHAR);
|
||||
RemainingPath.MaximumLength -= sizeof(WCHAR);
|
||||
RemainingPath.Buffer++;
|
||||
}
|
||||
|
||||
NewKey->KeyControlBlock->KeyCell = RegistryHive->Hive.BaseBlock->RootCell;
|
||||
NewKey->KeyControlBlock->KeyHive = &RegistryHive->Hive;
|
||||
|
||||
Status = RtlpCreateUnicodeString(&NewKey->Name,
|
||||
SubName, NonPagedPool);
|
||||
RtlFreeUnicodeString(&RemainingPath);
|
||||
/* 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("RtlpCreateUnicodeString() failed (Status %lx)\n", Status);
|
||||
ObDereferenceObject (NewKey);
|
||||
ObDereferenceObject (ParentKey);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
/* Failed */
|
||||
DPRINT1("CmpLinkHiveToMaster failed: %lx\n", Status);
|
||||
ObDereferenceObject(ParentKey);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Free the create information */
|
||||
ObpFreeAndReleaseCapturedAttributes(OBJECT_TO_OBJECT_HEADER(NewKey)->ObjectCreateInfo);
|
||||
OBJECT_TO_OBJECT_HEADER(NewKey)->ObjectCreateInfo = NULL;
|
||||
|
||||
/* FN1 */
|
||||
ObReferenceObject (NewKey);
|
||||
/* Mark the hive as clean */
|
||||
RegistryHive->Hive.DirtyFlag = FALSE;
|
||||
|
||||
CmiAddKeyToList (ParentKey, NewKey);
|
||||
ObDereferenceObject (ParentKey);
|
||||
/* Update KCB information */
|
||||
NewKey->KeyControlBlock->KeyCell = RegistryHive->Hive.BaseBlock->RootCell;
|
||||
NewKey->KeyControlBlock->KeyHive = &RegistryHive->Hive;
|
||||
|
||||
VERIFY_KEY_OBJECT(NewKey);
|
||||
/* Build the key name */
|
||||
RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
|
||||
&RemainingPath,
|
||||
&NewKey->Name);
|
||||
|
||||
/* We're holding a pointer to the parent key .. We must keep it
|
||||
* referenced */
|
||||
/* Note: Do not dereference NewKey here! */
|
||||
/* Reference the new key */
|
||||
ObReferenceObject(NewKey);
|
||||
|
||||
/* Link this key to the parent */
|
||||
CmiAddKeyToList(ParentKey, NewKey);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue