Configuration.cpp 39 KB

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