Configuration.cpp 79 KB

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