Configuration.cpp 51 KB

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