Author: fireball
Date: Wed Dec 5 00:39:15 2007
New Revision: 31009
URL:
http://svn.reactos.org/svn/reactos?rev=31009&view=rev
Log:
- Finish correct definition of CM_KEY_NODE.
- Fix broken CmpTestRegistryLock functions, they could return FALSE even if the lock was
held.
- Enable some extra assertions.
- Update KCB flags as well when updating keynode flags in CmpDoCreate.
- Update KCB Last write time as well when updating keynode lastwritetime in CmpDoCreate.
- Do CmpDoOpen with the registry lock held, and tell CmpCreateKeycontrolBlock to lock the
KCB exclusively.
- Enable link-node create code to set the ChildHiveRefernece values. This is used to
"escape" the current Hive when a KEY_HIVE_EXIT node is detected (an internal
symlink) and required for new parsing semantics.
- Implement CmpHandleExitNode to test how "escaping" from an exit node into a
link hive works (it does).
- Plug that function into the new parse routine for testing purposes.
- Enable CmpDoOpen path in the new parse routine, only used for link node creation for
now.
Modified:
trunk/reactos/lib/cmlib/cmdata.h
trunk/reactos/ntoskrnl/config/cmparse.c
trunk/reactos/ntoskrnl/config/cmsysini.c
Modified: trunk/reactos/lib/cmlib/cmdata.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/cmlib/cmdata.h?rev=310…
==============================================================================
--- trunk/reactos/lib/cmlib/cmdata.h (original)
+++ trunk/reactos/lib/cmlib/cmdata.h Wed Dec 5 00:39:15 2007
@@ -103,7 +103,7 @@
HCELL_INDEX SubKeyLists[HTYPE_COUNT];
CHILD_LIST ValueList;
};
- //CM_KEY_REFERENCE ChildHiveReference;
+ CM_KEY_REFERENCE ChildHiveReference;
};
HCELL_INDEX Security;
HCELL_INDEX Class;
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 Wed Dec 5 00:39:15 2007
@@ -379,11 +379,12 @@
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyCell == Cell);
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyHive == Hive);
ASSERT(KeyBody->KeyControlBlock->ParentKcb == ParentKcb);
- //ASSERT(KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen ==
KeyNode->MaxNameLen);
+ ASSERT(KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen ==
KeyNode->MaxNameLen);
/* Update the timestamp */
KeQuerySystemTime(&TimeStamp);
KeyNode->LastWriteTime = TimeStamp;
+ KeyBody->KeyControlBlock->ParentKcb->KcbLastWriteTime = TimeStamp;
/* Check if we need to update name maximum */
if (KeyNode->MaxNameLen < Name->Length)
@@ -413,6 +414,7 @@
/* Update the flags */
CellData->u.KeyNode.Flags |= KEY_SYM_LINK;
+ KeyBody->KeyControlBlock->Flags = CellData->u.KeyNode.Flags;
HvReleaseCell(Hive, KeyCell);
}
}
@@ -448,6 +450,9 @@
/* It is, don't touch it */
return STATUS_OBJECT_NAME_NOT_FOUND;
}
+
+ /* Do this in the registry lock */
+ CmpLockRegistry();
/* If we have a KCB, make sure it's locked */
//ASSERT(CmpIsKcbLockedExclusive(*CachedKcb));
@@ -457,13 +462,16 @@
Cell,
Node,
*CachedKcb,
- CMP_LOCK_HASHES_FOR_KCB,
+ 0,
KeyName);
if (!Kcb) return STATUS_INSUFFICIENT_RESOURCES;
/* Make sure it's also locked, and set the pointer */
//ASSERT(CmpIsKcbLockedExclusive(Kcb));
*CachedKcb = Kcb;
+
+ /* Release the registry lock */
+ CmpUnlockRegistry();
/* Allocate the key object */
Status = ObCreateObject(AccessMode,
@@ -671,8 +679,8 @@
KeyNode->ClassLength = 0;
/* Reference the root node */
- //KeyNode->ChildHiveReference.KeyHive = Context->ChildHive.KeyHive;
- //KeyNode->ChildHiveReference.KeyCell = ChildCell;
+ KeyNode->ChildHiveReference.KeyHive = Context->ChildHive.KeyHive;
+ KeyNode->ChildHiveReference.KeyCell = ChildCell;
HvReleaseCell(Hive, LinkCell);
/* Get the parent node */
@@ -698,7 +706,7 @@
/* Sanity checks */
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyCell == Cell);
ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyHive == Hive);
- //ASSERT(KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen ==
KeyNode->MaxNameLen);
+ ASSERT(KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen ==
KeyNode->MaxNameLen);
/* Update the timestamp */
KeQuerySystemTime(&TimeStamp);
@@ -725,6 +733,42 @@
ExReleasePushLock((PVOID)&((PCMHIVE)Context->ChildHive.KeyHive)->FlusherLock);
ExReleasePushLock((PVOID)&((PCMHIVE)Hive)->FlusherLock);
return Status;
+}
+
+VOID
+NTAPI
+CmpHandleExitNode(IN OUT PHHIVE *Hive,
+ IN OUT HCELL_INDEX *Cell,
+ IN OUT PCM_KEY_NODE *KeyNode,
+ IN OUT PHHIVE *ReleaseHive,
+ IN OUT HCELL_INDEX *ReleaseCell)
+{
+ /* Check if we have anything to release */
+ if (*ReleaseCell != HCELL_NIL)
+ {
+ /* Release it */
+ ASSERT(*ReleaseHive != NULL);
+ HvReleaseCell((*ReleaseHive), *ReleaseCell);
+ }
+
+ /* Get the link references */
+ *Hive = (*KeyNode)->ChildHiveReference.KeyHive;
+ *Cell = (*KeyNode)->ChildHiveReference.KeyCell;
+
+ /* Get the new node */
+ *KeyNode = (PCM_KEY_NODE)HvGetCell((*Hive), *Cell);
+ if (*KeyNode)
+ {
+ /* Set the new release values */
+ *ReleaseCell = *Cell;
+ *ReleaseHive = *Hive;
+ }
+ else
+ {
+ /* Nothing to release */
+ *ReleaseCell = HCELL_NIL;
+ *ReleaseHive = NULL;
+ }
}
NTSTATUS
@@ -775,11 +819,13 @@
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
OUT PVOID *Object)
{
- NTSTATUS Status = STATUS_UNSUCCESSFUL;
+ NTSTATUS Status;
PCM_KEY_CONTROL_BLOCK Kcb, ParentKcb;
PHHIVE Hive = NULL;
PCM_KEY_NODE Node = NULL;
HCELL_INDEX Cell = HCELL_NIL, NextCell;
+ PHHIVE HiveToRelease = NULL;
+ HCELL_INDEX CellToRelease = HCELL_NIL;
UNICODE_STRING Current, NextName;
PCM_PARSE_CONTEXT ParseContext = Context;
ULONG TotalRemainingSubkeys = 0, MatchRemainSubkeyLevel = 0, TotalSubkeys = 0;
@@ -852,7 +898,7 @@
DPRINT1("Node Parse: %p\n", Node);
/* Start parsing */
- Status = STATUS_SUCCESS;
+ Status = STATUS_NOT_IMPLEMENTED;
while (TRUE)
{
/* Get the next component */
@@ -865,7 +911,7 @@
{
/* Find the subkey */
NextCell = CmpFindSubKeyByName(Hive, Node, &NextName);
- DPRINT1("NextCell Parse: %lx\n", NextCell);
+ DPRINT1("NextCell Parse: %lx %wZ\n", NextCell, &NextName);
if (NextCell != HCELL_NIL)
{
/* Get the new node */
@@ -877,17 +923,57 @@
/* Check if this was the last key */
if (Last)
{
- /* Shouldn't happen yet */
- DPRINT1("Unhandled: Open of last key\n");
+ /* Is this an exit node */
+ if (Node->Flags & KEY_HIVE_EXIT)
+ {
+ /* Handle it */
+ DPRINT1("Exit node\n");
+ CmpHandleExitNode(&Hive,
+ &Cell,
+ &Node,
+ &HiveToRelease,
+ &CellToRelease);
+ DPRINT1("Node Parse: %p\n", Node);
+ if (!Node) ASSERT(FALSE);
+ }
+
+ /* Do the open */
+ Status = CmpDoOpen(Hive,
+ Cell,
+ Node,
+ AccessState,
+ AccessMode,
+ Attributes,
+ ParseContext,
+ 0,
+ &Kcb,
+ &NextName,
+ Object);
+ if (Status == STATUS_REPARSE)
+ {
+ /* Not implemented */
+ DPRINT1("Parsing sym link\n");
+ while (TRUE);
+ }
+
+ /* We are done */
+ DPRINT1("Open of last key\n");
break;
}
- /* Get hive and cell from reference */
- //Hive = Node->ChildHiveReference.KeyHive;
- //Cell = Node->ChildHiveReference.KeyCell;
- Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
- DPRINT1("Node Parse: %p\n", Node);
- if (!Node) ASSERT(FALSE);
+ /* Is this an exit node */
+ if (Node->Flags & KEY_HIVE_EXIT)
+ {
+ /* Handle it */
+ DPRINT1("Exit node: %lx\n", Node->Flags);
+ CmpHandleExitNode(&Hive,
+ &Cell,
+ &Node,
+ &HiveToRelease,
+ &CellToRelease);
+ DPRINT1("Node Parse: %p\n", Node);
+ if (!Node) ASSERT(FALSE);
+ }
/* Create a KCB for this key */
Kcb = CmpCreateKeyControlBlock(Hive,
@@ -959,5 +1045,5 @@
/* Unlock the registry */
CmpUnlockRegistry();
- return STATUS_NOT_IMPLEMENTED;
+ return Status;
}
Modified: trunk/reactos/ntoskrnl/config/cmsysini.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmsysini.c…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmsysini.c (original)
+++ trunk/reactos/ntoskrnl/config/cmsysini.c Wed Dec 5 00:39:15 2007
@@ -1580,7 +1580,7 @@
CmpTestRegistryLock(VOID)
{
/* Test the lock */
- return (BOOLEAN)ExIsResourceAcquiredSharedLite(&CmpRegistryLock);
+ return !ExIsResourceAcquiredSharedLite(&CmpRegistryLock) ? FALSE : TRUE;
}
BOOLEAN
@@ -1588,7 +1588,7 @@
CmpTestRegistryLockExclusive(VOID)
{
/* Test the lock */
- return ExIsResourceAcquiredExclusiveLite(&CmpRegistryLock);
+ return !ExIsResourceAcquiredExclusiveLite(&CmpRegistryLock) ? FALSE : TRUE;
}
VOID