mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 01:42:30 +00:00
- Use CmpLockRegistry instead of manual registry locking -- this also makes the registry lock shared instead of exclusive.
- Start using KCB locking/unlocking, usually shared first. - Support KCB lock promotion from shared to exclusive when value cache functions require it (SearchNeedExclusiveLock -- not yet used). - Add multiple checks for deleted KCBs so that operations on them fail. - Protect symlinks from being erroneously modified. - Remove a ReactOS symlink hack. - Add code to setup the KCB Value Cache (right now we use the node list since nobody was setting the value cache up). - Detect and assert on CM_KCB_SYM_LINK_FOUND, this is used by caching which we don't support. - Protect KEY_NO_DELETE nodes from deletion. - Lock the registry during hive flushing. - Respect CmpNoWrite if it's set. - Don't ignore Allocate flag sent to CmpLinkhivetoMaster during hive loading. svn path=/trunk/; revision=31262
This commit is contained in:
parent
442b5501fe
commit
d9633373f6
|
@ -266,10 +266,56 @@ CmSetValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
NTSTATUS Status;
|
||||
BOOLEAN Found, Result;
|
||||
ULONG Count, ChildIndex, SmallData, Storage;
|
||||
VALUE_SEARCH_RETURN_TYPE SearchResult;
|
||||
|
||||
/* Acquire hive lock exclusively */
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
|
||||
/* Acquire hive lock */
|
||||
CmpLockRegistry();
|
||||
CmpAcquireKcbLockShared(Kcb);
|
||||
|
||||
/* Sanity check */
|
||||
ASSERT(sizeof(ULONG) == CM_KEY_VALUE_SMALL);
|
||||
|
||||
/* Don't touch deleted KCBs */
|
||||
DoAgain:
|
||||
if (Kcb->Delete)
|
||||
{
|
||||
/* Fail */
|
||||
Status = STATUS_KEY_DELETED;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
/* Don't let anyone mess with symlinks */
|
||||
if ((Kcb->Flags & KEY_SYM_LINK) &&
|
||||
((Type != REG_LINK) ||
|
||||
!(ValueName) ||
|
||||
!(RtlEqualUnicodeString(&CmSymbolicLinkValueName, ValueName, TRUE))))
|
||||
{
|
||||
/* Invalid modification of a symlink key */
|
||||
Status = STATUS_ACCESS_DENIED;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
/* Search for the value */
|
||||
SearchResult = SearchFail;
|
||||
if (SearchResult == SearchNeedExclusiveLock)
|
||||
{
|
||||
/* Try again with the exclusive lock */
|
||||
CmpConvertKcbSharedToExclusive(Kcb);
|
||||
goto DoAgain;
|
||||
}
|
||||
else if (SearchResult == SearchSuccess)
|
||||
{
|
||||
/* We don't actually need to do anything! */
|
||||
Status = STATUS_SUCCESS;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
/* We need the exclusive KCB lock now */
|
||||
if (!(CmpIsKcbLockedExclusive(Kcb)) && !(CmpTryToConvertKcbSharedToExclusive(Kcb)))
|
||||
{
|
||||
/* Acquire exclusive lock */
|
||||
CmpConvertKcbSharedToExclusive(Kcb);
|
||||
}
|
||||
|
||||
/* Get pointer to key cell */
|
||||
Hive = Kcb->KeyHive;
|
||||
|
@ -315,7 +361,11 @@ CmSetValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
/* No child list, we'll need to add it */
|
||||
ChildIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
/* The KCB must be locked exclusive at this point */
|
||||
ASSERT((CmpIsKcbLockedExclusive(Kcb) == TRUE) ||
|
||||
(CmpTestRegistryLockExclusive() == TRUE));
|
||||
|
||||
/* Mark the cell dirty */
|
||||
HvMarkCellDirty(Hive, Cell, FALSE);
|
||||
|
||||
|
@ -357,27 +407,23 @@ CmSetValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
SmallData);
|
||||
}
|
||||
|
||||
/* Mark link key */
|
||||
if ((Type == REG_LINK) &&
|
||||
(_wcsicmp(ValueName->Buffer, L"SymbolicLinkValue") == 0))
|
||||
{
|
||||
Parent->Flags |= KEY_SYM_LINK;
|
||||
}
|
||||
|
||||
/* Check for success */
|
||||
Quickie:
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Check if the maximum value name length changed */
|
||||
ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen);
|
||||
if (Parent->MaxValueNameLen < ValueName->Length)
|
||||
{
|
||||
/* Set the new values */
|
||||
Parent->MaxValueNameLen = ValueName->Length;
|
||||
Kcb->KcbMaxValueNameLen = ValueName->Length;
|
||||
}
|
||||
|
||||
|
||||
/* Check if the maximum data length changed */
|
||||
ASSERT(Parent->MaxValueDataLen == Kcb->KcbMaxValueDataLen);
|
||||
if (Parent->MaxValueDataLen < DataLength)
|
||||
{
|
||||
/* Update it */
|
||||
Parent->MaxValueDataLen = DataLength;
|
||||
Kcb->KcbMaxValueDataLen = Parent->MaxValueDataLen;
|
||||
}
|
||||
|
@ -385,11 +431,32 @@ Quickie:
|
|||
/* Save the write time */
|
||||
KeQuerySystemTime(&Parent->LastWriteTime);
|
||||
KeQuerySystemTime(&Kcb->KcbLastWriteTime);
|
||||
}
|
||||
|
||||
/* Check if the cell is cached */
|
||||
if ((Found) && (CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList)))
|
||||
{
|
||||
/* Shouldn't happen */
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Cleanup the value cache */
|
||||
CmpCleanUpKcbValueCache(Kcb);
|
||||
|
||||
/* Release the lock */
|
||||
ExReleaseResourceLite(&CmpRegistryLock);
|
||||
KeLeaveCriticalRegion();
|
||||
/* Sanity checks */
|
||||
ASSERT(!(CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList)));
|
||||
ASSERT(!(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND));
|
||||
|
||||
/* Set the value cache */
|
||||
Kcb->ValueCache.Count = Parent->ValueList.Count;
|
||||
Kcb->ValueCache.ValueList = Parent->ValueList.List;
|
||||
}
|
||||
}
|
||||
|
||||
Quickie:
|
||||
/* Release the locks */
|
||||
CmpReleaseKcbLock(Kcb);
|
||||
CmpUnlockRegistry();
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -408,8 +475,19 @@ CmDeleteValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
BOOLEAN Result;
|
||||
|
||||
/* Acquire hive lock */
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
|
||||
CmpLockRegistry();
|
||||
|
||||
/* Lock KCB exclusively */
|
||||
CmpAcquireKcbLockExclusive(Kcb);
|
||||
|
||||
/* Don't touch deleted keys */
|
||||
if (Kcb->Delete)
|
||||
{
|
||||
/* Undo everything */
|
||||
CmpReleaseKcbLock(Kcb);
|
||||
CmpUnlockRegistry();
|
||||
return STATUS_KEY_DELETED;
|
||||
}
|
||||
|
||||
/* Get the hive and the cell index */
|
||||
Hive = Kcb->KeyHive;
|
||||
|
@ -490,6 +568,17 @@ CmDeleteValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
Kcb->KcbMaxValueNameLen = 0;
|
||||
Kcb->KcbMaxValueDataLen = 0;
|
||||
}
|
||||
|
||||
/* Cleanup the value cache */
|
||||
CmpCleanUpKcbValueCache(Kcb);
|
||||
|
||||
/* Sanity checks */
|
||||
ASSERT(!(CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList)));
|
||||
ASSERT(!(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND));
|
||||
|
||||
/* Set the value cache */
|
||||
Kcb->ValueCache.Count = ChildList->Count;
|
||||
Kcb->ValueCache.ValueList = ChildList->List;
|
||||
|
||||
/* Change default Status to success */
|
||||
Status = STATUS_SUCCESS;
|
||||
|
@ -507,9 +596,9 @@ Quickie:
|
|||
HvReleaseCell(Hive, ChildCell);
|
||||
}
|
||||
|
||||
/* Release hive lock */
|
||||
ExReleaseResourceLite(&CmpRegistryLock);
|
||||
KeLeaveCriticalRegion();
|
||||
/* Release locks */
|
||||
CmpReleaseKcbLock(Kcb);
|
||||
CmpUnlockRegistry();
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -533,8 +622,27 @@ CmQueryValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
PAGED_CODE();
|
||||
|
||||
/* Acquire hive lock */
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
|
||||
CmpLockRegistry();
|
||||
|
||||
/* Lock the KCB shared */
|
||||
CmpAcquireKcbLockShared(Kcb);
|
||||
|
||||
/* Don't touch deleted keys */
|
||||
DoAgain:
|
||||
if (Kcb->Delete)
|
||||
{
|
||||
/* Undo everything */
|
||||
CmpReleaseKcbLock(Kcb);
|
||||
CmpUnlockRegistry();
|
||||
return STATUS_KEY_DELETED;
|
||||
}
|
||||
|
||||
/* We don't deal with this yet */
|
||||
if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)
|
||||
{
|
||||
/* Shouldn't happen */
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
/* Get the hive */
|
||||
Hive = Kcb->KeyHive;
|
||||
|
@ -547,6 +655,17 @@ CmQueryValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
&ValueData,
|
||||
&ValueCached,
|
||||
&CellToRelease);
|
||||
if (Result == SearchNeedExclusiveLock)
|
||||
{
|
||||
/* Check if we need an exclusive lock */
|
||||
ASSERT(CellToRelease == HCELL_NIL);
|
||||
ASSERT(ValueData == NULL);
|
||||
|
||||
/* Try with exclusive KCB lock */
|
||||
CmpConvertKcbSharedToExclusive(Kcb);
|
||||
goto DoAgain;
|
||||
}
|
||||
|
||||
if (Result == SearchSuccess)
|
||||
{
|
||||
/* Sanity check */
|
||||
|
@ -562,6 +681,12 @@ CmQueryValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
Length,
|
||||
ResultLength,
|
||||
&Status);
|
||||
if (Result == SearchNeedExclusiveLock)
|
||||
{
|
||||
/* Try with exclusive KCB lock */
|
||||
CmpConvertKcbSharedToExclusive(Kcb);
|
||||
goto DoAgain;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -572,9 +697,9 @@ CmQueryValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
/* If we have a cell to release, do so */
|
||||
if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease);
|
||||
|
||||
/* Release hive lock */
|
||||
ExReleaseResourceLite(&CmpRegistryLock);
|
||||
KeLeaveCriticalRegion();
|
||||
/* Release locks */
|
||||
CmpReleaseKcbLock(Kcb);
|
||||
CmpUnlockRegistry();
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -599,8 +724,20 @@ CmEnumerateValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
PAGED_CODE();
|
||||
|
||||
/* Acquire hive lock */
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
|
||||
CmpLockRegistry();
|
||||
|
||||
/* Lock the KCB shared */
|
||||
CmpAcquireKcbLockShared(Kcb);
|
||||
|
||||
/* Don't touch deleted keys */
|
||||
DoAgain:
|
||||
if (Kcb->Delete)
|
||||
{
|
||||
/* Undo everything */
|
||||
CmpReleaseKcbLock(Kcb);
|
||||
CmpUnlockRegistry();
|
||||
return STATUS_KEY_DELETED;
|
||||
}
|
||||
|
||||
/* Get the hive and parent */
|
||||
Hive = Kcb->KeyHive;
|
||||
|
@ -621,13 +758,30 @@ CmEnumerateValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
Status = STATUS_NO_MORE_ENTRIES;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
/* We don't deal with this yet */
|
||||
if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)
|
||||
{
|
||||
/* Shouldn't happen */
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
/* Find the value list */
|
||||
Result = CmpGetValueListFromCache(Kcb,
|
||||
&CellData,
|
||||
&IndexIsCached,
|
||||
&CellToRelease);
|
||||
if (Result != SearchSuccess)
|
||||
if (Result == SearchNeedExclusiveLock)
|
||||
{
|
||||
/* Check if we need an exclusive lock */
|
||||
ASSERT(CellToRelease == HCELL_NIL);
|
||||
ASSERT(ValueData == NULL);
|
||||
|
||||
/* Try with exclusive KCB lock */
|
||||
CmpConvertKcbSharedToExclusive(Kcb);
|
||||
goto DoAgain;
|
||||
}
|
||||
else if (Result != SearchSuccess)
|
||||
{
|
||||
/* Sanity check */
|
||||
ASSERT(CellData == NULL);
|
||||
|
@ -646,10 +800,16 @@ CmEnumerateValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
IndexIsCached,
|
||||
&ValueIsCached,
|
||||
&CellToRelease2);
|
||||
if (Result != SearchSuccess)
|
||||
if (Result == SearchNeedExclusiveLock)
|
||||
{
|
||||
/* Try with exclusive KCB lock */
|
||||
CmpConvertKcbSharedToExclusive(Kcb);
|
||||
goto DoAgain;
|
||||
}
|
||||
else if (Result != SearchSuccess)
|
||||
{
|
||||
/* Sanity check */
|
||||
ASSERT(CellToRelease2 == HCELL_NIL);
|
||||
ASSERT(ValueData == NULL);
|
||||
|
||||
/* Release the cells and fail */
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
@ -666,6 +826,12 @@ CmEnumerateValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
Length,
|
||||
ResultLength,
|
||||
&Status);
|
||||
if (Result == SearchNeedExclusiveLock)
|
||||
{
|
||||
/* Try with exclusive KCB lock */
|
||||
CmpConvertKcbSharedToExclusive(Kcb);
|
||||
goto DoAgain;
|
||||
}
|
||||
|
||||
Quickie:
|
||||
/* If we have a cell to release, do so */
|
||||
|
@ -677,9 +843,9 @@ Quickie:
|
|||
/* If we have a cell to release, do so */
|
||||
if (CellToRelease2 != HCELL_NIL) HvReleaseCell(Hive, CellToRelease2);
|
||||
|
||||
/* Release hive lock */
|
||||
ExReleaseResourceLite(&CmpRegistryLock);
|
||||
KeLeaveCriticalRegion();
|
||||
/* Release locks */
|
||||
CmpReleaseKcbLock(Kcb);
|
||||
CmpUnlockRegistry();
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -911,8 +1077,10 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
PCM_KEY_NODE Parent;
|
||||
|
||||
/* Acquire hive lock */
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
|
||||
CmpLockRegistry();
|
||||
|
||||
/* Lock KCB shared */
|
||||
CmpAcquireKcbLockShared(Kcb);
|
||||
|
||||
/* Get the hive and parent */
|
||||
Hive = Kcb->KeyHive;
|
||||
|
@ -923,6 +1091,14 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
/* Don't touch deleted keys */
|
||||
if (Kcb->Delete)
|
||||
{
|
||||
/* Fail */
|
||||
Status = STATUS_KEY_DELETED;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
/* Check what class we got */
|
||||
switch (KeyInformationClass)
|
||||
|
@ -961,9 +1137,9 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
}
|
||||
|
||||
Quickie:
|
||||
/* Release hive lock */
|
||||
ExReleaseResourceLite(&CmpRegistryLock);
|
||||
KeLeaveCriticalRegion();
|
||||
/* Release locks */
|
||||
CmpReleaseKcbLock(Kcb);
|
||||
CmpUnlockRegistry();
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -982,8 +1158,19 @@ CmEnumerateKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
HCELL_INDEX ChildCell;
|
||||
|
||||
/* Acquire hive lock */
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
|
||||
CmpLockRegistry();
|
||||
|
||||
/* Lock the KCB shared */
|
||||
CmpAcquireKcbLockShared(Kcb);
|
||||
|
||||
/* Don't touch deleted keys */
|
||||
if (Kcb->Delete)
|
||||
{
|
||||
/* Undo everything */
|
||||
CmpReleaseKcbLock(Kcb);
|
||||
CmpUnlockRegistry();
|
||||
return STATUS_KEY_DELETED;
|
||||
}
|
||||
|
||||
/* Get the hive and parent */
|
||||
Hive = Kcb->KeyHive;
|
||||
|
@ -1027,9 +1214,9 @@ CmEnumerateKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
ResultLength);
|
||||
|
||||
Quickie:
|
||||
/* Release hive lock */
|
||||
ExReleaseResourceLite(&CmpRegistryLock);
|
||||
KeLeaveCriticalRegion();
|
||||
/* Release locks */
|
||||
CmpReleaseKcbLock(Kcb);
|
||||
CmpUnlockRegistry();
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -1041,11 +1228,32 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody)
|
|||
PHHIVE Hive;
|
||||
PCM_KEY_NODE Node, Parent;
|
||||
HCELL_INDEX Cell, ParentCell;
|
||||
PCM_KEY_CONTROL_BLOCK Kcb = KeyBody->KeyControlBlock;
|
||||
PCM_KEY_CONTROL_BLOCK Kcb;
|
||||
|
||||
/* Acquire hive lock */
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
|
||||
CmpLockRegistry();
|
||||
|
||||
/* Get the kcb */
|
||||
Kcb = KeyBody->KeyControlBlock;
|
||||
|
||||
/* Don't allow deleting the root */
|
||||
if (!Kcb->ParentKcb)
|
||||
{
|
||||
/* Fail */
|
||||
CmpUnlockRegistry();
|
||||
return STATUS_CANNOT_DELETE;
|
||||
}
|
||||
|
||||
/* Lock parent and child */
|
||||
CmpAcquireTwoKcbLocksExclusiveByKey(Kcb->ConvKey, Kcb->ParentKcb->ConvKey);
|
||||
|
||||
/* Check if we're already being deleted */
|
||||
if (Kcb->Delete)
|
||||
{
|
||||
/* Don't do it twice */
|
||||
Status = STATUS_SUCCESS;
|
||||
goto Quickie2;
|
||||
}
|
||||
|
||||
/* Get the hive and node */
|
||||
Hive = Kcb->KeyHive;
|
||||
|
@ -1059,34 +1267,22 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody)
|
|||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
/* Check if we have no parent */
|
||||
if (!Node->Parent)
|
||||
{
|
||||
/* This is an attempt to delete \Registry itself! */
|
||||
Status = STATUS_CANNOT_DELETE;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
/* Check if we're already being deleted */
|
||||
if (Kcb->Delete)
|
||||
{
|
||||
/* Don't do it twice */
|
||||
Status = STATUS_SUCCESS;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
|
||||
/* Sanity check */
|
||||
ASSERT(Node->Flags == Kcb->Flags);
|
||||
|
||||
/* Check if we don't have any children */
|
||||
if (!(Node->SubKeyCounts[Stable] + Node->SubKeyCounts[Volatile]))
|
||||
if (!(Node->SubKeyCounts[Stable] + Node->SubKeyCounts[Volatile]) &&
|
||||
!(Node->Flags & KEY_NO_DELETE))
|
||||
{
|
||||
/* Get the parent and free the cell */
|
||||
ParentCell = Node->Parent;
|
||||
Status = CmpFreeKeyByCell(Hive, Cell, TRUE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Clean up information we have on the subkey */
|
||||
CmpCleanUpSubKeyInfo(Kcb->ParentKcb);
|
||||
|
||||
/* Get the parent node */
|
||||
Parent = (PCM_KEY_NODE)HvGetCell(Hive, ParentCell);
|
||||
if (Parent)
|
||||
|
@ -1119,16 +1315,16 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody)
|
|||
Status = STATUS_CANNOT_DELETE;
|
||||
}
|
||||
|
||||
/* Flush the registry */
|
||||
CmpLazyFlush();
|
||||
|
||||
Quickie:
|
||||
/* Release the cell */
|
||||
HvReleaseCell(Hive, Cell);
|
||||
|
||||
/* Release the KCB locks */
|
||||
Quickie2:
|
||||
CmpReleaseTwoKcbLockByKey(Kcb->ConvKey, Kcb->ParentKcb->ConvKey);
|
||||
|
||||
/* Release hive lock */
|
||||
ExReleaseResourceLite(&CmpRegistryLock);
|
||||
KeLeaveCriticalRegion();
|
||||
CmpUnlockRegistry();
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -1140,6 +1336,9 @@ CmFlushKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
PCMHIVE CmHive;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PHHIVE Hive;
|
||||
|
||||
/* Ignore flushes until we're ready */
|
||||
if (CmpNoWrite) return STATUS_SUCCESS;
|
||||
|
||||
/* Get the hives */
|
||||
Hive = Kcb->KeyHive;
|
||||
|
@ -1239,7 +1438,7 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
|
|||
}
|
||||
|
||||
/* Lock the registry shared */
|
||||
//CmpLockRegistry();
|
||||
CmpLockRegistry();
|
||||
|
||||
/* Lock the hive to this thread */
|
||||
CmHive->Hive.HiveFlags |= HIVE_IS_UNLOADING;
|
||||
|
@ -1252,7 +1451,7 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
|
|||
Status = CmpLinkHiveToMaster(TargetKey->ObjectName,
|
||||
TargetKey->RootDirectory,
|
||||
CmHive,
|
||||
FALSE,
|
||||
Allocate,
|
||||
TargetKey->SecurityDescriptor);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -1276,7 +1475,7 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
|
|||
}
|
||||
|
||||
/* Unlock the registry */
|
||||
//CmpUnlockRegistry();
|
||||
CmpUnlockRegistry();
|
||||
|
||||
/* Close handle and return */
|
||||
if (KeyHandle) ZwClose(KeyHandle);
|
||||
|
|
Loading…
Reference in a new issue