Configuration.cpp 31 KB

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