Configuration.cpp 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312
  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. //---------------------------------------------------------------------------
  16. #pragma package(smart_init)
  17. //---------------------------------------------------------------------------
  18. __fastcall TConfiguration::TConfiguration()
  19. {
  20. FCriticalSection = new TCriticalSection();
  21. FUpdating = 0;
  22. FStorage = stDetect;
  23. FDontSave = false;
  24. FApplicationInfo = NULL;
  25. FUsage = new TUsage(this);
  26. FDefaultCollectUsage = false;
  27. wchar_t Buf[10];
  28. UnicodeString RandomSeedPath;
  29. if (GetEnvironmentVariable(L"APPDATA", Buf, LENOF(Buf)) > 0)
  30. {
  31. RandomSeedPath = L"%APPDATA%";
  32. }
  33. else
  34. {
  35. RandomSeedPath = GetShellFolderPath(CSIDL_LOCAL_APPDATA);
  36. if (RandomSeedPath.IsEmpty())
  37. {
  38. RandomSeedPath = GetShellFolderPath(CSIDL_APPDATA);
  39. }
  40. }
  41. FDefaultRandomSeedFile = IncludeTrailingBackslash(RandomSeedPath) + L"winscp.rnd";
  42. }
  43. //---------------------------------------------------------------------------
  44. void __fastcall TConfiguration::Default()
  45. {
  46. TGuard Guard(FCriticalSection);
  47. FDisablePasswordStoring = false;
  48. FForceBanners = false;
  49. FDisableAcceptingHostKeys = false;
  50. TRegistryStorage * AdminStorage;
  51. AdminStorage = new TRegistryStorage(RegistryStorageKey, HKEY_LOCAL_MACHINE);
  52. try
  53. {
  54. if (AdminStorage->OpenRootKey(false))
  55. {
  56. LoadAdmin(AdminStorage);
  57. AdminStorage->CloseSubKey();
  58. }
  59. }
  60. __finally
  61. {
  62. delete AdminStorage;
  63. }
  64. RandomSeedFile = FDefaultRandomSeedFile;
  65. PuttyRegistryStorageKey = OriginalPuttyRegistryStorageKey;
  66. FConfirmOverwriting = true;
  67. FConfirmResume = true;
  68. FAutoReadDirectoryAfterOp = true;
  69. FSessionReopenAuto = 5000;
  70. FSessionReopenBackground = 2000;
  71. FSessionReopenTimeout = 0;
  72. FSessionReopenAutoStall = 60000;
  73. FTunnelLocalPortNumberLow = 50000;
  74. FTunnelLocalPortNumberHigh = 50099;
  75. FCacheDirectoryChangesMaxSize = 100;
  76. FShowFtpWelcomeMessage = false;
  77. FExternalIpAddress = L"";
  78. FTryFtpWhenSshFails = true;
  79. CollectUsage = FDefaultCollectUsage;
  80. FLogging = false;
  81. FPermanentLogging = false;
  82. FLogFileName = DefaultLogFileName;
  83. FPermanentLogFileName = FLogFileName;
  84. FLogFileAppend = true;
  85. FLogWindowLines = 100;
  86. FLogProtocol = 0;
  87. UpdateActualLogProtocol();
  88. FLogActions = false;
  89. FPermanentLogActions = false;
  90. FActionsLogFileName = L"%TEMP%\\!S.xml";
  91. FPermanentActionsLogFileName = FActionsLogFileName;
  92. FProgramIniPathWrittable = -1;
  93. Changed();
  94. }
  95. //---------------------------------------------------------------------------
  96. __fastcall TConfiguration::~TConfiguration()
  97. {
  98. assert(!FUpdating);
  99. if (FApplicationInfo) FreeFileInfo(FApplicationInfo);
  100. delete FCriticalSection;
  101. delete FUsage;
  102. }
  103. //---------------------------------------------------------------------------
  104. void __fastcall TConfiguration::UpdateStaticUsage()
  105. {
  106. Usage->Set(L"ConfigurationIniFile", (Storage == stIniFile));
  107. // this is called from here, because we are guarded from calling into
  108. // master password handler here, see TWinConfiguration::UpdateStaticUsage
  109. StoredSessions->UpdateStaticUsage();
  110. }
  111. //---------------------------------------------------------------------------
  112. THierarchicalStorage * TConfiguration::CreateScpStorage(bool /*SessionList*/)
  113. {
  114. THierarchicalStorage * Result;
  115. if (Storage == stRegistry)
  116. {
  117. Result = new TRegistryStorage(RegistryStorageKey);
  118. }
  119. else if (Storage == stNul)
  120. {
  121. Result = new TIniFileStorage(L"nul");
  122. }
  123. else
  124. {
  125. Result = new TIniFileStorage(IniFileStorageName);
  126. }
  127. return Result;
  128. }
  129. //---------------------------------------------------------------------------
  130. UnicodeString __fastcall TConfiguration::PropertyToKey(const UnicodeString & Property)
  131. {
  132. // no longer useful
  133. int P = Property.LastDelimiter(L".>");
  134. return Property.SubString(P + 1, Property.Length() - P);
  135. }
  136. //---------------------------------------------------------------------------
  137. #define BLOCK(KEY, CANCREATE, BLOCK) \
  138. if (Storage->OpenSubKey(KEY, CANCREATE, true)) try { BLOCK } __finally { Storage->CloseSubKey(); }
  139. #define KEY(TYPE, VAR) KEYEX(TYPE, VAR, PropertyToKey(TEXT(#VAR)))
  140. #define REGCONFIG(CANCREATE) \
  141. BLOCK(L"Interface", CANCREATE, \
  142. KEY(String, RandomSeedFile); \
  143. KEY(String, PuttyRegistryStorageKey); \
  144. KEY(Bool, ConfirmOverwriting); \
  145. KEY(Bool, ConfirmResume); \
  146. KEY(Bool, AutoReadDirectoryAfterOp); \
  147. KEY(Integer, SessionReopenAuto); \
  148. KEY(Integer, SessionReopenBackground); \
  149. KEY(Integer, SessionReopenTimeout); \
  150. KEY(Integer, SessionReopenAutoStall); \
  151. KEY(Integer, TunnelLocalPortNumberLow); \
  152. KEY(Integer, TunnelLocalPortNumberHigh); \
  153. KEY(Integer, CacheDirectoryChangesMaxSize); \
  154. KEY(Bool, ShowFtpWelcomeMessage); \
  155. KEY(String, ExternalIpAddress); \
  156. KEY(Bool, TryFtpWhenSshFails); \
  157. KEY(Bool, CollectUsage); \
  158. ); \
  159. BLOCK(L"Logging", CANCREATE, \
  160. KEYEX(Bool, PermanentLogging, L"Logging"); \
  161. KEYEX(String,PermanentLogFileName, L"LogFileName"); \
  162. KEY(Bool, LogFileAppend); \
  163. KEY(Integer, LogWindowLines); \
  164. KEY(Integer, LogProtocol); \
  165. KEYEX(Bool, PermanentLogActions, L"LogActions"); \
  166. KEYEX(String,PermanentActionsLogFileName, L"ActionsLogFileName"); \
  167. );
  168. //---------------------------------------------------------------------------
  169. void __fastcall TConfiguration::SaveData(THierarchicalStorage * Storage, bool /*All*/)
  170. {
  171. #define KEYEX(TYPE, VAR, NAME) Storage->Write ## TYPE(NAME, VAR)
  172. REGCONFIG(true);
  173. #undef KEYEX
  174. if (Storage->OpenSubKey(L"Usage", true))
  175. {
  176. FUsage->Save(Storage);
  177. Storage->CloseSubKey();
  178. }
  179. }
  180. //---------------------------------------------------------------------------
  181. void __fastcall TConfiguration::Save()
  182. {
  183. // only modified, implicit
  184. DoSave(false, false);
  185. }
  186. //---------------------------------------------------------------------------
  187. void __fastcall TConfiguration::SaveExplicit()
  188. {
  189. // only modified, explicit
  190. DoSave(false, true);
  191. }
  192. //---------------------------------------------------------------------------
  193. void __fastcall TConfiguration::DoSave(bool All, bool Explicit)
  194. {
  195. if (FDontSave) return;
  196. THierarchicalStorage * AStorage = CreateScpStorage(false);
  197. try
  198. {
  199. AStorage->AccessMode = smReadWrite;
  200. AStorage->Explicit = Explicit;
  201. if (AStorage->OpenSubKey(ConfigurationSubKey, true))
  202. {
  203. SaveData(AStorage, All);
  204. }
  205. }
  206. __finally
  207. {
  208. delete AStorage;
  209. }
  210. Saved();
  211. if (All)
  212. {
  213. StoredSessions->Save(true, Explicit);
  214. }
  215. // clean up as last, so that if it fails (read only INI), the saving can proceed
  216. if (Storage == stRegistry)
  217. {
  218. CleanupIniFile();
  219. }
  220. }
  221. //---------------------------------------------------------------------------
  222. void __fastcall TConfiguration::Export(const UnicodeString & FileName)
  223. {
  224. THierarchicalStorage * Storage = NULL;
  225. THierarchicalStorage * ExportStorage = NULL;
  226. try
  227. {
  228. ExportStorage = new TIniFileStorage(FileName);
  229. ExportStorage->AccessMode = smReadWrite;
  230. ExportStorage->Explicit = true;
  231. Storage = CreateScpStorage(false);
  232. Storage->AccessMode = smRead;
  233. CopyData(Storage, ExportStorage);
  234. if (ExportStorage->OpenSubKey(ConfigurationSubKey, true))
  235. {
  236. SaveData(ExportStorage, true);
  237. }
  238. }
  239. __finally
  240. {
  241. delete ExportStorage;
  242. delete Storage;
  243. }
  244. StoredSessions->Export(FileName);
  245. }
  246. //---------------------------------------------------------------------------
  247. void __fastcall TConfiguration::Import(const UnicodeString & FileName)
  248. {
  249. THierarchicalStorage * Storage = NULL;
  250. THierarchicalStorage * ImportStorage = NULL;
  251. try
  252. {
  253. ImportStorage = new TIniFileStorage(FileName);
  254. ImportStorage->AccessMode = smRead;
  255. Storage = CreateScpStorage(false);
  256. Storage->AccessMode = smReadWrite;
  257. Storage->Explicit = true;
  258. CopyData(ImportStorage, Storage);
  259. Default();
  260. LoadFrom(ImportStorage);
  261. if (ImportStorage->OpenSubKey(Configuration->StoredSessionsSubKey, false))
  262. {
  263. StoredSessions->Clear();
  264. StoredSessions->DefaultSettings->Default();
  265. StoredSessions->Load(ImportStorage);
  266. }
  267. }
  268. __finally
  269. {
  270. delete ImportStorage;
  271. delete Storage;
  272. }
  273. // save all and explicit
  274. DoSave(true, true);
  275. }
  276. //---------------------------------------------------------------------------
  277. void __fastcall TConfiguration::LoadData(THierarchicalStorage * Storage)
  278. {
  279. #define KEYEX(TYPE, VAR, NAME) VAR = Storage->Read ## TYPE(NAME, VAR)
  280. #pragma warn -eas
  281. REGCONFIG(false);
  282. #pragma warn +eas
  283. #undef KEYEX
  284. if (Storage->OpenSubKey(L"Usage", false))
  285. {
  286. FUsage->Load(Storage);
  287. Storage->CloseSubKey();
  288. }
  289. if (FPermanentLogActions && FPermanentActionsLogFileName.IsEmpty() &&
  290. FPermanentLogging && !FPermanentLogFileName.IsEmpty())
  291. {
  292. FPermanentActionsLogFileName = FPermanentLogFileName;
  293. FPermanentLogging = false;
  294. FPermanentLogFileName = L"";
  295. }
  296. }
  297. //---------------------------------------------------------------------------
  298. void __fastcall TConfiguration::LoadAdmin(THierarchicalStorage * Storage)
  299. {
  300. FDisablePasswordStoring = Storage->ReadBool(L"DisablePasswordStoring", FDisablePasswordStoring);
  301. FForceBanners = Storage->ReadBool(L"ForceBanners", FForceBanners);
  302. FDisableAcceptingHostKeys = Storage->ReadBool(L"DisableAcceptingHostKeys", FDisableAcceptingHostKeys);
  303. FDefaultCollectUsage = Storage->ReadBool(L"DefaultCollectUsage", FDefaultCollectUsage);
  304. }
  305. //---------------------------------------------------------------------------
  306. void __fastcall TConfiguration::LoadFrom(THierarchicalStorage * Storage)
  307. {
  308. if (Storage->OpenSubKey(ConfigurationSubKey, false))
  309. {
  310. LoadData(Storage);
  311. Storage->CloseSubKey();
  312. }
  313. }
  314. //---------------------------------------------------------------------------
  315. void __fastcall TConfiguration::Load()
  316. {
  317. TGuard Guard(FCriticalSection);
  318. THierarchicalStorage * Storage = CreateScpStorage(false);
  319. try
  320. {
  321. Storage->AccessMode = smRead;
  322. LoadFrom(Storage);
  323. }
  324. __finally
  325. {
  326. delete Storage;
  327. }
  328. }
  329. //---------------------------------------------------------------------------
  330. void __fastcall TConfiguration::CopyData(THierarchicalStorage * Source,
  331. THierarchicalStorage * Target)
  332. {
  333. TStrings * Names = new TStringList();
  334. try
  335. {
  336. if (Source->OpenSubKey(ConfigurationSubKey, false))
  337. {
  338. if (Target->OpenSubKey(ConfigurationSubKey, true))
  339. {
  340. if (Source->OpenSubKey(L"CDCache", false))
  341. {
  342. if (Target->OpenSubKey(L"CDCache", true))
  343. {
  344. Names->Clear();
  345. Source->GetValueNames(Names);
  346. for (int Index = 0; Index < Names->Count; Index++)
  347. {
  348. Target->WriteBinaryData(Names->Strings[Index],
  349. Source->ReadBinaryData(Names->Strings[Index]));
  350. }
  351. Target->CloseSubKey();
  352. }
  353. Source->CloseSubKey();
  354. }
  355. if (Source->OpenSubKey(L"Banners", false))
  356. {
  357. if (Target->OpenSubKey(L"Banners", true))
  358. {
  359. Names->Clear();
  360. Source->GetValueNames(Names);
  361. for (int Index = 0; Index < Names->Count; Index++)
  362. {
  363. Target->WriteString(Names->Strings[Index],
  364. Source->ReadString(Names->Strings[Index], L""));
  365. }
  366. Target->CloseSubKey();
  367. }
  368. Source->CloseSubKey();
  369. }
  370. Target->CloseSubKey();
  371. }
  372. Source->CloseSubKey();
  373. }
  374. if (Source->OpenSubKey(SshHostKeysSubKey, false))
  375. {
  376. if (Target->OpenSubKey(SshHostKeysSubKey, true))
  377. {
  378. Names->Clear();
  379. Source->GetValueNames(Names);
  380. for (int Index = 0; Index < Names->Count; Index++)
  381. {
  382. Target->WriteStringRaw(Names->Strings[Index],
  383. Source->ReadStringRaw(Names->Strings[Index], L""));
  384. }
  385. Target->CloseSubKey();
  386. }
  387. Source->CloseSubKey();
  388. }
  389. }
  390. __finally
  391. {
  392. delete Names;
  393. }
  394. }
  395. //---------------------------------------------------------------------------
  396. void __fastcall TConfiguration::LoadDirectoryChangesCache(const UnicodeString SessionKey,
  397. TRemoteDirectoryChangesCache * DirectoryChangesCache)
  398. {
  399. THierarchicalStorage * Storage = CreateScpStorage(false);
  400. try
  401. {
  402. Storage->AccessMode = smRead;
  403. if (Storage->OpenSubKey(ConfigurationSubKey, false) &&
  404. Storage->OpenSubKey(L"CDCache", false) &&
  405. Storage->ValueExists(SessionKey))
  406. {
  407. DirectoryChangesCache->Deserialize(Storage->ReadBinaryData(SessionKey));
  408. }
  409. }
  410. __finally
  411. {
  412. delete Storage;
  413. }
  414. }
  415. //---------------------------------------------------------------------------
  416. void __fastcall TConfiguration::SaveDirectoryChangesCache(const UnicodeString SessionKey,
  417. TRemoteDirectoryChangesCache * DirectoryChangesCache)
  418. {
  419. THierarchicalStorage * Storage = CreateScpStorage(false);
  420. try
  421. {
  422. Storage->AccessMode = smReadWrite;
  423. if (Storage->OpenSubKey(ConfigurationSubKey, true) &&
  424. Storage->OpenSubKey(L"CDCache", true))
  425. {
  426. UnicodeString Data;
  427. DirectoryChangesCache->Serialize(Data);
  428. Storage->WriteBinaryData(SessionKey, Data);
  429. }
  430. }
  431. __finally
  432. {
  433. delete Storage;
  434. }
  435. }
  436. //---------------------------------------------------------------------------
  437. UnicodeString __fastcall TConfiguration::BannerHash(const UnicodeString & Banner)
  438. {
  439. RawByteString Result;
  440. Result.SetLength(16);
  441. md5checksum(
  442. reinterpret_cast<const char*>(Banner.c_str()), Banner.Length() * sizeof(wchar_t),
  443. (unsigned char*)Result.c_str());
  444. return BytesToHex(Result);
  445. }
  446. //---------------------------------------------------------------------------
  447. bool __fastcall TConfiguration::ShowBanner(const UnicodeString SessionKey,
  448. const UnicodeString & Banner)
  449. {
  450. bool Result;
  451. THierarchicalStorage * Storage = CreateScpStorage(false);
  452. try
  453. {
  454. Storage->AccessMode = smRead;
  455. Result =
  456. !Storage->OpenSubKey(ConfigurationSubKey, false) ||
  457. !Storage->OpenSubKey(L"Banners", false) ||
  458. !Storage->ValueExists(SessionKey) ||
  459. (Storage->ReadString(SessionKey, L"") != BannerHash(Banner));
  460. }
  461. __finally
  462. {
  463. delete Storage;
  464. }
  465. return Result;
  466. }
  467. //---------------------------------------------------------------------------
  468. void __fastcall TConfiguration::NeverShowBanner(const UnicodeString SessionKey,
  469. const UnicodeString & Banner)
  470. {
  471. THierarchicalStorage * Storage = CreateScpStorage(false);
  472. try
  473. {
  474. Storage->AccessMode = smReadWrite;
  475. if (Storage->OpenSubKey(ConfigurationSubKey, true) &&
  476. Storage->OpenSubKey(L"Banners", true))
  477. {
  478. Storage->WriteString(SessionKey, BannerHash(Banner));
  479. }
  480. }
  481. __finally
  482. {
  483. delete Storage;
  484. }
  485. }
  486. //---------------------------------------------------------------------------
  487. void __fastcall TConfiguration::Changed()
  488. {
  489. if (FUpdating == 0)
  490. {
  491. if (OnChange)
  492. {
  493. OnChange(this);
  494. }
  495. }
  496. else
  497. {
  498. FChanged = true;
  499. }
  500. }
  501. //---------------------------------------------------------------------------
  502. void __fastcall TConfiguration::BeginUpdate()
  503. {
  504. if (FUpdating == 0)
  505. {
  506. FChanged = false;
  507. }
  508. FUpdating++;
  509. // Greater value would probably indicate some nesting problem in code
  510. assert(FUpdating < 6);
  511. }
  512. //---------------------------------------------------------------------------
  513. void __fastcall TConfiguration::EndUpdate()
  514. {
  515. assert(FUpdating > 0);
  516. FUpdating--;
  517. if ((FUpdating == 0) && FChanged)
  518. {
  519. FChanged = false;
  520. Changed();
  521. }
  522. }
  523. //---------------------------------------------------------------------------
  524. void __fastcall TConfiguration::CleanupConfiguration()
  525. {
  526. try
  527. {
  528. CleanupRegistry(ConfigurationSubKey);
  529. if (Storage == stRegistry)
  530. {
  531. FDontSave = true;
  532. }
  533. }
  534. catch (Exception &E)
  535. {
  536. throw ExtException(&E, LoadStr(CLEANUP_CONFIG_ERROR));
  537. }
  538. }
  539. //---------------------------------------------------------------------------
  540. void __fastcall TConfiguration::CleanupRegistry(UnicodeString CleanupSubKey)
  541. {
  542. TRegistryStorage *Registry = new TRegistryStorage(RegistryStorageKey);
  543. try
  544. {
  545. Registry->RecursiveDeleteSubKey(CleanupSubKey);
  546. }
  547. __finally
  548. {
  549. delete Registry;
  550. }
  551. }
  552. //---------------------------------------------------------------------------
  553. void __fastcall TConfiguration::CleanupHostKeys()
  554. {
  555. try
  556. {
  557. CleanupRegistry(SshHostKeysSubKey);
  558. }
  559. catch (Exception &E)
  560. {
  561. throw ExtException(&E, LoadStr(CLEANUP_HOSTKEYS_ERROR));
  562. }
  563. }
  564. //---------------------------------------------------------------------------
  565. void __fastcall TConfiguration::CleanupRandomSeedFile()
  566. {
  567. try
  568. {
  569. DontSaveRandomSeed();
  570. if (FileExists(RandomSeedFileName))
  571. {
  572. DeleteFileChecked(RandomSeedFileName);
  573. }
  574. }
  575. catch (Exception &E)
  576. {
  577. throw ExtException(&E, LoadStr(CLEANUP_SEEDFILE_ERROR));
  578. }
  579. }
  580. //---------------------------------------------------------------------------
  581. void __fastcall TConfiguration::CleanupIniFile()
  582. {
  583. try
  584. {
  585. if (FileExists(IniFileStorageNameForReading))
  586. {
  587. DeleteFileChecked(IniFileStorageNameForReading);
  588. }
  589. if (Storage == stIniFile)
  590. {
  591. FDontSave = true;
  592. }
  593. }
  594. catch (Exception &E)
  595. {
  596. throw ExtException(&E, LoadStr(CLEANUP_INIFILE_ERROR));
  597. }
  598. }
  599. //---------------------------------------------------------------------------
  600. RawByteString __fastcall TConfiguration::EncryptPassword(UnicodeString Password, UnicodeString Key)
  601. {
  602. if (Password.IsEmpty())
  603. {
  604. return RawByteString();
  605. }
  606. else
  607. {
  608. return ::EncryptPassword(Password, Key);
  609. }
  610. }
  611. //---------------------------------------------------------------------------
  612. UnicodeString __fastcall TConfiguration::DecryptPassword(RawByteString Password, UnicodeString Key)
  613. {
  614. if (Password.IsEmpty())
  615. {
  616. return UnicodeString();
  617. }
  618. else
  619. {
  620. return ::DecryptPassword(Password, Key);
  621. }
  622. }
  623. //---------------------------------------------------------------------------
  624. RawByteString __fastcall TConfiguration::StronglyRecryptPassword(RawByteString Password, UnicodeString /*Key*/)
  625. {
  626. return Password;
  627. }
  628. //---------------------------------------------------------------------------
  629. UnicodeString __fastcall TConfiguration::GetOSVersionStr()
  630. {
  631. UnicodeString Result;
  632. OSVERSIONINFO OSVersionInfo;
  633. OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVersionInfo);
  634. if (GetVersionEx(&OSVersionInfo) != 0)
  635. {
  636. Result = FORMAT(L"%d.%d.%d", (int(OSVersionInfo.dwMajorVersion),
  637. int(OSVersionInfo.dwMinorVersion), int(OSVersionInfo.dwBuildNumber)));
  638. UnicodeString CSDVersion = OSVersionInfo.szCSDVersion;
  639. if (!CSDVersion.IsEmpty())
  640. {
  641. Result += L" " + CSDVersion;
  642. }
  643. UnicodeString ProductName = WindowsProductName();
  644. if (!ProductName.IsEmpty())
  645. {
  646. Result += L" - " + ProductName;
  647. }
  648. }
  649. return Result;
  650. }
  651. //---------------------------------------------------------------------------
  652. TVSFixedFileInfo *__fastcall TConfiguration::GetFixedApplicationInfo()
  653. {
  654. return GetFixedFileInfo(ApplicationInfo);
  655. }
  656. //---------------------------------------------------------------------------
  657. int __fastcall TConfiguration::GetCompoundVersion()
  658. {
  659. TVSFixedFileInfo * FileInfo = FixedApplicationInfo;
  660. return CalculateCompoundVersion(
  661. HIWORD(FileInfo->dwFileVersionMS), LOWORD(FileInfo->dwFileVersionMS),
  662. HIWORD(FileInfo->dwFileVersionLS), LOWORD(FileInfo->dwFileVersionLS));
  663. }
  664. //---------------------------------------------------------------------------
  665. UnicodeString __fastcall TConfiguration::ModuleFileName()
  666. {
  667. return ParamStr(0);
  668. }
  669. //---------------------------------------------------------------------------
  670. void * __fastcall TConfiguration::GetFileApplicationInfo(const UnicodeString FileName)
  671. {
  672. void * Result;
  673. if (FileName.IsEmpty())
  674. {
  675. if (!FApplicationInfo)
  676. {
  677. FApplicationInfo = CreateFileInfo(ModuleFileName());
  678. }
  679. Result = FApplicationInfo;
  680. }
  681. else
  682. {
  683. Result = CreateFileInfo(FileName);
  684. }
  685. return Result;
  686. }
  687. //---------------------------------------------------------------------------
  688. void * __fastcall TConfiguration::GetApplicationInfo()
  689. {
  690. return GetFileApplicationInfo("");
  691. }
  692. //---------------------------------------------------------------------------
  693. UnicodeString __fastcall TConfiguration::GetFileProductName(const UnicodeString FileName)
  694. {
  695. return GetFileFileInfoString(L"ProductName", FileName);
  696. }
  697. //---------------------------------------------------------------------------
  698. UnicodeString __fastcall TConfiguration::GetFileCompanyName(const UnicodeString FileName)
  699. {
  700. return GetFileFileInfoString(L"CompanyName", FileName);
  701. }
  702. //---------------------------------------------------------------------------
  703. UnicodeString __fastcall TConfiguration::GetProductName()
  704. {
  705. return GetFileProductName(L"");
  706. }
  707. //---------------------------------------------------------------------------
  708. UnicodeString __fastcall TConfiguration::GetCompanyName()
  709. {
  710. return GetFileCompanyName(L"");
  711. }
  712. //---------------------------------------------------------------------------
  713. UnicodeString __fastcall TConfiguration::GetFileProductVersion(const UnicodeString FileName)
  714. {
  715. return TrimVersion(GetFileFileInfoString(L"ProductVersion", FileName));
  716. }
  717. //---------------------------------------------------------------------------
  718. UnicodeString __fastcall TConfiguration::GetFileDescription(const UnicodeString & FileName)
  719. {
  720. return GetFileFileInfoString(L"FileDescription", FileName);
  721. }
  722. //---------------------------------------------------------------------------
  723. UnicodeString __fastcall TConfiguration::GetProductVersion()
  724. {
  725. return GetFileProductVersion(L"");
  726. }
  727. //---------------------------------------------------------------------------
  728. UnicodeString __fastcall TConfiguration::TrimVersion(UnicodeString Version)
  729. {
  730. while ((Version.Pos(L".") != Version.LastDelimiter(L".")) &&
  731. (Version.SubString(Version.Length() - 1, 2) == L".0"))
  732. {
  733. Version.SetLength(Version.Length() - 2);
  734. }
  735. return Version;
  736. }
  737. //---------------------------------------------------------------------------
  738. UnicodeString __fastcall TConfiguration::GetVersionStr()
  739. {
  740. TGuard Guard(FCriticalSection);
  741. try
  742. {
  743. TVSFixedFileInfo * Info = FixedApplicationInfo;
  744. return FMTLOAD(VERSION, (
  745. HIWORD(Info->dwFileVersionMS),
  746. LOWORD(Info->dwFileVersionMS),
  747. HIWORD(Info->dwFileVersionLS),
  748. LOWORD(Info->dwFileVersionLS)));
  749. }
  750. catch (Exception &E)
  751. {
  752. throw ExtException(&E, L"Can't get application version");
  753. }
  754. }
  755. //---------------------------------------------------------------------------
  756. UnicodeString __fastcall TConfiguration::GetVersion()
  757. {
  758. TGuard Guard(FCriticalSection);
  759. try
  760. {
  761. TVSFixedFileInfo * Info = FixedApplicationInfo;
  762. UnicodeString Result;
  763. Result = TrimVersion(FORMAT(L"%d.%d.%d", (
  764. HIWORD(Info->dwFileVersionMS),
  765. LOWORD(Info->dwFileVersionMS),
  766. HIWORD(Info->dwFileVersionLS))));
  767. return Result;
  768. }
  769. catch (Exception &E)
  770. {
  771. throw ExtException(&E, L"Can't get application version");
  772. }
  773. }
  774. //---------------------------------------------------------------------------
  775. UnicodeString __fastcall TConfiguration::GetFileFileInfoString(const UnicodeString Key,
  776. const UnicodeString FileName)
  777. {
  778. TGuard Guard(FCriticalSection);
  779. UnicodeString Result;
  780. void * Info = GetFileApplicationInfo(FileName);
  781. try
  782. {
  783. if ((Info != NULL) && (GetTranslationCount(Info) > 0))
  784. {
  785. TTranslation Translation;
  786. Translation = GetTranslation(Info, 0);
  787. Result = ::GetFileInfoString(Info, Translation, Key);
  788. }
  789. else
  790. {
  791. assert(!FileName.IsEmpty());
  792. }
  793. }
  794. __finally
  795. {
  796. if (!FileName.IsEmpty())
  797. {
  798. FreeFileInfo(Info);
  799. }
  800. }
  801. return Result;
  802. }
  803. //---------------------------------------------------------------------------
  804. UnicodeString __fastcall TConfiguration::GetFileInfoString(const UnicodeString Key)
  805. {
  806. return GetFileFileInfoString(Key, L"");
  807. }
  808. //---------------------------------------------------------------------------
  809. UnicodeString __fastcall TConfiguration::GetRegistryStorageKey()
  810. {
  811. return GetRegistryKey();
  812. }
  813. //---------------------------------------------------------------------------
  814. void __fastcall TConfiguration::SetNulStorage()
  815. {
  816. FStorage = stNul;
  817. }
  818. //---------------------------------------------------------------------------
  819. void __fastcall TConfiguration::SetDefaultStorage()
  820. {
  821. FStorage = stDetect;
  822. }
  823. //---------------------------------------------------------------------------
  824. void __fastcall TConfiguration::SetIniFileStorageName(UnicodeString value)
  825. {
  826. FIniFileStorageName = value;
  827. FStorage = stIniFile;
  828. }
  829. //---------------------------------------------------------------------------
  830. UnicodeString __fastcall TConfiguration::GetIniFileStorageNameForReading()
  831. {
  832. return GetIniFileStorageName(true);
  833. }
  834. //---------------------------------------------------------------------------
  835. UnicodeString __fastcall TConfiguration::GetIniFileStorageNameForReadingWritting()
  836. {
  837. return GetIniFileStorageName(false);
  838. }
  839. //---------------------------------------------------------------------------
  840. UnicodeString __fastcall TConfiguration::GetIniFileStorageName(bool ReadingOnly)
  841. {
  842. if (FIniFileStorageName.IsEmpty())
  843. {
  844. UnicodeString ProgramPath = ParamStr(0);
  845. UnicodeString ProgramIniPath = ChangeFileExt(ProgramPath, L".ini");
  846. UnicodeString IniPath;
  847. if (FileExists(ProgramIniPath))
  848. {
  849. IniPath = ProgramIniPath;
  850. }
  851. else
  852. {
  853. UnicodeString AppDataIniPath =
  854. IncludeTrailingBackslash(GetShellFolderPath(CSIDL_APPDATA)) +
  855. ExtractFileName(ProgramIniPath);
  856. if (FileExists(AppDataIniPath))
  857. {
  858. IniPath = AppDataIniPath;
  859. }
  860. else
  861. {
  862. // avoid expensive test if we are interested in existing files only
  863. if (!ReadingOnly && (FProgramIniPathWrittable < 0))
  864. {
  865. UnicodeString ProgramDir = ExtractFilePath(ProgramPath);
  866. FProgramIniPathWrittable = IsDirectoryWriteable(ProgramDir) ? 1 : 0;
  867. }
  868. // does not really matter what we return when < 0
  869. IniPath = (FProgramIniPathWrittable == 0) ? AppDataIniPath : ProgramIniPath;
  870. }
  871. }
  872. // BACKWARD COMPATIBILITY with 4.x
  873. if (FVirtualIniFileStorageName.IsEmpty() &&
  874. TPath::IsDriveRooted(IniPath))
  875. {
  876. UnicodeString LocalAppDataPath = GetShellFolderPath(CSIDL_LOCAL_APPDATA);
  877. // virtual store for non-system drives have a different virtual store,
  878. // do not bother about them
  879. if (TPath::IsDriveRooted(LocalAppDataPath) &&
  880. SameText(ExtractFileDrive(IniPath), ExtractFileDrive(LocalAppDataPath)))
  881. {
  882. FVirtualIniFileStorageName =
  883. IncludeTrailingBackslash(LocalAppDataPath) +
  884. L"VirtualStore\\" +
  885. IniPath.SubString(4, IniPath.Length() - 3);
  886. }
  887. }
  888. if (!FVirtualIniFileStorageName.IsEmpty() &&
  889. FileExists(FVirtualIniFileStorageName))
  890. {
  891. return FVirtualIniFileStorageName;
  892. }
  893. else
  894. {
  895. return IniPath;
  896. }
  897. }
  898. else
  899. {
  900. return FIniFileStorageName;
  901. }
  902. }
  903. //---------------------------------------------------------------------------
  904. UnicodeString __fastcall TConfiguration::GetPuttySessionsKey()
  905. {
  906. return PuttyRegistryStorageKey + L"\\Sessions";
  907. }
  908. //---------------------------------------------------------------------------
  909. UnicodeString __fastcall TConfiguration::GetStoredSessionsSubKey()
  910. {
  911. return L"Sessions";
  912. }
  913. //---------------------------------------------------------------------------
  914. UnicodeString __fastcall TConfiguration::GetSshHostKeysSubKey()
  915. {
  916. return L"SshHostKeys";
  917. }
  918. //---------------------------------------------------------------------------
  919. UnicodeString __fastcall TConfiguration::GetConfigurationSubKey()
  920. {
  921. return L"Configuration";
  922. }
  923. //---------------------------------------------------------------------------
  924. UnicodeString __fastcall TConfiguration::GetRootKeyStr()
  925. {
  926. return RootKeyToStr(HKEY_CURRENT_USER);
  927. }
  928. //---------------------------------------------------------------------------
  929. void __fastcall TConfiguration::SetStorage(TStorage value)
  930. {
  931. if (FStorage != value)
  932. {
  933. TStorage StorageBak = FStorage;
  934. try
  935. {
  936. THierarchicalStorage * SourceStorage = NULL;
  937. THierarchicalStorage * TargetStorage = NULL;
  938. try
  939. {
  940. SourceStorage = CreateScpStorage(false);
  941. SourceStorage->AccessMode = smRead;
  942. FStorage = value;
  943. TargetStorage = CreateScpStorage(false);
  944. TargetStorage->AccessMode = smReadWrite;
  945. TargetStorage->Explicit = true;
  946. // copy before save as it removes the ini file,
  947. // when switching from ini to registry
  948. CopyData(SourceStorage, TargetStorage);
  949. }
  950. __finally
  951. {
  952. delete SourceStorage;
  953. delete TargetStorage;
  954. }
  955. // save all and explicit,
  956. // this also removes an INI file, when switching to registry storage
  957. DoSave(true, true);
  958. }
  959. catch (...)
  960. {
  961. // If this fails, do not pretend that storage was switched.
  962. // For instance:
  963. // - When writting to an INI file fails (unlikely, as we fallback to user profile)
  964. // - When removing INI file fails, when switching to registry
  965. // (possible, when the INI file is in Program Files folder)
  966. FStorage = StorageBak;
  967. throw;
  968. }
  969. }
  970. }
  971. //---------------------------------------------------------------------------
  972. void __fastcall TConfiguration::Saved()
  973. {
  974. // nothing
  975. }
  976. //---------------------------------------------------------------------------
  977. TStorage __fastcall TConfiguration::GetStorage()
  978. {
  979. if (FStorage == stDetect)
  980. {
  981. if (FileExists(IniFileStorageNameForReading))
  982. {
  983. FStorage = stIniFile;
  984. }
  985. else
  986. {
  987. FStorage = stRegistry;
  988. }
  989. }
  990. return FStorage;
  991. }
  992. //---------------------------------------------------------------------------
  993. void __fastcall TConfiguration::SetRandomSeedFile(UnicodeString value)
  994. {
  995. if (RandomSeedFile != value)
  996. {
  997. UnicodeString PrevRandomSeedFileName = RandomSeedFileName;
  998. FRandomSeedFile = value;
  999. // never allow empty seed file to avoid Putty trying to reinitialize the path
  1000. if (RandomSeedFileName.IsEmpty())
  1001. {
  1002. FRandomSeedFile = FDefaultRandomSeedFile;
  1003. }
  1004. if (!PrevRandomSeedFileName.IsEmpty() &&
  1005. (PrevRandomSeedFileName != RandomSeedFileName) &&
  1006. FileExists(PrevRandomSeedFileName))
  1007. {
  1008. // ignore any error
  1009. DeleteFile(PrevRandomSeedFileName);
  1010. }
  1011. }
  1012. }
  1013. //---------------------------------------------------------------------
  1014. UnicodeString __fastcall TConfiguration::GetRandomSeedFileName()
  1015. {
  1016. return StripPathQuotes(ExpandEnvironmentVariables(FRandomSeedFile)).Trim();
  1017. }
  1018. //---------------------------------------------------------------------
  1019. void __fastcall TConfiguration::SetExternalIpAddress(UnicodeString value)
  1020. {
  1021. SET_CONFIG_PROPERTY(ExternalIpAddress);
  1022. }
  1023. //---------------------------------------------------------------------
  1024. void __fastcall TConfiguration::SetTryFtpWhenSshFails(bool value)
  1025. {
  1026. SET_CONFIG_PROPERTY(TryFtpWhenSshFails);
  1027. }
  1028. //---------------------------------------------------------------------
  1029. void __fastcall TConfiguration::SetPuttyRegistryStorageKey(UnicodeString value)
  1030. {
  1031. SET_CONFIG_PROPERTY(PuttyRegistryStorageKey);
  1032. }
  1033. //---------------------------------------------------------------------------
  1034. TEOLType __fastcall TConfiguration::GetLocalEOLType()
  1035. {
  1036. return eolCRLF;
  1037. }
  1038. //---------------------------------------------------------------------
  1039. bool __fastcall TConfiguration::GetCollectUsage()
  1040. {
  1041. return FUsage->Collect;
  1042. }
  1043. //---------------------------------------------------------------------
  1044. void __fastcall TConfiguration::SetCollectUsage(bool value)
  1045. {
  1046. FUsage->Collect = value;
  1047. }
  1048. //---------------------------------------------------------------------
  1049. void __fastcall TConfiguration::TemporaryLogging(const UnicodeString ALogFileName)
  1050. {
  1051. if (SameText(ExtractFileExt(ALogFileName), L".xml"))
  1052. {
  1053. TemporaryActionsLogging(ALogFileName);
  1054. }
  1055. else
  1056. {
  1057. FLogging = true;
  1058. FLogFileName = ALogFileName;
  1059. UpdateActualLogProtocol();
  1060. }
  1061. }
  1062. //---------------------------------------------------------------------
  1063. void __fastcall TConfiguration::TemporaryActionsLogging(const UnicodeString ALogFileName)
  1064. {
  1065. FLogActions = true;
  1066. FActionsLogFileName = ALogFileName;
  1067. }
  1068. //---------------------------------------------------------------------
  1069. void __fastcall TConfiguration::SetLogging(bool value)
  1070. {
  1071. if (Logging != value)
  1072. {
  1073. FPermanentLogging = value;
  1074. FLogging = value;
  1075. UpdateActualLogProtocol();
  1076. Changed();
  1077. }
  1078. }
  1079. //---------------------------------------------------------------------
  1080. void __fastcall TConfiguration::SetLogFileName(UnicodeString value)
  1081. {
  1082. if (LogFileName != value)
  1083. {
  1084. FPermanentLogFileName = value;
  1085. FLogFileName = value;
  1086. Changed();
  1087. }
  1088. }
  1089. //---------------------------------------------------------------------
  1090. void __fastcall TConfiguration::SetActionsLogFileName(UnicodeString value)
  1091. {
  1092. if (ActionsLogFileName != value)
  1093. {
  1094. FPermanentActionsLogFileName = value;
  1095. FActionsLogFileName = value;
  1096. Changed();
  1097. }
  1098. }
  1099. //---------------------------------------------------------------------
  1100. bool __fastcall TConfiguration::GetLogToFile()
  1101. {
  1102. return !LogFileName.IsEmpty();
  1103. }
  1104. //---------------------------------------------------------------------
  1105. void __fastcall TConfiguration::UpdateActualLogProtocol()
  1106. {
  1107. FActualLogProtocol = FLogging ? FLogProtocol : 0;
  1108. }
  1109. //---------------------------------------------------------------------
  1110. void __fastcall TConfiguration::SetLogProtocol(int value)
  1111. {
  1112. SET_CONFIG_PROPERTY(LogProtocol);
  1113. UpdateActualLogProtocol();
  1114. }
  1115. //---------------------------------------------------------------------
  1116. void __fastcall TConfiguration::SetLogActions(bool value)
  1117. {
  1118. if (LogActions != value)
  1119. {
  1120. FPermanentLogActions = value;
  1121. FLogActions = value;
  1122. Changed();
  1123. }
  1124. }
  1125. //---------------------------------------------------------------------
  1126. void __fastcall TConfiguration::SetLogFileAppend(bool value)
  1127. {
  1128. SET_CONFIG_PROPERTY(LogFileAppend);
  1129. }
  1130. //---------------------------------------------------------------------
  1131. void __fastcall TConfiguration::SetLogWindowLines(int value)
  1132. {
  1133. SET_CONFIG_PROPERTY(LogWindowLines);
  1134. }
  1135. //---------------------------------------------------------------------
  1136. void __fastcall TConfiguration::SetLogWindowComplete(bool value)
  1137. {
  1138. if (value != LogWindowComplete)
  1139. {
  1140. LogWindowLines = value ? 0 : 50;
  1141. Changed();
  1142. }
  1143. }
  1144. //---------------------------------------------------------------------
  1145. bool __fastcall TConfiguration::GetLogWindowComplete()
  1146. {
  1147. return (bool)(LogWindowLines == 0);
  1148. }
  1149. //---------------------------------------------------------------------
  1150. UnicodeString __fastcall TConfiguration::GetDefaultLogFileName()
  1151. {
  1152. return L"%TEMP%\\!S.log";
  1153. }
  1154. //---------------------------------------------------------------------------
  1155. void __fastcall TConfiguration::SetConfirmOverwriting(bool value)
  1156. {
  1157. TGuard Guard(FCriticalSection);
  1158. SET_CONFIG_PROPERTY(ConfirmOverwriting);
  1159. }
  1160. //---------------------------------------------------------------------------
  1161. bool __fastcall TConfiguration::GetConfirmOverwriting()
  1162. {
  1163. TGuard Guard(FCriticalSection);
  1164. return FConfirmOverwriting;
  1165. }
  1166. //---------------------------------------------------------------------------
  1167. void __fastcall TConfiguration::SetConfirmResume(bool value)
  1168. {
  1169. TGuard Guard(FCriticalSection);
  1170. SET_CONFIG_PROPERTY(ConfirmResume);
  1171. }
  1172. //---------------------------------------------------------------------------
  1173. bool __fastcall TConfiguration::GetConfirmResume()
  1174. {
  1175. TGuard Guard(FCriticalSection);
  1176. return FConfirmResume;
  1177. }
  1178. //---------------------------------------------------------------------------
  1179. void __fastcall TConfiguration::SetAutoReadDirectoryAfterOp(bool value)
  1180. {
  1181. TGuard Guard(FCriticalSection);
  1182. SET_CONFIG_PROPERTY(AutoReadDirectoryAfterOp);
  1183. }
  1184. //---------------------------------------------------------------------------
  1185. bool __fastcall TConfiguration::GetAutoReadDirectoryAfterOp()
  1186. {
  1187. TGuard Guard(FCriticalSection);
  1188. return FAutoReadDirectoryAfterOp;
  1189. }
  1190. //---------------------------------------------------------------------------
  1191. UnicodeString __fastcall TConfiguration::GetTimeFormat()
  1192. {
  1193. return L"h:nn:ss";
  1194. }
  1195. //---------------------------------------------------------------------------
  1196. UnicodeString __fastcall TConfiguration::GetPartialExt() const
  1197. {
  1198. return PARTIAL_EXT;
  1199. }
  1200. //---------------------------------------------------------------------------
  1201. UnicodeString __fastcall TConfiguration::GetDefaultKeyFile()
  1202. {
  1203. return L"";
  1204. }
  1205. //---------------------------------------------------------------------------
  1206. bool __fastcall TConfiguration::GetRememberPassword()
  1207. {
  1208. return false;
  1209. }
  1210. //---------------------------------------------------------------------------
  1211. void __fastcall TConfiguration::SetSessionReopenAuto(int value)
  1212. {
  1213. SET_CONFIG_PROPERTY(SessionReopenAuto);
  1214. }
  1215. //---------------------------------------------------------------------------
  1216. void __fastcall TConfiguration::SetSessionReopenBackground(int value)
  1217. {
  1218. SET_CONFIG_PROPERTY(SessionReopenBackground);
  1219. }
  1220. //---------------------------------------------------------------------------
  1221. void __fastcall TConfiguration::SetSessionReopenTimeout(int value)
  1222. {
  1223. SET_CONFIG_PROPERTY(SessionReopenTimeout);
  1224. }
  1225. //---------------------------------------------------------------------------
  1226. void __fastcall TConfiguration::SetSessionReopenAutoStall(int value)
  1227. {
  1228. SET_CONFIG_PROPERTY(SessionReopenAutoStall);
  1229. }
  1230. //---------------------------------------------------------------------------
  1231. void __fastcall TConfiguration::SetTunnelLocalPortNumberLow(int value)
  1232. {
  1233. SET_CONFIG_PROPERTY(TunnelLocalPortNumberLow);
  1234. }
  1235. //---------------------------------------------------------------------------
  1236. void __fastcall TConfiguration::SetTunnelLocalPortNumberHigh(int value)
  1237. {
  1238. SET_CONFIG_PROPERTY(TunnelLocalPortNumberHigh);
  1239. }
  1240. //---------------------------------------------------------------------------
  1241. void __fastcall TConfiguration::SetCacheDirectoryChangesMaxSize(int value)
  1242. {
  1243. SET_CONFIG_PROPERTY(CacheDirectoryChangesMaxSize);
  1244. }
  1245. //---------------------------------------------------------------------------
  1246. void __fastcall TConfiguration::SetShowFtpWelcomeMessage(bool value)
  1247. {
  1248. SET_CONFIG_PROPERTY(ShowFtpWelcomeMessage);
  1249. }
  1250. //---------------------------------------------------------------------------
  1251. //---------------------------------------------------------------------------
  1252. void __fastcall TShortCuts::Add(TShortCut ShortCut)
  1253. {
  1254. FShortCuts.insert(ShortCut);
  1255. }
  1256. //---------------------------------------------------------------------------
  1257. bool __fastcall TShortCuts::Has(TShortCut ShortCut) const
  1258. {
  1259. return (FShortCuts.count(ShortCut) != 0);
  1260. }