Configuration.cpp 30 KB

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