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);
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();
}
}

View File

@ -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;
}

View File

@ -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;

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.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<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);
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;
}

View File

@ -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;

View File

@ -45,7 +45,7 @@ WriteOnlyFileWithCache::~WriteOnlyFileWithCache() {
bool WriteOnlyFileWithCache::flush() {
if (this->writeBufferPos > 0) {
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);
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;