diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp
index f825f65e5..bf0fbfa72 100644
--- a/src/libslic3r/Utils.hpp
+++ b/src/libslic3r/Utils.hpp
@@ -65,7 +65,11 @@ extern std::string normalize_utf8_nfc(const char *src);
 extern std::error_code rename_file(const std::string &from, const std::string &to);
 
 // Copy a file, adjust the access attributes, so that the target is writable.
-extern int copy_file(const std::string &from, const std::string &to);
+int copy_file_inner(const std::string &from, const std::string &to);
+extern int copy_file(const std::string &from, const std::string &to, const bool with_check = false);
+
+// Compares two files, returns 0 if identical.
+extern int check_copy(const std::string& origin, const std::string& copy);
 
 // Ignore system and hidden files, which may be created by the DropBox synchronisation process.
 // https://github.com/prusa3d/PrusaSlicer/issues/1298
diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp
index 678ad9ed2..e78022053 100644
--- a/src/libslic3r/utils.cpp
+++ b/src/libslic3r/utils.cpp
@@ -417,27 +417,62 @@ std::error_code rename_file(const std::string &from, const std::string &to)
 #endif
 }
 
-int copy_file(const std::string &from, const std::string &to)
+int copy_file_inner(const std::string& from, const std::string& to)
 {
-    const boost::filesystem::path source(from);
-    const boost::filesystem::path target(to);
-    static const auto perms = boost::filesystem::owner_read | boost::filesystem::owner_write | boost::filesystem::group_read | boost::filesystem::others_read;   // aka 644
+	const boost::filesystem::path source(from);
+	const boost::filesystem::path target(to);
+	static const auto perms = boost::filesystem::owner_read | boost::filesystem::owner_write | boost::filesystem::group_read | boost::filesystem::others_read;   // aka 644
 
-    // Make sure the file has correct permission both before and after we copy over it.
-    // NOTE: error_code variants are used here to supress expception throwing.
-    // Error code of permission() calls is ignored on purpose - if they fail,
-    // the copy_file() function will fail appropriately and we don't want the permission()
-    // calls to cause needless failures on permissionless filesystems (ie. FATs on SD cards etc.)
-    // or when the target file doesn't exist.
-    boost::system::error_code ec;
-    boost::filesystem::permissions(target, perms, ec);
-    boost::filesystem::copy_file(source, target, boost::filesystem::copy_option::overwrite_if_exists, ec);
-    if (ec) {
-        return -1;
-    }
-    boost::filesystem::permissions(target, perms, ec);
+	// Make sure the file has correct permission both before and after we copy over it.
+	// NOTE: error_code variants are used here to supress expception throwing.
+	// Error code of permission() calls is ignored on purpose - if they fail,
+	// the copy_file() function will fail appropriately and we don't want the permission()
+	// calls to cause needless failures on permissionless filesystems (ie. FATs on SD cards etc.)
+	// or when the target file doesn't exist.
+	boost::system::error_code ec;
+	boost::filesystem::permissions(target, perms, ec);
+	boost::filesystem::copy_file(source, target, boost::filesystem::copy_option::overwrite_if_exists, ec);
+	if (ec) {
+		return -1;
+	}
+	boost::filesystem::permissions(target, perms, ec);
+	return 0;
+}
 
-    return 0;
+int copy_file(const std::string &from, const std::string &to, const bool with_check)
+{
+	std::string to_temp = to + ".tmp";
+	int ret_val = copy_file_inner(from,to_temp);
+	if(ret_val == 0 && with_check)
+	{
+		ret_val = check_copy(from, to_temp);
+		if (ret_val == 0)
+		{
+			rename_file(to_temp, to);
+		}
+	}
+	return ret_val;
+}
+
+int check_copy(const std::string &origin, const std::string &copy)
+{
+	std::ifstream f1(origin, std::ifstream::binary | std::ifstream::ate);
+	std::ifstream f2(copy, std::ifstream::binary | std::ifstream::ate);
+
+	if (f1.fail() || f2.fail()) {
+		return -1; 
+	}
+
+	if (f1.tellg() != f2.tellg()) {
+		return -1; 
+	}
+
+	f1.seekg(0, std::ifstream::beg);
+	f2.seekg(0, std::ifstream::beg);
+	bool ident = std::equal(std::istreambuf_iterator<char>(f1.rdbuf()),
+		std::istreambuf_iterator<char>(),
+		std::istreambuf_iterator<char>(f2.rdbuf()));
+	return(ident ? 0 : -1);
 }
 
 // Ignore system and hidden files, which may be created by the DropBox synchronisation process.
diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp
index a8b88dd03..9d6a2a5ec 100644
--- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp
+++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp
@@ -34,6 +34,7 @@
 #include <boost/nowide/cstdio.hpp>
 #include "I18N.hpp"
 #include "GUI.hpp"
+#include "RemovableDriveManager.hpp"
 
 namespace Slic3r {
 
@@ -107,7 +108,7 @@ void BackgroundSlicingProcess::process_fff()
 	    	//FIXME localize the messages
 	    	// Perform the final post-processing of the export path by applying the print statistics over the file name.
 	    	std::string export_path = m_fff_print->print_statistics().finalize_output_path(m_export_path);
-		    if (copy_file(m_temp_output_path, export_path) != 0)
+		    if (copy_file(m_temp_output_path, export_path, GUI::RemovableDriveManager::get_instance().is_path_on_removable_drive(export_path)) != 0)
 	    		throw std::runtime_error(_utf8(L("Copying of the temporary G-code to the output G-code failed. Maybe the SD card is write locked?")));
 	    	m_print->set_status(95, _utf8(L("Running post-processing scripts")));
 	    	run_post_process_scripts(export_path, m_fff_print->config());