Configuration.cpp 28 KB

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