Index: src/libchcore/ErrorCodes.h
===================================================================
diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -r27a43e40952cf2f3e0bb0e608a8f3142042ceb46
--- src/libchcore/ErrorCodes.h	(.../ErrorCodes.h)	(revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3)
+++ src/libchcore/ErrorCodes.h	(.../ErrorCodes.h)	(revision 27a43e40952cf2f3e0bb0e608a8f3142042ceb46)
@@ -79,6 +79,10 @@
 		eErr_CannotReadFile = 3003,
 		eErr_CannotWriteFile = 3004,
 		eErr_InvalidOverlappedPosition = 3005,
+		eErr_CannotOpenFile = 3006,
+		eErr_FileNotOpen = 3007,
+		eErr_SeekFailed = 3008,
+		eErr_CannotTruncate = 3009,
 
 		// Task handling errors (4000+)
 		eErr_MissingTaskSerializationPath = 4000,
Index: src/libchcore/IFilesystemFile.h
===================================================================
diff -u -r479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc -r27a43e40952cf2f3e0bb0e608a8f3142042ceb46
--- src/libchcore/IFilesystemFile.h	(.../IFilesystemFile.h)	(revision 479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc)
+++ src/libchcore/IFilesystemFile.h	(.../IFilesystemFile.h)	(revision 27a43e40952cf2f3e0bb0e608a8f3142042ceb46)
@@ -34,24 +34,23 @@
 	public:
 		virtual ~IFilesystemFile();
 
-		virtual bool OpenExistingForReading() = 0;
-		virtual bool CreateNewForWriting() = 0;
-		virtual bool OpenExistingForWriting() = 0;
+		virtual void OpenExistingForReading() = 0;
+		virtual void CreateNewForWriting() = 0;
+		virtual void OpenExistingForWriting() = 0;
 
-		virtual file_size_t GetSeekPositionForResume(file_size_t fsLastAvailablePosition) = 0;
+		virtual void Truncate(file_size_t fsNewSize) = 0;
 
-		virtual bool Truncate(file_size_t fsNewSize) = 0;
+		virtual void ReadFile(TOverlappedDataBuffer& rBuffer) = 0;
+		virtual void WriteFile(TOverlappedDataBuffer& rBuffer) = 0;
+		virtual void FinalizeFile(TOverlappedDataBuffer& rBuffer) = 0;
 
-		virtual bool ReadFile(TOverlappedDataBuffer& rBuffer) = 0;
-		virtual bool WriteFile(TOverlappedDataBuffer& rBuffer) = 0;
-		virtual bool FinalizeFile(TOverlappedDataBuffer& rBuffer) = 0;
-
 		virtual bool IsOpen() const = 0;
-		virtual unsigned long long GetFileSize() const = 0;
+		virtual file_size_t GetFileSize() const = 0;
 
 		virtual void Close() = 0;
 
 		virtual TSmartPath GetFilePath() const = 0;
+		virtual file_size_t GetSeekPositionForResume(file_size_t fsLastAvailablePosition) = 0;
 	};
 
 	typedef std::shared_ptr<IFilesystemFile> IFilesystemFilePtr;
Index: src/libchcore/TFakeFilesystemFile.cpp
===================================================================
diff -u -r479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc -r27a43e40952cf2f3e0bb0e608a8f3142042ceb46
--- src/libchcore/TFakeFilesystemFile.cpp	(.../TFakeFilesystemFile.cpp)	(revision 479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc)
+++ src/libchcore/TFakeFilesystemFile.cpp	(.../TFakeFilesystemFile.cpp)	(revision 27a43e40952cf2f3e0bb0e608a8f3142042ceb46)
@@ -23,6 +23,7 @@
 #include "TFakeFilesystem.h"
 #include <boost/numeric/conversion/cast.hpp>
 #include "RoundingFunctions.h"
+#include "TFileException.h"
 
 namespace
 {
@@ -87,7 +88,7 @@
 	{
 		TFakeFileDescriptionPtr spFileDesc = m_pFilesystem->FindFileByLocation(m_pathFile);
 		if (!spFileDesc)
-			return 0;
+			THROW_FILE_EXCEPTION(eErr_CannotGetFileInfo, ERROR_FILE_INVALID, m_pathFile, L"Cannot retrieve file info - file does not exist");
 
 		return spFileDesc->GetFileInfo().GetLength64();
 	}
@@ -97,21 +98,20 @@
 		return m_bIsOpen;
 	}
 
-	bool TFakeFilesystemFile::FinalizeFile(TOverlappedDataBuffer& /*rBuffer*/)
+	void TFakeFilesystemFile::FinalizeFile(TOverlappedDataBuffer& /*rBuffer*/)
 	{
 		// does nothing
-		return true;
 	}
 
-	bool TFakeFilesystemFile::WriteFile(TOverlappedDataBuffer& rBuffer)
+	void TFakeFilesystemFile::WriteFile(TOverlappedDataBuffer& rBuffer)
 	{
 		if (!IsOpen())
-			THROW_CORE_EXCEPTION(eErr_InternalProblem);
+			THROW_FILE_EXCEPTION(eErr_FileNotOpen, ERROR_INVALID_HANDLE, m_pathFile, L"Cannot write to closed file");
 
 		// file should have been created already by create for write functions
 		TFakeFileDescriptionPtr spFileDesc = m_pFilesystem->FindFileByLocation(m_pathFile);
 		if (!spFileDesc)
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotWriteFile, ERROR_FILE_INVALID, m_pathFile, L"Cannot write to non-existent file");
 
 		APCINFO* pInfo = new APCINFO;
 		unsigned long long ullNewSize = 0;
@@ -137,19 +137,17 @@
 
 		if (QueueUserAPC(WriteCompleted, GetCurrentThread(), (ULONG_PTR)pInfo) == 0)
 			THROW_CORE_EXCEPTION(eErr_InternalProblem);
-
-		return true;
 	}
 
-	bool TFakeFilesystemFile::ReadFile(TOverlappedDataBuffer& rBuffer)
+	void TFakeFilesystemFile::ReadFile(TOverlappedDataBuffer& rBuffer)
 	{
 		if (!IsOpen())
-			THROW_CORE_EXCEPTION(eErr_InternalProblem);
+			THROW_FILE_EXCEPTION(eErr_FileNotOpen, ERROR_INVALID_HANDLE, m_pathFile, L"Cannot read from closed file");
 
 		// check if we're reading the undamaged data
 		TFakeFileDescriptionPtr spFileDesc = m_pFilesystem->FindFileByLocation(m_pathFile);
 		if (!spFileDesc)
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotReadFile, ERROR_FILE_INVALID, m_pathFile, L"Cannot read from non-existent file");
 
 		const TSparseRangeMap& rmapDamage = spFileDesc->GetDamageMap();
 		if (rmapDamage.OverlapsRange(rBuffer.GetFilePosition(), rBuffer.GetRequestedDataSize()))
