Index: src/libchcore/ErrorCodes.h =================================================================== diff -u -N -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 -N -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 IFilesystemFilePtr; Index: src/libchcore/TFakeFilesystemFile.cpp =================================================================== diff -u -N -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 #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( @@ -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 -N -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 -N -r479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc -r27a43e40952cf2f3e0bb0e608a8f3142042ceb46 --- src/libchcore/TLocalFilesystemFile.cpp (.../TLocalFilesystemFile.cpp) (revision 479ad4e8f81a68cbf6d1623cd9b1f3342d8cfdcc) +++ src/libchcore/TLocalFilesystemFile.cpp (.../TLocalFilesystemFile.cpp) (revision 27a43e40952cf2f3e0bb0e608a8f3142042ceb46) @@ -25,6 +25,8 @@ #include #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(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(rBuffer.GetRealDataSize()); DWORD dwReallyWritten = RoundUp(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 -N -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 -N -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 #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(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(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(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(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()); + // 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()); - // 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(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(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(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(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(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(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(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(GetLastError()).c_str()); - strFormat.Replace(_t("%count"), boost::lexical_cast(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(dwLastError).c_str()); + strFormat.Replace(_t("%count"), boost::lexical_cast(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(dwLastError).c_str()); - strFormat.Replace(_t("%count"), boost::lexical_cast(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(dwLastError).c_str()); + strFormat.Replace(_t("%count"), boost::lexical_cast(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(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(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 -N -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 @@ + @@ -768,6 +769,7 @@ + Index: src/libchcore/libchcore.vc140.vcxproj.filters =================================================================== diff -u -N -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 @@ {a77c6575-b7b7-4683-9295-d5173da8c76b} + + {b5e932b3-5a5a-465b-8ade-3354c81e1996} + @@ -461,6 +464,9 @@ Source Files\Tools\Exceptions + + Source Files\Filesystems\Exceptions + @@ -844,5 +850,8 @@ Source Files\Tools\Exceptions + + Source Files\Filesystems\Exceptions + \ No newline at end of file