From 8d73b772516d14ae54956203b12c628e5e8fb5da Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Tue, 7 Jan 2014 23:51:56 +0000 Subject: [PATCH] [NTOSKRNL] - Update CM_KEY_CONTROL_BLOCK to match win2k3 SP2 symbols - Implement KeyCachedInformation and KeyFlagsInformation cases in CmQueryKey svn path=/trunk/; revision=61572 --- reactos/ntoskrnl/config/cmapi.c | 328 +++++++++++++++++++------ reactos/ntoskrnl/include/internal/cm.h | 12 +- 2 files changed, 258 insertions(+), 82 deletions(-) diff --git a/reactos/ntoskrnl/config/cmapi.c b/reactos/ntoskrnl/config/cmapi.c index a2742065a98..47436fae81d 100644 --- a/reactos/ntoskrnl/config/cmapi.c +++ b/reactos/ntoskrnl/config/cmapi.c @@ -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; diff --git a/reactos/ntoskrnl/include/internal/cm.h b/reactos/ntoskrnl/include/internal/cm.h index ad13a95b072..d34f5b32bb2 100644 --- a/reactos/ntoskrnl/include/internal/cm.h +++ b/reactos/ntoskrnl/include/internal/cm.h @@ -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;