Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Bypass system cache option to Copy/Move dialog #756

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions far/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2015,6 +2015,7 @@ void Options::InitConfigsData()
{FSSF_PRIVATE, NKeySystem, L"CmdHistoryRule"sv, CmdHistoryRule, false},
{FSSF_PRIVATE, NKeySystem, L"ConsoleDetachKey"sv, ConsoleDetachKey, L"CtrlShiftTab"sv},
{FSSF_PRIVATE, NKeySystem, L"CopyBufferSize"sv, CMOpt.BufferSize, 0},
{FSSF_PRIVATE, NKeySystem, L"SystemCopyNoBufferingMinSize"sv, CMOpt.SystemCopyNoBufferingMinSize, 1048576},
{FSSF_SYSTEM, NKeySystem, L"CopyOpened"sv, CMOpt.CopyOpened, true},
{FSSF_PRIVATE, NKeySystem, L"CopyTimeRule"sv, CMOpt.CopyTimeRule, 3},
{FSSF_PRIVATE, NKeySystem, L"CopySecurityOptions"sv, CMOpt.CopySecurityOptions, 0},
Expand Down
1 change: 1 addition & 0 deletions far/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,7 @@ class Options: noncopyable
IntOption CopySecurityOptions; // для операции Move - что делать с опцией "Copy access rights"
IntOption CopyTimeRule; // $ 30.01.2001 VVM Показывает время копирования,оставшееся время и среднюю скорость
IntOption BufferSize;
IntOption SystemCopyNoBufferingMinSize; // минимальная длина файла для которого можно включить COPY_FILE_NO_BUFFERING
};

struct DeleteOptions
Expand Down
63 changes: 53 additions & 10 deletions far/copy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ class ShellCopy : noncopyable
std::unique_ptr<copy_progress> CP;
std::unique_ptr<multifilter> m_Filter;
DWORD Flags;
DWORD SystemCopyNoBufferingMinSize;
panel_ptr SrcPanel, DestPanel;
panel_mode SrcPanelMode, DestPanelMode;
int SrcDriveType{}, DestDriveType{};
Expand Down Expand Up @@ -236,6 +237,7 @@ enum COPY_FLAGS
FCOPY_USESYSTEMCOPY = 10_bit, // использовать системную функцию копирования
FCOPY_COPYLASTTIME = 11_bit, // При копировании в несколько каталогов устанавливается для последнего.
FCOPY_UPDATEPPANEL = 12_bit, // необходимо обновить пассивную панель
FCOPY_COPY_FILE_NO_BUFFERING = 13_bit, // дополнение для системной функции копирования больших файлов
};