@@ -198,8 +196,6 @@
 			if (QueueUserAPC(ReadCompleted, GetCurrentThread(), (ULONG_PTR)pInfo) == 0)
 				THROW_CORE_EXCEPTION(eErr_InternalProblem);
 		}
-
-		return true;
 	}
 
 	file_size_t TFakeFilesystemFile::GetSeekPositionForResume(file_size_t fsLastAvailablePosition)
@@ -208,42 +204,39 @@
 		return fsMove;
 	}
 
-	bool TFakeFilesystemFile::Truncate(file_size_t fsNewSize)
+	void TFakeFilesystemFile::Truncate(file_size_t fsNewSize)
 	{
 		if (!IsOpen())
-			THROW_CORE_EXCEPTION(eErr_InternalProblem);
+			THROW_FILE_EXCEPTION(eErr_FileNotOpen, ERROR_INVALID_HANDLE, m_pathFile, L"Cannot truncate closed file");
 
 		// check if we're reading the undamaged data
 		TFakeFileDescriptionPtr spFileDesc = m_pFilesystem->FindFileByLocation(m_pathFile);
 		if (!spFileDesc)
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotTruncate, ERROR_FILE_INVALID, m_pathFile, L"Cannot truncate non-existent file");
 
 		spFileDesc->GetFileInfo().SetLength64(fsNewSize);
-		return true;
 	}
 
-	bool TFakeFilesystemFile::OpenExistingForWriting()
+	void TFakeFilesystemFile::OpenExistingForWriting()
 	{
 		TFakeFileDescriptionPtr spFileDesc = m_pFilesystem->FindFileByLocation(m_pathFile);
 		if (!spFileDesc)
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotOpenFile, ERROR_FILE_INVALID, m_pathFile, L"Cannot open existing for writing");
 
 		Close();
 
 		m_bIsOpen = true;
 		m_bModeReading = false;
-
-		return true;
 	}
 
