Configuration.cpp 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <FileInfo.h>
  5. #include "Common.h"
  6. #include "Exceptions.h"
  7. #include "Configuration.h"
  8. #include "PuttyIntf.h"
  9. #include "TextsCore.h"
  10. #include "Interface.h"
  11. #include "CoreMain.h"
  12. #include "Security.h"
  13. #include "FileMasks.h"
  14. #include "CopyParam.h"
  15. #include <shlobj.h>
  16. #include <System.IOUtils.hpp>
  17. #include <System.StrUtils.hpp>
  18. //---------------------------------------------------------------------------
  19. #pragma package(smart_init)
  20. //---------------------------------------------------------------------------
  21. const wchar_t * AutoSwitchNames = L"On;Off;Auto";
  22. const wchar_t * NotAutoSwitchNames = L"Off;On;Auto";
  23. //---------------------------------------------------------------------------
  24. // See https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xhtml
  25. const UnicodeString Sha1ChecksumAlg(L"sha-1");
  26. const UnicodeString Sha224ChecksumAlg(L"sha-224");
  27. const UnicodeString Sha256ChecksumAlg(L"sha-256");
  28. const UnicodeString Sha384ChecksumAlg(L"sha-384");
  29. const UnicodeString Sha512ChecksumAlg(L"sha-512");
  30. const UnicodeString Md5ChecksumAlg(L"md5");
  31. // Not defined by IANA
  32. const UnicodeString Crc32ChecksumAlg(L"crc32");
  33. //---------------------------------------------------------------------------
  34. const UnicodeString SshFingerprintType(L"ssh");
  35. const UnicodeString TlsFingerprintType(L"tls");
  36. //---------------------------------------------------------------------------
  37. const UnicodeString FtpsCertificateStorageKey(L"FtpsCertificates");
  38. const UnicodeString HttpsCertificateStorageKey(L"HttpsCertificates");
  39. const UnicodeString LastFingerprintsStorageKey(L"LastFingerprints");
  40. //---------------------------------------------------------------------------
  41. __fastcall TConfiguration::TConfiguration()
  42. {
  43. FCriticalSection = new TCriticalSection();
  44. FUpdating = 0;
  45. FStorage = stDetect;
  46. FDontSave = false;
  47. FForceSave = false;
  48. FApplicationInfo = NULL;
  49. FUsage = new TUsage(this);
  50. FDefaultCollectUsage = false;
  51. FScripting = false;
  52. UnicodeString RandomSeedPath;
  53. if (!GetEnvironmentVariable(L"APPDATA").IsEmpty())
  54. {
  55. RandomSeedPath = L"%APPDATA%";
  56. }
  57. else
  58. {
  59. RandomSeedPath = GetShellFolderPath(CSIDL_LOCAL_APPDATA);
  60. if (RandomSeedPath.IsEmpty())
  61. {
  62. RandomSeedPath = GetShellFolderPath(CSIDL_APPDATA);
  63. }
  64. }
  65. FDefaultRandomSeedFile = IncludeTrailingBackslash(RandomSeedPath) + L"winscp.rnd";
  66. }
  67. //---------------------------------------------------------------------------
  68. void __fastcall TConfiguration::Default()
  69. {
  70. TGuard Guard(FCriticalSection);
  71. FDisablePasswordStoring = false;
  72. FForceBanners = false;
  73. FDisableAcceptingHostKeys = false;
  74. TRegistryStorage * AdminStorage;
  75. AdminStorage = new TRegistryStorage(RegistryStorageKey, HKEY_LOCAL_MACHINE);
  76. try
  77. {
  78. if (AdminStorage->OpenRootKey(false))
  79. {
  80. LoadAdmin(AdminStorage);
  81. AdminStorage->CloseSubKey();
  82. }
  83. }
  84. __finally
  85. {
  86. delete AdminStorage;
  87. }
  88. RandomSeedFile = FDefaultRandomSeedFile;
  89. PuttyRegistryStorageKey = OriginalPuttyRegistryStorageKey;
  90. FConfirmOverwriting = true;
  91. FConfirmResume = true;
  92. FAutoReadDirectoryAfterOp = true;
  93. FSessionReopenAuto = 5000;
  94. FSessionReopenBackground = 2000;
  95. FSessionReopenTimeout = 0;
  96. FSessionReopenAutoStall = 60000;
  97. FTunnelLocalPortNumberLow = 50000;
  98. FTunnelLocalPortNumberHigh = 50099;
  99. FCacheDirectoryChangesMaxSize = 100;
  100. FShowFtpWelcomeMessage = false;
  101. FExternalIpAddress = L"";
  102. FTryFtpWhenSshFails = true;
  103. FParallelDurationThreshold = 10;
  104. FMimeTypes = UnicodeString();
  105. FDontReloadMoreThanSessions = 1000;
  106. FScriptProgressFileNameLimit = 25;
  107. CollectUsage = FDefaultCollectUsage;
  108. FLogging = false;
  109. FPermanentLogging = false;
  110. FLogFileName = DefaultLogFileName;
  111. FPermanentLogFileName = FLogFileName;
  112. FLogFileAppend = true;
  113. FLogSensitive = false;
  114. FPermanentLogSensitive = FLogSensitive;
  115. FLogMaxSize = 0;
  116. FPermanentLogMaxSize = FLogMaxSize;
  117. FLogMaxCount = 0;
  118. FPermanentLogMaxCount = FLogMaxCount;
  119. FLogProtocol = 0;
  120. FPermanentLogProtocol = FLogProtocol;
  121. UpdateActualLogProtocol();
  122. FLogActions = false;
  123. FPermanentLogActions = false;
  124. FLogActionsRequired = false;
  125. FActionsLogFileName = L"%TEMP%\\!S.xml";
  126. FPermanentActionsLogFileName = FActionsLogFileName;
  127. FProgramIniPathWrittable = -1;
  128. FCustomIniFileStorageName = LoadCustomIniFileStorageName();
  129. Changed();
  130. }
  131. //---------------------------------------------------------------------------
  132. __fastcall TConfiguration::~TConfiguration()
  133. {
  134. DebugAssert(!FUpdating);
  135. if (FApplicationInfo) FreeFileInfo(FApplicationInfo);
  136. delete FCriticalSection;
  137. delete FUsage;
  138. }
  139. //---------------------------------------------------------------------------
  140. void __fastcall TConfiguration::UpdateStaticUsage()
  141. {
  142. Usage->Set(L"ConfigurationIniFile", (Storage == stIniFile));
  143. Usage->Set(L"ConfigurationIniFileCustom", !CustomIniFileStorageName.IsEmpty());
  144. Usage->Set("Unofficial", IsUnofficial);
  145. // this is called from here, because we are guarded from calling into
  146. // master password handler here, see TWinConfiguration::UpdateStaticUsage
  147. StoredSessions->UpdateStaticUsage();
  148. }
  149. //---------------------------------------------------------------------------
  150. THierarchicalStorage * TConfiguration::CreateConfigStorage()
  151. {
  152. bool SessionList = false;
  153. return CreateScpStorage(SessionList);
  154. }
  155. //---------------------------------------------------------------------------
  156. THierarchicalStorage * TConfiguration::CreateScpStorage(bool & SessionList)
  157. {
  158. TGuard Guard(FCriticalSection);
  159. THierarchicalStorage * Result;
  160. if (Storage == stRegistry)
  161. {
  162. Result = new TRegistryStorage(RegistryStorageKey);
  163. }
  164. else if (Storage == stNul)
  165. {
  166. Result = TIniFileStorage::CreateFromPath(INI_NUL);
  167. }
  168. else
  169. {
  170. UnicodeString StorageName = IniFileStorageName;
  171. Result = TIniFileStorage::CreateFromPath(StorageName);
  172. }
  173. if ((FOptionsStorage.get() != NULL) && (FOptionsStorage->Count > 0))
  174. {
  175. if (!SessionList)
  176. {
  177. Result = new TOptionsStorage(FOptionsStorage.get(), ConfigurationSubKey, Result);
  178. }
  179. else
  180. {
  181. // cannot reuse session list storage for configuration as for it we need
  182. // the option-override storage above
  183. }
  184. }
  185. else
  186. {
  187. // All the above stores can be reused for configuration,
  188. // if no options-overrides are set
  189. SessionList = false;
  190. }
  191. return Result;
  192. }
  193. //---------------------------------------------------------------------------
  194. UnicodeString __fastcall TConfiguration::PropertyToKey(const UnicodeString & Property)
  195. {
  196. // no longer useful
  197. int P = Property.LastDelimiter(L".>");
  198. return Property.SubString(P + 1, Property.Length() - P);
  199. }
  200. //---------------------------------------------------------------------------
  201. #define BLOCK(KEY, CANCREATE, BLOCK) \
  202. if (Storage->OpenSubKey(KEY, CANCREATE, true)) try { BLOCK } __finally { Storage->CloseSubKey(); }
  203. #define KEY(TYPE, VAR) KEYEX(TYPE, VAR, PropertyToKey(TEXT(#VAR)))
  204. #define REGCONFIG(CANCREATE) \
  205. BLOCK(L"Interface", CANCREATE, \
  206. KEY(String, RandomSeedFile); \
  207. KEY(String, PuttyRegistryStorageKey); \
  208. KEY(Bool, ConfirmOverwriting); \
  209. KEY(Bool, ConfirmResume); \
  210. KEY(Bool, AutoReadDirectoryAfterOp); \
  211. KEY(Integer, SessionReopenAuto); \
  212. KEY(Integer, SessionReopenBackground); \
  213. KEY(Integer, SessionReopenTimeout); \
  214. KEY(Integer, SessionReopenAutoStall); \
  215. KEY(Integer, TunnelLocalPortNumberLow); \
  216. KEY(Integer, TunnelLocalPortNumberHigh); \
  217. KEY(Integer, CacheDirectoryChangesMaxSize); \
  218. KEY(Bool, ShowFtpWelcomeMessage); \
  219. KEY(String, ExternalIpAddress); \
  220. KEY(Bool, TryFtpWhenSshFails); \
  221. KEY(Integer, ParallelDurationThreshold); \
  222. KEY(String, MimeTypes); \
  223. KEY(Integer, DontReloadMoreThanSessions); \
  224. KEY(Integer, ScriptProgressFileNameLimit); \
  225. KEY(Bool, CollectUsage); \
  226. ); \
  227. BLOCK(L"Logging", CANCREATE, \
  228. KEYEX(Bool, PermanentLogging, L"Logging"); \
  229. KEYEX(String,PermanentLogFileName, L"LogFileName"); \
  230. KEY(Bool, LogFileAppend); \
  231. KEYEX(Bool, PermanentLogSensitive, L"LogSensitive"); \
  232. KEYEX(Int64, PermanentLogMaxSize, L"LogMaxSize"); \
  233. KEYEX(Integer, PermanentLogMaxCount, L"LogMaxCount"); \
  234. KEYEX(Integer,PermanentLogProtocol, L"LogProtocol"); \
  235. KEYEX(Bool, PermanentLogActions, L"LogActions"); \
  236. KEYEX(String,PermanentActionsLogFileName, L"ActionsLogFileName"); \
  237. );
  238. //---------------------------------------------------------------------------
  239. void __fastcall TConfiguration::SaveData(THierarchicalStorage * Storage, bool /*All*/)
  240. {
  241. #define KEYEX(TYPE, VAR, NAME) Storage->Write ## TYPE(NAME, VAR)
  242. REGCONFIG(true);
  243. #undef KEYEX
  244. if (Storage->OpenSubKey(L"Usage", true))
  245. {
  246. FUsage->Save(Storage);
  247. Storage->CloseSubKey();
  248. }
  249. }
  250. //---------------------------------------------------------------------------
  251. void __fastcall TConfiguration::Save()
  252. {
  253. // only modified, implicit
  254. DoSave(false, false);
  255. }
  256. //---------------------------------------------------------------------------
  257. void __fastcall TConfiguration::SaveExplicit()
  258. {
  259. // only modified, explicit
  260. DoSave(false, true);
  261. }
  262. //---------------------------------------------------------------------------
  263. void __fastcall TConfiguration::DoSave(bool All, bool Explicit)
  264. {
  265. if (FDontSave) return;
  266. THierarchicalStorage * AStorage = CreateConfigStorage();
  267. try
  268. {
  269. AStorage->AccessMode = smReadWrite;
  270. AStorage->Explicit = Explicit;
  271. AStorage->ForceSave = FForceSave;
  272. if (AStorage->OpenSubKey(ConfigurationSubKey, true))
  273. {
  274. // if saving to TOptionsStorage, make sure we save everything so that
  275. // all configuration is properly transferred to the master storage
  276. bool ConfigAll = All || AStorage->Temporary;
  277. SaveData(AStorage, ConfigAll);
  278. }
  279. }
  280. __finally
  281. {
  282. delete AStorage;
  283. }
  284. Saved();
  285. if (All)
  286. {
  287. StoredSessions->Save(true, Explicit);
  288. }
  289. // clean up as last, so that if it fails (read only INI), the saving can proceed
  290. if (Storage == stRegistry)
  291. {
  292. CleanupIniFile();
  293. }
  294. SaveCustomIniFileStorageName();
  295. }
  296. //---------------------------------------------------------------------------
  297. void __fastcall TConfiguration::SaveCustomIniFileStorageName()
  298. {
  299. // Particularly, not to create an empty "Override" key, unless the custom INI file is ever set
  300. if (CustomIniFileStorageName != LoadCustomIniFileStorageName())
  301. {
  302. std::unique_ptr<TRegistryStorage> RegistryStorage(new TRegistryStorage(GetRegistryStorageOverrideKey()));
  303. RegistryStorage->AccessMode = smReadWrite;
  304. RegistryStorage->Explicit = true;
  305. if (RegistryStorage->OpenRootKey(true))
  306. {
  307. RegistryStorage->WriteString(L"IniFile", CustomIniFileStorageName);
  308. RegistryStorage->CloseSubKey();
  309. }
  310. }
  311. }
  312. //---------------------------------------------------------------------------
  313. void __fastcall TConfiguration::Export(const UnicodeString & FileName)
  314. {
  315. // not to "append" the export to an existing file
  316. if (FileExists(FileName))
  317. {
  318. DeleteFileChecked(FileName);
  319. }
  320. THierarchicalStorage * Storage = NULL;
  321. THierarchicalStorage * ExportStorage = NULL;
  322. try
  323. {
  324. ExportStorage = TIniFileStorage::CreateFromPath(FileName);
  325. ExportStorage->AccessMode = smReadWrite;
  326. ExportStorage->Explicit = true;
  327. Storage = CreateConfigStorage();
  328. Storage->AccessMode = smRead;
  329. CopyData(Storage, ExportStorage);
  330. if (ExportStorage->OpenSubKey(ConfigurationSubKey, true))
  331. {
  332. SaveData(ExportStorage, true);
  333. }
  334. }
  335. __finally
  336. {
  337. delete ExportStorage;
  338. delete Storage;
  339. }
  340. StoredSessions->Export(FileName);
  341. }
  342. //---------------------------------------------------------------------------
  343. void __fastcall TConfiguration::Import(const UnicodeString & FileName)
  344. {
  345. THierarchicalStorage * Storage = NULL;
  346. THierarchicalStorage * ImportStorage = NULL;
  347. try
  348. {
  349. ImportStorage = TIniFileStorage::CreateFromPath(FileName);
  350. ImportStorage->AccessMode = smRead;
  351. Storage = CreateConfigStorage();
  352. Storage->AccessMode = smReadWrite;
  353. Storage->Explicit = true;
  354. CopyData(ImportStorage, Storage);
  355. Default();
  356. LoadFrom(ImportStorage);
  357. if (ImportStorage->OpenSubKey(Configuration->StoredSessionsSubKey, false))
  358. {
  359. StoredSessions->Clear();
  360. StoredSessions->DefaultSettings->Default();
  361. StoredSessions->Load(ImportStorage);
  362. }
  363. }
  364. __finally
  365. {
  366. delete ImportStorage;
  367. delete Storage;
  368. }
  369. // save all and explicit
  370. DoSave(true, true);
  371. }
  372. //---------------------------------------------------------------------------
  373. void __fastcall TConfiguration::LoadData(THierarchicalStorage * Storage)
  374. {
  375. #define KEYEX(TYPE, VAR, NAME) VAR = Storage->Read ## TYPE(NAME, VAR)
  376. #pragma warn -eas
  377. REGCONFIG(false);
  378. #pragma warn +eas
  379. #undef KEYEX
  380. if (Storage->OpenSubKey(L"Usage", false))
  381. {
  382. FUsage->Load(Storage);
  383. Storage->CloseSubKey();
  384. }
  385. if (FPermanentLogActions && FPermanentActionsLogFileName.IsEmpty() &&
  386. FPermanentLogging && !FPermanentLogFileName.IsEmpty())
  387. {
  388. FPermanentActionsLogFileName = FPermanentLogFileName;
  389. FPermanentLogging = false;
  390. FPermanentLogFileName = L"";
  391. }
  392. }
  393. //---------------------------------------------------------------------------
  394. void __fastcall TConfiguration::LoadAdmin(THierarchicalStorage * Storage)
  395. {
  396. FDisablePasswordStoring = Storage->ReadBool(L"DisablePasswordStoring", FDisablePasswordStoring);
  397. FForceBanners = Storage->ReadBool(L"ForceBanners", FForceBanners);
  398. FDisableAcceptingHostKeys = Storage->ReadBool(L"DisableAcceptingHostKeys", FDisableAcceptingHostKeys);
  399. FDefaultCollectUsage = Storage->ReadBool(L"DefaultCollectUsage", FDefaultCollectUsage);
  400. }
  401. //---------------------------------------------------------------------------
  402. void __fastcall TConfiguration::LoadFrom(THierarchicalStorage * Storage)
  403. {
  404. if (Storage->OpenSubKey(ConfigurationSubKey, false))
  405. {
  406. LoadData(Storage);
  407. Storage->CloseSubKey();
  408. }
  409. }
  410. //---------------------------------------------------------------------------
  411. UnicodeString __fastcall TConfiguration::GetRegistryStorageOverrideKey()
  412. {
  413. return GetRegistryStorageKey() + L" Override";
  414. }
  415. //---------------------------------------------------------------------------
  416. UnicodeString __fastcall TConfiguration::LoadCustomIniFileStorageName()
  417. {
  418. UnicodeString Result;
  419. std::unique_ptr<TRegistryStorage> RegistryStorage(new TRegistryStorage(GetRegistryStorageOverrideKey()));
  420. if (RegistryStorage->OpenRootKey(false))
  421. {
  422. Result = RegistryStorage->ReadString(L"IniFile", L"");
  423. RegistryStorage->CloseSubKey();
  424. }
  425. RegistryStorage.reset(NULL);
  426. return Result;
  427. }
  428. //---------------------------------------------------------------------------
  429. void __fastcall TConfiguration::Load(THierarchicalStorage * Storage)
  430. {
  431. TGuard Guard(FCriticalSection);
  432. TStorageAccessMode StorageAccessMode = Storage->AccessMode;
  433. try
  434. {
  435. Storage->AccessMode = smRead;
  436. LoadFrom(Storage);
  437. }
  438. __finally
  439. {
  440. Storage->AccessMode = StorageAccessMode;
  441. }
  442. }
  443. //---------------------------------------------------------------------------
  444. bool __fastcall TConfiguration::CopySubKey(THierarchicalStorage * Source, THierarchicalStorage * Target, const UnicodeString & Name)
  445. {
  446. bool Result = Source->OpenSubKey(Name, false);
  447. if (Result)
  448. {
  449. Result = Target->OpenSubKey(Name, true);
  450. if (!Result)
  451. {
  452. Source->CloseSubKey();
  453. }
  454. }
  455. return Result;
  456. }
  457. //---------------------------------------------------------------------------
  458. void __fastcall TConfiguration::CopyAllStringsInSubKey(
  459. THierarchicalStorage * Source, THierarchicalStorage * Target, const UnicodeString & Name)
  460. {
  461. if (CopySubKey(Source, Target, Name))
  462. {
  463. std::unique_ptr<TStrings> Names(new TStringList());
  464. Source->GetValueNames(Names.get());
  465. for (int Index = 0; Index < Names->Count; Index++)
  466. {
  467. UnicodeString Buf = Source->ReadStringRaw(Names->Strings[Index], UnicodeString());
  468. Target->WriteStringRaw(Names->Strings[Index], Buf);
  469. }
  470. Target->CloseSubKey();
  471. Source->CloseSubKey();
  472. }
  473. }
  474. //---------------------------------------------------------------------------
  475. void __fastcall TConfiguration::CopyData(THierarchicalStorage * Source,
  476. THierarchicalStorage * Target)
  477. {
  478. if (CopySubKey(Source, Target, ConfigurationSubKey))
  479. {
  480. if (CopySubKey(Source, Target, L"CDCache"))
  481. {
  482. std::unique_ptr<TStrings> Names(new TStringList());
  483. Source->GetValueNames(Names.get());
  484. for (int Index = 0; Index < Names->Count; Index++)
  485. {
  486. Target->WriteBinaryData(Names->Strings[Index], Source->ReadBinaryData(Names->Strings[Index]));
  487. }
  488. Target->CloseSubKey();
  489. Source->CloseSubKey();
  490. }
  491. CopyAllStringsInSubKey(Source, Target, L"Banners");
  492. CopyAllStringsInSubKey(Source, Target, LastFingerprintsStorageKey);
  493. Target->CloseSubKey();
  494. Source->CloseSubKey();
  495. }
  496. CopyAllStringsInSubKey(Source, Target, SshHostKeysSubKey);
  497. CopyAllStringsInSubKey(Source, Target, FtpsCertificateStorageKey);
  498. CopyAllStringsInSubKey(Source, Target, HttpsCertificateStorageKey);
  499. }
  500. //---------------------------------------------------------------------------
  501. void __fastcall TConfiguration::LoadDirectoryChangesCache(const UnicodeString SessionKey,
  502. TRemoteDirectoryChangesCache * DirectoryChangesCache)
  503. {
  504. THierarchicalStorage * Storage = CreateConfigStorage();
  505. try
  506. {
  507. Storage->AccessMode = smRead;
  508. if (Storage->OpenSubKey(ConfigurationSubKey, false) &&
  509. Storage->OpenSubKey(L"CDCache", false) &&
  510. Storage->ValueExists(SessionKey))
  511. {
  512. DirectoryChangesCache->Deserialize(Storage->ReadBinaryData(SessionKey));
  513. }
  514. }
  515. __finally
  516. {
  517. delete Storage;
  518. }
  519. }
  520. //---------------------------------------------------------------------------
  521. void __fastcall TConfiguration::SaveDirectoryChangesCache(const UnicodeString SessionKey,
  522. TRemoteDirectoryChangesCache * DirectoryChangesCache)
  523. {
  524. THierarchicalStorage * Storage = CreateConfigStorage();
  525. try
  526. {
  527. Storage->AccessMode = smReadWrite;
  528. if (Storage->OpenSubKey(ConfigurationSubKey, true) &&
  529. Storage->OpenSubKey(L"CDCache", true))
  530. {
  531. UnicodeString Data;
  532. DirectoryChangesCache->Serialize(Data);
  533. Storage->WriteBinaryData(SessionKey, Data);
  534. }
  535. }
  536. __finally
  537. {
  538. delete Storage;
  539. }
  540. }
  541. //---------------------------------------------------------------------------
  542. UnicodeString __fastcall TConfiguration::BannerHash(const UnicodeString & Banner)
  543. {
  544. RawByteString Result;
  545. Result.SetLength(16);
  546. md5checksum(
  547. reinterpret_cast<const char*>(Banner.c_str()), Banner.Length() * sizeof(wchar_t),
  548. (unsigned char*)Result.c_str());
  549. return BytesToHex(Result);
  550. }
  551. //---------------------------------------------------------------------------
  552. void __fastcall TConfiguration::GetBannerData(
  553. const UnicodeString & SessionKey, UnicodeString & BannerHash, unsigned int & Params)
  554. {
  555. BannerHash = UnicodeString();
  556. Params = 0;
  557. std::unique_ptr<THierarchicalStorage> Storage(CreateConfigStorage());
  558. Storage->AccessMode = smRead;
  559. if (Storage->OpenSubKey(ConfigurationSubKey, false) &&
  560. Storage->OpenSubKey(L"Banners", false))
  561. {
  562. UnicodeString S = Storage->ReadString(SessionKey, L"");
  563. BannerHash = CutToChar(S, L',', true);
  564. Params = StrToIntDef(L"$" + CutToChar(S, L',', true), 0);
  565. }
  566. }
  567. //---------------------------------------------------------------------------
  568. bool __fastcall TConfiguration::ShowBanner(
  569. const UnicodeString & SessionKey, const UnicodeString & Banner, unsigned int & Params)
  570. {
  571. UnicodeString StoredBannerHash;
  572. GetBannerData(SessionKey, StoredBannerHash, Params);
  573. bool Result = (StoredBannerHash != BannerHash(Banner));
  574. return Result;
  575. }
  576. //---------------------------------------------------------------------------
  577. void __fastcall TConfiguration::SetBannerData(
  578. const UnicodeString & SessionKey, const UnicodeString & BannerHash, unsigned int Params)
  579. {
  580. std::unique_ptr<THierarchicalStorage> Storage(CreateConfigStorage());
  581. Storage->AccessMode = smReadWrite;
  582. if (Storage->OpenSubKey(ConfigurationSubKey, true) &&
  583. Storage->OpenSubKey(L"Banners", true))
  584. {
  585. Storage->WriteString(SessionKey, BannerHash + L"," + UIntToStr(Params));
  586. }
  587. }
  588. //---------------------------------------------------------------------------
  589. void __fastcall TConfiguration::NeverShowBanner(const UnicodeString & SessionKey, const UnicodeString & Banner)
  590. {
  591. UnicodeString DummyBannerHash;
  592. unsigned int Params;
  593. GetBannerData(SessionKey, DummyBannerHash, Params);
  594. SetBannerData(SessionKey, BannerHash(Banner), Params);
  595. }
  596. //---------------------------------------------------------------------------
  597. void __fastcall TConfiguration::SetBannerParams(const UnicodeString & SessionKey, unsigned int Params)
  598. {
  599. UnicodeString BannerHash;
  600. unsigned int DummyParams;
  601. GetBannerData(SessionKey, BannerHash, DummyParams);
  602. SetBannerData(SessionKey, BannerHash, Params);
  603. }
  604. //---------------------------------------------------------------------------
  605. UnicodeString __fastcall TConfiguration::FormatFingerprintKey(const UnicodeString & SiteKey, const UnicodeString & FingerprintType)
  606. {
  607. return FORMAT(L"%s:%s", (SiteKey, FingerprintType));
  608. }
  609. //---------------------------------------------------------------------------
  610. void __fastcall TConfiguration::RememberLastFingerprint(const UnicodeString & SiteKey, const UnicodeString & FingerprintType, const UnicodeString & Fingerprint)
  611. {
  612. std::unique_ptr<THierarchicalStorage> Storage(CreateConfigStorage());
  613. Storage->AccessMode = smReadWrite;
  614. if (Storage->OpenSubKey(ConfigurationSubKey, true) &&
  615. Storage->OpenSubKey(LastFingerprintsStorageKey, true))
  616. {
  617. UnicodeString FingerprintKey = FormatFingerprintKey(SiteKey, FingerprintType);
  618. Storage->WriteString(FingerprintKey, Fingerprint);
  619. }
  620. }
  621. //---------------------------------------------------------------------------
  622. UnicodeString __fastcall TConfiguration::LastFingerprint(const UnicodeString & SiteKey, const UnicodeString & FingerprintType)
  623. {
  624. UnicodeString Result;
  625. std::unique_ptr<THierarchicalStorage> Storage(CreateConfigStorage());
  626. Storage->AccessMode = smRead;
  627. if (Storage->OpenSubKey(ConfigurationSubKey, false) &&
  628. Storage->OpenSubKey(LastFingerprintsStorageKey, false))
  629. {
  630. UnicodeString FingerprintKey = FormatFingerprintKey(SiteKey, FingerprintType);
  631. Result = Storage->ReadString(FingerprintKey, L"");
  632. }
  633. return Result;
  634. }
  635. //---------------------------------------------------------------------------
  636. void __fastcall TConfiguration::Changed()
  637. {
  638. TNotifyEvent AOnChange = NULL;
  639. {
  640. TGuard Guard(FCriticalSection);
  641. if (FUpdating == 0)
  642. {
  643. AOnChange = OnChange;
  644. }
  645. else
  646. {
  647. FChanged = true;
  648. }
  649. }
  650. // No specific reason to call this outside of a guard, just that it is less of a change to a previous unguarded code
  651. if (AOnChange != NULL)
  652. {
  653. AOnChange(this);
  654. }
  655. }
  656. //---------------------------------------------------------------------------
  657. void __fastcall TConfiguration::BeginUpdate()
  658. {
  659. FCriticalSection->Enter();
  660. if (FUpdating == 0)
  661. {
  662. FChanged = false;
  663. }
  664. FUpdating++;
  665. // Greater value would probably indicate some nesting problem in code
  666. DebugAssert(FUpdating < 6);
  667. }
  668. //---------------------------------------------------------------------------
  669. void __fastcall TConfiguration::EndUpdate()
  670. {
  671. DebugAssert(FUpdating > 0);
  672. FUpdating--;
  673. if ((FUpdating == 0) && FChanged)
  674. {
  675. FChanged = false;
  676. Changed();
  677. }
  678. FCriticalSection->Leave();
  679. }
  680. //---------------------------------------------------------------------------
  681. void __fastcall TConfiguration::CleanupConfiguration()
  682. {
  683. try
  684. {
  685. CleanupRegistry(ConfigurationSubKey);
  686. if (Storage == stRegistry)
  687. {
  688. FDontSave = true;
  689. }
  690. }
  691. catch (Exception &E)
  692. {
  693. throw ExtException(&E, LoadStr(CLEANUP_CONFIG_ERROR));
  694. }
  695. }
  696. //---------------------------------------------------------------------------
  697. void __fastcall TConfiguration::CleanupRegistry(UnicodeString CleanupSubKey)
  698. {
  699. TRegistryStorage *Registry = new TRegistryStorage(RegistryStorageKey);
  700. try
  701. {
  702. Registry->RecursiveDeleteSubKey(CleanupSubKey);
  703. }
  704. __finally
  705. {
  706. delete Registry;
  707. }
  708. }
  709. //---------------------------------------------------------------------------
  710. void __fastcall TConfiguration::CleanupHostKeys()
  711. {
  712. try
  713. {
  714. CleanupRegistry(SshHostKeysSubKey);
  715. }
  716. catch (Exception &E)
  717. {
  718. throw ExtException(&E, LoadStr(CLEANUP_HOSTKEYS_ERROR));
  719. }
  720. }
  721. //---------------------------------------------------------------------------
  722. void __fastcall TConfiguration::CleanupRandomSeedFile()
  723. {
  724. try
  725. {
  726. DontSaveRandomSeed();
  727. if (FileExists(ApiPath(RandomSeedFileName)))
  728. {
  729. DeleteFileChecked(RandomSeedFileName);
  730. }
  731. }
  732. catch (Exception &E)
  733. {
  734. throw ExtException(&E, LoadStr(CLEANUP_SEEDFILE_ERROR));
  735. }
  736. }
  737. //---------------------------------------------------------------------------
  738. void __fastcall TConfiguration::CleanupIniFile()
  739. {
  740. try
  741. {
  742. if (FileExists(ApiPath(IniFileStorageNameForReading)))
  743. {
  744. DeleteFileChecked(IniFileStorageNameForReading);
  745. }
  746. if (Storage == stIniFile)
  747. {
  748. FDontSave = true;
  749. }
  750. }
  751. catch (Exception &E)
  752. {
  753. throw ExtException(&E, LoadStr(CLEANUP_INIFILE_ERROR));
  754. }
  755. }
  756. //---------------------------------------------------------------------------
  757. void __fastcall TConfiguration::DontSave()
  758. {
  759. FDontSave = true;
  760. }
  761. //---------------------------------------------------------------------------
  762. RawByteString __fastcall TConfiguration::EncryptPassword(UnicodeString Password, UnicodeString Key)
  763. {
  764. if (Password.IsEmpty())
  765. {
  766. return RawByteString();
  767. }
  768. else
  769. {
  770. return ::EncryptPassword(Password, Key);
  771. }
  772. }
  773. //---------------------------------------------------------------------------
  774. UnicodeString __fastcall TConfiguration::DecryptPassword(RawByteString Password, UnicodeString Key)
  775. {
  776. if (Password.IsEmpty())
  777. {
  778. return UnicodeString();
  779. }
  780. else
  781. {
  782. return ::DecryptPassword(Password, Key);
  783. }
  784. }
  785. //---------------------------------------------------------------------------
  786. RawByteString __fastcall TConfiguration::StronglyRecryptPassword(RawByteString Password, UnicodeString /*Key*/)
  787. {
  788. return Password;
  789. }
  790. //---------------------------------------------------------------------------
  791. TVSFixedFileInfo *__fastcall TConfiguration::GetFixedApplicationInfo()
  792. {
  793. return GetFixedFileInfo(ApplicationInfo);
  794. }
  795. //---------------------------------------------------------------------------
  796. int __fastcall TConfiguration::GetCompoundVersion()
  797. {
  798. TVSFixedFileInfo * FileInfo = FixedApplicationInfo;
  799. return CalculateCompoundVersion(
  800. HIWORD(FileInfo->dwFileVersionMS), LOWORD(FileInfo->dwFileVersionMS),
  801. HIWORD(FileInfo->dwFileVersionLS), LOWORD(FileInfo->dwFileVersionLS));
  802. }
  803. //---------------------------------------------------------------------------
  804. UnicodeString __fastcall TConfiguration::ModuleFileName()
  805. {
  806. return ParamStr(0);
  807. }
  808. //---------------------------------------------------------------------------
  809. void * __fastcall TConfiguration::GetFileApplicationInfo(const UnicodeString FileName)
  810. {
  811. void * Result;
  812. if (FileName.IsEmpty())
  813. {
  814. if (!FApplicationInfo)
  815. {
  816. FApplicationInfo = CreateFileInfo(ModuleFileName());
  817. }
  818. Result = FApplicationInfo;
  819. }
  820. else
  821. {
  822. Result = CreateFileInfo(FileName);
  823. }
  824. return Result;
  825. }
  826. //---------------------------------------------------------------------------
  827. void * __fastcall TConfiguration::GetApplicationInfo()
  828. {
  829. return GetFileApplicationInfo("");
  830. }
  831. //---------------------------------------------------------------------------
  832. UnicodeString __fastcall TConfiguration::GetFileProductName(const UnicodeString FileName)
  833. {
  834. return GetFileFileInfoString(L"ProductName", FileName);
  835. }
  836. //---------------------------------------------------------------------------
  837. UnicodeString __fastcall TConfiguration::GetFileCompanyName(const UnicodeString FileName)
  838. {
  839. // particularly in IDE build, company name is empty
  840. return GetFileFileInfoString(L"CompanyName", FileName, true);
  841. }
  842. //---------------------------------------------------------------------------
  843. UnicodeString __fastcall TConfiguration::GetProductName()
  844. {
  845. return GetFileProductName(L"");
  846. }
  847. //---------------------------------------------------------------------------
  848. UnicodeString __fastcall TConfiguration::GetCompanyName()
  849. {
  850. return GetFileCompanyName(L"");
  851. }
  852. //---------------------------------------------------------------------------
  853. UnicodeString __fastcall TConfiguration::GetFileProductVersion(const UnicodeString FileName)
  854. {
  855. return TrimVersion(GetFileFileInfoString(L"ProductVersion", FileName));
  856. }
  857. //---------------------------------------------------------------------------
  858. UnicodeString __fastcall TConfiguration::GetFileDescription(const UnicodeString & FileName)
  859. {
  860. return GetFileFileInfoString(L"FileDescription", FileName);
  861. }
  862. //---------------------------------------------------------------------------
  863. UnicodeString __fastcall TConfiguration::GetProductVersion()
  864. {
  865. return GetFileProductVersion(L"");
  866. }
  867. //---------------------------------------------------------------------------
  868. UnicodeString __fastcall TConfiguration::GetReleaseType()
  869. {
  870. return GetFileInfoString(L"ReleaseType");
  871. }
  872. //---------------------------------------------------------------------------
  873. bool __fastcall TConfiguration::GetIsUnofficial()
  874. {
  875. #ifdef BUILD_OFFICIAL
  876. return false;
  877. #else
  878. return true;
  879. #endif
  880. }
  881. //---------------------------------------------------------------------------
  882. UnicodeString __fastcall TConfiguration::GetVersionStr()
  883. {
  884. TGuard Guard(FCriticalSection);
  885. try
  886. {
  887. UnicodeString BuildStr;
  888. if (!IsUnofficial)
  889. {
  890. BuildStr = LoadStr(VERSION_BUILD);
  891. }
  892. else
  893. {
  894. #ifdef _DEBUG
  895. BuildStr = LoadStr(VERSION_DEBUG_BUILD);
  896. #else
  897. BuildStr = LoadStr(VERSION_DEV_BUILD);
  898. #endif
  899. }
  900. int Build = LOWORD(FixedApplicationInfo->dwFileVersionLS);
  901. if (Build > 0)
  902. {
  903. BuildStr += L" " + IntToStr(Build);
  904. }
  905. #ifndef BUILD_OFFICIAL
  906. UnicodeString BuildDate = __DATE__;
  907. UnicodeString MonthStr = CutToChar(BuildDate, L' ', true);
  908. int Month = ParseShortEngMonthName(MonthStr);
  909. int Day = StrToInt(CutToChar(BuildDate, L' ', true));
  910. int Year = StrToInt(Trim(BuildDate));
  911. UnicodeString DateStr = FORMAT(L"%d-%2.2d-%2.2d", (Year, Month, Day));
  912. AddToList(BuildStr, DateStr, L" ");
  913. #endif
  914. UnicodeString FullVersion = Version;
  915. UnicodeString AReleaseType = GetReleaseType();
  916. if (DebugAlwaysTrue(!AReleaseType.IsEmpty()) &&
  917. !SameText(AReleaseType, L"stable") &&
  918. !SameText(AReleaseType, L"development"))
  919. {
  920. FullVersion += L" " + AReleaseType;
  921. }
  922. UnicodeString Result = FMTLOAD(VERSION2, (FullVersion, BuildStr));
  923. #ifndef BUILD_OFFICIAL
  924. Result += L" " + LoadStr(VERSION_DONT_DISTRIBUTE);
  925. #endif
  926. return Result;
  927. }
  928. catch (Exception &E)
  929. {
  930. throw ExtException(&E, L"Can't get application version");
  931. }
  932. }
  933. //---------------------------------------------------------------------------
  934. UnicodeString __fastcall TConfiguration::GetFileVersion(const UnicodeString & FileName)
  935. {
  936. UnicodeString Result;
  937. void * FileInfo = CreateFileInfo(FileName);
  938. try
  939. {
  940. Result = GetFileVersion(GetFixedFileInfo(FileInfo));
  941. }
  942. __finally
  943. {
  944. FreeFileInfo(FileInfo);
  945. }
  946. return Result;
  947. }
  948. //---------------------------------------------------------------------------
  949. UnicodeString __fastcall TConfiguration::GetFileVersion(TVSFixedFileInfo * Info)
  950. {
  951. TGuard Guard(FCriticalSection);
  952. try
  953. {
  954. UnicodeString Result =
  955. FormatVersion(
  956. HIWORD(Info->dwFileVersionMS),
  957. LOWORD(Info->dwFileVersionMS),
  958. HIWORD(Info->dwFileVersionLS));
  959. return Result;
  960. }
  961. catch (Exception &E)
  962. {
  963. throw ExtException(&E, L"Can't get file version");
  964. }
  965. }
  966. //---------------------------------------------------------------------------
  967. UnicodeString __fastcall TConfiguration::GetVersion()
  968. {
  969. return GetFileVersion(FixedApplicationInfo);
  970. }
  971. //---------------------------------------------------------------------------
  972. UnicodeString __fastcall TConfiguration::GetFileFileInfoString(const UnicodeString Key,
  973. const UnicodeString FileName, bool AllowEmpty)
  974. {
  975. TGuard Guard(FCriticalSection);
  976. UnicodeString Result;
  977. void * Info = GetFileApplicationInfo(FileName);
  978. try
  979. {
  980. if ((Info != NULL) && (GetTranslationCount(Info) > 0))
  981. {
  982. TTranslation Translation;
  983. Translation = GetTranslation(Info, 0);
  984. Result = ::GetFileInfoString(Info, Translation, Key, AllowEmpty);
  985. }
  986. else
  987. {
  988. DebugAssert(!FileName.IsEmpty());
  989. }
  990. }
  991. __finally
  992. {
  993. if (!FileName.IsEmpty())
  994. {
  995. FreeFileInfo(Info);
  996. }
  997. }
  998. return Result;
  999. }
  1000. //---------------------------------------------------------------------------
  1001. UnicodeString __fastcall TConfiguration::GetFileInfoString(const UnicodeString Key)
  1002. {
  1003. return GetFileFileInfoString(Key, L"");
  1004. }
  1005. //---------------------------------------------------------------------------
  1006. UnicodeString __fastcall TConfiguration::GetFileMimeType(const UnicodeString & FileName)
  1007. {
  1008. UnicodeString Result;
  1009. bool Found = false;
  1010. if (!MimeTypes.IsEmpty())
  1011. {
  1012. UnicodeString FileNameOnly = ExtractFileName(FileName);
  1013. UnicodeString AMimeTypes = MimeTypes;
  1014. while (!Found && !AMimeTypes.IsEmpty())
  1015. {
  1016. UnicodeString Token = CutToChar(AMimeTypes, L',', true);
  1017. UnicodeString MaskStr = CutToChar(Token, L'=', true);
  1018. TFileMasks Mask(MaskStr);
  1019. if (Mask.Matches(FileNameOnly))
  1020. {
  1021. Result = Token.Trim();
  1022. Found = true;
  1023. }
  1024. }
  1025. }
  1026. if (!Found) // allow an override to "no" Content-Type
  1027. {
  1028. Result = ::GetFileMimeType(FileName);
  1029. }
  1030. return Result;
  1031. }
  1032. //---------------------------------------------------------------------------
  1033. UnicodeString __fastcall TConfiguration::GetRegistryStorageKey()
  1034. {
  1035. return GetRegistryKey();
  1036. }
  1037. //---------------------------------------------------------------------------
  1038. void __fastcall TConfiguration::SetNulStorage()
  1039. {
  1040. FStorage = stNul;
  1041. }
  1042. //---------------------------------------------------------------------------
  1043. void __fastcall TConfiguration::SetDefaultStorage()
  1044. {
  1045. FStorage = stDetect;
  1046. }
  1047. //---------------------------------------------------------------------------
  1048. void __fastcall TConfiguration::SetIniFileStorageName(UnicodeString value)
  1049. {
  1050. FIniFileStorageName = value;
  1051. FStorage = stIniFile;
  1052. }
  1053. //---------------------------------------------------------------------------
  1054. UnicodeString __fastcall TConfiguration::GetDefaultIniFileExportPath()
  1055. {
  1056. UnicodeString PersonalDirectory = GetPersonalFolder();
  1057. UnicodeString FileName = IncludeTrailingBackslash(PersonalDirectory) +
  1058. ExtractFileName(ExpandEnvironmentVariables(IniFileStorageName));
  1059. return FileName;
  1060. }
  1061. //---------------------------------------------------------------------------
  1062. UnicodeString __fastcall TConfiguration::GetIniFileStorageNameForReading()
  1063. {
  1064. return GetIniFileStorageName(true);
  1065. }
  1066. //---------------------------------------------------------------------------
  1067. UnicodeString __fastcall TConfiguration::GetIniFileStorageNameForReadingWriting()
  1068. {
  1069. return GetIniFileStorageName(false);
  1070. }
  1071. //---------------------------------------------------------------------------
  1072. UnicodeString __fastcall TConfiguration::GetAutomaticIniFileStorageName(bool ReadingOnly)
  1073. {
  1074. UnicodeString ProgramPath = ParamStr(0);
  1075. UnicodeString ProgramIniPath = ChangeFileExt(ProgramPath, L".ini");
  1076. UnicodeString IniPath;
  1077. if (FileExists(ApiPath(ProgramIniPath)))
  1078. {
  1079. IniPath = ProgramIniPath;
  1080. }
  1081. else
  1082. {
  1083. UnicodeString AppDataIniPath =
  1084. IncludeTrailingBackslash(GetShellFolderPath(CSIDL_APPDATA)) +
  1085. ExtractFileName(ProgramIniPath);
  1086. if (FileExists(ApiPath(AppDataIniPath)))
  1087. {
  1088. IniPath = AppDataIniPath;
  1089. }
  1090. else
  1091. {
  1092. // avoid expensive test if we are interested in existing files only
  1093. if (!ReadingOnly && (FProgramIniPathWrittable < 0))
  1094. {
  1095. UnicodeString ProgramDir = ExtractFilePath(ProgramPath);
  1096. FProgramIniPathWrittable = IsDirectoryWriteable(ProgramDir) ? 1 : 0;
  1097. }
  1098. // does not really matter what we return when < 0
  1099. IniPath = (FProgramIniPathWrittable == 0) ? AppDataIniPath : ProgramIniPath;
  1100. }
  1101. }
  1102. // BACKWARD COMPATIBILITY with 4.x
  1103. if (FVirtualIniFileStorageName.IsEmpty() &&
  1104. TPath::IsDriveRooted(IniPath))
  1105. {
  1106. UnicodeString LocalAppDataPath = GetShellFolderPath(CSIDL_LOCAL_APPDATA);
  1107. // virtual store for non-system drives have a different virtual store,
  1108. // do not bother about them
  1109. if (TPath::IsDriveRooted(LocalAppDataPath) &&
  1110. SameText(ExtractFileDrive(IniPath), ExtractFileDrive(LocalAppDataPath)))
  1111. {
  1112. FVirtualIniFileStorageName =
  1113. IncludeTrailingBackslash(LocalAppDataPath) +
  1114. L"VirtualStore\\" +
  1115. IniPath.SubString(4, IniPath.Length() - 3);
  1116. }
  1117. }
  1118. if (!FVirtualIniFileStorageName.IsEmpty() &&
  1119. FileExists(ApiPath(FVirtualIniFileStorageName)))
  1120. {
  1121. return FVirtualIniFileStorageName;
  1122. }
  1123. else
  1124. {
  1125. return IniPath;
  1126. }
  1127. }
  1128. //---------------------------------------------------------------------------
  1129. UnicodeString __fastcall TConfiguration::GetIniFileStorageName(bool ReadingOnly)
  1130. {
  1131. UnicodeString Result;
  1132. if (!FIniFileStorageName.IsEmpty())
  1133. {
  1134. Result = FIniFileStorageName;
  1135. }
  1136. else if (!FCustomIniFileStorageName.IsEmpty())
  1137. {
  1138. Result = FCustomIniFileStorageName;
  1139. }
  1140. else
  1141. {
  1142. Result = GetAutomaticIniFileStorageName(ReadingOnly);
  1143. }
  1144. return Result;
  1145. }
  1146. //---------------------------------------------------------------------------
  1147. void __fastcall TConfiguration::SetOptionsStorage(TStrings * value)
  1148. {
  1149. TGuard Guard(FCriticalSection);
  1150. if (FOptionsStorage.get() == NULL)
  1151. {
  1152. FOptionsStorage.reset(new TStringList());
  1153. }
  1154. FOptionsStorage->AddStrings(value);
  1155. }
  1156. //---------------------------------------------------------------------------
  1157. TStrings * __fastcall TConfiguration::GetOptionsStorage()
  1158. {
  1159. return FOptionsStorage.get();
  1160. }
  1161. //---------------------------------------------------------------------------
  1162. UnicodeString __fastcall TConfiguration::GetPuttySessionsKey()
  1163. {
  1164. return PuttyRegistryStorageKey + L"\\Sessions";
  1165. }
  1166. //---------------------------------------------------------------------------
  1167. UnicodeString __fastcall TConfiguration::GetStoredSessionsSubKey()
  1168. {
  1169. return L"Sessions";
  1170. }
  1171. //---------------------------------------------------------------------------
  1172. UnicodeString __fastcall TConfiguration::GetSshHostKeysSubKey()
  1173. {
  1174. return L"SshHostKeys";
  1175. }
  1176. //---------------------------------------------------------------------------
  1177. UnicodeString __fastcall TConfiguration::GetConfigurationSubKey()
  1178. {
  1179. return L"Configuration";
  1180. }
  1181. //---------------------------------------------------------------------------
  1182. UnicodeString __fastcall TConfiguration::GetRootKeyStr()
  1183. {
  1184. return RootKeyToStr(HKEY_CURRENT_USER);
  1185. }
  1186. //---------------------------------------------------------------------------
  1187. void __fastcall TConfiguration::MoveStorage(TStorage AStorage, const UnicodeString & ACustomIniFileStorageName)
  1188. {
  1189. if ((FStorage != AStorage) ||
  1190. !IsPathToSameFile(FCustomIniFileStorageName, ACustomIniFileStorageName))
  1191. {
  1192. TStorage StorageBak = FStorage;
  1193. UnicodeString CustomIniFileStorageNameBak = FCustomIniFileStorageName;
  1194. try
  1195. {
  1196. THierarchicalStorage * SourceStorage = NULL;
  1197. THierarchicalStorage * TargetStorage = NULL;
  1198. try
  1199. {
  1200. SourceStorage = CreateConfigStorage();
  1201. SourceStorage->AccessMode = smRead;
  1202. FStorage = AStorage;
  1203. FCustomIniFileStorageName = ACustomIniFileStorageName;
  1204. TargetStorage = CreateConfigStorage();
  1205. TargetStorage->AccessMode = smReadWrite;
  1206. TargetStorage->Explicit = true;
  1207. // copy before save as it removes the ini file,
  1208. // when switching from ini to registry
  1209. CopyData(SourceStorage, TargetStorage);
  1210. }
  1211. __finally
  1212. {
  1213. delete SourceStorage;
  1214. delete TargetStorage;
  1215. }
  1216. // save all and explicit,
  1217. // this also removes an INI file, when switching to registry storage
  1218. DoSave(true, true);
  1219. }
  1220. catch (...)
  1221. {
  1222. // If this fails, do not pretend that storage was switched.
  1223. // For instance:
  1224. // - When writing to an INI file fails (unlikely, as we fallback to user profile)
  1225. // - When removing INI file fails, when switching to registry
  1226. // (possible, when the INI file is in Program Files folder)
  1227. FStorage = StorageBak;
  1228. FCustomIniFileStorageName = CustomIniFileStorageNameBak;
  1229. throw;
  1230. }
  1231. }
  1232. }
  1233. //---------------------------------------------------------------------------
  1234. void __fastcall TConfiguration::ScheduleCustomIniFileStorageUse(const UnicodeString & ACustomIniFileStorageName)
  1235. {
  1236. FStorage = stIniFile;
  1237. FCustomIniFileStorageName = ACustomIniFileStorageName;
  1238. SaveCustomIniFileStorageName();
  1239. }
  1240. //---------------------------------------------------------------------------
  1241. void __fastcall TConfiguration::Saved()
  1242. {
  1243. // nothing
  1244. }
  1245. //---------------------------------------------------------------------------
  1246. TStorage __fastcall TConfiguration::GetStorage()
  1247. {
  1248. TGuard Guard(FCriticalSection);
  1249. if (FStorage == stDetect)
  1250. {
  1251. if (FileExists(ApiPath(IniFileStorageNameForReading)))
  1252. {
  1253. FStorage = stIniFile;
  1254. }
  1255. else
  1256. {
  1257. FStorage = stRegistry;
  1258. }
  1259. }
  1260. return FStorage;
  1261. }
  1262. //---------------------------------------------------------------------
  1263. TStoredSessionList * __fastcall TConfiguration::SelectFilezillaSessionsForImport(
  1264. TStoredSessionList * Sessions, UnicodeString & Error)
  1265. {
  1266. std::unique_ptr<TStoredSessionList> ImportSessionList(new TStoredSessionList(true));
  1267. ImportSessionList->DefaultSettings = Sessions->DefaultSettings;
  1268. UnicodeString AppDataPath = GetShellFolderPath(CSIDL_APPDATA);
  1269. UnicodeString FilezillaSiteManagerFile =
  1270. IncludeTrailingBackslash(AppDataPath) + L"FileZilla\\sitemanager.xml";
  1271. UnicodeString FilezillaConfigurationFile =
  1272. IncludeTrailingBackslash(AppDataPath) + L"FileZilla\\filezilla.xml";
  1273. if (FileExists(ApiPath(FilezillaSiteManagerFile)))
  1274. {
  1275. ImportSessionList->ImportFromFilezilla(FilezillaSiteManagerFile, FilezillaConfigurationFile);
  1276. if (ImportSessionList->Count > 0)
  1277. {
  1278. ImportSessionList->SelectSessionsToImport(Sessions, true);
  1279. }
  1280. else
  1281. {
  1282. Error = FMTLOAD(FILEZILLA_NO_SITES, (FilezillaSiteManagerFile));
  1283. }
  1284. }
  1285. else
  1286. {
  1287. Error = FMTLOAD(FILEZILLA_SITE_MANAGER_NOT_FOUND, (FilezillaSiteManagerFile));
  1288. }
  1289. return ImportSessionList.release();
  1290. }
  1291. //---------------------------------------------------------------------
  1292. bool __fastcall TConfiguration::AnyFilezillaSessionForImport(TStoredSessionList * Sessions)
  1293. {
  1294. try
  1295. {
  1296. UnicodeString Error;
  1297. std::unique_ptr<TStoredSessionList> Sesssions(SelectFilezillaSessionsForImport(Sessions, Error));
  1298. return (Sesssions->Count > 0);
  1299. }
  1300. catch (...)
  1301. {
  1302. return false;
  1303. }
  1304. }
  1305. //---------------------------------------------------------------------
  1306. TStoredSessionList * __fastcall TConfiguration::SelectKnownHostsSessionsForImport(
  1307. TStoredSessionList * Sessions, UnicodeString & Error)
  1308. {
  1309. std::unique_ptr<TStoredSessionList> ImportSessionList(new TStoredSessionList(true));
  1310. ImportSessionList->DefaultSettings = Sessions->DefaultSettings;
  1311. UnicodeString ProfilePath = GetShellFolderPath(CSIDL_PROFILE);
  1312. UnicodeString KnownHostsFile = IncludeTrailingBackslash(ProfilePath) + L".ssh\\known_hosts";
  1313. try
  1314. {
  1315. if (FileExists(ApiPath(KnownHostsFile)))
  1316. {
  1317. std::unique_ptr<TStrings> Lines(new TStringList());
  1318. LoadScriptFromFile(KnownHostsFile, Lines.get());
  1319. ImportSessionList->ImportFromKnownHosts(Lines.get());
  1320. }
  1321. else
  1322. {
  1323. throw Exception(LoadStr(KNOWN_HOSTS_NOT_FOUND));
  1324. }
  1325. }
  1326. catch (Exception & E)
  1327. {
  1328. Error = FORMAT(L"%s\n(%s)", (E.Message, KnownHostsFile));
  1329. }
  1330. return ImportSessionList.release();
  1331. }
  1332. //---------------------------------------------------------------------
  1333. TStoredSessionList * __fastcall TConfiguration::SelectKnownHostsSessionsForImport(
  1334. TStrings * Lines, TStoredSessionList * Sessions, UnicodeString & Error)
  1335. {
  1336. std::unique_ptr<TStoredSessionList> ImportSessionList(new TStoredSessionList(true));
  1337. ImportSessionList->DefaultSettings = Sessions->DefaultSettings;
  1338. try
  1339. {
  1340. ImportSessionList->ImportFromKnownHosts(Lines);
  1341. }
  1342. catch (Exception & E)
  1343. {
  1344. Error = E.Message;
  1345. }
  1346. return ImportSessionList.release();
  1347. }
  1348. //---------------------------------------------------------------------------
  1349. void __fastcall TConfiguration::SetRandomSeedFile(UnicodeString value)
  1350. {
  1351. if (RandomSeedFile != value)
  1352. {
  1353. UnicodeString PrevRandomSeedFileName = RandomSeedFileName;
  1354. FRandomSeedFile = value;
  1355. // never allow empty seed file to avoid Putty trying to reinitialize the path
  1356. if (RandomSeedFileName.IsEmpty())
  1357. {
  1358. FRandomSeedFile = FDefaultRandomSeedFile;
  1359. }
  1360. if (!PrevRandomSeedFileName.IsEmpty() &&
  1361. (PrevRandomSeedFileName != RandomSeedFileName) &&
  1362. FileExists(ApiPath(PrevRandomSeedFileName)))
  1363. {
  1364. // ignore any error
  1365. DeleteFile(ApiPath(PrevRandomSeedFileName));
  1366. }
  1367. }
  1368. }
  1369. //---------------------------------------------------------------------------
  1370. UnicodeString __fastcall TConfiguration::GetDirectoryStatisticsCacheKey(
  1371. const UnicodeString & SessionKey, const UnicodeString & Path, const TCopyParamType & CopyParam)
  1372. {
  1373. std::unique_ptr<TStringList> RawOptions(new TStringList());
  1374. RawOptions->Add(SessionKey);
  1375. RawOptions->Add(UnixExcludeTrailingBackslash(Path));
  1376. TCopyParamType Defaults;
  1377. TCopyParamType FilterCopyParam;
  1378. FilterCopyParam.IncludeFileMask = CopyParam.IncludeFileMask;
  1379. FilterCopyParam.ExcludeHiddenFiles = CopyParam.ExcludeHiddenFiles;
  1380. FilterCopyParam.ExcludeEmptyDirectories = CopyParam.ExcludeEmptyDirectories;
  1381. std::unique_ptr<TOptionsStorage> OptionsStorage(new TOptionsStorage(RawOptions.get(), true));
  1382. FilterCopyParam.Save(OptionsStorage.get(), &Defaults);
  1383. UTF8String RawOptionsBuf(RawOptions->CommaText.LowerCase());
  1384. UnicodeString Result = Sha256(RawOptionsBuf.c_str(), RawOptionsBuf.Length());
  1385. return Result;
  1386. }
  1387. //---------------------------------------------------------------------------
  1388. THierarchicalStorage * TConfiguration::OpenDirectoryStatisticsCache(bool CanCreate)
  1389. {
  1390. std::unique_ptr<THierarchicalStorage> Storage(Configuration->CreateConfigStorage());
  1391. Storage->AccessMode = CanCreate ? smReadWrite : smRead;
  1392. if (!Storage->OpenSubKey(L"DirectoryStatisticsCache", CanCreate))
  1393. {
  1394. Storage.reset(NULL);
  1395. }
  1396. return Storage.release();
  1397. }
  1398. //---------------------------------------------------------------------------
  1399. TStrings * __fastcall TConfiguration::LoadDirectoryStatisticsCache(
  1400. const UnicodeString & SessionKey, const UnicodeString & Path, const TCopyParamType & CopyParam)
  1401. {
  1402. std::unique_ptr<THierarchicalStorage> Storage(OpenDirectoryStatisticsCache(false));
  1403. std::unique_ptr<TStringList> Result(new TStringList());
  1404. if (Storage.get() != NULL)
  1405. {
  1406. UnicodeString Key = GetDirectoryStatisticsCacheKey(SessionKey, Path, CopyParam);
  1407. UnicodeString Buf = Storage->ReadString(Key, UnicodeString());
  1408. Result->CommaText = Buf;
  1409. }
  1410. return Result.release();
  1411. }
  1412. //---------------------------------------------------------------------------
  1413. void __fastcall TConfiguration::SaveDirectoryStatisticsCache(
  1414. const UnicodeString & SessionKey, const UnicodeString & Path, const TCopyParamType & CopyParam, TStrings * DataList)
  1415. {
  1416. std::unique_ptr<THierarchicalStorage> Storage(OpenDirectoryStatisticsCache(true));
  1417. if (Storage.get() != NULL)
  1418. {
  1419. UnicodeString Key = GetDirectoryStatisticsCacheKey(SessionKey, Path, CopyParam);
  1420. UnicodeString Buf = DataList->CommaText;
  1421. Storage->WriteString(Key, Buf);
  1422. }
  1423. }
  1424. //---------------------------------------------------------------------
  1425. UnicodeString __fastcall TConfiguration::GetRandomSeedFileName()
  1426. {
  1427. // StripPathQuotes should not be needed as we do not feed quotes anymore
  1428. return StripPathQuotes(ExpandEnvironmentVariables(FRandomSeedFile)).Trim();
  1429. }
  1430. //---------------------------------------------------------------------
  1431. void __fastcall TConfiguration::SetExternalIpAddress(UnicodeString value)
  1432. {
  1433. SET_CONFIG_PROPERTY(ExternalIpAddress);
  1434. }
  1435. //---------------------------------------------------------------------
  1436. void __fastcall TConfiguration::SetMimeTypes(UnicodeString value)
  1437. {
  1438. SET_CONFIG_PROPERTY(MimeTypes);
  1439. }
  1440. //---------------------------------------------------------------------
  1441. void __fastcall TConfiguration::SetTryFtpWhenSshFails(bool value)
  1442. {
  1443. SET_CONFIG_PROPERTY(TryFtpWhenSshFails);
  1444. }
  1445. //---------------------------------------------------------------------
  1446. void __fastcall TConfiguration::SetParallelDurationThreshold(int value)
  1447. {
  1448. SET_CONFIG_PROPERTY(ParallelDurationThreshold);
  1449. }
  1450. //---------------------------------------------------------------------
  1451. void __fastcall TConfiguration::SetPuttyRegistryStorageKey(UnicodeString value)
  1452. {
  1453. SET_CONFIG_PROPERTY(PuttyRegistryStorageKey);
  1454. }
  1455. //---------------------------------------------------------------------------
  1456. TEOLType __fastcall TConfiguration::GetLocalEOLType()
  1457. {
  1458. return eolCRLF;
  1459. }
  1460. //---------------------------------------------------------------------
  1461. bool __fastcall TConfiguration::GetCollectUsage()
  1462. {
  1463. return FUsage->Collect;
  1464. }
  1465. //---------------------------------------------------------------------
  1466. void __fastcall TConfiguration::SetCollectUsage(bool value)
  1467. {
  1468. FUsage->Collect = value;
  1469. }
  1470. //---------------------------------------------------------------------
  1471. void __fastcall TConfiguration::TemporaryLogging(const UnicodeString ALogFileName)
  1472. {
  1473. if (SameText(ExtractFileExt(ALogFileName), L".xml"))
  1474. {
  1475. TemporaryActionsLogging(ALogFileName);
  1476. }
  1477. else
  1478. {
  1479. FLogging = true;
  1480. FLogFileName = ALogFileName;
  1481. UpdateActualLogProtocol();
  1482. }
  1483. }
  1484. //---------------------------------------------------------------------
  1485. void __fastcall TConfiguration::TemporaryActionsLogging(const UnicodeString ALogFileName)
  1486. {
  1487. FLogActions = true;
  1488. FActionsLogFileName = ALogFileName;
  1489. }
  1490. //---------------------------------------------------------------------
  1491. void __fastcall TConfiguration::TemporaryLogProtocol(int ALogProtocol)
  1492. {
  1493. FLogProtocol = ALogProtocol;
  1494. UpdateActualLogProtocol();
  1495. }
  1496. //---------------------------------------------------------------------
  1497. void __fastcall TConfiguration::TemporaryLogSensitive(bool ALogSensitive)
  1498. {
  1499. FLogSensitive = ALogSensitive;
  1500. }
  1501. //---------------------------------------------------------------------
  1502. void __fastcall TConfiguration::TemporaryLogMaxSize(__int64 ALogMaxSize)
  1503. {
  1504. FLogMaxSize = ALogMaxSize;
  1505. }
  1506. //---------------------------------------------------------------------
  1507. void __fastcall TConfiguration::TemporaryLogMaxCount(int ALogMaxCount)
  1508. {
  1509. FLogMaxCount = ALogMaxCount;
  1510. }
  1511. //---------------------------------------------------------------------
  1512. void __fastcall TConfiguration::SetLogging(bool value)
  1513. {
  1514. TGuard Guard(FCriticalSection);
  1515. if (Logging != value)
  1516. {
  1517. FPermanentLogging = value;
  1518. FLogging = value;
  1519. UpdateActualLogProtocol();
  1520. Changed();
  1521. }
  1522. }
  1523. //---------------------------------------------------------------------
  1524. bool __fastcall TConfiguration::GetLogging()
  1525. {
  1526. TGuard Guard(FCriticalSection);
  1527. return FPermanentLogging;
  1528. }
  1529. //---------------------------------------------------------------------
  1530. void __fastcall TConfiguration::SetLogFileName(UnicodeString value)
  1531. {
  1532. TGuard Guard(FCriticalSection);
  1533. if (LogFileName != value)
  1534. {
  1535. FPermanentLogFileName = value;
  1536. FLogFileName = value;
  1537. Changed();
  1538. }
  1539. }
  1540. //---------------------------------------------------------------------
  1541. UnicodeString __fastcall TConfiguration::GetLogFileName()
  1542. {
  1543. TGuard Guard(FCriticalSection);
  1544. return FPermanentLogFileName;
  1545. }
  1546. //---------------------------------------------------------------------
  1547. void __fastcall TConfiguration::SetActionsLogFileName(UnicodeString value)
  1548. {
  1549. TGuard Guard(FCriticalSection);
  1550. if (ActionsLogFileName != value)
  1551. {
  1552. FPermanentActionsLogFileName = value;
  1553. FActionsLogFileName = value;
  1554. Changed();
  1555. }
  1556. }
  1557. //---------------------------------------------------------------------
  1558. UnicodeString __fastcall TConfiguration::GetPermanentActionsLogFileName()
  1559. {
  1560. TGuard Guard(FCriticalSection);
  1561. return FPermanentActionsLogFileName;
  1562. }
  1563. //---------------------------------------------------------------------
  1564. UnicodeString __fastcall TConfiguration::GetActionsLogFileName()
  1565. {
  1566. TGuard Guard(FCriticalSection);
  1567. return FActionsLogFileName;
  1568. }
  1569. //---------------------------------------------------------------------
  1570. bool __fastcall TConfiguration::GetLogToFile()
  1571. {
  1572. // guarded within GetLogFileName
  1573. return !LogFileName.IsEmpty();
  1574. }
  1575. //---------------------------------------------------------------------
  1576. void __fastcall TConfiguration::UpdateActualLogProtocol()
  1577. {
  1578. FActualLogProtocol = FLogging ? FLogProtocol : 0;
  1579. }
  1580. //---------------------------------------------------------------------
  1581. void __fastcall TConfiguration::SetLogProtocol(int value)
  1582. {
  1583. TGuard Guard(FCriticalSection);
  1584. if (LogProtocol != value)
  1585. {
  1586. FPermanentLogProtocol = value;
  1587. FLogProtocol = value;
  1588. Changed();
  1589. UpdateActualLogProtocol();
  1590. }
  1591. }
  1592. //---------------------------------------------------------------------
  1593. void __fastcall TConfiguration::SetLogActions(bool value)
  1594. {
  1595. TGuard Guard(FCriticalSection);
  1596. if (LogActions != value)
  1597. {
  1598. FPermanentLogActions = value;
  1599. FLogActions = value;
  1600. Changed();
  1601. }
  1602. }
  1603. //---------------------------------------------------------------------
  1604. bool __fastcall TConfiguration::GetLogActions()
  1605. {
  1606. TGuard Guard(FCriticalSection);
  1607. return FPermanentLogActions;
  1608. }
  1609. //---------------------------------------------------------------------
  1610. void __fastcall TConfiguration::SetLogFileAppend(bool value)
  1611. {
  1612. SET_CONFIG_PROPERTY(LogFileAppend);
  1613. }
  1614. //---------------------------------------------------------------------
  1615. void __fastcall TConfiguration::SetLogSensitive(bool value)
  1616. {
  1617. if (LogSensitive != value)
  1618. {
  1619. FPermanentLogSensitive = value;
  1620. FLogSensitive = value;
  1621. Changed();
  1622. }
  1623. }
  1624. //---------------------------------------------------------------------
  1625. void __fastcall TConfiguration::SetLogMaxSize(__int64 value)
  1626. {
  1627. TGuard Guard(FCriticalSection);
  1628. if (LogMaxSize != value)
  1629. {
  1630. FPermanentLogMaxSize = value;
  1631. FLogMaxSize = value;
  1632. Changed();
  1633. }
  1634. }
  1635. //---------------------------------------------------------------------
  1636. __int64 __fastcall TConfiguration::GetLogMaxSize()
  1637. {
  1638. TGuard Guard(FCriticalSection);
  1639. return FPermanentLogMaxSize;
  1640. }
  1641. //---------------------------------------------------------------------
  1642. void __fastcall TConfiguration::SetLogMaxCount(int value)
  1643. {
  1644. if (LogMaxCount != value)
  1645. {
  1646. FPermanentLogMaxCount = value;
  1647. FLogMaxCount = value;
  1648. Changed();
  1649. }
  1650. }
  1651. //---------------------------------------------------------------------
  1652. int __fastcall TConfiguration::GetLogMaxCount()
  1653. {
  1654. TGuard Guard(FCriticalSection);
  1655. return FPermanentLogMaxCount;
  1656. }
  1657. //---------------------------------------------------------------------
  1658. UnicodeString __fastcall TConfiguration::GetDefaultLogFileName()
  1659. {
  1660. return L"%TEMP%\\!S.log";
  1661. }
  1662. //---------------------------------------------------------------------------
  1663. void __fastcall TConfiguration::SetConfirmOverwriting(bool value)
  1664. {
  1665. TGuard Guard(FCriticalSection);
  1666. SET_CONFIG_PROPERTY(ConfirmOverwriting);
  1667. }
  1668. //---------------------------------------------------------------------------
  1669. bool __fastcall TConfiguration::GetConfirmOverwriting()
  1670. {
  1671. TGuard Guard(FCriticalSection);
  1672. return FConfirmOverwriting;
  1673. }
  1674. //---------------------------------------------------------------------------
  1675. void __fastcall TConfiguration::SetConfirmResume(bool value)
  1676. {
  1677. TGuard Guard(FCriticalSection);
  1678. SET_CONFIG_PROPERTY(ConfirmResume);
  1679. }
  1680. //---------------------------------------------------------------------------
  1681. bool __fastcall TConfiguration::GetConfirmResume()
  1682. {
  1683. TGuard Guard(FCriticalSection);
  1684. return FConfirmResume;
  1685. }
  1686. //---------------------------------------------------------------------------
  1687. void __fastcall TConfiguration::SetAutoReadDirectoryAfterOp(bool value)
  1688. {
  1689. TGuard Guard(FCriticalSection);
  1690. SET_CONFIG_PROPERTY(AutoReadDirectoryAfterOp);
  1691. }
  1692. //---------------------------------------------------------------------------
  1693. bool __fastcall TConfiguration::GetAutoReadDirectoryAfterOp()
  1694. {
  1695. TGuard Guard(FCriticalSection);
  1696. return FAutoReadDirectoryAfterOp;
  1697. }
  1698. //---------------------------------------------------------------------------
  1699. UnicodeString __fastcall TConfiguration::GetTimeFormat()
  1700. {
  1701. return L"h:nn:ss";
  1702. }
  1703. //---------------------------------------------------------------------------
  1704. UnicodeString __fastcall TConfiguration::GetPartialExt() const
  1705. {
  1706. return PARTIAL_EXT;
  1707. }
  1708. //---------------------------------------------------------------------------
  1709. UnicodeString __fastcall TConfiguration::GetDefaultKeyFile()
  1710. {
  1711. return L"";
  1712. }
  1713. //---------------------------------------------------------------------------
  1714. bool __fastcall TConfiguration::GetRememberPassword()
  1715. {
  1716. return false;
  1717. }
  1718. //---------------------------------------------------------------------------
  1719. void __fastcall TConfiguration::SetSessionReopenAuto(int value)
  1720. {
  1721. SET_CONFIG_PROPERTY(SessionReopenAuto);
  1722. }
  1723. //---------------------------------------------------------------------------
  1724. void __fastcall TConfiguration::SetSessionReopenBackground(int value)
  1725. {
  1726. SET_CONFIG_PROPERTY(SessionReopenBackground);
  1727. }
  1728. //---------------------------------------------------------------------------
  1729. void __fastcall TConfiguration::SetSessionReopenTimeout(int value)
  1730. {
  1731. SET_CONFIG_PROPERTY(SessionReopenTimeout);
  1732. }
  1733. //---------------------------------------------------------------------------
  1734. void __fastcall TConfiguration::SetSessionReopenAutoStall(int value)
  1735. {
  1736. SET_CONFIG_PROPERTY(SessionReopenAutoStall);
  1737. }
  1738. //---------------------------------------------------------------------------
  1739. void __fastcall TConfiguration::SetTunnelLocalPortNumberLow(int value)
  1740. {
  1741. SET_CONFIG_PROPERTY(TunnelLocalPortNumberLow);
  1742. }
  1743. //---------------------------------------------------------------------------
  1744. void __fastcall TConfiguration::SetTunnelLocalPortNumberHigh(int value)
  1745. {
  1746. SET_CONFIG_PROPERTY(TunnelLocalPortNumberHigh);
  1747. }
  1748. //---------------------------------------------------------------------------
  1749. void __fastcall TConfiguration::SetCacheDirectoryChangesMaxSize(int value)
  1750. {
  1751. SET_CONFIG_PROPERTY(CacheDirectoryChangesMaxSize);
  1752. }
  1753. //---------------------------------------------------------------------------
  1754. void __fastcall TConfiguration::SetShowFtpWelcomeMessage(bool value)
  1755. {
  1756. SET_CONFIG_PROPERTY(ShowFtpWelcomeMessage);
  1757. }
  1758. //---------------------------------------------------------------------------
  1759. bool __fastcall TConfiguration::GetPersistent()
  1760. {
  1761. return (Storage != stNul) && !FDontSave;
  1762. }
  1763. //---------------------------------------------------------------------------
  1764. //---------------------------------------------------------------------------
  1765. void __fastcall TShortCuts::Add(TShortCut ShortCut)
  1766. {
  1767. FShortCuts.insert(ShortCut);
  1768. }
  1769. //---------------------------------------------------------------------------
  1770. bool __fastcall TShortCuts::Has(TShortCut ShortCut) const
  1771. {
  1772. return (FShortCuts.count(ShortCut) != 0);
  1773. }