00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
#include "cmp.h"
00099
00100 ULONG
00101
CmpFindSubKeyInRoot(
00102
PHHIVE Hive,
00103
PCM_KEY_INDEX Index,
00104 PUNICODE_STRING SearchName,
00105 PHCELL_INDEX Child
00106 );
00107
00108 ULONG
00109
CmpFindSubKeyInLeaf(
00110
PHHIVE Hive,
00111
PCM_KEY_INDEX Index,
00112 ULONG IndexHint,
00113 PUNICODE_STRING SearchName,
00114 PHCELL_INDEX Child
00115 );
00116
00117 LONG
00118
CmpCompareInIndex(
00119
PHHIVE Hive,
00120 PUNICODE_STRING SearchName,
00121 ULONG Count,
00122
PCM_KEY_INDEX Index,
00123 PHCELL_INDEX Child
00124 );
00125
00126 LONG
00127
CmpDoCompareKeyName(
00128
PHHIVE Hive,
00129 PUNICODE_STRING SearchName,
00130 HCELL_INDEX Cell
00131 );
00132
00133
HCELL_INDEX
00134
CmpDoFindSubKeyByNumber(
00135
PHHIVE Hive,
00136
PCM_KEY_INDEX Index,
00137 ULONG Number
00138 );
00139
00140
HCELL_INDEX
00141
CmpAddToLeaf(
00142
PHHIVE Hive,
00143 HCELL_INDEX LeafCell,
00144 HCELL_INDEX NewKey,
00145 PUNICODE_STRING NewName
00146 );
00147
00148
HCELL_INDEX
00149
CmpSelectLeaf(
00150
PHHIVE Hive,
00151
PCM_KEY_NODE ParentKey,
00152 PUNICODE_STRING NewName,
00153 HSTORAGE_TYPE Type,
00154 PHCELL_INDEX *RootPointer
00155 );
00156
00157
HCELL_INDEX
00158
CmpSplitLeaf(
00159
PHHIVE Hive,
00160 HCELL_INDEX RootCell,
00161 ULONG RootSelect,
00162 HSTORAGE_TYPE Type
00163 );
00164
00165
#ifdef ALLOC_PRAGMA
00166
#pragma alloc_text(PAGE,CmpFindSubKeyByName)
00167
#pragma alloc_text(PAGE,CmpFindSubKeyInRoot)
00168
#pragma alloc_text(PAGE,CmpFindSubKeyInLeaf)
00169
#pragma alloc_text(PAGE,CmpDoCompareKeyName)
00170
#pragma alloc_text(PAGE,CmpCompareInIndex)
00171
#pragma alloc_text(PAGE,CmpFindSubKeyByNumber)
00172
#pragma alloc_text(PAGE,CmpDoFindSubKeyByNumber)
00173
#pragma alloc_text(PAGE,CmpAddSubKey)
00174
#pragma alloc_text(PAGE,CmpAddToLeaf)
00175
#pragma alloc_text(PAGE,CmpSelectLeaf)
00176
#pragma alloc_text(PAGE,CmpSplitLeaf)
00177
#pragma alloc_text(PAGE,CmpMarkIndexDirty)
00178
#pragma alloc_text(PAGE,CmpRemoveSubKey)
00179
#endif
00180
00181 ULONG
CmpHintHits=0;
00182 ULONG
CmpHintMisses=0;
00183
00184
00185
HCELL_INDEX
00186 CmpFindSubKeyByName(
00187
PHHIVE Hive,
00188
PCM_KEY_NODE Parent,
00189 PUNICODE_STRING SearchName
00190 )
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
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
00223
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
00248
00249
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 }
00263
00264
00265 ULONG
00266 CmpFindSubKeyInRoot(
00267
PHHIVE Hive,
00268
PCM_KEY_INDEX Index,
00269 PUNICODE_STRING SearchName,
00270 PHCELL_INDEX Child
00271 )
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
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
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
00340
00341
00342 *Child = LeafCell;
00343
return CanCount;
00344 }
00345
00346
if (Result < 0) {
00347
00348
00349
00350
00351 Result =
CmpCompareInIndex(
Hive,
00352 SearchName,
00353 0,
00354 Leaf,
00355 Child);
00356
00357
if (Result >= 0) {
00358
00359
00360
00361
00362
00363
00364
00365 *Child = LeafCell;
00366
return CanCount;
00367 }
00368
00369 High = CanCount;
00370
00371 }
else {
00372
00373
00374
00375
00376 Low = CanCount;
00377 }
00378
00379
if ((High - Low) <= 1) {
00380
break;
00381 }
00382 }
00383
00384
00385
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
00400
00401 *Child = LeafCell;
00402
return Low;
00403 }
00404
00405
if (Result < 0) {
00406
00407
00408
00409
00410 Result =
CmpCompareInIndex(
Hive,
00411 SearchName,
00412 0,
00413 Leaf,
00414 Child);
00415
00416
if (Result >= 0) {
00417
00418
00419
00420
00421
00422
00423
00424 *Child = LeafCell;
00425
return Low;
00426 }
00427
00428
00429
00430
00431 *Child =
HCELL_NIL;
00432
return Low;
00433 }
00434
00435
00436
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
00449
00450 *Child = LeafCell;
00451
return High;
00452
00453 }
else if (Result < 0) {
00454
00455
00456
00457
00458
00459
00460
00461 *Child = LeafCell;
00462
return High;
00463
00464 }
00465
00466
00467
00468
00469 *Child =
HCELL_NIL;
00470
return High;
00471 }
00472
00473
00474 ULONG
00475 CmpFindSubKeyInLeaf(
00476
PHHIVE Hive,
00477
PCM_KEY_INDEX Index,
00478 ULONG HintIndex,
00479 PUNICODE_STRING SearchName,
00480 PHCELL_INDEX Child
00481 )
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
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
00540
00541 Result =
CmpCompareInIndex(
Hive,
00542 SearchName,
00543 CanCount,
00544
Index,
00545 Child);
00546
00547
if (Result == 0) {
00548
00549
00550
00551
00552
return CanCount;
00553 }
00554
00555
if (Result < 0) {
00556
00557
00558
00559
00560 High = CanCount;
00561
00562 }
else {
00563
00564
00565
00566
00567 Low = CanCount;
00568 }
00569
00570
if ((High - Low) <= 1) {
00571
break;
00572 }
00573 CanCount = ((High-Low)/2)+Low;
00574 }
00575
00576
00577
00578
00579
00580 Result =
CmpCompareInIndex(
Hive,
00581 SearchName,
00582 Low,
00583
Index,
00584 Child);
00585
if (Result == 0) {
00586
00587
00588
00589
00590
return Low;
00591 }
00592
00593
if (Result < 0) {
00594
00595
00596
00597
00598
return Low;
00599 }
00600
00601
00602
00603
00604
00605 Result =
CmpCompareInIndex(
Hive,
00606 SearchName,
00607 High,
00608
Index,
00609 Child);
00610
return High;
00611 }
00612
00613
00614 LONG
00615 CmpCompareInIndex(
00616
PHHIVE Hive,
00617 PUNICODE_STRING SearchName,
00618 ULONG Count,
00619
PCM_KEY_INDEX Index,
00620 PHCELL_INDEX Child
00621 )
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
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
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
00694
00695
00696
return(Result);
00697 }
00698 }
00699
00700
00701
00702
00703
00704 Result =
CmpDoCompareKeyName(
Hive,SearchName,FastIndex->
List[
Count].Cell);
00705
if (Result == 0) {
00706 *Child = Hint->
Cell;
00707 }
00708 }
else {
00709
00710
00711
00712 Result =
CmpDoCompareKeyName(
Hive,SearchName,
Index->List[
Count]);
00713
if (Result == 0) {
00714 *Child =
Index->List[
Count];
00715 }
00716 }
00717
return(Result);
00718 }
00719
00720
00721 LONG
00722 CmpDoCompareKeyName(
00723
PHHIVE Hive,
00724 PUNICODE_STRING SearchName,
00725 HCELL_INDEX Cell
00726 )
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
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 }
00768
00769
00770
HCELL_INDEX
00771 CmpFindSubKeyByNumber(
00772
PHHIVE Hive,
00773
PCM_KEY_NODE Node,
00774 ULONG Number
00775 )
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
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
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
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
00827
00828
return HCELL_NIL;
00829 }
00830
00831
00832
HCELL_INDEX
00833 CmpDoFindSubKeyByNumber(
00834
PHHIVE Hive,
00835
PCM_KEY_INDEX Index,
00836 ULONG Number
00837 )
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
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
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 }
00892
00893
00894 BOOLEAN
00895 CmpAddSubKey(
00896
PHHIVE Hive,
00897 HCELL_INDEX Parent,
00898 HCELL_INDEX Child
00899 )
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
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
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
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
00994
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
01007
01008 WorkCell =
HvAllocateCell(
01009
Hive,
01010
sizeof(
CM_KEY_INDEX) +
sizeof(
HCELL_INDEX),
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
01030
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
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 }
01084
01085
01086
HCELL_INDEX
01087 CmpAddToLeaf(
01088
PHHIVE Hive,
01089 HCELL_INDEX LeafCell,
01090 HCELL_INDEX NewKey,
01091 PUNICODE_STRING NewName
01092 )
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
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
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
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
01181
01182 Select =
CmpFindSubKeyInLeaf(
Hive, Leaf, (ULONG)-1,
NewName, &Child);
01183
ASSERT(Child ==
HCELL_NIL);
01184
01185
01186
01187
01188
01189
01190
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
01203
01204
01205
if (Result > 0) {
01206 Select++;
01207 }
01208
01209
if (Select != Leaf->
Count) {
01210
01211
01212
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
01241
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 }
01254
01255
01256
HCELL_INDEX
01257 CmpSelectLeaf(
01258
PHHIVE Hive,
01259
PCM_KEY_NODE ParentKey,
01260 PUNICODE_STRING NewName,
01261 HSTORAGE_TYPE Type,
01262 PHCELL_INDEX *RootPointer
01263 )
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
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
01312
01313
01314
01315
if (!
HvMarkCellDirty(
Hive, ParentKey->
SubKeyLists[Type])) {
01316
return HCELL_NIL;
01317 }
01318
01319
01320
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
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
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
01363
01364
if (RootSelect > 0) {
01365
01366
01367
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
01381
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
01393
01394
01395 }
else {
01396
01397
01398
01399
01400
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
01412
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
01427
01428 }
01429
01430 }
else {
01431
01432
01433
01434
01435
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
01446
01447 }
01448
01449
01450
01451
01452 WorkCell =
CmpSplitLeaf(
01453
Hive,
01454 ParentKey->
SubKeyLists[Type],
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 }
01467
return LeafCell;
01468 }
01469
01470
01471
HCELL_INDEX
01472 CmpSplitLeaf(
01473
PHHIVE Hive,
01474 HCELL_INDEX RootCell,
01475 ULONG RootSelect,
01476 HSTORAGE_TYPE Type
01477 )
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
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
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);
01531 NewCount = (OldCount - KeepCount);
01532
01533
Size = (
sizeof(
HCELL_INDEX) * NewCount) +
01534 FIELD_OFFSET(
CM_KEY_INDEX,
List) + 1;
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
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
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
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
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
01600
01601 Root->
Count += 1;
01602 Root->
List[RootSelect+1] = NewLeafCell;
01603
return RootCell;
01604 }
01605
01606
01607 BOOLEAN
01608 CmpMarkIndexDirty(
01609
PHHIVE Hive,
01610 HCELL_INDEX ParentKey,
01611 HCELL_INDEX TargetKey
01612 )
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
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
01676
01677
CmpFindSubKeyInRoot(
Hive,
Index, &SearchName, &Child);
01678
if (Child ==
HCELL_NIL) {
01679
continue;
01680 }
01681
01682
01683
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 }
01711
01712
01713 BOOLEAN
01714 CmpRemoveSubKey(
01715
PHHIVE Hive,
01716 HCELL_INDEX ParentKey,
01717 HCELL_INDEX TargetKey
01718 )
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
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
01810
01811
01812
01813 pcell->
SubKeyCounts[Type] -= 1;
01814
01815 Leaf->
Count -= 1;
01816
if (Leaf->
Count == 0) {
01817
01818
01819
01820
01821
HvFreeCell(
Hive, LeafCell);
01822
01823
if (Root !=
NULL) {
01824
01825 Root->
Count -= 1;
01826
if (Root->
Count == 0) {
01827
01828
01829
01830
01831
HvFreeCell(
Hive, RootCell);
01832 pcell->
SubKeyLists[Type] =
HCELL_NIL;
01833
01834 }
else if (RootSelect < (ULONG)(Root->
Count)) {
01835
01836
01837
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
01847
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
01871
01872
01873
if ((IsCompressed) &&
01874 (SearchName.MaximumLength >
sizeof(CompressedBuffer))) {
01875 (
Hive->
Free)(SearchName.Buffer, SearchName.Length);
01876 }
01877
return TRUE;
01878 }