Configuration.cpp 29 KB

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