1 /* 2 * PROJECT: Registry manipulation library 3 * LICENSE: GPL - See COPYING in the top level directory 4 * COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org> 5 * Copyright 2001 - 2005 Eric Kohl 6 */ 7 8 #include "cmlib.h" 9 #define NDEBUG 10 #include <debug.h> 11 12 ULONG CmlibTraceLevel = 0; 13 14 // FIXME: This function must be replaced by CmpCreateRootNode from ntoskrnl/config/cmsysini.c 15 // (and CmpCreateRootNode be moved there). 16 BOOLEAN CMAPI 17 CmCreateRootNode( 18 PHHIVE Hive, 19 PCWSTR Name) 20 { 21 UNICODE_STRING KeyName; 22 PCM_KEY_NODE KeyCell; 23 HCELL_INDEX RootCellIndex; 24 25 /* Initialize the node name and allocate it */ 26 RtlInitUnicodeString(&KeyName, Name); 27 RootCellIndex = HvAllocateCell(Hive, 28 FIELD_OFFSET(CM_KEY_NODE, Name) + 29 CmpNameSize(Hive, &KeyName), 30 Stable, 31 HCELL_NIL); 32 if (RootCellIndex == HCELL_NIL) return FALSE; 33 34 /* Seutp the base block */ 35 Hive->BaseBlock->RootCell = RootCellIndex; 36 Hive->BaseBlock->CheckSum = HvpHiveHeaderChecksum(Hive->BaseBlock); 37 38 /* Get the key cell */ 39 KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, RootCellIndex); 40 if (!KeyCell) 41 { 42 HvFreeCell(Hive, RootCellIndex); 43 return FALSE; 44 } 45 46 /* Setup the cell */ 47 KeyCell->Signature = CM_KEY_NODE_SIGNATURE; 48 KeyCell->Flags = KEY_HIVE_ENTRY | KEY_NO_DELETE; 49 // KeQuerySystemTime(&KeyCell->LastWriteTime); 50 KeyCell->LastWriteTime.QuadPart = 0ULL; 51 KeyCell->Parent = HCELL_NIL; 52 KeyCell->SubKeyCounts[Stable] = 0; 53 KeyCell->SubKeyCounts[Volatile] = 0; 54 KeyCell->SubKeyLists[Stable] = HCELL_NIL; 55 KeyCell->SubKeyLists[Volatile] = HCELL_NIL; 56 KeyCell->ValueList.Count = 0; 57 KeyCell->ValueList.List = HCELL_NIL; 58 KeyCell->Security = HCELL_NIL; 59 KeyCell->Class = HCELL_NIL; 60 KeyCell->ClassLength = 0; 61 KeyCell->MaxNameLen = 0; 62 KeyCell->MaxClassLen = 0; 63 KeyCell->MaxValueNameLen = 0; 64 KeyCell->MaxValueDataLen = 0; 65 KeyCell->NameLength = CmpCopyName(Hive, KeyCell->Name, &KeyName); 66 if (KeyCell->NameLength < KeyName.Length) KeyCell->Flags |= KEY_COMP_NAME; 67 68 /* Return success */ 69 HvReleaseCell(Hive, RootCellIndex); 70 return TRUE; 71 } 72 73 static VOID CMAPI 74 CmpPrepareKey( 75 PHHIVE RegistryHive, 76 PCM_KEY_NODE KeyCell); 77 78 static VOID CMAPI 79 CmpPrepareIndexOfKeys( 80 PHHIVE RegistryHive, 81 PCM_KEY_INDEX IndexCell) 82 { 83 ULONG i; 84 85 if (IndexCell->Signature == CM_KEY_INDEX_ROOT || 86 IndexCell->Signature == CM_KEY_INDEX_LEAF) 87 { 88 for (i = 0; i < IndexCell->Count; i++) 89 { 90 PCM_KEY_INDEX SubIndexCell = HvGetCell(RegistryHive, IndexCell->List[i]); 91 if (SubIndexCell->Signature == CM_KEY_NODE_SIGNATURE) 92 CmpPrepareKey(RegistryHive, (PCM_KEY_NODE)SubIndexCell); 93 else 94 CmpPrepareIndexOfKeys(RegistryHive, SubIndexCell); 95 } 96 } 97 else if (IndexCell->Signature == CM_KEY_FAST_LEAF || 98 IndexCell->Signature == CM_KEY_HASH_LEAF) 99 { 100 PCM_KEY_FAST_INDEX HashCell = (PCM_KEY_FAST_INDEX)IndexCell; 101 for (i = 0; i < HashCell->Count; i++) 102 { 103 PCM_KEY_NODE SubKeyCell = HvGetCell(RegistryHive, HashCell->List[i].Cell); 104 CmpPrepareKey(RegistryHive, SubKeyCell); 105 } 106 } 107 else 108 { 109 DPRINT1("IndexCell->Signature %x\n", IndexCell->Signature); 110 ASSERT(FALSE); 111 } 112 } 113 114 static VOID CMAPI 115 CmpPrepareKey( 116 PHHIVE RegistryHive, 117 PCM_KEY_NODE KeyCell) 118 { 119 PCM_KEY_INDEX IndexCell; 120 121 ASSERT(KeyCell->Signature == CM_KEY_NODE_SIGNATURE); 122 123 KeyCell->SubKeyCounts[Volatile] = 0; 124 // KeyCell->SubKeyLists[Volatile] = HCELL_NIL; // FIXME! Done only on Windows < XP. 125 126 /* Enumerate and add subkeys */ 127 if (KeyCell->SubKeyCounts[Stable] > 0) 128 { 129 IndexCell = HvGetCell(RegistryHive, KeyCell->SubKeyLists[Stable]); 130 CmpPrepareIndexOfKeys(RegistryHive, IndexCell); 131 } 132 } 133 134 VOID CMAPI 135 CmPrepareHive( 136 PHHIVE RegistryHive) 137 { 138 PCM_KEY_NODE RootCell; 139 140 RootCell = HvGetCell(RegistryHive, RegistryHive->BaseBlock->RootCell); 141 CmpPrepareKey(RegistryHive, RootCell); 142 } 143