Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

cmindex.c File Reference

#include "cmp.h"

Go to the source code of this file.

Functions

ULONG CmpFindSubKeyInRoot (PHHIVE Hive, PCM_KEY_INDEX Index, PUNICODE_STRING SearchName, PHCELL_INDEX Child)
ULONG CmpFindSubKeyInLeaf (PHHIVE Hive, PCM_KEY_INDEX Index, ULONG IndexHint, PUNICODE_STRING SearchName, PHCELL_INDEX Child)
LONG CmpCompareInIndex (PHHIVE Hive, PUNICODE_STRING SearchName, ULONG Count, PCM_KEY_INDEX Index, PHCELL_INDEX Child)
LONG CmpDoCompareKeyName (PHHIVE Hive, PUNICODE_STRING SearchName, HCELL_INDEX Cell)
HCELL_INDEX CmpDoFindSubKeyByNumber (PHHIVE Hive, PCM_KEY_INDEX Index, ULONG Number)
HCELL_INDEX CmpAddToLeaf (PHHIVE Hive, HCELL_INDEX LeafCell, HCELL_INDEX NewKey, PUNICODE_STRING NewName)
HCELL_INDEX CmpSelectLeaf (PHHIVE Hive, PCM_KEY_NODE ParentKey, PUNICODE_STRING NewName, HSTORAGE_TYPE Type, PHCELL_INDEX *RootPointer)
HCELL_INDEX CmpSplitLeaf (PHHIVE Hive, HCELL_INDEX RootCell, ULONG RootSelect, HSTORAGE_TYPE Type)
HCELL_INDEX CmpFindSubKeyByName (PHHIVE Hive, PCM_KEY_NODE Parent, PUNICODE_STRING SearchName)
HCELL_INDEX CmpFindSubKeyByNumber (PHHIVE Hive, PCM_KEY_NODE Node, ULONG Number)
BOOLEAN CmpAddSubKey (PHHIVE Hive, HCELL_INDEX Parent, HCELL_INDEX Child)
BOOLEAN CmpMarkIndexDirty (PHHIVE Hive, HCELL_INDEX ParentKey, HCELL_INDEX TargetKey)
BOOLEAN CmpRemoveSubKey (PHHIVE Hive, HCELL_INDEX ParentKey, HCELL_INDEX TargetKey)

Variables

ULONG CmpHintHits = 0
ULONG CmpHintMisses = 0


Function Documentation

BOOLEAN CmpAddSubKey PHHIVE  Hive,
HCELL_INDEX  Parent,
HCELL_INDEX  Child
 

Definition at line 895 of file cmindex.c.

References _HHIVE::Allocate, _CM_INDEX::Cell, CM_KEY_FAST_LEAF, CM_KEY_INDEX_LEAF, CM_KEY_INDEX_ROOT, CM_MAX_FAST_INDEX, CM_MAX_INDEX, CML_MAJOR, CMLOG, CmpAddToLeaf(), CmpCompressedNameSize(), CmpCopyCompressedName(), CmpSelectLeaf(), CMS_INDEX, ErrorExit(), FALSE, _CM_KEY_NODE::Flags, _HHIVE::Free, HCELL_INDEX, HCELL_NIL, Hive, HvAllocateCell(), HvFreeCell(), HvGetCell, HvGetCellType, Index, KEY_COMP_NAME, _CM_KEY_FAST_INDEX::List, _CM_KEY_NODE::Name, _CM_KEY_NODE::NameLength, NewName, NULL, PHCELL_INDEX, _CM_KEY_NODE::SubKeyCounts, _CM_KEY_NODE::SubKeyLists, TRUE, and UseFastIndex.

Referenced by CmpCopySyncTree2(), CmpCreateLinkNode(), CmpDoCreate(), and EhCreateChild().

00902 : 00903 00904 Add a new child subkey to the subkey index for a cell. The 00905 child MUST NOT already be present (bugcheck if so.) 00906 00907 NOTE: We expect Parent to already be marked dirty. 00908 We will mark stuff in Index dirty 00909 00910 Arguments: 00911 00912 Hive - pointer to hive control structure for hive of interest 00913 00914 Parent - cell of key that will be parent of new key 00915 00916 Child - new key to put in Paren't sub key list 00917 00918 Return Value: 00919 00920 TRUE - it worked 00921 00922 FALSE - resource problem 00923 00924 --*/ 00925 { 00926 PCM_KEY_NODE pcell; 00927 HCELL_INDEX WorkCell; 00928 PCM_KEY_INDEX Index; 00929 PCM_KEY_FAST_INDEX FastIndex; 00930 UNICODE_STRING NewName; 00931 HCELL_INDEX LeafCell; 00932 PHCELL_INDEX RootPointer = NULL; 00933 ULONG cleanup = 0; 00934 ULONG Type; 00935 BOOLEAN IsCompressed; 00936 ULONG i; 00937 00938 CMLOG(CML_MAJOR, CMS_INDEX) { 00939 KdPrint(("CmpAddSubKey:\n\t")); 00940 KdPrint(("Hive=%08lx Parent=%08lx Child=%08lx\n",Hive,Parent,Child)); 00941 } 00942 00943 // 00944 // build a name string 00945 // 00946 pcell = (PCM_KEY_NODE)HvGetCell(Hive, Child); 00947 if (pcell->Flags & KEY_COMP_NAME) { 00948 IsCompressed = TRUE; 00949 NewName.Length = CmpCompressedNameSize(pcell->Name, pcell->NameLength); 00950 NewName.MaximumLength = NewName.Length; 00951 NewName.Buffer = (Hive->Allocate)(NewName.Length, FALSE); 00952 if (NewName.Buffer==NULL) { 00953 return(FALSE); 00954 } 00955 CmpCopyCompressedName(NewName.Buffer, 00956 NewName.MaximumLength, 00957 pcell->Name, 00958 pcell->NameLength); 00959 } else { 00960 IsCompressed = FALSE; 00961 NewName.Length = pcell->NameLength; 00962 NewName.MaximumLength = pcell->NameLength; 00963 NewName.Buffer = &(pcell->Name[0]); 00964 } 00965 00966 pcell = (PCM_KEY_NODE)HvGetCell(Hive, Parent); 00967 00968 Type = HvGetCellType(Child); 00969 00970 if (pcell->SubKeyCounts[Type] == 0) { 00971 00972 ULONG Signature; 00973 00974 // 00975 // we must allocate a leaf 00976 // 00977 WorkCell = HvAllocateCell(Hive, sizeof(CM_KEY_FAST_INDEX), Type); 00978 if (WorkCell == HCELL_NIL) { 00979 goto ErrorExit; 00980 } 00981 Index = (PCM_KEY_INDEX)HvGetCell(Hive, WorkCell); 00982 Index->Signature = UseFastIndex(Hive) ? CM_KEY_FAST_LEAF : CM_KEY_INDEX_LEAF; 00983 Index->Count = 0; 00984 pcell->SubKeyLists[Type] = WorkCell; 00985 cleanup = 1; 00986 } else { 00987 00988 Index = (PCM_KEY_INDEX)HvGetCell(Hive, pcell->SubKeyLists[Type]); 00989 if ((Index->Signature == CM_KEY_FAST_LEAF) && 00990 (Index->Count >= (CM_MAX_FAST_INDEX))) { 00991 00992 // 00993 // We must change fast index to a slow index to accomodate 00994 // growth. 00995 // 00996 00997 FastIndex = (PCM_KEY_FAST_INDEX)Index; 00998 for (i=0; i<Index->Count; i++) { 00999 Index->List[i] = FastIndex->List[i].Cell; 01000 } 01001 Index->Signature = CM_KEY_INDEX_LEAF; 01002 01003 } else if ((Index->Signature == CM_KEY_INDEX_LEAF) && 01004 (Index->Count >= (CM_MAX_INDEX - 1) )) { 01005 // 01006 // We must change flat entry to a root/leaf tree 01007 // 01008 WorkCell = HvAllocateCell( 01009 Hive, 01010 sizeof(CM_KEY_INDEX) + sizeof(HCELL_INDEX), // allow for 2 01011 Type 01012 ); 01013 if (WorkCell == HCELL_NIL) { 01014 goto ErrorExit; 01015 } 01016 01017 Index = (PCM_KEY_INDEX)HvGetCell(Hive, WorkCell); 01018 Index->Signature = CM_KEY_INDEX_ROOT; 01019 Index->Count = 1; 01020 Index->List[0] = pcell->SubKeyLists[Type]; 01021 pcell->SubKeyLists[Type] = WorkCell; 01022 cleanup = 2; 01023 01024 } 01025 } 01026 LeafCell = pcell->SubKeyLists[Type]; 01027 01028 // 01029 // LeafCell is target for add, or perhaps root 01030 // Index is pointer to fast leaf, slow Leaf or Root, whichever applies 01031 // 01032 if (Index->Signature == CM_KEY_INDEX_ROOT) { 01033 LeafCell = CmpSelectLeaf(Hive, pcell, &NewName, Type, &RootPointer); 01034 if (LeafCell == HCELL_NIL) { 01035 goto ErrorExit; 01036 } 01037 } 01038 01039 // 01040 // Add new cell to Leaf, update pointers 01041 // 01042 LeafCell = CmpAddToLeaf(Hive, LeafCell, Child, &NewName); 01043 01044 if (LeafCell == HCELL_NIL) { 01045 goto ErrorExit; 01046 } 01047 01048 pcell->SubKeyCounts[Type] += 1; 01049 01050 if (RootPointer != NULL) { 01051 *RootPointer = LeafCell; 01052 } else { 01053 pcell->SubKeyLists[Type] = LeafCell; 01054 } 01055 01056 if (IsCompressed) { 01057 (Hive->Free)(NewName.Buffer, NewName.Length); 01058 } 01059 01060 return TRUE; 01061 01062 01063 01064 ErrorExit: 01065 if (IsCompressed) { 01066 (Hive->Free)(NewName.Buffer, NewName.Length); 01067 } 01068 01069 switch (cleanup) { 01070 case 1: 01071 HvFreeCell(Hive, pcell->SubKeyLists[Type]); 01072 pcell->SubKeyLists[Type] = HCELL_NIL; 01073 break; 01074 01075 case 2: 01076 Index = (PCM_KEY_INDEX)HvGetCell(Hive, pcell->SubKeyLists[Type]); 01077 pcell->SubKeyLists[Type] = Index->List[0]; 01078 HvFreeCell(Hive, pcell->SubKeyLists[Type]); 01079 break; 01080 } 01081 01082 return FALSE; 01083 }

