public CopyFileEngine (List <FileInfoEx> source, string destination, CopyEngineOptions options, CopyFileProgressDialog dialog, string mask, bool dest_remote) { this.options = options; copy_progress_routine_delegate_holder = new CopyProgressRoutine(copy_progress_proc); copyFileEx_options = CopyFileExOptions.None; if ((options & CopyEngineOptions.AllowDecryptDestination) == CopyEngineOptions.AllowDecryptDestination) { copyFileEx_options = copyFileEx_options | CopyFileExOptions.ALLOW_DECRYPTED_DESTINATION; } if (Options.IsVistaOrServer2003OrLater()) { if ((options & CopyEngineOptions.CopySymlinkAsSymlink) == CopyEngineOptions.CopySymlinkAsSymlink) { copyFileEx_options = copyFileEx_options | CopyFileExOptions.COPY_SYMLINK; } } if ((options & CopyEngineOptions.NoRewrite) == CopyEngineOptions.NoRewrite) { copyFileEx_options = copyFileEx_options | CopyFileExOptions.FAIL_IF_EXISTS; } if ((options & CopyEngineOptions.RewriteIfSourceNewer) == CopyEngineOptions.RewriteIfSourceNewer) { copyFileEx_options = copyFileEx_options | CopyFileExOptions.FAIL_IF_EXISTS; } progress_dialog = dialog; if (progress_dialog != null) { progress_dialog.FormClosing += new System.Windows.Forms.FormClosingEventHandler (progress_dialog_FormClosing); } initial_source = source; initial_destination = destination; initial_mask = mask; destination_remote = dest_remote; update_progress_delegate_holder = new MethodInvokerUpdateProgress(update_progress); copy_thread = new Thread(internal_do); }
/// <summary> /// show error window if needed and returns do second take or no, if no caller must continue to next source /// </summary> /// <param name="source"></param> /// <param name="src_data"></param> /// <param name="destination"></param> /// <param name="win_error"></param> /// <returns></returns> private bool process_CopyFileEx_errors(FileInfoEx source_info, string destination, int win_error, ref CopyFileExOptions temp_options) { var dst_data = new WIN32_FIND_DATA(); switch (win_error) { case WinApiFS.ERROR_PATH_NOT_FOUND: //ERROR_PATH_NOT_FOUND //there is no target directory, create it var src_dir_3 = Path.GetDirectoryName(source_info.FullName); var dst_dir_3 = Path.GetDirectoryName(destination); try { create_empty_dir(src_dir_3, dst_dir_3); } catch (Exception ex_3) { if (process_error (string.Format (Options.GetLiteral(Options.LANG_CANNOT_CREATE_DIRECTORY_0), dst_dir_3), ex_3)) { return(false); } else { stop(); return(false); } } return(true); case WinApiFS.ERROR_FILE_EXISTS: //ERROR_FILE_EXISTS if ((options & CopyEngineOptions.RewriteIfSourceNewer) == CopyEngineOptions.RewriteIfSourceNewer) { //overwrite enable if source newer WinAPiFSwrapper.GetFileInfo(destination, ref dst_data); if (source_info.WriteFileTime > dst_data.ftLastWriteTime) { temp_options = ~((~temp_options) | CopyFileExOptions.FAIL_IF_EXISTS); return(clear_dest_attributes(destination, dst_data)); } else { if (process_error (string.Format (Options.GetLiteral(Options.LANG_DESTINATION_0_NEWER_THEN_SOURCE_1_OVERWRITING_PROHIBITED), destination, source_info.FullName), null)) { return(false); } else { stop(); return(false); } } } //destination exists and overwrite prohibited if (process_error (string.Format (Options.GetLiteral(Options.LANG_DESTINATION_0_EXIST_OVERWRITING_PROHIBITED), destination), null)) { return(false); } else { stop(); return(false); } case 5: //ERROR_ACCESS_DENIED //destination file have readonly or hidden attribute //clear attributes WinAPiFSwrapper.GetFileInfo(destination, ref dst_data); return(clear_dest_attributes(destination, dst_data)); } //end switch //default: var ex = new Win32Exception(win_error); if (process_error (string.Format (Options.GetLiteral(Options.LANG_CANNOT_COPY_0_ARROW_1), source_info.FullName, destination), ex)) { return(false); } else { stop(); return(false); } }
private void copy_one_file(FileInfoEx source_info, string destination_file) { //check mask if (!Wildcard.Match(initial_mask, source_info.FileName)) { return; } bool success = false; //now prepare callback buffer if (callback_data != IntPtr.Zero) { Marshal.FreeHGlobal(callback_data); } callback_data = IOhelper.strings_to_buffer(source_info.FullName, destination_file); //prepare uni names string source_uni = IOhelper.GetUnicodePath(source_info.FullName); string dest_uni = IOhelper.GetUnicodePath(destination_file); //string source_uni = source_info.FullName; //string dest_uni = destination_file; //and call CopyFileEx first time int res = WinApiFS.CopyFileEx (source_uni, dest_uni, copy_progress_routine_delegate_holder, callback_data, IntPtr.Zero, copyFileEx_options); if (res == 0) { int win_err = Marshal.GetLastWin32Error(); //process win_err and do second take if needed CopyFileExOptions temp_copy_options = copyFileEx_options; if (process_CopyFileEx_errors(source_info, destination_file, win_err, ref temp_copy_options)) { //second take res = WinApiFS.CopyFileEx (source_uni, dest_uni, copy_progress_routine_delegate_holder, callback_data, IntPtr.Zero, temp_copy_options); if (res == 0) { win_err = Marshal.GetLastWin32Error(); Win32Exception win_ex_2 = new Win32Exception(win_err); if (!process_error (string.Format (Options.GetLiteral(Options.LANG_CANNOT_COPY_0_ARROW_1), source_info.FullName, destination_file), win_ex_2)) { stop(); } } else { success = true; } } }//end of res==0 brunch else { //copy success success = true; } if (success) { //update counts total_bytes_transferred += current_file_bytes_transferred; current_file_bytes_transferred = 0; total_files_copied++; //time to notify current panel -> unset selection ItemEventArs e_file_done = new ItemEventArs(source_info.FileName); OnCopyItemDone(e_file_done); //set sec attributes if needed if ((options & CopyEngineOptions.CopySecurityAttributes) == CopyEngineOptions.CopySecurityAttributes) { try { File.SetAccessControl(destination_file, File.GetAccessControl(source_info.FullName)); } catch (Exception ex) { if (!process_error (string.Format (Options.GetLiteral(Options.LANG_CANNOT_SET_SEC_ATTRIBUTES_0), destination_file), ex)) { stop(); } } } } }