mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
Cleanup application data dialog shown only data what exists + Uninstaller does not offer to delete application data, where are not any
Source commit: 5d1f4b8a6e495105e0c877b4854b497cb219ac26
This commit is contained in:
@@ -747,28 +747,69 @@ void __fastcall TConfiguration::CleanupConfiguration()
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TConfiguration::CleanupRegistry(const UnicodeString & CleanupSubKey, const UnicodeString & ParentKey)
|
||||
bool TConfiguration::RegistryPathExists(const UnicodeString & RegistryPath)
|
||||
{
|
||||
std::unique_ptr<TRegistryStorage> Registry(new TRegistryStorage(RegistryStorageKey));
|
||||
|
||||
UnicodeString ParentKey = ExtractFileDir(RegistryPath);
|
||||
UnicodeString SubKey = ExtractFileName(RegistryPath);
|
||||
return
|
||||
Registry->OpenRootKey(false) &&
|
||||
(ParentKey.IsEmpty() ||
|
||||
Registry->OpenSubKeyPath(ParentKey, false)) &&
|
||||
Registry->KeyExists(SubKey);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TConfiguration::CleanupRegistry(const UnicodeString & RegistryPath)
|
||||
{
|
||||
std::unique_ptr<TRegistryStorage> Registry(new TRegistryStorage(RegistryStorageKey));
|
||||
|
||||
UnicodeString ParentKey = ExtractFileDir(RegistryPath);
|
||||
if (ParentKey.IsEmpty() ||
|
||||
Registry->OpenSubKeyPath(ParentKey, false))
|
||||
{
|
||||
Registry->RecursiveDeleteSubKey(CleanupSubKey);
|
||||
UnicodeString SubKey = ExtractFileName(RegistryPath);
|
||||
Registry->RecursiveDeleteSubKey(SubKey);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
TStrings * TConfiguration::GetCaches()
|
||||
{
|
||||
std::unique_ptr<TStrings> Result(new TStringList());
|
||||
Result->Add(SshHostKeysSubKey);
|
||||
Result->Add(FtpsCertificateStorageKey);
|
||||
Result->Add(HttpsCertificateStorageKey);
|
||||
Result->Add(DirectoryStatisticsCacheKey);
|
||||
Result->Add(TPath::Combine(ConfigurationSubKey, CDCacheKey));
|
||||
Result->Add(TPath::Combine(ConfigurationSubKey, BannersKey));
|
||||
Result->Add(TPath::Combine(ConfigurationSubKey, LastFingerprintsStorageKey));
|
||||
return Result.release();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TConfiguration::HasAnyCache()
|
||||
{
|
||||
bool Result = false;
|
||||
std::unique_ptr<TStrings> Caches(GetCaches());
|
||||
for (int Index = 0; Index < Caches->Count; Index++)
|
||||
{
|
||||
if (RegistryPathExists(Caches->Strings[Index]))
|
||||
{
|
||||
Result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TConfiguration::CleanupCaches()
|
||||
{
|
||||
try
|
||||
{
|
||||
CleanupRegistry(SshHostKeysSubKey);
|
||||
CleanupRegistry(FtpsCertificateStorageKey);
|
||||
CleanupRegistry(HttpsCertificateStorageKey);
|
||||
CleanupRegistry(DirectoryStatisticsCacheKey);
|
||||
CleanupRegistry(CDCacheKey, ConfigurationSubKey);
|
||||
CleanupRegistry(BannersKey, ConfigurationSubKey);
|
||||
CleanupRegistry(LastFingerprintsStorageKey, ConfigurationSubKey);
|
||||
std::unique_ptr<TStrings> Caches(GetCaches());
|
||||
for (int Index = 0; Index < Caches->Count; Index++)
|
||||
{
|
||||
CleanupRegistry(Caches->Strings[Index]);
|
||||
}
|
||||
}
|
||||
catch (Exception & E)
|
||||
{
|
||||
|
||||
@@ -161,7 +161,7 @@ protected:
|
||||
virtual void __fastcall LoadAdmin(THierarchicalStorage * Storage);
|
||||
virtual UnicodeString __fastcall GetDefaultKeyFile();
|
||||
virtual void __fastcall Saved();
|
||||
void __fastcall CleanupRegistry(const UnicodeString & CleanupSubKey, const UnicodeString & ParentKey = UnicodeString());
|
||||
void __fastcall CleanupRegistry(const UnicodeString & RegistryPath);
|
||||
void __fastcall CopyAllStringsInSubKey(
|
||||
THierarchicalStorage * Source, THierarchicalStorage * Target, const UnicodeString & Name);
|
||||
bool __fastcall CopySubKey(THierarchicalStorage * Source, THierarchicalStorage * Target, const UnicodeString & Name);
|
||||
@@ -186,6 +186,7 @@ protected:
|
||||
UnicodeString __fastcall LoadCustomIniFileStorageName();
|
||||
void __fastcall SaveCustomIniFileStorageName();
|
||||
UnicodeString __fastcall GetRegistryStorageOverrideKey();
|
||||
TStrings * GetCaches();
|
||||
|
||||
virtual UnicodeString __fastcall ModuleFileName();
|
||||
|
||||
@@ -224,6 +225,7 @@ public:
|
||||
void __fastcall CleanupConfiguration();
|
||||
void __fastcall CleanupIniFile();
|
||||
void __fastcall CleanupCaches();
|
||||
bool __fastcall HasAnyCache();
|
||||
void __fastcall CleanupRandomSeedFile();
|
||||
void __fastcall BeginUpdate();
|
||||
void __fastcall EndUpdate();
|
||||
@@ -255,6 +257,7 @@ public:
|
||||
UnicodeString __fastcall GetFileDescription(const UnicodeString & FileName);
|
||||
UnicodeString __fastcall GetFileVersion(const UnicodeString & FileName);
|
||||
UnicodeString __fastcall GetFileMimeType(const UnicodeString & FileName);
|
||||
bool RegistryPathExists(const UnicodeString & RegistryPath);
|
||||
|
||||
TStoredSessionList * __fastcall SelectFilezillaSessionsForImport(
|
||||
TStoredSessionList * Sessions, UnicodeString & Error);
|
||||
|
||||
@@ -56,6 +56,11 @@ void __fastcall PuttyInitialize()
|
||||
strcpy(appname_, AppName.c_str());
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
static bool DeleteRandomSeedOnExit()
|
||||
{
|
||||
return !HadRandomSeed && !SaveRandomSeed;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall PuttyFinalize()
|
||||
{
|
||||
if (SaveRandomSeed)
|
||||
@@ -64,7 +69,7 @@ void __fastcall PuttyFinalize()
|
||||
}
|
||||
random_unref();
|
||||
// random_ref in PuttyInitialize creates the seed file. Delete it, if didn't want to create it.
|
||||
if (!HadRandomSeed && !SaveRandomSeed)
|
||||
if (DeleteRandomSeedOnExit())
|
||||
{
|
||||
DeleteFile(ApiPath(Configuration->RandomSeedFileName));
|
||||
}
|
||||
@@ -81,6 +86,13 @@ void __fastcall DontSaveRandomSeed()
|
||||
SaveRandomSeed = false;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool RandomSeedExists()
|
||||
{
|
||||
return
|
||||
!DeleteRandomSeedOnExit() &&
|
||||
FileExists(ApiPath(Configuration->RandomSeedFileName));
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
TSecureShell * GetSecureShell(Plug * plug, bool & pfwd)
|
||||
{
|
||||
if (!is_ssh(plug) && !is_pfwd(plug))
|
||||
|
||||
@@ -51,4 +51,6 @@ class THierarchicalStorage;
|
||||
void WritePuttySettings(THierarchicalStorage * Storage, const UnicodeString & Settings);
|
||||
void SavePuttyDefaults(const UnicodeString & Name);
|
||||
//---------------------------------------------------------------------------
|
||||
bool RandomSeedExists();
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
@@ -4,139 +4,104 @@
|
||||
|
||||
#include <Common.h>
|
||||
#include <VCLCommon.h>
|
||||
#include <CoreMain.h>
|
||||
#include <WinConfiguration.h>
|
||||
#include <TextsWin.h>
|
||||
#include <HelpWin.h>
|
||||
#include <PuttyTools.h>
|
||||
#include "Cleanup.h"
|
||||
//---------------------------------------------------------------------
|
||||
#ifndef NO_RESOURCES
|
||||
#pragma resource "*.dfm"
|
||||
#endif
|
||||
//---------------------------------------------------------------------
|
||||
Boolean __fastcall DoCleanupDialog(TStoredSessionList *SessionList,
|
||||
TConfiguration *Configuration)
|
||||
bool __fastcall DoCleanupDialog()
|
||||
{
|
||||
Boolean Result;
|
||||
TCleanupDialog *CleanupDialog;
|
||||
try {
|
||||
CleanupDialog = SafeFormCreate<TCleanupDialog>();
|
||||
|
||||
CleanupDialog->SessionList = SessionList;
|
||||
CleanupDialog->Configuration = Configuration;
|
||||
|
||||
Result = (CleanupDialog->ShowModal() == DefaultResult(CleanupDialog));
|
||||
if (Result)
|
||||
{
|
||||
Configuration->Usage->Inc(L"Cleanups");
|
||||
|
||||
for (int i = wdConfiguration; i <= wdTemporaryFolders; i++)
|
||||
{
|
||||
if (CleanupDialog->CleanupData[(TWinSCPData)i])
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case wdConfiguration:
|
||||
Configuration->CleanupConfiguration();
|
||||
break;
|
||||
|
||||
case wdStoredSessions:
|
||||
SessionList->Cleanup();
|
||||
break;
|
||||
|
||||
case wdCaches:
|
||||
Configuration->CleanupCaches();
|
||||
break;
|
||||
|
||||
case wdConfigurationIniFile:
|
||||
Configuration->CleanupIniFile();
|
||||
break;
|
||||
|
||||
case wdRandomSeedFile:
|
||||
Configuration->CleanupRandomSeedFile();
|
||||
break;
|
||||
|
||||
case wdTemporaryFolders:
|
||||
WinConfiguration->CleanupTemporaryFolders();
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch(Exception & E)
|
||||
{
|
||||
ShowExtendedException(&E);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} __finally {
|
||||
delete CleanupDialog;
|
||||
std::unique_ptr<TCleanupDialog> CleanupDialog(SafeFormCreate<TCleanupDialog>());
|
||||
return CleanupDialog->Execute();
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void __fastcall DoCleanupDialogIfAnyDataAndWanted()
|
||||
{
|
||||
std::unique_ptr<TCleanupDialog> CleanupDialog(SafeFormCreate<TCleanupDialog>());
|
||||
if (CleanupDialog->AnyData() &&
|
||||
(MessageDialog(LoadStr(UNINSTALL_CLEANUP), qtConfirmation, qaYes | qaNo, HELP_UNINSTALL_CLEANUP) == qaYes))
|
||||
{
|
||||
CleanupDialog->Execute();
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
__fastcall TCleanupDialog::TCleanupDialog(TComponent* AOwner)
|
||||
: TForm(AOwner)
|
||||
{
|
||||
FAnyData = false;
|
||||
FindData();
|
||||
UseSystemSettings(this);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void __fastcall TCleanupDialog::AddLocation(int CaptionId, const UnicodeString & Location, TCleanupEvent Event)
|
||||
{
|
||||
FCaptions.push_back(LoadStr(CaptionId));
|
||||
FLocations.push_back(Location);
|
||||
FCleanupEvents.push_back(Event);
|
||||
FAnyData = true;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void __fastcall TCleanupDialog::AddRegistryLocation(int CaptionId, const UnicodeString & Location, TCleanupEvent Event)
|
||||
{
|
||||
AddLocation(CaptionId, Configuration->RootKeyStr + L'\\' + Configuration->RegistryStorageKey + L'\\' + Location, Event);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
bool __fastcall TCleanupDialog::AnyData()
|
||||
{
|
||||
return FAnyData;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void __fastcall TCleanupDialog::FindData()
|
||||
{
|
||||
// Add unconditionally (as it has a side effect of not saving the configuration)
|
||||
AddRegistryLocation(CLEANUP_CONFIG, Configuration->ConfigurationSubKey, Configuration->CleanupConfiguration);
|
||||
// But count as real data, only if it really exists
|
||||
FAnyData = Configuration->RegistryPathExists(Configuration->ConfigurationSubKey);
|
||||
|
||||
if (Configuration->RegistryPathExists(Configuration->StoredSessionsSubKey))
|
||||
{
|
||||
AddRegistryLocation(CLEANUP_SESSIONS, Configuration->StoredSessionsSubKey, StoredSessions->Cleanup);
|
||||
}
|
||||
|
||||
if (Configuration->HasAnyCache())
|
||||
{
|
||||
AddRegistryLocation(CLEANUP_HOSTKEYS, L"...", Configuration->CleanupCaches);
|
||||
}
|
||||
|
||||
UnicodeString IniFilePath = ExpandEnvironmentVariables(Configuration->IniFileStorageNameForReading);
|
||||
if (FileExists(IniFilePath))
|
||||
{
|
||||
AddLocation(CLEANUP_INIFILE, IniFilePath, Configuration->CleanupIniFile);
|
||||
}
|
||||
|
||||
if (RandomSeedExists())
|
||||
{
|
||||
AddLocation(CLEANUP_SEEDFILE, Configuration->RandomSeedFileName, Configuration->CleanupRandomSeedFile);
|
||||
}
|
||||
|
||||
if (WinConfiguration->AnyTemporaryFolders())
|
||||
{
|
||||
AddLocation(CLEANUP_TEMP_FOLDERS, WinConfiguration->TemporaryDir(true), WinConfiguration->CleanupTemporaryFolders);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void __fastcall TCleanupDialog::InitControls()
|
||||
{
|
||||
DebugAssert(FCaptions.size() == FLocations.size());
|
||||
DebugAssert(FCaptions.size() == FCleanupEvents.size());
|
||||
// Particularly in response to WM_DPICHANGED, the form may re-show
|
||||
DataListView->Items->Clear();
|
||||
|
||||
for (int i = wdConfiguration; i <= wdTemporaryFolders; i++)
|
||||
for (size_t Index = 0; Index < FCaptions.size(); Index++)
|
||||
{
|
||||
UnicodeString Caption;
|
||||
UnicodeString Location;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case wdConfiguration:
|
||||
Caption = LoadStr(CLEANUP_CONFIG);
|
||||
Location = Configuration->ConfigurationSubKey;
|
||||
break;
|
||||
|
||||
case wdStoredSessions:
|
||||
Caption = LoadStr(CLEANUP_SESSIONS);
|
||||
Location = Configuration->StoredSessionsSubKey;
|
||||
break;
|
||||
|
||||
case wdCaches:
|
||||
Caption = LoadStr(CLEANUP_HOSTKEYS);
|
||||
Location = L"...";
|
||||
break;
|
||||
|
||||
case wdConfigurationIniFile:
|
||||
Caption = LoadStr(CLEANUP_INIFILE);
|
||||
Location = ExpandEnvironmentVariables(Configuration->IniFileStorageNameForReading);
|
||||
break;
|
||||
|
||||
case wdRandomSeedFile:
|
||||
Caption = LoadStr(CLEANUP_SEEDFILE);
|
||||
Location = ExpandEnvironmentVariables(Configuration->RandomSeedFile);
|
||||
break;
|
||||
|
||||
case wdTemporaryFolders:
|
||||
Caption = LoadStr(CLEANUP_TEMP_FOLDERS);
|
||||
Location = WinConfiguration->TemporaryDir(true);
|
||||
break;
|
||||
|
||||
default:
|
||||
DebugFail();
|
||||
break;
|
||||
}
|
||||
|
||||
TListItem * Item = DataListView->Items->Add();
|
||||
Item->Caption = Caption;
|
||||
if (i < wdConfigurationIniFile)
|
||||
{
|
||||
Location = Configuration->RootKeyStr + L'\\' +
|
||||
Configuration->RegistryStorageKey + L'\\' + Location;
|
||||
}
|
||||
|
||||
Item->SubItems->Add(Location);
|
||||
DebugAssert(Item->Index == i - 1);
|
||||
Item->Caption = FCaptions[Index];
|
||||
Item->SubItems->Add(FLocations[Index]);
|
||||
}
|
||||
|
||||
AutoSizeListColumnsWidth(DataListView);
|
||||
@@ -179,13 +144,33 @@ void __fastcall TCleanupDialog::DataListViewInfoTip(TObject * /*Sender*/,
|
||||
ARRAYOFCONST((Item->Caption, Item->SubItems->Strings[0])));
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TCleanupDialog::GetCleanupData(TWinSCPData Data)
|
||||
{
|
||||
return DataListView->Items->Item[Data - 1]->Checked;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCleanupDialog::HelpButtonClick(TObject * /*Sender*/)
|
||||
{
|
||||
FormHelp(this);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TCleanupDialog::Execute()
|
||||
{
|
||||
bool Result = (ShowModal() == DefaultResult(this));
|
||||
if (Result)
|
||||
{
|
||||
Configuration->Usage->Inc(L"Cleanups");
|
||||
|
||||
for (int Index = 0; Index < DataListView->Items->Count; Index++)
|
||||
{
|
||||
if (DataListView->Items->Item[Index]->Checked)
|
||||
{
|
||||
try
|
||||
{
|
||||
FCleanupEvents[Index]();
|
||||
}
|
||||
catch (Exception & E)
|
||||
{
|
||||
ShowExtendedException(&E);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
#include <WinInterface.h>
|
||||
#include <GUITools.h>
|
||||
//---------------------------------------------------------------------
|
||||
enum TWinSCPData {wdConfiguration = 1, wdStoredSessions, wdCaches,
|
||||
wdConfigurationIniFile, wdRandomSeedFile, wdTemporaryFolders };
|
||||
//---------------------------------------------------------------------
|
||||
class TCleanupDialog : public TForm
|
||||
{
|
||||
__published:
|
||||
@@ -34,19 +31,23 @@ __published:
|
||||
TListItem *Item, UnicodeString &InfoTip);
|
||||
void __fastcall HelpButtonClick(TObject *Sender);
|
||||
private:
|
||||
TStoredSessionList *FSessionList;
|
||||
TConfiguration * FConfiguration;
|
||||
std::vector<UnicodeString> FCaptions;
|
||||
std::vector<UnicodeString> FLocations;
|
||||
typedef void __fastcall (__closure *TCleanupEvent)();
|
||||
std::vector<TCleanupEvent> FCleanupEvents;
|
||||
bool FAnyData;
|
||||
void __fastcall InitControls();
|
||||
void __fastcall UpdateControls();
|
||||
bool __fastcall GetCleanupData(TWinSCPData Data);
|
||||
void __fastcall FindData();
|
||||
void __fastcall AddLocation(int CaptionId, const UnicodeString & Location, TCleanupEvent Event);
|
||||
void __fastcall AddRegistryLocation(int CaptionId, const UnicodeString & Location, TCleanupEvent Event);
|
||||
|
||||
INTERFACE_HOOK;
|
||||
|
||||
public:
|
||||
virtual __fastcall TCleanupDialog(TComponent* AOwner);
|
||||
__property TStoredSessionList *SessionList = { read=FSessionList, write=FSessionList };
|
||||
__property TConfiguration * Configuration = { read=FConfiguration, write=FConfiguration };
|
||||
__property Boolean CleanupData[TWinSCPData Data] = { read=GetCleanupData };
|
||||
virtual __fastcall TCleanupDialog(TComponent * AOwner);
|
||||
bool __fastcall Execute();
|
||||
bool __fastcall AnyData();
|
||||
};
|
||||
//----------------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
@@ -1113,7 +1113,7 @@ void __fastcall TLoginDialog::ImportSessionsActionExecute(TObject * /*Sender*/)
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TLoginDialog::CleanUpActionExecute(TObject * /*Sender*/)
|
||||
{
|
||||
if (DoCleanupDialog(StoredSessions, Configuration))
|
||||
if (DoCleanupDialog())
|
||||
{
|
||||
SaveState();
|
||||
LoadSessions();
|
||||
|
||||
@@ -2480,87 +2480,75 @@ UnicodeString __fastcall TWinConfiguration::TemporaryDir(bool Mask)
|
||||
return UniqTempDir(ExpandedTemporaryDirectory(), L"scp", Mask);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
TStrings * __fastcall TWinConfiguration::DoFindTemporaryFolders(bool OnlyFirst)
|
||||
{
|
||||
std::unique_ptr<TStrings> Result(new TStringList());
|
||||
TSearchRecOwned SRec;
|
||||
UnicodeString Mask = TemporaryDir(true);
|
||||
UnicodeString Directory = ExtractFilePath(Mask);
|
||||
if (FindFirstUnchecked(Mask, faDirectory | faHidden, SRec) == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (SRec.IsDirectory())
|
||||
{
|
||||
Result->Add(Directory + SRec.Name);
|
||||
}
|
||||
}
|
||||
while ((FindNextChecked(SRec) == 0) && (!OnlyFirst || Result->Count == 0));
|
||||
}
|
||||
|
||||
if (Result->Count == 0)
|
||||
{
|
||||
Result.reset(NULL);
|
||||
}
|
||||
|
||||
return Result.release();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
TStrings * __fastcall TWinConfiguration::FindTemporaryFolders()
|
||||
{
|
||||
TStrings * Result = new TStringList();
|
||||
try
|
||||
return DoFindTemporaryFolders(false);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TWinConfiguration::AnyTemporaryFolders()
|
||||
{
|
||||
std::unique_ptr<TStrings> Folders(DoFindTemporaryFolders(true));
|
||||
return (Folders.get() != NULL);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TWinConfiguration::CleanupTemporaryFolders()
|
||||
{
|
||||
std::unique_ptr<TStrings> Folders(FindTemporaryFolders());
|
||||
if (Folders.get() != NULL)
|
||||
{
|
||||
TSearchRecOwned SRec;
|
||||
UnicodeString Mask = TemporaryDir(true);
|
||||
UnicodeString Directory = ExtractFilePath(Mask);
|
||||
if (FindFirstUnchecked(Mask, faDirectory | faHidden, SRec) == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (SRec.IsDirectory())
|
||||
{
|
||||
Result->Add(Directory + SRec.Name);
|
||||
}
|
||||
}
|
||||
while (FindNextChecked(SRec) == 0);
|
||||
}
|
||||
|
||||
if (Result->Count == 0)
|
||||
{
|
||||
delete Result;
|
||||
Result = NULL;
|
||||
}
|
||||
CleanupTemporaryFolders(Folders.get());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
delete Result;
|
||||
throw;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TWinConfiguration::CleanupTemporaryFolders(TStrings * Folders)
|
||||
{
|
||||
if (DebugAlwaysTrue(Folders->Count > 0))
|
||||
{
|
||||
Usage->Inc(L"TemporaryDirectoryCleanups");
|
||||
}
|
||||
|
||||
UnicodeString ErrorList;
|
||||
TStrings * F;
|
||||
if (Folders == NULL)
|
||||
for (int i = 0; i < Folders->Count; i++)
|
||||
{
|
||||
F = FindTemporaryFolders();
|
||||
}
|
||||
else
|
||||
{
|
||||
F = Folders;
|
||||
if (!DeleteDirectory(Folders->Strings[i]))
|
||||
{
|
||||
if (!ErrorList.IsEmpty())
|
||||
{
|
||||
ErrorList += L"\n";
|
||||
}
|
||||
ErrorList += Folders->Strings[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (F != NULL)
|
||||
if (!ErrorList.IsEmpty())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DebugAlwaysTrue(F->Count > 0))
|
||||
{
|
||||
Usage->Inc(L"TemporaryDirectoryCleanups");
|
||||
}
|
||||
|
||||
for (int i = 0; i < F->Count; i++)
|
||||
{
|
||||
if (!DeleteDirectory(F->Strings[i]))
|
||||
{
|
||||
if (!ErrorList.IsEmpty())
|
||||
{
|
||||
ErrorList += L"\n";
|
||||
}
|
||||
ErrorList += F->Strings[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
__finally
|
||||
{
|
||||
if (Folders == NULL)
|
||||
{
|
||||
delete F;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ErrorList.IsEmpty())
|
||||
{
|
||||
throw ExtException(LoadStr(CLEANUP_TEMP_ERROR), ErrorList);
|
||||
}
|
||||
throw ExtException(LoadStr(CLEANUP_TEMP_ERROR), ErrorList);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -2737,7 +2725,9 @@ void __fastcall TWinConfiguration::UpdateEntryInJumpList(
|
||||
FDontDecryptPasswords++;
|
||||
Storage->AccessMode = smReadWrite;
|
||||
|
||||
if (Storage->OpenSubKey(ConfigurationSubKey, true))
|
||||
// For initial call from UpdateJumpList, do not create the key if it does ot exist yet.
|
||||
// To avoid creating the key if we are being started just for a maintenance task.
|
||||
if (Storage->OpenSubKey(ConfigurationSubKey, !Name.IsEmpty()))
|
||||
{
|
||||
std::unique_ptr<TStringList> ListSessions(LoadJumpList(Storage, L"JumpList"));
|
||||
std::unique_ptr<TStringList> ListWorkspaces(LoadJumpList(Storage, L"JumpListWorkspaces"));
|
||||
|
||||
@@ -609,6 +609,7 @@ protected:
|
||||
void __fastcall LoadExtensionList();
|
||||
void __fastcall ReleaseExtensionTranslations();
|
||||
void __fastcall LoadExtensionTranslations();
|
||||
TStrings * __fastcall DoFindTemporaryFolders(bool OnlyFirst);
|
||||
|
||||
public:
|
||||
__fastcall TWinConfiguration();
|
||||
@@ -618,6 +619,8 @@ public:
|
||||
virtual THierarchicalStorage * CreateScpStorage(bool & SessionList);
|
||||
UnicodeString __fastcall TemporaryDir(bool Mask = false);
|
||||
TStrings * __fastcall FindTemporaryFolders();
|
||||
bool __fastcall AnyTemporaryFolders();
|
||||
void __fastcall CleanupTemporaryFolders();
|
||||
void __fastcall CleanupTemporaryFolders(TStrings * Folders = NULL);
|
||||
UnicodeString __fastcall ExpandedTemporaryDirectory();
|
||||
void __fastcall CheckDefaultTranslation();
|
||||
|
||||
@@ -193,8 +193,8 @@ void __fastcall DoAboutDialog(TConfiguration * Configuration,
|
||||
void __fastcall DoAboutDialog(TConfiguration *Configuration);
|
||||
|
||||
// forms\Cleanup.cpp
|
||||
bool __fastcall DoCleanupDialog(TStoredSessionList *SessionList,
|
||||
TConfiguration *Configuration);
|
||||
bool __fastcall DoCleanupDialog();
|
||||
void __fastcall DoCleanupDialogIfAnyDataAndWanted();
|
||||
|
||||
// forms\Console.cpp
|
||||
void __fastcall DoConsoleDialog(TTerminal * Terminal,
|
||||
|
||||
@@ -865,14 +865,13 @@ int __fastcall Execute()
|
||||
if (Params->FindSwitch(L"UninstallCleanup"))
|
||||
{
|
||||
MaintenanceTask();
|
||||
Configuration->DontSave();
|
||||
// The innosetup cannot skip UninstallCleanup run task for silent uninstalls,
|
||||
// workaround is that we create mutex in uninstaller, if it runs silent, and
|
||||
// ignore the UninstallCleanup, when the mutex exists.
|
||||
if ((OpenMutex(SYNCHRONIZE, false, L"WinSCPSilentUninstall") == NULL) &&
|
||||
(MessageDialog(LoadStr(UNINSTALL_CLEANUP), qtConfirmation,
|
||||
qaYes | qaNo, HELP_UNINSTALL_CLEANUP) == qaYes))
|
||||
if (OpenMutex(SYNCHRONIZE, false, L"WinSCPSilentUninstall") == NULL)
|
||||
{
|
||||
DoCleanupDialog(StoredSessions, Configuration);
|
||||
DoCleanupDialogIfAnyDataAndWanted();
|
||||
}
|
||||
}
|
||||
else if (Params->FindSwitch(L"RegisterForDefaultProtocols") ||
|
||||
|
||||
Reference in New Issue
Block a user