From bb6734a499bf5a3d1ceec82a6d0a29b52c45a778 Mon Sep 17 00:00:00 2001 From: Maschell Date: Thu, 28 Jul 2022 13:27:44 +0200 Subject: [PATCH] Improve write error handling --- source/WUDDumperState.cpp | 6 +++- source/fs/WUDFileWriter.cpp | 3 +- source/fs/WUDFileWriter.h | 2 +- source/fs/WUXFileWriter.cpp | 50 ++++++++++++++++++++++------ source/fs/WUXFileWriter.h | 4 +-- source/fs/WriteOnlyFileWithCache.cpp | 4 +-- 6 files changed, 51 insertions(+), 18 deletions(-) diff --git a/source/WUDDumperState.cpp b/source/WUDDumperState.cpp index ec53ebb..4e8b31e 100644 --- a/source/WUDDumperState.cpp +++ b/source/WUDDumperState.cpp @@ -169,7 +169,11 @@ ApplicationState::eSubState WUDDumperState::update(Input *input) { this->setError(ERROR_WRITE_FAILED); return ApplicationState::SUBSTATE_RUNNING; } - this->fileHandle->finalize(); + if (!this->fileHandle->finalize()) { + DEBUG_FUNCTION_LINE_ERR("Finalize failed"); + this->setError(ERROR_WRITE_FAILED); + return ApplicationState::SUBSTATE_RUNNING; + } this->fileHandle->close(); } } diff --git a/source/fs/WUDFileWriter.cpp b/source/fs/WUDFileWriter.cpp index 2b284c0..57cf5e4 100644 --- a/source/fs/WUDFileWriter.cpp +++ b/source/fs/WUDFileWriter.cpp @@ -29,5 +29,6 @@ int32_t WUDFileWriter::writeSector(const uint8_t *buffer, uint32_t numberOfSecto return -1; } -void WUDFileWriter::finalize() { +bool WUDFileWriter::finalize() { + return true; } diff --git a/source/fs/WUDFileWriter.h b/source/fs/WUDFileWriter.h index 17fc21a..2ed429f 100644 --- a/source/fs/WUDFileWriter.h +++ b/source/fs/WUDFileWriter.h @@ -24,7 +24,7 @@ public: virtual int32_t writeSector(const uint8_t *buffer, uint32_t numberOfSectors); - virtual void finalize(); + virtual bool finalize(); protected: int32_t sectorSize; diff --git a/source/fs/WUXFileWriter.cpp b/source/fs/WUXFileWriter.cpp index e15a121..7206ff8 100644 --- a/source/fs/WUXFileWriter.cpp +++ b/source/fs/WUXFileWriter.cpp @@ -27,7 +27,11 @@ WUXFileWriter::WUXFileWriter(const char *path, int32_t cacheSize, int32_t sector wuxHeader.uncompressedSize = swap_uint64(WUD_FILE_SIZE); wuxHeader.flags = 0; - this->write((uint8_t *) &wuxHeader, sizeof(wuxHeader_t)); + if (this->write((uint8_t *) &wuxHeader, sizeof(wuxHeader_t)) != sizeof(wuxHeader_t)) { + DEBUG_FUNCTION_LINE_ERR("Failed to write header"); + WUDFileWriter::close(); + return; + } this->sectorTableStart = this->tell(); this->totalSectorCount = WUD_FILE_SIZE / this->sectorSize; @@ -39,7 +43,8 @@ WUXFileWriter::WUXFileWriter(const char *path, int32_t cacheSize, int32_t sector } memset(this->sectorIndexTable, 0, totalSectorCount * 4); - if (this->write((uint8_t *) this->sectorIndexTable, totalSectorCount * 4) < 0) { + if (this->write((uint8_t *) this->sectorIndexTable, totalSectorCount * 4) != (int32_t) ((uint32_t) totalSectorCount * 4)) { + DEBUG_FUNCTION_LINE_ERR("Failed to write initial sector index table"); WUDFileWriter::close(); return; } @@ -53,14 +58,24 @@ WUXFileWriter::WUXFileWriter(const char *path, int32_t cacheSize, int32_t sector uint64_t padding = this->sectorTableEnd - tableEnd; auto *paddingData = (uint8_t *) memalign(0x40, ROUNDUP(padding, 0x40)); memset(paddingData, 0, padding); - this->write(reinterpret_cast(paddingData), padding); + if (this->write(reinterpret_cast(paddingData), padding) != (int32_t) padding) { + DEBUG_FUNCTION_LINE_ERR("Failed to write padding."); + WUDFileWriter::close(); + return; + } free(paddingData); this->hashMap.clear(); - flush(); + if (!flush()) { + WUXFileWriter::close(); + } } int32_t WUXFileWriter::writeSector(const uint8_t *buffer, uint32_t numberOfSectors) { + if (!isOpen()) { + DEBUG_FUNCTION_LINE_ERR("Failed to write sector, file is not open"); + return -1; + } int32_t curWrittenSectors = 0; for (uint32_t i = 0; i < numberOfSectors; i++) { uint32_t addr = ((uint32_t) buffer) + (i * this->sectorSize); @@ -89,23 +104,36 @@ int32_t WUXFileWriter::writeSector(const uint8_t *buffer, uint32_t numberOfSecto return curWrittenSectors; } -void WUXFileWriter::writeSectorIndexTable() { +bool WUXFileWriter::writeSectorIndexTable() { if (this->isOpen()) { - flush(); + if (!flush()) { + return false; + } // We need to make sure to call CFile::seek! - seek((int64_t) sectorTableStart, SEEK_SET_BASE_CLASS); - write((uint8_t *) sectorIndexTable, totalSectorCount * 4); - flush(); + if (seek((int64_t) sectorTableStart, SEEK_SET_BASE_CLASS) < 0) { + DEBUG_FUNCTION_LINE_ERR("Seek failed"); + return false; + } + if (write((uint8_t *) sectorIndexTable, totalSectorCount * 4) != (int32_t) ((uint32_t) totalSectorCount * 4)) { + DEBUG_FUNCTION_LINE_ERR("Failed to write sector index table"); + return false; + } + if (!flush()) { + return false; + } } + return true; } WUXFileWriter::~WUXFileWriter() { + WUXFileWriter::flush(); WUXFileWriter::close(); free(sectorIndexTable); } -void WUXFileWriter::finalize() { +bool WUXFileWriter::finalize() { WUDFileWriter::finalize(); - writeSectorIndexTable(); + bool res = writeSectorIndexTable(); WUXFileWriter::close(); + return res; } diff --git a/source/fs/WUXFileWriter.h b/source/fs/WUXFileWriter.h index 8eed01b..440353c 100644 --- a/source/fs/WUXFileWriter.h +++ b/source/fs/WUXFileWriter.h @@ -39,10 +39,10 @@ public: int32_t writeSector(const uint8_t *buffer, uint32_t numberOfSectors) override; - void finalize() override; + bool finalize() override; private: - void writeSectorIndexTable(); + bool writeSectorIndexTable(); uint64_t totalSectorCount; diff --git a/source/fs/WriteOnlyFileWithCache.cpp b/source/fs/WriteOnlyFileWithCache.cpp index 62ecb3f..f45e9ec 100644 --- a/source/fs/WriteOnlyFileWithCache.cpp +++ b/source/fs/WriteOnlyFileWithCache.cpp @@ -45,7 +45,7 @@ WriteOnlyFileWithCache::~WriteOnlyFileWithCache() { bool WriteOnlyFileWithCache::flush() { if (this->writeBufferPos > 0) { int32_t res = CFile::write(static_cast(this->writeBuffer), this->writeBufferPos); - if (res != this->writeBufferPos) { + if (res != (int32_t) this->writeBufferPos) { DEBUG_FUNCTION_LINE_ERR("Failed to flush cache, write failed: %d (expected %d)", res, this->writeBufferPos); return false; } @@ -58,7 +58,7 @@ int32_t WriteOnlyFileWithCache::write(const uint8_t *addr, size_t writeSize) { auto finalAddr = addr; size_t finalWriteSize = writeSize; if (splitFile) { - if (pos + writeBufferPos + finalWriteSize >= SPLIT_SIZE) { + if (pos + writeBufferPos + finalWriteSize >= (uint64_t) SPLIT_SIZE) { DEBUG_FUNCTION_LINE("We need to split files"); if (!flush()) { return -2;