-	bool TFakeFilesystemFile::CreateNewForWriting()
+	void TFakeFilesystemFile::CreateNewForWriting()
 	{
 		TFakeFileDescriptionPtr spFileDesc = m_pFilesystem->FindFileByLocation(m_pathFile);
 		if(!spFileDesc)
 		{
 			TFakeFileDescriptionPtr parentDesc = m_pFilesystem->FindFileByLocation(m_pathFile.GetParent());
 			if (!parentDesc)
-				return false;
+				THROW_FILE_EXCEPTION(eErr_CannotOpenFile, ERROR_FUNCTION_FAILED, m_pathFile, L"Cannot open existing for writing");
 
 			FILETIME ftCurrent = m_pFilesystem->GetCurrentFileTime();
 			TFakeFileDescriptionPtr spNewFile(std::make_shared<TFakeFileDescription>(
@@ -258,22 +251,18 @@
 
 		m_bIsOpen = true;
 		m_bModeReading = false;
-
-		return true;
 	}
 
-	bool TFakeFilesystemFile::OpenExistingForReading()
+	void TFakeFilesystemFile::OpenExistingForReading()
 	{
 		TFakeFileDescriptionPtr spFileDesc = m_pFilesystem->FindFileByLocation(m_pathFile);
 		if (!spFileDesc)
-			return false;
+			THROW_FILE_EXCEPTION(eErr_CannotOpenFile, ERROR_FILE_INVALID, m_pathFile, L"Cannot find file");
 
 		Close();
 
 		m_bIsOpen = true;
 		m_bModeReading = true;
-
-		return true;
 	}
 
 	void TFakeFilesystemFile::GenerateBufferContent(TOverlappedDataBuffer &rBuffer)
Index: src/libchcore/TFakeFilesystemFile.h
===================================================================
diff -u -r479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc -r27a43e40952cf2f3e0bb0e608a8f3142042ceb46
--- src/libchcore/TFakeFilesystemFile.h	(.../TFakeFilesystemFile.h)	(revision 479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc)
+++ src/libchcore/TFakeFilesystemFile.h	(.../TFakeFilesystemFile.h)	(revision 27a43e40952cf2f3e0bb0e608a8f3142042ceb46)
@@ -33,21 +33,20 @@
 		TFakeFilesystemFile(const TSmartPath& pathFile, bool bNoBuffering, TFakeFilesystem* pFilesystem);
 		~TFakeFilesystemFile();
 
-		virtual bool OpenExistingForReading() override;
-		virtual bool CreateNewForWriting() override;
-		virtual bool OpenExistingForWriting() override;
-		virtual bool Truncate(file_size_t fsNewSize) override;
-		virtual bool ReadFile(TOverlappedDataBuffer& rBuffer) override;
+		virtual void OpenExistingForReading() override;
+		virtual void CreateNewForWriting() override;
+		virtual void OpenExistingForWriting() override;
+		virtual void Truncate(file_size_t fsNewSize) override;
+		virtual void ReadFile(TOverlappedDataBuffer& rBuffer) override;
 
-		file_size_t GetSeekPositionForResume(file_size_t fsLastAvailablePosition) override;
-
-		virtual bool WriteFile(TOverlappedDataBuffer& rBuffer) override;
-		virtual bool FinalizeFile(TOverlappedDataBuffer& rBuffer) override;
+		virtual void WriteFile(TOverlappedDataBuffer& rBuffer) override;
+		virtual void FinalizeFile(TOverlappedDataBuffer& rBuffer) override;
 		virtual bool IsOpen() const override;
 		virtual unsigned long long GetFileSize() const override;
 		virtual void Close() override;
 
 		virtual TSmartPath GetFilePath() const override;
+		file_size_t GetSeekPositionForResume(file_size_t fsLastAvailablePosition) override;
 
 	private:
 		void GenerateBufferContent(TOverlappedDataBuffer &rBuffer);
Index: src/libchcore/TLocalFilesystemFile.cpp
===================================================================
diff -u -r479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc -r27a43e40952cf2f3e0bb0e608a8f3142042ceb46
--- src/libchcore/TLocalFilesystemFile.cpp	(.../TLocalFilesystemFile.cpp)	(revision 479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc)
+++ src/libchcore/TLocalFilesystemFile.cpp	(.../TLocalFilesystemFile.cpp)	(revision 27a43e40952cf2f3e0bb0e608a8f3142042ceb46)
@@ -25,6 +25,8 @@
 #include <boost/numeric/conversion/cast.hpp>
 #include "RoundingFunctions.h"
 #include "TLocalFilesystem.h"
+#include "TCoreWin32Exception.h"
+#include "TFileException.h"
 
 namespace chcore
 {
@@ -42,50 +44,59 @@
 
 	TLocalFilesystemFile::~TLocalFilesystemFile()
 	{
-		Close();
+		try
+		{
+			Close();
+		}
+		catch (const std::exception&)
+		{
+		}
 	}
 
 	constexpr DWORD TLocalFilesystemFile::GetFlagsAndAttributes(bool bNoBuffering) const
 	{
 		return FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FILE_FLAG_SEQUENTIAL_SCAN | (bNoBuffering ? FILE_FLAG_NO_BUFFERING : 0);
 	}
 
-	bool TLocalFilesystemFile::OpenExistingForReading()
+	void TLocalFilesystemFile::OpenExistingForReading()
 	{
 		Close();
 
 		m_hFile = ::CreateFile(m_pathFile.ToString(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, GetFlagsAndAttributes(m_bNoBuffering), NULL);
 		if (m_hFile == INVALID_HANDLE_VALUE)
-			return false;
-
-		return true;
+		{
+			DWORD dwLastError = GetLastError();
+			THROW_FILE_EXCEPTION(eErr_CannotOpenFile, dwLastError, m_pathFile, L"Cannot open for reading.");
+		}
 	}
 
-	bool TLocalFilesystemFile::CreateNewForWriting()
+	void TLocalFilesystemFile::CreateNewForWriting()
 	{
 		Close();
 
 		m_hFile = ::CreateFile(m_pathFile.ToString(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, GetFlagsAndAttributes(m_bNoBuffering), NULL);
 		if (m_hFile == INVALID_HANDLE_VALUE)
-			return false;
-
-		return true;
+		{
+			DWORD dwLastError = GetLastError();
+			THROW_FILE_EXCEPTION(eErr_CannotOpenFile, dwLastError, m_pathFile, L"Cannot create file.");
+		}
 	}
 
-	bool TLocalFilesystemFile::OpenExistingForWriting()
+	void TLocalFilesystemFile::OpenExistingForWriting()
 	{
-		return OpenExistingForWriting(m_bNoBuffering);
+		OpenExistingForWriting(m_bNoBuffering);
 	}
 
-	bool TLocalFilesystemFile::OpenExistingForWriting(bool bNoBuffering)
+	void TLocalFilesystemFile::OpenExistingForWriting(bool bNoBuffering)
 	{
 		Close();
 
 		m_hFile = CreateFile(m_pathFile.ToString(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, GetFlagsAndAttributes(bNoBuffering), NULL);
 		if (m_hFile == INVALID_HANDLE_VALUE)
-			return false;
-
-		return true;
+		{
+			DWORD dwLastError = GetLastError();
+			THROW_FILE_EXCEPTION(eErr_CannotOpenFile, dwLastError, m_pathFile, L"Cannot open for reading.");
+		}
 	}
 
 	file_size_t TLocalFilesystemFile::GetSeekPositionForResume(file_size_t fsLastAvailablePosition)
@@ -94,10 +105,10 @@
 		return fsMove;
 	}
 
-	bool TLocalFilesystemFile::Truncate(file_size_t fsNewSize)
+	void TLocalFilesystemFile::Truncate(file_size_t fsNewSize)
 	{
 		if (!IsOpen())
-			return false;
+			THROW_FILE_EXCEPTION(eErr_FileNotOpen, ERROR_INVALID_HANDLE, m_pathFile, L"File not open yet. Cannot truncate.");
 
 		// when no-buffering is used, there are cases where we'd need to switch to buffered ops
 		// to adjust file size
@@ -108,10 +119,8 @@
 			if (fsNewAlignedSize != fsNewSize)
 			{
 				Close();
+				OpenExistingForWriting(false);
 
-				if (!OpenExistingForWriting(false))
-					return false;
-
 				bFileSettingsChanged = true;
 			}
 		}
@@ -122,21 +131,26 @@
 		li.QuadPart = fsNewSize;
 
 		if (!SetFilePointerEx(m_hFile, li, &liNew, FILE_BEGIN))
-			return false;
+		{
+			DWORD dwLastError = GetLastError();
+			THROW_FILE_EXCEPTION(eErr_SeekFailed, dwLastError, m_pathFile, L"Cannot seek to appropriate position");
+		}
 
-		bool bResult = ::SetEndOfFile(m_hFile) != FALSE;
+		if(!::SetEndOfFile(m_hFile))
+		{
+			DWORD dwLastError = GetLastError();
+			THROW_FILE_EXCEPTION(eErr_CannotTruncate, dwLastError, m_pathFile, L"Cannot mark the end of file");
+		}
 
 		// close the file that was open in inappropriate mode
 		if(bFileSettingsChanged)
 			Close();
-
-		return bResult;
 	}
 
-	bool TLocalFilesystemFile::ReadFile(TOverlappedDataBuffer& rBuffer)
+	void TLocalFilesystemFile::ReadFile(TOverlappedDataBuffer& rBuffer)
 	{
 		if (!IsOpen())
-			THROW_CORE_EXCEPTION(eErr_InternalProblem);
+			THROW_FILE_EXCEPTION(eErr_FileNotOpen, ERROR_INVALID_HANDLE, m_pathFile, L"Cannot read from closed file");
 
 		ATLTRACE(_T("Reading %lu bytes\n"), rBuffer.GetRequestedDataSize());
 		if (!::ReadFileEx(m_hFile, rBuffer.GetBufferPtr(), rBuffer.GetRequestedDataSize(), &rBuffer, OverlappedReadCompleted))
@@ -145,30 +159,28 @@
 			switch (dwLastError)
 			{
 			case ERROR_IO_PENDING:
-				return true;
+				return;
 
 			case ERROR_HANDLE_EOF:
-			{
-				rBuffer.SetBytesTransferred(0);
-				rBuffer.SetStatusCode(0);
-				rBuffer.SetErrorCode(ERROR_SUCCESS);
-				rBuffer.SetLastPart(true);
+				{
+					rBuffer.SetBytesTransferred(0);
+					rBuffer.SetStatusCode(0);
+					rBuffer.SetErrorCode(ERROR_SUCCESS);
+					rBuffer.SetLastPart(true);
 
-				rBuffer.RequeueAsFull();	// basically the same as OverlappedReadCompleted
+					rBuffer.RequeueAsFull();	// basically the same as OverlappedReadCompleted
+				}
 
-				return true;
+			default:
+				THROW_FILE_EXCEPTION(eErr_CannotReadFile, dwLastError, m_pathFile, L"Error reading data from file");
 			}
-			}
-
-			return false;
 		}
-		return true;
 	}
 
-	bool TLocalFilesystemFile::WriteFile(TOverlappedDataBuffer& rBuffer)
+	void TLocalFilesystemFile::WriteFile(TOverlappedDataBuffer& rBuffer)
 	{
 		if (!IsOpen())
-			THROW_CORE_EXCEPTION(eErr_InternalProblem);
+			THROW_FILE_EXCEPTION(eErr_FileNotOpen, ERROR_INVALID_HANDLE, m_pathFile, L"Cannot write to closed file");
 
 		DWORD dwToWrite = boost::numeric_cast<DWORD>(rBuffer.GetRealDataSize());
 
@@ -178,38 +190,32 @@
 		ATLTRACE(_T("Writing %lu bytes\n"), dwToWrite);
 		if (!::WriteFileEx(m_hFile, rBuffer.GetBufferPtr(), dwToWrite, &rBuffer, OverlappedWriteCompleted))
 		{
-			if (GetLastError() == ERROR_IO_PENDING)
-				return true;
-			return false;
+			DWORD dwLastError = GetLastError();
+			if (dwLastError != ERROR_IO_PENDING)
+				THROW_FILE_EXCEPTION(eErr_CannotWriteFile, dwLastError, m_pathFile, L"Error while writing to file");
 		}
-
-		return true;
 	}
 
-	bool TLocalFilesystemFile::FinalizeFile(TOverlappedDataBuffer& rBuffer)
+	void TLocalFilesystemFile::FinalizeFile(TOverlappedDataBuffer& rBuffer)
 	{
 		if (!IsOpen())
-			THROW_CORE_EXCEPTION(eErr_InternalProblem);
+			THROW_FILE_EXCEPTION(eErr_FileNotOpen, ERROR_INVALID_HANDLE, m_pathFile, L"Cannot write to closed file");
 
 		if (m_bNoBuffering && rBuffer.IsLastPart())
 		{
 			DWORD dwToWrite = boost::numeric_cast<DWORD>(rBuffer.GetRealDataSize());
 			DWORD dwReallyWritten = RoundUp<DWORD>(dwToWrite, MaxSectorSize);
 
 			ATLTRACE(_T("Finalize file - size diff: written: %I64u, required: %I64u\n"), dwReallyWritten, dwToWrite);
-
 			if (dwToWrite != dwReallyWritten)
 			{
 				file_size_t fsNewFileSize = rBuffer.GetFilePosition() + dwToWrite;	// new size
 
 				//seek
 				ATLTRACE(_T("Truncating file to %I64u bytes\n"), fsNewFileSize);
-				if (!Truncate(fsNewFileSize))
-					return false;
+				Truncate(fsNewFileSize);
 			}
 		}
-
-		return true;
 	}
 
 	void TLocalFilesystemFile::Close()
@@ -219,7 +225,7 @@
 		m_hFile = INVALID_HANDLE_VALUE;
 	}
 
-	unsigned long long TLocalFilesystemFile::GetFileSize() const
+	file_size_t TLocalFilesystemFile::GetFileSize() const
 	{
 		if (!IsOpen())
 			return 0;
Index: src/libchcore/TLocalFilesystemFile.h
===================================================================
diff -u -r479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc -r27a43e40952cf2f3e0bb0e608a8f3142042ceb46
--- src/libchcore/TLocalFilesystemFile.h	(.../TLocalFilesystemFile.h)	(revision 479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc)
+++ src/libchcore/TLocalFilesystemFile.h	(.../TLocalFilesystemFile.h)	(revision 27a43e40952cf2f3e0bb0e608a8f3142042ceb46)
@@ -31,30 +31,29 @@
 	public:
 		virtual ~TLocalFilesystemFile();
 
-		virtual bool OpenExistingForReading() override;
-		virtual bool CreateNewForWriting() override;
-		virtual bool OpenExistingForWriting() override;
+		virtual void OpenExistingForReading() override;
+		virtual void CreateNewForWriting() override;
+		virtual void OpenExistingForWriting() override;
 
-		virtual file_size_t GetSeekPositionForResume(file_size_t fsLastAvailablePosition);
+		virtual void Truncate(file_size_t fsNewSize) override;
 
-		virtual bool Truncate(file_size_t fsNewSize) override;
+		virtual void ReadFile(TOverlappedDataBuffer& rBuffer) override;
+		virtual void WriteFile(TOverlappedDataBuffer& rBuffer) override;
+		virtual void FinalizeFile(TOverlappedDataBuffer& rBuffer) override;
 
-		virtual bool ReadFile(TOverlappedDataBuffer& rBuffer) override;
-		virtual bool WriteFile(TOverlappedDataBuffer& rBuffer) override;
-		virtual bool FinalizeFile(TOverlappedDataBuffer& rBuffer) override;
-
 		virtual bool IsOpen() const  override { return m_hFile != INVALID_HANDLE_VALUE; }
-		virtual unsigned long long GetFileSize() const override;
+		virtual file_size_t GetFileSize() const override;
 		virtual TSmartPath GetFilePath() const override;
 
 		virtual void Close() override;
+		virtual file_size_t GetSeekPositionForResume(file_size_t fsLastAvailablePosition) override;
 
 	private:
 		TLocalFilesystemFile(const TSmartPath& pathFile, bool bNoBuffering);
 
 		constexpr DWORD GetFlagsAndAttributes(bool bNoBuffering) const;
 
-		bool OpenExistingForWriting(bool bNoBuffering);
+		void OpenExistingForWriting(bool bNoBuffering);
 
 	private:
 		TSmartPath m_pathFile;
Index: src/libchcore/TSubTaskCopyMove.cpp
===================================================================
diff -u -r0c48142d3db406c32c05d7afdf77da45b2459b34 -r27a43e40952cf2f3e0bb0e608a8f3142042ceb46
--- src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision 0c48142d3db406c32c05d7afdf77da45b2459b34)
+++ src/libchcore/TSubTaskCopyMove.cpp	(.../TSubTaskCopyMove.cpp)	(revision 27a43e40952cf2f3e0bb0e608a8f3142042ceb46)
@@ -46,6 +46,7 @@
 #include "RoundingFunctions.h"
 #include <array>
 #include "TTaskConfigBufferSizes.h"
+#include "TFileException.h"
 
 namespace chcore
 {
@@ -704,46 +705,54 @@
 		{
 			bRetry = false;
 
-			if(!fileSrc->OpenExistingForReading())
+			DWORD dwLastError = ERROR_SUCCESS;
+
+			try
 			{
-				DWORD dwLastError = GetLastError();
+				fileSrc->OpenExistingForReading();
 
-				EFeedbackResult frResult = spFeedbackHandler->FileError(fileSrc->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError);
-				switch(frResult)
-				{
-				case EFeedbackResult::eResult_Skip:
-					break;	// will return INVALID_HANDLE_VALUE
+				return TSubTaskBase::eSubResult_Continue;
+			}
+			catch (const TFileException& e)
+			{
+				dwLastError = e.GetNativeError();
+			}
 
-				case EFeedbackResult::eResult_Cancel:
-					{
-						// log
-						TString strFormat = _T("Cancel request [error %errno] while opening source file %path (OpenSourceFileFB)");
-						strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-						strFormat.Replace(_T("%path"), fileSrc->GetFilePath().ToString());
-						rLog.loge(strFormat.c_str());
+			EFeedbackResult frResult = spFeedbackHandler->FileError(fileSrc->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError);
+			switch(frResult)
+			{
+			case EFeedbackResult::eResult_Skip:
+				break;	// will return INVALID_HANDLE_VALUE
 
-						return TSubTaskBase::eSubResult_CancelRequest;
-					}
+			case EFeedbackResult::eResult_Cancel:
+				{
+					// log
+					TString strFormat = _T("Cancel request [error %errno] while opening source file %path (OpenSourceFileFB)");
+					strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
+					strFormat.Replace(_T("%path"), fileSrc->GetFilePath().ToString());
+					rLog.loge(strFormat.c_str());
 
-				case EFeedbackResult::eResult_Pause:
-					return TSubTaskBase::eSubResult_PauseRequest;
+					return TSubTaskBase::eSubResult_CancelRequest;
+				}
 
-				case EFeedbackResult::eResult_Retry:
-					{
-						// log
-						TString strFormat = _T("Retrying [error %errno] to open source file %path (OpenSourceFileFB)");
-						strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-						strFormat.Replace(_T("%path"), fileSrc->GetFilePath().ToString());
-						rLog.loge(strFormat.c_str());
+			case EFeedbackResult::eResult_Pause:
+				return TSubTaskBase::eSubResult_PauseRequest;
 
-						bRetry = true;
-						break;
-					}
+			case EFeedbackResult::eResult_Retry:
+				{
+					// log
+					TString strFormat = _T("Retrying [error %errno] to open source file %path (OpenSourceFileFB)");
+					strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
+					strFormat.Replace(_T("%path"), fileSrc->GetFilePath().ToString());
+					rLog.loge(strFormat.c_str());
 
-				default:
-					BOOST_ASSERT(FALSE);		// unknown result
-					THROW_CORE_EXCEPTION(eErr_UnhandledCase);
+					bRetry = true;
+					break;
 				}
+
+			default:
+				BOOST_ASSERT(FALSE);		// unknown result
+				THROW_CORE_EXCEPTION(eErr_UnhandledCase);
 			}
 		}
 		while(bRetry);
@@ -767,132 +776,80 @@
 		{
 			bRetry = false;
 
-			if(!fileDst->CreateNewForWriting())
+			DWORD dwLastError = ERROR_SUCCESS;
+			try
 			{
-				DWORD dwLastError = GetLastError();
-				if(dwLastError == ERROR_FILE_EXISTS)
-				{
-					bFreshlyCreated = false;
+				fileDst->CreateNewForWriting();
+				return TSubTaskBase::eSubResult_Continue;
+			}
+			catch (const TFileException& e)
+			{
+				dwLastError = e.GetNativeError();
+			}
 
-					// pass it to the specialized method
-					TSubTaskBase::ESubOperationResult eResult = OpenExistingDestinationFileFB(spFeedbackHandler, fileDst);
-					if(eResult != TSubTaskBase::eSubResult_Continue)
-						return eResult;
-					else if(!fileDst->IsOpen())
-						return TSubTaskBase::eSubResult_Continue;
+			if(dwLastError == ERROR_FILE_EXISTS)
+			{
+				bFreshlyCreated = false;
 
-					// read info about the existing destination file,
-					// NOTE: it is not known which one would be faster - reading file parameters
-					//       by using spDstFileInfo->Create() (which uses FindFirstFile()) or by
-					//       reading parameters using opened handle; need to be tested in the future
-					TFileInfoPtr spDstFileInfo(boost::make_shared<TFileInfo>());
+				// pass it to the specialized method
+				TSubTaskBase::ESubOperationResult eResult = OpenExistingDestinationFileFB(spFeedbackHandler, fileDst);
+				if(eResult != TSubTaskBase::eSubResult_Continue)
+					return eResult;
+				else if(!fileDst->IsOpen())
+					return TSubTaskBase::eSubResult_Continue;
 
-					if(!spFilesystem->GetFileInfo(fileDst->GetFilePath(), spDstFileInfo))
-						THROW_CORE_EXCEPTION_WIN32(eErr_CannotGetFileInfo, GetLastError());
+				// read info about the existing destination file,
+				// NOTE: it is not known which one would be faster - reading file parameters
+				//       by using spDstFileInfo->Create() (which uses FindFirstFile()) or by
+				//       reading parameters using opened handle; need to be tested in the future
+				TFileInfoPtr spDstFileInfo(boost::make_shared<TFileInfo>());
 
-					// src and dst files are the same
-					EFeedbackResult frResult = spFeedbackHandler->FileAlreadyExists(spSrcFileInfo, spDstFileInfo);
-					switch(frResult)
-					{
-					case EFeedbackResult::eResult_Overwrite:
-						ullSeekTo = 0;
-						break;
+				if(!spFilesystem->GetFileInfo(fileDst->GetFilePath(), spDstFileInfo))
+					THROW_CORE_EXCEPTION_WIN32(eErr_CannotGetFileInfo, GetLastError());
 
-					case EFeedbackResult::eResult_CopyRest:
-						ullSeekTo = spDstFileInfo->GetLength64();
-						break;
+				// src and dst files are the same
+				EFeedbackResult frResult = spFeedbackHandler->FileAlreadyExists(spSrcFileInfo, spDstFileInfo);
+				switch(frResult)
+				{
+				case EFeedbackResult::eResult_Overwrite:
+					ullSeekTo = 0;
+					break;
 
-					case EFeedbackResult::eResult_Skip:
-						return TSubTaskBase::eSubResult_Continue;
+				case EFeedbackResult::eResult_CopyRest:
+					ullSeekTo = spDstFileInfo->GetLength64();
+					break;
 
-					case EFeedbackResult::eResult_Cancel:
-						{
-							// log
-							TString strFormat = _T("Cancel request while checking result of dialog before opening source file %path (CustomCopyFileFB)");
-							strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString());
-							rLog.logi(strFormat.c_str());
+				case EFeedbackResult::eResult_Skip:
+					return TSubTaskBase::eSubResult_Continue;
 
-							return TSubTaskBase::eSubResult_CancelRequest;
-						}
-					case EFeedbackResult::eResult_Pause:
-						return TSubTaskBase::eSubResult_PauseRequest;
-
-					default:
-						BOOST_ASSERT(FALSE);		// unknown result
-						THROW_CORE_EXCEPTION(eErr_UnhandledCase);
-					}
-				}
-				else
-				{
-					EFeedbackResult frResult = spFeedbackHandler->FileError(fileDst->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError);
-					switch(frResult)
+				case EFeedbackResult::eResult_Cancel:
 					{
-					case EFeedbackResult::eResult_Retry:
-						{
-							// log
-							TString strFormat = _T("Retrying [error %errno] to open destination file %path (CustomCopyFileFB)");
-							strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-							strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString());
-							rLog.loge(strFormat.c_str());
+						// log
+						TString strFormat = _T("Cancel request while checking result of dialog before opening source file %path (CustomCopyFileFB)");
+						strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString());
+						rLog.logi(strFormat.c_str());
 
-							bRetry = true;
-
-							break;
-						}
-					case EFeedbackResult::eResult_Cancel:
-						{
-							// log
-							TString strFormat = _T("Cancel request [error %errno] while opening destination file %path (CustomCopyFileFB)");
-							strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-							strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString());
-							rLog.loge(strFormat.c_str());
-
-							return TSubTaskBase::eSubResult_CancelRequest;
-						}
-
-					case EFeedbackResult::eResult_Skip:
-						break;		// will return invalid handle value
-
-					case EFeedbackResult::eResult_Pause:
-						return TSubTaskBase::eSubResult_PauseRequest;
-
-					default:
-						BOOST_ASSERT(FALSE);		// unknown result
-						THROW_CORE_EXCEPTION(eErr_UnhandledCase);
+						return TSubTaskBase::eSubResult_CancelRequest;
 					}
+				case EFeedbackResult::eResult_Pause:
+					return TSubTaskBase::eSubResult_PauseRequest;
+
+				default:
+					BOOST_ASSERT(FALSE);		// unknown result
+					THROW_CORE_EXCEPTION(eErr_UnhandledCase);
 				}
 			}
-		}
-		while(bRetry);
-
-		return TSubTaskBase::eSubResult_Continue;
-	}
-
-	TSubTaskBase::ESubOperationResult TSubTaskCopyMove::OpenExistingDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileDst)
-	{
-		icpf::log_file& rLog = GetContext().GetLog();
-
-		bool bRetry = false;
-
-		fileDst->Close();
-
-		do
-		{
-			bRetry = false;
-
-			if(!fileDst->OpenExistingForWriting())
+			else
 			{
-				DWORD dwLastError = GetLastError();
-
 				EFeedbackResult frResult = spFeedbackHandler->FileError(fileDst->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError);
-				switch (frResult)
+				switch(frResult)
 				{
 				case EFeedbackResult::eResult_Retry:
 					{
 						// log
 						TString strFormat = _T("Retrying [error %errno] to open destination file %path (CustomCopyFileFB)");
 						strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-						strFormat.Replace(_t("%path"), fileDst->GetFilePath().ToString());
+						strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString());
 						rLog.loge(strFormat.c_str());
 
 						bRetry = true;
@@ -927,6 +884,71 @@
 		return TSubTaskBase::eSubResult_Continue;
 	}
 
+	TSubTaskBase::ESubOperationResult TSubTaskCopyMove::OpenExistingDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileDst)
+	{
+		icpf::log_file& rLog = GetContext().GetLog();
+
+		bool bRetry = false;
+
+		fileDst->Close();
+
+		do
+		{
+			bRetry = false;
+
+			DWORD dwLastError = ERROR_SUCCESS;
+			try
+			{
+				fileDst->OpenExistingForWriting();
+				return TSubTaskBase::eSubResult_Continue;
+			}
+			catch (const TFileException& e)
+			{
+				dwLastError = e.GetNativeError();
+			}
+
+			EFeedbackResult frResult = spFeedbackHandler->FileError(fileDst->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError);
+			switch (frResult)
+			{
+			case EFeedbackResult::eResult_Retry:
+				{
+					// log
+					TString strFormat = _T("Retrying [error %errno] to open destination file %path (CustomCopyFileFB)");
+					strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
+					strFormat.Replace(_t("%path"), fileDst->GetFilePath().ToString());
+					rLog.loge(strFormat.c_str());
+
+					bRetry = true;
+
+					break;
+				}
+			case EFeedbackResult::eResult_Cancel:
+				{
+					// log
+					TString strFormat = _T("Cancel request [error %errno] while opening destination file %path (CustomCopyFileFB)");
+					strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
+					strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString());
+					rLog.loge(strFormat.c_str());
+
+					return TSubTaskBase::eSubResult_CancelRequest;
+				}
+
+			case EFeedbackResult::eResult_Skip:
+				break;		// will return invalid handle value
+
+			case EFeedbackResult::eResult_Pause:
+				return TSubTaskBase::eSubResult_PauseRequest;
+
+			default:
+				BOOST_ASSERT(FALSE);		// unknown result
+				THROW_CORE_EXCEPTION(eErr_UnhandledCase);
+			}
+		}
+		while(bRetry);
+
+		return TSubTaskBase::eSubResult_Continue;
+	}
+
 	TSubTaskBase::ESubOperationResult TSubTaskCopyMove::TruncateFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, file_size_t fsNewSize, 
 		const TSmartPath& pathFile, bool& bSkip)
 	{
@@ -937,36 +959,43 @@
 		bool bRetry = false;
 		do
 		{
-			if(!spFile->Truncate(fsNewSize))
+			DWORD dwLastError = ERROR_SUCCESS;
+
+			try
 			{
-				// log
-				DWORD dwLastError = GetLastError();
+				spFile->Truncate(fsNewSize);
+				return TSubTaskBase::eSubResult_Continue;
+			}
+			catch (const TFileException& e)
+			{
+				dwLastError = e.GetNativeError();
+			}
 
-				TString strFormat = _T("Error %errno while truncating file %path to 0");
-				strFormat.Replace(_t("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-				strFormat.Replace(_t("%path"), pathFile.ToString());
-				rLog.loge(strFormat.c_str());
+			TString strFormat = _T("Error %errno while truncating file %path to 0");
+			strFormat.Replace(_t("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
+			strFormat.Replace(_t("%path"), pathFile.ToString());
+			rLog.loge(strFormat.c_str());
 
-				EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eResizeError, dwLastError);
-				switch(frResult)
-				{
-				case EFeedbackResult::eResult_Cancel:
-					return TSubTaskBase::eSubResult_CancelRequest;
+			EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eResizeError, dwLastError);
+			switch(frResult)
+			{
+			case EFeedbackResult::eResult_Cancel:
+				return TSubTaskBase::eSubResult_CancelRequest;
 
-				case EFeedbackResult::eResult_Retry:
-					bRetry = true;
+			case EFeedbackResult::eResult_Retry:
+				bRetry = true;
+				break;
 
-				case EFeedbackResult::eResult_Pause:
-					return TSubTaskBase::eSubResult_PauseRequest;
+			case EFeedbackResult::eResult_Pause:
+				return TSubTaskBase::eSubResult_PauseRequest;
 
-				case EFeedbackResult::eResult_Skip:
-					bSkip = true;
-					return TSubTaskBase::eSubResult_Continue;
+			case EFeedbackResult::eResult_Skip:
+				bSkip = true;
+				return TSubTaskBase::eSubResult_Continue;
 
-				default:
-					BOOST_ASSERT(FALSE);		// unknown result
-					THROW_CORE_EXCEPTION(eErr_UnhandledCase);
-				}
+			default:
+				BOOST_ASSERT(FALSE);		// unknown result
+				THROW_CORE_EXCEPTION(eErr_UnhandledCase);
 			}
 		}
 		while(bRetry);
@@ -985,35 +1014,44 @@
 		{
 			bRetry = false;
 
-			if(!spFile->ReadFile(rBuffer))
+			DWORD dwLastError = ERROR_SUCCESS;
+
+			try
 			{
-				TString strFormat = _T("Error %errno while requesting read of %count bytes from source file %path (CustomCopyFileFB)");
-				strFormat.Replace(_t("%errno"), boost::lexical_cast<std::wstring>(GetLastError()).c_str());
-				strFormat.Replace(_t("%count"), boost::lexical_cast<std::wstring>(rBuffer.GetRequestedDataSize()).c_str());
-				strFormat.Replace(_t("%path"), pathFile.ToString());
-				rLog.loge(strFormat.c_str());
+				spFile->ReadFile(rBuffer);
+				return TSubTaskBase::eSubResult_Continue;
+			}
+			catch (const TFileException& e)
+			{
+				dwLastError = e.GetNativeError();
+			}
 
-				EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eReadError, GetLastError());
-				switch(frResult)
-				{
-				case EFeedbackResult::eResult_Cancel:
-					return TSubTaskBase::eSubResult_CancelRequest;
+			TString strFormat = _T("Error %errno while requesting read of %count bytes from source file %path (CustomCopyFileFB)");
+			strFormat.Replace(_t("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
+			strFormat.Replace(_t("%count"), boost::lexical_cast<std::wstring>(rBuffer.GetRequestedDataSize()).c_str());
+			strFormat.Replace(_t("%path"), pathFile.ToString());
+			rLog.loge(strFormat.c_str());
 
-				case EFeedbackResult::eResult_Retry:
-					bRetry = true;
-					break;
+			EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eReadError, dwLastError);
+			switch(frResult)
+			{
+			case EFeedbackResult::eResult_Cancel:
+				return TSubTaskBase::eSubResult_CancelRequest;
 
-				case EFeedbackResult::eResult_Pause:
-					return TSubTaskBase::eSubResult_PauseRequest;
+			case EFeedbackResult::eResult_Retry:
+				bRetry = true;
+				break;
 
-				case EFeedbackResult::eResult_Skip:
-					bSkip = true;
-					return TSubTaskBase::eSubResult_Continue;
+			case EFeedbackResult::eResult_Pause:
+				return TSubTaskBase::eSubResult_PauseRequest;
 
-				default:
-					BOOST_ASSERT(FALSE);		// unknown result
-					THROW_CORE_EXCEPTION(eErr_UnhandledCase);
-				}
+			case EFeedbackResult::eResult_Skip:
+				bSkip = true;
+				return TSubTaskBase::eSubResult_Continue;
+
+			default:
+				BOOST_ASSERT(FALSE);		// unknown result
+				THROW_CORE_EXCEPTION(eErr_UnhandledCase);
 			}
 		}
 		while(bRetry);
@@ -1072,38 +1110,44 @@
 		{
 			bRetry = false;
 
-			if(!spFile->WriteFile(rBuffer))
+			DWORD dwLastError = ERROR_SUCCESS;
+
+			try
 			{
-				// log
-				DWORD dwLastError = GetLastError();
+				spFile->WriteFile(rBuffer);
+				return TSubTaskBase::eSubResult_Continue;
+			}
+			catch (const TFileException& e)
+			{
+				dwLastError = e.GetNativeError();
+			}
 
-				TString strFormat = _T("Error %errno while trying to write %count bytes to destination file %path (CustomCopyFileFB)");
-				strFormat.Replace(_t("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-				strFormat.Replace(_t("%count"), boost::lexical_cast<std::wstring>(rBuffer.GetBytesTransferred()).c_str());
-				strFormat.Replace(_t("%path"), pathFile.ToString());
-				rLog.loge(strFormat.c_str());
+			TString strFormat = _T("Error %errno while trying to write %count bytes to destination file %path (CustomCopyFileFB)");
+			strFormat.Replace(_t("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
+			strFormat.Replace(_t("%count"), boost::lexical_cast<std::wstring>(rBuffer.GetBytesTransferred()).c_str());
+			strFormat.Replace(_t("%path"), pathFile.ToString());
+			rLog.loge(strFormat.c_str());
 
-				EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eWriteError, dwLastError);
-				switch(frResult)
-				{
-				case EFeedbackResult::eResult_Cancel:
-					return TSubTaskBase::eSubResult_CancelRequest;
+			EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eWriteError, dwLastError);
+			switch(frResult)
+			{
+			case EFeedbackResult::eResult_Cancel:
+				return TSubTaskBase::eSubResult_CancelRequest;
 
-				case EFeedbackResult::eResult_Retry:
-					bRetry = true;
-					break;
+			case EFeedbackResult::eResult_Retry:
+				bRetry = true;
+				break;
 
-				case EFeedbackResult::eResult_Pause:
-					return TSubTaskBase::eSubResult_PauseRequest;
+			case EFeedbackResult::eResult_Pause:
+				return TSubTaskBase::eSubResult_PauseRequest;
 
-				case EFeedbackResult::eResult_Skip:
-					bSkip = true;
-					return TSubTaskBase::eSubResult_Continue;
+			case EFeedbackResult::eResult_Skip:
+				bSkip = true;
+				return TSubTaskBase::eSubResult_Continue;
 
-				default:
-					BOOST_ASSERT(FALSE);		// unknown result
-					THROW_CORE_EXCEPTION(eErr_UnhandledCase);
-				}
+			default:
+				BOOST_ASSERT(FALSE);		// unknown result
+				THROW_CORE_EXCEPTION(eErr_UnhandledCase);
 			}
 		}
 		while(bRetry);
@@ -1162,37 +1206,43 @@
 		{
 			bRetry = false;
 
-			if (!spFile->FinalizeFile(rBuffer))
+			DWORD dwLastError = ERROR_SUCCESS;
+
+			try
 			{
-				// log
-				DWORD dwLastError = GetLastError();
+				spFile->FinalizeFile(rBuffer);
+				return TSubTaskBase::eSubResult_Continue;
+			}
+			catch (const TFileException& e)
+			{
+				dwLastError = e.GetNativeError();
+			}
 
-				TString strFormat = _T("Error %errno while trying to finalize file %path (CustomCopyFileFB)");
-				strFormat.Replace(_t("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
-				strFormat.Replace(_t("%path"), pathFile.ToString());
-				rLog.loge(strFormat.c_str());
+			TString strFormat = _T("Error %errno while trying to finalize file %path (CustomCopyFileFB)");
+			strFormat.Replace(_t("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
+			strFormat.Replace(_t("%path"), pathFile.ToString());
+			rLog.loge(strFormat.c_str());
 
-				EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eFinalizeError, dwLastError);
-				switch (frResult)
-				{
-				case EFeedbackResult::eResult_Cancel:
-					return TSubTaskBase::eSubResult_CancelRequest;
+			EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eFinalizeError, dwLastError);
+			switch (frResult)
+			{
+			case EFeedbackResult::eResult_Cancel:
+				return TSubTaskBase::eSubResult_CancelRequest;
 
-				case EFeedbackResult::eResult_Retry:
-					bRetry = true;
-					break;
+			case EFeedbackResult::eResult_Retry:
+				bRetry = true;
+				break;
 
-				case EFeedbackResult::eResult_Pause:
-					return TSubTaskBase::eSubResult_PauseRequest;
+			case EFeedbackResult::eResult_Pause:
+				return TSubTaskBase::eSubResult_PauseRequest;
 
-				case EFeedbackResult::eResult_Skip:
-					bSkip = true;
-					return TSubTaskBase::eSubResult_Continue;
+			case EFeedbackResult::eResult_Skip:
+				bSkip = true;
+				return TSubTaskBase::eSubResult_Continue;
 
-				default:
-					BOOST_ASSERT(FALSE);		// unknown result
-					THROW_CORE_EXCEPTION(eErr_UnhandledCase);
-				}
+			default:
+				BOOST_ASSERT(FALSE);		// unknown result
+				THROW_CORE_EXCEPTION(eErr_UnhandledCase);
 			}
 		}
 		while (bRetry);
Index: src/libchcore/libchcore.vc140.vcxproj
===================================================================
diff -u -r0c48142d3db406c32c05d7afdf77da45b2459b34 -r27a43e40952cf2f3e0bb0e608a8f3142042ceb46
--- src/libchcore/libchcore.vc140.vcxproj	(.../libchcore.vc140.vcxproj)	(revision 0c48142d3db406c32c05d7afdf77da45b2459b34)
+++ src/libchcore/libchcore.vc140.vcxproj	(.../libchcore.vc140.vcxproj)	(revision 27a43e40952cf2f3e0bb0e608a8f3142042ceb46)
@@ -536,6 +536,7 @@
     <ClInclude Include="TFileErrorFilter.h" />
     <ClInclude Include="TFileInfoFwd.h" />
     <ClInclude Include="TFileTime.h" />
+    <ClInclude Include="TFileException.h" />
     <ClInclude Include="TLocalFilesystemFile.h" />
     <ClInclude Include="TLocalFilesystemFind.h" />
     <ClInclude Include="TModificationTracker.h" />
@@ -768,6 +769,7 @@
     <ClCompile Include="TFileAlreadyExistsFilter.cpp" />
     <ClCompile Include="TFileErrorFilter.cpp" />
     <ClCompile Include="TFileTime.cpp" />
+    <ClCompile Include="TFileException.cpp" />
     <ClCompile Include="TLocalFilesystemFile.cpp" />
     <ClCompile Include="TLocalFilesystemFind.cpp" />
     <ClCompile Include="TModPathContainer.cpp" />
Index: src/libchcore/libchcore.vc140.vcxproj.filters
===================================================================
diff -u -r0c48142d3db406c32c05d7afdf77da45b2459b34 -r27a43e40952cf2f3e0bb0e608a8f3142042ceb46
--- src/libchcore/libchcore.vc140.vcxproj.filters	(.../libchcore.vc140.vcxproj.filters)	(revision 0c48142d3db406c32c05d7afdf77da45b2459b34)
+++ src/libchcore/libchcore.vc140.vcxproj.filters	(.../libchcore.vc140.vcxproj.filters)	(revision 27a43e40952cf2f3e0bb0e608a8f3142042ceb46)
@@ -78,6 +78,9 @@
     <Filter Include="Source Files\Tools\Exceptions">
       <UniqueIdentifier>{a77c6575-b7b7-4683-9295-d5173da8c76b}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Source Files\Filesystems\Exceptions">
+      <UniqueIdentifier>{b5e932b3-5a5a-465b-8ade-3354c81e1996}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="ESubTaskTypes.h">
@@ -461,6 +464,9 @@
     <ClInclude Include="TCoreStdException.h">
       <Filter>Source Files\Tools\Exceptions</Filter>
     </ClInclude>
+    <ClInclude Include="TFileException.h">
+      <Filter>Source Files\Filesystems\Exceptions</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="TSubTaskArray.cpp">
@@ -844,5 +850,8 @@
     <ClCompile Include="TCoreStdException.cpp">
       <Filter>Source Files\Tools\Exceptions</Filter>
     </ClCompile>
+    <ClCompile Include="TFileException.cpp">
+      <Filter>Source Files\Filesystems\Exceptions</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file