registry.pp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. Unit registry;
  2. {$mode objfpc}
  3. {$H+}
  4. interface
  5. {$ifndef windows}
  6. {$define XMLREG}
  7. {$endif}
  8. Uses
  9. {$ifndef XMLREG}
  10. Windows,
  11. {$endif XMLREG}
  12. Classes,
  13. SysUtils,
  14. inifiles;
  15. {$I regdef.inc}
  16. type
  17. ERegistryException = class(Exception);
  18. TRegKeyInfo = record
  19. NumSubKeys: Integer;
  20. MaxSubKeyLen: Integer;
  21. NumValues: Integer;
  22. MaxValueLen: Integer;
  23. MaxDataLen: Integer;
  24. FileTime: TDateTime;
  25. end;
  26. TRegDataType = (rdUnknown, rdString, rdExpandString, rdBinary, rdInteger);
  27. TRegDataInfo = record
  28. RegData: TRegDataType;
  29. DataSize: Integer;
  30. end;
  31. { ---------------------------------------------------------------------
  32. TRegistry
  33. ---------------------------------------------------------------------}
  34. TRegistry = class(TObject)
  35. private
  36. FStringSizeIncludesNull : Boolean;
  37. {$ifdef XMLREG}
  38. FSysData : Pointer;
  39. {$endif XMLREG}
  40. fAccess: LongWord;
  41. fCurrentKey: HKEY;
  42. fRootKey: HKEY;
  43. fLazyWrite: Boolean;
  44. fCurrentPath: string;
  45. procedure SetRootKey(Value: HKEY);
  46. Procedure SysRegCreate;
  47. Procedure SysRegFree;
  48. Function SysGetData(const Name: String; Buffer: Pointer; BufSize: Integer; var RegData: TRegDataType): Integer;
  49. Function SysPutData(const Name: string; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
  50. Function SysCreateKey(const Key: String): Boolean;
  51. protected
  52. function GetBaseKey(Relative: Boolean): HKey;
  53. function GetData(const Name: string; Buffer: Pointer;
  54. BufSize: Integer; var RegData: TRegDataType): Integer;
  55. function GetKey(const Key: string): HKEY;
  56. procedure ChangeKey(Value: HKey; const Path: string);
  57. procedure PutData(const Name: string; Buffer: Pointer;
  58. BufSize: Integer; RegData: TRegDataType);
  59. procedure SetCurrentKey(Value: HKEY);
  60. public
  61. constructor Create; overload;
  62. constructor Create(aaccess:longword); overload;
  63. destructor Destroy; override;
  64. function CreateKey(const Key: string): Boolean;
  65. function DeleteKey(const Key: string): Boolean;
  66. function DeleteValue(const Name: string): Boolean;
  67. function GetDataInfo(const ValueName: string; var Value: TRegDataInfo): Boolean;
  68. function GetDataSize(const ValueName: string): Integer;
  69. function GetDataType(const ValueName: string): TRegDataType;
  70. function GetKeyInfo(var Value: TRegKeyInfo): Boolean;
  71. function HasSubKeys: Boolean;
  72. function KeyExists(const Key: string): Boolean;
  73. function LoadKey(const Key, FileName: string): Boolean;
  74. function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
  75. function OpenKeyReadOnly(const Key: string): Boolean;
  76. function ReadCurrency(const Name: string): Currency;
  77. function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
  78. function ReadBool(const Name: string): Boolean;
  79. function ReadDate(const Name: string): TDateTime;
  80. function ReadDateTime(const Name: string): TDateTime;
  81. function ReadFloat(const Name: string): Double;
  82. function ReadInteger(const Name: string): Integer;
  83. function ReadString(const Name: string): string;
  84. function ReadTime(const Name: string): TDateTime;
  85. function RegistryConnect(const UNCName: string): Boolean;
  86. function ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
  87. function RestoreKey(const Key, FileName: string): Boolean;
  88. function SaveKey(const Key, FileName: string): Boolean;
  89. function UnLoadKey(const Key: string): Boolean;
  90. function ValueExists(const Name: string): Boolean;
  91. procedure CloseKey;
  92. procedure CloseKey(key:HKEY);
  93. procedure GetKeyNames(Strings: TStrings);
  94. procedure GetValueNames(Strings: TStrings);
  95. procedure MoveKey(const OldName, NewName: string; Delete: Boolean);
  96. procedure RenameValue(const OldName, NewName: string);
  97. procedure WriteCurrency(const Name: string; Value: Currency);
  98. procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
  99. procedure WriteBool(const Name: string; Value: Boolean);
  100. procedure WriteDate(const Name: string; Value: TDateTime);
  101. procedure WriteDateTime(const Name: string; Value: TDateTime);
  102. procedure WriteFloat(const Name: string; Value: Double);
  103. procedure WriteInteger(const Name: string; Value: Integer);
  104. procedure WriteString(const Name, Value: string);
  105. procedure WriteExpandString(const Name, Value: string);
  106. procedure WriteTime(const Name: string; Value: TDateTime);
  107. property Access: LongWord read fAccess write fAccess;
  108. property CurrentKey: HKEY read fCurrentKey;
  109. property CurrentPath: string read fCurrentPath;
  110. property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
  111. property RootKey: HKEY read fRootKey write SetRootKey;
  112. Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
  113. end;
  114. { ---------------------------------------------------------------------
  115. TRegIniFile
  116. ---------------------------------------------------------------------}
  117. TRegIniFile = class(TRegistry)
  118. private
  119. fFileName : String;
  120. fPath : String;
  121. fPreferStringValues: Boolean;
  122. fOldCurKey : HKEY;
  123. function OpenSection(const Section: string): boolean;
  124. procedure CloseSection;
  125. public
  126. constructor Create(const FN: string); overload;
  127. constructor Create(const FN: string;aaccess:longword); overload;
  128. function ReadString(const Section, Ident, Default: string): string;
  129. function ReadInteger(const Section, Ident: string;
  130. Default: Longint): Longint;
  131. function ReadBool(const Section, Ident: string; Default: Boolean): Boolean;
  132. procedure WriteString(const Section, Ident, Value: String);
  133. procedure WriteInteger(const Section, Ident: string; Value: Longint);
  134. procedure WriteBool(const Section, Ident: string; Value: Boolean);
  135. procedure ReadSection(const Section: string; Strings: TStrings);
  136. procedure ReadSections(Strings: TStrings);
  137. procedure ReadSectionValues(const Section: string; Strings: TStrings);
  138. procedure EraseSection(const Section: string);
  139. procedure DeleteKey(const Section, Ident: String);
  140. property FileName: String read fFileName;
  141. property PreferStringValues: Boolean read fPreferStringValues
  142. write fPreferStringValues;
  143. end;
  144. { ---------------------------------------------------------------------
  145. TRegIniFile
  146. ---------------------------------------------------------------------}
  147. TRegistryIniFile = class(TCustomIniFile)
  148. private
  149. FRegIniFile: TRegIniFile;
  150. public
  151. constructor Create(const AFileName: string); overload;
  152. constructor Create(const AFileName: string; AAccess: LongWord); overload;
  153. function ReadDate(const Section, Name: string; Default: TDateTime): TDateTime; override;
  154. function ReadDateTime(const Section, Name: string; Default: TDateTime): TDateTime; override;
  155. function ReadInteger(const Section, Name: string; Default: Longint): Longint; override;
  156. function ReadFloat(const Section, Name: string; Default: Double): Double; override;
  157. function ReadString(const Section, Name, Default: string): string; override;
  158. function ReadTime(const Section, Name: string; Default: TDateTime): TDateTime; override;
  159. function ReadBinaryStream(const Section, Name: string; Value: TStream): Integer; override;
  160. procedure WriteDate(const Section, Name: string; Value: TDateTime); override;
  161. procedure WriteDateTime(const Section, Name: string; Value: TDateTime); override;
  162. procedure WriteFloat(const Section, Name: string; Value: Double); override;
  163. procedure WriteInteger(const Section, Name: string; Value: Longint); override;
  164. procedure WriteString(const Section, Name, Value: String); override;
  165. procedure WriteTime(const Section, Name: string; Value: TDateTime); override;
  166. procedure WriteBinaryStream(const Section, Name: string; Value: TStream); override;
  167. procedure ReadSection(const Section: string; Strings: TStrings); override;
  168. procedure ReadSections(Strings: TStrings); override;
  169. procedure ReadSectionValues(const Section: string; Strings: TStrings); override;
  170. procedure EraseSection(const Section: string); override;
  171. procedure DeleteKey(const Section, Name: String); override;
  172. procedure UpdateFile; override;
  173. function ValueExists(const Section, Ident: string): Boolean; override;
  174. property RegIniFile: TRegIniFile read FRegIniFile;
  175. end;
  176. ResourceString
  177. SInvalidRegType = 'Invalid registry data type: "%s"';
  178. SRegCreateFailed = 'Failed to create key: "%s"';
  179. SRegSetDataFailed = 'Failed to set data for value "%s"';
  180. SRegGetDataFailed = 'Failed to get data for value "%s"';
  181. var
  182. GlobalXMLFile : Boolean = False;
  183. implementation
  184. { ---------------------------------------------------------------------
  185. Include implementation-dependent code
  186. ---------------------------------------------------------------------}
  187. {$ifdef XMLREG}
  188. {$i xregreg.inc}
  189. {$else}
  190. {$i winreg.inc}
  191. {$endif}
  192. { ---------------------------------------------------------------------
  193. Generic, implementation-independent code.
  194. ---------------------------------------------------------------------}
  195. Constructor TRegistry.Create;
  196. begin
  197. inherited Create;
  198. FAccess := KEY_ALL_ACCESS;
  199. FRootKey := HKEY_CURRENT_USER;
  200. FLazyWrite := True;
  201. FCurrentKey := 0;
  202. SysRegCreate;
  203. end;
  204. Constructor TRegistry.Create(aaccess:longword);
  205. begin
  206. Create;
  207. FAccess := aaccess;
  208. end;
  209. Destructor TRegistry.Destroy;
  210. begin
  211. CloseKey;
  212. SysRegFree;
  213. inherited Destroy;
  214. end;
  215. function TRegistry.CreateKey(const Key: String): Boolean;
  216. begin
  217. Result:=SysCreateKey(Key);
  218. If Not Result Then
  219. Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
  220. end;
  221. function TRegistry.GetBaseKey(Relative: Boolean): HKey;
  222. begin
  223. If Relative and (CurrentKey<>0) Then
  224. Result := CurrentKey
  225. else
  226. Result := RootKey;
  227. end;
  228. function TRegistry.GetData(const Name: String; Buffer: Pointer;
  229. BufSize: Integer; var RegData: TRegDataType): Integer;
  230. begin
  231. Result:=SysGetData(Name,Buffer,BufSize,RegData);
  232. If (Result=-1) then
  233. Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
  234. end;
  235. procedure TRegistry.PutData(const Name: string; Buffer: Pointer;
  236. BufSize: Integer; RegData: TRegDataType);
  237. begin
  238. If Not SysPutData(Name,Buffer,BufSize,RegData) then
  239. Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
  240. end;
  241. function TRegistry.GetDataSize(const ValueName: String): Integer;
  242. Var
  243. Info: TRegDataInfo;
  244. begin
  245. If GetDataInfo(ValueName,Info) Then
  246. Result := Info.DataSize
  247. else
  248. Result := -1;
  249. end;
  250. function TRegistry.GetDataType(const ValueName: string): TRegDataType;
  251. Var
  252. Info: TRegDataInfo;
  253. begin
  254. GetDataInfo(ValueName, Info);
  255. Result:=Info.RegData;
  256. end;
  257. Function TRegistry.HasSubKeys: Boolean;
  258. Var
  259. Info : TRegKeyInfo;
  260. begin
  261. Result:=GetKeyInfo(Info);
  262. If Result then
  263. Result:=(Info.NumSubKeys>0);
  264. end;
  265. function TRegistry.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
  266. Var
  267. RegDataType: TRegDataType;
  268. begin
  269. Result := GetData(Name, @Buffer, BufSize, RegDataType);
  270. If (RegDataType<>rdBinary) Then
  271. Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
  272. end;
  273. function TRegistry.ReadInteger(const Name: string): Integer;
  274. Var
  275. RegDataType: TRegDataType;
  276. begin
  277. GetData(Name, @Result, SizeOf(Integer), RegDataType);
  278. If RegDataType<>rdInteger Then
  279. Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
  280. end;
  281. function TRegistry.ReadBool(const Name: string): Boolean;
  282. begin
  283. Result:=ReadInteger(Name)<>0;
  284. end;
  285. function TRegistry.ReadCurrency(const Name: string): Currency;
  286. begin
  287. ReadBinaryData(Name, Result, SizeOf(Currency));
  288. end;
  289. function TRegistry.ReadDate(const Name: string): TDateTime;
  290. begin
  291. ReadBinaryData(Name, Result, SizeOf(TDateTime));
  292. Result:=Trunc(Result);
  293. end;
  294. function TRegistry.ReadDateTime(const Name: string): TDateTime;
  295. begin
  296. ReadBinaryData(Name, Result, SizeOf(TDateTime));
  297. end;
  298. function TRegistry.ReadFloat(const Name: string): Double;
  299. begin
  300. ReadBinaryData(Name,Result,SizeOf(Double));
  301. end;
  302. function TRegistry.ReadString(const Name: string): string;
  303. Var
  304. Info : TRegDataInfo;
  305. begin
  306. GetDataInfo(Name,Info);
  307. if info.datasize>0 then
  308. begin
  309. If Not (Info.RegData in [rdString,rdExpandString]) then
  310. Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
  311. SetLength(Result,Info.DataSize);
  312. If StringSizeIncludesNull then
  313. SetLength(Result, Info.DataSize-1)
  314. else
  315. SetLength(Result, Info.DataSize);
  316. GetData(Name,PChar(Result),Info.DataSize,Info.RegData);
  317. end
  318. else
  319. result:='';
  320. end;
  321. function TRegistry.ReadTime(const Name: string): TDateTime;
  322. begin
  323. ReadBinaryData(Name, Result, SizeOf(TDateTime));
  324. Result:=Frac(Result);
  325. end;
  326. procedure TRegistry.WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
  327. begin
  328. PutData(Name, @Buffer, BufSize, rdBinary);
  329. end;
  330. procedure TRegistry.WriteBool(const Name: string; Value: Boolean);
  331. begin
  332. WriteInteger(Name,Ord(Value));
  333. end;
  334. procedure TRegistry.WriteCurrency(const Name: string; Value: Currency);
  335. begin
  336. WriteBinaryData(Name, Value, SizeOf(Currency));
  337. end;
  338. procedure TRegistry.WriteDate(const Name: string; Value: TDateTime);
  339. begin
  340. WriteBinarydata(Name, Value, SizeOf(TDateTime));
  341. end;
  342. procedure TRegistry.WriteTime(const Name: string; Value: TDateTime);
  343. begin
  344. WriteBinaryData(Name, Value, SizeOf(TDateTime));
  345. end;
  346. procedure TRegistry.WriteDateTime(const Name: string; Value: TDateTime);
  347. begin
  348. WriteBinaryData(Name, Value, SizeOf(TDateTime));
  349. end;
  350. procedure TRegistry.WriteExpandString(const Name, Value: string);
  351. begin
  352. PutData(Name, PChar(Value), Length(Value),rdExpandString);
  353. end;
  354. procedure TRegistry.WriteFloat(const Name: string; Value: Double);
  355. begin
  356. WriteBinaryData(Name, Value, SizeOf(Double));
  357. end;
  358. procedure TRegistry.WriteInteger(const Name: string; Value: Integer);
  359. begin
  360. PutData(Name, @Value, SizeOf(Integer), rdInteger);
  361. end;
  362. procedure TRegistry.WriteString(const Name, Value: string);
  363. begin
  364. PutData(Name, PChar(Value), Length(Value), rdString);
  365. end;
  366. procedure TRegistry.MoveKey(const OldName, NewName: string; Delete: Boolean);
  367. begin
  368. end;
  369. { ---------------------------------------------------------------------
  370. Include TRegIniFile implementation
  371. ---------------------------------------------------------------------}
  372. {$i regini.inc}
  373. { TRegistryIniFile }
  374. // interface from
  375. // http://www.koders.com/delphi/fid65C1FFAEF89B0CDC4B93FF94C1819686CA6141FC.aspx
  376. constructor TRegistryIniFile.Create(const AFileName: string;
  377. AAccess: LongWord);
  378. begin
  379. inherited create(AFilename);
  380. FRegInifile:=TreginiFile.Create(AFileName,AAccess);
  381. end;
  382. constructor TRegistryIniFile.Create(const AFileName: string);
  383. begin
  384. Create(AFileName,KEY_ALL_ACCESS);
  385. end;
  386. procedure TRegistryIniFile.DeleteKey(const Section, Name: String);
  387. begin
  388. FRegIniFile.Deletekey(section,name);
  389. end;
  390. procedure TRegistryIniFile.EraseSection(const Section: string);
  391. begin
  392. FRegIniFile.EraseSection(section);
  393. end;
  394. function TRegistryIniFile.ReadBinaryStream(const Section, Name: string;
  395. Value: TStream): Integer;
  396. begin
  397. result:=-1; // unimplemented
  398. //
  399. end;
  400. function TRegistryIniFile.ReadDate(const Section, Name: string;
  401. Default: TDateTime): TDateTime;
  402. begin
  403. Result:=Default;
  404. with FRegInifile do
  405. if OpenSection(Section) then
  406. try
  407. if ValueExists(Name) then
  408. Result:=FRegInifile.ReadDate(Name);
  409. finally
  410. CloseSection;
  411. end;
  412. end;
  413. function TRegistryIniFile.ReadDateTime(const Section, Name: string;
  414. Default: TDateTime): TDateTime;
  415. begin
  416. Result:=Default;
  417. with FRegInifile do
  418. if OpenSection(Section) then
  419. try
  420. if ValueExists(Name) then
  421. Result:=FRegInifile.ReadDateTime(Name);
  422. finally
  423. CloseSection;
  424. end;
  425. end;
  426. function TRegistryIniFile.ReadFloat(const Section, Name: string;
  427. Default: Double): Double;
  428. begin
  429. Result:=Default;
  430. with FRegInifile do
  431. if OpenSection(Section) then
  432. try
  433. if ValueExists(Name) then
  434. Result:=FRegInifile.ReadFloat(Name);
  435. finally
  436. CloseSection;
  437. end;
  438. end;
  439. function TRegistryIniFile.ReadInteger(const Section, Name: string;
  440. Default: Integer): Longint;
  441. begin
  442. Result:=FRegInifile.ReadInteger(Section, Name, Default);
  443. end;
  444. procedure TRegistryIniFile.ReadSection(const Section: string; Strings: TStrings);
  445. begin
  446. FRegIniFile.ReadSection(Section,strings);
  447. end;
  448. procedure TRegistryIniFile.ReadSections(Strings: TStrings);
  449. begin
  450. FRegIniFile.ReadSections(strings);
  451. end;
  452. procedure TRegistryIniFile.ReadSectionValues(const Section: string;
  453. Strings: TStrings);
  454. begin
  455. FRegIniFile.ReadSectionValues(Section,strings);
  456. end;
  457. function TRegistryIniFile.ReadString(const Section, Name,
  458. Default: string): string;
  459. begin
  460. Result:=FRegInifile.ReadString(Section, Name, Default);
  461. end;
  462. function TRegistryIniFile.ReadTime(const Section, Name: string;
  463. Default: TDateTime): TDateTime;
  464. begin
  465. Result:=Default;
  466. with FRegInifile do
  467. if OpenSection(Section) then
  468. try
  469. if ValueExists(Name) then
  470. Result:=FRegInifile.ReadTime(Name);
  471. finally
  472. CloseSection;
  473. end;
  474. end;
  475. procedure TRegistryIniFile.UpdateFile;
  476. begin
  477. // FRegIniFile.UpdateFile; ??
  478. end;
  479. procedure TRegistryIniFile.WriteBinaryStream(const Section, Name: string;
  480. Value: TStream);
  481. begin
  482. // ??
  483. end;
  484. procedure TRegistryIniFile.WriteDate(const Section, Name: string;
  485. Value: TDateTime);
  486. begin
  487. with FRegInifile do
  488. if OpenSection(Section) then
  489. try
  490. FRegInifile.WriteDate(Name, Value);
  491. finally
  492. CloseSection;
  493. end;
  494. end;
  495. procedure TRegistryIniFile.WriteDateTime(const Section, Name: string;
  496. Value: TDateTime);
  497. begin
  498. with FRegInifile do
  499. if OpenSection(Section) then
  500. try
  501. FRegInifile.WriteDateTime(Name, Value);
  502. finally
  503. CloseSection;
  504. end;
  505. end;
  506. procedure TRegistryIniFile.WriteFloat(const Section, Name: string;
  507. Value: Double);
  508. begin
  509. with FRegInifile do
  510. if OpenSection(Section) then
  511. try
  512. FRegInifile.WriteFloat(Name, Value);
  513. finally
  514. CloseSection;
  515. end;
  516. end;
  517. procedure TRegistryIniFile.WriteInteger(const Section, Name: string;
  518. Value: Integer);
  519. begin
  520. FRegInifile.WriteInteger(Section, Name, Value);
  521. end;
  522. procedure TRegistryIniFile.WriteString(const Section, Name, Value: String);
  523. begin
  524. FRegInifile.WriteString(Section, Name, Value);
  525. end;
  526. procedure TRegistryIniFile.WriteTime(const Section, Name: string;
  527. Value: TDateTime);
  528. begin
  529. with FRegInifile do
  530. if OpenSection(Section) then
  531. try
  532. FRegInifile.WriteTime(Name, Value);
  533. finally
  534. CloseSection;
  535. end;
  536. end;
  537. function TRegistryIniFile.ValueExists(const Section, Ident: string): Boolean;
  538. begin
  539. with FRegInifile do
  540. if OpenSection(Section) then
  541. try
  542. Result:=FRegInifile.ValueExists(Ident);
  543. finally
  544. CloseSection;
  545. end;
  546. end;
  547. end.