-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathRegistryEx.pas
7890 lines (6695 loc) · 307 KB
/
RegistryEx.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
{-------------------------------------------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
-------------------------------------------------------------------------------}
{===============================================================================
RegistryEx
Provides class TRegistryEx, which offers similar, but significantly
extended, functionality as standard TRegistry class implemented in RTL.
Since the interface is slightly different, it is not intended as a direct
drop-in replacement.
Version 1.1.2 (2024-10-14)
Last change 2024-10-14
©2019-2024 František Milt
Contacts:
František Milt: [email protected]
Support:
If you find this code useful, please consider supporting its author(s) by
making a small donation using the following link(s):
https://www.paypal.me/FMilt
Changelog:
For detailed changelog and history please refer to this git repository:
github.com/TheLazyTomcat/Lib.RegistryEx
Dependencies:
AuxClasses - github.com/TheLazyTomcat/Lib.AuxClasses
* AuxExceptions - github.com/TheLazyTomcat/Lib.AuxExceptions
AuxTypes - github.com/TheLazyTomcat/Lib.AuxTypes
DynLibUtils - github.com/TheLazyTomcat/Lib.DynLibUtils
StrRect - github.com/TheLazyTomcat/Lib.StrRect
WindowsVersion - github.com/TheLazyTomcat/Lib.WindowsVersion
Library AuxExceptions is required only when rebasing local exception classes
(see symbol RegistryEx_UseAuxExceptions for details).
Library AuxExceptions might also be required as an indirect dependency.
Indirect dependencies:
InterlockedOps - github.com/TheLazyTomcat/Lib.InterlockedOps
SimpleCPUID - github.com/TheLazyTomcat/Lib.SimpleCPUID
UInt64Utils - github.com/TheLazyTomcat/Lib.UInt64Utils
WinFileInfo - github.com/TheLazyTomcat/Lib.WinFileInfo
===============================================================================}
unit RegistryEx;
{
RegistryEx_UseAuxExceptions
If you want library-specific exceptions to be based on more advanced classes
provided by AuxExceptions library instead of basic Exception class, and don't
want to or cannot change code in this unit, you can define global symbol
RegistryEx_UseAuxExceptions to achieve this.
}
{$IF Defined(RegistryEx_UseAuxExceptions)}
{$DEFINE UseAuxExceptions}
{$IFEND}
//------------------------------------------------------------------------------
{$IF defined(CPU64) or defined(CPU64BITS)}
{$DEFINE CPU64bit}
{$ELSEIF defined(CPU16)}
{$MESSAGE FATAL 'Unsupported CPU.'}
{$ELSE}
{$DEFINE CPU32bit}
{$IFEND}
{$IF not(defined(MSWINDOWS) or defined(WINDOWS))}
{$MESSAGE FATAL 'Unsupported operating system.'}
{$IFEND}
{$IFDEF FPC}
{$MODE ObjFPC}
{$MODESWITCH DuplicateLocals}
{$MODESWITCH PointerToProcVar}
{$MODESWITCH ClassicProcVars}
{$DEFINE FPC_DisableWarns}
{$MACRO ON}
{$ENDIF}
{$H+}
interface
uses
Windows, SysUtils, Classes,
AuxTypes, AuxClasses{$IFDEF UseAuxExceptions}, AuxExceptions{$ENDIF};
{===============================================================================
Library-specific exceptions
===============================================================================}
type
ERXException = class({$IFDEF UseAuxExceptions}EAEGeneralException{$ELSE}Exception{$ENDIF});
ERXTimeConversionError = class(ERXException);
ERXInvalidValue = class(ERXException);
ERXRegistryError = class(ERXException);
ERXRegInvalidKey = class(ERXRegistryError);
ERXRegWriteError = class(ERXRegistryError);
ERXRegReadError = class(ERXRegistryError);
{===============================================================================
System constants
===============================================================================}
{-------------------------------------------------------------------------------
System constants - security information
-------------------------------------------------------------------------------}
const
//possible values for SecurityDescriptorCopyInfo property
OWNER_SECURITY_INFORMATION = $00000001;
GROUP_SECURITY_INFORMATION = $00000002;
DACL_SECURITY_INFORMATION = $00000004;
SACL_SECURITY_INFORMATION = $00000008;
LABEL_SECURITY_INFORMATION = $00000010;
ATTRIBUTE_SECURITY_INFORMATION = $00000020;
SCOPE_SECURITY_INFORMATION = $00000040;
PROCESS_TRUST_LABEL_SECURITY_INFORMATION = $00000080;
ACCESS_FILTER_SECURITY_INFORMATION = $00000100;
BACKUP_SECURITY_INFORMATION = $00010000;
PROTECTED_DACL_SECURITY_INFORMATION = $80000000;
PROTECTED_SACL_SECURITY_INFORMATION = $40000000;
UNPROTECTED_DACL_SECURITY_INFORMATION = $20000000;
UNPROTECTED_SACL_SECURITY_INFORMATION = $10000000;
{-------------------------------------------------------------------------------
System constants - registry access rights
-------------------------------------------------------------------------------}
const
KEY_QUERY_VALUE = $0001;
KEY_SET_VALUE = $0002;
KEY_CREATE_SUB_KEY = $0004;
KEY_ENUMERATE_SUB_KEYS = $0008;
KEY_NOTIFY = $0010;
KEY_CREATE_LINK = $0020;
KEY_WOW64_32KEY = $0200;
KEY_WOW64_64KEY = $0100;
KEY_WOW64_RES = $0300;
KEY_READ = (STANDARD_RIGHTS_READ or KEY_QUERY_VALUE or KEY_ENUMERATE_SUB_KEYS or KEY_NOTIFY) and not SYNCHRONIZE;
KEY_WRITE = (STANDARD_RIGHTS_WRITE or KEY_SET_VALUE or KEY_CREATE_SUB_KEY) and not SYNCHRONIZE;
KEY_EXECUTE = KEY_READ and not SYNCHRONIZE;
KEY_ALL_ACCESS = (STANDARD_RIGHTS_ALL or KEY_QUERY_VALUE or KEY_SET_VALUE or
KEY_CREATE_SUB_KEY or KEY_ENUMERATE_SUB_KEYS or KEY_NOTIFY or
KEY_CREATE_LINK) and not SYNCHRONIZE;
{-------------------------------------------------------------------------------
System constants - open/create options
-------------------------------------------------------------------------------}
const
REG_OPTION_RESERVED = DWORD($00000000); // Parameter is reserved
REG_OPTION_NON_VOLATILE = DWORD($00000000); // Key is preserved when system is rebooted
REG_OPTION_VOLATILE = DWORD($00000001); // Key is not preserved when system is rebooted
REG_OPTION_CREATE_LINK = DWORD($00000002); // Created key is a symbolic link
REG_OPTION_BACKUP_RESTORE = DWORD($00000004); // Open for backup or restore, special access rules, privilege required
REG_OPTION_OPEN_LINK = DWORD($00000008); // Open symbolic link
REG_OPTION_DONT_VIRTUALIZE = DWORD($00000010); // Disable Open/Read/Write virtualization for this open and the resulting handle.
REG_LEGAL_OPTION = REG_OPTION_RESERVED or REG_OPTION_NON_VOLATILE or
REG_OPTION_VOLATILE or REG_OPTION_CREATE_LINK or
REG_OPTION_BACKUP_RESTORE or REG_OPTION_OPEN_LINK or
REG_OPTION_DONT_VIRTUALIZE;
REG_OPEN_LEGAL_OPTION = REG_OPTION_RESERVED or REG_OPTION_BACKUP_RESTORE or
REG_OPTION_OPEN_LINK or REG_OPTION_DONT_VIRTUALIZE;
{-------------------------------------------------------------------------------
System constants - key creation/open disposition
-------------------------------------------------------------------------------}
const
REG_CREATED_NEW_KEY = DWORD($00000001); // New Registry Key created
REG_OPENED_EXISTING_KEY = DWORD($00000002); // Existing Key opened
{-------------------------------------------------------------------------------
System constants - hive format to be used by Reg(Nt)SaveKeyEx
-------------------------------------------------------------------------------}
const
REG_STANDARD_FORMAT = 1;
REG_LATEST_FORMAT = 2;
REG_NO_COMPRESSION = 4;
{-------------------------------------------------------------------------------
System constants - key restore & hive load flags
-------------------------------------------------------------------------------}
const
REG_WHOLE_HIVE_VOLATILE = DWORD($00000001); // Restore whole hive volatile
REG_REFRESH_HIVE = DWORD($00000002); // Unwind changes to last flush
REG_NO_LAZY_FLUSH = DWORD($00000004); // Never lazy flush this hive
REG_FORCE_RESTORE = DWORD($00000008); // Force the restore process even when we have open handles on subkeys
REG_APP_HIVE = DWORD($00000010); // Loads the hive visible to the calling process
REG_PROCESS_PRIVATE = DWORD($00000020); // Hive cannot be mounted by any other process while in use
REG_START_JOURNAL = DWORD($00000040); // Starts Hive Journal
REG_HIVE_EXACT_FILE_GROWTH = DWORD($00000080); // Grow hive file in exact 4k increments
REG_HIVE_NO_RM = DWORD($00000100); // No RM is started for this hive (no transactions)
REG_HIVE_SINGLE_LOG = DWORD($00000200); // Legacy single logging is used for this hive
REG_BOOT_HIVE = DWORD($00000400); // This hive might be used by the OS loader
REG_LOAD_HIVE_OPEN_HANDLE = DWORD($00000800); // Load the hive and return a handle to its root kcb
REG_FLUSH_HIVE_FILE_GROWTH = DWORD($00001000); // Flush changes to primary hive file size as part of all flushes
REG_OPEN_READ_ONLY = DWORD($00002000); // Open a hive's files in read-only mode
REG_IMMUTABLE = DWORD($00004000); // Load the hive, but don't allow any modification of it
REG_NO_IMPERSONATION_FALLBACK = DWORD($00008000); // Do not fall back to impersonating the caller if hive file access fails
REG_APP_HIVE_OPEN_READ_ONLY = DWORD(REG_OPEN_READ_ONLY); // Open an app hive's files in read-only mode (if the hive was not previously loaded)
{-------------------------------------------------------------------------------
System constants - unload flags
-------------------------------------------------------------------------------}
const
REG_FORCE_UNLOAD = 1;
REG_UNLOAD_LEGAL_FLAGS = REG_FORCE_UNLOAD;
{-------------------------------------------------------------------------------
System constants - notify filter values
-------------------------------------------------------------------------------}
const
REG_NOTIFY_CHANGE_NAME = DWORD($00000001); // Create or delete (child)
REG_NOTIFY_CHANGE_ATTRIBUTES = DWORD($00000002);
REG_NOTIFY_CHANGE_LAST_SET = DWORD($00000004); // time stamp
REG_NOTIFY_CHANGE_SECURITY = DWORD($00000008);
REG_NOTIFY_THREAD_AGNOSTIC = DWORD($10000000); // Not associated with a calling thread, can only be used for async user event based notification
REG_LEGAL_CHANGE_FILTER = REG_NOTIFY_CHANGE_NAME or REG_NOTIFY_CHANGE_ATTRIBUTES or
REG_NOTIFY_CHANGE_LAST_SET or REG_NOTIFY_CHANGE_SECURITY or
REG_NOTIFY_THREAD_AGNOSTIC;
{-------------------------------------------------------------------------------
System constants - predefined value types
-------------------------------------------------------------------------------}
const
REG_NONE = 0; // No value type
REG_SZ = 1; // Unicode nul terminated string
REG_EXPAND_SZ = 2; // Unicode nul terminated string (with environment variable references)
REG_BINARY = 3; // Free form binary
REG_DWORD = 4; // 32-bit number
REG_DWORD_LITTLE_ENDIAN = 4; // 32-bit number (same as REG_DWORD)
REG_DWORD_BIG_ENDIAN = 5; // 32-bit number
REG_LINK = 6; // Symbolic Link (unicode)
REG_MULTI_SZ = 7; // Multiple Unicode strings
REG_RESOURCE_LIST = 8; // Resource list in the resource map
REG_FULL_RESOURCE_DESCRIPTOR = 9; // Resource list in the hardware description
REG_RESOURCE_REQUIREMENTS_LIST = 10;
REG_QWORD = 11; // 64-bit number
REG_QWORD_LITTLE_ENDIAN = 11; // 64-bit number (same as REG_QWORD)
{-------------------------------------------------------------------------------
System constants - (RRF) registry routine flags (for RegGetValue)
-------------------------------------------------------------------------------}
const
RRF_RT_REG_NONE = $00000001; // restrict type to REG_NONE (other data types will not return ERROR_SUCCESS)
RRF_RT_REG_SZ = $00000002; // restrict type to REG_SZ (other data types will not return ERROR_SUCCESS) (automatically converts REG_EXPAND_SZ to REG_SZ unless RRF_NOEXPAND is specified)
RRF_RT_REG_EXPAND_SZ = $00000004; // restrict type to REG_EXPAND_SZ (other data types will not return ERROR_SUCCESS) (must specify RRF_NOEXPAND or RegGetValue will fail with ERROR_INVALID_PARAMETER)
RRF_RT_REG_BINARY = $00000008; // restrict type to REG_BINARY (other data types will not return ERROR_SUCCESS)
RRF_RT_REG_DWORD = $00000010; // restrict type to REG_DWORD (other data types will not return ERROR_SUCCESS)
RRF_RT_REG_MULTI_SZ = $00000020; // restrict type to REG_MULTI_SZ (other data types will not return ERROR_SUCCESS)
RRF_RT_REG_QWORD = $00000040; // restrict type to REG_QWORD (other data types will not return ERROR_SUCCESS)
RRF_RT_DWORD = RRF_RT_REG_BINARY or RRF_RT_REG_DWORD; // restrict type to *32-bit* RRF_RT_REG_BINARY or RRF_RT_REG_DWORD (other data types will not return ERROR_SUCCESS)
RRF_RT_QWORD = RRF_RT_REG_BINARY or RRF_RT_REG_QWORD; // restrict type to *64-bit* RRF_RT_REG_BINARY or RRF_RT_REG_DWORD (other data types will not return ERROR_SUCCESS)
RRF_RT_ANY = $0000FFFF; // no type restriction
RRF_SUBKEY_WOW6464KEY = $00010000; // when opening the subkey (if provided) force open from the 64bit location (only one SUBKEY_WOW64* flag can be set or RegGetValue will fail with ERROR_INVALID_PARAMETER)
RRF_SUBKEY_WOW6432KEY = $00020000; // when opening the subkey (if provided) force open from the 32bit location (only one SUBKEY_WOW64* flag can be set or RegGetValue will fail with ERROR_INVALID_PARAMETER)
RRF_WOW64_MASK = $00030000;
RRF_NOEXPAND = $10000000; // do not automatically expand environment strings if value is of type REG_EXPAND_SZ
RRF_ZEROONFAILURE = $20000000; // if pvData is not NULL, set content to all zeros on failure
{-------------------------------------------------------------------------------
System constants - flags for RegLoadAppKey
-------------------------------------------------------------------------------}
const
REG_PROCESS_APPKEY = $00000001;
REG_USE_CURRENT_SECURITY_CONTEXT = $00000002;
{-------------------------------------------------------------------------------
System constants - reserved key handles
-------------------------------------------------------------------------------}
const
// the handles must be sign-extended for 64bit OS
HKEY_CLASSES_ROOT = HKEY(PtrInt(Int32($80000000)));
HKEY_CURRENT_USER = HKEY(PtrInt(Int32($80000001)));
HKEY_LOCAL_MACHINE = HKEY(PtrInt(Int32($80000002)));
HKEY_USERS = HKEY(PtrInt(Int32($80000003)));
HKEY_PERFORMANCE_DATA = HKEY(PtrInt(Int32($80000004)));
HKEY_PERFORMANCE_TEXT = HKEY(PtrInt(Int32($80000050)));
HKEY_PERFORMANCE_NLSTEXT = HKEY(PtrInt(Int32($80000060)));
HKEY_CURRENT_CONFIG = HKEY(PtrInt(Int32($80000005)));
HKEY_DYN_DATA = HKEY(PtrInt(Int32($80000006)));
HKEY_CURRENT_USER_LOCAL_SETTINGS = HKEY(PtrInt(Int32($80000007)));
// short aliases
HKCR = HKEY_CLASSES_ROOT;
HKCU = HKEY_CURRENT_USER;
HKLM = HKEY_LOCAL_MACHINE;
HKU = HKEY_USERS;
HKPD = HKEY_PERFORMANCE_DATA;
HKPT = HKEY_PERFORMANCE_TEXT;
HKPN = HKEY_PERFORMANCE_NLSTEXT;
HKCC = HKEY_CURRENT_CONFIG;
HKDD = HKEY_DYN_DATA;
HKLS = HKEY_CURRENT_USER_LOCAL_SETTINGS;
{===============================================================================
--------------------------------------------------------------------------------
TRegistryEx
--------------------------------------------------------------------------------
===============================================================================}
const
REG_PATH_DELIMITER = '\';
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
type
TRXKeyAccessRight = (karQueryValue,karSetValue,karCreateSubKey,
karEnumerateSubKeys,karNotify,karCreateLink,
karWoW64_32Key,karWoW64_64Key,{standard access rights...}
karDelete,karReadControl,karWriteDAC,karWriteOwner,
karSynchronize);
TRXKeyAccessRights = set of TRXKeyAccessRight;
const
karWoW64_Res = [karWoW64_32Key,karWoW64_64Key];
karStandardRead = [karReadControl];
karStandardWrite = [karReadControl];
karStandardExecute = [karReadControl];
karStandardAll = [karDelete,karReadControl,karWriteDAC,karWriteOwner,karSynchronize];
karRead = karStandardRead + [karQueryValue,karEnumerateSubKeys,karNotify] - [karSynchronize];
karWrite = karStandardWrite + [karSetValue,karCreateSubKey] - [karSynchronize];
karExecute = karRead - [karSynchronize];
karAllAccess = karStandardAll + [karQueryValue,karSetValue, karCreateSubKey,
karEnumerateSubKeys,karNotify,karCreateLink] - [karSynchronize];
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
type
TRXKeyCreateOption = (kcoNonVolatile,kcoVolatile,kcoCreateLink,
kcoBackupRestore,kcoOpenLink,kcoDontVirtualize);
TRXKeyCreateOptions = set of TRXKeyCreateOption;
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
type
TRXValueType = (vtNone,vtString,vtExpandString,vtBinary,vtDWord,vtDWordLE,
vtDWordBE,vtLink,vtMultiString,vtResourceList,
vtFullResourceDescriptor,vtResourceRequirementsList,vtQWord,
vtQWordLE,vtUnknown);
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
type
TRXPredefinedKey = (pkClassesRoot,pkCurrentUser,pkLocalMachine,pkUsers,
pkPerformanceData,pkPerformanceText,pkPerformanceNLSText,
pkCurrentConfig,pkDynData,pkCurrentUserLocalSettings);
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
type
{
Lengths are in unicode characters, without terminating zero, except for
MaxValueLen, which is in bytes.
}
TRXKeyInfo = record
SubKeys: DWORD;
MaxSubKeyLen: DWORD;
MaxClassLen: DWORD;
Values: DWORD;
MaxValueNameLen: DWORD;
MaxValueLen: DWORD;
SecDescrBytes: DWORD;
LastWriteTime: TDateTime;
end;
TRXValueInfo = record
ValueType: TRXValueType;
DataSize: TMemSize;
end;
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
type
TRXPrivilegeStatus = (psError,psRemoved,psDisabled,psEnabled,psEnabledDefault);
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
type
TRXFileFormat = (ffStandardFormat,ffLatestFormat,ffNoCompression);
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
type
TRXRestoreFlag = (rfNone,rfWholeHiveVolatile,rfRefreshHive,rfNoLazyFlush,
rfForceRestore,rfAppHive,rfProcessPrivate,rfStartJournal,
rfHiveExactFileGrowth,rfHiveNoRM,rfHiveSingleLog,
rfBootHive,rfLoadHiveOpenHandle,rfFlushHiveFileGrowth,
rfOpenReadOnly,rfImmutable,rfNoImpersonationFallback,
rfAppHiveOpenReadOnly);
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
type
TRXNotifyFilterOption = (noNameChange, // sub key addition or deletion
noAttributeChange, // key attributes change
noLastSetChange, // value change/addition/deletetion
noSecurityChange, // change to security descriptor
noThreadAgnostic);
TRXNotifyFilter = set of TRXNotifyFilterOption;
const
noWaitAll = [noNameChange,noAttributeChange,noLastSetChange,noSecurityChange];
type
TRXWaitResult = (wrError,wrTimeout,wrChanged);
Function WaitResultToStr(WaitResult: TRXWaitResult): String;
{===============================================================================
TRegistryEx - class declaration
===============================================================================}
{
Following functions, when they fail, will store an error code indicating the
cause of failure in property LastSystemError:
RegistryQuota*
DisablePredefinedCache
ConnectRegistry
OpenCurrentUser
OpenUserClassesRoot
OverridePredefinedKey
RestorePredefinedKey
WaitForKeyChange
OpenKey
OpenKeyReadOnly
KeyExists
CreateKey
DeleteKey
GetKeyInfo
HasSubKeys
GetSubKeys
GetValueInfo
HasValues
GetValues
GetValueType
GetValueDataSize
ValueExists
ValueOfTypeExists
DeleteValue
DeleteSubKeys
DeleteValues
DeleteContent
CopyKey
MoveKey
RenameKey
CopyValue*
MoveValue*
RenameValue
Query*Privilege
Enable*Privilege
Disable*Privilege
SaveKey
RestoreKey
LoadKey
UnloadKey
ReplaceKey
ExportKey
TryRead*
Read*Def
Depending of how a key to work on/with is selected, there are several
behavioral classes of some public methods (they are marked with appropriate
class letter). These classes are:
A - parameters RootKey of type TRXPredefinedKey and KeyName string
These functions operate on a key given by KeyName that is a subkey of
predefined key given in parameter RootKey.
B - string parameter KeyName
If KeyName is relative (ie. does NOT start with path delimiter) and
current key is open (property CurrentKey[Handle/Name]), then these
functions operate on a subkey given by parameter KeyName that is within
current key. Otherwise they operate on a subkey given by KeyName that
is within predefined key stored in object's property RootKey.
C - no common parameter
If current key is open, then these functions operate on the current key
and its values, otherwise they operate on predefined key stored in
property RootKey.
D - no common parameter
Such functions are affecting only the current key, if any is open.
If no current key is open, then they have no effect.
If more than one class is noted, then the method is operating on more than
one key, and the order of noted classes matches order of parameters.
If no class is given, it usually means that the method does not operate on
any specific key.
}
type
TRegistryEx = class(TCustomObject)
protected
fAccessRightsSys: DWORD;
fAccessRights: TRXKeyAccessRights;
fRootKeyHandle: HKEY;
fRootKey: TRXPredefinedKey;
fRemoteRootKey: Boolean;
fCloseRootKey: Boolean;
fCurrentKeyHandle: HKEY;
fCurrentKeyName: String;
fCurrentKeyAccessRights: TRXKeyAccessRights;
fFlushOnClose: Boolean;
fLastSysError: Integer;
fSecDesrCopyInfo: DWORD;
//--- getters, setters ---
procedure SetAccessRightsSys(Value: DWORD); virtual;
procedure SetAccessRights(Value: TRXKeyAccessRights); virtual;
procedure SetRootKeyHandle(Value: HKEY); virtual;
procedure SetRootKey(Value: TRXPredefinedKey); virtual;
Function GetRootKeyString: String; virtual;
Function GetRootKeyShortString: String; virtual;
Function GetCurrentKeyReflection: Boolean; virtual;
procedure SetCurrentKeyReflection(Value: Boolean); virtual;
Function GetCurrentKeyPath: String; virtual;
//--- auxiliaty methods ---
Function SetErrorCode(ErrorCode: Integer): Integer; virtual;
Function CheckErrorCode(ErrorCode: Integer; AllowMoreDataErr: Boolean = False): Boolean; virtual;
Function SysCallError(CallResult: BOOL): Boolean; virtual;
Function WaitForKeyChange(Key: HKEY; Filter: DWORD; WatchSubTree: Boolean; Timeout: DWORD): TRXWaitResult; overload; virtual;
Function AuxCreateKey(BaseKey: HKEY; const KeyName: String; AccessRights: DWORD; out NewKey: HKEY;
CreateOptions: DWORD = REG_OPTION_NON_VOLATILE; Disposition: LPDWORD = nil): Boolean; overload; virtual;
Function AuxOpenKey(BaseKey: HKEY; const KeyName: String; AccessRights: DWORD; out NewKey: HKEY): Boolean; overload; virtual;
Function AuxCloseKey(Key: HKEY): Boolean; virtual;
procedure ChangeRootKey(KeyHandle: HKEY; Key: TRXPredefinedKey); virtual;
procedure ChangeCurrentKey(KeyHandle: HKEY; const KeyName: String); virtual;
Function GetWorkingKey(Relative: Boolean; out WorkingKeyName: String): HKEY; overload; virtual;
Function GetWorkingKey(Relative: Boolean): HKEY; overload; virtual;
Function CurrentKeyIsSubKeyOf(RootKey: TRXPredefinedKey; const KeyName: String; Strict: Boolean): Boolean; overload; virtual;
Function CurrentKeyIsSubKeyOf(const KeyName: String; Strict: Boolean): Boolean; overload; virtual;
Function GetKeyInfo(Key: HKEY; out KeyInfo: TRXKeyInfo): Boolean; overload; virtual;
Function GetSubKeys(Key: HKEY; SubKeys: TStrings): Boolean; overload; virtual;
Function GetSubTree(Key: HKEY; SubKeys: TStrings; const ParentPath: String): Boolean; overload; virtual;
Function GetValueInfo(Key: HKEY; const ValueName: String; out ValueInfo: TRXValueInfo): Boolean; overload; virtual;
Function GetValues(Key: HKEY; Values: TStrings): Boolean; overload; virtual;
Function DeleteSubKeys(Key: HKEY): Boolean; overload; virtual;
Function DeleteValues(Key: HKEY): Boolean; overload; virtual;
Function QueryProcessPrivilege(const PrivilegeName: String): TRXPrivilegeStatus; virtual;
Function SetProcessPrivilege(const PrivilegeName: String; Enable: Boolean): Boolean; virtual;
Function ExecuteRegCommand(const Command: String): Boolean;
//--- copy/move auxiliaty methods ---
Function MoveKey(SrcBaseKey: HKEY; const SrcSubKey: String; DstBaseKey: HKEY; const DstSubKey: String; CopySecurity,DeleteSource: Boolean): Boolean; overload; virtual;
Function MoveValue(SrcKey: HKEY; const SrcValueName: String; DstKey: HKEY; const DstValueName: String; DeleteSource: Boolean): Boolean; overload; virtual;
//--- data access methods and macros ---
procedure SetValueData(const TypeName: String; Key: HKEY; const ValueName: String; const Data; Size: TMemSize; ValueType: TRXValueType); overload; virtual;
procedure SetValueData(const TypeName: String; Key: HKEY; const ValueName: String; Data: Integer); overload; virtual;
Function TrySetValueData(Key: HKEY; const ValueName: String; const Data; Size: TMemSize; ValueType: TRXValueType): Boolean; virtual;
procedure WriteMacro(const TypeName: String; RootKey: TRXPredefinedKey; const KeyName,ValueName: String; const Value; Size: TMemSize; ValueType: TRXValueType); overload; virtual;
procedure WriteMacro(const TypeName,KeyName,ValueName: String; const Value; Size: TMemSize; ValueType: TRXValueType); overload; virtual;
procedure WriteMacro(const TypeName: String; RootKey: TRXPredefinedKey; const KeyName,ValueName: String; Value: Integer); overload; virtual;
procedure WriteMacro(const TypeName,KeyName,ValueName: String; Value: Integer); overload; virtual;
Function GetValueDataOut(Key: HKEY; const ValueName: String; out Mem: Pointer; out Size: TMemSize; ValueType: TRXValueType): Boolean; overload; virtual;
Function GetValueDataOut(Key: HKEY; const ValueName: String; out Str: WideString; ValueType: TRXValueType): Boolean; overload; virtual;
Function GetValueDataExtBuff(Key: HKEY; const ValueName: String; out Data; var Size: TMemSize; ValueType: TRXValueType): Boolean; virtual;
Function GetValueData(Key: HKEY; const ValueName: String; out Data; Size: TMemSize; ValueType: TRXValueType): Boolean; overload; virtual;
Function GetValueData(Key: HKEY; const ValueName: String; out Data: Integer): Boolean; overload; virtual;
Function TryReadMacroOut(RootKey: TRXPredefinedKey; const KeyName,ValueName: String; out Mem: Pointer; out Size: TMemSize; ValueType: TRXValueType): Boolean; overload; virtual;
Function TryReadMacroOut(const KeyName,ValueName: String; out Mem: Pointer; out Size: TMemSize; ValueType: TRXValueType): Boolean; overload; virtual;
Function TryReadMacroOut(RootKey: TRXPredefinedKey; const KeyName,ValueName: String; out Str: WideString; ValueType: TRXValueType): Boolean; overload; virtual;
Function TryReadMacroOut(const KeyName,ValueName: String; out Str: WideString; ValueType: TRXValueType): Boolean; overload; virtual;
Function TryReadMacroExtBuff(RootKey: TRXPredefinedKey; const KeyName,ValueName: String; out Value; var Size: TMemSize; ValueType: TRXValueType): Boolean; overload; virtual;
Function TryReadMacroExtBuff(const KeyName,ValueName: String; out Value; var Size: TMemSize; ValueType: TRXValueType): Boolean; overload; virtual;
Function TryReadMacro(RootKey: TRXPredefinedKey; const KeyName,ValueName: String; out Value; Size: TMemSize; ValueType: TRXValueType): Boolean; overload; virtual;
Function TryReadMacro(const KeyName,ValueName: String; out Value; Size: TMemSize; ValueType: TRXValueType): Boolean; overload; virtual;
Function TryReadMacro(RootKey: TRXPredefinedKey; const KeyName,ValueName: String; out Success: Boolean): Integer; overload; virtual;
Function TryReadMacro(const KeyName,ValueName: String; out Success: Boolean): Integer; overload; virtual;
procedure ReadMacroOut(const TypeName: String; RootKey: TRXPredefinedKey; const KeyName,ValueName: String; out Mem: Pointer; out Size: TMemSize; ValueType: TRXValueType); overload; virtual;
procedure ReadMacroOut(const TypeName,KeyName,ValueName: String; out Mem: Pointer; out Size: TMemSize; ValueType: TRXValueType); overload; virtual;
procedure ReadMacroOut(const TypeName,ValueName: String; out Mem: Pointer; out Size: TMemSize; ValueType: TRXValueType); overload; virtual;
procedure ReadMacroOut(const TypeName: String; RootKey: TRXPredefinedKey; const KeyName,ValueName: String; out Str: WideString; ValueType: TRXValueType); overload; virtual;
procedure ReadMacroOut(const TypeName,KeyName,ValueName: String; out Str: WideString; ValueType: TRXValueType); overload; virtual;
procedure ReadMacroOut(const TypeName,ValueName: String; out Str: WideString; ValueType: TRXValueType); overload; virtual;
procedure ReadMacroExtBuff(const TypeName: String; RootKey: TRXPredefinedKey; const KeyName,ValueName: String; out Value; var Size: TMemSize; ValueType: TRXValueType); overload; virtual;
procedure ReadMacroExtBuff(const TypeName,KeyName,ValueName: String; out Value; var Size: TMemSize; ValueType: TRXValueType); overload; virtual;
procedure ReadMacroExtBuff(const TypeName,ValueName: String; out Value; var Size: TMemSize; ValueType: TRXValueType); overload; virtual;
procedure ReadMacro(const TypeName: String; RootKey: TRXPredefinedKey; const KeyName,ValueName: String; out Value; Size: TMemSize; ValueType: TRXValueType); overload; virtual;
procedure ReadMacro(const TypeName,KeyName,ValueName: String; out Value; Size: TMemSize; ValueType: TRXValueType); overload; virtual;
procedure ReadMacro(const TypeName,ValueName: String; out Value; Size: TMemSize; ValueType: TRXValueType); overload; virtual;
Function ReadMacro(const TypeName: String; RootKey: TRXPredefinedKey; const KeyName,ValueName: String): Integer; overload; virtual;
Function ReadMacro(const TypeName,KeyName,ValueName: String): Integer; overload; virtual;
Function ReadMacro(const TypeName,ValueName: String): Integer; overload; virtual;
//--- init/final methods ---
procedure Initialize(RootKey: TRXPredefinedKey; AccessRights: TRXKeyAccessRights); virtual;
procedure Finalize; virtual;
public
constructor Create(RootKey: TRXPredefinedKey; AccessRights: TRXKeyAccessRights = karAllAccess); overload;
constructor Create(AccessRights: TRXKeyAccessRights = karAllAccess); overload; // root key is set to pkCurrentUser
destructor Destroy; override;
//--- global registry functions ---
{
If functions RegistryQuota* fail to obtain the number, they will return 0
and LastSystemError will contain error code of the cause of failure.
}
Function RegistryQuotaAllowed: UInt32; virtual;
Function RegistryQuotaUsed: UInt32; virtual;
{
When parameter AllKeys is set to false, function RegDisablePredefinedCache
is called. When set to true, RegDisablePredefinedCacheEx is called - but
note that this function is implemented only from Windows Vista up. If you
call this method with AllKeys set to true in older systems, it will fail
(returns false and LastSystemError is set to ERROR_CALL_NOT_IMPLEMENTED)
and has no effect.
}
Function DisablePredefinedCache(AllKeys: Boolean): Boolean; virtual;
{
ConnectRegistry only connects to a remote registry, proper access and
possible needed logon is not managed.
}
Function ConnectRegistry(const MachineName: String; RootKey: TRXPredefinedKey): Boolean; virtual;
{
Sets root key to pkCurrentUserbut instead of using predefined key handle,
the handle is obtained using function RegOpenCurrentUser - meaning it is
bound to current user key of a user the calling thread is impersonating.
}
Function OpenCurrentUser(AccessRights: TRXKeyAccessRights = karAllAccess): Boolean; virtual;
{
Similarly to OpenCurrentUser, sets root key to pkClassesRootbut, but the
handle is obtained using function RegOpenUserClassesRoot - it is a handle
of classes root key belonging to a user identified by impersonation access
token that is passed in AccessToken parameter.
For more details, see documentation of RegOpenUserClassesRoot function.
}
Function OpenUserClassesRoot(AccessToken: THandle; AccessRights: TRXKeyAccessRights = karAllAccess): Boolean; virtual;
{
OverridePredefinedKey maps specified predefined registry key to another
open key.
RestorePredefinedKey restores the default mapping for specified predefined
registry key.
}
{A}Function OverridePredefinedKey(PredefinedKey: TRXPredefinedKey; RootKey: TRXPredefinedKey; const KeyName: String): Boolean; overload; virtual;
{B}Function OverridePredefinedKey(PredefinedKey: TRXPredefinedKey; const KeyName: String): Boolean; overload; virtual;
{D}Function OverridePredefinedKey(PredefinedKey: TRXPredefinedKey): Boolean; overload; virtual;
Function RestorePredefinedKey(PredefinedKey: TRXPredefinedKey): Boolean; virtual;
{
For any kind of failure, the WaitForKeyChange will return wrError.
WARNING - if called on current key, you must close and re-open the key
before next call to WaitForKeyChange, otherwise the function
will behave incorrectly. It is therefore recommended to only
use first (class A) or second (class B) overload with non-empty
key name.
}
{A}Function WaitForKeyChange(RootKey: TRXPredefinedKey; const KeyName: String; WatchSubTree: Boolean; Filter: TRXNotifyFilter = noWaitAll; Timeout: DWORD = INFINITE): TRXWaitResult; overload; virtual;
{B}Function WaitForKeyChange(const KeyName: String; WatchSubTree: Boolean; Filter: TRXNotifyFilter = noWaitAll; Timeout: DWORD = INFINITE): TRXWaitResult; overload; virtual;
{C}Function WaitForKeyChange(WatchSubTree: Boolean; Filter: TRXNotifyFilter = noWaitAll; Timeout: DWORD = INFINITE): TRXWaitResult; overload; virtual;
//--- keys management ---
{
Opens or creates requested key as a current key. If current key was already
opened, it is first closed. If the function fails, nothing is changed
(current key, if already opened, will stay opened).
Note that the key can only be created when the KeyName is not empty.
}
{A}Function OpenKey(RootKey: TRXPredefinedKey; const KeyName: String; CanCreate: Boolean; out Created: Boolean; CreateOptions: TRXKeyCreateOptions = [kcoNonVolatile]): Boolean; overload; virtual;
{B}Function OpenKey(const KeyName: String; CanCreate: Boolean; out Created: Boolean; CreateOptions: TRXKeyCreateOptions = [kcoNonVolatile]): Boolean; overload; virtual;
{A}Function OpenKey(RootKey: TRXPredefinedKey; const KeyName: String; CanCreate: Boolean = False): Boolean; overload; virtual;
{B}Function OpenKey(const KeyName: String; CanCreate: Boolean = False): Boolean; overload; virtual;
{
OpenKeyReadOnly, when successful, will change AccessRight property to
karRead, but it will also preserve karWoW64_32Key and karWoW64_64Key if
they were previously set.
}
{A}Function OpenKeyReadOnly(RootKey: TRXPredefinedKey; const KeyName: String): Boolean; overload; virtual;
{B}Function OpenKeyReadOnly(const KeyName: String): Boolean; overload; virtual;
{
KeyExists tries to open given key for reading. When it succeeds, it is
assumed the key exists, otherwise it is assumed it does not exist.
}
{A}Function KeyExists(RootKey: TRXPredefinedKey; const KeyName: String): Boolean; overload; virtual;
{B}Function KeyExists(const KeyName: String): Boolean; overload; virtual;
{
KeyName must not be empty, otherwise the creation fails.
}
{A}Function CreateKey(RootKey: TRXPredefinedKey; const KeyName: String; AccessRights: TRXKeyAccessRights = karAllAccess; CreateOptions: TRXKeyCreateOptions = [kcoNonVolatile]): Boolean; overload; virtual;
{B}Function CreateKey(const KeyName: String; AccessRights: TRXKeyAccessRights = karAllAccess; CreateOptions: TRXKeyCreateOptions = [kcoNonVolatile]): Boolean; overload; virtual;
{
Be carefull what you are deleting, I have managed to delete entire content
of HKEY_CURRENT_USER during testing (thank god for system restore).
}
{A}Function DeleteKey(RootKey: TRXPredefinedKey; const KeyName: String; CanDeleteCurrentKey: Boolean; out CurrentKeyClosed: Boolean): Boolean; overload; virtual;
{B}Function DeleteKey(const KeyName: String; CanDeleteCurrentKey: Boolean; out CurrentKeyClosed: Boolean): Boolean; overload; virtual;
{A}Function DeleteKey(RootKey: TRXPredefinedKey; const KeyName: String; CanDeleteCurrentKey: Boolean = True): Boolean; overload; virtual;
{B}Function DeleteKey(const KeyName: String; CanDeleteCurrentKey: Boolean = True): Boolean; overload; virtual;
{D}procedure FlushKey; virtual;
{D}procedure CloseKey; virtual;
//--- key information ---
{
If GetKeyInfo fails (returns false), the content of KeyInfo is undefined.
}
{A}Function GetKeyInfo(RootKey: TRXPredefinedKey; const KeyName: String; out KeyInfo: TRXKeyInfo): Boolean; overload; virtual;
{B}Function GetKeyInfo(const KeyName: String; out KeyInfo: TRXKeyInfo): Boolean; overload; virtual;
{C}Function GetKeyInfo(out KeyInfo: TRXKeyInfo): Boolean; overload; virtual;
{
Following three overloads of HasSubKeys return true when the requested key
has any subkey.
When they return false, it means either that there is no subkey or that the
function has failed - check property LastSystemError. When it contains
ERROR_SUCCESS, then the function succeeded and there is no subkey, when it
contains other error code, it indicates that the function has failed (the
code can be used to discern the cause of failure).
}
{A}Function HasSubKeys(RootKey: TRXPredefinedKey; const KeyName: String): Boolean; overload; virtual;
{B}Function HasSubKeys(const KeyName: String): Boolean; overload; virtual;
{C}Function HasSubKeys: Boolean; overload; virtual;
{
Following overloads of HasSubKeys are working the same as previous versions,
except that the result strictly indicates whether the function succeeded or
not, whether the key has subkeys is indicated by output parameter
SubKeysRes.
Note that when the function fails, the value of SubKeysRes is undefined.
}
{A}Function HasSubKeys(RootKey: TRXPredefinedKey; const KeyName: String; out SubKeysRes: Boolean): Boolean; overload; virtual;
{B}Function HasSubKeys(const KeyName: String; out SubKeysRes: Boolean): Boolean; overload; virtual;
{C}Function HasSubKeys(out SubKeysRes: Boolean): Boolean; overload; virtual;
{
SubKeys object is always cleared, irrespective of whether the function
succeeds or not.
}
{A}Function GetSubKeys(RootKey: TRXPredefinedKey; const KeyName: String; SubKeys: TStrings): Boolean; overload; virtual;
{B}Function GetSubKeys(const KeyName: String; SubKeys: TStrings): Boolean; overload; virtual;
{C}Function GetSubKeys(SubKeys: TStrings): Boolean; overload; virtual;
{
SubKeys object is always cleared, irrespective of whether the function
succeeds or not.
}
{A}Function GetSubTree(RootKey: TRXPredefinedKey; const KeyName: String; SubKeys: TStrings): Boolean; overload; virtual;
{B}Function GetSubTree(const KeyName: String; SubKeys: TStrings): Boolean; overload; virtual;
{C}Function GetSubTree(SubKeys: TStrings): Boolean; overload; virtual;
//--- values information/access ---
{
Functions GetValueInfo, HasValues and GetValues are working the same as
corresponding functions for keys (GetKeyInfo, HasSubKeys, ...).
}
{A}Function GetValueInfo(RootKey: TRXPredefinedKey; const KeyName,ValueName: String; out ValueInfo: TRXValueInfo): Boolean; overload; virtual;
{B}Function GetValueInfo(const KeyName,ValueName: String; out ValueInfo: TRXValueInfo): Boolean; overload; virtual;
{C}Function GetValueInfo(const ValueName: String; out ValueInfo: TRXValueInfo): Boolean; overload; virtual;
{A}Function HasValues(RootKey: TRXPredefinedKey; const KeyName: String): Boolean; overload; virtual;
{B}Function HasValues(const KeyName: String): Boolean; overload; virtual;
{C}Function HasValues: Boolean; overload; virtual;
{A}Function HasValues(RootKey: TRXPredefinedKey; const KeyName: String; out ValuesRes: Boolean): Boolean; overload; virtual;
{B}Function HasValues(const KeyName: String; out ValuesRes: Boolean): Boolean; overload; virtual;
{C}Function HasValues(out ValuesRes: Boolean): Boolean; overload; virtual;
{A}Function GetValues(RootKey: TRXPredefinedKey; const KeyName: String; Values: TStrings): Boolean; overload; virtual;
{B}Function GetValues(const KeyName: String; Values: TStrings): Boolean; overload; virtual;
{C}Function GetValues(Values: TStrings): Boolean; overload; virtual;
{
GetValueType will return vtUnknown in case the value does not exist or
cannot be queried in general.
}
{A}Function GetValueType(RootKey: TRXPredefinedKey; const KeyName,ValueName: String): TRXValueType; overload; virtual;
{B}Function GetValueType(const KeyName,ValueName: String): TRXValueType; overload; virtual;
{C}Function GetValueType(const ValueName: String): TRXValueType; overload; virtual;
{
Following three overloads of GetValueDataSize will return 0 in case the
value does not exist or cannot be queried.
Note that 0 is a valid data size, so do not assume the function have failed
when it returned zero. This method will explicitly set property
LastSystemError to ERROR_SUCCESS when it succeeds, so you can check whether
the returned zero is a valid result or not (in which case the
LastSystemError will contain other error code than ERROR_SUCCESS).
}
{A}Function GetValueDataSize(RootKey: TRXPredefinedKey; const KeyName,ValueName: String): TMemSize; overload; virtual;
{B}Function GetValueDataSize(const KeyName,ValueName: String): TMemSize; overload; virtual;
{C}Function GetValueDataSize(const ValueName: String): TMemSize; overload; virtual;
{
Following overloads will indicate success in ther result and the actual
size is returned in output parameter DataSize.
If the function fails, then content of DataSize is undefined.
}
{A}Function GetValueDataSize(RootKey: TRXPredefinedKey; const KeyName,ValueName: String; out DataSize: TMemSize): Boolean; overload; virtual;
{B}Function GetValueDataSize(const KeyName,ValueName: String; out DataSize: TMemSize): Boolean; overload; virtual;
{C}Function GetValueDataSize(const ValueName: String; out DataSize: TMemSize): Boolean; overload; virtual;
{
ValueExists returns result of GetValueInfo for the given key and value.
So if the info can be obtained, it is assumed the value exists, otherwise
it is assumed it does not exist.
}
{A}Function ValueExists(RootKey: TRXPredefinedKey; const KeyName,ValueName: String): Boolean; overload; virtual;
{B}Function ValueExists(const KeyName,ValueName: String): Boolean; overload; virtual;
{C}Function ValueExists(const ValueName: String): Boolean; overload; virtual;
{
ValueOfTypeExists checks whether the given value exist within given key,
and also whether is of given type.
If the value exists but is of differing type, then false is returned and
LastSystemError is set to ERROR_DATATYPE_MISMATCH.
}
{A}Function ValueOfTypeExists(RootKey: TRXPredefinedKey; const KeyName,ValueName: String; ValueType: TRXValueType): Boolean; overload; virtual;
{B}Function ValueOfTypeExists(const KeyName,ValueName: String; ValueType: TRXValueType): Boolean; overload; virtual;
{C}Function ValueOfTypeExists(const ValueName: String; ValueType: TRXValueType): Boolean; overload; virtual;
{A}Function DeleteValue(RootKey: TRXPredefinedKey; const KeyName,ValueName: String): Boolean; overload; virtual;
{B}Function DeleteValue(const KeyName,ValueName: String): Boolean; overload; virtual;
{C}Function DeleteValue(const ValueName: String): Boolean; overload; virtual;
//--- content deletion ---
{
DeleteSubKeys returns true when ALL subkeys are deleted. If deletion of
even one subkey fails, it returns false.
Note that the function will stop deleting the subkeys on a first failed
attempt.
}
{A}Function DeleteSubKeys(RootKey: TRXPredefinedKey; const KeyName: String; out CurrentKeyClosed: Boolean): Boolean; overload; virtual;
{B}Function DeleteSubKeys(const KeyName: String; out CurrentKeyClosed: Boolean): Boolean; overload; virtual;
{C}Function DeleteSubKeys: Boolean; overload; virtual;
{A}Function DeleteSubKeys(RootKey: TRXPredefinedKey; const KeyName: String): Boolean; overload; virtual;
{B}Function DeleteSubKeys(const KeyName: String): Boolean; overload; virtual;
{
DeleteValues returns true when ALL values are deleted. If deletion of even
one value fails, it returns false.
Note that the function will stop deleting the values on a first failed
attempt.
}
{A}Function DeleteValues(RootKey: TRXPredefinedKey; const KeyName: String): Boolean; overload; virtual;
{B}Function DeleteValues(const KeyName: String): Boolean; overload; virtual;
{C}Function DeleteValues: Boolean; overload; virtual;
{
DeleteContent first tries to delete all values in the given key (calls
DeleteValues). When it succeeds, it will try to delete all subkeys (using
DeleteSubKeys) and return result of this operation.
If it fails to delete all values, the subkeys deletion is not even
attempted.
}
{A}Function DeleteContent(RootKey: TRXPredefinedKey; const KeyName: String): Boolean; overload; virtual;
{B}Function DeleteContent(const KeyName: String): Boolean; overload; virtual;
{C}Function DeleteContent: Boolean; overload; virtual;
//--- advanced keys and values manipulation ---
{
In CopyKey and MoveKey, the destination key must not exist, otherwise the
function will fail.
}
{
CopyKey, MoveKey and RenameKey (which calls MoveKey) are all multi-stage
processes. It is possible, since there is no roll-back (for the sake of
data protection), when the function fails at any point, that the destination
will be partially or even fully created, or the source only partially
removed.
}
{AA}Function CopyKey(SrcRootKey: TRXPredefinedKey; const SrcKeyName: String; DstRootKey: TRXPredefinedKey; const DstKeyName: String; CopySecurityDescriptors: Boolean = False): Boolean; overload; virtual;
{AB}Function CopyKey(SrcRootKey: TRXPredefinedKey; const SrcKeyName: String; const DstKeyName: String; CopySecurityDescriptors: Boolean = False): Boolean; overload; virtual;
{BA}Function CopyKey(const SrcKeyName: String; DstRootKey: TRXPredefinedKey; const DstKeyName: String; CopySecurityDescriptors: Boolean = False): Boolean; overload; virtual;
{BB}Function CopyKey(const SrcKeyName,DstKeyName: String; CopySecurityDescriptors: Boolean = False): Boolean; overload; virtual;
{
If current key is a subkey of moved source key, it is closed and reopened
from the new location.
}
{AA}Function MoveKey(SrcRootKey: TRXPredefinedKey; const SrcKeyName: String; DstRootKey: TRXPredefinedKey; const DstKeyName: String; CopySecurityDescriptors: Boolean = False): Boolean; overload; virtual;
{AB}Function MoveKey(SrcRootKey: TRXPredefinedKey; const SrcKeyName: String; const DstKeyName: String; CopySecurityDescriptors: Boolean = False): Boolean; overload; virtual;
{BA}Function MoveKey(const SrcKeyName: String; DstRootKey: TRXPredefinedKey; const DstKeyName: String; CopySecurityDescriptors: Boolean = False): Boolean; overload; virtual;
{BB}Function MoveKey(const SrcKeyName,DstKeyName: String; CopySecurityDescriptors: Boolean = False): Boolean; overload; virtual;
{
RenameKey changes name of a key given by OldKeyName to NewKeyName. Since
there is no way of directly changing registry key name, it is instead
copied and the original is then deleted (calls MoveKey).
}
{A}Function RenameKey(RootKey: TRXPredefinedKey; const OldKeyName,NewKeyName: String; CopySecurityDescriptors: Boolean = False): Boolean; overload; virtual;
{B}Function RenameKey(const OldKeyName,NewKeyName: String; CopySecurityDescriptors: Boolean = False): Boolean; overload; virtual;
{
For all CopyValue and MoveValue functions, the destination key must already
exist, it will not be created.
Also, the destination value must not exist, otherwise the function fails
and LastSystemError is set to ERROR_ALREADY_EXISTS.
All CopyValue, MoveValue and RenameValue methods are multi-stage. So it is
possible that, in the case of failure, the destination value will be
nevertheless created.
}
{
CopyValue copies value from one arbitrary key into another arbitrary key.
}
{AA}Function CopyValue(SrcRootKey: TRXPredefinedKey; const SrcKeyName,SrcValueName: String; DstRootKey: TRXPredefinedKey; const DstKeyName,DstValueName: String): Boolean; overload; virtual;
{AB}Function CopyValue(SrcRootKey: TRXPredefinedKey; const SrcKeyName,SrcValueName: String; const DstKeyName,DstValueName: String): Boolean; overload; virtual;
{BA}Function CopyValue(const SrcKeyName,SrcValueName: String; DstRootKey: TRXPredefinedKey; const DstKeyName,DstValueName: String): Boolean; overload; virtual;
{BB}Function CopyValue(const SrcKeyName,SrcValueName: String; const DstKeyName,DstValueName: String): Boolean; overload; virtual;
{
CopyValueTo copies value from subkey of current key or root key into an
arbitrary key.
}
{CA}Function CopyValueTo(const SrcValueName: String; DstRootKey: TRXPredefinedKey; const DstKeyName,DstValueName: String): Boolean; overload; virtual;
{CB}Function CopyValueTo(const SrcValueName: String; const DstKeyName,DstValueName: String): Boolean; overload; virtual;
{
CopyValueFrom copies value from an arbitrary key into a subkey of current
key or root key.
}
{AC}Function CopyValueFrom(SrcRootKey: TRXPredefinedKey; const SrcKeyName,SrcValueName: String; const DstValueName: String): Boolean; overload; virtual;
{BC}Function CopyValueFrom(const SrcKeyName,SrcValueName: String; const DstValueName: String): Boolean; overload; virtual;
{
CopyValueIn copies value within one key, be it arbitrary, current or root
key.
}
{A}Function CopyValueIn(RootKey: TRXPredefinedKey; const KeyName,SrcValueName,DstValueName: String): Boolean; overload; virtual;
{B}Function CopyValueIn(const KeyName,SrcValueName,DstValueName: String): Boolean; overload; virtual;
{C}Function CopyValueIn(const SrcValueName,DstValueName: String): Boolean; overload; virtual;
{
The processing in MoveValue* functions is two-phase. First, a copy of the
source is created. If this fails, the function exits and returns false.
When successful, then the source is then deleted and MoveValue* returns
result of this deletion.
}
{AA}Function MoveValue(SrcRootKey: TRXPredefinedKey; const SrcKeyName,SrcValueName: String; DstRootKey: TRXPredefinedKey; const DstKeyName,DstValueName: String): Boolean; overload; virtual;
{AB}Function MoveValue(SrcRootKey: TRXPredefinedKey; const SrcKeyName,SrcValueName: String; const DstKeyName,DstValueName: String): Boolean; overload; virtual;
{BA}Function MoveValue(const SrcKeyName,SrcValueName: String; DstRootKey: TRXPredefinedKey; const DstKeyName,DstValueName: String): Boolean; overload; virtual;
{BB}Function MoveValue(const SrcKeyName,SrcValueName: String; const DstKeyName,DstValueName: String): Boolean; overload; virtual;
{CA}Function MoveValueTo(const SrcValueName: String; DstRootKey: TRXPredefinedKey; const DstKeyName,DstValueName: String): Boolean; overload; virtual;
{CB}Function MoveValueTo(const SrcValueName: String; const DstKeyName,DstValueName: String): Boolean; overload; virtual;
{AC}Function MoveValueFrom(SrcRootKey: TRXPredefinedKey; const SrcKeyName,SrcValueName: String; const DstValueName: String): Boolean; overload; virtual;
{BC}Function MoveValueFrom(const SrcKeyName,SrcValueName: String; const DstValueName: String): Boolean; overload; virtual;
{A}Function MoveValueIn(RootKey: TRXPredefinedKey; const KeyName,SrcValueName,DstValueName: String): Boolean; overload; virtual;
{B}Function MoveValueIn(const KeyName,SrcValueName,DstValueName: String): Boolean; overload; virtual;
{C}Function MoveValueIn(const SrcValueName,DstValueName: String): Boolean; overload; virtual;
{
Afaik there is no way to directly rename a value, so it is instead copied
to a new value with NewName and the original (OldName) is then deleted.
Value with the new name must not exist, otherwise the function fails
and LastSystemError is set to ERROR_ALREADY_EXISTS.
}
{A}Function RenameValue(RootKey: TRXPredefinedKey; const KeyName,OldValueName,NewValueName: String): Boolean; overload; virtual;
{B}Function RenameValue(const KeyName,OldValueName,NewValueName: String): Boolean; overload; virtual;
{C}Function RenameValue(const OldValueName,NewValueName: String): Boolean; overload; virtual;
//--- keys saving and loading ---
{
See further...
}
Function QueryBackupPrivilege: TRXPrivilegeStatus; virtual;
Function EnableBackupPrivilege: Boolean; virtual;
Function DisableBackupPrivilege: Boolean; virtual;
Function QueryRestorePrivilege: TRXPrivilegeStatus; virtual;
Function EnableRestorePrivilege: Boolean; virtual;
Function DisableRestorePrivilege: Boolean; virtual;
{
Following functions are only simple wrappers for backup and restore
registry functions. More detailed implementation is beyond the scope of
this library.
All presented functions require for the calling process to have special
privileges enabled, otherwise they will fail. Namely SeBackupPrivilege and
SeRestorePrivilege must be present in access token and must be enabled
(exception being SaveKey functions - they require only backup privilege).
For this, Query*Privilege, Enable*Privilege and Disable*Privilege methods
are provided - use them to get a state of mentioned privileges and
potentially enable or disable them.
WARNING - it is not possible to add privilege to acess token, and none of
the required privilege is present for normal precesses.
So if you need to use those functions, make sure the process is
run with administrator privileges (then the required privileges
are present, but disabled - you can enable them).
}
{A}Function SaveKey(RootKey: TRXPredefinedKey; const KeyName,FileName: String; FileFormat: TRXFileFormat = ffStandardFormat): Boolean; overload; virtual;
{B}Function SaveKey(const KeyName,FileName: String; FileFormat: TRXFileFormat = ffStandardFormat): Boolean; overload; virtual;
{C}Function SaveKey(const FileName: String; FileFormat: TRXFileFormat = ffStandardFormat): Boolean; overload; virtual;
{A}Function RestoreKey(RootKey: TRXPredefinedKey; const KeyName,FileName: String; Flag: TRXRestoreFlag = rfNone): Boolean; overload; virtual;
{B}Function RestoreKey(const KeyName,FileName: String; Flag: TRXRestoreFlag = rfNone): Boolean; overload; virtual;
{C}Function RestoreKey(const FileName: String; Flag: TRXRestoreFlag = rfNone): Boolean; overload; virtual;
{
RootKey parameter in LoadKey and UnLoadKey can only be set to pkUsers or
pkLocalMachine, otherwise the function will fail.
KeyName must not be empty and cannot be a path, only a simple key name.
}
Function LoadKey(RootKey: TRXPredefinedKey; const KeyName, FileName: String): Boolean; virtual;
Function UnLoadKey(RootKey: TRXPredefinedKey; const KeyName: String): Boolean; virtual;
{
WARNING - considering how RegReplaceKey (which is internally called)
works, using this function can be very dangerous. There is a
good chance to completely erase registry hive when used
inappropriately. Please refer to documentation of Win32
function RegReplaceKey for details.
}
{A}Function ReplaceKey(RootKey: TRXPredefinedKey; const KeyName,NewFileName,OldFileName: String): Boolean; overload; virtual;
{B}Function ReplaceKey(const KeyName,NewFileName,OldFileName: String): Boolean; overload; virtual;
{C}Function ReplaceKey(const NewFileName,OldFileName: String): Boolean; overload; virtual;
{A}Function ExportKey(RootKey: TRXPredefinedKey; const KeyName,FileName: String): Boolean; overload; virtual;
{B}Function ExportKey(const KeyName,FileName: String): Boolean; overload; virtual;
{C}Function ExportKey(const FileName: String): Boolean; overload; virtual;
Function ImportKey(const FileName: String): Boolean; virtual;
//--- values write ---
{