Improve write error handling

This commit is contained in:
Maschell 2022-07-28 13:27:44 +02:00
parent bc74da90dc
commit bb6734a499
6 changed files with 51 additions and 18 deletions

View File

@ -169,7 +169,11 @@ ApplicationState::eSubState WUDDumperState::update(Input *input) {
this->setError(ERROR_WRITE_FAILED); this->setError(ERROR_WRITE_FAILED);
return ApplicationState::SUBSTATE_RUNNING; 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(); this->fileHandle->close();
} }
} }

View File

@ -29,5 +29,6 @@ int32_t WUDFileWriter::writeSector(const uint8_t *buffer, uint32_t numberOfSecto
return -1; return -1;
} }
void WUDFileWriter::finalize() { bool WUDFileWriter::finalize() {
return true;
} }

View File

@ -24,7 +24,7 @@ public:
virtual int32_t writeSector(const uint8_t *buffer, uint32_t numberOfSectors); virtual int32_t writeSector(const uint8_t *buffer, uint32_t numberOfSectors);
virtual void finalize(); virtual bool finalize();
protected: protected:
int32_t sectorSize; int32_t sectorSize;

View File

@ -27,7 +27,11 @@ WUXFileWriter::WUXFileWriter(const char *path, int32_t cacheSize, int32_t sector
wuxHeader.uncompressedSize = swap_uint64(WUD_FILE_SIZE); wuxHeader.uncompressedSize = swap_uint64(WUD_FILE_SIZE);
wuxHeader.flags = 0; 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->sectorTableStart = this->tell();
this->totalSectorCount = WUD_FILE_SIZE / this->sectorSize; 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); 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(); WUDFileWriter::close();
return; return;
} }
@ -53,14 +58,24 @@ WUXFileWriter::WUXFileWriter(const char *path, int32_t cacheSize, int32_t sector
uint64_t padding = this->sectorTableEnd - tableEnd; uint64_t padding = this->sectorTableEnd - tableEnd;
auto *paddingData = (uint8_t *) memalign(0x40, ROUNDUP(padding, 0x40)); auto *paddingData = (uint8_t *) memalign(0x40, ROUNDUP(padding, 0x40));
memset(paddingData, 0, padding); memset(paddingData, 0, padding);
this->write(reinterpret_cast<const uint8_t *>(paddingData), padding); if (this->write(reinterpret_cast<const uint8_t *>(paddingData), padding) != (int32_t) padding) {
DEBUG_FUNCTION_LINE_ERR("Failed to write padding.");
WUDFileWriter::close();
return;
}
free(paddingData); free(paddingData);
this->hashMap.clear(); this->hashMap.clear();
flush(); if (!flush()) {
WUXFileWriter::close();
}
} }
int32_t WUXFileWriter::writeSector(const uint8_t *buffer, uint32_t numberOfSectors) { 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; int32_t curWrittenSectors = 0;
for (uint32_t i = 0; i < numberOfSectors; i++) { for (uint32_t i = 0; i < numberOfSectors; i++) {
uint32_t addr = ((uint32_t) buffer) + (i * this->sectorSize); 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; return curWrittenSectors;
} }
void WUXFileWriter::writeSectorIndexTable() { bool WUXFileWriter::writeSectorIndexTable() {
if (this->isOpen()) { if (this->isOpen()) {
flush(); if (!flush()) {
// We need to make sure to call CFile::seek! return false;
seek((int64_t) sectorTableStart, SEEK_SET_BASE_CLASS);
write((uint8_t *) sectorIndexTable, totalSectorCount * 4);
flush();
} }
// We need to make sure to call CFile::seek!
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::~WUXFileWriter() {
WUXFileWriter::flush();
WUXFileWriter::close(); WUXFileWriter::close();
free(sectorIndexTable); free(sectorIndexTable);
} }
void WUXFileWriter::finalize() { bool WUXFileWriter::finalize() {
WUDFileWriter::finalize(); WUDFileWriter::finalize();
writeSectorIndexTable(); bool res = writeSectorIndexTable();
WUXFileWriter::close(); WUXFileWriter::close();
return res;
} }

View File

@ -39,10 +39,10 @@ public:
int32_t writeSector(const uint8_t *buffer, uint32_t numberOfSectors) override; int32_t writeSector(const uint8_t *buffer, uint32_t numberOfSectors) override;
void finalize() override; bool finalize() override;
private: private:
void writeSectorIndexTable(); bool writeSectorIndexTable();
uint64_t totalSectorCount; uint64_t totalSectorCount;

View File

@ -45,7 +45,7 @@ WriteOnlyFileWithCache::~WriteOnlyFileWithCache() {
bool WriteOnlyFileWithCache::flush() { bool WriteOnlyFileWithCache::flush() {
if (this->writeBufferPos > 0) { if (this->writeBufferPos > 0) {
int32_t res = CFile::write(static_cast<const uint8_t *>(this->writeBuffer), this->writeBufferPos); int32_t res = CFile::write(static_cast<const uint8_t *>(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); DEBUG_FUNCTION_LINE_ERR("Failed to flush cache, write failed: %d (expected %d)", res, this->writeBufferPos);
return false; return false;
} }
@ -58,7 +58,7 @@ int32_t WriteOnlyFileWithCache::write(const uint8_t *addr, size_t writeSize) {
auto finalAddr = addr; auto finalAddr = addr;
size_t finalWriteSize = writeSize; size_t finalWriteSize = writeSize;
if (splitFile) { if (splitFile) {
if (pos + writeBufferPos + finalWriteSize >= SPLIT_SIZE) { if (pos + writeBufferPos + finalWriteSize >= (uint64_t) SPLIT_SIZE) {
DEBUG_FUNCTION_LINE("We need to split files"); DEBUG_FUNCTION_LINE("We need to split files");
if (!flush()) { if (!flush()) {
return -2; return -2;