Configuration.cpp 63 KB

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