//--------------------------------------------------------------------------- void __fastcall TConfiguration::Export(const UnicodeString & FileName) { THierarchicalStorage * Storage = NULL; THierarchicalStorage * ExportStorage = NULL; try { ExportStorage = new TIniFileStorage(FileName); ExportStorage->AccessMode = smReadWrite; ExportStorage->Explicit = true; Storage = CreateScpStorage(false); Storage->AccessMode = smRead; CopyData(Storage, ExportStorage); if (ExportStorage->OpenSubKey(ConfigurationSubKey, true)) { SaveData(ExportStorage, true); } } __finally { delete ExportStorage; delete Storage; } StoredSessions->Export(FileName); }
//--------------------------------------------------------------------------- void __fastcall TConfiguration::Import(const UnicodeString & FileName) { THierarchicalStorage * Storage = NULL; THierarchicalStorage * ImportStorage = NULL; try { ImportStorage = new TIniFileStorage(FileName); ImportStorage->AccessMode = smRead; Storage = CreateScpStorage(false); Storage->AccessMode = smReadWrite; Storage->Explicit = true; CopyData(ImportStorage, Storage); Default(); LoadFrom(ImportStorage); if (ImportStorage->OpenSubKey(Configuration->StoredSessionsSubKey, false)) { StoredSessions->Clear(); StoredSessions->DefaultSettings->Default(); StoredSessions->Load(ImportStorage); } } __finally { delete ImportStorage; delete Storage; } // save all and explicit DoSave(true, true); }
//--------------------------------------------------------------------------- void __fastcall TConfiguration::DoSave(bool All, bool Explicit) { if (FDontSave) return; THierarchicalStorage * AStorage = CreateScpStorage(false); try { AStorage->AccessMode = smReadWrite; AStorage->Explicit = Explicit; if (AStorage->OpenSubKey(ConfigurationSubKey, true)) { SaveData(AStorage, All); } } __finally { delete AStorage; } Saved(); if (All) { StoredSessions->Save(true, Explicit); } // clean up as last, so that if it fails (read only INI), the saving can proceed if (Storage == stRegistry) { CleanupIniFile(); } }
long reg_query_winscp_value_ex(HKEY Key, const char * ValueName, unsigned long * /*Reserved*/, unsigned long * Type, uint8_t * Data, unsigned long * DataSize) { long R; DebugAssert(GetConfiguration() != nullptr); THierarchicalStorage * Storage = reinterpret_cast<THierarchicalStorage *>(Key); AnsiString Value; if (Storage == nullptr) { if (UnicodeString(ValueName) == L"RandSeedFile") { Value = AnsiString(GetConfiguration()->GetRandomSeedFileName()); R = ERROR_SUCCESS; } else { DebugFail(); R = ERROR_READ_FAULT; } } else { if (Storage->ValueExists(ValueName)) { Value = AnsiString(Storage->ReadStringRaw(ValueName, L"")); R = ERROR_SUCCESS; } else { R = ERROR_READ_FAULT; } } if (R == ERROR_SUCCESS) { DebugAssert(Type != nullptr); *Type = REG_SZ; char * DataStr = reinterpret_cast<char *>(Data); int sz = static_cast<int>(*DataSize); if (sz > 0) { strncpy(DataStr, Value.c_str(), sz); DataStr[sz - 1] = '\0'; } *DataSize = static_cast<uint32_t>(strlen(DataStr)); } return R; }
long reg_set_winscp_value_ex(HKEY Key, const char * ValueName, unsigned long /*Reserved*/, unsigned long Type, const uint8_t * Data, unsigned long DataSize) { assert(Type == REG_SZ); USEDPARAM(Type); THierarchicalStorage * Storage = reinterpret_cast<THierarchicalStorage *>(Key); assert(Storage != nullptr); if (Storage != nullptr) { UnicodeString Value(reinterpret_cast<const char *>(Data), DataSize - 1); Storage->WriteStringRaw(ValueName, Value); } return ERROR_SUCCESS; }
//--------------------------------------------------------------------------- long reg_query_winscp_value_ex(HKEY Key, const char * ValueName, unsigned long * /*Reserved*/, unsigned long * Type, unsigned char * Data, unsigned long * DataSize) { long R; assert(Configuration != NULL); THierarchicalStorage * Storage = reinterpret_cast<THierarchicalStorage *>(Key); AnsiString Value; if (Storage == NULL) { if (UnicodeString(ValueName) == L"RandSeedFile") { Value = Configuration->RandomSeedFileName; R = ERROR_SUCCESS; } else { FAIL; R = ERROR_READ_FAULT; } } else { if (Storage->ValueExists(ValueName)) { Value = Storage->ReadStringRaw(ValueName, L""); R = ERROR_SUCCESS; } else { R = ERROR_READ_FAULT; } } if (R == ERROR_SUCCESS) { assert(Type != NULL); *Type = REG_SZ; char * DataStr = reinterpret_cast<char *>(Data); strncpy(DataStr, Value.c_str(), *DataSize); DataStr[*DataSize - 1] = '\0'; *DataSize = strlen(DataStr); } return R; }
void CoreLoad() { bool SessionList = false; std::unique_ptr<THierarchicalStorage> SessionsStorage(GetConfiguration()->CreateStorage(SessionList)); THierarchicalStorage * ConfigStorage = nullptr; std::unique_ptr<THierarchicalStorage> ConfigStorageAuto; if (!SessionList) { // can reuse this for configuration ConfigStorage = SessionsStorage.get(); } else { ConfigStorageAuto.reset(GetConfiguration()->CreateConfigStorage()); ConfigStorage = ConfigStorageAuto.get(); } assert(GetConfiguration() != nullptr); try { GetConfiguration()->Load(ConfigStorage); } catch (Exception & E) { ShowExtendedException(&E); } // should be noop, unless exception occurred above ConfigStorage->CloseAll(); StoredSessions = new TStoredSessionList(); try { if (SessionsStorage->OpenSubKey(GetConfiguration()->GetStoredSessionsSubKey(), false)) { StoredSessions->Load(SessionsStorage.get()); } } catch (Exception & E) { ShowExtendedException(&E); } }
//--------------------------------------------------------------------------- void __fastcall RecordWrapperVersions(UnicodeString ConsoleVersion, UnicodeString DotNetVersion) { TUpdatesConfiguration Updates = WinConfiguration->Updates; if (!DotNetVersion.IsEmpty()) { Updates.DotNetVersion = DotNetVersion; } if (!ConsoleVersion.IsEmpty()) { Updates.ConsoleVersion = ConsoleVersion; } WinConfiguration->Updates = Updates; if (Configuration->Storage == stNul) { Configuration->SetDefaultStorage(); try { THierarchicalStorage * Storage = Configuration->CreateConfigStorage(); try { Storage->AccessMode = smReadWrite; if (Storage->OpenSubKey(Configuration->ConfigurationSubKey, true) && Storage->OpenSubKey(L"Interface\\Updates", true, true)) { if (!DotNetVersion.IsEmpty()) { Storage->WriteString(L"DotNetVersion", DotNetVersion); } if (!ConsoleVersion.IsEmpty()) { Storage->WriteString(L"ConsoleVersion", ConsoleVersion); } } } __finally { delete Storage; } } __finally { Configuration->SetNulStorage(); } }
//--------------------------------------------------------------------------- static long OpenWinSCPKey(HKEY Key, const char * SubKey, HKEY * Result, bool CanCreate) { long R; assert(Configuration != NULL); assert(Key == HKEY_CURRENT_USER); USEDPARAM(Key); UnicodeString RegKey = SubKey; int PuttyKeyLen = OriginalPuttyRegistryStorageKey.Length(); assert(RegKey.SubString(1, PuttyKeyLen) == OriginalPuttyRegistryStorageKey); RegKey = RegKey.SubString(PuttyKeyLen + 1, RegKey.Length() - PuttyKeyLen); if (!RegKey.IsEmpty()) { assert(RegKey[1] == L'\\'); RegKey.Delete(1, 1); } if (RegKey.IsEmpty()) { *Result = static_cast<HKEY>(NULL); R = ERROR_SUCCESS; } else { // we expect this to be called only from verify_host_key() or store_host_key() assert(RegKey == L"SshHostKeys"); THierarchicalStorage * Storage = Configuration->CreateConfigStorage(); Storage->AccessMode = (CanCreate ? smReadWrite : smRead); if (Storage->OpenSubKey(RegKey, CanCreate)) { *Result = reinterpret_cast<HKEY>(Storage); R = ERROR_SUCCESS; } else { delete Storage; R = ERROR_CANTOPEN; } } return R; }
//--------------------------------------------------------------------------- void __fastcall TConfiguration::NeverShowBanner(const UnicodeString SessionKey, const UnicodeString & Banner) { THierarchicalStorage * Storage = CreateScpStorage(false); try { Storage->AccessMode = smReadWrite; if (Storage->OpenSubKey(ConfigurationSubKey, true) && Storage->OpenSubKey(L"Banners", true)) { Storage->WriteString(SessionKey, BannerHash(Banner)); } } __finally { delete Storage; } }
//--------------------------------------------------------------------------- void __fastcall TConfiguration::LoadDirectoryChangesCache(const UnicodeString SessionKey, TRemoteDirectoryChangesCache * DirectoryChangesCache) { THierarchicalStorage * Storage = CreateScpStorage(false); try { Storage->AccessMode = smRead; if (Storage->OpenSubKey(ConfigurationSubKey, false) && Storage->OpenSubKey(L"CDCache", false) && Storage->ValueExists(SessionKey)) { DirectoryChangesCache->Deserialize(Storage->ReadBinaryData(SessionKey)); } } __finally { delete Storage; } }
//--------------------------------------------------------------------------- void __fastcall TConfiguration::SaveDirectoryChangesCache(const UnicodeString SessionKey, TRemoteDirectoryChangesCache * DirectoryChangesCache) { THierarchicalStorage * Storage = CreateScpStorage(false); try { Storage->AccessMode = smReadWrite; if (Storage->OpenSubKey(ConfigurationSubKey, true) && Storage->OpenSubKey(L"CDCache", true)) { UnicodeString Data; DirectoryChangesCache->Serialize(Data); Storage->WriteBinaryData(SessionKey, Data); } } __finally { delete Storage; } }
//--------------------------------------------------------------------------- bool __fastcall TConfiguration::ShowBanner(const UnicodeString SessionKey, const UnicodeString & Banner) { bool Result; THierarchicalStorage * Storage = CreateScpStorage(false); try { Storage->AccessMode = smRead; Result = !Storage->OpenSubKey(ConfigurationSubKey, false) || !Storage->OpenSubKey(L"Banners", false) || !Storage->ValueExists(SessionKey) || (Storage->ReadString(SessionKey, L"") != BannerHash(Banner)); } __finally { delete Storage; } return Result; }