template<typename times_type>
Expand Down Expand Up @@ -294,6 +296,9 @@ enum enumShellCopy
IS_SC_PRESERVETIMESTAMPS,
ID_SC_COPYSYMLINK,
ID_SC_MULTITARGET,
ID_SC_SYSTEM_COPY_FILE_NO_BUFFERING,
ID_SC_SYSTEM_COPY_FILE_NO_BUFFERING_MIN_SIZE,
ID_SC_SYSTEM_COPY_FILE_NO_BUFFERING_MIN_SIZE_TITLE,
ID_SC_SEPARATOR3,
ID_SC_USEFILTER,
ID_SC_SEPARATOR4,
Expand Down Expand Up @@ -645,10 +650,12 @@ ShellCopy::ShellCopy(
// ***********************************************************************
// *** Prepare Dialog Controls
// ***********************************************************************
int DlgW = 76, DlgH = 17;
int DlgW = 76, DlgH = 17 + 1;

FARDIALOGITEMFLAGS no_tree = Global->Opt->Tree.TurnOffCompletely ? DIF_HIDDEN|DIF_DISABLE : 0;

int posFix = (int)(msg(lng::MCopySystemCopyNoBuffering).length() + 9);

auto CopyDlg = MakeDialogItems<ID_SC_COUNT>(
{
{ DI_DOUBLEBOX, {{3, 1 }, {DlgW - 4, DlgH - 2}}, DIF_NONE, msg(lng::MCopyDlgTitle), },
Expand All @@ -665,13 +672,18 @@ ShellCopy::ShellCopy(
{ DI_CHECKBOX, {{5, 8 }, {0, 8 }}, DIF_NONE, msg(lng::MCopyPreserveAllTimestamps), },
{ DI_CHECKBOX, {{5, 9 }, {0, 9 }}, DIF_NONE, msg(lng::MCopySymLinkContents), },
{ DI_CHECKBOX, {{5, 10}, {0, 10}}, DIF_NONE, msg(lng::MCopyMultiActions), },
{ DI_TEXT, {{-1, 11}, {0, 11}}, DIF_SEPARATOR, },
{ DI_CHECKBOX, {{5, 12}, {0, 12}}, DIF_AUTOMATION, msg(lng::MCopyUseFilter), },
{ DI_TEXT, {{-1, 13}, {0, 13}}, DIF_SEPARATOR, },
{ DI_BUTTON, {{0, 14}, {0, 14}}, DIF_CENTERGROUP | DIF_DEFAULTBUTTON, msg(lng::MCopyDlgCopy), },
{ DI_BUTTON, {{0, 14}, {0, 14}}, DIF_CENTERGROUP | DIF_BTNNOCLOSE | no_tree, msg(lng::MCopyDlgTree), },
{ DI_BUTTON, {{0, 14}, {0, 14}}, DIF_CENTERGROUP | DIF_BTNNOCLOSE | DIF_AUTOMATION | (m_UseFilter ? DIF_NONE : DIF_DISABLE), msg(lng::MCopySetFilter), },
{ DI_BUTTON, {{0, 14}, {0, 14}}, DIF_CENTERGROUP, msg(lng::MCopyDlgCancel), },

{ DI_CHECKBOX, {{5, 11}, {0, 11}}, DIF_AUTOMATION, msg(lng::MCopySystemCopyNoBuffering), },
{ DI_FIXEDIT, {{posFix, 11}, {posFix + 3, 11}}, DIF_MASKEDIT | DIF_AUTOMATION | DIF_DISABLE, L""},
{ DI_TEXT, {{posFix + 5, 11}, {0, 11}}, DIF_NONE, L"MB", },

{ DI_TEXT, {{-1, 12}, {0, 12}}, DIF_SEPARATOR, },
{ DI_CHECKBOX, {{5, 13}, {0, 13}}, DIF_AUTOMATION, msg(lng::MCopyUseFilter), },
{ DI_TEXT, {{-1, 14}, {0, 14}}, DIF_SEPARATOR, },
{ DI_BUTTON, {{0, 15}, {0, 15}}, DIF_CENTERGROUP | DIF_DEFAULTBUTTON, msg(lng::MCopyDlgCopy), },
{ DI_BUTTON, {{0, 15}, {0, 15}}, DIF_CENTERGROUP | DIF_BTNNOCLOSE | no_tree, msg(lng::MCopyDlgTree), },
{ DI_BUTTON, {{0, 15}, {0, 15}}, DIF_CENTERGROUP | DIF_BTNNOCLOSE | DIF_AUTOMATION | (m_UseFilter ? DIF_NONE : DIF_DISABLE), msg(lng::MCopySetFilter), },
{ DI_BUTTON, {{0, 15}, {0, 15}}, DIF_CENTERGROUP, msg(lng::MCopyDlgCancel), },
});

CopyDlg[ID_SC_TARGETEDIT].strHistory = L"Copy"sv;
Expand All @@ -694,6 +706,18 @@ ShellCopy::ShellCopy(
}
}

CopyDlg[ID_SC_SYSTEM_COPY_FILE_NO_BUFFERING].Selected = 0;

if (!Global->Opt->CMOpt.UseSystemCopy)
{
CopyDlg[ID_SC_SYSTEM_COPY_FILE_NO_BUFFERING].Flags |= DIF_DISABLE;
CopyDlg[ID_SC_SYSTEM_COPY_FILE_NO_BUFFERING_MIN_SIZE_TITLE].Flags |= DIF_DISABLE;
}

SystemCopyNoBufferingMinSize = Global->Opt->CMOpt.SystemCopyNoBufferingMinSize.Get();
// for Dlg size in MB
CopyDlg[ID_SC_SYSTEM_COPY_FILE_NO_BUFFERING_MIN_SIZE].strData = str(SystemCopyNoBufferingMinSize / 1048576UL);

if (Link)
{
CopyDlg[ID_SC_COMBOTEXT].strData=msg(lng::MLinkType);
Expand Down Expand Up @@ -975,7 +999,8 @@ ShellCopy::ShellCopy(
Dlg->SetId(Link?HardSymLinkId:(Move?(CurrentOnly?MoveCurrentOnlyFileId:MoveFilesId):(CurrentOnly?CopyCurrentOnlyFileId:CopyFilesId)));
Dlg->SetPosition({ -1, -1, DlgW, DlgH });
Dlg->SetAutomation(ID_SC_USEFILTER,ID_SC_BTNFILTER,DIF_DISABLE,DIF_NONE,DIF_NONE,DIF_DISABLE);
// Dlg->Show();
Dlg->SetAutomation(ID_SC_SYSTEM_COPY_FILE_NO_BUFFERING, ID_SC_SYSTEM_COPY_FILE_NO_BUFFERING_MIN_SIZE, DIF_DISABLE, DIF_NONE, DIF_NONE, DIF_DISABLE);
// Dlg->Show();
// $ 02.06.2001 IS + Проверим список целей и поднимем тревогу, если он содержит ошибки
int DlgExitCode;

Expand All @@ -1000,6 +1025,16 @@ ShellCopy::ShellCopy(

Global->Opt->CMOpt.PreserveTimestamps = CopyDlg[IS_SC_PRESERVETIMESTAMPS].Selected == BSTATE_CHECKED;

if (CopyDlg[ID_SC_SYSTEM_COPY_FILE_NO_BUFFERING].Selected == BSTATE_CHECKED)
{
if (Global->Opt->CMOpt.SystemCopyNoBufferingMinSize.TryParse(CopyDlg[ID_SC_SYSTEM_COPY_FILE_NO_BUFFERING_MIN_SIZE].strData))
{
// from Dlg size in MB
SystemCopyNoBufferingMinSize = Global->Opt->CMOpt.SystemCopyNoBufferingMinSize.Get() * 1048576UL;
Global->Opt->CMOpt.SystemCopyNoBufferingMinSize.Set(SystemCopyNoBufferingMinSize);
}
}

if(!Move)
{
Global->Opt->CMOpt.MultiCopy=CopyDlg[ID_SC_MULTITARGET].Selected == BSTATE_CHECKED;
Expand Down Expand Up @@ -1144,6 +1179,7 @@ ShellCopy::ShellCopy(
}

Flags|=CopyDlg[ID_SC_COPYSYMLINK].Selected? FCOPY_COPYSYMLINKCONTENTS : FCOPY_NONE;
Flags|= CopyDlg[ID_SC_SYSTEM_COPY_FILE_NO_BUFFERING].Selected? FCOPY_COPY_FILE_NO_BUFFERING : FCOPY_NONE;

if (DestPlugin && CopyDlg[ID_SC_TARGETEDIT].strData == strInitDestDir)
{
Expand Down Expand Up @@ -3327,7 +3363,14 @@ bool ShellCopy::ShellSystemCopy(const string_view SrcName, const string_view Des

const auto sd = GetSecurity(SrcName);

if (!os::fs::copy_file(SrcName, DestName, callback, {}, Flags & FCOPY_DECRYPTED_DESTINATION? COPY_FILE_ALLOW_DECRYPTED_DESTINATION : 0))
auto copyFlags = Flags & FCOPY_DECRYPTED_DESTINATION ? COPY_FILE_ALLOW_DECRYPTED_DESTINATION : 0;

if (Flags & FCOPY_COPY_FILE_NO_BUFFERING && SrcData.FileSize >= SystemCopyNoBufferingMinSize)
{
copyFlags |= COPY_FILE_NO_BUFFERING;
}

if (!os::fs::copy_file(SrcName, DestName, callback, {}, copyFlags))
{
rethrow_if(ExceptionPtr);
Flags&=~FCOPY_DECRYPTED_DESTINATION;
Expand Down
14 changes: 14 additions & 0 deletions far/farlang.templ.m4
Original file line number Diff line number Diff line change
Expand Up @@ -4651,6 +4651,20 @@ MCopyMultiActions
"Апр&ацоўваць некалькі імёнаў файлаў"
upd:"Process &multiple destinations"

MCopySystemCopyNoBuffering
"Обход &системного кэша для больших файлов"
"Bypass &system cache for large files:"
"Bypass &system cache for large files:"
"Bypass &system cache for large files:"
"Bypass &system cache for large files:"
"Bypass &system cache for large files:"
"Bypass &system cache for large files:"
"Bypass &system cache for large files:"
"Bypass &system cache for large files:"
"Bypass &system cache for large files:"
"Bypass &system cache for large files:"
upd:"Bypass &system cache for large files:"

MCopyDlgCopy
"&Копировать"
"&Copy"
Expand Down
6 changes: 6 additions & 0 deletions far/platform.fs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1941,6 +1941,12 @@ namespace os::fs
return false;
}

if (LastError.NtError == STATUS_INVALID_PARAMETER)
{
SetLastError(ERROR_INVALID_PARAMETER);
return false;
}

if (ElevationRequired(ELEVATION_MODIFY_REQUEST)) //BUGBUG, really unknown
return elevation::instance().copy_file(strFrom, strTo, RoutinePtr, DataPtr, Cancel, CopyFlags);

Expand Down