mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +00:00
[NTOSKRNL]
- Update CM_KEY_CONTROL_BLOCK to match win2k3 SP2 symbols - Implement KeyCachedInformation and KeyFlagsInformation cases in CmQueryKey svn path=/trunk/; revision=61572
This commit is contained in:
parent
e5813955cb
commit
8d73b77251
2 changed files with 258 additions and 82 deletions
|
@ -61,7 +61,7 @@ CmpIsHiveAlreadyLoaded(IN HANDLE KeyHandle,
|
|||
/* Same file found */
|
||||
Loaded = TRUE;
|
||||
*CmHive = Hive;
|
||||
|
||||
|
||||
/* If the hive is frozen, not sure what to do */
|
||||
if (Hive->Frozen)
|
||||
{
|
||||
|
@ -102,7 +102,7 @@ CmpDoFlushAll(IN BOOLEAN ForceFlush)
|
|||
{
|
||||
/* Acquire the flusher lock */
|
||||
CmpLockHiveFlusherExclusive(Hive);
|
||||
|
||||
|
||||
/* Check for illegal state */
|
||||
if ((ForceFlush) && (Hive->UseCount))
|
||||
{
|
||||
|
@ -111,7 +111,7 @@ CmpDoFlushAll(IN BOOLEAN ForceFlush)
|
|||
DPRINT1("FIXME: Hive is damaged and needs fixup\n");
|
||||
while (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/* Only sync if we are forced to or if it won't cause a hive shrink */
|
||||
if ((ForceFlush) || (!HvHiveWillShrink(&Hive->Hive)))
|
||||
{
|
||||
|
@ -242,7 +242,7 @@ CmpSetValueKeyNew(IN PHHIVE Hive,
|
|||
CellData->u.KeyValue.DataLength = DataSize + CM_KEY_VALUE_SPECIAL_SIZE;
|
||||
CellData->u.KeyValue.Data = SmallData;
|
||||
}
|
||||
|
||||
|
||||
/* Set the type now */
|
||||
CellData->u.KeyValue.Type = Type;
|
||||
|
||||
|
@ -280,7 +280,7 @@ CmpSetValueKeyExisting(IN PHHIVE Hive,
|
|||
PCELL_DATA CellData;
|
||||
ULONG Length;
|
||||
BOOLEAN WasSmall, IsSmall;
|
||||
|
||||
|
||||
/* Registry writes must be blocked */
|
||||
CMP_ASSERT_FLUSH_LOCK(Hive);
|
||||
|
||||
|
@ -316,7 +316,7 @@ CmpSetValueKeyExisting(IN PHHIVE Hive,
|
|||
Value->Type = Type;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* We have a normal key. Was the old cell also normal and had data? */
|
||||
if (!(WasSmall) && (Length > 0))
|
||||
{
|
||||
|
@ -607,10 +607,10 @@ CmSetValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
/* Acquire hive and KCB lock */
|
||||
CmpLockRegistry();
|
||||
CmpAcquireKcbLockShared(Kcb);
|
||||
|
||||
|
||||
/* Sanity check */
|
||||
ASSERT(sizeof(ULONG) == CM_KEY_VALUE_SMALL);
|
||||
|
||||
|
||||
/* Don't touch deleted KCBs */
|
||||
DoAgain:
|
||||
if (Kcb->Delete)
|
||||
|
@ -619,7 +619,7 @@ DoAgain:
|
|||
Status = STATUS_KEY_DELETED;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
|
||||
/* Don't let anyone mess with symlinks */
|
||||
if ((Kcb->Flags & KEY_SYM_LINK) &&
|
||||
((Type != REG_LINK) ||
|
||||
|
@ -660,10 +660,10 @@ DoAgain:
|
|||
/* Acquire exclusive lock */
|
||||
CmpConvertKcbSharedToExclusive(Kcb);
|
||||
}
|
||||
|
||||
|
||||
/* Cache lookup failed, so don't try it next time */
|
||||
FirstTry = FALSE;
|
||||
|
||||
|
||||
/* Now grab the flush lock since the key will be modified */
|
||||
ASSERT(FlusherLocked == FALSE);
|
||||
CmpLockHiveFlusherShared((PCMHIVE)Kcb->KeyHive);
|
||||
|
@ -680,7 +680,7 @@ DoAgain:
|
|||
Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
|
||||
ASSERT(Parent);
|
||||
ParentCell = Cell;
|
||||
|
||||
|
||||
/* Prepare to scan the key node */
|
||||
Count = Parent->ValueList.Count;
|
||||
Found = FALSE;
|
||||
|
@ -708,7 +708,7 @@ DoAgain:
|
|||
HvReleaseCell(Hive, ChildCell);
|
||||
ChildCell = HCELL_NIL;
|
||||
}
|
||||
|
||||
|
||||
/* Get its value */
|
||||
Value = (PCM_KEY_VALUE)HvGetCell(Hive, CurrentChild);
|
||||
if (!Value)
|
||||
|
@ -729,13 +729,13 @@ DoAgain:
|
|||
ChildIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Should only get here on the second pass */
|
||||
ASSERT(FirstTry == FALSE);
|
||||
|
||||
|
||||
/* The KCB must be locked exclusive at this point */
|
||||
CMP_ASSERT_KCB_LOCK(Kcb);
|
||||
|
||||
|
||||
/* Mark the cell dirty */
|
||||
if (!HvMarkCellDirty(Hive, Cell, FALSE))
|
||||
{
|
||||
|
@ -804,7 +804,7 @@ DoAgain:
|
|||
Parent->MaxValueNameLen = ValueName->Length;
|
||||
Kcb->KcbMaxValueNameLen = ValueName->Length;
|
||||
}
|
||||
|
||||
|
||||
/* Check if the maximum data length changed */
|
||||
ASSERT(Parent->MaxValueDataLen == Kcb->KcbMaxValueDataLen);
|
||||
if (Parent->MaxValueDataLen < DataLength)
|
||||
|
@ -813,11 +813,11 @@ DoAgain:
|
|||
Parent->MaxValueDataLen = DataLength;
|
||||
Kcb->KcbMaxValueDataLen = Parent->MaxValueDataLen;
|
||||
}
|
||||
|
||||
|
||||
/* Save the write time */
|
||||
KeQuerySystemTime(&Parent->LastWriteTime);
|
||||
Kcb->KcbLastWriteTime = Parent->LastWriteTime;
|
||||
|
||||
|
||||
/* Check if the cell is cached */
|
||||
if ((Found) && (CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList)))
|
||||
{
|
||||
|
@ -832,19 +832,19 @@ DoAgain:
|
|||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
/* Notify registered callbacks */
|
||||
CmpReportNotify(Kcb,
|
||||
Hive,
|
||||
Kcb->KeyCell,
|
||||
REG_NOTIFY_CHANGE_LAST_SET);
|
||||
}
|
||||
|
||||
|
||||
/* Release the cells */
|
||||
Quickie:
|
||||
if ((ParentCell != HCELL_NIL) && (Hive)) HvReleaseCell(Hive, ParentCell);
|
||||
|
@ -873,10 +873,10 @@ CmDeleteValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
|
||||
/* Acquire hive lock */
|
||||
CmpLockRegistry();
|
||||
|
||||
|
||||
/* Lock KCB exclusively */
|
||||
CmpAcquireKcbLockExclusive(Kcb);
|
||||
|
||||
|
||||
/* Don't touch deleted keys */
|
||||
if (Kcb->Delete)
|
||||
{
|
||||
|
@ -889,7 +889,7 @@ CmDeleteValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
/* Get the hive and the cell index */
|
||||
Hive = Kcb->KeyHive;
|
||||
Cell = Kcb->KeyCell;
|
||||
|
||||
|
||||
/* Lock flushes */
|
||||
CmpLockHiveFlusherShared((PCMHIVE)Hive);
|
||||
|
||||
|
@ -978,18 +978,18 @@ 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;
|
||||
|
||||
|
||||
/* Notify registered callbacks */
|
||||
CmpReportNotify(Kcb, Hive, Cell, REG_NOTIFY_CHANGE_LAST_SET);
|
||||
|
||||
|
@ -1037,10 +1037,10 @@ CmQueryValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
|
||||
/* Acquire hive lock */
|
||||
CmpLockRegistry();
|
||||
|
||||
|
||||
/* Lock the KCB shared */
|
||||
CmpAcquireKcbLockShared(Kcb);
|
||||
|
||||
|
||||
/* Don't touch deleted keys */
|
||||
DoAgain:
|
||||
if (Kcb->Delete)
|
||||
|
@ -1050,7 +1050,7 @@ DoAgain:
|
|||
CmpUnlockRegistry();
|
||||
return STATUS_KEY_DELETED;
|
||||
}
|
||||
|
||||
|
||||
/* We don't deal with this yet */
|
||||
if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)
|
||||
{
|
||||
|
@ -1074,12 +1074,12 @@ DoAgain:
|
|||
/* 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 */
|
||||
|
@ -1106,7 +1106,7 @@ DoAgain:
|
|||
HvReleaseCell(Hive, CellToRelease);
|
||||
CellToRelease = HCELL_NIL;
|
||||
}
|
||||
|
||||
|
||||
/* Try with exclusive KCB lock */
|
||||
CmpConvertKcbSharedToExclusive(Kcb);
|
||||
_SEH2_YIELD(goto DoAgain);
|
||||
|
@ -1155,7 +1155,7 @@ CmEnumerateValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
|
||||
/* Acquire hive lock */
|
||||
CmpLockRegistry();
|
||||
|
||||
|
||||
/* Lock the KCB shared */
|
||||
CmpAcquireKcbLockShared(Kcb);
|
||||
|
||||
|
@ -1189,7 +1189,7 @@ DoAgain:
|
|||
Status = STATUS_NO_MORE_ENTRIES;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
|
||||
/* We don't deal with this yet */
|
||||
if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)
|
||||
{
|
||||
|
@ -1207,7 +1207,7 @@ DoAgain:
|
|||
/* Check if we need an exclusive lock */
|
||||
ASSERT(CellToRelease == HCELL_NIL);
|
||||
HvReleaseCell(Hive, Kcb->KeyCell);
|
||||
|
||||
|
||||
/* Try with exclusive KCB lock */
|
||||
CmpConvertKcbSharedToExclusive(Kcb);
|
||||
goto DoAgain;
|
||||
|
@ -1255,7 +1255,7 @@ DoAgain:
|
|||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
|
||||
/* User data, need SEH */
|
||||
_SEH2_TRY
|
||||
{
|
||||
|
@ -1304,6 +1304,162 @@ Quickie:
|
|||
return Status;
|
||||
}
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
CmpQueryKeyDataFromCache(
|
||||
_In_ PCM_KEY_CONTROL_BLOCK Kcb,
|
||||
_Out_ PKEY_CACHED_INFORMATION KeyCachedInfo,
|
||||
_In_ ULONG Length,
|
||||
_Out_ PULONG ResultLength)
|
||||
{
|
||||
PCM_KEY_NODE Node;
|
||||
ULONG SubKeyCount;
|
||||
PHHIVE KeyHive;
|
||||
HCELL_INDEX KeyCell;
|
||||
USHORT NameLength;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Get the hive and cell index */
|
||||
KeyHive = Kcb->KeyHash.KeyHive;
|
||||
KeyCell = Kcb->KeyHash.KeyCell;
|
||||
|
||||
#if DBG
|
||||
/* Get the cell node */
|
||||
Node = HvGetCell(KeyHive, KeyCell);
|
||||
if (Node != NULL)
|
||||
{
|
||||
ASSERT(Node->ValueList.Count == Kcb->ValueCache.Count);
|
||||
|
||||
if (!(Kcb->ExtFlags & CM_KCB_INVALID_CACHED_INFO))
|
||||
{
|
||||
SubKeyCount = Node->SubKeyCounts[0] + Node->SubKeyCounts[1];
|
||||
if (Kcb->ExtFlags & CM_KCB_NO_SUBKEY)
|
||||
{
|
||||
ASSERT(SubKeyCount == 0);
|
||||
}
|
||||
else if (Kcb->ExtFlags & CM_KCB_SUBKEY_ONE)
|
||||
{
|
||||
ASSERT(SubKeyCount == 1);
|
||||
}
|
||||
else if (Kcb->ExtFlags & CM_KCB_SUBKEY_HINT)
|
||||
{
|
||||
ASSERT(SubKeyCount == Kcb->IndexHint->Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(SubKeyCount == Kcb->SubKeyCount);
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(Node->LastWriteTime.QuadPart == Kcb->KcbLastWriteTime.QuadPart);
|
||||
ASSERT(Node->MaxNameLen == Kcb->KcbMaxNameLen);
|
||||
ASSERT(Node->MaxValueNameLen == Kcb->KcbMaxValueNameLen);
|
||||
ASSERT(Node->MaxValueDataLen == Kcb->KcbMaxValueDataLen);
|
||||
|
||||
/* Release the cell */
|
||||
HvReleaseCell(KeyHive, KeyCell);
|
||||
}
|
||||
#endif // DBG
|
||||
|
||||
/* Make sure we have a name block */
|
||||
if (Kcb->NameBlock == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Check for compressed name */
|
||||
if (Kcb->NameBlock->Compressed)
|
||||
{
|
||||
/* Calculate the name size */
|
||||
NameLength = CmpCompressedNameSize(Kcb->NameBlock->NameHash.Name,
|
||||
Kcb->NameBlock->NameHash.NameLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use the stored name size */
|
||||
NameLength = Kcb->NameBlock->NameHash.NameLength;
|
||||
}
|
||||
|
||||
/* Validate buffer length (we do not copy the name!) */
|
||||
*ResultLength = sizeof(KeyCachedInfo);
|
||||
if (Length < *ResultLength)
|
||||
{
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Fill the structure */
|
||||
KeyCachedInfo->LastWriteTime = Kcb->KcbLastWriteTime;
|
||||
KeyCachedInfo->TitleIndex = 0;
|
||||
KeyCachedInfo->NameLength = NameLength;
|
||||
KeyCachedInfo->Values = Kcb->ValueCache.Count;
|
||||
KeyCachedInfo->MaxNameLen = Kcb->KcbMaxNameLen;
|
||||
KeyCachedInfo->MaxValueNameLen = Kcb->KcbMaxValueNameLen;
|
||||
KeyCachedInfo->MaxValueDataLen = Kcb->KcbMaxValueDataLen;
|
||||
|
||||
/* Check the ExtFlags for what we have */
|
||||
if (Kcb->ExtFlags & CM_KCB_INVALID_CACHED_INFO)
|
||||
{
|
||||
/* Cache is not valid, do a full lookup */
|
||||
DPRINT1("Kcb cache incoherency detected, kcb = %p\n", Kcb);
|
||||
|
||||
/* Get the cell node */
|
||||
Node = HvGetCell(KeyHive, KeyCell);
|
||||
if (Node == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Calculate number of subkeys */
|
||||
KeyCachedInfo->SubKeys = Node->SubKeyCounts[0] + Node->SubKeyCounts[1];
|
||||
|
||||
/* Release the cell */
|
||||
HvReleaseCell(KeyHive, KeyCell);
|
||||
}
|
||||
else if (Kcb->ExtFlags & CM_KCB_NO_SUBKEY)
|
||||
{
|
||||
/* There are no subkeys */
|
||||
KeyCachedInfo->SubKeys = 0;
|
||||
}
|
||||
else if (Kcb->ExtFlags & CM_KCB_SUBKEY_ONE)
|
||||
{
|
||||
/* There is exactly one subley */
|
||||
KeyCachedInfo->SubKeys = 1;
|
||||
}
|
||||
else if (Kcb->ExtFlags & CM_KCB_SUBKEY_HINT)
|
||||
{
|
||||
/* Get the number of subkeys from the subkey hint */
|
||||
KeyCachedInfo->SubKeys = Kcb->IndexHint->Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No subkey hint, use the key count field */
|
||||
KeyCachedInfo->SubKeys = Kcb->SubKeyCount;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
CmpQueryFlagsInformation(
|
||||
_In_ PCM_KEY_CONTROL_BLOCK Kcb,
|
||||
_Out_ PKEY_USER_FLAGS_INFORMATION KeyFlagsInfo,
|
||||
_In_ ULONG Length,
|
||||
_In_ PULONG ResultLength)
|
||||
{
|
||||
/* Validate the buffer size */
|
||||
*ResultLength = sizeof(*KeyFlagsInfo);
|
||||
if (Length < *ResultLength)
|
||||
{
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Copy the user flags */
|
||||
KeyFlagsInfo->UserFlags = Kcb->KcbUserFlags;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
||||
|
@ -1319,7 +1475,7 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
|
||||
/* Acquire hive lock */
|
||||
CmpLockRegistry();
|
||||
|
||||
|
||||
/* Lock KCB shared */
|
||||
CmpAcquireKcbLockShared(Kcb);
|
||||
|
||||
|
@ -1343,7 +1499,7 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
Hive = Kcb->KeyHive;
|
||||
Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell);
|
||||
ASSERT(Parent);
|
||||
|
||||
|
||||
/* Track cell references */
|
||||
if (!HvTrackCellRef(&CellReferences, Hive, Kcb->KeyCell))
|
||||
{
|
||||
|
@ -1362,10 +1518,24 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
}
|
||||
break;
|
||||
|
||||
/* Unsupported classes for now */
|
||||
case KeyNameInformation:
|
||||
case KeyCachedInformation:
|
||||
/* Call the internal API */
|
||||
Status = CmpQueryKeyDataFromCache(Kcb,
|
||||
KeyInformation,
|
||||
Length,
|
||||
ResultLength);
|
||||
break;
|
||||
|
||||
case KeyFlagsInformation:
|
||||
/* Call the internal API */
|
||||
Status = CmpQueryFlagsInformation(Kcb,
|
||||
KeyInformation,
|
||||
Length,
|
||||
ResultLength);
|
||||
break;
|
||||
|
||||
/* Unsupported class for now */
|
||||
case KeyNameInformation:
|
||||
|
||||
/* Print message and fail */
|
||||
DPRINT1("Unsupported class: %d!\n", KeyInformationClass);
|
||||
|
@ -1408,10 +1578,10 @@ CmEnumerateKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
|
||||
/* Acquire hive lock */
|
||||
CmpLockRegistry();
|
||||
|
||||
|
||||
/* Lock the KCB shared */
|
||||
CmpAcquireKcbLockShared(Kcb);
|
||||
|
||||
|
||||
/* Don't touch deleted keys */
|
||||
if (Kcb->Delete)
|
||||
{
|
||||
|
@ -1442,7 +1612,7 @@ CmEnumerateKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
/* Now get the actual child node */
|
||||
Child = (PCM_KEY_NODE)HvGetCell(Hive, ChildCell);
|
||||
ASSERT(Child);
|
||||
|
||||
|
||||
/* Track references */
|
||||
if (!HvTrackCellRef(&CellReferences, Hive, ChildCell))
|
||||
{
|
||||
|
@ -1492,10 +1662,10 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody)
|
|||
|
||||
/* Acquire hive lock */
|
||||
CmpLockRegistry();
|
||||
|
||||
|
||||
/* Get the kcb */
|
||||
Kcb = KeyBody->KeyControlBlock;
|
||||
|
||||
|
||||
/* Don't allow deleting the root */
|
||||
if (!Kcb->ParentKcb)
|
||||
{
|
||||
|
@ -1503,10 +1673,10 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody)
|
|||
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)
|
||||
{
|
||||
|
@ -1518,14 +1688,14 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody)
|
|||
/* Get the hive and node */
|
||||
Hive = Kcb->KeyHive;
|
||||
Cell = Kcb->KeyCell;
|
||||
|
||||
|
||||
/* Lock flushes */
|
||||
CmpLockHiveFlusherShared((PCMHIVE)Hive);
|
||||
|
||||
|
||||
/* Get the key node */
|
||||
Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
|
||||
ASSERT(Node);
|
||||
|
||||
|
||||
/* Sanity check */
|
||||
ASSERT(Node->Flags == Kcb->Flags);
|
||||
|
||||
|
@ -1535,7 +1705,7 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody)
|
|||
{
|
||||
/* Send notification to registered callbacks */
|
||||
CmpReportNotify(Kcb, Hive, Cell, REG_NOTIFY_CHANGE_NAME);
|
||||
|
||||
|
||||
/* Get the parent and free the cell */
|
||||
ParentCell = Node->Parent;
|
||||
Status = CmpFreeKeyByCell(Hive, Cell, TRUE);
|
||||
|
@ -1543,7 +1713,7 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody)
|
|||
{
|
||||
/* Flush any notifications */
|
||||
CmpFlushNotifiesOnKeyBodyList(Kcb, FALSE);
|
||||
|
||||
|
||||
/* Clean up information we have on the subkey */
|
||||
CmpCleanUpSubKeyInfo(Kcb->ParentKcb);
|
||||
|
||||
|
@ -1553,7 +1723,7 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody)
|
|||
{
|
||||
/* Update the maximum name length */
|
||||
Kcb->ParentKcb->KcbMaxNameLen = (USHORT)Parent->MaxNameLen;
|
||||
|
||||
|
||||
/* Make sure we're dirty */
|
||||
ASSERT(HvIsCellDirty(Hive, ParentCell));
|
||||
|
||||
|
@ -1564,7 +1734,7 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody)
|
|||
/* Release the cell */
|
||||
HvReleaseCell(Hive, ParentCell);
|
||||
}
|
||||
|
||||
|
||||
/* Set the KCB in delete mode and remove it */
|
||||
Kcb->Delete = TRUE;
|
||||
CmpRemoveKeyControlBlock(Kcb);
|
||||
|
@ -1578,7 +1748,7 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody)
|
|||
/* Fail */
|
||||
Status = STATUS_CANNOT_DELETE;
|
||||
}
|
||||
|
||||
|
||||
/* Release the cell */
|
||||
HvReleaseCell(Hive, Cell);
|
||||
|
||||
|
@ -1605,11 +1775,11 @@ CmFlushKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
|
||||
/* Ignore flushes until we're ready */
|
||||
if (CmpNoWrite) return STATUS_SUCCESS;
|
||||
|
||||
|
||||
/* Get the hives */
|
||||
Hive = Kcb->KeyHive;
|
||||
CmHive = (PCMHIVE)Hive;
|
||||
|
||||
|
||||
/* Check if this is the master hive */
|
||||
if (CmHive == CmiVolatileHive)
|
||||
{
|
||||
|
@ -1623,7 +1793,7 @@ CmFlushKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
ASSERT(CmHive->ViewLock);
|
||||
KeAcquireGuardedMutex(CmHive->ViewLock);
|
||||
CmHive->ViewLockOwner = KeGetCurrentThread();
|
||||
|
||||
|
||||
/* Will the hive shrink? */
|
||||
if (HvHiveWillShrink(Hive))
|
||||
{
|
||||
|
@ -1638,14 +1808,14 @@ CmFlushKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
ASSERT(KeGetCurrentThread() == CmHive->ViewLockOwner);
|
||||
KeReleaseGuardedMutex(CmHive->ViewLock);
|
||||
}
|
||||
|
||||
|
||||
/* Flush only this hive */
|
||||
if (!HvSyncHive(Hive))
|
||||
{
|
||||
/* Fail */
|
||||
Status = STATUS_REGISTRY_IO_FAILED;
|
||||
}
|
||||
|
||||
|
||||
/* Release the flush lock */
|
||||
CmpUnlockHiveFlusher((PCMHIVE)Hive);
|
||||
}
|
||||
|
@ -1668,7 +1838,7 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
|
|||
PCMHIVE CmHive, LoadedHive;
|
||||
NTSTATUS Status;
|
||||
CM_PARSE_CONTEXT ParseContext;
|
||||
|
||||
|
||||
/* Check if we have a trust key */
|
||||
if (KeyBody)
|
||||
{
|
||||
|
@ -1676,7 +1846,7 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
|
|||
DPRINT1("Trusted classes not yet supported\n");
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/* Build a service QoS for a security context */
|
||||
ServiceQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
|
||||
ServiceQos.ImpersonationLevel = SecurityImpersonation;
|
||||
|
@ -1692,7 +1862,7 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
|
|||
DPRINT1("Security context failed\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/* Open the target key */
|
||||
#if 0
|
||||
Status = ZwOpenKey(&KeyHandle, KEY_READ, TargetKey);
|
||||
|
@ -1727,7 +1897,7 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
|
|||
{
|
||||
/* Lock the registry */
|
||||
CmpLockRegistryExclusive();
|
||||
|
||||
|
||||
/* Check if we are already loaded */
|
||||
if (CmpIsHiveAlreadyLoaded(KeyHandle, SourceFile, &LoadedHive))
|
||||
{
|
||||
|
@ -1739,25 +1909,25 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
|
|||
/* Release the registry */
|
||||
CmpUnlockRegistry();
|
||||
}
|
||||
|
||||
|
||||
/* Close the key handle if we had one */
|
||||
if (KeyHandle) ZwClose(KeyHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/* Lock the registry shared */
|
||||
CmpLockRegistry();
|
||||
|
||||
|
||||
/* Lock loading */
|
||||
ExAcquirePushLockExclusive(&CmpLoadHiveLock);
|
||||
|
||||
|
||||
/* Lock the hive to this thread */
|
||||
CmHive->Hive.HiveFlags |= HIVE_IS_UNLOADING;
|
||||
CmHive->CreatorOwner = KeGetCurrentThread();
|
||||
|
||||
|
||||
/* Set flag */
|
||||
if (Flags & REG_NO_LAZY_FLUSH) CmHive->Hive.HiveFlags |= HIVE_NOLAZYFLUSH;
|
||||
|
||||
|
||||
/* Link the hive */
|
||||
Status = CmpLinkHiveToMaster(TargetKey->ObjectName,
|
||||
TargetKey->RootDirectory,
|
||||
|
@ -1768,7 +1938,7 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
|
|||
{
|
||||
/* Add to HiveList key */
|
||||
CmpAddToHiveFileList(CmHive);
|
||||
|
||||
|
||||
/* Sync the hive if necessary */
|
||||
if (Allocate)
|
||||
{
|
||||
|
@ -1777,11 +1947,11 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
|
|||
HvSyncHive(&CmHive->Hive);
|
||||
CmpUnlockHiveFlusher(CmHive);
|
||||
}
|
||||
|
||||
|
||||
/* Release the hive */
|
||||
CmHive->Hive.HiveFlags &= ~HIVE_IS_UNLOADING;
|
||||
CmHive->CreatorOwner = NULL;
|
||||
|
||||
|
||||
/* Allow loads */
|
||||
ExReleasePushLock(&CmpLoadHiveLock);
|
||||
}
|
||||
|
@ -1791,7 +1961,7 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
|
|||
/* FIXME: TODO */
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/* Is this first profile load? */
|
||||
if (!(CmpProfileLoaded) && !(CmpWasSetupBoot))
|
||||
{
|
||||
|
@ -1799,10 +1969,10 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
|
|||
CmpProfileLoaded = TRUE;
|
||||
CmpSetGlobalQuotaAllowed();
|
||||
}
|
||||
|
||||
|
||||
/* Unlock the registry */
|
||||
CmpUnlockRegistry();
|
||||
|
||||
|
||||
/* Close handle and return */
|
||||
if (KeyHandle) ZwClose(KeyHandle);
|
||||
return Status;
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
#define CM_KCB_INVALID_SIGNATURE '4FmC'
|
||||
|
||||
//
|
||||
// CM_KEY_CONTROL_BLOCK Flags
|
||||
// CM_KEY_CONTROL_BLOCK ExtFlags
|
||||
//
|
||||
#define CM_KCB_NO_SUBKEY 0x01
|
||||
#define CM_KCB_SUBKEY_ONE 0x02
|
||||
|
@ -253,8 +253,7 @@ typedef struct _CM_NAME_CONTROL_BLOCK
|
|||
typedef struct _CM_KEY_CONTROL_BLOCK
|
||||
{
|
||||
ULONG Signature;
|
||||
USHORT RefCount;
|
||||
USHORT Flags;
|
||||
ULONG RefCount;
|
||||
struct
|
||||
{
|
||||
ULONG ExtFlags:8;
|
||||
|
@ -295,6 +294,13 @@ typedef struct _CM_KEY_CONTROL_BLOCK
|
|||
USHORT KcbMaxNameLen;
|
||||
USHORT KcbMaxValueNameLen;
|
||||
ULONG KcbMaxValueDataLen;
|
||||
struct
|
||||
{
|
||||
ULONG KcbUserFlags : 4;
|
||||
ULONG KcbVirtControlFlags : 4;
|
||||
ULONG KcbDebug : 8;
|
||||
ULONG Flags : 16;
|
||||
};
|
||||
ULONG InDelayClose;
|
||||
} CM_KEY_CONTROL_BLOCK, *PCM_KEY_CONTROL_BLOCK;
|
||||
|
||||
|
|
Loading…
Reference in a new issue