registry.pp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2022 by Michael van Canneyt and other members of the
  4. Free Pascal development team
  5. Core registry unit
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. Unit Registry;
  13. {$mode objfpc}
  14. {$H+}
  15. interface
  16. {$ifndef windows}
  17. {$define XMLREG}
  18. {$endif}
  19. Uses
  20. {$ifndef XMLREG}
  21. Windows,
  22. {$endif XMLREG}
  23. Classes,
  24. SysUtils,
  25. inifiles;
  26. {$I regdef.inc}
  27. type
  28. ERegistryException = class(Exception);
  29. TRegKeyInfo = record
  30. NumSubKeys: Integer;
  31. MaxSubKeyLen: Integer;
  32. NumValues: Integer;
  33. MaxValueLen: Integer;
  34. MaxDataLen: Integer;
  35. FileTime: TDateTime;
  36. end;
  37. TRegDataType = (rdUnknown, rdString, rdExpandString, rdBinary, rdInteger, rdIntegerBigEndian,
  38. rdLink, rdMultiString, rdResourceList, rdFullResourceDescriptor, rdResourceRequirementList, rdInt64);
  39. TRegDataInfo = record
  40. RegData: TRegDataType;
  41. DataSize: Integer;
  42. end;
  43. TUnicodeStringArray = Array of UnicodeString;
  44. { ---------------------------------------------------------------------
  45. TRegistry
  46. ---------------------------------------------------------------------}
  47. { TRegistry }
  48. TRegistry = class(TObject)
  49. private
  50. FLastError: Longint;
  51. FStringSizeIncludesNull : Boolean;
  52. FSysData : Pointer;
  53. fAccess: LongWord;
  54. fCurrentKey: HKEY;
  55. fRootKey: HKEY;
  56. fLazyWrite: Boolean;
  57. fCurrentPath: UnicodeString;
  58. function FixPath(APath: UnicodeString): UnicodeString;
  59. function GetLastErrorMsg: string;
  60. function RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
  61. function ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
  62. procedure ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
  63. procedure SetRootKey(Value: HKEY);
  64. Procedure SysRegCreate;
  65. Procedure SysRegFree;
  66. Function SysGetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
  67. Function SysPutData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
  68. Function SysCreateKey(Key: UnicodeString): Boolean;
  69. protected
  70. function GetBaseKey(Relative: Boolean): HKey;
  71. function GetData(const Name: UnicodeString; Buffer: Pointer;
  72. BufSize: Integer; Out RegData: TRegDataType): Integer;
  73. function GetData(const Name: AnsiString; Buffer: Pointer;
  74. BufSize: Integer; Out RegData: TRegDataType): Integer;
  75. function GetKey(Key: UnicodeString): HKEY;
  76. function GetKey(Key: AnsiString): HKEY;
  77. procedure ChangeKey(Value: HKey; const Path: UnicodeString);
  78. procedure ChangeKey(Value: HKey; const Path: AnsiString);
  79. procedure PutData(const Name: UnicodeString; Buffer: Pointer;
  80. BufSize: Integer; RegData: TRegDataType);
  81. procedure PutData(const Name: AnsiString; Buffer: Pointer;
  82. BufSize: Integer; RegData: TRegDataType);
  83. procedure SetCurrentKey(Value: HKEY);
  84. public
  85. constructor Create; overload;
  86. constructor Create(aaccess:longword); overload;
  87. destructor Destroy; override;
  88. function CreateKey(const Key: UnicodeString): Boolean;
  89. function CreateKey(const Key: AnsiString): Boolean;
  90. function DeleteKey(const Key: UnicodeString): Boolean;
  91. function DeleteKey(const Key: AnsiString): Boolean;
  92. function DeleteValue(const Name: UnicodeString): Boolean;
  93. function DeleteValue(const Name: AnsiString): Boolean;
  94. function GetDataInfo(const ValueName: UnicodeString; Out Value: TRegDataInfo): Boolean;
  95. function GetDataInfo(const ValueName: AnsiString; Out Value: TRegDataInfo): Boolean;
  96. function GetDataSize(const ValueName: UnicodeString): Integer;
  97. function GetDataSize(const ValueName: AnsiString): Integer;
  98. function GetDataType(const ValueName: UnicodeString): TRegDataType;
  99. function GetDataType(const ValueName: AnsiString): TRegDataType;
  100. function GetKeyInfo(Out Value: TRegKeyInfo): Boolean;
  101. function HasSubKeys: Boolean;
  102. function KeyExists(const Key: UnicodeString): Boolean;
  103. function KeyExists(const Key: AnsiString): Boolean;
  104. function LoadKey(const Key, FileName: UnicodeString): Boolean; unimplemented;
  105. function LoadKey(const Key, FileName: AnsiString): Boolean; unimplemented;
  106. function OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
  107. function OpenKey(const Key: AnsiString; CanCreate: Boolean): Boolean;
  108. function OpenKeyReadOnly(const Key: UnicodeString): Boolean;
  109. function OpenKeyReadOnly(const Key: AnsiString): Boolean;
  110. function ReadCurrency(const Name: UnicodeString): Currency;
  111. function ReadCurrency(const Name: AnsiString): Currency;
  112. function ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
  113. function ReadBinaryData(const Name: AnsiString; var Buffer; BufSize: Integer): Integer;
  114. function ReadBool(const Name: UnicodeString): Boolean;
  115. function ReadBool(const Name: AnsiString): Boolean;
  116. function ReadDate(const Name: UnicodeString): TDateTime;
  117. function ReadDate(const Name: AnsiString): TDateTime;
  118. function ReadDateTime(const Name: UnicodeString): TDateTime;
  119. function ReadDateTime(const Name: AnsiString): TDateTime;
  120. function ReadFloat(const Name: UnicodeString): Double;
  121. function ReadFloat(const Name: AnsiString): Double;
  122. function ReadInteger(const Name: UnicodeString): Integer;
  123. function ReadInteger(const Name: AnsiString): Integer;
  124. function ReadInt64(const Name: UnicodeString): Int64;
  125. function ReadInt64(const Name: AnsiString): Int64;
  126. function ReadString(const Name: UnicodeString): UnicodeString;
  127. function ReadString(const Name: AnsiString): string;
  128. procedure ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
  129. procedure ReadStringList(const Name: AnsiString; AList: TStrings);
  130. function ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
  131. function ReadStringArray(const Name: AnsiString): TStringArray;
  132. function ReadTime(const Name: UnicodeString): TDateTime;
  133. function ReadTime(const Name: AnsiString): TDateTime;
  134. function RegistryConnect(const UNCName: UnicodeString): Boolean;
  135. function RegistryConnect(const UNCName: AnsiString): Boolean;
  136. function ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean; unimplemented;
  137. function ReplaceKey(const Key, FileName, BackUpFileName: AnsiString): Boolean; unimplemented;
  138. function RestoreKey(const Key, FileName: UnicodeString): Boolean; unimplemented;
  139. function RestoreKey(const Key, FileName: AnsiString): Boolean; unimplemented;
  140. function SaveKey(const Key, FileName: UnicodeString): Boolean;
  141. function SaveKey(const Key, FileName: AnsiString): Boolean;
  142. function UnLoadKey(const Key: UnicodeString): Boolean;
  143. function UnLoadKey(const Key: AnsiString): Boolean;
  144. function ValueExists(const Name: UnicodeString): Boolean;
  145. function ValueExists(const Name: AnsiString): Boolean;
  146. procedure CloseKey;
  147. procedure CloseKey(key:HKEY);
  148. procedure GetKeyNames(Strings: TStrings);
  149. function GetKeyNames: TUnicodeStringArray;
  150. procedure GetValueNames(Strings: TStrings);
  151. //ToDo
  152. function GetValueNames: TUnicodeStringArray;
  153. procedure MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean); unimplemented;
  154. procedure MoveKey(const OldName, NewName: AnsiString; Delete: Boolean); unimplemented;
  155. procedure RenameValue(const OldName, NewName: UnicodeString);
  156. procedure RenameValue(const OldName, NewName: AnsiString);
  157. procedure WriteCurrency(const Name: UnicodeString; Value: Currency);
  158. procedure WriteCurrency(const Name: AnsiString; Value: Currency);
  159. procedure WriteBinaryData(const Name: UnicodeString; const Buffer; BufSize: Integer);
  160. procedure WriteBinaryData(const Name: AnsiString; const Buffer; BufSize: Integer);
  161. procedure WriteBool(const Name: UnicodeString; Value: Boolean);
  162. procedure WriteBool(const Name: AnsiString; Value: Boolean);
  163. procedure WriteDate(const Name: UnicodeString; Value: TDateTime);
  164. procedure WriteDate(const Name: AnsiString; Value: TDateTime);
  165. procedure WriteDateTime(const Name: UnicodeString; Value: TDateTime);
  166. procedure WriteDateTime(const Name: AnsiString; Value: TDateTime);
  167. procedure WriteFloat(const Name: UnicodeString; Value: Double);
  168. procedure WriteFloat(const Name: AnsiString; Value: Double);
  169. procedure WriteInteger(const Name: UnicodeString; Value: Integer);
  170. procedure WriteInteger(const Name: AnsiString; Value: Integer);
  171. procedure WriteInt64(const Name: UnicodeString; Value: Int64);
  172. procedure WriteInt64(const Name: AnsiString; Value: Int64);
  173. procedure WriteString(const Name, Value: UnicodeString);
  174. procedure WriteString(const Name, Value: AnsiString);
  175. procedure WriteExpandString(const Name, Value: UnicodeString);
  176. procedure WriteExpandString(const Name, Value: AnsiString);
  177. procedure WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
  178. procedure WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
  179. procedure WriteStringArray(const Name: AnsiString; const Arr: TStringArray);
  180. procedure WriteTime(const Name: UnicodeString; Value: TDateTime);
  181. procedure WriteTime(const Name: AnsiString; Value: TDateTime);
  182. property Access: LongWord read fAccess write fAccess;
  183. property CurrentKey: HKEY read fCurrentKey;
  184. property CurrentPath: UnicodeString read fCurrentPath;
  185. property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
  186. property RootKey: HKEY read fRootKey write SetRootKey;
  187. Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
  188. property LastError: Longint read FLastError; platform;
  189. property LastErrorMsg: string read GetLastErrorMsg; platform;
  190. end;
  191. { ---------------------------------------------------------------------
  192. TRegIniFile
  193. ---------------------------------------------------------------------}
  194. TRegIniFile = class(TRegistry)
  195. private
  196. fFileName : String;
  197. fPath : String;
  198. fPreferStringValues: Boolean;
  199. fOldCurKey : HKEY;
  200. fOldCurPath : UnicodeString;
  201. function OpenSection(const Section: string; CreateSection : Boolean = false): boolean;
  202. procedure CloseSection;
  203. public
  204. constructor Create(const FN: string); overload;
  205. constructor Create(const FN: string;aaccess:longword); overload;
  206. function ReadString(const Section, Ident, Default: string): string;
  207. function ReadInteger(const Section, Ident: string; Default: Longint): Longint;
  208. function ReadBool(const Section, Ident: string; Default: Boolean): Boolean;
  209. function ReadDate(const Section, Ident: string; Default: TDateTime):TDateTime;
  210. function ReadDateTime(const Section, Ident: string; Default: TDateTime):TDateTime;
  211. function ReadTime(const Section, Ident: string; Default: TDateTime):TDateTime;
  212. function ReadFloat(const Section, Ident: string; Default: Double): Double;
  213. procedure WriteString(const Section, Ident, Value: String);
  214. procedure WriteInteger(const Section, Ident: string; Value: Longint);
  215. procedure WriteBool(const Section, Ident: string; Value: Boolean);
  216. procedure WriteDate(const Section, Ident: string; Value: TDateTime);
  217. procedure WriteDateTime(const Section, Ident: string; Value: TDateTime);
  218. procedure WriteTime(const Section, Ident: string; Value: TDateTime);
  219. procedure WriteFloat(const Section, Ident: string; Value: Double);
  220. procedure ReadSection(const Section: string; Strings: TStrings);
  221. procedure ReadSections(Strings: TStrings);
  222. procedure ReadSectionValues(const Section: string; Strings: TStrings);
  223. procedure EraseSection(const Section: string);
  224. procedure DeleteKey(const Section, Ident: String);
  225. property FileName: String read fFileName;
  226. property PreferStringValues: Boolean read fPreferStringValues
  227. write fPreferStringValues;
  228. end{$ifdef XMLREG}deprecated 'Use TRegistry instead. Will be removed in 4.0'{$endif} platform;
  229. { ---------------------------------------------------------------------
  230. TRegIniFile
  231. ---------------------------------------------------------------------}
  232. TRegistryIniFile = class(TCustomIniFile)
  233. private
  234. FRegIniFile: TRegIniFile;
  235. public
  236. constructor Create(const AFileName: string); overload;
  237. constructor Create(const AFileName: string; AAccess: LongWord); overload;
  238. destructor destroy; override;
  239. function ReadDate(const Section, Name: string; Default: TDateTime): TDateTime; override;
  240. function ReadDateTime(const Section, Name: string; Default: TDateTime): TDateTime; override;
  241. function ReadInteger(const Section, Name: string; Default: Longint): Longint; override;
  242. function ReadFloat(const Section, Name: string; Default: Double): Double; override;
  243. function ReadString(const Section, Name, Default: string): string; override;
  244. function ReadTime(const Section, Name: string; Default: TDateTime): TDateTime; override;
  245. function ReadBinaryStream(const Section, Name: string; Value: TStream): Integer; override; unimplemented;
  246. procedure WriteDate(const Section, Name: string; Value: TDateTime); override;
  247. procedure WriteDateTime(const Section, Name: string; Value: TDateTime); override;
  248. procedure WriteFloat(const Section, Name: string; Value: Double); override;
  249. procedure WriteInteger(const Section, Name: string; Value: Longint); override;
  250. procedure WriteString(const Section, Name, Value: String); override;
  251. procedure WriteTime(const Section, Name: string; Value: TDateTime); override;
  252. procedure WriteBinaryStream(const Section, Name: string; Value: TStream); override;
  253. procedure ReadSection(const Section: string; Strings: TStrings); override;
  254. procedure ReadSections(Strings: TStrings); override;
  255. procedure ReadSectionValues(const Section: string; Strings: TStrings); override;
  256. procedure EraseSection(const Section: string); override;
  257. procedure DeleteKey(const Section, Name: String); override;
  258. procedure UpdateFile; override;
  259. function ValueExists(const Section, Ident: string): Boolean; override;
  260. function SectionExists(const Section: string): Boolean; override;
  261. property RegIniFile: TRegIniFile read FRegIniFile;
  262. end{$ifdef XMLREG}deprecated 'Use TRegistry instead. Will be removed in 4.0'{$endif} platform;
  263. ResourceString
  264. SInvalidRegType = 'Invalid registry data type: "%s"';
  265. SRegCreateFailed = 'Failed to create key: "%s"';
  266. SRegSetDataFailed = 'Failed to set data for value "%s"';
  267. SRegGetDataFailed = 'Failed to get data for value "%s"';
  268. var
  269. GlobalXMLFile : Boolean = False;
  270. implementation
  271. { ---------------------------------------------------------------------
  272. Include implementation-dependent code
  273. ---------------------------------------------------------------------}
  274. {$ifdef XMLREG}
  275. {$i xregreg.inc}
  276. {$else}
  277. {$i winreg.inc}
  278. {$endif}
  279. { ---------------------------------------------------------------------
  280. Generic, implementation-independent code.
  281. ---------------------------------------------------------------------}
  282. {$ifdef DebugRegistry}
  283. function DbgS(const S: UnicodeString): String;
  284. var
  285. C: WideChar;
  286. begin
  287. Result := '';
  288. for C in S do Result := Result + IntToHex(Word(C),4) + #32;
  289. Result := TrimRight(Result);
  290. end;
  291. {$endif}
  292. constructor TRegistry.Create;
  293. begin
  294. inherited Create;
  295. FAccess := KEY_ALL_ACCESS;
  296. FRootKey := HKEY_CURRENT_USER;
  297. FLazyWrite := True;
  298. FCurrentKey := 0;
  299. SysRegCreate;
  300. end;
  301. constructor TRegistry.Create(aaccess: longword);
  302. begin
  303. Create;
  304. FAccess := aaccess;
  305. end;
  306. destructor TRegistry.Destroy;
  307. begin
  308. CloseKey;
  309. SysRegFree;
  310. inherited Destroy;
  311. end;
  312. function TRegistry.CreateKey(const Key: UnicodeString): Boolean;
  313. begin
  314. Result:=SysCreateKey(Key);
  315. If Not Result Then
  316. Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
  317. end;
  318. function TRegistry.CreateKey(const Key: AnsiString): Boolean;
  319. begin
  320. Result:=CreateKey(UnicodeString(Key));
  321. end;
  322. function TRegistry.DeleteKey(const Key: AnsiString): Boolean;
  323. begin
  324. Result:=DeleteKey(UnicodeString(Key));
  325. end;
  326. function TRegistry.DeleteValue(const Name: AnsiString): Boolean;
  327. begin
  328. Result:=DeleteValue(UnicodeString(Name));
  329. end;
  330. function TRegistry.GetDataInfo(const ValueName: AnsiString; out Value: TRegDataInfo
  331. ): Boolean;
  332. begin
  333. Result:=GetDataInfo(UnicodeString(ValueName), Value);
  334. end;
  335. function TRegistry.GetBaseKey(Relative: Boolean): HKey;
  336. begin
  337. If Relative and (CurrentKey<>0) Then
  338. Result := CurrentKey
  339. else
  340. Result := RootKey;
  341. end;
  342. function TRegistry.GetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
  343. begin
  344. Result:=SysGetData(Name,Buffer,BufSize,RegData);
  345. If (Result=-1) then
  346. Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
  347. end;
  348. function TRegistry.GetData(const Name: AnsiString; Buffer: Pointer;
  349. BufSize: Integer; out RegData: TRegDataType): Integer;
  350. begin
  351. Result:=GetData(UnicodeString(Name), Buffer, BufSize, RegData);
  352. end;
  353. function TRegistry.GetKey(Key: AnsiString): HKEY;
  354. begin
  355. Result:=GetKey(UnicodeString(Key));
  356. end;
  357. procedure TRegistry.ChangeKey(Value: HKey; const Path: AnsiString);
  358. begin
  359. ChangeKey(Value, UnicodeString(Path));
  360. end;
  361. procedure TRegistry.PutData(const Name: UnicodeString; Buffer: Pointer;
  362. BufSize: Integer; RegData: TRegDataType);
  363. begin
  364. If Not SysPutData(Name,Buffer,BufSize,RegData) then
  365. Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
  366. end;
  367. procedure TRegistry.PutData(const Name: AnsiString; Buffer: Pointer;
  368. BufSize: Integer; RegData: TRegDataType);
  369. begin
  370. PutData(UnicodeString(Name), Buffer, BufSize, RegData);
  371. end;
  372. function TRegistry.GetDataSize(const ValueName: UnicodeString): Integer;
  373. Var
  374. Info: TRegDataInfo;
  375. begin
  376. If GetDataInfo(ValueName,Info) Then
  377. Result := Info.DataSize
  378. else
  379. Result := -1;
  380. end;
  381. function TRegistry.GetDataSize(const ValueName: AnsiString): Integer;
  382. begin
  383. Result:=GetDataSize(UnicodeString(ValueName));
  384. end;
  385. function TRegistry.GetDataType(const ValueName: UnicodeString): TRegDataType;
  386. Var
  387. Info: TRegDataInfo;
  388. begin
  389. GetDataInfo(ValueName, Info);
  390. Result:=Info.RegData;
  391. end;
  392. function TRegistry.GetDataType(const ValueName: AnsiString): TRegDataType;
  393. begin
  394. Result:=GetDataType(UnicodeString(ValueName));
  395. end;
  396. function TRegistry.KeyExists(const Key: AnsiString): Boolean;
  397. begin
  398. Result:=KeyExists(UnicodeString(Key));
  399. end;
  400. function TRegistry.LoadKey(const Key, FileName: AnsiString): Boolean;
  401. begin
  402. Result:=LoadKey(UnicodeString(Key), UnicodeString(FileName));
  403. end;
  404. function TRegistry.OpenKey(const Key: AnsiString; CanCreate: Boolean): Boolean;
  405. begin
  406. Result:=OpenKey(UnicodeString(Key), CanCreate);
  407. end;
  408. function TRegistry.OpenKeyReadOnly(const Key: AnsiString): Boolean;
  409. begin
  410. Result:=OpenKeyReadOnly(UnicodeString(Key));
  411. end;
  412. function TRegistry.HasSubKeys: Boolean;
  413. Var
  414. Info : TRegKeyInfo;
  415. begin
  416. Result:=GetKeyInfo(Info);
  417. If Result then
  418. Result:=(Info.NumSubKeys>0);
  419. end;
  420. function TRegistry.ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
  421. Var
  422. RegDataType: TRegDataType;
  423. begin
  424. Result := GetData(Name, @Buffer, BufSize, RegDataType);
  425. end;
  426. function TRegistry.ReadBinaryData(const Name: AnsiString; var Buffer;
  427. BufSize: Integer): Integer;
  428. begin
  429. Result:=ReadBinaryData(UnicodeString(Name), Buffer, BufSize);
  430. end;
  431. function TRegistry.ReadInteger(const Name: UnicodeString): Integer;
  432. Var
  433. RegDataType: TRegDataType;
  434. begin
  435. GetData(Name, @Result, SizeOf(Integer), RegDataType);
  436. If RegDataType<>rdInteger Then
  437. Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
  438. end;
  439. function TRegistry.ReadInteger(const Name: AnsiString): Integer;
  440. begin
  441. Result:=ReadInteger(UnicodeString(Name));
  442. end;
  443. function TRegistry.ReadInt64(const Name: UnicodeString): Int64;
  444. Var
  445. RegDataType: TRegDataType;
  446. begin
  447. GetData(Name, @Result, SizeOf(Int64), RegDataType);
  448. If RegDataType<>rdInt64 Then
  449. Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
  450. end;
  451. function TRegistry.ReadInt64(const Name: AnsiString): Int64;
  452. begin
  453. Result:=ReadInt64(UnicodeString(Name));
  454. end;
  455. function TRegistry.ReadBool(const Name: UnicodeString): Boolean;
  456. begin
  457. Result:=ReadInteger(Name)<>0;
  458. end;
  459. function TRegistry.ReadBool(const Name: AnsiString): Boolean;
  460. begin
  461. Result:=ReadBool(UnicodeString(Name));
  462. end;
  463. function TRegistry.ReadCurrency(const Name: UnicodeString): Currency;
  464. begin
  465. Result:=Default(Currency);
  466. ReadBinaryData(Name, Result, SizeOf(Currency));
  467. end;
  468. function TRegistry.ReadCurrency(const Name: AnsiString): Currency;
  469. begin
  470. Result:=ReadCurrency(UnicodeString(Name));
  471. end;
  472. function TRegistry.ReadDate(const Name: UnicodeString): TDateTime;
  473. begin
  474. Result:=Trunc(ReadDateTime(Name));
  475. end;
  476. function TRegistry.ReadDate(const Name: AnsiString): TDateTime;
  477. begin
  478. Result:=ReadDate(UnicodeString(Name));
  479. end;
  480. function TRegistry.ReadDateTime(const Name: UnicodeString): TDateTime;
  481. begin
  482. Result:=Default(TDateTime);
  483. ReadBinaryData(Name, Result, SizeOf(TDateTime));
  484. end;
  485. function TRegistry.ReadDateTime(const Name: AnsiString): TDateTime;
  486. begin
  487. Result:=ReadDateTime(UnicodeString(Name));
  488. end;
  489. function TRegistry.ReadFloat(const Name: UnicodeString): Double;
  490. begin
  491. Result:=Default(Double);
  492. ReadBinaryData(Name,Result,SizeOf(Double));
  493. end;
  494. function TRegistry.ReadFloat(const Name: AnsiString): Double;
  495. begin
  496. Result:=ReadFloat(UnicodeString(Name));
  497. end;
  498. function TRegistry.ReadString(const Name: UnicodeString): UnicodeString;
  499. Var
  500. Info : TRegDataInfo;
  501. ReadDataSize: Integer;
  502. u: UnicodeString;
  503. begin
  504. Result:='';
  505. GetDataInfo(Name,Info);
  506. if info.datasize>0 then
  507. begin
  508. if Not (Info.RegData in [rdString,rdExpandString]) then
  509. Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
  510. if Odd(Info.DataSize) then
  511. SetLength(u,round((Info.DataSize+1)/SizeOf(UnicodeChar)))
  512. else
  513. SetLength(u,round(Info.DataSize/SizeOf(UnicodeChar)));
  514. ReadDataSize := GetData(Name,@u[1],Info.DataSize,Info.RegData);
  515. if ReadDataSize > 0 then
  516. begin
  517. // If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type,
  518. // the size includes any terminating null character or characters
  519. // unless the data was stored without them! (RegQueryValueEx @ MSDN)
  520. if StringSizeIncludesNull and
  521. (u[Length(u)] = WideChar(0)) then
  522. SetLength(u,Length(u)-1);
  523. Result:=u;
  524. end;
  525. end;
  526. end;
  527. function TRegistry.ReadString(const Name: AnsiString): string;
  528. begin
  529. Result:=ReadString(UnicodeString(Name));
  530. end;
  531. procedure TRegistry.ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
  532. Var
  533. UArr: TUnicodeStringArray;
  534. begin
  535. UArr := ReadStringArray(Name);
  536. ArrayToList(UArr, AList, ForceUtf8);
  537. end;
  538. procedure TRegistry.ReadStringList(const Name: AnsiString; AList: TStrings);
  539. begin
  540. ReadStringList(UnicodeString(Name), AList);
  541. end;
  542. function TRegistry.FixPath(APath: UnicodeString): UnicodeString;
  543. const
  544. Delim={$ifdef XMLREG}'/'{$else}'\'{$endif};
  545. begin
  546. //At this point we know the path is valid, since this is only called after OpenKey succeeded
  547. //Just sanitize it
  548. while (Pos(Delim+Delim,APath) > 0) do
  549. APath := UnicodeStringReplace(APath, Delim+Delim,Delim,[rfReplaceAll]);
  550. if (Length(APath) > 1) and (APath[Length(APath)] = Delim) then
  551. System.Delete(APath, Length(APath), 1);
  552. Result := APath;
  553. end;
  554. function TRegistry.RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
  555. var
  556. Len, i, p: Integer;
  557. Sub: UnicodeString;
  558. begin
  559. Result := nil;
  560. if (U = '') then Exit;
  561. Len := 1;
  562. for i := 1 to Length(U) do if (U[i] = #0) then Inc(Len);
  563. SetLength(Result, Len);
  564. i := 0;
  565. while (U <> '') and (i < Length(Result)) do
  566. begin
  567. p := Pos(#0, U);
  568. if (p = 0) then p := Length(U) + 1;
  569. Sub := Copy(U, 1, p - 1);
  570. Result[i] := Sub;
  571. System.Delete(U, 1, p);
  572. Inc(i);
  573. end;
  574. end;
  575. function TRegistry.ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
  576. var
  577. i, curr, Len: Integer;
  578. u: UnicodeString;
  579. begin
  580. Result := nil;
  581. Len := List.Count;
  582. SetLength(Result, Len);
  583. //REG_MULTI_SZ data cannot contain empty strings
  584. curr := 0;
  585. for i := 0 to List.Count - 1 do
  586. begin
  587. if IsUtf8 then
  588. u := Utf8Decode(List[i])
  589. else
  590. u := List[i];
  591. if (u>'') then
  592. begin
  593. Result[curr] := u;
  594. inc(curr);
  595. end
  596. else
  597. Dec(Len);
  598. end;
  599. if (Len <> List.Count) then SetLength(Result, Len);
  600. end;
  601. procedure TRegistry.ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
  602. var
  603. i: Integer;
  604. begin
  605. List.Clear;
  606. for i := Low(Arr) to High(Arr) do
  607. begin
  608. if ForceUtf8 then
  609. List.Add(Utf8Encode(Arr[i]))
  610. else
  611. List.Add(String(Arr[i]));
  612. end;
  613. end;
  614. function TRegistry.ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
  615. Var
  616. Info : TRegDataInfo;
  617. ReadDataSize: Integer;
  618. Data: UnicodeString;
  619. begin
  620. Result := nil;
  621. GetDataInfo(Name,Info);
  622. //writeln('TRegistry.ReadStringArray: datasize=',info.datasize);
  623. if info.datasize>0 then
  624. begin
  625. If Not (Info.RegData in [rdMultiString]) then
  626. Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
  627. SetLength(Data,Info.DataSize);
  628. ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
  629. //writeln('TRegistry.ReadStringArray: ReadDataSize=',ReadDataSize);
  630. if ReadDataSize > 0 then
  631. begin
  632. // Windows returns the data with or without trailing zero's, so just strip all trailing null characters
  633. while (Data[ReadDataSize] = #0) do Dec(ReadDataSize);
  634. SetLength(Data, ReadDataSize);
  635. //writeln('Data=',dbgs(data));
  636. //Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
  637. //AList.Text := Data;
  638. Result := RegMultiSzDataToUnicodeStringArray(Data);
  639. end
  640. end
  641. end;
  642. function TRegistry.ReadStringArray(const Name: AnsiString): TStringArray;
  643. var
  644. UArr: TUnicodeStringArray;
  645. i: Integer;
  646. begin
  647. Result := nil;
  648. UArr := ReadStringArray(UnicodeString(Name));
  649. SetLength(Result, Length(UArr));
  650. for i := Low(UArr) to High(UArr) do Result[i] := UArr[i];
  651. end;
  652. function TRegistry.ReadTime(const Name: UnicodeString): TDateTime;
  653. begin
  654. Result:=Frac(ReadDateTime(Name));
  655. end;
  656. function TRegistry.ReadTime(const Name: AnsiString): TDateTime;
  657. begin
  658. Result:=ReadTime(UnicodeString(Name));
  659. end;
  660. function TRegistry.RegistryConnect(const UNCName: AnsiString): Boolean;
  661. begin
  662. Result:=RegistryConnect(UnicodeString(UNCName));
  663. end;
  664. function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: AnsiString): Boolean;
  665. begin
  666. Result:=ReplaceKey(UnicodeString(Key), UnicodeString(FileName), UnicodeString(BackUpFileName))
  667. end;
  668. function TRegistry.RestoreKey(const Key, FileName: AnsiString): Boolean;
  669. begin
  670. Result:=RestoreKey(UnicodeString(Key), UnicodeString(FileName));
  671. end;
  672. function TRegistry.SaveKey(const Key, FileName: AnsiString): Boolean;
  673. begin
  674. Result:=SaveKey(UnicodeString(Key), UnicodeString(FileName));
  675. end;
  676. function TRegistry.UnLoadKey(const Key: AnsiString): Boolean;
  677. begin
  678. Result:=UnloadKey(UnicodeString(Key));
  679. end;
  680. function TRegistry.ValueExists(const Name: AnsiString): Boolean;
  681. begin
  682. Result:=ValueExists(UnicodeString(Name));
  683. end;
  684. procedure TRegistry.WriteBinaryData(const Name: UnicodeString; const Buffer; BufSize: Integer);
  685. begin
  686. PutData(Name, @Buffer, BufSize, rdBinary);
  687. end;
  688. procedure TRegistry.WriteBinaryData(const Name: AnsiString; const Buffer;
  689. BufSize: Integer);
  690. begin
  691. WriteBinaryData(UnicodeString(Name), Buffer, BufSize);
  692. end;
  693. procedure TRegistry.WriteBool(const Name: UnicodeString; Value: Boolean);
  694. begin
  695. WriteInteger(Name,Ord(Value));
  696. end;
  697. procedure TRegistry.WriteBool(const Name: AnsiString; Value: Boolean);
  698. begin
  699. WriteBool(UnicodeString(Name), Value);
  700. end;
  701. procedure TRegistry.WriteCurrency(const Name: UnicodeString; Value: Currency);
  702. begin
  703. WriteBinaryData(Name, Value, SizeOf(Currency));
  704. end;
  705. procedure TRegistry.WriteCurrency(const Name: AnsiString; Value: Currency);
  706. begin
  707. WriteCurrency(UnicodeString(Name), Value);
  708. end;
  709. procedure TRegistry.WriteDate(const Name: UnicodeString; Value: TDateTime);
  710. begin
  711. WriteBinarydata(Name, Value, SizeOf(TDateTime));
  712. end;
  713. procedure TRegistry.WriteDate(const Name: AnsiString; Value: TDateTime);
  714. begin
  715. WriteDate(UnicodeString(Name), Value);
  716. end;
  717. procedure TRegistry.WriteTime(const Name: UnicodeString; Value: TDateTime);
  718. begin
  719. WriteBinaryData(Name, Value, SizeOf(TDateTime));
  720. end;
  721. procedure TRegistry.WriteTime(const Name: AnsiString; Value: TDateTime);
  722. begin
  723. WriteTime(UnicodeString(Name), Value);
  724. end;
  725. procedure TRegistry.WriteDateTime(const Name: UnicodeString; Value: TDateTime);
  726. begin
  727. WriteBinaryData(Name, Value, SizeOf(TDateTime));
  728. end;
  729. procedure TRegistry.WriteDateTime(const Name: AnsiString; Value: TDateTime);
  730. begin
  731. WriteDateTime(UnicodeString(Name), Value);
  732. end;
  733. procedure TRegistry.WriteExpandString(const Name, Value: UnicodeString);
  734. begin
  735. PutData(Name, PWideChar(Value), ByteLength(Value), rdExpandString);
  736. end;
  737. procedure TRegistry.WriteExpandString(const Name, Value: AnsiString);
  738. begin
  739. WriteExpandString(UnicodeString(Name), UnicodeString(Value));
  740. end;
  741. procedure TRegistry.WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
  742. Var
  743. UArr: TUnicodeStringArray;
  744. begin
  745. UArr := ListToArray(List, IsUtf8);
  746. WriteStringArray(Name, UArr);
  747. end;
  748. procedure TRegistry.WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
  749. Var
  750. Data: UnicodeString;
  751. u: UnicodeString;
  752. i: Integer;
  753. begin
  754. Data := '';
  755. //REG_MULTI_SZ data cannot contain empty strings
  756. for i := Low(Arr) to High(Arr) do
  757. begin
  758. u := Arr[i];
  759. if (u>'') then
  760. begin
  761. if (Data>'') then
  762. Data := Data + #0 + u
  763. else
  764. Data := Data + u;
  765. end;
  766. end;
  767. if StringSizeIncludesNull then
  768. Data := Data + #0#0;
  769. //writeln('Data=',Dbgs(Data));
  770. PutData(Name, PWideChar(Data), ByteLength(Data), rdMultiString);
  771. end;
  772. procedure TRegistry.WriteStringArray(const Name: AnsiString; const Arr: TStringArray);
  773. var
  774. UArr: TUnicodeStringArray;
  775. i: Integer;
  776. begin
  777. UArr := nil;
  778. SetLength(UArr, Length(Arr));
  779. for i := Low(Arr) to High(Arr) do UArr[i] := Arr[i];
  780. WriteStringArray(UnicodeString(Name), UArr);
  781. end;
  782. procedure TRegistry.WriteFloat(const Name: UnicodeString; Value: Double);
  783. begin
  784. WriteBinaryData(Name, Value, SizeOf(Double));
  785. end;
  786. procedure TRegistry.WriteFloat(const Name: AnsiString; Value: Double);
  787. begin
  788. WriteFloat(UnicodeString(Name), Value);
  789. end;
  790. procedure TRegistry.WriteInteger(const Name: UnicodeString; Value: Integer);
  791. begin
  792. PutData(Name, @Value, SizeOf(Integer), rdInteger);
  793. end;
  794. procedure TRegistry.WriteInteger(const Name: AnsiString; Value: Integer);
  795. begin
  796. WriteInteger(UnicodeString(Name), Value);
  797. end;
  798. procedure TRegistry.WriteInt64(const Name: UnicodeString; Value: Int64);
  799. begin
  800. PutData(Name, @Value, SizeOf(Int64), rdInt64);
  801. end;
  802. procedure TRegistry.WriteInt64(const Name: AnsiString; Value: Int64);
  803. begin
  804. WriteInt64(UnicodeString(Name), Value);
  805. end;
  806. procedure TRegistry.WriteString(const Name, Value: UnicodeString);
  807. begin
  808. PutData(Name, PWideChar(Value), ByteLength(Value), rdString);
  809. end;
  810. procedure TRegistry.WriteString(const Name, Value: AnsiString);
  811. begin
  812. WriteString(UnicodeString(Name), UnicodeString(Value));
  813. end;
  814. procedure TRegistry.GetKeyNames(Strings: TStrings);
  815. var
  816. UArr: TUnicodeStringArray;
  817. begin
  818. UArr := GetKeyNames;
  819. ArrayToList(UArr, Strings, True);
  820. end;
  821. procedure TRegistry.GetValueNames(Strings: TStrings);
  822. var
  823. UArr: TUnicodeStringArray;
  824. begin
  825. UArr := GetValueNames;
  826. ArrayToList(UArr, Strings, True);
  827. end;
  828. procedure TRegistry.MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
  829. begin
  830. end;
  831. procedure TRegistry.MoveKey(const OldName, NewName: AnsiString; Delete: Boolean);
  832. begin
  833. MoveKey(UnicodeString(OldName), UnicodeString(NewName), Delete);
  834. end;
  835. procedure TRegistry.RenameValue(const OldName, NewName: AnsiString);
  836. begin
  837. RenameValue(UnicodeString(OldName), UnicodeString(NewName));
  838. end;
  839. { ---------------------------------------------------------------------
  840. Include TRegIniFile implementation
  841. ---------------------------------------------------------------------}
  842. {$i regini.inc}
  843. { TRegistryIniFile }
  844. // interface from
  845. // http://www.koders.com/delphi/fid65C1FFAEF89B0CDC4B93FF94C1819686CA6141FC.aspx
  846. constructor TRegistryIniFile.Create(const AFileName: string;
  847. AAccess: LongWord);
  848. begin
  849. inherited create(AFilename);
  850. FRegInifile:=TreginiFile.Create(AFileName,AAccess);
  851. end;
  852. constructor TRegistryIniFile.Create(const AFileName: string);
  853. begin
  854. Create(AFileName,KEY_ALL_ACCESS);
  855. end;
  856. destructor TRegistryIniFile.destroy;
  857. begin
  858. FreeAndNil(FRegInifile);
  859. Inherited;
  860. end;
  861. procedure TRegistryIniFile.DeleteKey(const Section, Name: String);
  862. begin
  863. FRegIniFile.Deletekey(section,name);
  864. end;
  865. procedure TRegistryIniFile.EraseSection(const Section: string);
  866. begin
  867. FRegIniFile.EraseSection(section);
  868. end;
  869. function TRegistryIniFile.ReadBinaryStream(const Section, Name: string;
  870. Value: TStream): Integer;
  871. begin
  872. result:=-1; // unimplemented
  873. //
  874. end;
  875. function TRegistryIniFile.ReadDate(const Section, Name: string;
  876. Default: TDateTime): TDateTime;
  877. begin
  878. Result:=FRegInifile.ReadDate(Section,Name,Default);
  879. end;
  880. function TRegistryIniFile.ReadDateTime(const Section, Name: string;
  881. Default: TDateTime): TDateTime;
  882. begin
  883. Result:=FRegInifile.ReadDateTime(Section,Name,Default);
  884. end;
  885. function TRegistryIniFile.ReadFloat(const Section, Name: string;
  886. Default: Double): Double;
  887. begin
  888. Result:=FRegInifile.ReadFloat(Section,Name,Default);
  889. end;
  890. function TRegistryIniFile.ReadInteger(const Section, Name: string;
  891. Default: Integer): Longint;
  892. begin
  893. Result:=FRegInifile.ReadInteger(Section, Name, Default);
  894. end;
  895. procedure TRegistryIniFile.ReadSection(const Section: string; Strings: TStrings);
  896. begin
  897. FRegIniFile.ReadSection(Section,strings);
  898. end;
  899. procedure TRegistryIniFile.ReadSections(Strings: TStrings);
  900. begin
  901. FRegIniFile.ReadSections(strings);
  902. end;
  903. procedure TRegistryIniFile.ReadSectionValues(const Section: string;
  904. Strings: TStrings);
  905. begin
  906. FRegIniFile.ReadSectionValues(Section,strings);
  907. end;
  908. function TRegistryIniFile.ReadString(const Section, Name,
  909. Default: string): string;
  910. begin
  911. Result:=FRegInifile.ReadString(Section, Name, Default);
  912. end;
  913. function TRegistryIniFile.ReadTime(const Section, Name: string;
  914. Default: TDateTime): TDateTime;
  915. begin
  916. Result:=FRegInifile.ReadTime(Section,Name,Default);
  917. end;
  918. procedure TRegistryIniFile.UpdateFile;
  919. begin
  920. // FRegIniFile.UpdateFile; ??
  921. end;
  922. procedure TRegistryIniFile.WriteBinaryStream(const Section, Name: string;
  923. Value: TStream);
  924. begin
  925. // ??
  926. end;
  927. procedure TRegistryIniFile.WriteDate(const Section, Name: string;
  928. Value: TDateTime);
  929. begin
  930. FRegInifile.WriteDate(Section,Name, Value);
  931. end;
  932. procedure TRegistryIniFile.WriteDateTime(const Section, Name: string;
  933. Value: TDateTime);
  934. begin
  935. FRegInifile.WriteDateTime(Section,Name, Value);
  936. end;
  937. procedure TRegistryIniFile.WriteFloat(const Section, Name: string;
  938. Value: Double);
  939. begin
  940. FRegInifile.WriteFloat(Section,Name, Value);
  941. end;
  942. procedure TRegistryIniFile.WriteInteger(const Section, Name: string;
  943. Value: Integer);
  944. begin
  945. FRegInifile.WriteInteger(Section, Name, Value);
  946. end;
  947. procedure TRegistryIniFile.WriteString(const Section, Name, Value: String);
  948. begin
  949. FRegInifile.WriteString(Section, Name, Value);
  950. end;
  951. procedure TRegistryIniFile.WriteTime(const Section, Name: string;
  952. Value: TDateTime);
  953. begin
  954. FRegInifile.WriteTime(Section,Name, Value);
  955. end;
  956. function TRegistryIniFile.ValueExists(const Section, Ident: string): Boolean;
  957. begin
  958. Result:=FRegInifile.OpenSection(Section);
  959. if Result then
  960. try
  961. Result:=FRegInifile.ValueExists(Ident);
  962. finally
  963. FRegInifile.CloseSection;
  964. end;
  965. end;
  966. function TRegistryIniFile.SectionExists(const Section: string): Boolean;
  967. begin
  968. Result:=FRegIniFile.KeyExists(Section);
  969. end;
  970. {$ifdef XMLREG}
  971. finalization
  972. TXMLRegistryInstance.FreeXMLRegistryCache;
  973. {$endif}
  974. end.