Configuration.cpp 63 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <FileInfo.h>
  5. #include "Common.h"
  6. #include "Exceptions.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 "FileMasks.h"
  14. #include "CopyParam.h"
  15. #include <shlobj.h>
  16. #include <System.IOUtils.hpp>
  17. #include <System.StrUtils.hpp>
  18. //---------------------------------------------------------------------------
  19. #pragma package(smart_init)
  20. //---------------------------------------------------------------------------
  21. const wchar_t * AutoSwitchNames = L"On;Off;Auto";
  22. const wchar_t * NotAutoSwitchNames = L"Off;On;Auto";
  23. //---------------------------------------------------------------------------
  24. // See https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xhtml
  25. const UnicodeString Sha1ChecksumAlg(L"sha-1");
  26. const UnicodeString Sha224ChecksumAlg(L"sha-224");
  27. const UnicodeString Sha256ChecksumAlg(L"sha-256");
  28. const UnicodeString Sha384ChecksumAlg(L"sha-384");
  29. const UnicodeString Sha512ChecksumAlg(L"sha-512");
  30. const UnicodeString Md5ChecksumAlg(L"md5");
  31. // Not defined by IANA
  32. const UnicodeString Crc32ChecksumAlg(L"crc32");
  33. //---------------------------------------------------------------------------
  34. const UnicodeString SshFingerprintType(L"ssh");
  35. const UnicodeString TlsFingerprintType(L"tls");
  36. //---------------------------------------------------------------------------
  37. const UnicodeString FtpsCertificateStorageKey(L"FtpsCertificates");
  38. const UnicodeString HttpsCertificateStorageKey(L"HttpsCertificates");
  39. const UnicodeString LastFingerprintsStorageKey(L"LastFingerprints");
  40. const UnicodeString DirectoryStatisticsCacheKey(L"DirectoryStatisticsCache");
  41. const UnicodeString CDCacheKey(L"CDCache");
  42. const UnicodeString BannersKey(L"Banners");
  43. //---------------------------------------------------------------------------
  44. const int BelowNormalLogLevels = 1;
  45. //---------------------------------------------------------------------------
  46. __fastcall TConfiguration::TConfiguration()
  47. {
  48. FCriticalSection = new TCriticalSection();
  49. FUpdating = 0;
  50. FStorage = stDetect;
  51. FDontSave = false;
  52. FForceSave = false;
  53. FApplicationInfo = NULL;
  54. FUsage = new TUsage(this);
  55. FDefaultCollectUsage = false;
  56. FScripting = false;
  57. UnicodeString RandomSeedPath;
  58. if (!GetEnvironmentVariable(L"APPDATA").IsEmpty())
  59. {
  60. RandomSeedPath = L"%APPDATA%";
  61. }
  62. else
  63. {
  64. RandomSeedPath = GetShellFolderPath(CSIDL_LOCAL_APPDATA);
  65. if (RandomSeedPath.IsEmpty())
  66. {
  67. RandomSeedPath = GetShellFolderPath(CSIDL_APPDATA);
  68. }
  69. }
  70. FDefaultRandomSeedFile = IncludeTrailingBackslash(RandomSeedPath) + L"winscp.rnd";
  71. }
  72. //---------------------------------------------------------------------------
  73. void __fastcall TConfiguration::Default()
  74. {
  75. TGuard Guard(FCriticalSection);
  76. FDisablePasswordStoring = false;
  77. FForceBanners = false;
  78. FDisableAcceptingHostKeys = false;
  79. TRegistryStorage * AdminStorage;
  80. AdminStorage = new TRegistryStorage(RegistryStorageKey, HKEY_LOCAL_MACHINE);
  81. try
  82. {
  83. if (AdminStorage->OpenRootKey(false))
  84. {
  85. LoadAdmin(AdminStorage);
  86. AdminStorage->CloseSubKey();
  87. }
  88. }
  89. __finally
  90. {
  91. delete AdminStorage;
  92. }
  93. RandomSeedFile = FDefaultRandomSeedFile;
  94. PuttyRegistryStorageKey = OriginalPuttyRegistryStorageKey;
  95. FConfirmOverwriting = true;
  96. FConfirmResume = true;
  97. FAutoReadDirectoryAfterOp = true;
  98. FSessionReopenAuto = 5000;
  99. FSessionReopenBackground = 2000;
  100. FSessionReopenTimeout = 0;
  101. FSessionReopenAutoStall = 60000;
  102. FTunnelLocalPortNumberLow = 50000;
  103. FTunnelLocalPortNumberHigh = 50099;
  104. FCacheDirectoryChangesMaxSize = 100;
  105. FShowFtpWelcomeMessage = false;
  106. FExternalIpAddress = L"";
  107. FTryFtpWhenSshFails = true;
  108. FParallelDurationThreshold = 10;
  109. FMimeTypes = UnicodeString();
  110. FDontReloadMoreThanSessions = 1000;
  111. FScriptProgressFileNameLimit = 25;
  112. CollectUsage = FDefaultCollectUsage;
  113. FLogging = false;
  114. FPermanentLogging = false;
  115. FLogFileName = DefaultLogFileName;
  116. FPermanentLogFileName = FLogFileName;
  117. FLogFileAppend = true;
  118. FLogSensitive = false;
  119. FPermanentLogSensitive = FLogSensitive;
  120. FLogMaxSize = 0;
  121. FPermanentLogMaxSize = FLogMaxSize;
  122. FLogMaxCount = 0;
  123. FPermanentLogMaxCount = FLogMaxCount;
  124. FLogProtocol = 0;
  125. FPermanentLogProtocol = FLogProtocol;
  126. UpdateActualLogProtocol();
  127. FLogActions = false;
  128. FPermanentLogActions = false;
  129. FLogActionsRequired = false;
  130. FActionsLogFileName = L"%TEMP%\\!S.xml";
  131. FPermanentActionsLogFileName = FActionsLogFileName;
  132. FProgramIniPathWrittable = -1;
  133. FCustomIniFileStorageName = LoadCustomIniFileStorageName();
  134. Changed();
  135. }
  136. //---------------------------------------------------------------------------
  137. __fastcall TConfiguration::~TConfiguration()
  138. {
  139. DebugAssert(!FUpdating);
  140. if (FApplicationInfo) FreeFileInfo(FApplicationInfo);
  141. delete FCriticalSection;
  142. delete FUsage;
  143. }
  144. //---------------------------------------------------------------------------
  145. void __fastcall TConfiguration::UpdateStaticUsage()
  146. {
  147. Usage->Set(L"ConfigurationIniFile", (Storage == stIniFile));
  148. Usage->Set(L"ConfigurationIniFileCustom", !CustomIniFileStorageName.IsEmpty());
  149. Usage->Set("Unofficial", IsUnofficial);
  150. // this is called from here, because we are guarded from calling into
  151. // master password handler here, see TWinConfiguration::UpdateStaticUsage
  152. StoredSessions->UpdateStaticUsage();
  153. }
  154. //---------------------------------------------------------------------------
  155. THierarchicalStorage * TConfiguration::CreateConfigStorage()
  156. {
  157. bool SessionList = false;
  158. return CreateScpStorage(SessionList);
  159. }
  160. //---------------------------------------------------------------------------
  161. THierarchicalStorage * TConfiguration::CreateConfigRegistryStorage()
  162. {
  163. return new TRegistryStorage(RegistryStorageKey);
  164. }
  165. //---------------------------------------------------------------------------
  166. THierarchicalStorage * TConfiguration::CreateScpStorage(bool & SessionList)
  167. {
  168. TGuard Guard(FCriticalSection);
  169. THierarchicalStorage * Result;
  170. if (Storage == stRegistry)
  171. {
  172. Result = CreateConfigRegistryStorage();
  173. }
  174. else if (Storage == stNul)
  175. {
  176. Result = TIniFileStorage::CreateFromPath(INI_NUL);
  177. }
  178. else
  179. {
  180. UnicodeString StorageName = IniFileStorageName;
  181. Result = TIniFileStorage::CreateFromPath(StorageName);
  182. }
  183. if ((FOptionsStorage.get() != NULL) && (FOptionsStorage->Count > 0))
  184. {
  185. if (!SessionList)
  186. {
  187. Result = new TOptionsStorage(FOptionsStorage.get(), ConfigurationSubKey, Result);
  188. }
  189. else
  190. {
  191. // cannot reuse session list storage for configuration as for it we need
  192. // the option-override storage above
  193. }
  194. }
  195. else
  196. {
  197. // All the above stores can be reused for configuration,
  198. // if no options-overrides are set
  199. SessionList = false;
  200. }
  201. return Result;
  202. }
  203. //---------------------------------------------------------------------------
  204. UnicodeString __fastcall TConfiguration::PropertyToKey(const UnicodeString & Property)
  205. {
  206. // no longer useful
  207. int P = Property.LastDelimiter(L".>");
  208. UnicodeString Result = Property.SubString(P + 1, Property.Length() - P);
  209. if ((Result[1] == L'F') && ((wchar_t)toupper(Result[2]) == Result[2]))
  210. {
  211. Result.Delete(1, 1);
  212. }
  213. return Result;
  214. }
  215. //---------------------------------------------------------------------------
  216. #define BLOCK(KEY, CANCREATE, BLOCK) \
  217. if (Storage->OpenSubKeyPath(KEY, CANCREATE)) try { BLOCK } __finally { Storage->CloseSubKeyPath(); }
  218. #define KEY(TYPE, VAR) KEYEX(TYPE, VAR, PropertyToKey(TEXT(#VAR)))
  219. #define REGCONFIG(CANCREATE) \
  220. BLOCK(L"Interface", CANCREATE, \
  221. KEY(String, RandomSeedFile); \
  222. KEY(String, PuttyRegistryStorageKey); \
  223. KEY(Bool, ConfirmOverwriting); \
  224. KEY(Bool, ConfirmResume); \
  225. KEY(Bool, AutoReadDirectoryAfterOp); \
  226. KEY(Integer, SessionReopenAuto); \
  227. KEY(Integer, SessionReopenBackground); \
  228. KEY(Integer, SessionReopenTimeout); \
  229. KEY(Integer, SessionReopenAutoStall); \
  230. KEY(Integer, TunnelLocalPortNumberLow); \
  231. KEY(Integer, TunnelLocalPortNumberHigh); \
  232. KEY(Integer, CacheDirectoryChangesMaxSize); \
  233. KEY(Bool, ShowFtpWelcomeMessage); \
  234. KEY(String, ExternalIpAddress); \
  235. KEY(Bool, TryFtpWhenSshFails); \
  236. KEY(Integer, ParallelDurationThreshold); \
  237. KEY(String, MimeTypes); \
  238. KEY(Integer, DontReloadMoreThanSessions); \
  239. KEY(Integer, ScriptProgressFileNameLimit); \
  240. KEY(Bool, CollectUsage); \
  241. ); \
  242. BLOCK(L"Logging", CANCREATE, \
  243. KEYEX(Bool, PermanentLogging, L"Logging"); \
  244. KEYEX(String,PermanentLogFileName, L"LogFileName"); \
  245. KEY(Bool, LogFileAppend); \
  246. KEYEX(Bool, PermanentLogSensitive, L"LogSensitive"); \
  247. KEYEX(Int64, PermanentLogMaxSize, L"LogMaxSize"); \
  248. KEYEX(Integer, PermanentLogMaxCount, L"LogMaxCount"); \
  249. KEYEX(Integer,PermanentLogProtocol, L"LogProtocol"); \
  250. KEYEX(Bool, PermanentLogActions, L"LogActions"); \
  251. KEYEX(String,PermanentActionsLogFileName, L"ActionsLogFileName"); \
  252. );
  253. //---------------------------------------------------------------------------
  254. void __fastcall TConfiguration::SaveData(THierarchicalStorage * Storage, bool /*All*/)
  255. {
  256. #define KEYEX(TYPE, VAR, NAME) Storage->Write ## TYPE(NAME, VAR)
  257. REGCONFIG(true);
  258. #undef KEYEX
  259. if (Storage->OpenSubKey(L"Usage", true))
  260. {
  261. FUsage->Save(Storage);
  262. Storage->CloseSubKey();
  263. }
  264. }
  265. //---------------------------------------------------------------------------
  266. void __fastcall TConfiguration::Save()
  267. {
  268. // only modified, implicit
  269. DoSave(false, false);
  270. }
  271. //---------------------------------------------------------------------------
  272. void __fastcall TConfiguration::SaveExplicit()
  273. {
  274. // only modified, explicit
  275. DoSave(false, true);
  276. }
  277. //---------------------------------------------------------------------------
  278. void __fastcall TConfiguration::DoSave(bool All, bool Explicit)
  279. {
  280. if (FDontSave) return;
  281. THierarchicalStorage * AStorage = CreateConfigStorage();
  282. try
  283. {
  284. AStorage->AccessMode = smReadWrite;
  285. AStorage->Explicit = Explicit;
  286. AStorage->ForceSave = FForceSave;
  287. if (AStorage->OpenSubKey(ConfigurationSubKey, true))
  288. {
  289. // if saving to TOptionsStorage, make sure we save everything so that
  290. // all configuration is properly transferred to the master storage
  291. bool ConfigAll = All || AStorage->Temporary;
  292. SaveData(AStorage, ConfigAll);
  293. }
  294. }
  295. __finally
  296. {
  297. delete AStorage;
  298. }
  299. Saved();
  300. if (All)
  301. {
  302. StoredSessions->Save(true, Explicit);
  303. }
  304. // clean up as last, so that if it fails (read only INI), the saving can proceed
  305. if (Storage == stRegistry)
  306. {
  307. CleanupIniFile();
  308. }
  309. SaveCustomIniFileStorageName();
  310. }
  311. //---------------------------------------------------------------------------
  312. void __fastcall TConfiguration::SaveCustomIniFileStorageName()
  313. {
  314. // Particularly, not to create an empty "Override" key, unless the custom INI file is ever set
  315. if (CustomIniFileStorageName != LoadCustomIniFileStorageName())
  316. {
  317. std::unique_ptr<TRegistryStorage> RegistryStorage(new TRegistryStorage(GetRegistryStorageOverrideKey()));
  318. RegistryStorage->AccessMode = smReadWrite;
  319. RegistryStorage->Explicit = true;
  320. if (RegistryStorage->OpenRootKey(true))
  321. {
  322. RegistryStorage->WriteString(L"IniFile", CustomIniFileStorageName);
  323. RegistryStorage->CloseSubKey();
  324. }
  325. }
  326. }
  327. //---------------------------------------------------------------------------
  328. void __fastcall TConfiguration::Export(const UnicodeString & FileName)
  329. {
  330. // not to "append" the export to an existing file
  331. if (FileExists(FileName))
  332. {
  333. DeleteFileChecked(FileName);
  334. }
  335. THierarchicalStorage * Storage = NULL;
  336. THierarchicalStorage * ExportStorage = NULL;
  337. try
  338. {
  339. ExportStorage = TIniFileStorage::CreateFromPath(FileName);
  340. ExportStorage->AccessMode = smReadWrite;
  341. ExportStorage->Explicit = true;
  342. Storage = CreateConfigStorage();
  343. Storage->AccessMode = smRead;
  344. CopyData(Storage, ExportStorage);
  345. if (ExportStorage->OpenSubKey(ConfigurationSubKey, true))
  346. {
  347. SaveData(ExportStorage, true);
  348. }
  349. }
  350. __finally
  351. {
  352. delete ExportStorage;
  353. delete Storage;
  354. }
  355. StoredSessions->Export(FileName);
  356. }
  357. //---------------------------------------------------------------------------
  358. void __fastcall TConfiguration::Import(const UnicodeString & FileName)
  359. {
  360. THierarchicalStorage * Storage = NULL;
  361. THierarchicalStorage * ImportStorage = NULL;
  362. try
  363. {
  364. ImportStorage = TIniFileStorage::CreateFromPath(FileName);
  365. ImportStorage->AccessMode = smRead;
  366. Storage = CreateConfigStorage();
  367. Storage->AccessMode = smReadWrite;
  368. Storage->Explicit = true;
  369. CopyData(ImportStorage, Storage);
  370. Default();
  371. LoadFrom(ImportStorage);
  372. if (ImportStorage->OpenSubKey(Configuration->StoredSessionsSubKey, false))
  373. {
  374. StoredSessions->Clear();
  375. StoredSessions->DefaultSettings->Default();
  376. StoredSessions->Load(ImportStorage);
  377. }
  378. }
  379. __finally
  380. {
  381. delete ImportStorage;
  382. delete Storage;
  383. }
  384. // save all and explicit
  385. DoSave(true, true);
  386. }
  387. //---------------------------------------------------------------------------
  388. void __fastcall TConfiguration::LoadData(THierarchicalStorage * Storage)
  389. {
  390. #define KEYEX(TYPE, VAR, NAME) VAR = Storage->Read ## TYPE(NAME, VAR)
  391. #pragma warn -eas
  392. REGCONFIG(false);
  393. #pragma warn +eas
  394. #undef KEYEX
  395. if (Storage->OpenSubKey(L"Usage", false))
  396. {
  397. FUsage->Load(Storage);
  398. Storage->CloseSubKey();
  399. }
  400. if (FPermanentLogActions && FPermanentActionsLogFileName.IsEmpty() &&
  401. FPermanentLogging && !FPermanentLogFileName.IsEmpty())
  402. {
  403. FPermanentActionsLogFileName = FPermanentLogFileName;
  404. FPermanentLogging = false;
  405. FPermanentLogFileName = L"";
  406. }
  407. }
  408. //---------------------------------------------------------------------------
  409. void __fastcall TConfiguration::LoadAdmin(THierarchicalStorage * Storage)
  410. {
  411. FDisablePasswordStoring = Storage->ReadBool(L"DisablePasswordStoring", FDisablePasswordStoring);
  412. FForceBanners = Storage->ReadBool(L"ForceBanners", FForceBanners);
  413. FDisableAcceptingHostKeys = Storage->ReadBool(L"DisableAcceptingHostKeys", FDisableAcceptingHostKeys);
  414. FDefaultCollectUsage = Storage->ReadBool(L"DefaultCollectUsage", FDefaultCollectUsage);
  415. }
  416. //---------------------------------------------------------------------------
  417. void __fastcall TConfiguration::LoadFrom(THierarchicalStorage * Storage)
  418. {
  419. if (Storage->OpenSubKey(ConfigurationSubKey, false))
  420. {
  421. LoadData(Storage);
  422. Storage->CloseSubKey();
  423. }
  424. }
  425. //---------------------------------------------------------------------------
  426. UnicodeString __fastcall TConfiguration::GetRegistryStorageOverrideKey()
  427. {
  428. return GetRegistryStorageKey() + L" Override";
  429. }
  430. //---------------------------------------------------------------------------
  431. UnicodeString __fastcall TConfiguration::LoadCustomIniFileStorageName()
  432. {
  433. UnicodeString Result;
  434. std::unique_ptr<TRegistryStorage> RegistryStorage(new TRegistryStorage(GetRegistryStorageOverrideKey()));
  435. if (RegistryStorage->OpenRootKey(false))
  436. {
  437. Result = RegistryStorage->ReadString(L"IniFile", L"");
  438. RegistryStorage->CloseSubKey();
  439. }
  440. RegistryStorage.reset(NULL);
  441. return Result;
  442. }
  443. //---------------------------------------------------------------------------
  444. void __fastcall TConfiguration::Load(THierarchicalStorage * Storage)
  445. {
  446. TGuard Guard(FCriticalSection);
  447. TStorageAccessMode StorageAccessMode = Storage->AccessMode;
  448. try
  449. {
  450. Storage->AccessMode = smRead;
  451. LoadFrom(Storage);
  452. }
  453. __finally
  454. {
  455. Storage->AccessMode = StorageAccessMode;
  456. }
  457. }
  458. //---------------------------------------------------------------------------
  459. bool __fastcall TConfiguration::CopySubKey(THierarchicalStorage * Source, THierarchicalStorage * Target, const UnicodeString & Name)
  460. {
  461. bool Result = Source->OpenSubKey(Name, false);
  462. if (Result)
  463. {
  464. Result = Target->OpenSubKey(Name, true);
  465. if (!Result)
  466. {
  467. Source->CloseSubKey();
  468. }
  469. }
  470. return Result;
  471. }
  472. //---------------------------------------------------------------------------
  473. void __fastcall TConfiguration::CopyAllStringsInSubKey(
  474. THierarchicalStorage * Source, THierarchicalStorage * Target, const UnicodeString & Name)
  475. {
  476. if (CopySubKey(Source, Target, Name))
  477. {
  478. std::unique_ptr<TStrings> Names(new TStringList());
  479. Source->GetValueNames(Names.get());
  480. for (int Index = 0; Index < Names->Count; Index++)
  481. {
  482. UnicodeString Buf = Source->ReadStringRaw(Names->Strings[Index], UnicodeString());
  483. Target->WriteStringRaw(Names->Strings[Index], Buf);
  484. }
  485. Target->CloseSubKey();
  486. Source->CloseSubKey();
  487. }
  488. }
  489. //---------------------------------------------------------------------------
  490. void __fastcall TConfiguration::CopyData(THierarchicalStorage * Source,
  491. THierarchicalStorage * Target)
  492. {
  493. if (CopySubKey(Source, Target, ConfigurationSubKey))
  494. {
  495. if (CopySubKey(Source, Target, CDCacheKey))
  496. {
  497. std::unique_ptr<TStrings> Names(new TStringList());
  498. Source->GetValueNames(Names.get());
  499. for (int Index = 0; Index < Names->Count; Index++)
  500. {
  501. Target->WriteBinaryData(Names->Strings[Index], Source->ReadBinaryData(Names->Strings[Index]));
  502. }
  503. Target->CloseSubKey();
  504. Source->CloseSubKey();
  505. }
  506. CopyAllStringsInSubKey(Source, Target, BannersKey);
  507. CopyAllStringsInSubKey(Source, Target, LastFingerprintsStorageKey);
  508. Target->CloseSubKey();
  509. Source->CloseSubKey();
  510. }
  511. CopyAllStringsInSubKey(Source, Target, SshHostKeysSubKey);
  512. CopyAllStringsInSubKey(Source, Target, FtpsCertificateStorageKey);
  513. CopyAllStringsInSubKey(Source, Target, HttpsCertificateStorageKey);
  514. }
  515. //---------------------------------------------------------------------------
  516. void __fastcall TConfiguration::LoadDirectoryChangesCache(const UnicodeString SessionKey,
  517. TRemoteDirectoryChangesCache * DirectoryChangesCache)
  518. {
  519. THierarchicalStorage * Storage = CreateConfigStorage();
  520. try
  521. {
  522. Storage->AccessMode = smRead;
  523. if (Storage->OpenSubKey(ConfigurationSubKey, false) &&
  524. Storage->OpenSubKey(CDCacheKey, false) &&
  525. Storage->ValueExists(SessionKey))
  526. {
  527. DirectoryChangesCache->Deserialize(Storage->ReadBinaryData(SessionKey));
  528. }
  529. }
  530. __finally
  531. {
  532. delete Storage;
  533. }
  534. }
  535. //---------------------------------------------------------------------------
  536. void __fastcall TConfiguration::SaveDirectoryChangesCache(const UnicodeString SessionKey,
  537. TRemoteDirectoryChangesCache * DirectoryChangesCache)
  538. {
  539. THierarchicalStorage * Storage = CreateConfigStorage();
  540. try
  541. {
  542. Storage->AccessMode = smReadWrite;
  543. if (Storage->OpenSubKey(ConfigurationSubKey, true) &&
  544. Storage->OpenSubKey(CDCacheKey, true))
  545. {
  546. UnicodeString Data;
  547. DirectoryChangesCache->Serialize(Data);
  548. Storage->WriteBinaryData(SessionKey, Data);
  549. }
  550. }
  551. __finally
  552. {
  553. delete Storage;
  554. }
  555. }
  556. //---------------------------------------------------------------------------
  557. UnicodeString __fastcall TConfiguration::BannerHash(const UnicodeString & Banner)
  558. {
  559. RawByteString Result;
  560. Result.SetLength(16);
  561. md5checksum(
  562. reinterpret_cast<const char*>(Banner.c_str()), Banner.Length() * sizeof(wchar_t),
  563. (unsigned char*)Result.c_str());
  564. return BytesToHex(Result);
  565. }
  566. //---------------------------------------------------------------------------
  567. void __fastcall TConfiguration::GetBannerData(
  568. const UnicodeString & SessionKey, UnicodeString & BannerHash, unsigned int & Params)
  569. {
  570. BannerHash = UnicodeString();
  571. Params = 0;
  572. std::unique_ptr<THierarchicalStorage> Storage(CreateConfigStorage());
  573. Storage->AccessMode = smRead;
  574. if (Storage->OpenSubKey(ConfigurationSubKey, false) &&
  575. Storage->OpenSubKey(BannersKey, false))
  576. {
  577. UnicodeString S = Storage->ReadString(SessionKey, L"");
  578. BannerHash = CutToChar(S, L',', true);
  579. Params = StrToIntDef(L"$" + CutToChar(S, L',', true), 0);
  580. }
  581. }
  582. //---------------------------------------------------------------------------
  583. bool __fastcall TConfiguration::ShowBanner(
  584. const UnicodeString & SessionKey, const UnicodeString & Banner, unsigned int & Params)
  585. {
  586. UnicodeString StoredBannerHash;
  587. GetBannerData(SessionKey, StoredBannerHash, Params);
  588. bool Result = (StoredBannerHash != BannerHash(Banner));
  589. return Result;
  590. }
  591. //---------------------------------------------------------------------------
  592. void __fastcall TConfiguration::SetBannerData(
  593. const UnicodeString & SessionKey, const UnicodeString & BannerHash, unsigned int Params)
  594. {
  595. std::unique_ptr<THierarchicalStorage> Storage(CreateConfigStorage());
  596. Storage->AccessMode = smReadWrite;
  597. if (Storage->OpenSubKey(ConfigurationSubKey, true) &&
  598. Storage->OpenSubKey(BannersKey, true))
  599. {
  600. Storage->WriteString(SessionKey, BannerHash + L"," + UIntToStr(Params));
  601. }
  602. }
  603. //---------------------------------------------------------------------------
  604. void __fastcall TConfiguration::NeverShowBanner(const UnicodeString & SessionKey, const UnicodeString & Banner)
  605. {
  606. UnicodeString DummyBannerHash;
  607. unsigned int Params;
  608. GetBannerData(SessionKey, DummyBannerHash, Params);
  609. SetBannerData(SessionKey, BannerHash(Banner), Params);
  610. }
  611. //---------------------------------------------------------------------------
  612. void __fastcall TConfiguration::SetBannerParams(const UnicodeString & SessionKey, unsigned int Params)
  613. {
  614. UnicodeString BannerHash;
  615. unsigned int DummyParams;
  616. GetBannerData(SessionKey, BannerHash, DummyParams);
  617. SetBannerData(SessionKey, BannerHash, Params);
  618. }
  619. //---------------------------------------------------------------------------
  620. UnicodeString __fastcall TConfiguration::FormatFingerprintKey(const UnicodeString & SiteKey, const UnicodeString & FingerprintType)
  621. {
  622. return FORMAT(L"%s:%s", (SiteKey, FingerprintType));
  623. }
  624. //---------------------------------------------------------------------------
  625. void __fastcall TConfiguration::RememberLastFingerprint(const UnicodeString & SiteKey, const UnicodeString & FingerprintType, const UnicodeString & Fingerprint)
  626. {
  627. std::unique_ptr<THierarchicalStorage> Storage(CreateConfigStorage());
  628. Storage->AccessMode = smReadWrite;
  629. if (Storage->OpenSubKey(ConfigurationSubKey, true) &&
  630. Storage->OpenSubKey(LastFingerprintsStorageKey, true))
  631. {
  632. UnicodeString FingerprintKey = FormatFingerprintKey(SiteKey, FingerprintType);
  633. Storage->WriteString(FingerprintKey, Fingerprint);
  634. }
  635. }
  636. //---------------------------------------------------------------------------
  637. UnicodeString __fastcall TConfiguration::LastFingerprint(const UnicodeString & SiteKey, const UnicodeString & FingerprintType)
  638. {
  639. UnicodeString Result;
  640. std::unique_ptr<THierarchicalStorage> Storage(CreateConfigStorage());
  641. Storage->AccessMode = smRead;
  642. if (Storage->OpenSubKey(ConfigurationSubKey, false) &&
  643. Storage->OpenSubKey(LastFingerprintsStorageKey, false))
  644. {
  645. UnicodeString FingerprintKey = FormatFingerprintKey(SiteKey, FingerprintType);
  646. Result = Storage->ReadString(FingerprintKey, L"");
  647. }
  648. return Result;
  649. }
  650. //---------------------------------------------------------------------------
  651. void __fastcall TConfiguration::Changed()
  652. {
  653. TNotifyEvent AOnChange = NULL;
  654. {
  655. TGuard Guard(FCriticalSection);
  656. if (FUpdating == 0)
  657. {
  658. AOnChange = OnChange;
  659. }
  660. else
  661. {
  662. FChanged = true;
  663. }
  664. }
  665. // No specific reason to call this outside of a guard, just that it is less of a change to a previous unguarded code
  666. if (AOnChange != NULL)
  667. {
  668. AOnChange(this);
  669. }
  670. }
  671. //---------------------------------------------------------------------------
  672. void __fastcall TConfiguration::BeginUpdate()
  673. {
  674. FCriticalSection->Enter();
  675. if (FUpdating == 0)
  676. {
  677. FChanged = false;
  678. }
  679. FUpdating++;
  680. // Greater value would probably indicate some nesting problem in code
  681. DebugAssert(FUpdating < 6);
  682. }
  683. //---------------------------------------------------------------------------
  684. void __fastcall TConfiguration::EndUpdate()
  685. {
  686. DebugAssert(FUpdating > 0);
  687. FUpdating--;
  688. if ((FUpdating == 0) && FChanged)
  689. {
  690. FChanged = false;
  691. Changed();
  692. }
  693. FCriticalSection->Leave();
  694. }
  695. //---------------------------------------------------------------------------
  696. void __fastcall TConfiguration::CleanupConfiguration()
  697. {
  698. try
  699. {
  700. CleanupRegistry(ConfigurationSubKey);
  701. if (Storage == stRegistry)
  702. {
  703. FDontSave = true;
  704. }
  705. }
  706. catch (Exception &E)
  707. {
  708. throw ExtException(&E, LoadStr(CLEANUP_CONFIG_ERROR));
  709. }
  710. }
  711. //---------------------------------------------------------------------------
  712. bool TConfiguration::RegistryPathExists(const UnicodeString & RegistryPath)
  713. {
  714. std::unique_ptr<TRegistryStorage> Registry(new TRegistryStorage(RegistryStorageKey));
  715. UnicodeString ParentKey = ExtractFileDir(RegistryPath);
  716. UnicodeString SubKey = ExtractFileName(RegistryPath);
  717. return
  718. Registry->OpenRootKey(false) &&
  719. (ParentKey.IsEmpty() ||
  720. Registry->OpenSubKeyPath(ParentKey, false)) &&
  721. Registry->KeyExists(SubKey);
  722. }
  723. //---------------------------------------------------------------------------
  724. void __fastcall TConfiguration::CleanupRegistry(const UnicodeString & RegistryPath)
  725. {
  726. std::unique_ptr<TRegistryStorage> Registry(new TRegistryStorage(RegistryStorageKey));
  727. UnicodeString ParentKey = ExtractFileDir(RegistryPath);
  728. if (ParentKey.IsEmpty() ||
  729. Registry->OpenSubKeyPath(ParentKey, false))
  730. {
  731. UnicodeString SubKey = ExtractFileName(RegistryPath);
  732. Registry->RecursiveDeleteSubKey(SubKey);
  733. }
  734. }
  735. //---------------------------------------------------------------------------
  736. TStrings * TConfiguration::GetCaches()
  737. {
  738. std::unique_ptr<TStrings> Result(new TStringList());
  739. Result->Add(SshHostKeysSubKey);
  740. Result->Add(FtpsCertificateStorageKey);
  741. Result->Add(HttpsCertificateStorageKey);
  742. Result->Add(DirectoryStatisticsCacheKey);
  743. Result->Add(TPath::Combine(ConfigurationSubKey, CDCacheKey));
  744. Result->Add(TPath::Combine(ConfigurationSubKey, BannersKey));
  745. Result->Add(TPath::Combine(ConfigurationSubKey, LastFingerprintsStorageKey));
  746. return Result.release();
  747. }
  748. //---------------------------------------------------------------------------
  749. bool __fastcall TConfiguration::HasAnyCache()
  750. {
  751. bool Result = false;
  752. std::unique_ptr<TStrings> Caches(GetCaches());
  753. for (int Index = 0; Index < Caches->Count; Index++)
  754. {
  755. if (RegistryPathExists(Caches->Strings[Index]))
  756. {
  757. Result = true;
  758. break;
  759. }
  760. }
  761. return Result;
  762. }
  763. //---------------------------------------------------------------------------
  764. void __fastcall TConfiguration::CleanupCaches()
  765. {
  766. try
  767. {
  768. std::unique_ptr<TStrings> Caches(GetCaches());
  769. for (int Index = 0; Index < Caches->Count; Index++)
  770. {
  771. CleanupRegistry(Caches->Strings[Index]);
  772. }
  773. }
  774. catch (Exception & E)
  775. {
  776. throw ExtException(&E, LoadStr(CLEANUP_CACHES_ERROR));
  777. }
  778. }
  779. //---------------------------------------------------------------------------
  780. void __fastcall TConfiguration::CleanupRandomSeedFile()
  781. {
  782. try
  783. {
  784. DontSaveRandomSeed();
  785. if (FileExists(ApiPath(RandomSeedFileName)))
  786. {
  787. DeleteFileChecked(RandomSeedFileName);
  788. }
  789. }
  790. catch (Exception &E)
  791. {
  792. throw ExtException(&E, LoadStr(CLEANUP_SEEDFILE_ERROR));
  793. }
  794. }
  795. //---------------------------------------------------------------------------
  796. void __fastcall TConfiguration::CleanupIniFile()
  797. {
  798. try
  799. {
  800. if (FileExists(ApiPath(IniFileStorageNameForReading)))
  801. {
  802. DeleteFileChecked(IniFileStorageNameForReading);
  803. }
  804. if (Storage == stIniFile)
  805. {
  806. FDontSave = true;
  807. }
  808. }
  809. catch (Exception &E)
  810. {
  811. throw ExtException(&E, LoadStr(CLEANUP_INIFILE_ERROR));
  812. }
  813. }
  814. //---------------------------------------------------------------------------
  815. void __fastcall TConfiguration::DontSave()
  816. {
  817. FDontSave = true;
  818. }
  819. //---------------------------------------------------------------------------
  820. RawByteString __fastcall TConfiguration::EncryptPassword(UnicodeString Password, UnicodeString Key)
  821. {
  822. if (Password.IsEmpty())
  823. {
  824. return RawByteString();
  825. }
  826. else
  827. {
  828. return ::EncryptPassword(Password, Key);
  829. }
  830. }
  831. //---------------------------------------------------------------------------
  832. UnicodeString __fastcall TConfiguration::DecryptPassword(RawByteString Password, UnicodeString Key)
  833. {
  834. if (Password.IsEmpty())
  835. {
  836. return UnicodeString();
  837. }
  838. else
  839. {
  840. return ::DecryptPassword(Password, Key);
  841. }
  842. }
  843. //---------------------------------------------------------------------------
  844. RawByteString __fastcall TConfiguration::StronglyRecryptPassword(RawByteString Password, UnicodeString /*Key*/)
  845. {
  846. return Password;
  847. }
  848. //---------------------------------------------------------------------------
  849. TVSFixedFileInfo *__fastcall TConfiguration::GetFixedApplicationInfo()
  850. {
  851. return GetFixedFileInfo(ApplicationInfo);
  852. }
  853. //---------------------------------------------------------------------------
  854. int __fastcall TConfiguration::GetCompoundVersion()
  855. {
  856. TVSFixedFileInfo * FileInfo = FixedApplicationInfo;
  857. return CalculateCompoundVersion(
  858. HIWORD(FileInfo->dwFileVersionMS), LOWORD(FileInfo->dwFileVersionMS),
  859. HIWORD(FileInfo->dwFileVersionLS));
  860. }
  861. //---------------------------------------------------------------------------
  862. UnicodeString __fastcall TConfiguration::ModuleFileName()
  863. {
  864. return ParamStr(0);
  865. }
  866. //---------------------------------------------------------------------------
  867. void * __fastcall TConfiguration::GetFileApplicationInfo(const UnicodeString FileName)
  868. {
  869. void * Result;
  870. if (FileName.IsEmpty())
  871. {
  872. if (!FApplicationInfo)
  873. {
  874. FApplicationInfo = CreateFileInfo(ModuleFileName());
  875. }
  876. Result = FApplicationInfo;
  877. }
  878. else
  879. {
  880. Result = CreateFileInfo(FileName);
  881. }
  882. return Result;
  883. }
  884. //---------------------------------------------------------------------------
  885. void * __fastcall TConfiguration::GetApplicationInfo()
  886. {
  887. return GetFileApplicationInfo("");
  888. }
  889. //---------------------------------------------------------------------------
  890. UnicodeString __fastcall TConfiguration::GetFileProductName(const UnicodeString FileName)
  891. {
  892. return GetFileFileInfoString(L"ProductName", FileName);
  893. }
  894. //---------------------------------------------------------------------------
  895. UnicodeString __fastcall TConfiguration::GetFileCompanyName(const UnicodeString FileName)
  896. {
  897. // particularly in IDE build, company name is empty
  898. return GetFileFileInfoString(L"CompanyName", FileName, true);
  899. }
  900. //---------------------------------------------------------------------------
  901. UnicodeString __fastcall TConfiguration::GetProductName()
  902. {
  903. return GetFileProductName(L"");
  904. }
  905. //---------------------------------------------------------------------------
  906. UnicodeString __fastcall TConfiguration::GetCompanyName()
  907. {
  908. return GetFileCompanyName(L"");
  909. }
  910. //---------------------------------------------------------------------------
  911. UnicodeString __fastcall TConfiguration::GetFileProductVersion(const UnicodeString FileName)
  912. {
  913. return TrimVersion(GetFileFileInfoString(L"ProductVersion", FileName));
  914. }
  915. //---------------------------------------------------------------------------
  916. UnicodeString __fastcall TConfiguration::GetFileDescription(const UnicodeString & FileName)
  917. {
  918. return GetFileFileInfoString(L"FileDescription", FileName);
  919. }
  920. //---------------------------------------------------------------------------
  921. UnicodeString __fastcall TConfiguration::GetProductVersion()
  922. {
  923. return GetFileProductVersion(L"");
  924. }
  925. //---------------------------------------------------------------------------
  926. UnicodeString __fastcall TConfiguration::GetReleaseType()
  927. {
  928. return GetFileInfoString(L"ReleaseType");
  929. }
  930. //---------------------------------------------------------------------------
  931. bool __fastcall TConfiguration::GetIsUnofficial()
  932. {
  933. #ifdef BUILD_OFFICIAL
  934. return false;
  935. #else
  936. return true;
  937. #endif
  938. }
  939. //---------------------------------------------------------------------------
  940. UnicodeString __fastcall TConfiguration::GetVersionStr()
  941. {
  942. TGuard Guard(FCriticalSection);
  943. try
  944. {
  945. UnicodeString BuildStr;
  946. if (!IsUnofficial)
  947. {
  948. BuildStr = LoadStr(VERSION_BUILD);
  949. }
  950. else
  951. {
  952. #ifdef _DEBUG
  953. BuildStr = LoadStr(VERSION_DEBUG_BUILD);
  954. #else
  955. BuildStr = LoadStr(VERSION_DEV_BUILD);
  956. #endif
  957. }
  958. int Build = LOWORD(FixedApplicationInfo->dwFileVersionLS);
  959. if (Build > 0)
  960. {
  961. BuildStr += L" " + IntToStr(Build);
  962. }
  963. #ifndef BUILD_OFFICIAL
  964. UnicodeString BuildDate = __DATE__;
  965. UnicodeString MonthStr = CutToChar(BuildDate, L' ', true);
  966. int Month = ParseShortEngMonthName(MonthStr);
  967. int Day = StrToInt(CutToChar(BuildDate, L' ', true));
  968. int Year = StrToInt(Trim(BuildDate));
  969. UnicodeString DateStr = FORMAT(L"%d-%2.2d-%2.2d", (Year, Month, Day));
  970. AddToList(BuildStr, DateStr, L" ");
  971. #endif
  972. UnicodeString FullVersion = Version;
  973. UnicodeString AReleaseType = GetReleaseType();
  974. if (DebugAlwaysTrue(!AReleaseType.IsEmpty()) &&
  975. !SameText(AReleaseType, L"stable") &&
  976. !SameText(AReleaseType, L"development"))
  977. {
  978. FullVersion += L" " + AReleaseType;
  979. }
  980. UnicodeString Result = FMTLOAD(VERSION2, (FullVersion, BuildStr));
  981. #ifndef BUILD_OFFICIAL
  982. Result += L" " + LoadStr(VERSION_DONT_DISTRIBUTE);
  983. #endif
  984. return Result;
  985. }
  986. catch (Exception &E)
  987. {
  988. throw ExtException(&E, L"Can't get application version");
  989. }
  990. }
  991. //---------------------------------------------------------------------------
  992. UnicodeString __fastcall TConfiguration::GetFileVersion(const UnicodeString & FileName)
  993. {
  994. UnicodeString Result;
  995. void * FileInfo = CreateFileInfo(FileName);
  996. try
  997. {
  998. Result = GetFileVersion(GetFixedFileInfo(FileInfo));
  999. }
  1000. __finally
  1001. {
  1002. FreeFileInfo(FileInfo);
  1003. }
  1004. return Result;
  1005. }
  1006. //---------------------------------------------------------------------------
  1007. UnicodeString __fastcall TConfiguration::GetFileVersion(TVSFixedFileInfo * Info)
  1008. {
  1009. TGuard Guard(FCriticalSection);
  1010. try
  1011. {
  1012. UnicodeString Result =
  1013. FormatVersion(
  1014. HIWORD(Info->dwFileVersionMS),
  1015. LOWORD(Info->dwFileVersionMS),
  1016. HIWORD(Info->dwFileVersionLS));
  1017. return Result;
  1018. }
  1019. catch (Exception &E)
  1020. {
  1021. throw ExtException(&E, L"Can't get file version");
  1022. }
  1023. }
  1024. //---------------------------------------------------------------------------
  1025. UnicodeString __fastcall TConfiguration::GetVersion()
  1026. {
  1027. return GetFileVersion(FixedApplicationInfo);
  1028. }
  1029. //---------------------------------------------------------------------------
  1030. UnicodeString __fastcall TConfiguration::GetFileFileInfoString(const UnicodeString Key,
  1031. const UnicodeString FileName, bool AllowEmpty)
  1032. {
  1033. TGuard Guard(FCriticalSection);
  1034. UnicodeString Result;
  1035. void * Info = GetFileApplicationInfo(FileName);
  1036. try
  1037. {
  1038. if ((Info != NULL) && (GetTranslationCount(Info) > 0))
  1039. {
  1040. TTranslation Translation;
  1041. Translation = GetTranslation(Info, 0);
  1042. Result = ::GetFileInfoString(Info, Translation, Key, AllowEmpty);
  1043. }
  1044. else
  1045. {
  1046. DebugAssert(!FileName.IsEmpty());
  1047. }
  1048. }
  1049. __finally
  1050. {
  1051. if (!FileName.IsEmpty())
  1052. {
  1053. FreeFileInfo(Info);
  1054. }
  1055. }
  1056. return Result;
  1057. }
  1058. //---------------------------------------------------------------------------
  1059. UnicodeString __fastcall TConfiguration::GetFileInfoString(const UnicodeString Key)
  1060. {
  1061. return GetFileFileInfoString(Key, L"");
  1062. }
  1063. //---------------------------------------------------------------------------
  1064. UnicodeString __fastcall TConfiguration::GetFileMimeType(const UnicodeString & FileName)
  1065. {
  1066. UnicodeString Result;
  1067. bool Found = false;
  1068. if (!MimeTypes.IsEmpty())
  1069. {
  1070. UnicodeString FileNameOnly = ExtractFileName(FileName);
  1071. UnicodeString AMimeTypes = MimeTypes;
  1072. while (!Found && !AMimeTypes.IsEmpty())
  1073. {
  1074. UnicodeString Token = CutToChar(AMimeTypes, L',', true);
  1075. UnicodeString MaskStr = CutToChar(Token, L'=', true);
  1076. TFileMasks Mask(MaskStr);
  1077. if (Mask.Matches(FileNameOnly))
  1078. {
  1079. Result = Token.Trim();
  1080. Found = true;
  1081. }
  1082. }
  1083. }
  1084. if (!Found) // allow an override to "no" Content-Type
  1085. {
  1086. Result = ::GetFileMimeType(FileName);
  1087. }
  1088. return Result;
  1089. }
  1090. //---------------------------------------------------------------------------
  1091. UnicodeString __fastcall TConfiguration::GetRegistryStorageKey()
  1092. {
  1093. return GetRegistryKey();
  1094. }
  1095. //---------------------------------------------------------------------------
  1096. void __fastcall TConfiguration::SetNulStorage()
  1097. {
  1098. FStorage = stNul;
  1099. }
  1100. //---------------------------------------------------------------------------
  1101. void __fastcall TConfiguration::SetDefaultStorage()
  1102. {
  1103. FStorage = stDetect;
  1104. }
  1105. //---------------------------------------------------------------------------
  1106. void __fastcall TConfiguration::SetExplicitIniFileStorageName(const UnicodeString & FileName)
  1107. {
  1108. FIniFileStorageName = FileName;
  1109. FStorage = stIniFile;
  1110. }
  1111. //---------------------------------------------------------------------------
  1112. UnicodeString __fastcall TConfiguration::GetDefaultIniFileExportPath()
  1113. {
  1114. UnicodeString PersonalDirectory = GetPersonalFolder();
  1115. UnicodeString FileName = IncludeTrailingBackslash(PersonalDirectory) +
  1116. ExtractFileName(ExpandEnvironmentVariables(IniFileStorageName));
  1117. return FileName;
  1118. }
  1119. //---------------------------------------------------------------------------
  1120. UnicodeString __fastcall TConfiguration::GetIniFileStorageNameForReading()
  1121. {
  1122. return GetIniFileStorageName(true);
  1123. }
  1124. //---------------------------------------------------------------------------
  1125. UnicodeString __fastcall TConfiguration::GetIniFileStorageNameForReadingWriting()
  1126. {
  1127. return GetIniFileStorageName(false);
  1128. }
  1129. //---------------------------------------------------------------------------
  1130. UnicodeString __fastcall TConfiguration::GetAutomaticIniFileStorageName(bool ReadingOnly)
  1131. {
  1132. UnicodeString ProgramPath = ParamStr(0);
  1133. UnicodeString ProgramIniPath = ChangeFileExt(ProgramPath, L".ini");
  1134. UnicodeString IniPath;
  1135. if (FileExists(ApiPath(ProgramIniPath)))
  1136. {
  1137. IniPath = ProgramIniPath;
  1138. }
  1139. else
  1140. {
  1141. UnicodeString AppDataIniPath =
  1142. IncludeTrailingBackslash(GetShellFolderPath(CSIDL_APPDATA)) +
  1143. ExtractFileName(ProgramIniPath);
  1144. if (FileExists(ApiPath(AppDataIniPath)))
  1145. {
  1146. IniPath = AppDataIniPath;
  1147. }
  1148. else
  1149. {
  1150. // avoid expensive test if we are interested in existing files only
  1151. if (!ReadingOnly && (FProgramIniPathWrittable < 0))
  1152. {
  1153. UnicodeString ProgramDir = ExtractFilePath(ProgramPath);
  1154. FProgramIniPathWrittable = IsDirectoryWriteable(ProgramDir) ? 1 : 0;
  1155. }
  1156. // does not really matter what we return when < 0
  1157. IniPath = (FProgramIniPathWrittable == 0) ? AppDataIniPath : ProgramIniPath;
  1158. }
  1159. }
  1160. // BACKWARD COMPATIBILITY with 4.x
  1161. if (FVirtualIniFileStorageName.IsEmpty() &&
  1162. TPath::IsDriveRooted(IniPath))
  1163. {
  1164. UnicodeString LocalAppDataPath = GetShellFolderPath(CSIDL_LOCAL_APPDATA);
  1165. // virtual store for non-system drives have a different virtual store,
  1166. // do not bother about them
  1167. if (TPath::IsDriveRooted(LocalAppDataPath) &&
  1168. SameText(ExtractFileDrive(IniPath), ExtractFileDrive(LocalAppDataPath)))
  1169. {
  1170. FVirtualIniFileStorageName =
  1171. IncludeTrailingBackslash(LocalAppDataPath) +
  1172. L"VirtualStore\\" +
  1173. IniPath.SubString(4, IniPath.Length() - 3);
  1174. }
  1175. }
  1176. if (!FVirtualIniFileStorageName.IsEmpty() &&
  1177. FileExists(ApiPath(FVirtualIniFileStorageName)))
  1178. {
  1179. return FVirtualIniFileStorageName;
  1180. }
  1181. else
  1182. {
  1183. return IniPath;
  1184. }
  1185. }
  1186. //---------------------------------------------------------------------------
  1187. UnicodeString __fastcall TConfiguration::GetIniFileParamValue()
  1188. {
  1189. UnicodeString Result;
  1190. if (Storage == stNul)
  1191. {
  1192. Result = INI_NUL;
  1193. }
  1194. else if ((Storage == stIniFile) && !FIniFileStorageName.IsEmpty())
  1195. {
  1196. Result = FIniFileStorageName;
  1197. }
  1198. return Result;
  1199. }
  1200. //---------------------------------------------------------------------------
  1201. UnicodeString __fastcall TConfiguration::GetIniFileStorageName(bool ReadingOnly)
  1202. {
  1203. UnicodeString Result;
  1204. if (!FIniFileStorageName.IsEmpty())
  1205. {
  1206. Result = FIniFileStorageName;
  1207. }
  1208. else if (!FCustomIniFileStorageName.IsEmpty())
  1209. {
  1210. Result = FCustomIniFileStorageName;
  1211. }
  1212. else
  1213. {
  1214. Result = GetAutomaticIniFileStorageName(ReadingOnly);
  1215. }
  1216. return Result;
  1217. }
  1218. //---------------------------------------------------------------------------
  1219. void __fastcall TConfiguration::SetOptionsStorage(TStrings * value)
  1220. {
  1221. TGuard Guard(FCriticalSection);
  1222. if (FOptionsStorage.get() == NULL)
  1223. {
  1224. FOptionsStorage.reset(new TStringList());
  1225. }
  1226. FOptionsStorage->AddStrings(value);
  1227. }
  1228. //---------------------------------------------------------------------------
  1229. TStrings * __fastcall TConfiguration::GetOptionsStorage()
  1230. {
  1231. return FOptionsStorage.get();
  1232. }
  1233. //---------------------------------------------------------------------------
  1234. UnicodeString __fastcall TConfiguration::GetPuttySessionsSubKey()
  1235. {
  1236. return StoredSessionsSubKey;
  1237. }
  1238. //---------------------------------------------------------------------------
  1239. UnicodeString __fastcall TConfiguration::GetPuttySessionsKey()
  1240. {
  1241. return PuttyRegistryStorageKey + L"\\" + PuttySessionsSubKey;
  1242. }
  1243. //---------------------------------------------------------------------------
  1244. UnicodeString __fastcall TConfiguration::GetStoredSessionsSubKey()
  1245. {
  1246. return L"Sessions";
  1247. }
  1248. //---------------------------------------------------------------------------
  1249. UnicodeString __fastcall TConfiguration::GetSshHostKeysSubKey()
  1250. {
  1251. return L"SshHostKeys";
  1252. }
  1253. //---------------------------------------------------------------------------
  1254. UnicodeString __fastcall TConfiguration::GetConfigurationSubKey()
  1255. {
  1256. return L"Configuration";
  1257. }
  1258. //---------------------------------------------------------------------------
  1259. UnicodeString __fastcall TConfiguration::GetRootKeyStr()
  1260. {
  1261. return RootKeyToStr(HKEY_CURRENT_USER);
  1262. }
  1263. //---------------------------------------------------------------------------
  1264. void __fastcall TConfiguration::MoveStorage(TStorage AStorage, const UnicodeString & ACustomIniFileStorageName)
  1265. {
  1266. if ((FStorage != AStorage) ||
  1267. ((FStorage == stIniFile) && !FIniFileStorageName.IsEmpty()) ||
  1268. !IsPathToSameFile(FCustomIniFileStorageName, ACustomIniFileStorageName))
  1269. {
  1270. TStorage StorageBak = FStorage;
  1271. UnicodeString CustomIniFileStorageNameBak = FCustomIniFileStorageName;
  1272. UnicodeString IniFileStorageNameBak = FIniFileStorageName;
  1273. try
  1274. {
  1275. THierarchicalStorage * SourceStorage = NULL;
  1276. THierarchicalStorage * TargetStorage = NULL;
  1277. try
  1278. {
  1279. SourceStorage = CreateConfigStorage();
  1280. SourceStorage->AccessMode = smRead;
  1281. FStorage = AStorage;
  1282. FCustomIniFileStorageName = ACustomIniFileStorageName;
  1283. FIniFileStorageName = UnicodeString();
  1284. TargetStorage = CreateConfigStorage();
  1285. TargetStorage->AccessMode = smReadWrite;
  1286. TargetStorage->Explicit = true;
  1287. // copy before save as it removes the ini file,
  1288. // when switching from ini to registry
  1289. CopyData(SourceStorage, TargetStorage);
  1290. }
  1291. __finally
  1292. {
  1293. delete SourceStorage;
  1294. delete TargetStorage;
  1295. }
  1296. // save all and explicit,
  1297. // this also removes an INI file, when switching to registry storage
  1298. DoSave(true, true);
  1299. }
  1300. catch (...)
  1301. {
  1302. // If this fails, do not pretend that storage was switched.
  1303. // For instance:
  1304. // - When writing to an INI file fails (unlikely, as we fallback to user profile)
  1305. // - When removing INI file fails, when switching to registry
  1306. // (possible, when the INI file is in Program Files folder)
  1307. FStorage = StorageBak;
  1308. FCustomIniFileStorageName = CustomIniFileStorageNameBak;
  1309. FIniFileStorageName = IniFileStorageNameBak;
  1310. throw;
  1311. }
  1312. }
  1313. }
  1314. //---------------------------------------------------------------------------
  1315. void __fastcall TConfiguration::ScheduleCustomIniFileStorageUse(const UnicodeString & ACustomIniFileStorageName)
  1316. {
  1317. FStorage = stIniFile;
  1318. FCustomIniFileStorageName = ACustomIniFileStorageName;
  1319. SaveCustomIniFileStorageName();
  1320. }
  1321. //---------------------------------------------------------------------------
  1322. void __fastcall TConfiguration::Saved()
  1323. {
  1324. // nothing
  1325. }
  1326. //---------------------------------------------------------------------------
  1327. TStorage __fastcall TConfiguration::GetStorage()
  1328. {
  1329. TGuard Guard(FCriticalSection);
  1330. if (FStorage == stDetect)
  1331. {
  1332. if (FileExists(ApiPath(IniFileStorageNameForReading)))
  1333. {
  1334. FStorage = stIniFile;
  1335. }
  1336. else
  1337. {
  1338. FStorage = stRegistry;
  1339. }
  1340. }
  1341. return FStorage;
  1342. }
  1343. //---------------------------------------------------------------------
  1344. TStoredSessionList * __fastcall TConfiguration::SelectFilezillaSessionsForImport(
  1345. TStoredSessionList * Sessions, UnicodeString & Error)
  1346. {
  1347. std::unique_ptr<TStoredSessionList> ImportSessionList(new TStoredSessionList(true));
  1348. ImportSessionList->DefaultSettings = Sessions->DefaultSettings;
  1349. UnicodeString AppDataPath = GetShellFolderPath(CSIDL_APPDATA);
  1350. UnicodeString FilezillaSiteManagerFile =
  1351. IncludeTrailingBackslash(AppDataPath) + L"FileZilla\\sitemanager.xml";
  1352. UnicodeString FilezillaConfigurationFile =
  1353. IncludeTrailingBackslash(AppDataPath) + L"FileZilla\\filezilla.xml";
  1354. if (FileExists(ApiPath(FilezillaSiteManagerFile)))
  1355. {
  1356. ImportSessionList->ImportFromFilezilla(FilezillaSiteManagerFile, FilezillaConfigurationFile);
  1357. if (ImportSessionList->Count > 0)
  1358. {
  1359. ImportSessionList->SelectSessionsToImport(Sessions, true);
  1360. }
  1361. else
  1362. {
  1363. Error = FMTLOAD(FILEZILLA_NO_SITES, (FilezillaSiteManagerFile));
  1364. }
  1365. }
  1366. else
  1367. {
  1368. Error = FMTLOAD(FILEZILLA_SITE_MANAGER_NOT_FOUND, (FilezillaSiteManagerFile));
  1369. }
  1370. return ImportSessionList.release();
  1371. }
  1372. //---------------------------------------------------------------------
  1373. bool __fastcall TConfiguration::AnyFilezillaSessionForImport(TStoredSessionList * Sessions)
  1374. {
  1375. try
  1376. {
  1377. UnicodeString Error;
  1378. std::unique_ptr<TStoredSessionList> Sesssions(SelectFilezillaSessionsForImport(Sessions, Error));
  1379. return (Sesssions->Count > 0);
  1380. }
  1381. catch (...)
  1382. {
  1383. return false;
  1384. }
  1385. }
  1386. //---------------------------------------------------------------------
  1387. TStoredSessionList * __fastcall TConfiguration::SelectKnownHostsSessionsForImport(
  1388. TStoredSessionList * Sessions, UnicodeString & Error)
  1389. {
  1390. std::unique_ptr<TStoredSessionList> ImportSessionList(new TStoredSessionList(true));
  1391. ImportSessionList->DefaultSettings = Sessions->DefaultSettings;
  1392. UnicodeString ProfilePath = GetShellFolderPath(CSIDL_PROFILE);
  1393. UnicodeString KnownHostsFile = IncludeTrailingBackslash(ProfilePath) + L".ssh\\known_hosts";
  1394. try
  1395. {
  1396. if (FileExists(ApiPath(KnownHostsFile)))
  1397. {
  1398. std::unique_ptr<TStrings> Lines(new TStringList());
  1399. LoadScriptFromFile(KnownHostsFile, Lines.get(), true);
  1400. ImportSessionList->ImportFromKnownHosts(Lines.get());
  1401. }
  1402. else
  1403. {
  1404. throw Exception(LoadStr(KNOWN_HOSTS_NOT_FOUND));
  1405. }
  1406. }
  1407. catch (Exception & E)
  1408. {
  1409. Error = FORMAT(L"%s\n(%s)", (E.Message, KnownHostsFile));
  1410. }
  1411. return ImportSessionList.release();
  1412. }
  1413. //---------------------------------------------------------------------
  1414. TStoredSessionList * __fastcall TConfiguration::SelectKnownHostsSessionsForImport(
  1415. TStrings * Lines, TStoredSessionList * Sessions, UnicodeString & Error)
  1416. {
  1417. std::unique_ptr<TStoredSessionList> ImportSessionList(new TStoredSessionList(true));
  1418. ImportSessionList->DefaultSettings = Sessions->DefaultSettings;
  1419. try
  1420. {
  1421. ImportSessionList->ImportFromKnownHosts(Lines);
  1422. }
  1423. catch (Exception & E)
  1424. {
  1425. Error = E.Message;
  1426. }
  1427. return ImportSessionList.release();
  1428. }
  1429. //---------------------------------------------------------------------------
  1430. void __fastcall TConfiguration::SetRandomSeedFile(UnicodeString value)
  1431. {
  1432. if (RandomSeedFile != value)
  1433. {
  1434. UnicodeString PrevRandomSeedFileName = RandomSeedFileName;
  1435. FRandomSeedFile = value;
  1436. // never allow empty seed file to avoid Putty trying to reinitialize the path
  1437. if (RandomSeedFileName.IsEmpty())
  1438. {
  1439. FRandomSeedFile = FDefaultRandomSeedFile;
  1440. }
  1441. if (!PrevRandomSeedFileName.IsEmpty() &&
  1442. (PrevRandomSeedFileName != RandomSeedFileName) &&
  1443. FileExists(ApiPath(PrevRandomSeedFileName)))
  1444. {
  1445. // ignore any error
  1446. DeleteFile(ApiPath(PrevRandomSeedFileName));
  1447. }
  1448. }
  1449. }
  1450. //---------------------------------------------------------------------------
  1451. UnicodeString __fastcall TConfiguration::GetDirectoryStatisticsCacheKey(
  1452. const UnicodeString & SessionKey, const UnicodeString & Path, const TCopyParamType & CopyParam)
  1453. {
  1454. std::unique_ptr<TStringList> RawOptions(new TStringList());
  1455. RawOptions->Add(SessionKey);
  1456. RawOptions->Add(UnixExcludeTrailingBackslash(Path));
  1457. TCopyParamType Defaults;
  1458. TCopyParamType FilterCopyParam;
  1459. FilterCopyParam.IncludeFileMask = CopyParam.IncludeFileMask;
  1460. FilterCopyParam.ExcludeHiddenFiles = CopyParam.ExcludeHiddenFiles;
  1461. FilterCopyParam.ExcludeEmptyDirectories = CopyParam.ExcludeEmptyDirectories;
  1462. std::unique_ptr<TOptionsStorage> OptionsStorage(new TOptionsStorage(RawOptions.get(), true));
  1463. FilterCopyParam.Save(OptionsStorage.get(), &Defaults);
  1464. UTF8String RawOptionsBuf(RawOptions->CommaText.LowerCase());
  1465. UnicodeString Result = Sha256(RawOptionsBuf.c_str(), RawOptionsBuf.Length());
  1466. return Result;
  1467. }
  1468. //---------------------------------------------------------------------------
  1469. THierarchicalStorage * TConfiguration::OpenDirectoryStatisticsCache(bool CanCreate)
  1470. {
  1471. std::unique_ptr<THierarchicalStorage> Storage(Configuration->CreateConfigStorage());
  1472. Storage->AccessMode = CanCreate ? smReadWrite : smRead;
  1473. if (!Storage->OpenSubKey(DirectoryStatisticsCacheKey, CanCreate))
  1474. {
  1475. Storage.reset(NULL);
  1476. }
  1477. return Storage.release();
  1478. }
  1479. //---------------------------------------------------------------------------
  1480. TStrings * __fastcall TConfiguration::LoadDirectoryStatisticsCache(
  1481. const UnicodeString & SessionKey, const UnicodeString & Path, const TCopyParamType & CopyParam)
  1482. {
  1483. std::unique_ptr<THierarchicalStorage> Storage(OpenDirectoryStatisticsCache(false));
  1484. std::unique_ptr<TStringList> Result(new TStringList());
  1485. if (Storage.get() != NULL)
  1486. {
  1487. UnicodeString Key = GetDirectoryStatisticsCacheKey(SessionKey, Path, CopyParam);
  1488. UnicodeString Buf = Storage->ReadString(Key, UnicodeString());
  1489. Result->CommaText = Buf;
  1490. }
  1491. return Result.release();
  1492. }
  1493. //---------------------------------------------------------------------------
  1494. void __fastcall TConfiguration::SaveDirectoryStatisticsCache(
  1495. const UnicodeString & SessionKey, const UnicodeString & Path, const TCopyParamType & CopyParam, TStrings * DataList)
  1496. {
  1497. std::unique_ptr<THierarchicalStorage> Storage(OpenDirectoryStatisticsCache(true));
  1498. if (Storage.get() != NULL)
  1499. {
  1500. UnicodeString Key = GetDirectoryStatisticsCacheKey(SessionKey, Path, CopyParam);
  1501. UnicodeString Buf = DataList->CommaText;
  1502. Storage->WriteString(Key, Buf);
  1503. }
  1504. }
  1505. //---------------------------------------------------------------------
  1506. UnicodeString __fastcall TConfiguration::GetRandomSeedFileName()
  1507. {
  1508. // StripPathQuotes should not be needed as we do not feed quotes anymore
  1509. return StripPathQuotes(ExpandEnvironmentVariables(FRandomSeedFile)).Trim();
  1510. }
  1511. //---------------------------------------------------------------------
  1512. void __fastcall TConfiguration::SetExternalIpAddress(UnicodeString value)
  1513. {
  1514. SET_CONFIG_PROPERTY(ExternalIpAddress);
  1515. }
  1516. //---------------------------------------------------------------------
  1517. void __fastcall TConfiguration::SetMimeTypes(UnicodeString value)
  1518. {
  1519. SET_CONFIG_PROPERTY(MimeTypes);
  1520. }
  1521. //---------------------------------------------------------------------
  1522. void __fastcall TConfiguration::SetTryFtpWhenSshFails(bool value)
  1523. {
  1524. SET_CONFIG_PROPERTY(TryFtpWhenSshFails);
  1525. }
  1526. //---------------------------------------------------------------------
  1527. void __fastcall TConfiguration::SetParallelDurationThreshold(int value)
  1528. {
  1529. SET_CONFIG_PROPERTY(ParallelDurationThreshold);
  1530. }
  1531. //---------------------------------------------------------------------
  1532. void __fastcall TConfiguration::SetPuttyRegistryStorageKey(UnicodeString value)
  1533. {
  1534. SET_CONFIG_PROPERTY(PuttyRegistryStorageKey);
  1535. }
  1536. //---------------------------------------------------------------------------
  1537. TEOLType __fastcall TConfiguration::GetLocalEOLType()
  1538. {
  1539. return eolCRLF;
  1540. }
  1541. //---------------------------------------------------------------------
  1542. bool __fastcall TConfiguration::GetCollectUsage()
  1543. {
  1544. return FUsage->Collect;
  1545. }
  1546. //---------------------------------------------------------------------
  1547. void __fastcall TConfiguration::SetCollectUsage(bool value)
  1548. {
  1549. FUsage->Collect = value;
  1550. }
  1551. //---------------------------------------------------------------------
  1552. void __fastcall TConfiguration::TemporaryLogging(const UnicodeString ALogFileName)
  1553. {
  1554. if (SameText(ExtractFileExt(ALogFileName), L".xml"))
  1555. {
  1556. TemporaryActionsLogging(ALogFileName);
  1557. }
  1558. else
  1559. {
  1560. FLogging = true;
  1561. FLogFileName = ALogFileName;
  1562. UpdateActualLogProtocol();
  1563. }
  1564. }
  1565. //---------------------------------------------------------------------
  1566. void __fastcall TConfiguration::TemporaryActionsLogging(const UnicodeString ALogFileName)
  1567. {
  1568. FLogActions = true;
  1569. FActionsLogFileName = ALogFileName;
  1570. }
  1571. //---------------------------------------------------------------------
  1572. void __fastcall TConfiguration::TemporaryLogProtocol(int ALogProtocol)
  1573. {
  1574. FLogProtocol = ALogProtocol;
  1575. UpdateActualLogProtocol();
  1576. }
  1577. //---------------------------------------------------------------------
  1578. void __fastcall TConfiguration::TemporaryLogSensitive(bool ALogSensitive)
  1579. {
  1580. FLogSensitive = ALogSensitive;
  1581. }
  1582. //---------------------------------------------------------------------
  1583. void __fastcall TConfiguration::TemporaryLogMaxSize(__int64 ALogMaxSize)
  1584. {
  1585. FLogMaxSize = ALogMaxSize;
  1586. }
  1587. //---------------------------------------------------------------------
  1588. void __fastcall TConfiguration::TemporaryLogMaxCount(int ALogMaxCount)
  1589. {
  1590. FLogMaxCount = ALogMaxCount;
  1591. }
  1592. //---------------------------------------------------------------------
  1593. void __fastcall TConfiguration::SetLogging(bool value)
  1594. {
  1595. TGuard Guard(FCriticalSection);
  1596. if (Logging != value)
  1597. {
  1598. FPermanentLogging = value;
  1599. FLogging = value;
  1600. UpdateActualLogProtocol();
  1601. Changed();
  1602. }
  1603. }
  1604. //---------------------------------------------------------------------
  1605. bool __fastcall TConfiguration::GetLogging()
  1606. {
  1607. TGuard Guard(FCriticalSection);
  1608. return FPermanentLogging;
  1609. }
  1610. //---------------------------------------------------------------------
  1611. void __fastcall TConfiguration::SetLogFileName(UnicodeString value)
  1612. {
  1613. TGuard Guard(FCriticalSection);
  1614. if (LogFileName != value)
  1615. {
  1616. FPermanentLogFileName = value;
  1617. FLogFileName = value;
  1618. Changed();
  1619. }
  1620. }
  1621. //---------------------------------------------------------------------
  1622. UnicodeString __fastcall TConfiguration::GetLogFileName()
  1623. {
  1624. TGuard Guard(FCriticalSection);
  1625. return FPermanentLogFileName;
  1626. }
  1627. //---------------------------------------------------------------------
  1628. void __fastcall TConfiguration::SetActionsLogFileName(UnicodeString value)
  1629. {
  1630. TGuard Guard(FCriticalSection);
  1631. if (ActionsLogFileName != value)
  1632. {
  1633. FPermanentActionsLogFileName = value;
  1634. FActionsLogFileName = value;
  1635. Changed();
  1636. }
  1637. }
  1638. //---------------------------------------------------------------------
  1639. UnicodeString __fastcall TConfiguration::GetPermanentActionsLogFileName()
  1640. {
  1641. TGuard Guard(FCriticalSection);
  1642. return FPermanentActionsLogFileName;
  1643. }
  1644. //---------------------------------------------------------------------
  1645. UnicodeString __fastcall TConfiguration::GetActionsLogFileName()
  1646. {
  1647. TGuard Guard(FCriticalSection);
  1648. return FActionsLogFileName;
  1649. }
  1650. //---------------------------------------------------------------------
  1651. bool __fastcall TConfiguration::GetLogToFile()
  1652. {
  1653. // guarded within GetLogFileName
  1654. return !LogFileName.IsEmpty();
  1655. }
  1656. //---------------------------------------------------------------------
  1657. void __fastcall TConfiguration::UpdateActualLogProtocol()
  1658. {
  1659. FActualLogProtocol = FLogging ? FLogProtocol : (-BelowNormalLogLevels - 1);
  1660. }
  1661. //---------------------------------------------------------------------
  1662. void __fastcall TConfiguration::SetLogProtocol(int value)
  1663. {
  1664. TGuard Guard(FCriticalSection);
  1665. if (LogProtocol != value)
  1666. {
  1667. FPermanentLogProtocol = value;
  1668. FLogProtocol = value;
  1669. Changed();
  1670. UpdateActualLogProtocol();
  1671. }
  1672. }
  1673. //---------------------------------------------------------------------
  1674. void __fastcall TConfiguration::SetLogActions(bool value)
  1675. {
  1676. TGuard Guard(FCriticalSection);
  1677. if (LogActions != value)
  1678. {
  1679. FPermanentLogActions = value;
  1680. FLogActions = value;
  1681. Changed();
  1682. }
  1683. }
  1684. //---------------------------------------------------------------------
  1685. bool __fastcall TConfiguration::GetLogActions()
  1686. {
  1687. TGuard Guard(FCriticalSection);
  1688. return FPermanentLogActions;
  1689. }
  1690. //---------------------------------------------------------------------
  1691. void __fastcall TConfiguration::SetLogFileAppend(bool value)
  1692. {
  1693. SET_CONFIG_PROPERTY(LogFileAppend);
  1694. }
  1695. //---------------------------------------------------------------------
  1696. void __fastcall TConfiguration::SetLogSensitive(bool value)
  1697. {
  1698. if (LogSensitive != value)
  1699. {
  1700. FPermanentLogSensitive = value;
  1701. FLogSensitive = value;
  1702. Changed();
  1703. }
  1704. }
  1705. //---------------------------------------------------------------------
  1706. void __fastcall TConfiguration::SetLogMaxSize(__int64 value)
  1707. {
  1708. TGuard Guard(FCriticalSection);
  1709. if (LogMaxSize != value)
  1710. {
  1711. FPermanentLogMaxSize = value;
  1712. FLogMaxSize = value;
  1713. Changed();
  1714. }
  1715. }
  1716. //---------------------------------------------------------------------
  1717. __int64 __fastcall TConfiguration::GetLogMaxSize()
  1718. {
  1719. TGuard Guard(FCriticalSection);
  1720. return FPermanentLogMaxSize;
  1721. }
  1722. //---------------------------------------------------------------------
  1723. void __fastcall TConfiguration::SetLogMaxCount(int value)
  1724. {
  1725. if (LogMaxCount != value)
  1726. {
  1727. FPermanentLogMaxCount = value;
  1728. FLogMaxCount = value;
  1729. Changed();
  1730. }
  1731. }
  1732. //---------------------------------------------------------------------
  1733. int __fastcall TConfiguration::GetLogMaxCount()
  1734. {
  1735. TGuard Guard(FCriticalSection);
  1736. return FPermanentLogMaxCount;
  1737. }
  1738. //---------------------------------------------------------------------
  1739. UnicodeString __fastcall TConfiguration::GetDefaultLogFileName()
  1740. {
  1741. return L"%TEMP%\\!S.log";
  1742. }
  1743. //---------------------------------------------------------------------------
  1744. void __fastcall TConfiguration::SetConfirmOverwriting(bool value)
  1745. {
  1746. TGuard Guard(FCriticalSection);
  1747. SET_CONFIG_PROPERTY(ConfirmOverwriting);
  1748. }
  1749. //---------------------------------------------------------------------------
  1750. bool __fastcall TConfiguration::GetConfirmOverwriting()
  1751. {
  1752. TGuard Guard(FCriticalSection);
  1753. return FConfirmOverwriting;
  1754. }
  1755. //---------------------------------------------------------------------------
  1756. void __fastcall TConfiguration::SetConfirmResume(bool value)
  1757. {
  1758. TGuard Guard(FCriticalSection);
  1759. SET_CONFIG_PROPERTY(ConfirmResume);
  1760. }
  1761. //---------------------------------------------------------------------------
  1762. bool __fastcall TConfiguration::GetConfirmResume()
  1763. {
  1764. TGuard Guard(FCriticalSection);
  1765. return FConfirmResume;
  1766. }
  1767. //---------------------------------------------------------------------------
  1768. void __fastcall TConfiguration::SetAutoReadDirectoryAfterOp(bool value)
  1769. {
  1770. TGuard Guard(FCriticalSection);
  1771. SET_CONFIG_PROPERTY(AutoReadDirectoryAfterOp);
  1772. }
  1773. //---------------------------------------------------------------------------
  1774. bool __fastcall TConfiguration::GetAutoReadDirectoryAfterOp()
  1775. {
  1776. TGuard Guard(FCriticalSection);
  1777. return FAutoReadDirectoryAfterOp;
  1778. }
  1779. //---------------------------------------------------------------------------
  1780. UnicodeString __fastcall TConfiguration::GetTimeFormat()
  1781. {
  1782. return L"h:nn:ss";
  1783. }
  1784. //---------------------------------------------------------------------------
  1785. UnicodeString __fastcall TConfiguration::GetPartialExt() const
  1786. {
  1787. return PARTIAL_EXT;
  1788. }
  1789. //---------------------------------------------------------------------------
  1790. UnicodeString __fastcall TConfiguration::GetDefaultKeyFile()
  1791. {
  1792. return L"";
  1793. }
  1794. //---------------------------------------------------------------------------
  1795. bool __fastcall TConfiguration::GetRememberPassword()
  1796. {
  1797. return false;
  1798. }
  1799. //---------------------------------------------------------------------------
  1800. void __fastcall TConfiguration::SetSessionReopenAuto(int value)
  1801. {
  1802. SET_CONFIG_PROPERTY(SessionReopenAuto);
  1803. }
  1804. //---------------------------------------------------------------------------
  1805. void __fastcall TConfiguration::SetSessionReopenBackground(int value)
  1806. {
  1807. SET_CONFIG_PROPERTY(SessionReopenBackground);
  1808. }
  1809. //---------------------------------------------------------------------------
  1810. void __fastcall TConfiguration::SetSessionReopenTimeout(int value)
  1811. {
  1812. SET_CONFIG_PROPERTY(SessionReopenTimeout);
  1813. }
  1814. //---------------------------------------------------------------------------
  1815. void __fastcall TConfiguration::SetSessionReopenAutoStall(int value)
  1816. {
  1817. SET_CONFIG_PROPERTY(SessionReopenAutoStall);
  1818. }
  1819. //---------------------------------------------------------------------------
  1820. void __fastcall TConfiguration::SetTunnelLocalPortNumberLow(int value)
  1821. {
  1822. SET_CONFIG_PROPERTY(TunnelLocalPortNumberLow);
  1823. }
  1824. //---------------------------------------------------------------------------
  1825. void __fastcall TConfiguration::SetTunnelLocalPortNumberHigh(int value)
  1826. {
  1827. SET_CONFIG_PROPERTY(TunnelLocalPortNumberHigh);
  1828. }
  1829. //---------------------------------------------------------------------------
  1830. void __fastcall TConfiguration::SetCacheDirectoryChangesMaxSize(int value)
  1831. {
  1832. SET_CONFIG_PROPERTY(CacheDirectoryChangesMaxSize);
  1833. }
  1834. //---------------------------------------------------------------------------
  1835. void __fastcall TConfiguration::SetShowFtpWelcomeMessage(bool value)
  1836. {
  1837. SET_CONFIG_PROPERTY(ShowFtpWelcomeMessage);
  1838. }
  1839. //---------------------------------------------------------------------------
  1840. bool __fastcall TConfiguration::GetPersistent()
  1841. {
  1842. return (Storage != stNul) && !FDontSave;
  1843. }
  1844. //---------------------------------------------------------------------------
  1845. //---------------------------------------------------------------------------
  1846. void __fastcall TShortCuts::Add(TShortCut ShortCut)
  1847. {
  1848. FShortCuts.insert(ShortCut);
  1849. }
  1850. //---------------------------------------------------------------------------
  1851. bool __fastcall TShortCuts::Has(TShortCut ShortCut) const
  1852. {
  1853. return (FShortCuts.count(ShortCut) != 0);
  1854. }