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
#include "cmp.h"
00026
00027
00028
00029
00030
00031 #define DEBUG_TREE_SYNC FALSE
00032
00033
00034
00035
00036
00037
00038 #define CMP_INITIAL_STACK_SIZE 1024 // ENTRIES
00039
00040 typedef struct {
00041 HCELL_INDEX SourceCell;
00042 HCELL_INDEX TargetCell;
00043 ULONG i;
00044 }
CMP_COPY_STACK_ENTRY, *
PCMP_COPY_STACK_ENTRY;
00045
00046 BOOLEAN
00047
CmpCopySyncTree2(
00048 PCMP_COPY_STACK_ENTRY CmpCopyStack,
00049 ULONG CmpCopyStackSize,
00050 ULONG CmpCopyStackTop,
00051
PHHIVE CmpSourceHive,
00052
PHHIVE CmpTargetHive,
00053 BOOLEAN CopyVolatile,
00054 CMP_COPY_TYPE CopyType
00055 );
00056
00057 BOOLEAN
00058
CmpFreeKeyValues(
00059
PHHIVE Hive,
00060 HCELL_INDEX Cell,
00061
PCM_KEY_NODE Node
00062 );
00063
00064 BOOLEAN
00065
CmpSyncKeyValues(
00066
PHHIVE SourceHive,
00067 HCELL_INDEX SourceKeyCell,
00068
PCM_KEY_NODE SourceKeyNode,
00069
PHHIVE TargetHive,
00070 HCELL_INDEX TargetKeyCell,
00071
PCM_KEY_NODE TargetKeyNode
00072 );
00073
00074 BOOLEAN
00075
CmpMergeKeyValues(
00076
PHHIVE SourceHive,
00077 HCELL_INDEX SourceKeyCell,
00078
PCM_KEY_NODE SourceKeyNode,
00079
PHHIVE TargetHive,
00080 HCELL_INDEX TargetKeyCell,
00081
PCM_KEY_NODE TargetKeyNode
00082 );
00083
00084
00085 BOOLEAN
00086
CmpSyncSubKeysAfterDelete(
00087
PHHIVE SourceHive,
00088
PCM_KEY_NODE SourceCell,
00089
PHHIVE TargetHive,
00090
PCM_KEY_NODE TargetCell,
00091 WCHAR *NameBuffer);
00092
00093 BOOLEAN
00094
CmpMarkKeyValuesDirty(
00095
PHHIVE Hive,
00096 HCELL_INDEX Cell,
00097
PCM_KEY_NODE Node
00098 );
00099
00100 BOOLEAN
00101
CmpMarkKeyParentDirty(
00102
PHHIVE Hive,
00103 HCELL_INDEX Cell
00104 );
00105
00106
#ifdef ALLOC_PRAGMA
00107
#pragma alloc_text(PAGE,CmpCopySyncTree)
00108
#pragma alloc_text(PAGE,CmpCopySyncTree2)
00109
#pragma alloc_text(PAGE,CmpCopyKeyPartial)
00110
#pragma alloc_text(PAGE,CmpCopyValue)
00111
#pragma alloc_text(PAGE,CmpCopyCell)
00112
#pragma alloc_text(PAGE,CmpFreeKeyValues)
00113
#pragma alloc_text(PAGE,CmpSyncKeyValues)
00114
#pragma alloc_text(PAGE,CmpMergeKeyValues)
00115
#pragma alloc_text(PAGE,CmpInitializeKeyNameString)
00116
#pragma alloc_text(PAGE,CmpInitializeValueNameString)
00117
#pragma alloc_text(PAGE,CmpSyncSubKeysAfterDelete)
00118
#pragma alloc_text(PAGE,CmpMarkKeyValuesDirty)
00119
#pragma alloc_text(PAGE,CmpMarkKeyParentDirty)
00120
#endif
00121
00122
00123
00124
00125
00126 BOOLEAN
00127 CmpCopySyncTree(
00128
PHHIVE SourceHive,
00129 HCELL_INDEX SourceCell,
00130
PHHIVE TargetHive,
00131 HCELL_INDEX TargetCell,
00132 BOOLEAN CopyVolatile,
00133 CMP_COPY_TYPE CopyType
00134 )
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 {
00214 BOOLEAN result;
00215
PCMP_COPY_STACK_ENTRY CmpCopyStack;
00216
00217
CMLOG(
CML_MAJOR,
CMS_SAVRES) {
00218 KdPrint((
"CmpCopyTree:\n"));
00219 }
00220
00221 CmpCopyStack =
ExAllocatePool(
00222
PagedPool,
00223
sizeof(
CMP_COPY_STACK_ENTRY)*
CMP_INITIAL_STACK_SIZE
00224 );
00225
if (CmpCopyStack ==
NULL) {
00226
return FALSE;
00227 }
00228 CmpCopyStack[0].SourceCell = SourceCell;
00229 CmpCopyStack[0].TargetCell = TargetCell;
00230
00231 result =
CmpCopySyncTree2(
00232 CmpCopyStack,
00233
CMP_INITIAL_STACK_SIZE,
00234 0,
00235 SourceHive,
00236 TargetHive,
00237 CopyVolatile,
00238 CopyType
00239 );
00240
00241
ExFreePool(CmpCopyStack);
00242
return result;
00243 }
00244
00245
00246
00247
00248
00249
00250 BOOLEAN
00251 CmpCopySyncTree2(
00252 PCMP_COPY_STACK_ENTRY CmpCopyStack,
00253 ULONG CmpCopyStackSize,
00254 ULONG CmpCopyStackTop,
00255
PHHIVE CmpSourceHive,
00256
PHHIVE CmpTargetHive,
00257 BOOLEAN CopyVolatile,
00258 CMP_COPY_TYPE CopyType
00259 )
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
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
PCMP_COPY_STACK_ENTRY Frame;
00296
HCELL_INDEX SourceChild;
00297
HCELL_INDEX NewSubKey;
00298
00299 BOOLEAN Ret =
FALSE, SyncNeedsTreeCopy =
FALSE;
00300 UNICODE_STRING
KeyName;
00301
PCM_KEY_NODE SourceChildCell, TargetChildCell;
00302
PCM_KEY_NODE SourceCell, TargetCell;
00303 ULONG SyncTreeCopyStackStart;
00304 WCHAR *NameBuffer =
NULL;
00305
00306
00307 BOOLEAN TreeSync = (CopyType ==
Sync || CopyType ==
Merge)?
TRUE:
FALSE;
00308
00309
CMLOG(
CML_MINOR,
CMS_SAVRES) {
00310 KdPrint((
"CmpCopyTree2:\n"));
00311 }
00312
00313
if (TreeSync) {
00314
00315
00316
00317
00318
00319
00320 NameBuffer =
ExAllocatePool(
PagedPool,
MAX_KEY_NAME_LENGTH);
00321
if(!NameBuffer)
return FALSE;
00322
00323 }
00324
00325
00326
00327
00328
00329 Outer:
while (
TRUE) {
00330
00331 Frame = &(CmpCopyStack[CmpCopyStackTop]);
00332
00333 Frame->i = 0;
00334
00335
00336
00337
00338
00339 Inner:
while (
TRUE) {
00340
00341 SourceCell = (
PCM_KEY_NODE)
HvGetCell(CmpSourceHive, Frame->SourceCell);
00342
00343 SourceChild =
CmpFindSubKeyByNumber(CmpSourceHive,
00344 SourceCell,
00345 Frame->i);
00346 (Frame->i)++;
00347
00348
if ((SourceChild ==
HCELL_NIL) || (!CopyVolatile &&
00349 (
HvGetCellType(SourceChild) ==
Volatile))) {
00350
00351
00352
00353
00354
00355
00356
00357
if(TreeSync && (CopyType !=
Merge))
00358 {
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 TargetCell = (
PCM_KEY_NODE)
HvGetCell(CmpTargetHive, Frame->TargetCell);
00382
00383
00384
00385
00386
00387
if((TargetCell->
SubKeyCounts[
Stable] +
00388 TargetCell->
SubKeyCounts[
Volatile]) >
00389 (SourceCell->
SubKeyCounts[
Stable] +
00390
00391
00392
00393
00394
00395
00396 (CopyVolatile ? SourceCell->
SubKeyCounts[
Volatile] : 0)))
00397
00398 {
00399
#if DEBUG_TREE_SYNC
00400
KdPrint((
"CONFIG: SubKey Deletion from Source Cell #%lu.\n",
00401 Frame->SourceCell));
00402
#endif
00403
00404
00405
00406
00407
00408
CmpSyncSubKeysAfterDelete(CmpSourceHive,
00409 SourceCell,
00410 CmpTargetHive,
00411 TargetCell,
00412 NameBuffer);
00413 }
00414 }
00415
00416
break;
00417 }
00418
00419
if (TreeSync) {
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 SourceChildCell = (
PCM_KEY_NODE)
HvGetCell(CmpSourceHive,
00436 SourceChild);
00437
00438
CmpInitializeKeyNameString(SourceChildCell,
00439 &
KeyName,
00440 NameBuffer);
00441
00442
00443
00444
00445
00446
00447 NewSubKey =
CmpFindSubKeyByName(CmpTargetHive,
00448 (
PCM_KEY_NODE)
HvGetCell(CmpTargetHive,
00449 Frame->TargetCell),
00450 &
KeyName);
00451
00452
00453
if (NewSubKey !=
HCELL_NIL) {
00454
00455
00456
00457
00458
00459
00460
00461
00462 TargetChildCell = (
PCM_KEY_NODE)
HvGetCell(CmpTargetHive,
00463 NewSubKey);
00464
00465
00466
00467
00468
00469
00470
00471
if ( (CopyType ==
Merge) ||
00472 ((TargetChildCell->
LastWriteTime.QuadPart) <
00473 (SourceChildCell->
LastWriteTime.QuadPart))) {
00474
00475
00476
00477
00478
00479
#if DEBUG_TREE_SYNC
00480
KdPrint((
"CONFIG: Target Refresh.\n"));
00481 KdPrint((
"CONFIG: Source Cell %lu = %.*S\n",
00482 SourceChild,
00483
KeyName.Length /
sizeof(WCHAR),
00484
KeyName.Buffer));
00485
#endif
00486
00487
00488
00489
00490
00491
if(CopyType ==
Merge) {
00492
if(!
CmpMergeKeyValues(CmpSourceHive, SourceChild, SourceChildCell,
00493 CmpTargetHive, NewSubKey, TargetChildCell)) {
00494
goto CopyEnd;
00495 }
00496 }
else {
00497
if(!
CmpSyncKeyValues(CmpSourceHive, SourceChild, SourceChildCell,
00498 CmpTargetHive, NewSubKey, TargetChildCell)) {
00499
goto CopyEnd;
00500 }
00501 }
00502
00503
00504
00505
00506
00507 TargetChildCell->
LastWriteTime.QuadPart =
00508 SourceChildCell->
LastWriteTime.QuadPart;
00509
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
goto NewKeyCreated;
00521
00522 }
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
#if DEBUG_TREE_SYNC
00538
KdPrint((
"CONFIG: New SubKey.\n"));
00539 KdPrint((
"CONFIG: Source Cell %lu = %.*S\n",
00540 SourceChild,
00541
KeyName.Length /
sizeof(WCHAR),
00542
KeyName.Buffer));
00543
#endif
00544
00545
00546
00547
00548
00549 SyncNeedsTreeCopy =
TRUE;
00550
00551 }
00552
00553 NewSubKey =
CmpCopyKeyPartial(
00554 CmpSourceHive,
00555 SourceChild,
00556 CmpTargetHive,
00557 Frame->TargetCell,
00558
TRUE
00559 );
00560
00561
00562
if (NewSubKey ==
HCELL_NIL) {
00563
00564
goto CopyEnd;
00565 }
00566
00567
if ( !
CmpAddSubKey(
00568 CmpTargetHive,
00569 Frame->TargetCell,
00570 NewSubKey
00571 )
00572 ) {
00573
00574
goto CopyEnd;
00575 }
00576
00577
00578
00579
00580
00581
00582
if(TreeSync && SyncNeedsTreeCopy) {
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
if (!
CmpMarkKeyParentDirty(CmpTargetHive, NewSubKey)) {
00594
00595
goto CopyEnd;
00596 }
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606 SyncTreeCopyStackStart = CmpCopyStackTop;
00607
00608
00609
00610
00611
00612
00613 TreeSync =
FALSE;
00614 }
00615
00616 NewKeyCreated:
00617
00618
00619
00620
00621
00622 CmpCopyStackTop++;
00623
00624
if (CmpCopyStackTop >= CmpCopyStackSize) {
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
goto CopyEnd;
00635 }
00636
00637 CmpCopyStack[CmpCopyStackTop].SourceCell =
00638 SourceChild;
00639
00640 CmpCopyStack[CmpCopyStackTop].TargetCell =
00641 NewSubKey;
00642
00643
goto Outer;
00644
00645
00646 }
00647
00648
if (CmpCopyStackTop == 0) {
00649 Ret =
TRUE;
00650
goto CopyEnd;
00651 }
00652
00653 CmpCopyStackTop--;
00654 Frame = &(CmpCopyStack[CmpCopyStackTop]);
00655
00656
00657
00658
00659
00660
00661
00662
if(SyncNeedsTreeCopy && (CmpCopyStackTop == SyncTreeCopyStackStart))
00663 {
00664
00665
00666
00667
00668
00669 TreeSync =
TRUE;
00670 SyncNeedsTreeCopy =
FALSE;
00671 }
00672
00673
00674
goto Inner;
00675
00676 }
00677
00678 CopyEnd:
00679
00680
if (NameBuffer)
ExFreePool(NameBuffer);
00681
return Ret;
00682 }
00683
00684
00685
HCELL_INDEX
00686 CmpCopyKeyPartial(
00687
PHHIVE SourceHive,
00688 HCELL_INDEX SourceKeyCell,
00689
PHHIVE TargetHive,
00690 HCELL_INDEX Parent,
00691 BOOLEAN CopyValues
00692 )
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718 {
00719
NTSTATUS status;
00720
HCELL_INDEX newkey =
HCELL_NIL;
00721
HCELL_INDEX newclass =
HCELL_NIL;
00722
HCELL_INDEX newsecurity =
HCELL_NIL;
00723
HCELL_INDEX newlist =
HCELL_NIL;
00724
HCELL_INDEX newvalue;
00725 BOOLEAN success =
FALSE;
00726 ULONG i;
00727
PCELL_DATA psrckey;
00728
PCM_KEY_NODE ptarkey;
00729
PCELL_DATA psrclist;
00730
PCELL_DATA ptarlist;
00731
PCELL_DATA psrcsecurity;
00732
HCELL_INDEX security;
00733
HCELL_INDEX class;
00734 ULONG classlength;
00735 ULONG count;
00736 ULONG Type;
00737
00738
CMLOG(
CML_MINOR,
CMS_SAVRES) {
00739 KdPrint((
"CmpCopyKeyPartial:\n"));
00740 KdPrint((
"\tSHive=%08lx SCell=%08lx\n",SourceHive,SourceKeyCell));
00741 KdPrint((
"\tTHive=%08lx\n",TargetHive));
00742 }
00743
00744
00745
00746
00747
00748
if (Parent ==
HCELL_NIL) {
00749
00750
00751
00752 Type =
Stable;
00753 }
else {
00754 Type =
HvGetCellType(Parent);
00755 }
00756 psrckey =
HvGetCell(SourceHive, SourceKeyCell);
00757 security = psrckey->
u.
KeyNode.
Security;
00758
class = psrckey->u.KeyNode.Class;
00759 classlength = psrckey->
u.
KeyNode.
ClassLength;
00760
00761
00762
00763
00764 newkey =
CmpCopyCell(SourceHive, SourceKeyCell, TargetHive, Type);
00765
if (newkey ==
HCELL_NIL) {
00766
goto DoFinally;
00767 }
00768
00769
00770
00771
00772
if (classlength > 0) {
00773 newclass =
CmpCopyCell(SourceHive,
class, TargetHive, Type);
00774
if (newclass ==
HCELL_NIL) {
00775
goto DoFinally;
00776 }
00777 }
00778
00779
00780
00781
00782 ptarkey = (
PCM_KEY_NODE)
HvGetCell(TargetHive, newkey);
00783
00784 ptarkey->
Class = newclass;
00785 ptarkey->
Security =
HCELL_NIL;
00786 ptarkey->
SubKeyLists[
Stable] =
HCELL_NIL;
00787 ptarkey->
SubKeyLists[
Volatile] =
HCELL_NIL;
00788 ptarkey->
SubKeyCounts[
Stable] = 0;
00789 ptarkey->
SubKeyCounts[
Volatile] = 0;
00790 ptarkey->
Parent = Parent;
00791
00792 ptarkey->
Flags = (psrckey->
u.
KeyNode.
Flags &
KEY_COMP_NAME);
00793
if (Parent ==
HCELL_NIL) {
00794 ptarkey->
Flags |=
KEY_HIVE_ENTRY +
KEY_NO_DELETE;
00795 }
00796
00797
00798
00799
00800 psrcsecurity =
HvGetCell(SourceHive, security);
00801
00802 status =
CmpAssignSecurityDescriptor(TargetHive,
00803 newkey,
00804 ptarkey,
00805 &(psrcsecurity->
u.
KeySecurity.
Descriptor));
00806
if (!
NT_SUCCESS(status)) {
00807
goto DoFinally;
00808 }
00809
00810
00811
00812
00813
00814 count = psrckey->
u.
KeyNode.
ValueList.
Count;
00815
00816
if ((count == 0) || (CopyValues ==
FALSE)) {
00817 ptarkey->
ValueList.
List =
HCELL_NIL;
00818 ptarkey->
ValueList.
Count = 0;
00819 success =
TRUE;
00820 }
else {
00821
00822 psrclist =
HvGetCell(SourceHive, psrckey->
u.
KeyNode.
ValueList.
List);
00823
00824 newlist =
HvAllocateCell(
00825 TargetHive,
00826 count *
sizeof(
HCELL_INDEX),
00827 Type
00828 );
00829
if (newlist ==
HCELL_NIL) {
00830
goto DoFinally;
00831 }
00832 ptarkey->
ValueList.
List = newlist;
00833 ptarlist =
HvGetCell(TargetHive, newlist);
00834
00835
00836
00837
00838
00839
for (i = 0; i < count; i++) {
00840
00841 newvalue =
CmpCopyValue(
00842 SourceHive,
00843 psrclist->
u.
KeyList[i],
00844 TargetHive,
00845 Type
00846 );
00847
00848
if (newvalue !=
HCELL_NIL) {
00849
00850 ptarlist->
u.
KeyList[i] = newvalue;
00851
00852 }
else {
00853
00854
for (; i > 0; i--) {
00855
HvFreeCell(
00856 TargetHive,
00857 ptarlist->
u.
KeyList[i - 1]
00858 );
00859 }
00860
goto DoFinally;
00861 }
00862 }
00863 success =
TRUE;
00864 }
00865
00866 DoFinally:
00867
if (success ==
FALSE) {
00868
00869
if (newlist !=
HCELL_NIL) {
00870
HvFreeCell(TargetHive, newlist);
00871 }
00872
00873
if (newsecurity !=
HCELL_NIL) {
00874
HvFreeCell(TargetHive, newsecurity);
00875 }
00876
00877
if (newclass !=
HCELL_NIL) {
00878
HvFreeCell(TargetHive, newclass);
00879 }
00880
00881
if (newkey !=
HCELL_NIL) {
00882
HvFreeCell(TargetHive, newkey);
00883 }
00884
00885
return HCELL_NIL;
00886
00887 }
else {
00888
00889
return newkey;
00890 }
00891 }
00892
00893
00894
HCELL_INDEX
00895 CmpCopyValue(
00896
PHHIVE SourceHive,
00897 HCELL_INDEX SourceValueCell,
00898
PHHIVE TargetHive,
00899 HSTORAGE_TYPE Type
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
HCELL_INDEX newvalue;
00926
HCELL_INDEX newdata;
00927
PCELL_DATA pvalue;
00928 ULONG datalength;
00929
HCELL_INDEX olddata;
00930 ULONG tempdata;
00931 BOOLEAN small;
00932
00933
CMLOG(
CML_MINOR,
CMS_SAVRES) {
00934 KdPrint((
"CmpCopyValue:\n"));
00935 KdPrint((
"\tSHive=%08lx SCell=%08lx\n",SourceHive,SourceValueCell));
00936 KdPrint((
"\tTargetHive=%08lx\n",TargetHive));
00937 }
00938
00939
00940
00941
00942 pvalue =
HvGetCell(SourceHive, SourceValueCell);
00943 small =
CmpIsHKeyValueSmall(datalength, pvalue->
u.
KeyValue.
DataLength);
00944 olddata = pvalue->
u.
KeyValue.
Data;
00945
00946
00947
00948
00949 newvalue =
CmpCopyCell(SourceHive, SourceValueCell, TargetHive, Type);
00950
if (newvalue ==
HCELL_NIL) {
00951
return HCELL_NIL;
00952 }
00953
00954
00955
00956
00957
if (datalength > 0) {
00958
00959
if (datalength >
CM_KEY_VALUE_SMALL) {
00960
00961
00962
00963
00964 newdata =
CmpCopyCell(SourceHive, olddata, TargetHive, Type);
00965
00966
if (newdata ==
HCELL_NIL) {
00967
HvFreeCell(TargetHive, newvalue);
00968
return HCELL_NIL;
00969 }
00970
00971 pvalue =
HvGetCell(TargetHive, newvalue);
00972 pvalue->
u.
KeyValue.
Data = newdata;
00973 pvalue->
u.
KeyValue.
DataLength = datalength;
00974
00975 }
else {
00976
00977
00978
00979
00980
00981
if (small) {
00982
00983
00984
00985
00986 tempdata = pvalue->
u.
KeyValue.
Data;
00987
00988 }
else {
00989
00990
00991
00992
00993 pvalue =
HvGetCell(SourceHive, pvalue->
u.
KeyValue.
Data);
00994 tempdata = *((PULONG)pvalue);
00995 }
00996 pvalue =
HvGetCell(TargetHive, newvalue);
00997 pvalue->
u.
KeyValue.
Data = tempdata;
00998 pvalue->
u.
KeyValue.
DataLength =
00999 datalength +
CM_KEY_VALUE_SPECIAL_SIZE;
01000
01001 }
01002 }
01003
01004
return newvalue;
01005 }
01006
01007
01008
HCELL_INDEX
01009 CmpCopyCell(
01010
PHHIVE SourceHive,
01011 HCELL_INDEX SourceCell,
01012
PHHIVE TargetHive,
01013 HSTORAGE_TYPE Type
01014 )
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036 {
01037 PVOID psource;
01038 PVOID ptarget;
01039 ULONG size;
01040
HCELL_INDEX newcell;
01041
01042
CMLOG(
CML_MINOR,
CMS_SAVRES) {
01043 KdPrint((
"CmpCopyCell:\n"));
01044 KdPrint((
"\tSourceHive=%08lx SourceCell=%08lx\n",SourceHive,SourceCell));
01045 KdPrint((
"\tTargetHive=%08lx\n",TargetHive));
01046 }
01047
01048 psource =
HvGetCell(SourceHive, SourceCell);
01049 size =
HvGetCellSize(SourceHive, psource);
01050
01051 newcell =
HvAllocateCell(TargetHive, size, Type);
01052
if (newcell ==
HCELL_NIL) {
01053
return HCELL_NIL;
01054 }
01055
01056 ptarget =
HvGetCell(TargetHive, newcell);
01057
01058 RtlCopyMemory(ptarget, psource, size);
01059
01060
return newcell;
01061 }
01062
01063 BOOLEAN
01064 CmpFreeKeyValues(
01065
PHHIVE Hive,
01066 HCELL_INDEX Cell,
01067
PCM_KEY_NODE Node
01068 )
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087 {
01088
PCELL_DATA plist;
01089 ULONG i;
01090
01091
01092
01093
01094
01095
if (!
CmpMarkKeyValuesDirty(
Hive,
Cell, Node)) {
01096
return FALSE;
01097 }
01098
01099
01100
01101
01102
01103
if (!(Node->
Flags &
KEY_HIVE_EXIT)) {
01104
01105
01106
01107
01108
if (Node->
ValueList.
Count > 0) {
01109
01110
01111 plist =
HvGetCell(
Hive, Node->
ValueList.
List);
01112
01113
01114
for (i = 0; i < Node->
ValueList.
Count; i++) {
01115
CmpFreeValue(
Hive, plist->
u.
KeyList[i]);
01116 }
01117
01118
01119
HvFreeCell(
Hive, Node->
ValueList.
List);
01120 }
01121
01122
01123
01124
01125
01126 Node->
ValueList.
List =
HCELL_NIL;
01127 Node->
ValueList.
Count = 0;
01128
01129
01130
01131
01132
CmpFreeSecurityDescriptor(
Hive,
Cell);
01133
01134
01135
01136
01137
01138
if (Node->
ClassLength > 0) {
01139
HvFreeCell(
Hive, Node->
Class);
01140 Node->
Class =
HCELL_NIL;
01141 Node->
ClassLength = 0;
01142 }
01143
01144 }
01145
01146
return TRUE;
01147 }
01148
01149 BOOLEAN
01150 CmpMergeKeyValues(
01151
PHHIVE SourceHive,
01152 HCELL_INDEX SourceKeyCell,
01153
PCM_KEY_NODE SourceKeyNode,
01154
PHHIVE TargetHive,
01155 HCELL_INDEX TargetKeyCell,
01156
PCM_KEY_NODE TargetKeyNode
01157 )
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183 {
01184
NTSTATUS status;
01185 BOOLEAN success =
FALSE;
01186
PCELL_DATA psrclist, ptarlist;
01187
HCELL_INDEX newvalue, newlist =
HCELL_NIL;
01188 ULONG i, count, Type;
01189
PCM_KEY_VALUE poldvalue;
01190 WCHAR *NameBuffer =
NULL;
01191 UNICODE_STRING
ValueName;
01192
01193
01194
if(TargetKeyNode->
MaxValueNameLen < SourceKeyNode->
MaxValueNameLen) {
01195 TargetKeyNode->
MaxValueNameLen = SourceKeyNode->
MaxValueNameLen;
01196 }
01197
01198
if(TargetKeyNode->
MaxValueDataLen < SourceKeyNode->
MaxValueDataLen) {
01199 TargetKeyNode->
MaxValueDataLen = SourceKeyNode->
MaxValueDataLen;
01200 }
01201
01202
if(TargetKeyNode->
ValueList.
Count == 0) {
01203
01204
01205
01206
return CmpSyncKeyValues(SourceHive, SourceKeyCell, SourceKeyNode, TargetHive, TargetKeyCell, TargetKeyNode);
01207 }
01208
01209
01210
01211 count = SourceKeyNode->
ValueList.
Count;
01212
01213
if (count == 0) {
01214
01215
01216 success =
TRUE;
01217 }
else {
01218
01219 NameBuffer =
ExAllocatePool(
PagedPool,
MAX_KEY_VALUE_NAME_LENGTH);
01220
if(!NameBuffer)
return FALSE;
01221
01222
01223
01224
01225
01226
01227 Type =
HvGetCellType(TargetKeyCell);
01228
01229
01230
01231
01232
01233
01234
01235 psrclist =
HvGetCell(SourceHive, SourceKeyNode->
ValueList.
List);
01236
01237 newlist =
HvReallocateCell(
01238 TargetHive,
01239 TargetKeyNode->
ValueList.
List,
01240 (TargetKeyNode->
ValueList.
Count + count) *
sizeof(
HCELL_INDEX)
01241 );
01242
01243
01244
if (newlist ==
HCELL_NIL) {
01245
goto EndValueMerge;
01246 }
01247 TargetKeyNode->
ValueList.
List = newlist;
01248 ptarlist =
HvGetCell(TargetHive, newlist);
01249
01250
01251
01252
01253
01254
for (i = 0; i < count; i++) {
01255
01256 poldvalue = (
PCM_KEY_VALUE)
HvGetCell(SourceHive, psrclist->
u.
KeyList[i]);
01257
01258
01259
01260
01261
CmpInitializeValueNameString(poldvalue,&
ValueName,NameBuffer);
01262
01263
01264
01265
01266
01267
if(
HCELL_NIL ==
CmpFindNameInList(TargetHive,&(TargetKeyNode->
ValueList),&
ValueName,
NULL,
NULL)) {
01268
01269
01270
01271
01272 newvalue =
CmpCopyValue(
01273 SourceHive,
01274 psrclist->
u.
KeyList[i],
01275 TargetHive,
01276 Type
01277 );
01278
01279
if (newvalue !=
HCELL_NIL) {
01280
01281 ptarlist->
u.
KeyList[TargetKeyNode->
ValueList.
Count++] = newvalue;
01282
01283 }
else {
01284
01285
01286
01287
for (; i > 0; i--) {
01288
HvFreeCell(
01289 TargetHive,
01290 ptarlist->
u.
KeyList[--TargetKeyNode->
ValueList.
Count]
01291 );
01292 }
01293
goto EndValueMerge;
01294 }
01295 }
01296 }
01297
01298
01299
01300
01301
01302 newlist =
HvReallocateCell(
01303 TargetHive,
01304 TargetKeyNode->
ValueList.
List,
01305 TargetKeyNode->
ValueList.
Count *
sizeof(
HCELL_INDEX)
01306 );
01307
01308
ASSERT(newlist !=
HCELL_NIL);
01309 TargetKeyNode->
ValueList.
List = newlist;
01310
01311 success =
TRUE;
01312 }
01313
01314 EndValueMerge:
01315
if (NameBuffer)
ExFreePool(NameBuffer);
01316
01317
if (success ==
FALSE) {
01318
01319
01320
01321
if (newlist !=
HCELL_NIL) {
01322 newlist =
HvReallocateCell(
01323 TargetHive,
01324 TargetKeyNode->
ValueList.
List,
01325 TargetKeyNode->
ValueList.
Count *
sizeof(
HCELL_INDEX)
01326 );
01327
01328
ASSERT(newlist !=
HCELL_NIL);
01329 TargetKeyNode->
ValueList.
List = newlist;
01330 }
01331
01332 }
01333
01334
return success;
01335 }
01336
01337 BOOLEAN
01338 CmpSyncKeyValues(
01339
PHHIVE SourceHive,
01340 HCELL_INDEX SourceKeyCell,
01341
PCM_KEY_NODE SourceKeyNode,
01342
PHHIVE TargetHive,
01343 HCELL_INDEX TargetKeyCell,
01344
PCM_KEY_NODE TargetKeyNode
01345 )
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369 {
01370
NTSTATUS status;
01371 BOOLEAN success =
FALSE;
01372
PCELL_DATA psrclist, ptarlist, psrcsecurity;
01373
HCELL_INDEX newvalue, newlist =
HCELL_NIL, newclass =
HCELL_NIL, newsecurity =
HCELL_NIL;
01374 ULONG i, count, Type;
01375
01376
01377
01378
01379
01380
if(!
CmpFreeKeyValues(TargetHive, TargetKeyCell, TargetKeyNode))
01381
return FALSE;
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392 Type =
HvGetCellType(TargetKeyCell);
01393
01394
01395
01396
01397
if ((SourceKeyNode->
ClassLength > 0) && (SourceKeyNode->
Class !=
HCELL_NIL)) {
01398 newclass =
CmpCopyCell(SourceHive, SourceKeyNode->
Class, TargetHive, Type);
01399
if (newclass ==
HCELL_NIL) {
01400
goto EndValueSync;
01401 }
01402
01403
01404 TargetKeyNode->
ClassLength = SourceKeyNode->
ClassLength;
01405 }
01406
01407
01408
01409
01410
01411
01412 TargetKeyNode->
Class = newclass;
01413 TargetKeyNode->
Security =
HCELL_NIL;
01414
01415
01416
01417
01418 psrcsecurity =
HvGetCell(SourceHive, SourceKeyNode->
Security);
01419
01420 status =
CmpAssignSecurityDescriptor(TargetHive,
01421 TargetKeyCell,
01422 TargetKeyNode,
01423 &(psrcsecurity->
u.
KeySecurity.
Descriptor));
01424
if (!
NT_SUCCESS(status)) {
01425
goto EndValueSync;
01426 }
01427
01428
01429
01430
01431 count = SourceKeyNode->
ValueList.
Count;
01432
01433
if (count == 0) {
01434
01435
01436
01437 TargetKeyNode->
ValueList.
List =
HCELL_NIL;
01438 TargetKeyNode->
ValueList.
Count = 0;
01439 success =
TRUE;
01440 }
else {
01441
01442
01443
01444 psrclist =
HvGetCell(SourceHive, SourceKeyNode->
ValueList.
List);
01445
01446 newlist =
HvAllocateCell(
01447 TargetHive,
01448 count *
sizeof(
HCELL_INDEX),
01449 Type
01450 );
01451
if (newlist ==
HCELL_NIL) {
01452
goto EndValueSync;
01453 }
01454 TargetKeyNode->
ValueList.
List = newlist;
01455 ptarlist =
HvGetCell(TargetHive, newlist);
01456
01457
01458
01459
01460
01461
for (i = 0; i < count; i++) {
01462
01463 newvalue =
CmpCopyValue(
01464 SourceHive,
01465 psrclist->
u.
KeyList[i],
01466 TargetHive,
01467 Type
01468 );
01469
01470
if (newvalue !=
HCELL_NIL) {
01471
01472 ptarlist->
u.
KeyList[i] = newvalue;
01473
01474 }
else {
01475
01476
01477
01478
for (; i > 0; i--) {
01479
HvFreeCell(
01480 TargetHive,
01481 ptarlist->
u.
KeyList[i - 1]
01482 );
01483 }
01484
goto EndValueSync;
01485 }
01486 }
01487
01488 TargetKeyNode->
ValueList.
Count = count;
01489 success =
TRUE;
01490 }
01491
01492 EndValueSync:
01493
if (success ==
FALSE) {
01494
01495
01496
01497
if (newlist !=
HCELL_NIL) {
01498
HvFreeCell(TargetHive, newlist);
01499 }
01500
01501
if (newsecurity !=
HCELL_NIL) {
01502
HvFreeCell(TargetHive, newsecurity);
01503 }
01504
01505
if (newclass !=
HCELL_NIL) {
01506
HvFreeCell(TargetHive, newclass);
01507 }
01508
01509 }
01510
01511
return success;
01512 }
01513
01514
VOID
01515 CmpInitializeKeyNameString(
PCM_KEY_NODE Cell,
01516 PUNICODE_STRING KeyName,
01517 WCHAR *NameBuffer
01518 )
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541 {
01542
01543
01544
if(
Cell->Flags &
KEY_COMP_NAME) {
01545
01546
01547
01548
01549
01550
KeyName->Length =
CmpCompressedNameSize(
Cell->Name,
01551
Cell->NameLength);
01552
01553
01554
01555
CmpCopyCompressedName(NameBuffer,
01556
MAX_KEY_NAME_LENGTH,
01557
Cell->Name,
01558
Cell->NameLength);
01559
01560
01561
01562
01563
01564
KeyName->Buffer = NameBuffer;
01565
KeyName->MaximumLength =
MAX_KEY_NAME_LENGTH;
01566
01567 }
else {
01568
01569
01570
01571
01572
01573
01574
KeyName->Length =
Cell->NameLength;
01575
KeyName->Buffer =
Cell->Name;
01576
KeyName->MaximumLength = (
USHORT)
Cell->MaxNameLen;
01577
01578 }
01579 }
01580
01581
VOID
01582 CmpInitializeValueNameString(
PCM_KEY_VALUE Cell,
01583 PUNICODE_STRING ValueName,
01584 WCHAR *NameBuffer
01585 )
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607 {
01608
01609
01610
if(
Cell->Flags &
VALUE_COMP_NAME) {
01611
01612
01613
01614
01615
01616
ValueName->Length =
CmpCompressedNameSize(
Cell->Name,
01617
Cell->NameLength);
01618
01619
01620
01621
CmpCopyCompressedName(NameBuffer,
01622
MAX_KEY_VALUE_NAME_LENGTH,
01623
Cell->Name,
01624
Cell->NameLength);
01625
01626
01627
01628
01629
01630
ValueName->Buffer = NameBuffer;
01631
ValueName->MaximumLength =
MAX_KEY_VALUE_NAME_LENGTH;
01632
01633 }
else {
01634
01635
01636
01637
01638
01639
01640
ValueName->Length =
Cell->NameLength;
01641
ValueName->Buffer =
Cell->Name;
01642
ValueName->MaximumLength =
ValueName->Length;
01643
01644 }
01645 }
01646
01647 BOOLEAN
01648 CmpSyncSubKeysAfterDelete(
PHHIVE SourceHive,
01649
PCM_KEY_NODE SourceCell,
01650
PHHIVE TargetHive,
01651
PCM_KEY_NODE TargetCell,
01652 WCHAR *NameBuffer)
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682 {
01683
HCELL_INDEX TargetSubKey, SourceSubKey;
01684 ULONG i = 0;
01685
PCM_KEY_NODE SubKeyCell;
01686 UNICODE_STRING SubKeyName;
01687
01688
01689
01690
01691
01692
while((TargetSubKey =
CmpFindSubKeyByNumber(
01693 TargetHive,
01694 TargetCell,
01695 i)) !=
HCELL_NIL)
01696 {
01697
01698
01699
01700
01701
01702
01703
01704
01705 SubKeyCell = (
PCM_KEY_NODE)
HvGetCell(TargetHive, TargetSubKey);
01706
01707
CmpInitializeKeyNameString(SubKeyCell,
01708 &SubKeyName,
01709 NameBuffer);
01710
01711 SourceSubKey =
CmpFindSubKeyByName(SourceHive,
01712 SourceCell,
01713 &SubKeyName);
01714
01715
if(SourceSubKey ==
HCELL_NIL)
01716 {
01717
01718
01719
01720
01721
01722
#if DEBUG_TREE_SYNC
01723
KdPrint((
"CONFIG: SubKey Deletion of %.*S\n",
01724 SubKeyName.Length /
sizeof(WCHAR),
01725 SubKeyName.Buffer));
01726
#endif
01727
01728
if(SubKeyCell->
SubKeyCounts[
Stable] + SubKeyCell->
SubKeyCounts[
Volatile])
01729 {
01730
01731
01732
CmpDeleteTree(TargetHive, TargetSubKey);
01733
01734
#if DEBUG_TREE_SYNC
01735
KdPrint((
"CONFIG: Delete TREE performed.\n"));
01736
#endif
01737
}
01738
01739
01740
01741
01742
if(!
NT_SUCCESS(
CmpFreeKeyByCell(TargetHive, TargetSubKey,
TRUE)))
01743 {
01744
return FALSE;
01745 }
01746
01747
01748
01749
01750
01751 }
01752
else
01753 {
01754
01755
01756
01757
01758 i++;
01759 }
01760 }
01761
01762
return TRUE;
01763 }
01764
01765
01766 BOOLEAN
01767 CmpMarkKeyValuesDirty(
01768
PHHIVE Hive,
01769 HCELL_INDEX Cell,
01770
PCM_KEY_NODE Node
01771 )
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794 {
01795
PCELL_DATA plist, security, pvalue;
01796 ULONG i, realsize;
01797
01798
if (Node->
Flags &
KEY_HIVE_EXIT) {
01799
01800
01801
01802
01803
01804
01805
return(
TRUE);
01806 }
01807
01808
01809
01810
01811
if (!
HvMarkCellDirty(
Hive,
Cell)) {
01812
return FALSE;
01813 }
01814
01815
01816
01817
01818
if (Node->
Class !=
HCELL_NIL) {
01819
if (!
HvMarkCellDirty(
Hive, Node->
Class)) {
01820
return FALSE;
01821 }
01822 }
01823
01824
01825
01826
01827
if (Node->
Security !=
HCELL_NIL) {
01828
if (!
HvMarkCellDirty(
Hive, Node->
Security)) {
01829
return FALSE;
01830 }
01831
01832 security =
HvGetCell(
Hive, Node->
Security);
01833
if (! (
HvMarkCellDirty(
Hive, security->
u.
KeySecurity.
Flink) &&
01834
HvMarkCellDirty(
Hive, security->
u.
KeySecurity.
Blink)))
01835 {
01836
return FALSE;
01837 }
01838 }
01839
01840
01841
01842
01843
if (Node->
ValueList.
Count > 0) {
01844
01845
01846
if (!
HvMarkCellDirty(
Hive, Node->
ValueList.
List)) {
01847
return FALSE;
01848 }
01849 plist =
HvGetCell(
Hive, Node->
ValueList.
List);
01850
01851
for (i = 0; i < Node->
ValueList.
Count; i++) {
01852
if (!
HvMarkCellDirty(
Hive, plist->
u.
KeyList[i])) {
01853
return FALSE;
01854 }
01855
01856 pvalue =
HvGetCell(
Hive, plist->
u.
KeyList[i]);
01857
01858
if (!
CmpIsHKeyValueSmall(realsize, pvalue->
u.
KeyValue.
DataLength)) {
01859
if (!
HvMarkCellDirty(
Hive, pvalue->
u.
KeyValue.
Data)) {
01860
return(
FALSE);
01861 }
01862 }
01863 }
01864 }
01865
01866
return TRUE;
01867 }
01868
01869 BOOLEAN
01870 CmpMarkKeyParentDirty(
01871
PHHIVE Hive,
01872 HCELL_INDEX Cell
01873 )
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893 {
01894
01895
PCELL_DATA ptarget;
01896
01897
01898
01899
01900 ptarget =
HvGetCell(
Hive,
Cell);
01901
01902
01903
if (ptarget->
u.
KeyNode.
Flags &
KEY_HIVE_ENTRY) {
01904
01905
01906
01907
01908
01909
return TRUE;
01910 }
01911
01912
01913
01914
01915
if (!
CmpMarkIndexDirty(
Hive, ptarget->
u.
KeyNode.
Parent,
Cell)) {
01916
return FALSE;
01917 }
01918
01919
01920
01921
01922
if (!
HvMarkCellDirty(
Hive, ptarget->
u.
KeyNode.
Parent)) {
01923
return FALSE;
01924 }
01925
01926
return TRUE;
01927 }