Configuration.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <FileInfo.h>
  5. #include "Exceptions.h"
  6. #include "Common.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 <shfolder.h>
  14. //---------------------------------------------------------------------------
  15. #pragma package(smart_init)
  16. //---------------------------------------------------------------------------
  17. __fastcall TConfiguration::TConfiguration()
  18. {
  19. FCriticalSection = new TCriticalSection();
  20. FUpdating = 0;
  21. FStorage = stDetect;
  22. FDontSave = false;
  23. FApplicationInfo = NULL;
  24. char Buf[10];
  25. AnsiString RandomSeedPath;
  26. if (GetEnvironmentVariable("APPDATA", Buf, sizeof(Buf)) > 0)
  27. {
  28. RandomSeedPath = "%APPDATA%";
  29. }
  30. else
  31. {
  32. RandomSeedPath = GetShellFolderPath(CSIDL_LOCAL_APPDATA);
  33. if (RandomSeedPath.IsEmpty())
  34. {
  35. RandomSeedPath = GetShellFolderPath(CSIDL_APPDATA);
  36. }
  37. }
  38. FDefaultRandomSeedFile = IncludeTrailingBackslash(RandomSeedPath) + "winscp.rnd";
  39. }
  40. //---------------------------------------------------------------------------
  41. void __fastcall TConfiguration::Default()
  42. {
  43. TGuard Guard(FCriticalSection);
  44. FDisablePasswordStoring = false;
  45. FForceBanners = false;
  46. FDisableAcceptingHostKeys = false;
  47. TRegistryStorage * AdminStorage;
  48. AdminStorage = new TRegistryStorage(RegistryStorageKey, HKEY_LOCAL_MACHINE);
  49. try
  50. {
  51. if (AdminStorage->OpenRootKey(false))
  52. {
  53. LoadAdmin(AdminStorage);
  54. AdminStorage->CloseSubKey();
  55. }
  56. }
  57. __finally
  58. {
  59. delete AdminStorage;
  60. }
  61. RandomSeedFile = FDefaultRandomSeedFile;
  62. PuttyRegistryStorageKey = "Software\\SimonTatham\\PuTTY";
  63. FConfirmOverwriting = true;
  64. FConfirmResume = true;
  65. FAutoReadDirectoryAfterOp = true;
  66. FSessionReopenAuto = 5000;
  67. FSessionReopenBackground = 2000;
  68. FSessionReopenTimeout = 0;
  69. FTunnelLocalPortNumberLow = 50000;
  70. FTunnelLocalPortNumberHigh = 50099;
  71. FCacheDirectoryChangesMaxSize = 100;
  72. FShowFtpWelcomeMessage = false;
  73. FLogging = false;
  74. FPermanentLogging = false;
  75. FLogFileName = "";
  76. FPermanentLogFileName = "";
  77. FLogFileAppend = true;
  78. FLogWindowLines = 100;
  79. FLogProtocol = 0;
  80. FLogActions = false;
  81. FPermanentLogActions = false;
  82. Changed();
  83. }
  84. //---------------------------------------------------------------------------
  85. __fastcall TConfiguration::~TConfiguration()
  86. {
  87. assert(!FUpdating);
  88. if (FApplicationInfo) FreeFileInfo(FApplicationInfo);
  89. delete FCriticalSection;
  90. }
  91. //---------------------------------------------------------------------------
  92. THierarchicalStorage * TConfiguration::CreateScpStorage(bool /*SessionList*/)
  93. {
  94. if (Storage == stRegistry)
  95. {
  96. return new TRegistryStorage(RegistryStorageKey);
  97. }
  98. else
  99. {
  100. return new TIniFileStorage(IniFileStorageName);
  101. }
  102. }
  103. //---------------------------------------------------------------------------
  104. #define LASTELEM(ELEM) \
  105. ELEM.SubString(ELEM.LastDelimiter(".>")+1, ELEM.Length() - ELEM.LastDelimiter(".>"))
  106. #define BLOCK(KEY, CANCREATE, BLOCK) \
  107. if (Storage->OpenSubKey(KEY, CANCREATE, true)) try { BLOCK } __finally { Storage->CloseSubKey(); }
  108. #define KEY(TYPE, VAR) KEYEX(TYPE, VAR, VAR)
  109. #define REGCONFIG(CANCREATE) \
  110. BLOCK("Interface", CANCREATE, \
  111. KEY(String, RandomSeedFile); \
  112. KEY(String, PuttyRegistryStorageKey); \
  113. KEY(Bool, ConfirmOverwriting); \
  114. KEY(Bool, ConfirmResume); \
  115. KEY(Bool, AutoReadDirectoryAfterOp); \
  116. KEY(Integer, SessionReopenAuto); \
  117. KEY(Integer, SessionReopenBackground); \
  118. KEY(Integer, SessionReopenTimeout); \
  119. KEY(Integer, TunnelLocalPortNumberLow); \
  120. KEY(Integer, TunnelLocalPortNumberHigh); \
  121. KEY(Integer, CacheDirectoryChangesMaxSize); \
  122. KEY(Bool, ShowFtpWelcomeMessage); \
  123. ); \
  124. BLOCK("Logging", CANCREATE, \
  125. KEYEX(Bool, PermanentLogging, Logging); \
  126. KEYEX(String,PermanentLogFileName, LogFileName); \
  127. KEY(Bool, LogFileAppend); \
  128. KEY(Integer, LogWindowLines); \
  129. KEY(Integer, LogProtocol); \
  130. KEYEX(Bool, PermanentLogActions, LogActions); \
  131. );
  132. //---------------------------------------------------------------------------
  133. void __fastcall TConfiguration::SaveData(THierarchicalStorage * Storage, bool /*All*/)
  134. {
  135. #define KEYEX(TYPE, VAR, NAME) Storage->Write ## TYPE(LASTELEM(AnsiString(#NAME)), VAR)
  136. REGCONFIG(true);
  137. #undef KEYEX
  138. }
  139. //---------------------------------------------------------------------------
  140. void __fastcall TConfiguration::Save(bool All, bool Explicit)
  141. {
  142. if (FDontSave) return;
  143. THierarchicalStorage * AStorage = CreateScpStorage(false);
  144. try
  145. {
  146. AStorage->AccessMode = smReadWrite;
  147. AStorage->Explicit = Explicit;
  148. if (AStorage->OpenSubKey(ConfigurationSubKey, true))
  149. {
  150. SaveData(AStorage, All);
  151. }
  152. }
  153. __finally
  154. {
  155. delete AStorage;
  156. }
  157. Saved();
  158. if (All)
  159. {
  160. StoredSessions->Save(true, Explicit);
  161. }
  162. // clean up as last, so that if it fails (read only INI), the saving can proceed
  163. if (Storage == stRegistry)
  164. {
  165. CleanupIniFile();
  166. }
  167. }
  168. //---------------------------------------------------------------------------
  169. void __fastcall TConfiguration::Export(const AnsiString FileName)
  170. {
  171. THierarchicalStorage * Storage = NULL;
  172. THierarchicalStorage * ExportStorage = NULL;
  173. try
  174. {
  175. ExportStorage = new TIniFileStorage(FileName);
  176. ExportStorage->AccessMode = smReadWrite;
  177. ExportStorage->Explicit = true;
  178. Storage = CreateScpStorage(false);
  179. Storage->AccessMode = smRead;
  180. CopyData(Storage, ExportStorage);
  181. if (ExportStorage->OpenSubKey(ConfigurationSubKey, true))
  182. {
  183. SaveData(ExportStorage, true);
  184. }
  185. }
  186. __finally
  187. {
  188. delete ExportStorage;
  189. delete Storage;
  190. }
  191. StoredSessions->Export(FileName);
  192. }
  193. //---------------------------------------------------------------------------
  194. void __fastcall TConfiguration::LoadData(THierarchicalStorage * Storage)
  195. {
  196. #define KEYEX(TYPE, VAR, NAME) VAR = Storage->Read ## TYPE(LASTELEM(AnsiString(#NAME)), VAR)
  197. #pragma warn -eas
  198. REGCONFIG(false);
  199. #pragma warn +eas
  200. #undef KEYEX
  201. }
  202. //---------------------------------------------------------------------------
  203. void __fastcall TConfiguration::LoadAdmin(THierarchicalStorage * Storage)
  204. {
  205. FDisablePasswordStoring = Storage->ReadBool("DisablePasswordStoring", FDisablePasswordStoring);
  206. FForceBanners = Storage->ReadBool("ForceBanners", FForceBanners);
  207. FDisableAcceptingHostKeys = Storage->ReadBool("DisableAcceptingHostKeys", FDisableAcceptingHostKeys);
  208. }
  209. //---------------------------------------------------------------------------
  210. void __fastcall TConfiguration::Load()
  211. {
  212. TGuard Guard(FCriticalSection);
  213. THierarchicalStorage * Storage = CreateScpStorage(false);
  214. try
  215. {
  216. Storage->AccessMode = smRead;
  217. if (Storage->OpenSubKey(ConfigurationSubKey, false))
  218. {
  219. LoadData(Storage);
  220. }
  221. }
  222. __finally
  223. {
  224. delete Storage;
  225. }
  226. }
  227. //---------------------------------------------------------------------------
  228. void __fastcall TConfiguration::CopyData(THierarchicalStorage * Source,
  229. THierarchicalStorage * Target)
  230. {
  231. TStrings * Names = new TStringList();
  232. try
  233. {
  234. if (Source->OpenSubKey(ConfigurationSubKey, false))
  235. {
  236. if (Target->OpenSubKey(ConfigurationSubKey, true))
  237. {
  238. if (Source->OpenSubKey("CDCache", false))
  239. {
  240. if (Target->OpenSubKey("CDCache", true))
  241. {
  242. Names->Clear();
  243. Source->GetValueNames(Names);
  244. for (int Index = 0; Index < Names->Count; Index++)
  245. {
  246. Target->WriteBinaryData(Names->Strings[Index],
  247. Source->ReadBinaryData(Names->Strings[Index]));
  248. }
  249. Target->CloseSubKey();
  250. }
  251. Source->CloseSubKey();
  252. }
  253. if (Source->OpenSubKey("Banners", false))
  254. {
  255. if (Target->OpenSubKey("Banners", true))
  256. {
  257. Names->Clear();
  258. Source->GetValueNames(Names);
  259. for (int Index = 0; Index < Names->Count; Index++)
  260. {
  261. Target->WriteString(Names->Strings[Index],
  262. Source->ReadString(Names->Strings[Index], ""));
  263. }
  264. Target->CloseSubKey();
  265. }
  266. Source->CloseSubKey();
  267. }
  268. Target->CloseSubKey();
  269. }
  270. Source->CloseSubKey();
  271. }
  272. if (Source->OpenSubKey(SshHostKeysSubKey, false))
  273. {
  274. if (Target->OpenSubKey(SshHostKeysSubKey, true))
  275. {
  276. Names->Clear();
  277. Source->GetValueNames(Names);
  278. for (int Index = 0; Index < Names->Count; Index++)
  279. {
  280. Target->WriteStringRaw(Names->Strings[Index],
  281. Source->ReadStringRaw(Names->Strings[Index], ""));
  282. }
  283. Target->CloseSubKey();
  284. }
  285. Source->CloseSubKey();
  286. }
  287. }
  288. __finally
  289. {
  290. delete Names;
  291. }
  292. }
  293. //---------------------------------------------------------------------------
  294. void __fastcall TConfiguration::LoadDirectoryChangesCache(const AnsiString SessionKey,
  295. TRemoteDirectoryChangesCache * DirectoryChangesCache)
  296. {
  297. THierarchicalStorage * Storage = CreateScpStorage(false);
  298. try
  299. {
  300. Storage->AccessMode = smRead;
  301. if (Storage->OpenSubKey(ConfigurationSubKey, false) &&
  302. Storage->OpenSubKey("CDCache", false) &&
  303. Storage->ValueExists(SessionKey))
  304. {
  305. DirectoryChangesCache->Deserialize(Storage->ReadBinaryData(SessionKey));
  306. }
  307. }
  308. __finally
  309. {
  310. delete Storage;
  311. }
  312. }
  313. //---------------------------------------------------------------------------
  314. void __fastcall TConfiguration::SaveDirectoryChangesCache(const AnsiString SessionKey,
  315. TRemoteDirectoryChangesCache * DirectoryChangesCache)
  316. {
  317. THierarchicalStorage * Storage = CreateScpStorage(false);
  318. try
  319. {
  320. Storage->AccessMode = smReadWrite;
  321. if (Storage->OpenSubKey(ConfigurationSubKey, true) &&
  322. Storage->OpenSubKey("CDCache", true))
  323. {
  324. AnsiString Data;
  325. DirectoryChangesCache->Serialize(Data);
  326. Storage->WriteBinaryData(SessionKey, Data);
  327. }
  328. }
  329. __finally
  330. {
  331. delete Storage;
  332. }
  333. }
  334. //---------------------------------------------------------------------------
  335. AnsiString __fastcall TConfiguration::BannerHash(const AnsiString & Banner)
  336. {
  337. AnsiString Result;
  338. Result.SetLength(16);
  339. md5checksum(Banner.c_str(), Banner.Length(), (unsigned char*)Result.c_str());
  340. return Result;
  341. }
  342. //---------------------------------------------------------------------------
  343. bool __fastcall TConfiguration::ShowBanner(const AnsiString SessionKey,
  344. const AnsiString & Banner)
  345. {
  346. bool Result;
  347. THierarchicalStorage * Storage = CreateScpStorage(false);
  348. try
  349. {
  350. Storage->AccessMode = smRead;
  351. Result =
  352. !Storage->OpenSubKey(ConfigurationSubKey, false) ||
  353. !Storage->OpenSubKey("Banners", false) ||
  354. !Storage->ValueExists(SessionKey) ||
  355. (Storage->ReadString(SessionKey, "") != StrToHex(BannerHash(Banner)));
  356. }
  357. __finally
  358. {
  359. delete Storage;
  360. }
  361. return Result;
  362. }
  363. //---------------------------------------------------------------------------
  364. void __fastcall TConfiguration::NeverShowBanner(const AnsiString SessionKey,
  365. const AnsiString & Banner)
  366. {
  367. THierarchicalStorage * Storage = CreateScpStorage(false);
  368. try
  369. {
  370. Storage->AccessMode = smReadWrite;
  371. if (Storage->OpenSubKey(ConfigurationSubKey, true) &&
  372. Storage->OpenSubKey("Banners", true))
  373. {
  374. Storage->WriteString(SessionKey, StrToHex(BannerHash(Banner)));
  375. }
  376. }
  377. __finally
  378. {
  379. delete Storage;
  380. }
  381. }
  382. //---------------------------------------------------------------------------
  383. void __fastcall TConfiguration::Changed()
  384. {
  385. if (FUpdating == 0)
  386. {
  387. if (OnChange)
  388. {
  389. OnChange(this);
  390. }
  391. }
  392. else
  393. {
  394. FChanged = true;
  395. }
  396. }
  397. //---------------------------------------------------------------------------
  398. void __fastcall TConfiguration::BeginUpdate()
  399. {
  400. if (FUpdating == 0)
  401. {
  402. FChanged = false;
  403. }
  404. FUpdating++;
  405. // Greater value would probably indicate some nesting problem in code
  406. assert(FUpdating < 6);
  407. }
  408. //---------------------------------------------------------------------------
  409. void __fastcall TConfiguration::EndUpdate()
  410. {
  411. assert(FUpdating > 0);
  412. FUpdating--;
  413. if ((FUpdating == 0) && FChanged)
  414. {
  415. FChanged = false;
  416. Changed();
  417. }
  418. }
  419. //---------------------------------------------------------------------------
  420. void __fastcall TConfiguration::CleanupConfiguration()
  421. {
  422. try
  423. {
  424. CleanupRegistry(ConfigurationSubKey);
  425. if (Storage == stRegistry)
  426. {
  427. FDontSave = true;
  428. }
  429. }
  430. catch (Exception &E)
  431. {
  432. throw ExtException(&E, CLEANUP_CONFIG_ERROR);
  433. }
  434. }
  435. //---------------------------------------------------------------------------
  436. void __fastcall TConfiguration::CleanupRegistry(AnsiString CleanupSubKey)
  437. {
  438. TRegistryStorage *Registry = new TRegistryStorage(RegistryStorageKey);
  439. try
  440. {
  441. Registry->RecursiveDeleteSubKey(CleanupSubKey);
  442. }
  443. __finally
  444. {
  445. delete Registry;
  446. }
  447. }
  448. //---------------------------------------------------------------------------
  449. void __fastcall TConfiguration::CleanupHostKeys()
  450. {
  451. try
  452. {
  453. CleanupRegistry(SshHostKeysSubKey);
  454. }
  455. catch (Exception &E)
  456. {
  457. throw ExtException(&E, CLEANUP_HOSTKEYS_ERROR);
  458. }
  459. }
  460. //---------------------------------------------------------------------------
  461. void __fastcall TConfiguration::CleanupRandomSeedFile()
  462. {
  463. try
  464. {
  465. DontSaveRandomSeed();
  466. if (FileExists(RandomSeedFileName))
  467. {
  468. if (!DeleteFile(RandomSeedFileName))
  469. {
  470. RaiseLastOSError();
  471. }
  472. }
  473. }
  474. catch (Exception &E)
  475. {
  476. throw ExtException(&E, CLEANUP_SEEDFILE_ERROR);
  477. }
  478. }
  479. //---------------------------------------------------------------------------
  480. void __fastcall TConfiguration::CleanupIniFile()
  481. {
  482. try
  483. {
  484. if (FileExists(IniFileStorageName))
  485. {
  486. if (!DeleteFile(IniFileStorageName))
  487. {
  488. RaiseLastOSError();
  489. }
  490. }
  491. if (Storage == stIniFile)
  492. {
  493. FDontSave = true;
  494. }
  495. }
  496. catch (Exception &E)
  497. {
  498. throw ExtException(&E, CLEANUP_INIFILE_ERROR);
  499. }
  500. }
  501. //---------------------------------------------------------------------------
  502. AnsiString __fastcall TConfiguration::EncryptPassword(AnsiString Password, AnsiString Key)
  503. {
  504. if (Password.IsEmpty())
  505. {
  506. return AnsiString();
  507. }
  508. else
  509. {
  510. return ::EncryptPassword(Password, Key);
  511. }
  512. }
  513. //---------------------------------------------------------------------------
  514. AnsiString __fastcall TConfiguration::DecryptPassword(AnsiString Password, AnsiString Key)
  515. {
  516. if (Password.IsEmpty())
  517. {
  518. return AnsiString();
  519. }
  520. else
  521. {
  522. return ::DecryptPassword(Password, Key);
  523. }
  524. }
  525. //---------------------------------------------------------------------------
  526. AnsiString __fastcall TConfiguration::StronglyRecryptPassword(AnsiString Password, AnsiString /*Key*/)
  527. {
  528. return Password;
  529. }
  530. //---------------------------------------------------------------------------
  531. AnsiString __fastcall TConfiguration::GetOSVersionStr()
  532. {
  533. AnsiString Result;
  534. OSVERSIONINFO OSVersionInfo;
  535. OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVersionInfo);
  536. if (GetVersionEx(&OSVersionInfo) != 0)
  537. {
  538. Result = FORMAT("%d.%d.%d %s", (int(OSVersionInfo.dwMajorVersion),
  539. int(OSVersionInfo.dwMinorVersion), int(OSVersionInfo.dwBuildNumber),
  540. OSVersionInfo.szCSDVersion)).Trim();
  541. }
  542. return Result;
  543. }
  544. //---------------------------------------------------------------------------
  545. TVSFixedFileInfo *__fastcall TConfiguration::GetFixedApplicationInfo()
  546. {
  547. return GetFixedFileInfo(ApplicationInfo);
  548. }
  549. //---------------------------------------------------------------------------
  550. int __fastcall TConfiguration::GetCompoundVersion()
  551. {
  552. TVSFixedFileInfo * FileInfo = FixedApplicationInfo;
  553. return CalculateCompoundVersion(
  554. HIWORD(FileInfo->dwFileVersionMS), LOWORD(FileInfo->dwFileVersionMS),
  555. HIWORD(FileInfo->dwFileVersionLS), LOWORD(FileInfo->dwFileVersionLS));
  556. }
  557. //---------------------------------------------------------------------------
  558. AnsiString __fastcall TConfiguration::ModuleFileName()
  559. {
  560. return ParamStr(0);
  561. }
  562. //---------------------------------------------------------------------------
  563. void * __fastcall TConfiguration::GetFileApplicationInfo(const AnsiString FileName)
  564. {
  565. void * Result;
  566. if (FileName.IsEmpty())
  567. {
  568. if (!FApplicationInfo)
  569. {
  570. FApplicationInfo = CreateFileInfo(ModuleFileName());
  571. }
  572. Result = FApplicationInfo;
  573. }
  574. else
  575. {
  576. Result = CreateFileInfo(FileName);
  577. }
  578. return Result;
  579. }
  580. //---------------------------------------------------------------------------
  581. void * __fastcall TConfiguration::GetApplicationInfo()
  582. {
  583. return GetFileApplicationInfo("");
  584. }
  585. //---------------------------------------------------------------------------
  586. AnsiString __fastcall TConfiguration::GetFileProductName(const AnsiString FileName)
  587. {
  588. return GetFileFileInfoString("ProductName", FileName);
  589. }
  590. //---------------------------------------------------------------------------
  591. AnsiString __fastcall TConfiguration::GetFileCompanyName(const AnsiString FileName)
  592. {
  593. return GetFileFileInfoString("CompanyName", FileName);
  594. }
  595. //---------------------------------------------------------------------------
  596. AnsiString __fastcall TConfiguration::GetProductName()
  597. {
  598. return GetFileProductName("");
  599. }
  600. //---------------------------------------------------------------------------
  601. AnsiString __fastcall TConfiguration::GetCompanyName()
  602. {
  603. return GetFileCompanyName("");
  604. }
  605. //---------------------------------------------------------------------------
  606. AnsiString __fastcall TConfiguration::GetFileProductVersion(const AnsiString FileName)
  607. {
  608. return TrimVersion(GetFileFileInfoString("ProductVersion", FileName));
  609. }
  610. //---------------------------------------------------------------------------
  611. AnsiString __fastcall TConfiguration::GetProductVersion()
  612. {
  613. return GetFileProductVersion("");
  614. }
  615. //---------------------------------------------------------------------------
  616. AnsiString __fastcall TConfiguration::TrimVersion(AnsiString Version)
  617. {
  618. while ((Version.Pos(".") != Version.LastDelimiter(".")) &&
  619. (Version.SubString(Version.Length() - 1, 2) == ".0"))
  620. {
  621. Version.SetLength(Version.Length() - 2);
  622. }
  623. return Version;
  624. }
  625. //---------------------------------------------------------------------------
  626. AnsiString __fastcall TConfiguration::GetVersionStr()
  627. {
  628. TGuard Guard(FCriticalSection);
  629. try
  630. {
  631. TVSFixedFileInfo * Info = FixedApplicationInfo;
  632. return FMTLOAD(VERSION, (
  633. HIWORD(Info->dwFileVersionMS),
  634. LOWORD(Info->dwFileVersionMS),
  635. HIWORD(Info->dwFileVersionLS),
  636. LOWORD(Info->dwFileVersionLS)));
  637. }
  638. catch (Exception &E)
  639. {
  640. throw ExtException(&E, "Can't get application version");
  641. }
  642. }
  643. //---------------------------------------------------------------------------
  644. AnsiString __fastcall TConfiguration::GetVersion()
  645. {
  646. TGuard Guard(FCriticalSection);
  647. try
  648. {
  649. TVSFixedFileInfo * Info = FixedApplicationInfo;
  650. AnsiString Result;
  651. Result = TrimVersion(FORMAT("%d.%d.%d", (
  652. HIWORD(Info->dwFileVersionMS),
  653. LOWORD(Info->dwFileVersionMS),
  654. HIWORD(Info->dwFileVersionLS))));
  655. return Result;
  656. }
  657. catch (Exception &E)
  658. {
  659. throw ExtException(&E, "Can't get application version");
  660. }
  661. }
  662. //---------------------------------------------------------------------------
  663. AnsiString __fastcall TConfiguration::GetFileFileInfoString(const AnsiString Key,
  664. const AnsiString FileName)
  665. {
  666. TGuard Guard(FCriticalSection);
  667. AnsiString Result;
  668. void * Info = GetFileApplicationInfo(FileName);
  669. try
  670. {
  671. if ((Info != NULL) && (GetTranslationCount(Info) > 0))
  672. {
  673. TTranslation Translation;
  674. Translation = GetTranslation(Info, 0);
  675. Result = ::GetFileInfoString(Info, Translation, Key);
  676. }
  677. else
  678. {
  679. assert(!FileName.IsEmpty());
  680. }
  681. }
  682. __finally
  683. {
  684. if (!FileName.IsEmpty())
  685. {
  686. FreeFileInfo(Info);
  687. }
  688. }
  689. return Result;
  690. }
  691. //---------------------------------------------------------------------------
  692. AnsiString __fastcall TConfiguration::GetFileInfoString(const AnsiString Key)
  693. {
  694. return GetFileFileInfoString(Key, "");
  695. }
  696. //---------------------------------------------------------------------------
  697. AnsiString __fastcall TConfiguration::GetRegistryStorageKey()
  698. {
  699. return GetRegistryKey();
  700. }
  701. //---------------------------------------------------------------------------
  702. void __fastcall TConfiguration::SetIniFileStorageName(AnsiString value)
  703. {
  704. FIniFileStorageName = value;
  705. FStorage = stIniFile;
  706. }
  707. //---------------------------------------------------------------------------
  708. AnsiString __fastcall TConfiguration::GetIniFileStorageName()
  709. {
  710. if (FIniFileStorageName.IsEmpty())
  711. {
  712. return ChangeFileExt(ParamStr(0), ".ini");
  713. }
  714. else
  715. {
  716. return FIniFileStorageName;
  717. }
  718. }
  719. //---------------------------------------------------------------------------
  720. AnsiString __fastcall TConfiguration::GetPuttySessionsKey()
  721. {
  722. return PuttyRegistryStorageKey + "\\Sessions";
  723. }
  724. //---------------------------------------------------------------------------
  725. AnsiString __fastcall TConfiguration::GetStoredSessionsSubKey()
  726. {
  727. return "Sessions";
  728. }
  729. //---------------------------------------------------------------------------
  730. AnsiString __fastcall TConfiguration::GetSshHostKeysSubKey()
  731. {
  732. return "SshHostKeys";
  733. }
  734. //---------------------------------------------------------------------------
  735. AnsiString __fastcall TConfiguration::GetConfigurationSubKey()
  736. {
  737. return "Configuration";
  738. }
  739. //---------------------------------------------------------------------------
  740. AnsiString __fastcall TConfiguration::GetRootKeyStr()
  741. {
  742. return RootKeyToStr(HKEY_CURRENT_USER);
  743. }
  744. //---------------------------------------------------------------------------
  745. bool __fastcall TConfiguration::GetGSSAPIInstalled()
  746. {
  747. return HasGSSAPI();
  748. }
  749. //---------------------------------------------------------------------------
  750. void __fastcall TConfiguration::SetStorage(TStorage value)
  751. {
  752. if (FStorage != value)
  753. {
  754. THierarchicalStorage * SourceStorage = NULL;
  755. THierarchicalStorage * TargetStorage = NULL;
  756. try
  757. {
  758. SourceStorage = CreateScpStorage(false);
  759. SourceStorage->AccessMode = smRead;
  760. FStorage = value;
  761. TargetStorage = CreateScpStorage(false);
  762. TargetStorage->AccessMode = smReadWrite;
  763. TargetStorage->Explicit = true;
  764. // copy before save as it removes the ini file,
  765. // when switching from ini to registry
  766. CopyData(SourceStorage, TargetStorage);
  767. }
  768. __finally
  769. {
  770. delete SourceStorage;
  771. delete TargetStorage;
  772. }
  773. // save all and explicit
  774. Save(true, true);
  775. }
  776. }
  777. //---------------------------------------------------------------------------
  778. void __fastcall TConfiguration::Saved()
  779. {
  780. // nothing
  781. }
  782. //---------------------------------------------------------------------------
  783. TStorage __fastcall TConfiguration::GetStorage()
  784. {
  785. if (FStorage == stDetect)
  786. {
  787. FStorage = FileExists(IniFileStorageName) ? stIniFile : stRegistry;
  788. }
  789. return FStorage;
  790. }
  791. //---------------------------------------------------------------------------
  792. void __fastcall TConfiguration::SetRandomSeedFile(AnsiString value)
  793. {
  794. if (RandomSeedFile != value)
  795. {
  796. AnsiString PrevRandomSeedFileName = RandomSeedFileName;
  797. FRandomSeedFile = value;
  798. // never allow empty seed file to avoid Putty trying to reinitialize the path
  799. if (RandomSeedFileName.IsEmpty())
  800. {
  801. FRandomSeedFile = FDefaultRandomSeedFile;
  802. }
  803. if (!PrevRandomSeedFileName.IsEmpty() &&
  804. (PrevRandomSeedFileName != RandomSeedFileName) &&
  805. FileExists(PrevRandomSeedFileName))
  806. {
  807. // ignore any error
  808. DeleteFile(PrevRandomSeedFileName);
  809. }
  810. }
  811. }
  812. //---------------------------------------------------------------------
  813. AnsiString __fastcall TConfiguration::GetRandomSeedFileName()
  814. {
  815. return StripPathQuotes(ExpandEnvironmentVariables(FRandomSeedFile)).Trim();
  816. }
  817. //---------------------------------------------------------------------
  818. void __fastcall TConfiguration::SetPuttyRegistryStorageKey(AnsiString value)
  819. {
  820. SET_CONFIG_PROPERTY(PuttyRegistryStorageKey);
  821. }
  822. //---------------------------------------------------------------------------
  823. TEOLType __fastcall TConfiguration::GetLocalEOLType()
  824. {
  825. return eolCRLF;
  826. }
  827. //---------------------------------------------------------------------
  828. void __fastcall TConfiguration::TemporaryLogging(const AnsiString ALogFileName)
  829. {
  830. FLogging = true;
  831. FLogFileName = ALogFileName;
  832. FLogActions = SameText(ExtractFileExt(FLogFileName), ".xml");
  833. }
  834. //---------------------------------------------------------------------
  835. void __fastcall TConfiguration::SetLogging(bool value)
  836. {
  837. if (Logging != value)
  838. {
  839. FPermanentLogging = value;
  840. FLogging = value;
  841. Changed();
  842. }
  843. }
  844. //---------------------------------------------------------------------
  845. void __fastcall TConfiguration::SetLogFileName(AnsiString value)
  846. {
  847. if (LogFileName != value)
  848. {
  849. FPermanentLogFileName = value;
  850. FLogFileName = value;
  851. Changed();
  852. }
  853. }
  854. //---------------------------------------------------------------------
  855. void __fastcall TConfiguration::SetLogToFile(bool value)
  856. {
  857. if (value != LogToFile)
  858. {
  859. LogFileName = value ? DefaultLogFileName : AnsiString("");
  860. Changed();
  861. }
  862. }
  863. //---------------------------------------------------------------------
  864. bool __fastcall TConfiguration::GetLogToFile()
  865. {
  866. return !LogFileName.IsEmpty();
  867. }
  868. //---------------------------------------------------------------------
  869. void __fastcall TConfiguration::SetLogProtocol(int value)
  870. {
  871. SET_CONFIG_PROPERTY(LogProtocol);
  872. }
  873. //---------------------------------------------------------------------
  874. void __fastcall TConfiguration::SetLogActions(bool value)
  875. {
  876. if (LogActions != value)
  877. {
  878. FPermanentLogActions = value;
  879. FLogActions = value;
  880. Changed();
  881. }
  882. }
  883. //---------------------------------------------------------------------
  884. void __fastcall TConfiguration::SetLogFileAppend(bool value)
  885. {
  886. SET_CONFIG_PROPERTY(LogFileAppend);
  887. }
  888. //---------------------------------------------------------------------
  889. void __fastcall TConfiguration::SetLogWindowLines(int value)
  890. {
  891. SET_CONFIG_PROPERTY(LogWindowLines);
  892. }
  893. //---------------------------------------------------------------------
  894. void __fastcall TConfiguration::SetLogWindowComplete(bool value)
  895. {
  896. if (value != LogWindowComplete)
  897. {
  898. LogWindowLines = value ? 0 : 50;
  899. Changed();
  900. }
  901. }
  902. //---------------------------------------------------------------------
  903. bool __fastcall TConfiguration::GetLogWindowComplete()
  904. {
  905. return (bool)(LogWindowLines == 0);
  906. }
  907. //---------------------------------------------------------------------
  908. AnsiString __fastcall TConfiguration::GetDefaultLogFileName()
  909. {
  910. return IncludeTrailingBackslash(SystemTemporaryDirectory()) + "winscp.log";
  911. }
  912. //---------------------------------------------------------------------------
  913. void __fastcall TConfiguration::SetConfirmOverwriting(bool value)
  914. {
  915. TGuard Guard(FCriticalSection);
  916. SET_CONFIG_PROPERTY(ConfirmOverwriting);
  917. }
  918. //---------------------------------------------------------------------------
  919. bool __fastcall TConfiguration::GetConfirmOverwriting()
  920. {
  921. TGuard Guard(FCriticalSection);
  922. return FConfirmOverwriting;
  923. }
  924. //---------------------------------------------------------------------------
  925. void __fastcall TConfiguration::SetConfirmResume(bool value)
  926. {
  927. TGuard Guard(FCriticalSection);
  928. SET_CONFIG_PROPERTY(ConfirmResume);
  929. }
  930. //---------------------------------------------------------------------------
  931. bool __fastcall TConfiguration::GetConfirmResume()
  932. {
  933. TGuard Guard(FCriticalSection);
  934. return FConfirmResume;
  935. }
  936. //---------------------------------------------------------------------------
  937. void __fastcall TConfiguration::SetAutoReadDirectoryAfterOp(bool value)
  938. {
  939. TGuard Guard(FCriticalSection);
  940. SET_CONFIG_PROPERTY(AutoReadDirectoryAfterOp);
  941. }
  942. //---------------------------------------------------------------------------
  943. bool __fastcall TConfiguration::GetAutoReadDirectoryAfterOp()
  944. {
  945. TGuard Guard(FCriticalSection);
  946. return FAutoReadDirectoryAfterOp;
  947. }
  948. //---------------------------------------------------------------------------
  949. AnsiString __fastcall TConfiguration::GetTimeFormat()
  950. {
  951. return "h:nn:ss";
  952. }
  953. //---------------------------------------------------------------------------
  954. AnsiString __fastcall TConfiguration::GetPartialExt() const
  955. {
  956. return PARTIAL_EXT;
  957. }
  958. //---------------------------------------------------------------------------
  959. AnsiString __fastcall TConfiguration::GetDefaultKeyFile()
  960. {
  961. return "";
  962. }
  963. //---------------------------------------------------------------------------
  964. AnsiString __fastcall TConfiguration::GetLocalInvalidChars()
  965. {
  966. return "/\\:*?\"<>|";
  967. }
  968. //---------------------------------------------------------------------------
  969. bool __fastcall TConfiguration::GetRememberPassword()
  970. {
  971. return false;
  972. }
  973. //---------------------------------------------------------------------------
  974. void __fastcall TConfiguration::SetSessionReopenAuto(int value)
  975. {
  976. SET_CONFIG_PROPERTY(SessionReopenAuto);
  977. }
  978. //---------------------------------------------------------------------------
  979. void __fastcall TConfiguration::SetSessionReopenBackground(int value)
  980. {
  981. SET_CONFIG_PROPERTY(SessionReopenBackground);
  982. }
  983. //---------------------------------------------------------------------------
  984. void __fastcall TConfiguration::SetSessionReopenTimeout(int value)
  985. {
  986. SET_CONFIG_PROPERTY(SessionReopenTimeout);
  987. }
  988. //---------------------------------------------------------------------------
  989. void __fastcall TConfiguration::SetTunnelLocalPortNumberLow(int value)
  990. {
  991. SET_CONFIG_PROPERTY(TunnelLocalPortNumberLow);
  992. }
  993. //---------------------------------------------------------------------------
  994. void __fastcall TConfiguration::SetTunnelLocalPortNumberHigh(int value)
  995. {
  996. SET_CONFIG_PROPERTY(TunnelLocalPortNumberHigh);
  997. }
  998. //---------------------------------------------------------------------------
  999. void __fastcall TConfiguration::SetCacheDirectoryChangesMaxSize(int value)
  1000. {
  1001. SET_CONFIG_PROPERTY(CacheDirectoryChangesMaxSize);
  1002. }
  1003. //---------------------------------------------------------------------------
  1004. void __fastcall TConfiguration::SetShowFtpWelcomeMessage(bool value)
  1005. {
  1006. SET_CONFIG_PROPERTY(ShowFtpWelcomeMessage);
  1007. }
  1008. //---------------------------------------------------------------------------
  1009. //---------------------------------------------------------------------------
  1010. void __fastcall TShortCuts::Add(TShortCut ShortCut)
  1011. {
  1012. FShortCuts.insert(ShortCut);
  1013. }
  1014. //---------------------------------------------------------------------------
  1015. bool __fastcall TShortCuts::Has(TShortCut ShortCut) const
  1016. {
  1017. return (FShortCuts.count(ShortCut) != 0);
  1018. }