registry.pp 35 KB

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