From 7c3997775c25728b3720375f30b858563a5c7273 Mon Sep 17 00:00:00 2001 From: Maschell Date: Wed, 27 Jul 2022 19:00:56 +0200 Subject: [PATCH] Fix handling of discs without a discId --- README.md | 2 +- source/GMPartitionsDumperState.cpp | 19 +++++++++++++------ source/GMPartitionsDumperState.h | 4 ++++ source/WUDDumperState.cpp | 30 +++++++++++++++++++----------- source/WUDDumperState.h | 2 ++ 5 files changed, 39 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 11288a1..4aa54a4 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Features: - Dump the GM Partitions (Game, Updates, DLCs) of an Wii U Disc as *.app,*.h3, .tmd, .tik, .cert files - Supports dumping to SD (FAT32) and USB (NTFS only). When dumping to SD the files get slitted in 2 GiB parts. -Files will be dumped to `/wudump/[DISC-ID]/`. The DiscID of a game can be found on the disc (e.g. WUP-P-ARDP for the EUR version of Super Mario 3D World). +Files will be dumped to `/wudump/[DISC-ID]/`. The disc id of a game can be found on the disc (e.g. WUP-P-ARDP for the EUR version of Super Mario 3D World). If WUDD fails to determine the disc id, "DISC" with a timestamp will be used instead. ## How to merge splitted files diff --git a/source/GMPartitionsDumperState.cpp b/source/GMPartitionsDumperState.cpp index 7fbff41..cc1e538 100644 --- a/source/GMPartitionsDumperState.cpp +++ b/source/GMPartitionsDumperState.cpp @@ -32,6 +32,7 @@ GMPartitionsDumperState::GMPartitionsDumperState(eDumpTarget pTargetDevice) : ta this->sectorBufSize = SECTOR_SIZE; this->state = STATE_OPEN_ODD1; gBlockHomeButton = true; + dumpStartDate = OSGetTime(); } GMPartitionsDumperState::~GMPartitionsDumperState() { @@ -198,11 +199,6 @@ ApplicationState::eSubState GMPartitionsDumperState::update(Input *input) { if (FSAEx_RawRead(__wut_devoptab_fs_client, this->sectorBuf, READ_SECTOR_SIZE, 1, 0, this->oddFd) >= 0) { this->discId[10] = '\0'; memcpy(this->discId.data(), sectorBuf, 10); - if (this->discId[0] == 0) { - setError(ERROR_NO_DISC_ID); - return ApplicationState::SUBSTATE_RUNNING; - } - this->state = STATE_READ_DISC_INFO_DONE; return ApplicationState::SUBSTATE_RUNNING; } @@ -278,7 +274,7 @@ ApplicationState::eSubState GMPartitionsDumperState::update(Input *input) { return SUBSTATE_RUNNING; } - this->targetPath = string_format("%swudump/%s/%s", getPathForDevice(targetDevice).c_str(), this->discId, curPartition->getVolumeId().c_str()); + this->targetPath = string_format("%swudump/%s/%s", getPathForDevice(targetDevice).c_str(), getPathNameForDisc().c_str(), curPartition->getVolumeId().c_str()); if (!FSUtils::CreateSubfolder(targetPath.c_str())) { this->setError(ERROR_CREATE_DIR); return SUBSTATE_RUNNING; @@ -557,3 +553,14 @@ std::string GMPartitionsDumperState::ErrorDescription() const { } return "UNKNOWN_ERROR"; } + +std::string GMPartitionsDumperState::getPathNameForDisc() { + if (this->discId[0] == '\0') { + OSCalendarTime tm; + OSTicksToCalendarTime(this->dumpStartDate, &tm); + return string_format("DISC-%04d-%02d-%02d-%02d-%02d-%02d", + tm.tm_year, tm.tm_mon + 1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + } + return std::string((char *) &discId[0]); +} diff --git a/source/GMPartitionsDumperState.h b/source/GMPartitionsDumperState.h index c900d89..d9899bc 100644 --- a/source/GMPartitionsDumperState.h +++ b/source/GMPartitionsDumperState.h @@ -114,4 +114,8 @@ public: std::vector, std::shared_ptr>> gmPartitionPairs; eDumpTarget targetDevice = TARGET_SD; + + std::string getPathNameForDisc(); + + OSTime dumpStartDate; }; \ No newline at end of file diff --git a/source/WUDDumperState.cpp b/source/WUDDumperState.cpp index 57bdeaf..0b292ad 100644 --- a/source/WUDDumperState.cpp +++ b/source/WUDDumperState.cpp @@ -30,6 +30,7 @@ WUDDumperState::WUDDumperState(WUDDumperState::eDumpTargetFormat pTargetFormat, this->sectorBufSize = READ_SECTOR_SIZE * READ_NUM_SECTORS; this->state = STATE_OPEN_ODD1; gBlockHomeButton = true; + this->dumpStartDate = OSGetTime(); } WUDDumperState::~WUDDumperState() { @@ -85,10 +86,6 @@ ApplicationState::eSubState WUDDumperState::update(Input *input) { if (FSAEx_RawRead(__wut_devoptab_fs_client, this->sectorBuf, READ_SECTOR_SIZE, 1, 0, this->oddFd) >= 0) { this->discId[10] = '\0'; memcpy(this->discId.data(), sectorBuf, 10); - if (this->discId[0] == 0) { - setError(ERROR_NO_DISC_ID); - return ApplicationState::SUBSTATE_RUNNING; - } this->state = STATE_READ_DISC_INFO_DONE; return ApplicationState::SUBSTATE_RUNNING; } @@ -112,26 +109,26 @@ ApplicationState::eSubState WUDDumperState::update(Input *input) { } if (hasDiscKey) { - if (!FSUtils::CreateSubfolder(string_format("%swudump/%s", getPathForDevice(targetDevice).c_str(), discId).c_str())) { + if (!FSUtils::CreateSubfolder(string_format("%swudump/%s", getPathForDevice(targetDevice).c_str(), getPathNameForDisc().c_str()).c_str())) { setError(ERROR_WRITE_FAILED); return SUBSTATE_RUNNING; } - if (!FSUtils::saveBufferToFile(string_format("%swudump/%s/game.key", getPathForDevice(targetDevice).c_str(), discId).c_str(), discKey.key, 16)) { + if (!FSUtils::saveBufferToFile(string_format("%swudump/%s/game.key", getPathForDevice(targetDevice).c_str(), getPathNameForDisc().c_str()).c_str(), discKey.key, 16)) { setError(ERROR_WRITE_FAILED); return SUBSTATE_RUNNING; } } this->state = STATE_DUMP_DISC_START; } else if (this->state == STATE_DUMP_DISC_START) { - if (!FSUtils::CreateSubfolder(string_format("%swudump/%s", getPathForDevice(targetDevice).c_str(), discId).c_str())) { + if (!FSUtils::CreateSubfolder(string_format("%swudump/%s", getPathForDevice(targetDevice).c_str(), getPathNameForDisc().c_str()).c_str())) { setError(ERROR_WRITE_FAILED); return ApplicationState::SUBSTATE_RUNNING; } if (targetFormat == DUMP_AS_WUX) { - this->fileHandle = std::make_unique(string_format("%swudump/%s/game.wux", getPathForDevice(targetDevice).c_str(), discId).c_str(), READ_SECTOR_SIZE * WRITE_BUFFER_NUM_SECTORS, + this->fileHandle = std::make_unique(string_format("%swudump/%s/game.wux", getPathForDevice(targetDevice).c_str(), getPathNameForDisc().c_str()).c_str(), READ_SECTOR_SIZE * WRITE_BUFFER_NUM_SECTORS, SECTOR_SIZE, targetDevice == TARGET_SD); } else { - this->fileHandle = std::make_unique(string_format("%swudump/%s/game.wud", getPathForDevice(targetDevice).c_str(), discId).c_str(), READ_SECTOR_SIZE * WRITE_BUFFER_NUM_SECTORS, + this->fileHandle = std::make_unique(string_format("%swudump/%s/game.wud", getPathForDevice(targetDevice).c_str(), getPathNameForDisc().c_str()).c_str(), READ_SECTOR_SIZE * WRITE_BUFFER_NUM_SECTORS, SECTOR_SIZE, targetDevice == TARGET_SD); } if (!this->fileHandle->isOpen()) { @@ -264,9 +261,9 @@ void WUDDumperState::render() { } else if (this->state == STATE_READ_DISC_INFO) { WiiUScreen::drawLine("Read disc information"); } else if (this->state == STATE_READ_DISC_INFO_DONE) { - WiiUScreen::drawLinef("Dumping: %s", this->discId); + WiiUScreen::drawLinef("Dumping: %s", getPathNameForDisc().c_str()); } else if (this->state == STATE_DUMP_DISC_START || this->state == STATE_DUMP_DISC || this->state == STATE_WAIT_USER_ERROR_CONFIRM) { - WiiUScreen::drawLinef("Dumping: %s", this->discId); + WiiUScreen::drawLinef("Dumping: %s", getPathNameForDisc().c_str()); float percent = this->currentSector / (WUD_FILE_SIZE / READ_SECTOR_SIZE * 1.0f) * 100.0f; WiiUScreen::drawLinef("Progress: %0.2f MiB / %5.2f MiB (%2.1f %%)", this->currentSector * (READ_SECTOR_SIZE / 1024.0f / 1024.0f), WUD_FILE_SIZE / 1024.0f / 1024.0f, percent); @@ -362,3 +359,14 @@ std::string WUDDumperState::getPathForDevice(eDumpTarget target) const { } return "fs:/vol/external01/"; } + +std::string WUDDumperState::getPathNameForDisc() { + if (this->discId[0] == '\0') { + OSCalendarTime tm; + OSTicksToCalendarTime(this->dumpStartDate, &tm); + return string_format("DISC-%04d-%02d-%02d-%02d-%02d-%02d", + tm.tm_year, tm.tm_mon + 1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + } + return std::string((char *) &discId[0]); +} diff --git a/source/WUDDumperState.h b/source/WUDDumperState.h index e45e346..99d520e 100644 --- a/source/WUDDumperState.h +++ b/source/WUDDumperState.h @@ -110,4 +110,6 @@ public: int32_t writtenSectors{}; void *emptySector = nullptr; + std::string getPathNameForDisc(); + OSTime dumpStartDate; }; \ No newline at end of file