HCELL_INDEX CmpAddToLeaf PHHIVE  Hive,
HCELL_INDEX  LeafCell,
HCELL_INDEX  NewKey,
PUNICODE_STRING  NewName
 

Definition at line 1087 of file cmindex.c.

References ASSERT, _CM_INDEX::Cell, CM_KEY_FAST_LEAF, CM_KEY_INDEX_LEAF, CML_MAJOR, CMLOG, CmpCompareInIndex(), CmpFindSubKeyInLeaf(), CMS_INDEX, _CM_KEY_FAST_INDEX::Count, _CM_KEY_INDEX::Count, HCELL_INDEX, HCELL_NIL, Hive, HvGetCell, HvGetCellSize(), HvMarkCellDirty(), HvReallocateCell(), _CM_KEY_INDEX::List, _CM_KEY_FAST_INDEX::List, List, _CM_INDEX::NameHint, NewName, NULL, _CM_KEY_INDEX::Signature, Size, and USHORT.

Referenced by CmpAddSubKey().

01095 : 01096 01097 Insert a new subkey into a Leaf index. Supports both fast and slow 01098 leaf indexes and will determine which sort of index the given leaf is. 01099 01100 NOTE: We expect Root to already be marked dirty by caller if non NULL. 01101 We expect Leaf to always be marked dirty by caller. 01102 01103 Arguments: 01104 01105 Hive - pointer to hive control structure for hive of interest 01106 01107 LeafCell - cell of index leaf node we are to add entry too 01108 01109 NewKey - cell of KEY_NODE we are to add 01110 01111 NewName - pointer to unicode string with name to we are to add 01112 01113 Return Value: 01114 01115 HCELL_NIL - some resource problem 01116 01117 Else - cell of Leaf index when are done, caller is expected to 01118 set this into Root index or Key body. 01119 01120 --*/ 01121 { 01122 PCM_KEY_INDEX Leaf; 01123 PCM_KEY_FAST_INDEX FastLeaf; 01124 ULONG Size; 01125 ULONG OldSize; 01126 ULONG freecount; 01127 HCELL_INDEX NewCell; 01128 HCELL_INDEX Child; 01129 ULONG Select; 01130 LONG Result; 01131 ULONG EntrySize; 01132 ULONG i; 01133 01134 CMLOG(CML_MAJOR, CMS_INDEX) { 01135 KdPrint(("CmpAddToLeaf:\n\t")); 01136 KdPrint(("Hive=%08lx LeafCell=%08lx NewKey=%08lx\n",Hive,LeafCell,NewKey)); 01137 } 01138 01139 if (!HvMarkCellDirty(Hive, LeafCell)) { 01140 return HCELL_NIL; 01141 } 01142 01143 // 01144 // compute number free slots left in the leaf 01145 // 01146 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); 01147 if (Leaf->Signature == CM_KEY_INDEX_LEAF) { 01148 FastLeaf = NULL; 01149 EntrySize = sizeof(HCELL_INDEX); 01150 } else { 01151 ASSERT(Leaf->Signature == CM_KEY_FAST_LEAF); 01152 FastLeaf = (PCM_KEY_FAST_INDEX)Leaf; 01153 EntrySize = sizeof(CM_INDEX); 01154 } 01155 OldSize = HvGetCellSize(Hive, Leaf); 01156 Size = OldSize - ((EntrySize * Leaf->Count) + 01157 FIELD_OFFSET(CM_KEY_INDEX, List)); 01158 freecount = Size / EntrySize; 01159 01160 // 01161 // grow the leaf if it isn't big enough 01162 // 01163 NewCell = LeafCell; 01164 if (freecount < 1) { 01165 Size = OldSize + OldSize / 2; 01166 if (Size < (OldSize + EntrySize)) { 01167 Size = OldSize + EntrySize; 01168 } 01169 NewCell = HvReallocateCell(Hive, LeafCell, Size); 01170 if (NewCell == HCELL_NIL) { 01171 return HCELL_NIL; 01172 } 01173 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, NewCell); 01174 if (FastLeaf != NULL) { 01175 FastLeaf = (PCM_KEY_FAST_INDEX)Leaf; 01176 } 01177 } 01178 01179 // 01180 // Find where to put the new entry 01181 // 01182 Select = CmpFindSubKeyInLeaf(Hive, Leaf, (ULONG)-1, NewName, &Child); 01183 ASSERT(Child == HCELL_NIL); 01184 01185 // 01186 // Select is the index in List of the entry nearest where the 01187 // new entry should go. 01188 // Decide wether the new entry goes before or after Offset entry, 01189 // and then ripple copy and set. 01190 // If Select == Count, then the leaf is empty, so simply set our entry 01191 // 01192 if (Select != Leaf->Count) { 01193 01194 Result = CmpCompareInIndex(Hive, 01195 NewName, 01196 Select, 01197 Leaf, 01198 &Child); 01199 ASSERT(Result != 0); 01200 01201 // 01202 // Result < 0 - NewName/NewKey less than selected key, insert before 01203 // > 0 - NewName/NewKey greater than selected key, insert after 01204 // 01205 if (Result > 0) { 01206 Select++; 01207 } 01208 01209 if (Select != Leaf->Count) { 01210 01211 // 01212 // ripple copy to make space and insert 01213 // 01214 01215 if (FastLeaf != NULL) { 01216 RtlMoveMemory((PVOID)&(FastLeaf->List[Select+1]), 01217 (PVOID)&(FastLeaf->List[Select]), 01218 sizeof(CM_INDEX)*(FastLeaf->Count - Select)); 01219 } else { 01220 RtlMoveMemory((PVOID)&(Leaf->List[Select+1]), 01221 (PVOID)&(Leaf->List[Select]), 01222 sizeof(HCELL_INDEX)*(Leaf->Count - Select)); 01223 } 01224 } 01225 } 01226 if (FastLeaf != NULL) { 01227 FastLeaf->List[Select].Cell = NewKey; 01228 FastLeaf->List[Select].NameHint[0] = 0; 01229 FastLeaf->List[Select].NameHint[1] = 0; 01230 FastLeaf->List[Select].NameHint[2] = 0; 01231 FastLeaf->List[Select].NameHint[3] = 0; 01232 if (NewName->Length/sizeof(WCHAR) < 4) { 01233 i = NewName->Length/sizeof(WCHAR); 01234 } else { 01235 i = 4; 01236 } 01237 do { 01238 if ((USHORT)NewName->Buffer[i-1] > (UCHAR)-1) { 01239 // 01240 // Can't compress this name. Leave NameHint[0]==0 01241 // to force the name to be looked up in the key. 01242 // 01243 break; 01244 } 01245 FastLeaf->List[Select].NameHint[i-1] = (UCHAR)NewName->Buffer[i-1]; 01246 i--; 01247 } while ( i>0 ); 01248 } else { 01249 Leaf->List[Select] = NewKey; 01250 } 01251 Leaf->Count += 1; 01252 return NewCell; 01253 }

LONG CmpCompareInIndex PHHIVE  Hive,
PUNICODE_STRING  SearchName,
ULONG  Count,
PCM_KEY_INDEX  Index,
PHCELL_INDEX  Child
 

Definition at line 615 of file cmindex.c.

References _CM_INDEX::Cell, CM_KEY_FAST_LEAF, CmpDoCompareKeyName(), Count, HCELL_NIL, Hive, Index, _CM_KEY_FAST_INDEX::List, _CM_INDEX::NameHint, and RtlUpcaseUnicodeChar().

Referenced by CmpAddToLeaf(), CmpFindSubKeyInLeaf(), and CmpFindSubKeyInRoot().

00624 : 00625 00626 Do a compare of a name in an index. This routine handles both 00627 fast leafs and slow ones. 00628 00629 Arguments: 00630 00631 Hive - pointer to hive control structure for hive of interest 00632 00633 SearchName - pointer to name of key we are searching for 00634 00635 Count - supplies index that we are searching at. 00636 00637 Index - Supplies pointer to either a CM_KEY_INDEX or 00638 a CM_KEY_FAST_INDEX. This routine will determine which 00639 type of index it is passed. 00640 00641 Child - pointer to variable to receive hcell_index of found key 00642 HCELL_NIL if result != 0 00643 00644 Return Value: 00645 00646 0 = SearchName == KeyName (of Cell) 00647 00648 < 0 = SearchName < KeyName 00649 00650 > 0 = SearchName > KeyName 00651 00652 --*/ 00653 { 00654 PCM_KEY_FAST_INDEX FastIndex; 00655 LONG Result; 00656 ULONG i; 00657 WCHAR c1; 00658 WCHAR c2; 00659 ULONG HintLength; 00660 ULONG ValidChars; 00661 ULONG NameLength; 00662 PCM_INDEX Hint; 00663 00664 *Child = HCELL_NIL; 00665 if (Index->Signature == CM_KEY_FAST_LEAF) { 00666 FastIndex = (PCM_KEY_FAST_INDEX)Index; 00667 Hint = &FastIndex->List[Count]; 00668 00669 // 00670 // Compute the number of valid characters in the hint to compare. 00671 // 00672 HintLength = 4; 00673 for (i=0;i<4;i++) { 00674 if (Hint->NameHint[i] == 0) { 00675 HintLength = i; 00676 break; 00677 } 00678 } 00679 NameLength = SearchName->Length / sizeof(WCHAR); 00680 if (NameLength < HintLength) { 00681 ValidChars = NameLength; 00682 } else { 00683 ValidChars = HintLength; 00684 } 00685 for (i=0; i<ValidChars; i++) { 00686 c1 = SearchName->Buffer[i]; 00687 c2 = FastIndex->List[Count].NameHint[i]; 00688 Result = (LONG)RtlUpcaseUnicodeChar(c1) - 00689 (LONG)RtlUpcaseUnicodeChar(c2); 00690 if (Result != 0) { 00691 00692 // 00693 // We have found a mismatched character in the hint, 00694 // we can now tell which direction to go. 00695 // 00696 return(Result); 00697 } 00698 } 00699 00700 // 00701 // We have compared all the available characters without a 00702 // discrepancy. Go ahead and do the actual comparison now. 00703 // 00704 Result = CmpDoCompareKeyName(Hive,SearchName,FastIndex->List[Count].Cell); 00705 if (Result == 0) { 00706 *Child = Hint->Cell; 00707 } 00708 } else { 00709 // 00710 // This is just a normal old slow index. 00711 // 00712 Result = CmpDoCompareKeyName(Hive,SearchName,Index->List[Count]); 00713 if (Result == 0) { 00714 *Child = Index->List[Count]; 00715 } 00716 } 00717 return(Result); 00718 }

LONG CmpDoCompareKeyName PHHIVE  Hive,
PUNICODE_STRING  SearchName,
HCELL_INDEX  Cell
 

Definition at line 722 of file cmindex.c.

References Cell, CmpCompareCompressedName(), _CM_KEY_NODE::Flags, Hive, HvGetCell, KEY_COMP_NAME, KeyName, _CM_KEY_NODE::Name, _CM_KEY_NODE::NameLength, RtlCompareUnicodeString(), and TRUE.

Referenced by CmpCompareInIndex(), and CmpSelectLeaf().

00729 : 00730 00731 Do a compare of a name with a key. 00732 00733 Arguments: 00734 00735 Hive - pointer to hive control structure for hive of interest 00736 00737 SearchName - pointer to name of key we are searching for 00738 00739 Cell - cell of key we are to compare with 00740 00741 Return Value: 00742 00743 0 = SearchName == KeyName (of Cell) 00744 00745 < 0 = SearchName < KeyName 00746 00747 > 0 = SearchName > KeyName 00748 00749 --*/ 00750 { 00751 PCM_KEY_NODE Pcan; 00752 UNICODE_STRING KeyName; 00753 00754 Pcan = (PCM_KEY_NODE)HvGetCell(Hive, Cell); 00755 if (Pcan->Flags & KEY_COMP_NAME) { 00756 return(CmpCompareCompressedName(SearchName, 00757 Pcan->Name, 00758 Pcan->NameLength)); 00759 } else { 00760 KeyName.Buffer = &(Pcan->Name[0]); 00761 KeyName.Length = Pcan->NameLength; 00762 KeyName.MaximumLength = KeyName.Length; 00763 return (RtlCompareUnicodeString(SearchName, 00764 &KeyName, 00765 TRUE)); 00766 } 00767 }

HCELL_INDEX CmpDoFindSubKeyByNumber PHHIVE  Hive,
PCM_KEY_INDEX  Index,
ULONG  Number
 

Definition at line 833 of file cmindex.c.

References ASSERT, _CM_INDEX::Cell, CM_KEY_FAST_LEAF, CM_KEY_INDEX_ROOT, Count, _CM_KEY_INDEX::Count, FALSE, HCELL_INDEX, Hive, HvGetCell, Index, _CM_KEY_INDEX::List, _CM_KEY_FAST_INDEX::List, and _CM_KEY_INDEX::Signature.

Referenced by CmpFindSubKeyByNumber().

00840 : 00841 00842 Helper for CmpFindSubKeyByNumber, 00843 Find the Number'th entry in the index, starting from 0. 00844 00845 Arguments: 00846 00847 Hive - pointer to hive control structure for hive of interest 00848 00849 Index - root or leaf of the index 00850 00851 Number - ordinal of child key to return 00852 00853 Return Value: 00854 00855 Cell of requested entry. 00856 00857 --*/ 00858 { 00859 ULONG i; 00860 HCELL_INDEX LeafCell; 00861 PCM_KEY_INDEX Leaf; 00862 PCM_KEY_FAST_INDEX FastIndex; 00863 00864 if (Index->Signature == CM_KEY_INDEX_ROOT) { 00865 // 00866 // step through root, till we find the right leaf 00867 // 00868 for (i = 0; i < Index->Count; i++) { 00869 LeafCell = Index->List[i]; 00870 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); 00871 if (Number < Leaf->Count) { 00872 if (Leaf->Signature == CM_KEY_FAST_LEAF) { 00873 FastIndex = (PCM_KEY_FAST_INDEX)Leaf; 00874 return (FastIndex->List[Number].Cell); 00875 } else { 00876 return (Leaf->List[Number]); 00877 } 00878 } else { 00879 Number = Number - Leaf->Count; 00880 } 00881 } 00882 ASSERT(FALSE); 00883 } 00884 ASSERT(Number < Index->Count); 00885 if (Index->Signature == CM_KEY_FAST_LEAF) { 00886 FastIndex = (PCM_KEY_FAST_INDEX)Index; 00887 return(FastIndex->List[Number].Cell); 00888 } else { 00889 return (Index->List[Number]); 00890 } 00891 }

HCELL_INDEX CmpFindSubKeyByName PHHIVE  Hive,
PCM_KEY_NODE  Parent,
PUNICODE_STRING  SearchName
 

Definition at line 186 of file cmindex.c.

References ASSERT, CM_KEY_FAST_LEAF, CM_KEY_INDEX_LEAF, CM_KEY_INDEX_ROOT, CML_MAJOR, CMLOG, CmpFindSubKeyInLeaf(), CmpFindSubKeyInRoot(), CmpHintHits, CmpHintMisses, CMS_INDEX, HCELL_INDEX, HCELL_NIL, Hive, HvGetCell, HvIsCellAllocated(), _CM_KEY_INDEX::Signature, _HHIVE::StorageTypeCount, _CM_KEY_NODE::SubKeyCounts, _CM_KEY_NODE::SubKeyLists, and _CM_KEY_NODE::WorkVar.

Referenced by CmGetSystemControlValues(), CmpCopySyncTree2(), CmpFindControlSet(), CmpFindDrivers(), CmpFindNLSData(), CmpFindProfileOption(), CmpParseKey(), CmpSortDriverList(), CmpSyncSubKeysAfterDelete(), and CmpWalkPath().

00193 : 00194 00195 Find the child cell (either subkey or value) specified by name. 00196 00197 Arguments: 00198 00199 Hive - pointer to hive control structure for hive of interest 00200 00201 Parent - cell of key body which is parent of child of interest 00202 00203 SearchName - name of child of interest 00204 00205 Return Value: 00206 00207 Cell of matching child key, or HCELL_NIL if none. 00208 00209 --*/ 00210 { 00211 PCM_KEY_INDEX IndexRoot; 00212 HCELL_INDEX Child; 00213 ULONG i; 00214 ULONG FoundIndex; 00215 00216 CMLOG(CML_MAJOR, CMS_INDEX) { 00217 KdPrint(("CmpFindSubKeyByName:\n\t")); 00218 KdPrint(("Hive=%08lx Parent=%08lx SearchName=%08lx\n", Hive, Parent, SearchName)); 00219 } 00220 00221 // 00222 // Try first the Stable, then the Volatile store. Assumes that 00223 // all Volatile refs in Stable space are zeroed out at boot. 00224 // 00225 for (i = 0; i < Hive->StorageTypeCount; i++) { 00226 if (Parent->SubKeyCounts[i] != 0) { 00227 ASSERT(HvIsCellAllocated(Hive, Parent->SubKeyLists[i])); 00228 IndexRoot = (PCM_KEY_INDEX)HvGetCell(Hive, Parent->SubKeyLists[i]); 00229 00230 if (IndexRoot->Signature == CM_KEY_INDEX_ROOT) { 00231 CmpFindSubKeyInRoot(Hive, IndexRoot, SearchName, &Child); 00232 if (Child == HCELL_NIL) { 00233 continue; 00234 } 00235 IndexRoot = (PCM_KEY_INDEX)HvGetCell(Hive, Child); 00236 } 00237 ASSERT((IndexRoot->Signature == CM_KEY_INDEX_LEAF) || 00238 (IndexRoot->Signature == CM_KEY_FAST_LEAF)); 00239 00240 FoundIndex = CmpFindSubKeyInLeaf(Hive, 00241 IndexRoot, 00242 Parent->WorkVar, 00243 SearchName, 00244 &Child); 00245 if (Child != HCELL_NIL) { 00246 // 00247 // WorkVar is used as a hint for the last successful lookup 00248 // to improve our locality when similar keys are opened 00249 // repeatedly. 00250 // 00251 if (FoundIndex == Parent->WorkVar) { 00252 CmpHintHits++; 00253 } else { 00254 CmpHintMisses++; 00255 } 00256 Parent->WorkVar = FoundIndex; 00257 return Child; 00258 } 00259 } 00260 } 00261 return HCELL_NIL; 00262 }

HCELL_INDEX CmpFindSubKeyByNumber PHHIVE  Hive,
PCM_KEY_NODE  Node,
ULONG  Number
 

Definition at line 771 of file cmindex.c.

References CML_MAJOR, CMLOG, CmpDoFindSubKeyByNumber(), CMS_INDEX, HCELL_NIL, Hive, HvGetCell, Index, Stable, _HHIVE::StorageTypeCount, _CM_KEY_NODE::SubKeyCounts, _CM_KEY_NODE::SubKeyLists, and Volatile.

Referenced by CmEnumerateKey(), CmpCheckRegistry2(), CmpCopySyncTree2(), CmpDeleteTree(), CmpFindDrivers(), CmpFindMatchingDescriptorCell(), CmpFindProfileOption(), and CmpSyncSubKeysAfterDelete().

00778 : 00779 00780 Find the Number'th entry in the index, starting from 0. 00781 00782 Arguments: 00783 00784 Hive - pointer to hive control structure for hive of interest 00785 00786 Node - pointer to key body which is parent of child of interest 00787 00788 Number - ordinal of child key to return 00789 00790 Return Value: 00791 00792 Cell of matching child key, or HCELL_NIL if none. 00793 00794 --*/ 00795 { 00796 PCM_KEY_INDEX Index; 00797 00798 CMLOG(CML_MAJOR, CMS_INDEX) { 00799 KdPrint(("CmpFindSubKeyByNumber:\n\t")); 00800 KdPrint(("Hive=%08lx Node=%08lx Number=%08lx\n",Hive,Node,Number)); 00801 } 00802 00803 if (Number < Node->SubKeyCounts[Stable]) { 00804 00805 // 00806 // It's in the stable set 00807 // 00808 Index = (PCM_KEY_INDEX)HvGetCell(Hive, Node->SubKeyLists[Stable]); 00809 return (CmpDoFindSubKeyByNumber(Hive, Index, Number)); 00810 00811 } else if (Hive->StorageTypeCount > Volatile) { 00812 00813 // 00814 // It's in the volatile set 00815 // 00816 Number = Number - Node->SubKeyCounts[Stable]; 00817 if (Number < Node->SubKeyCounts[Volatile]) { 00818 00819 Index = (PCM_KEY_INDEX)HvGetCell(Hive, Node->SubKeyLists[Volatile]); 00820 return (CmpDoFindSubKeyByNumber(Hive, Index, Number)); 00821 00822 } 00823 } 00824 00825 // 00826 // It's nowhere 00827 // 00828 return HCELL_NIL; 00829 }

ULONG CmpFindSubKeyInLeaf PHHIVE  Hive,
PCM_KEY_INDEX  Index,
ULONG  IndexHint,
PUNICODE_STRING  SearchName,
PHCELL_INDEX  Child
 

Definition at line 475 of file cmindex.c.

References ASSERT, CM_KEY_FAST_LEAF, CM_KEY_INDEX_LEAF, CML_MAJOR, CMLOG, CmpCompareInIndex(), CMS_INDEX, HCELL_NIL, Hive, Index, and TRUE.

Referenced by CmpAddToLeaf(), CmpFindSubKeyByName(), CmpMarkIndexDirty(), and CmpRemoveSubKey().

00484 : 00485 00486 Find a named key in a leaf index, if it exists. The supplied index 00487 may be either a fast index or a slow one. 00488 00489 Arguments: 00490 00491 Hive - pointer to hive control structure for hive of interest 00492 00493 Index - pointer to leaf block 00494 00495 HintIndex - Supplies hint for first key to check. 00496 00497 SearchName - pointer to name of key of interest 00498 00499 Child - pointer to variable to receive hcell_index of found key 00500 HCELL_NIL if none found 00501 00502 Return Value: 00503 00504 Index in List of last cell. If Child != HCELL_NIL, is offset in 00505 list at which Child was found. Else, is offset of last place 00506 we looked. 00507 00508 --*/ 00509 { 00510 ULONG High; 00511 ULONG Low; 00512 ULONG CanCount; 00513 LONG Result; 00514 00515 CMLOG(CML_MAJOR, CMS_INDEX) { 00516 KdPrint(("CmpFindSubKeyInLeaf:\n\t")); 00517 KdPrint(("Hive=%08lx Index=%08lx SearchName=%08lx\n",Hive,Index,SearchName)); 00518 } 00519 00520 ASSERT((Index->Signature == CM_KEY_INDEX_LEAF) || 00521 (Index->Signature == CM_KEY_FAST_LEAF)); 00522 00523 High = Index->Count - 1; 00524 Low = 0; 00525 if (HintIndex < High) { 00526 CanCount = HintIndex; 00527 } else { 00528 CanCount = High/2; 00529 } 00530 00531 if (Index->Count == 0) { 00532 *Child = HCELL_NIL; 00533 return 0; 00534 } 00535 00536 while (TRUE) { 00537 00538 // 00539 // Compute where to look next, get correct pointer, do compare 00540 // 00541 Result = CmpCompareInIndex(Hive, 00542 SearchName, 00543 CanCount, 00544 Index, 00545 Child); 00546 00547 if (Result == 0) { 00548 00549 // 00550 // SearchName == KeyName 00551 // 00552 return CanCount; 00553 } 00554 00555 if (Result < 0) { 00556 00557 // 00558 // SearchName < KeyName 00559 // 00560 High = CanCount; 00561 00562 } else { 00563 00564 // 00565 // SearchName > KeyName 00566 // 00567 Low = CanCount; 00568 } 00569 00570 if ((High - Low) <= 1) { 00571 break; 00572 } 00573 CanCount = ((High-Low)/2)+Low; 00574 } 00575 00576 // 00577 // If we get here, High - Low = 1 or High == Low 00578 // Simply look first at Low, then at High 00579 // 00580 Result = CmpCompareInIndex(Hive, 00581 SearchName, 00582 Low, 00583 Index, 00584 Child); 00585 if (Result == 0) { 00586 00587 // 00588 // found it 00589 // 00590 return Low; 00591 } 00592 00593 if (Result < 0) { 00594 00595 // 00596 // does not exist, under 00597 // 00598 return Low; 00599 } 00600 00601 // 00602 // see if High matches, we will return High as the 00603 // closest key regardless. 00604 // 00605 Result = CmpCompareInIndex(Hive, 00606 SearchName, 00607 High, 00608 Index, 00609 Child); 00610 return High; 00611 }

ULONG CmpFindSubKeyInRoot PHHIVE  Hive,
PCM_KEY_INDEX  Index,
PUNICODE_STRING  SearchName,
PHCELL_INDEX  Child
 

Definition at line 266 of file cmindex.c.

References ASSERT, CM_KEY_FAST_LEAF, CM_KEY_INDEX_LEAF, CM_KEY_INDEX_ROOT, CML_MAJOR, CMLOG, CmpCompareInIndex(), CMS_INDEX, _CM_KEY_INDEX::Count, HCELL_INDEX, HCELL_NIL, Hive, HvGetCell, Index, _CM_KEY_INDEX::Signature, and TRUE.

Referenced by CmpFindSubKeyByName(), CmpMarkIndexDirty(), CmpRemoveSubKey(), and CmpSelectLeaf().

00274 : 00275 00276 Find the leaf index that would contain a key, if there is one. 00277 00278 Arguments: 00279 00280 Hive - pointer to hive control structure for hive of interest 00281 00282 Index - pointer to root index block 00283 00284 SearchName - pointer to name of key of interest 00285 00286 Child - pointer to variable to receive hcell_index of found leaf index 00287 block, HCELL_NIL if none. Non nil does not necessarily mean 00288 the key is present, call FindSubKeyInLeaf to decide that. 00289 00290 Return Value: 00291 00292 Index in List of last Leaf Cell entry examined. If Child != HCELL_NIL, 00293 Index is entry that matched, else, index is for last entry we looked 00294 at. (Target Leaf will be this value plus or minus 1) 00295 00296 --*/ 00297 { 00298 ULONG High; 00299 ULONG Low; 00300 ULONG CanCount; 00301 HCELL_INDEX LeafCell; 00302 PCM_KEY_INDEX Leaf; 00303 LONG Result; 00304 00305 CMLOG(CML_MAJOR, CMS_INDEX) { 00306 KdPrint(("CmpFindSubKeyInRoot:\n\t")); 00307 KdPrint(("Hive=%08lx Index=%08lx SearchName=%08lx\n",Hive,Index,SearchName)); 00308 } 00309 00310 00311 ASSERT(Index->Count != 0); 00312 ASSERT(Index->Signature == CM_KEY_INDEX_ROOT); 00313 00314 High = Index->Count - 1; 00315 Low = 0; 00316 00317 while (TRUE) { 00318 00319 // 00320 // Compute where to look next, get correct pointer, do compare 00321 // 00322 CanCount = ((High-Low)/2)+Low; 00323 LeafCell = Index->List[CanCount]; 00324 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); 00325 00326 ASSERT((Leaf->Signature == CM_KEY_INDEX_LEAF) || 00327 (Leaf->Signature == CM_KEY_FAST_LEAF)); 00328 ASSERT(Leaf->Count != 0); 00329 00330 Result = CmpCompareInIndex(Hive, 00331 SearchName, 00332 Leaf->Count-1, 00333 Leaf, 00334 Child); 00335 00336 if (Result == 0) { 00337 00338 // 00339 // SearchName == KeyName of last key in leaf, so 00340 // this is our leaf 00341 // 00342 *Child = LeafCell; 00343 return CanCount; 00344 } 00345 00346 if (Result < 0) { 00347 00348 // 00349 // SearchName < KeyName, so this may still be our leaf 00350 // 00351 Result = CmpCompareInIndex(Hive, 00352 SearchName, 00353 0, 00354 Leaf, 00355 Child); 00356 00357 if (Result >= 0) { 00358 00359 // 00360 // we know from above that SearchName is less than 00361 // last key in leaf. 00362 // since it is also >= first key in leaf, it must 00363 // reside in leaf somewhere, and we are done 00364 // 00365 *Child = LeafCell; 00366 return CanCount; 00367 } 00368 00369 High = CanCount; 00370 00371 } else { 00372 00373 // 00374 // SearchName > KeyName 00375 // 00376 Low = CanCount; 00377 } 00378 00379 if ((High - Low) <= 1) { 00380 break; 00381 } 00382 } 00383 00384 // 00385 // If we get here, High - Low = 1 or High == Low 00386 // 00387 ASSERT((High - Low == 1) || (High == Low)); 00388 LeafCell = Index->List[Low]; 00389 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); 00390 Result = CmpCompareInIndex(Hive, 00391 SearchName, 00392 Leaf->Count-1, 00393 Leaf, 00394 Child); 00395 00396 if (Result == 0) { 00397 00398 // 00399 // found it 00400 // 00401 *Child = LeafCell; 00402 return Low; 00403 } 00404 00405 if (Result < 0) { 00406 00407 // 00408 // SearchName < KeyName, so this may still be our leaf 00409 // 00410 Result = CmpCompareInIndex(Hive, 00411 SearchName, 00412 0, 00413 Leaf, 00414 Child); 00415 00416 if (Result >= 0) { 00417 00418 // 00419 // we know from above that SearchName is less than 00420 // last key in leaf. 00421 // since it is also >= first key in leaf, it must 00422 // reside in leaf somewhere, and we are done 00423 // 00424 *Child = LeafCell; 00425 return Low; 00426 } 00427 00428 // 00429 // does not exist, but belongs in Low or Leaf below low 00430 // 00431 *Child = HCELL_NIL; 00432 return Low; 00433 } 00434 00435 // 00436 // see if High matches 00437 // 00438 LeafCell = Index->List[High]; 00439 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); 00440 Result = CmpCompareInIndex(Hive, 00441 SearchName, 00442 Leaf->Count - 1, 00443 Leaf, 00444 Child); 00445 if (Result == 0) { 00446 00447 // 00448 // found it 00449 // 00450 *Child = LeafCell; 00451 return High; 00452 00453 } else if (Result < 0) { 00454 00455 // 00456 // Clearly greater than low, or we wouldn't be here. 00457 // So regardless of whether it's below the start 00458 // of this leaf, it would be in this leaf if it were 00459 // where, so report this leaf. 00460 // 00461 *Child = LeafCell; 00462 return High; 00463 00464 } 00465 00466 // 00467 // Off the high end 00468 // 00469 *Child = HCELL_NIL; 00470 return High; 00471 }

BOOLEAN CmpMarkIndexDirty PHHIVE  Hive,
HCELL_INDEX  ParentKey,
HCELL_INDEX  TargetKey
 

Definition at line 1608 of file cmindex.c.

References _HHIVE::Allocate, ASSERT, CM_KEY_FAST_LEAF, CM_KEY_INDEX_LEAF, CM_KEY_INDEX_ROOT, CmpCompressedNameSize(), CmpCopyCompressedName(), CmpFindSubKeyInLeaf(), CmpFindSubKeyInRoot(), ErrorExit(), FALSE, _CM_KEY_NODE::Flags, _HHIVE::Free, HCELL_INDEX, HCELL_NIL, Hive, HvGetCell, HvIsCellAllocated(), HvMarkCellDirty(), Index, KEY_COMP_NAME, _CM_KEY_NODE::Name, _CM_KEY_NODE::NameLength, NULL, _HHIVE::StorageTypeCount, _CM_KEY_NODE::SubKeyCounts, _CM_KEY_NODE::SubKeyLists, TRUE, and _CM_KEY_NODE::WorkVar.

Referenced by CmpMarkKeyDirty(), and CmpMarkKeyParentDirty().

01615 : 01616 01617 Mark as dirty relevent cells of a subkey index. The Leaf that 01618 points to TargetKey, and the Root index block, if applicable, 01619 will be marked dirty. This call assumes we are setting up 01620 for a subkey delete. 01621 01622 Arguments: 01623 01624 Hive - pointer to hive control structure for hive of interest 01625 01626 ParentKey - key from whose subkey list delete is to be performed 01627 01628 TargetKey - key being deleted 01629 01630 Return Value: 01631 01632 TRUE - it worked, FALSE - it didn't, some resource problem 01633 01634 --*/ 01635 { 01636 PCM_KEY_NODE pcell; 01637 ULONG i; 01638 HCELL_INDEX IndexCell; 01639 PCM_KEY_INDEX Index; 01640 HCELL_INDEX Child = HCELL_NIL; 01641 UNICODE_STRING SearchName; 01642 BOOLEAN IsCompressed; 01643 01644 pcell = (PCM_KEY_NODE)HvGetCell(Hive, TargetKey); 01645 if (pcell->Flags & KEY_COMP_NAME) { 01646 IsCompressed = TRUE; 01647 SearchName.Length = CmpCompressedNameSize(pcell->Name, pcell->NameLength); 01648 SearchName.MaximumLength = SearchName.Length; 01649 SearchName.Buffer = (Hive->Allocate)(SearchName.Length, FALSE); 01650 if (SearchName.Buffer==NULL) { 01651 return(FALSE); 01652 } 01653 CmpCopyCompressedName(SearchName.Buffer, 01654 SearchName.MaximumLength, 01655 pcell->Name, 01656 pcell->NameLength); 01657 } else { 01658 IsCompressed = FALSE; 01659 SearchName.Length = pcell->NameLength; 01660 SearchName.MaximumLength = pcell->NameLength; 01661 SearchName.Buffer = &(pcell->Name[0]); 01662 } 01663 01664 pcell = (PCM_KEY_NODE)HvGetCell(Hive, ParentKey); 01665 01666 for (i = 0; i < Hive->StorageTypeCount; i++) { 01667 if (pcell->SubKeyCounts[i] != 0) { 01668 ASSERT(HvIsCellAllocated(Hive, pcell->SubKeyLists[i])); 01669 IndexCell = pcell->SubKeyLists[i]; 01670 Index = (PCM_KEY_INDEX)HvGetCell(Hive, IndexCell); 01671 01672 if (Index->Signature == CM_KEY_INDEX_ROOT) { 01673 01674 // 01675 // target even in index? 01676 // 01677 CmpFindSubKeyInRoot(Hive, Index, &SearchName, &Child); 01678 if (Child == HCELL_NIL) { 01679 continue; 01680 } 01681 01682 // 01683 // mark root dirty 01684 // 01685 if (! HvMarkCellDirty(Hive, IndexCell)) { 01686 goto ErrorExit; 01687 } 01688 01689 IndexCell = Child; 01690 Index = (PCM_KEY_INDEX)HvGetCell(Hive, Child); 01691 } 01692 ASSERT((Index->Signature == CM_KEY_INDEX_LEAF) || 01693 (Index->Signature == CM_KEY_FAST_LEAF)); 01694 01695 CmpFindSubKeyInLeaf(Hive, Index, pcell->WorkVar, &SearchName, &Child); 01696 if (Child != HCELL_NIL) { 01697 if (IsCompressed) { 01698 (Hive->Free)(SearchName.Buffer, SearchName.Length); 01699 } 01700 return(HvMarkCellDirty(Hive, IndexCell)); 01701 } 01702 } 01703 } 01704 01705 ErrorExit: 01706 if (IsCompressed) { 01707 (Hive->Free)(SearchName.Buffer, SearchName.Length); 01708 } 01709 return FALSE; 01710 }

BOOLEAN CmpRemoveSubKey PHHIVE  Hive,
HCELL_INDEX  ParentKey,
HCELL_INDEX  TargetKey
 

Definition at line 1714 of file cmindex.c.

References _HHIVE::Allocate, ASSERT, CM_KEY_FAST_LEAF, CM_KEY_INDEX_LEAF, CM_KEY_INDEX_ROOT, CmpCompressedNameSize(), CmpCopyCompressedName(), CmpFindSubKeyInLeaf(), CmpFindSubKeyInRoot(), _CM_KEY_INDEX::Count, _CM_KEY_FAST_INDEX::Count, FALSE, _CM_KEY_NODE::Flags, _HHIVE::Free, HCELL_INDEX, HCELL_NIL, Hive, HvFreeCell(), HvGetCell, HvGetCellType, HvIsCellAllocated(), KEY_COMP_NAME, _CM_KEY_INDEX::List, _CM_KEY_FAST_INDEX::List, _CM_KEY_NODE::Name, _CM_KEY_NODE::NameLength, NULL, _CM_KEY_INDEX::Signature, _CM_KEY_NODE::SubKeyCounts, _CM_KEY_NODE::SubKeyLists, TRUE, and _CM_KEY_NODE::WorkVar.

Referenced by CmpFreeKeyByCell().

01721 : 01722 01723 Remove the subkey TargetKey refers to from ParentKey's list. 01724 01725 NOTE: Assumes that caller has marked relevent cells dirty, 01726 see CmpMarkIndexDirty. 01727 01728 Arguments: 01729 01730 Hive - pointer to hive control structure for hive of interest 01731 01732 ParentKey - key from whose subkey list delete is to be performed 01733 01734 TargetKey - key being deleted 01735 01736 Return Value: 01737 01738 TRUE - it worked, FALSE - it didn't, some resource problem 01739 01740 --*/ 01741 { 01742 PCM_KEY_NODE pcell; 01743 HCELL_INDEX LeafCell; 01744 PCM_KEY_INDEX Leaf; 01745 PCM_KEY_FAST_INDEX FastIndex; 01746 HCELL_INDEX RootCell = HCELL_NIL; 01747 PCM_KEY_INDEX Root = NULL; 01748 HCELL_INDEX Child; 01749 ULONG Type; 01750 ULONG RootSelect; 01751 ULONG LeafSelect; 01752 UNICODE_STRING SearchName; 01753 BOOLEAN IsCompressed; 01754 WCHAR CompressedBuffer[50]; 01755 01756 pcell = (PCM_KEY_NODE)HvGetCell(Hive, TargetKey); 01757 if (pcell->Flags & KEY_COMP_NAME) { 01758 IsCompressed = TRUE; 01759 SearchName.Length = CmpCompressedNameSize(pcell->Name, pcell->NameLength); 01760 SearchName.MaximumLength = SearchName.Length; 01761 if (SearchName.MaximumLength > sizeof(CompressedBuffer)) { 01762 SearchName.Buffer = (Hive->Allocate)(SearchName.Length, FALSE); 01763 if (SearchName.Buffer==NULL) { 01764 return(FALSE); 01765 } 01766 } else { 01767 SearchName.Buffer = CompressedBuffer; 01768 } 01769 CmpCopyCompressedName(SearchName.Buffer, 01770 SearchName.MaximumLength, 01771 pcell->Name, 01772 pcell->NameLength); 01773 } else { 01774 IsCompressed = FALSE; 01775 SearchName.Length = pcell->NameLength; 01776 SearchName.MaximumLength = pcell->NameLength; 01777 SearchName.Buffer = &(pcell->Name[0]); 01778 } 01779 01780 pcell = (PCM_KEY_NODE)HvGetCell(Hive, ParentKey); 01781 Type = HvGetCellType(TargetKey); 01782 01783 ASSERT(pcell->SubKeyCounts[Type] != 0); 01784 ASSERT(HvIsCellAllocated(Hive, pcell->SubKeyLists[Type])); 01785 01786 LeafCell = pcell->SubKeyLists[Type]; 01787 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); 01788 01789 if (Leaf->Signature == CM_KEY_INDEX_ROOT) { 01790 RootSelect = CmpFindSubKeyInRoot(Hive, Leaf, &SearchName, &Child); 01791 01792 ASSERT(Child != FALSE); 01793 01794 Root = Leaf; 01795 RootCell = LeafCell; 01796 LeafCell = Child; 01797 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); 01798 01799 } 01800 01801 ASSERT((Leaf->Signature == CM_KEY_INDEX_LEAF) || 01802 (Leaf->Signature == CM_KEY_FAST_LEAF)); 01803 01804 LeafSelect = CmpFindSubKeyInLeaf(Hive, Leaf, pcell->WorkVar, &SearchName, &Child); 01805 01806 ASSERT(Child != HCELL_NIL); 01807 01808 // 01809 // Leaf points to Index Leaf block 01810 // Child is Index Leaf block cell 01811 // LeafSelect is Index for List[] 01812 // 01813 pcell->SubKeyCounts[Type] -= 1; 01814 01815 Leaf->Count -= 1; 01816 if (Leaf->Count == 0) { 01817 01818 // 01819 // Empty Leaf, drop it. 01820 // 01821 HvFreeCell(Hive, LeafCell); 01822 01823 if (Root != NULL) { 01824 01825 Root->Count -= 1; 01826 if (Root->Count == 0) { 01827 01828 // 01829 // Root is empty, free it too. 01830 // 01831 HvFreeCell(Hive, RootCell); 01832 pcell->SubKeyLists[Type] = HCELL_NIL; 01833 01834 } else if (RootSelect < (ULONG)(Root->Count)) { 01835 01836 // 01837 // Middle entry, squeeze root 01838 // 01839 RtlMoveMemory( 01840 (PVOID)&(Root->List[RootSelect]), 01841 (PVOID)&(Root->List[RootSelect+1]), 01842 (Root->Count - RootSelect) * sizeof(HCELL_INDEX) 01843 ); 01844 } 01845 // 01846 // Else RootSelect == last entry, so decrementing count 01847 // was all we needed to do 01848 // 01849 01850 } else { 01851 01852 pcell->SubKeyLists[Type] = HCELL_NIL; 01853 01854 } 01855 01856 } else if (LeafSelect < (ULONG)(Leaf->Count)) { 01857 01858 if (Leaf->Signature == CM_KEY_INDEX_LEAF) { 01859 RtlMoveMemory((PVOID)&(Leaf->List[LeafSelect]), 01860 (PVOID)&(Leaf->List[LeafSelect+1]), 01861 (Leaf->Count - LeafSelect) * sizeof(HCELL_INDEX)); 01862 } else { 01863 FastIndex = (PCM_KEY_FAST_INDEX)Leaf; 01864 RtlMoveMemory((PVOID)&(FastIndex->List[LeafSelect]), 01865 (PVOID)&(FastIndex->List[LeafSelect+1]), 01866 (FastIndex->Count - LeafSelect) * sizeof(CM_INDEX)); 01867 } 01868 } 01869 // 01870 // Else LeafSelect == last entry, so decrementing count was enough 01871 // 01872 01873 if ((IsCompressed) && 01874 (SearchName.MaximumLength > sizeof(CompressedBuffer))) { 01875 (Hive->Free)(SearchName.Buffer, SearchName.Length); 01876 } 01877 return TRUE; 01878 } }

HCELL_INDEX CmpSelectLeaf PHHIVE  Hive,
PCM_KEY_NODE  ParentKey,
PUNICODE_STRING  NewName,
HSTORAGE_TYPE  Type,
PHCELL_INDEX RootPointer
 

Definition at line 1257 of file cmindex.c.

References ASSERT, CM_KEY_INDEX_ROOT, CM_MAX_INDEX, CML_MAJOR, CMLOG, CmpDoCompareKeyName(), CmpFindSubKeyInRoot(), CmpSplitLeaf(), CMS_INDEX, _CM_KEY_INDEX::Count, HCELL_INDEX, HCELL_NIL, Hive, HvGetCell, HvMarkCellDirty(), Index, _CM_KEY_INDEX::List, NewName, _CM_KEY_NODE::SubKeyLists, and TRUE.

Referenced by CmpAddSubKey().

01266 : 01267 01268 This routine is only called if the subkey index for a cell is NOT 01269 simply a single Leaf index block. 01270 01271 It selects the Leaf index block to which a new entry is to be 01272 added. It may create this block by splitting an existing Leaf 01273 block. 01274 01275 Arguments: 01276 01277 Hive - pointer to hive control structure for hive of interest 01278 01279 ParentKey - mapped pointer to parent key 01280 01281 NewName - pointer to unicode string naming entry to add 01282 01283 Type - Stable or Volatile, describes Child's storage 01284 01285 RootPointer - pointer to variable to receive address of HCELL_INDEX 01286 that points to Leaf block returned as function argument. 01287 Used for updates. 01288 01289 Return Value: 01290 01291 HCELL_NIL - resource problem 01292 01293 Else, cell index of Leaf index block to add entry to 01294 01295 --*/ 01296 { 01297 HCELL_INDEX LeafCell; 01298 HCELL_INDEX WorkCell; 01299 PCM_KEY_INDEX Index; 01300 PCM_KEY_INDEX Leaf; 01301 ULONG RootSelect; 01302 LONG Result; 01303 01304 CMLOG(CML_MAJOR, CMS_INDEX) { 01305 KdPrint(("CmpSelectLeaf:\n\t")); 01306 KdPrint(("Hive=%08lx ParentKey=%08lx\n", Hive, ParentKey)); 01307 } 01308 01309 01310 // 01311 // Force root to always be dirty, since we'll either grow it or edit it, 01312 // and it needs to be marked dirty for BOTH cases. (Edit may not 01313 // occur until after we leave 01314 // 01315 if (! HvMarkCellDirty(Hive, ParentKey->SubKeyLists[Type])) { 01316 return HCELL_NIL; 01317 } 01318 01319 // 01320 // must find the proper leaf 01321 // 01322 Index = (PCM_KEY_INDEX)HvGetCell(Hive, ParentKey->SubKeyLists[Type]); 01323 ASSERT(Index->Signature == CM_KEY_INDEX_ROOT); 01324 01325 while (TRUE) { 01326 01327 RootSelect = CmpFindSubKeyInRoot(Hive, Index, NewName, &LeafCell); 01328 01329 if (LeafCell == HCELL_NIL) { 01330 01331 // 01332 // Leaf of interest is somewhere near RootSelect 01333 // 01334 // . Always use lowest order leaf we can get away with 01335 // . Never split a leaf if there's one with space we can use 01336 // . When we split a leaf, we have to repeat search 01337 // 01338 // If (NewKey is below lowest key in selected) 01339 // If there's a Leaf below selected with space 01340 // use the leaf below 01341 // else 01342 // use the leaf (split it if not enough space) 01343 // Else 01344 // must be above highest key in selected, less than 01345 // lowest key in Leaf to right of selected 01346 // if space in selected 01347 // use selected 01348 // else if space in leaf above selected 01349 // use leaf above 01350 // else 01351 // split selected 01352 // 01353 LeafCell = Index->List[RootSelect]; 01354 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); 01355 WorkCell = Leaf->List[0]; 01356 Result = CmpDoCompareKeyName(Hive, NewName, WorkCell); 01357 ASSERT(Result != 0); 01358 01359 if (Result < 0) { 01360 01361 // 01362 // new is off the left end of Selected 01363 // 01364 if (RootSelect > 0) { 01365 01366 // 01367 // there's a Leaf to the left, try to use it 01368 // 01369 LeafCell = Index->List[RootSelect-1]; 01370 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); 01371 01372 if (Leaf->Count < (CM_MAX_INDEX - 1)) { 01373 RootSelect--; 01374 *RootPointer = &(Index->List[RootSelect]); 01375 break; 01376 } 01377 01378 } else { 01379 // 01380 // new key is off the left end of the leftmost leaf. 01381 // Use the leftmost leaf, if there's enough room 01382 // 01383 LeafCell = Index->List[0]; 01384 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); 01385 if (Leaf->Count < (CM_MAX_INDEX - 1)) { 01386 *RootPointer = &(Index->List[0]); 01387 break; 01388 } 01389 } 01390 01391 // 01392 // else fall to split case 01393 // 01394 01395 } else { 01396 01397 // 01398 // since new key is not in a Leaf, and is not off 01399 // the left end of the ResultSelect Leaf, it must 01400 // be off the right end. 01401 // 01402 LeafCell = Index->List[RootSelect]; 01403 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); 01404 01405 if (Leaf->Count < (CM_MAX_INDEX - 1)) { 01406 *RootPointer = &(Index->List[RootSelect]); 01407 break; 01408 } 01409 01410 // 01411 // No space, see if there's a leaf to the rigth 01412 // and if it has space 01413 // 01414 if (RootSelect < (ULONG)(Index->Count - 1)) { 01415 01416 LeafCell = Index->List[RootSelect+1]; 01417 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); 01418 01419 if (Leaf->Count < (CM_MAX_INDEX - 1)) { 01420 *RootPointer = &(Index->List[RootSelect+1]); 01421 break; 01422 } 01423 } 01424 01425 // 01426 // fall to split case 01427 // 01428 } 01429 01430 } else { // LeafCell != HCELL_NIL 01431 01432 // 01433 // Since newkey cannot already be in tree, it must be 01434 // greater than the bottom of Leaf and less than the top, 01435 // therefore it must go in Leaf. If no space, split it. 01436 // 01437 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); 01438 if (Leaf->Count < (CM_MAX_INDEX - 1)) { 01439 01440 *RootPointer = &(Index->List[RootSelect]); 01441 break; 01442 } 01443 01444 // 01445 // fall to split case 01446 // 01447 } 01448 01449 // 01450 // either no neigbor, or no space in neighbor, so split 01451 // 01452 WorkCell = CmpSplitLeaf( 01453 Hive, 01454 ParentKey->SubKeyLists[Type], // root cell 01455 RootSelect, 01456 Type 01457 ); 01458 if (WorkCell == HCELL_NIL) { 01459 return HCELL_NIL; 01460 } 01461 01462 ParentKey->SubKeyLists[Type] = WorkCell; 01463 Index = (PCM_KEY_INDEX)HvGetCell(Hive, WorkCell); 01464 ASSERT(Index->Signature == CM_KEY_INDEX_ROOT); 01465 01466 } // while(true) 01467 return LeafCell; 01468 }

HCELL_INDEX CmpSplitLeaf PHHIVE  Hive,
HCELL_INDEX  RootCell,
ULONG  RootSelect,
HSTORAGE_TYPE  Type
 

Definition at line 1472 of file cmindex.c.

References ASSERT, CM_KEY_INDEX_LEAF, CML_MAJOR, CMLOG, CMS_INDEX, _CM_KEY_INDEX::Count, HCELL_INDEX, HCELL_NIL, Hive, HvAllocateCell(), HvFreeCell(), HvGetCell, HvGetCellSize(), HvMarkCellDirty(), HvReallocateCell(), List, _CM_KEY_INDEX::List, _CM_KEY_INDEX::Signature, Size, and USHORT.

Referenced by CmpSelectLeaf().

01480 : 01481 01482 Split the Leaf index block specified by RootSelect, causing both 01483 of the split out Leaf blocks to appear in the Root index block 01484 specified by RootCell. 01485 01486 Caller is expected to have marked old root cell dirty. 01487 01488 Arguments: 01489 01490 Hive - pointer to hive control structure for hive of interest 01491 01492 RootCell - cell of the Root index block of index being grown 01493 01494 RootSelect - indicates which child of Root to split 01495 01496 Type - Stable or Volatile 01497 01498 Return Value: 01499 01500 HCELL_NIL - some resource problem 01501 01502 Else - cell of new (e.g. reallocated) Root index block 01503 01504 --*/ 01505 { 01506 PCM_KEY_INDEX Root; 01507 HCELL_INDEX LeafCell; 01508 PCM_KEY_INDEX Leaf; 01509 HCELL_INDEX NewLeafCell; 01510 PCM_KEY_INDEX NewLeaf; 01511 ULONG Size; 01512 ULONG freecount; 01513 USHORT OldCount; 01514 USHORT KeepCount; 01515 USHORT NewCount; 01516 01517 CMLOG(CML_MAJOR, CMS_INDEX) { 01518 KdPrint(("CmpSplitLeaf:\n\t")); 01519 KdPrint(("Hive=%08lx RootCell=%08lx RootSelect\n", Hive, RootCell, RootSelect)); 01520 } 01521 01522 // 01523 // allocate new Leaf index block 01524 // 01525 Root = (PCM_KEY_INDEX)HvGetCell(Hive, RootCell); 01526 LeafCell = Root->List[RootSelect]; 01527 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); 01528 OldCount = Leaf->Count; 01529 01530 KeepCount = (USHORT)(OldCount / 2); // # of entries to keep in org. Leaf 01531 NewCount = (OldCount - KeepCount); // # of entries to move 01532 01533 Size = (sizeof(HCELL_INDEX) * NewCount) + 01534 FIELD_OFFSET(CM_KEY_INDEX, List) + 1; // +1 to assure room for add 01535 01536 if (!HvMarkCellDirty(Hive, LeafCell)) { 01537 return HCELL_NIL; 01538 } 01539 01540 NewLeafCell = HvAllocateCell(Hive, Size, Type); 01541 if (NewLeafCell == HCELL_NIL) { 01542 return HCELL_NIL; 01543 } 01544 NewLeaf = (PCM_KEY_INDEX)HvGetCell(Hive, NewLeafCell); 01545 NewLeaf->Signature = CM_KEY_INDEX_LEAF; 01546 01547 01548 // 01549 // compute number of free slots left in the root 01550 // 01551 Size = HvGetCellSize(Hive, Root); 01552 Size = Size - ((sizeof(HCELL_INDEX) * Root->Count) + 01553 FIELD_OFFSET(CM_KEY_INDEX, List)); 01554 freecount = Size / sizeof(HCELL_INDEX); 01555 01556 01557 // 01558 // grow the root if it isn't big enough 01559 // 01560 if (freecount < 1) { 01561 Size = HvGetCellSize(Hive, Root) + sizeof(HCELL_INDEX); 01562 RootCell = HvReallocateCell(Hive, RootCell, Size); 01563 if (RootCell == HCELL_NIL) { 01564 HvFreeCell(Hive, NewLeafCell); 01565 return HCELL_NIL; 01566 } 01567 Root = (PCM_KEY_INDEX)HvGetCell(Hive, RootCell); 01568 } 01569 01570 01571 // 01572 // copy data from one Leaf to the other 01573 // 01574 RtlMoveMemory( 01575 (PVOID)&(NewLeaf->List[0]), 01576 (PVOID)&(Leaf->List[KeepCount]), 01577 sizeof(HCELL_INDEX) * NewCount 01578 ); 01579 01580 ASSERT(KeepCount != 0); 01581 ASSERT(NewCount != 0); 01582 01583 Leaf->Count = KeepCount; 01584 NewLeaf->Count = NewCount; 01585 01586 01587 // 01588 // make an open slot in the root 01589 // 01590 if (RootSelect < (ULONG)(Root->Count-1)) { 01591 RtlMoveMemory( 01592 (PVOID)&(Root->List[RootSelect+2]), 01593 (PVOID)&(Root->List[RootSelect+1]), 01594 (Root->Count - (RootSelect + 1)) * sizeof(HCELL_INDEX) 01595 ); 01596 } 01597 01598 // 01599 // update the root 01600 // 01601 Root->Count += 1; 01602 Root->List[RootSelect+1] = NewLeafCell; 01603 return RootCell; 01604 }


Variable Documentation

ULONG CmpHintHits = 0
 

Definition at line 181 of file cmindex.c.

Referenced by CmpFindSubKeyByName().

ULONG CmpHintMisses = 0
 

Definition at line 182 of file cmindex.c.

Referenced by CmpFindSubKeyByName().


Generated on Sat May 15 19:43:08 2004 for test by doxygen 1.3.7