Index: cmparse.c =================================================================== --- ntoskrnl/config/cmparse.c (revision 70042) +++ ntoskrnl/config/cmparse.c (working copy) @@ -337,7 +337,7 @@ *KeyCell, KeyNode, ParentKcb, - 0, // CMP_LOCK_HASHES_FOR_KCB, + CMP_LOCK_HASHES_FOR_KCB, Name); if (!Kcb) { @@ -411,6 +411,10 @@ LARGE_INTEGER TimeStamp; PCM_KEY_NODE KeyNode; + /* Lock flushes */ + CMP_ASSERT_KCB_LOCK(ParentKcb); + CmpLockHiveFlusherShared((PCMHIVE)Hive); + /* Check if the parent is being deleted */ if (ParentKcb->Delete) { @@ -497,6 +501,9 @@ ASSERT(FALSE); } + /* Clean up information we have on the subkey */ + CmpCleanUpSubKeyInfo(KeyBody->KeyControlBlock->ParentKcb); + /* Sanity checks */ ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyCell == Cell); ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyHive == Hive); @@ -543,6 +550,7 @@ Exit: /* Release the flusher lock and return status */ + CmpUnlockHiveFlusher((PCMHIVE)Hive); return Status; } @@ -631,7 +639,7 @@ Cell, Node, *CachedKcb, - 0, + CMP_LOCK_HASHES_FOR_KCB, KeyName); if (!Kcb) { @@ -651,12 +659,12 @@ return STATUS_REPARSE; } - /* Create the KCB. FIXME: Use lock flag */ + /* Create the KCB */ Kcb = CmpCreateKeyControlBlock(Hive, Cell, Node, *CachedKcb, - 0, + CMP_LOCK_HASHES_FOR_KCB, KeyName); if (!Kcb) { @@ -908,6 +916,9 @@ /* Get the key body */ KeyBody = (PCM_KEY_BODY)*Object; + /* Clean up information we have on the subkey */ + CmpCleanUpSubKeyInfo(KeyBody->KeyControlBlock->ParentKcb); + /* Sanity checks */ ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyCell == Cell); ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyHive == Hive); @@ -996,9 +1007,6 @@ OUT PULONG OuterStackArray, OUT PULONG *LockedKcbs) { - /* We don't lock anything for now */ - *LockedKcbs = NULL; - /* Calculate hash values */ *TotalRemainingSubkeys = 0xBAADF00D; @@ -1015,10 +1023,27 @@ /* Reference it */ (VOID)CmpReferenceKeyControlBlock(*Kcb); + /* Lock */ + CmpAcquireKcbLockExclusive(*Kcb); + OuterStackArray[0] = 1; + OuterStackArray[1] = (*Kcb)->ConvKey; + *LockedKcbs = OuterStackArray; + /* Return success for now */ return STATUS_SUCCESS; } +VOID +CmpUnLockKcbArray(PULONG LockedKcbs) +{ + ULONG i; + + for (i = 0; i < LockedKcbs[0]; i++) + { + CmpReleaseKcbLockByKey(LockedKcbs[i+1]); + } +} + NTSTATUS NTAPI CmpParseKey(IN PVOID ParseObject, @@ -1042,7 +1067,8 @@ UNICODE_STRING Current, NextName; PCM_PARSE_CONTEXT ParseContext = Context; ULONG TotalRemainingSubkeys = 0, MatchRemainSubkeyLevel = 0, TotalSubkeys = 0; - PULONG LockedKcbs = NULL; + ULONG LockedKcbArray[2]; + PULONG LockedKcbs; BOOLEAN Result, Last; PAGED_CODE(); @@ -1087,8 +1113,14 @@ &TotalRemainingSubkeys, &MatchRemainSubkeyLevel, &TotalSubkeys, - NULL, + LockedKcbArray, &LockedKcbs); + CMP_ASSERT_REGISTRY_LOCK(); + if (!NT_SUCCESS(Status)) + { + ParentKcb = NULL; + goto Quickie; + } /* This is now the parent */ ParentKcb = Kcb; @@ -1131,6 +1163,10 @@ } Current.MaximumLength += NextName.MaximumLength; + /* CmpGetSymbolicLink doesn't want a lock */ + CmpUnLockKcbArray(LockedKcbs); + LockedKcbs = NULL; + /* Parse the symlink */ if (CmpGetSymbolicLink(Hive, CompleteName, @@ -1207,6 +1243,10 @@ Object); if (Status == STATUS_REPARSE) { + /* CmpGetSymbolicLink doesn't want a lock */ + CmpUnLockKcbArray(LockedKcbs); + LockedKcbs = NULL; + /* Parse the symlink */ if (!CmpGetSymbolicLink(Hive, CompleteName, @@ -1239,12 +1279,12 @@ Cell, Node, ParentKcb, - 0, + CMP_LOCK_HASHES_FOR_KCB, &NextName); if (!Kcb) ASSERT(FALSE); /* Dereference the parent and set the new one */ - CmpDereferenceKeyControlBlock(ParentKcb); + CmpDereferenceKeyControlBlockWithLock(ParentKcb, FALSE); ParentKcb = Kcb; } else @@ -1322,6 +1362,10 @@ } Current.MaximumLength += NextName.MaximumLength; + /* CmpGetSymbolicLink doesn't want a lock */ + CmpUnLockKcbArray(LockedKcbs); + LockedKcbs = NULL; + /* Parse the symlink */ if (CmpGetSymbolicLink(Hive, CompleteName, @@ -1385,6 +1429,11 @@ /* Dereference the parent if it exists */ Quickie: + if (LockedKcbs != NULL) + { + CmpUnLockKcbArray(LockedKcbs); + } + if (ParentKcb) CmpDereferenceKeyControlBlock(ParentKcb); /* Unlock the registry */