[NTOSKRNL]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Tue, 7 Jan 2014 23:51:56 +0000 (23:51 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Tue, 7 Jan 2014 23:51:56 +0000 (23:51 +0000)
- 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
reactos/ntoskrnl/include/internal/cm.h

index a274206..47436fa 100644 (file)
@@ -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;
index ad13a95..d34f5b3 100644 (file)
@@ -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;