diff --git a/apps/cdbackup/meta.xml b/apps/cdbackup/meta.xml index 378109d..df996d4 100644 --- a/apps/cdbackup/meta.xml +++ b/apps/cdbackup/meta.xml @@ -1,8 +1,8 @@ cdbackup - 1.2.0 - 20230802000000 + 1.2.1 + 20231105004800 thepikachugamer Backup/restore/delete Wii message board data. Backup/restore your Wii message board data to cdbackup.vff on your SD card or USB drive, or delete it entirely. diff --git a/include/fatMounter.h b/include/fatMounter.h index 7f874df..001f816 100644 --- a/include/fatMounter.h +++ b/include/fatMounter.h @@ -1,19 +1,7 @@ -#ifndef _FATMOUNTER_H_ -#define _FATMOUNTER_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -// Prototypes -int MountSD(void); -void UnmountSD(void); -int MountUSB(void); -void UnmountUSB(void); - -#ifdef __cplusplus -} -#endif - -#endif +#include + +bool mountSD(); +void unmountSD(); + +bool mountUSB(); +void unmountUSB(); diff --git a/include/fs.h b/include/fs.h new file mode 100644 index 0000000..0f16bbc --- /dev/null +++ b/include/fs.h @@ -0,0 +1,13 @@ +#include +#include + +typedef int (*RWCallback)(size_t read, size_t filesize); + +#define MAXIMUM(max, size) ( ( size > max ) ? max : size ) +#define FS_CHUNK 1048576 + +int FS_Read(const char* filepath, unsigned char** buffer, size_t* filesize, RWCallback cb); +int FS_Write(const char* filepath, unsigned char* buffer, size_t filesize, RWCallback cb); +int FAT_Read(const char* filepath, unsigned char** buffer, size_t* filesize, RWCallback cb); +int FAT_Write(const char* filepath, unsigned char* buffer, size_t filesize, RWCallback cb); +int progressbar(size_t read, size_t filesize); diff --git a/include/tools.h b/include/tools.h index 916f54f..631565b 100644 --- a/include/tools.h +++ b/include/tools.h @@ -23,10 +23,9 @@ extern uint16_t input_btns; extern uint32_t wii_down; extern uint16_t gcn_down; -void init_video(int row, int col); +[[gnu::constructor]] void init_video(); void input_scan(void); - -int quit(int ret); +[[noreturn]] void quit(int ret); bool confirmation(const char* message, unsigned int wait_time); diff --git a/source/fatMounter.c b/source/fatMounter.c index 33adf73..0483946 100644 --- a/source/fatMounter.c +++ b/source/fatMounter.c @@ -1,198 +1,62 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// These are the only stable and speed is good -#define CACHE 8 -#define SECTORS 64 -#define BYTES_PER_READ 512 - -extern DISC_INTERFACE __io_usbstorage; - -enum BPB -{ - BPB_jmpBoot = 0x00, - BPB_OEMName = 0x03, - - // BIOS Parameter Block - BPB_bytesPerSector = 0x0B, - BPB_sectorsPerCluster = 0x0D, - BPB_reservedSectors = 0x0E, - BPB_numFATs = 0x10, - BPB_rootEntries = 0x11, - BPB_numSectorsSmall = 0x13, - BPB_mediaDesc = 0x15, - BPB_sectorsPerFAT = 0x16, - BPB_sectorsPerTrk = 0x18, - BPB_numHeads = 0x1A, - BPB_numHiddenSectors = 0x1C, - BPB_numSectors = 0x20, - - // Ext BIOS Parameter Block for FAT16 - BPB_FAT16_driveNumber = 0x24, - BPB_FAT16_reserved1 = 0x25, - BPB_FAT16_extBootSig = 0x26, - BPB_FAT16_volumeID = 0x27, - BPB_FAT16_volumeLabel = 0x2B, - BPB_FAT16_fileSysType = 0x36, - - // Bootcode - BPB_FAT16_bootCode = 0x3E, - - // FAT32 Extended Block - BPB_FAT32_sectorsPerFAT32 = 0x24, - BPB_FAT32_extFlags = 0x28, - BPB_FAT32_fsVer = 0x2A, - BPB_FAT32_rootClus = 0x2C, - BPB_FAT32_fsInfo = 0x30, - BPB_FAT32_bkBootSec = 0x32, - - // Ext BIOS Parameter Block for FAT32 - BPB_FAT32_driveNumber = 0x40, - BPB_FAT32_reserved1 = 0x41, - BPB_FAT32_extBootSig = 0x42, - BPB_FAT32_volumeID = 0x43, - BPB_FAT32_volumeLabel = 0x47, - BPB_FAT32_fileSysType = 0x52, - - // Bootcode - BPB_FAT32_bootCode = 0x5A, - BPB_bootSig_55 = 0x1FE, - BPB_bootSig_AA = 0x1FF -}; - -static const char FAT_SIG[3] = {'F', 'A', 'T'}; -static bool sd_mounted = false; -static bool usb_mounted = false; - -static bool _FAT_partition_isFAT(const DISC_INTERFACE* disc, sec_t startSector) -{ - uint8_t sectorBuffer[BYTES_PER_READ] = {0}; - - if (!disc->readSectors(startSector, 1, sectorBuffer)) return false; - - // Make sure it is a valid BPB - if ((sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) return false; - - // Now verify that this is indeed a FAT partition - if (memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) && memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) return false; - - // Check again for the last two cases to make sure that we really have a FAT filesystem here and won't corrupt any data - if(memcmp(sectorBuffer + BPB_FAT16_fileSysType, "FAT", 3) != 0 && memcmp(sectorBuffer + BPB_FAT32_fileSysType, "FAT32", 5) != 0) return false; - - return true; -} - -static inline uint32_t u8array_to_u32 (const uint8_t* item, int offset) -{ - return (item[offset] | (item[offset + 1] << 8) | (item[offset + 2] << 16) | (item[offset + 3] << 24)); -} - -sec_t GetFATPartition(const DISC_INTERFACE* disc) -{ - int i; - uint8_t sectorBuffer[BYTES_PER_READ] = {0}; - sec_t startSector = 0; - - if (!disc->startup()) return 0; - - // Read first sector of disc - if (!disc->readSectors(0, 1, sectorBuffer)) startSector = 0; - - // Make sure it is a valid MBR or boot sector - if ((sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) startSector = 0; - - if (!memcmp(sectorBuffer+BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG))) - { - // Check if there is a FAT string, which indicates this is a boot sector - startSector = 0; - } - else if (!memcmp(sectorBuffer+BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) - { - // Check for FAT32 - startSector = 0; - } - else - { - // This is an MBR - // Find first valid partition from MBR - // First check for an active partition - for (i = 0x1BE; (i < 0x1FE) && (sectorBuffer[i] != 0x80); i+= 0x10); - - // If it find an active partition, check for FAT Partition - if (i != 0x1FE && !_FAT_partition_isFAT(disc, u8array_to_u32(sectorBuffer, 0x8+i))) i = 0x1FE; - - // If it didn't find an active partition, search for any valid partition - if (i == 0x1FE) - { - for (i = 0x1BE; i < 0x1FE; i+= 0x10) - { - if (sectorBuffer[i+0x04] != 0x00 && _FAT_partition_isFAT(disc, u8array_to_u32(sectorBuffer, 0x8+i))) break; - } - } - - if (i != 0x1FE) startSector = u8array_to_u32(sectorBuffer, 0x8+i); - } - - disc->shutdown(); - - return startSector; -} - -int MountSD(void) -{ - // Close all open files write back the cache and then shutdown them - fatUnmount("sd"); - - // Mount first FAT partition - if (fatMount("sd", &__io_wiisd, GetFATPartition(&__io_wiisd), CACHE, SECTORS)) - { - sd_mounted = true; - return 1; - } - return -1; -} - -void UnmountSD(void) -{ - if (!sd_mounted) return; - // Close all open files write back the cache and then shutdown them - fatUnmount("sd"); - sd_mounted = false; -} - -int MountUSB() -{ - fatUnmount("usb"); - __io_usbstorage.startup(); - if ((usb_mounted = __io_usbstorage.isInserted())) - { - int retry = 10; - while ((retry) && ((usb_mounted = fatMountSimple("usb", &__io_usbstorage)) == false)) - { - sleep(1); - retry--; - } - } - return usb_mounted; -} - -void UnmountUSB(void) -{ - - if(!usb_mounted) return; - /* Unmount device */ - fatUnmount("usb"); - - /* Shutdown interface */ - __io_usbstorage.shutdown(); - usb_mounted = false; -} - +#include "fatMounter.h" + +#include +#include +#include +#include +#include + +static const DISC_INTERFACE *sd_card = &__io_wiisd, + *usb_msc = &__io_usbstorage; + +static bool sd_mounted = false, + usb_mounted = false; + +bool mountSD() { + if (sd_mounted) return sd_mounted; + + sd_card->startup(); + if (!sd_card->isInserted()) { + sd_card->shutdown(); + errno = ENODEV; + return false; + } + sd_mounted = fatMountSimple("sd", sd_card); + chdir("sd:/"); + return sd_mounted; +} + +void unmountSD() { + if (sd_mounted) { + fatUnmount("sd"); + sd_card->shutdown(); + sd_mounted = false; + } +} + +bool mountUSB() { + if (usb_mounted) return usb_mounted; + + usb_msc->startup(); + if (!usb_msc->isInserted()) { + usb_msc->shutdown(); + errno = ENODEV; + return false; + } + +// for(int r = 0; r < 10; r++) { + usb_mounted = fatMountSimple("usb", usb_msc); +// if(usb_mounted) break; +// } + chdir("usb:/"); + return usb_mounted; +} + +void unmountUSB() { + if (usb_mounted) { + fatUnmount("usb"); + usb_msc->shutdown(); + usb_mounted = false; + } +} + diff --git a/source/fs.c b/source/fs.c new file mode 100644 index 0000000..105a405 --- /dev/null +++ b/source/fs.c @@ -0,0 +1,162 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "fs.h" + +extern void* memalign(size_t, size_t); + +[[gnu::aligned(0x20)]] static fstats stats; +[[gnu::aligned(0x20)]] static unsigned char tmp_buf[FS_CHUNK]; + +int progressbar(size_t read, size_t total) { + printf("\r["); + for (size_t i = 0; i < total; i += FS_CHUNK) { + if (i < read) + putchar('='); + else + putchar(' '); + } + printf("] %u / %u bytes (%.2f%%) ", read, total, (read / (double)total) * 100); + + return 0; +} + +int FS_Read(const char* filepath, unsigned char** buffer, size_t* filesize, RWCallback callback) { + int ret = ISFS_Open(filepath, ISFS_OPEN_READ); + if (ret < 0) + return ret; + + int fd = ret; + + ret = ISFS_GetFileStats(fd, &stats); + if (ret < 0) { + ISFS_Close(fd); + return ret; + } + *filesize = stats.file_length; + + *buffer = memalign(0x20, *filesize); + if (!*buffer) { + ISFS_Close(fd); + return -ENOMEM; + } + + size_t read = 0; + while (read < *filesize) { + ret = ISFS_Read(fd, tmp_buf, FS_CHUNK); + if (ret <= 0) + break; + + memcpy((*buffer) + read, tmp_buf, ret); + read += ret; + if (callback) callback(read, *filesize); + } + + ISFS_Close(fd); + + if (read == *filesize) + return 0; + + free(*buffer); + if (ret < 0) + return ret; + else + return -EIO; +} + +int FAT_Read(const char* filepath, unsigned char** buffer, size_t* filesize, RWCallback callback) { + FILE* fp = fopen(filepath, "rb"); + if (!fp) + return -errno; + + fseek(fp, 0, SEEK_END); + *filesize = ftell(fp); + fseek(fp, 0, SEEK_SET); + if(!*filesize) + return -105; + + *buffer = memalign(0x20, *filesize); + if(!*buffer) { + fclose(fp); + return -ENOMEM; + }; + + size_t read = 0; + while (read < *filesize) { + size_t _read = fread(tmp_buf, 1, FS_CHUNK, fp); + if (!_read) + break; + + memcpy((*buffer) + read, tmp_buf, _read); + read += _read; + if (callback) callback(read, *filesize); + } + fclose(fp); + + if (read == *filesize) + return 0; + + free(*buffer); + if (errno) //? + return -errno; + else + return -EIO; +} + +int FS_Write(const char* filepath, unsigned char* buffer, size_t filesize, RWCallback callback) { + int ret = ISFS_Open(filepath, ISFS_OPEN_WRITE); + if (ret < 0) + return ret; + + int fd = ret; + + size_t wrote = 0; + while (wrote < filesize) { + size_t _count = MAXIMUM(FS_CHUNK, filesize - wrote); + memcpy(tmp_buf, buffer + wrote, _count); + ret = ISFS_Write(fd, tmp_buf, _count); + if (ret <= 0) + break; + + wrote += ret; + if (callback) callback(wrote, filesize); + } + + ISFS_Close(fd); + if (wrote == filesize) + return 0; + else if (ret < 0) + return ret; + else + return -EIO; +} + +int FAT_Write(const char* filepath, unsigned char* buffer, size_t filesize, RWCallback callback) { + FILE *fp = fopen(filepath, "wb"); + if (!fp) return -errno; + + size_t wrote = 0; + while (wrote < filesize) { + size_t _count = MAXIMUM(FS_CHUNK, filesize - wrote); + memcpy(tmp_buf, buffer + wrote, _count); + size_t _wrote = fwrite(tmp_buf, 1, _count, fp); + if (!_wrote) + break; + + wrote += _wrote; + if (callback) callback(wrote, filesize); + } + fclose(fp); + + if (wrote == filesize) + return 0; + else if (errno) //? + return errno; + else + return -EIO; +} diff --git a/source/main.c b/source/main.c index a2404f3..42b3cc7 100755 --- a/source/main.c +++ b/source/main.c @@ -1,244 +1,58 @@ -#define VERSION "1.2.0" +#define VERSION "1.2.1" #include #include +#include #include #include #include #include -#include #include #include #include #include "fatMounter.h" #include "tools.h" - -#define MAXIMUM(max, size) ( ( size > max ) ? max : size ) -#define CHUNK_MAX 1048576 // the Wii menu creates a new cdb.vff by writing 20 * 1M, possibly any other newly created file +#include "fs.h" #define user_abort 2976579765 -static fstats stats ATTRIBUTE_ALIGN(0x20); - -const char - header[] = "cdbackup v" VERSION ", by thepikachugamer\n" - "Backup/Restore your Wii Message Board data.\n\n", - - cdb_filepath[] = "/title/00000001/00000002/data/cdb.vff", - sd_filepath[] = "cdbackup.vff"; - -void* FS_Read(const char* filepath, unsigned int* filesize, int* ec) { - printf(">> Reading %s from NAND...\n", filepath); - - *ec = ISFS_Open(filepath, ISFS_OPEN_READ); - if (*ec < 0) return NULL; - int fd = *ec; - - *ec = ISFS_GetFileStats(fd, &stats); - if (*ec < 0) { - ISFS_Close(fd); - return NULL; - } - *filesize = stats.file_length; - - unsigned char* buffer = malloc(*filesize); - if (!buffer) { - ISFS_Close(fd); - *ec = -ENOMEM; - return NULL; - } - - unsigned int - chunks = ceil(*filesize / (double)CHUNK_MAX), - chunk = 0, - read_total = 0; - while(chunk < chunks) { - unsigned int chunk_size = MAXIMUM(CHUNK_MAX, *filesize - read_total); - *ec = ISFS_Read(fd, buffer + read_total, chunk_size); - printf("\r%u / %u bytes... [", read_total + (*ec < 0 ? 0 : *ec), *filesize); - for(int i = 0; i < (chunks - 1); i++) - putc(chunk > i ? '=' : ' ', stdout); - putc(']', stdout); - fflush(stdout); - - if (*ec < 0) { - printf(" error! (%d)\n", *ec); - free(buffer); - ISFS_Close(fd); - return NULL; - } else if (*ec < chunk_size) { - printf("\nI asked /dev/fs for %u bytes and he came back with %u ...\n", chunk_size, chunk_size - *ec); - free(buffer); - ISFS_Close(fd); - *ec = -EIO; - return NULL; - } - - read_total += *ec; - chunk++; - } +const char* header = "cdbackup v" VERSION ", by thepikachugamer\nBackup/Restore your Wii Message Board data.\n\n", + *cdb_filepath = "/title/00000001/00000002/data/cdb.vff", + *sd_filepath = "cdbackup.vff"; - printf(" OK!\n"); - ISFS_Close(fd); - *ec = 0; - return buffer; -} - -void* FAT_Read(const char* filepath, unsigned int* filesize, int* ec) { - printf(">> Reading %s from FAT device...\n", filepath); - - FILE* fp = fopen(filepath, "rb"); - if (!fp) { - *ec = -ENOENT; - return fp; - }; - - fseek(fp, 0, SEEK_END); - *filesize = ftell(fp); - fseek(fp, 0, SEEK_SET); - if(!*filesize) { - printf("\x1b[41;30m!>> this file is 0 bytes, is it corrupt?\x1b[40;37m\n"); - *ec = -EINVAL; - return NULL; - } - - unsigned char* buffer = malloc(*filesize); - if(!buffer) { - *ec = -ENOMEM; - fclose(fp); - return buffer; - }; - - unsigned int - chunks = ceil(*filesize / (double)CHUNK_MAX), - chunk = 0, - read_total = 0; - while(chunk < chunks) { - unsigned int - chunk_size = MAXIMUM(CHUNK_MAX, *filesize - read_total), - read = fread(buffer + read_total, 1, chunk_size, fp); - printf("\r%u / %u bytes... [", read_total + read, *filesize); - for(int i = 0; i < (chunks - 1); i++) - putc(chunk > i ? '=' : ' ', stdout); - putc(']', stdout); - fflush(stdout); - - if (read < chunk_size) { - printf("\nI asked for %u bytes and got %u ...\n", chunk_size, read); - *ec = -EIO; - free(buffer); - fclose(fp); - return NULL; - } - - read_total += read; - chunk++; - } - fclose(fp); - printf(" OK!\n"); - return buffer; - -} - -int FS_Write(const char* filepath, unsigned char* buffer, unsigned int filesize) { - printf(">> Writing to %s on NAND...\n", filepath); - - int ret = 0; - int fd = ISFS_Open(filepath, ISFS_OPEN_WRITE); - if (fd < 0) return fd; - - /* - int ret = ISFS_Write(fd, buffer, filesize); - if (ret < filesize) - ret = ret < 0 ? ret : -EIO - */ - - unsigned int - chunks = ceil(filesize / (double)CHUNK_MAX), - chunk = 0, - written = 0; - while (chunk < chunks) { - unsigned int chunk_size = MAXIMUM(CHUNK_MAX, filesize - written); - ret = ISFS_Write(fd, buffer + written, chunk_size); - printf("\r%u / %u bytes... [", written + (ret < 0 ? 0 : ret) , filesize); // ret & (1 << 31) <-- why did i write that - for(int i = 0; i < (chunks - 1); i++) - putc(chunk > i ? '=' : ' ', stdout); - putc(']', stdout); - fflush(stdout); - if (ret < 0) { - printf(" error! (%d)\n", ret); - ISFS_Close(fd); - return ret; - } else if (ret < chunk_size) { - printf("\nI gave /dev/fs %u bytes and he came back with %u left ...\n\n", chunk_size, chunk_size - ret); - ISFS_Close(fd); - return -EIO; - } - written += ret; - chunk++; - } - - printf(" OK!\n\n"); - ISFS_Close(fd); - return ret; -} - -int FAT_Write(const char* filepath, unsigned char* buffer, unsigned int filesize) { - printf(">> Writing to %s on FAT device...\n", filepath); - - FILE *fp = fopen(filepath, "wb"); - if (!fp) return ~0; - - unsigned int - chunks = ceil(filesize / (double)CHUNK_MAX), - chunk = 0, - written = 0; - while (chunk < chunks) { - unsigned int chunk_size = MAXIMUM(CHUNK_MAX, filesize - written); - size_t wrote = fwrite(buffer + written, 1, chunk_size, fp); - printf("\r%u / %u bytes... [", written + wrote, filesize); - for(int i = 0; i < (chunks - 1); i++) - putc(chunk > i ? '=' : ' ', stdout); - putc(']', stdout); - fflush(stdout); - if (wrote < chunk_size) { - printf("\nfwrite() came back with %u bytes left...\n\n", wrote); - fclose(fp); - return -EIO; - } - written += wrote; - chunk++; - } - - printf(" OK!\n\n"); - fclose(fp); - return 0; +static char* pwd() { + static char path[0x400]; + return getcwd(path, sizeof(path)); } int backup() { - int ret = 0; - unsigned int filesize; - - FILE* fp = fopen(sd_filepath, "rb"); - if (fp) { + int ret; + size_t filesize = 0; + unsigned char* buffer; + FILE* fp; + if ((fp = fopen(sd_filepath, "rb"))) { fclose(fp); - fp = NULL; if(!confirmation("Backup file appears to exist; overwrite it?\n", 3)) return user_abort; } - putc('\n', stdout); + putchar('\n'); - unsigned char* buffer = FS_Read(cdb_filepath, &filesize, &ret); - if(ret < 0) { - printf("Error reading message board data! (%d)\n", ret); + printf(">> Reading %s from NAND...\n", cdb_filepath); + ret = FS_Read(cdb_filepath, &buffer, &filesize, &progressbar); + if (ret < 0) { + printf("Error! (%d)\n", ret); return ret; } + printf("OK!\n"); + - ret = FAT_Write(sd_filepath, buffer, filesize); + printf(">> Writing %s to %s...\n", sd_filepath, pwd()); + ret = FAT_Write(sd_filepath, buffer, filesize, &progressbar); if (ret < 0) { - printf("Error writing backup file! (%d)\n", ret); + printf("Error! (%d)\n", ret); return ret; } + printf("OK!\n"); free(buffer); printf("All done!\n"); @@ -246,38 +60,45 @@ int backup() { } int restore() { - int ret = 0; - unsigned int filesize; + int ret; + size_t filesize = 0; + unsigned char* buffer; if(!confirmation("Are you sure you want to restore your message board data backup?\n", 3)) return user_abort; - unsigned char* buffer = FAT_Read(sd_filepath, &filesize, &ret); + printf("Reading %s from %s...\n", sd_filepath, pwd()); + ret = FAT_Read(sd_filepath, &buffer, &filesize, &progressbar); if(ret < 0) { - printf("Error reading backup file! (%d)\n", ret); - if(ret == -ENOENT) - printf("(does it exist?)\n"); + printf("Error! (%d)\n", ret); + if (ret == -ENOENT) + printf("\"No such file or directory\".\n"); + return ret; } + printf("OK!\n"); - if(memcmp(buffer, "VFF ", 4)) { + if(memcmp(buffer, "VFF ", 4) != 0) { printf("\x1b[41;30m this isn't a VFF file... [0x%08x != 0x%08x (\"VFF \")] \x1b[40;37m", *(unsigned int*)buffer, 0x56464620); free(buffer); return -EINVAL; } - ret = FS_Write(cdb_filepath, buffer, filesize); + printf("Writing to %s on NAND...\n", cdb_filepath); + ret = FS_Write(cdb_filepath, buffer, filesize, &progressbar); if (ret < 0) { - printf("Error writing backup file! (%d)\n", ret); + printf("Error! (%d)\n", ret); if(ret == -106) { - printf("* Please don't delete the data before restoring your backup...\n"); + printf("\nPlease don't delete the data before restoring your backup...\n"); sleep(1); printf("Press any button to return to the Wii Menu."); + input_scan(); while(!wii_down) { input_scan(); VIDEO_WaitVSync(); } SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0); } return ret; } + printf("OK!\n"); free(buffer); printf("All done!\n"); @@ -287,16 +108,16 @@ int restore() { int delete() { if(!confirmation("Are you sure you want to delete your message board data??\n", 6)) return user_abort; + printf (">> Deleting %s from NAND...\n", cdb_filepath); int ret = ISFS_Delete(cdb_filepath); - if (ret == -106) { // ENOENT - printf("\nYou already deleted it. (%d)", ret); - sleep(3); + if (ret == -106) { + printf("You already deleted it. (%d)\n", ret); ret = 0; } else if (ret < 0) - printf("Error deleting %s! (%d)", cdb_filepath, ret); + printf("Error! (%d)", ret); else - printf("Deleted %s.\n", cdb_filepath); + printf("OK!\n"); return ret; } @@ -304,19 +125,14 @@ int delete() { int main() { int ret = ~1; - init_video(2, 0); printf(header); WPAD_Init(); PAD_Init(); - ISFS_Initialize(); // i'll just hit enotinit on the attempt to open. dont care + ISFS_Initialize(); - if (MountSD() > 0) - chdir("sd:/"); - else if (MountUSB()) - chdir("usb:/"); - else { + if (!mountSD() && !mountUSB()) { printf("Could not mount any storage device!\n"); - return quit(~0); + quit(-ENXIO); } sleep(2); @@ -342,5 +158,7 @@ int main() { VIDEO_WaitVSync(); } - return quit(ret); + quit(ret); + + return 0; } diff --git a/source/tools.c b/source/tools.c index 0b84819..3a49318 100644 --- a/source/tools.c +++ b/source/tools.c @@ -1,6 +1,7 @@ #include "tools.h" #include +#include #include #include @@ -13,7 +14,7 @@ uint32_t wii_down = 0; uint16_t gcn_down = 0; uint16_t input_btns = 0; -void init_video(int row, int col) { +void init_video() { VIDEO_Init(); rmode = VIDEO_GetPreferredMode(NULL); xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); @@ -25,12 +26,12 @@ void init_video(int row, int col) { VIDEO_WaitVSync(); if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync(); - printf("\x1b[%d;%dH", row, col); + printf("\x1b[%d;%dH", 2, 0); } -int quit(int ret) { - UnmountSD(); - UnmountUSB(); +void quit(int ret) { + unmountSD(); + unmountUSB(); ISFS_Deinitialize(); printf("\nPress HOME/START to return to loader."); input_scan(); @@ -39,7 +40,7 @@ int quit(int ret) { VIDEO_WaitVSync(); } WPAD_Shutdown(); - return ret; + exit(ret); } void input_scan(void) {