From 0177b612f4bd3035c267bced8a97a03a5333f262 Mon Sep 17 00:00:00 2001 From: hexkyz Date: Sun, 28 Apr 2019 18:22:32 +0100 Subject: [PATCH] emunand: Use HOS archive style for rawnand parts --- fusee/fusee-secondary/src/device_partition.c | 6 ++-- fusee/fusee-secondary/src/fs_dev.c | 15 +++++++++ fusee/fusee-secondary/src/fs_dev.h | 3 ++ fusee/fusee-secondary/src/lib/fatfs/ffconf.h | 2 +- fusee/fusee-secondary/src/nxboot.c | 5 +-- fusee/fusee-secondary/src/nxfs.c | 35 ++++++++++++++++++-- 6 files changed, 59 insertions(+), 7 deletions(-) diff --git a/fusee/fusee-secondary/src/device_partition.c b/fusee/fusee-secondary/src/device_partition.c index 274d51929..cf15fe171 100644 --- a/fusee/fusee-secondary/src/device_partition.c +++ b/fusee/fusee-secondary/src/device_partition.c @@ -104,7 +104,8 @@ int emu_device_partition_read_data(device_partition_t *devpart, void *dst, uint6 } } - snprintf(target_path, sizeof(target_path) - 1, "%s%02d", origin_path, target_part); + /* Treat the path as a folder with each part inside. */ + snprintf(target_path, sizeof(target_path) - 1, "%s/%02d", origin_path, target_part); } else { target_sector = sector; strcpy(target_path, origin_path); @@ -176,7 +177,8 @@ int emu_device_partition_write_data(device_partition_t *devpart, const void *src } } - snprintf(target_path, sizeof(target_path) - 1, "%s%02d", origin_path, target_part); + /* Treat the path as a folder with each part inside. */ + snprintf(target_path, sizeof(target_path) - 1, "%s/%02d", origin_path, target_part); } else { target_sector = sector; strcpy(target_path, origin_path); diff --git a/fusee/fusee-secondary/src/fs_dev.c b/fusee/fusee-secondary/src/fs_dev.c index 7e5a4df88..288d49cf6 100644 --- a/fusee/fusee-secondary/src/fs_dev.c +++ b/fusee/fusee-secondary/src/fs_dev.c @@ -300,6 +300,21 @@ int fsdev_unmount_all(void) { return 0; } +int fsdev_set_attr(const char *file, int attr, int mask) { + return fsdev_convert_rc(NULL, f_chmod(file, (BYTE)attr, (BYTE)mask)); +} + +int fsdev_get_attr(const char *file) { + FILINFO info; + FRESULT rc = f_stat(file, &info); + + if (rc == FR_OK) { + return info.fattrib; + } + + return fsdev_convert_rc(NULL, rc); +} + /* Adapted from https://github.com/benemorius/openOBC-devboard/blob/bf0a4a33e22d24e7c299f921d185da27377310e0/lib/fatfs/FatFS.cpp#L173 */ static int fsdev_convert_rc(struct _reent *r, FRESULT rc) { int errornumber; diff --git a/fusee/fusee-secondary/src/fs_dev.h b/fusee/fusee-secondary/src/fs_dev.h index 459ad4ad0..fa499e9bf 100644 --- a/fusee/fusee-secondary/src/fs_dev.h +++ b/fusee/fusee-secondary/src/fs_dev.h @@ -27,6 +27,9 @@ int fsdev_register_device(const char *name); int fsdev_unregister_device(const char *name); int fsdev_unmount_device(const char *name); /* also unregisters. */ +int fsdev_set_attr(const char *file, int attr, int mask); /* Non-standard function to set file DOS attributes. */ +int fsdev_get_attr(const char *file); /* Non-standard function to get file DOS attributes. */ + int fsdev_set_default_device(const char *name); /* must be registered. */ int fsdev_is_exfat(const char *name); /* must be registered. */ diff --git a/fusee/fusee-secondary/src/lib/fatfs/ffconf.h b/fusee/fusee-secondary/src/lib/fatfs/ffconf.h index 78a3133ce..491977d4b 100644 --- a/fusee/fusee-secondary/src/lib/fatfs/ffconf.h +++ b/fusee/fusee-secondary/src/lib/fatfs/ffconf.h @@ -50,7 +50,7 @@ /* This option switches f_expand function. (0:Disable or 1:Enable) */ -#define FF_USE_CHMOD 0 +#define FF_USE_CHMOD 1 /* This option switches attribute manipulation functions, f_chmod() and f_utime(). / (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */ diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c index 6593bc2eb..0cecff931 100644 --- a/fusee/fusee-secondary/src/nxboot.c +++ b/fusee/fusee-secondary/src/nxboot.c @@ -230,11 +230,12 @@ static bool nxboot_configure_emunand() { /* Check if full rawnand image file is present. */ if (!is_valid_file(emunand_rawnand_base_path)) { - char emunand_rawnand_path[0x300 + 3 + 1] = {0}; + char emunand_rawnand_path[0x300 + 4 + 1] = {0}; /* Search for rawnand part files instead. */ for (int i = 0; i < 64; i++) { - snprintf(emunand_rawnand_path, sizeof(emunand_rawnand_path) - 1, "%s%02d", emunand_rawnand_base_path, i); + /* Treat rawnand as a folder with each part inside. */ + snprintf(emunand_rawnand_path, sizeof(emunand_rawnand_path) - 1, "%s/%02d", emunand_rawnand_base_path, i); if (is_valid_file(emunand_rawnand_path)) { if (i == 0) { /* The size of the first part file should tell us the part limit. */ diff --git a/fusee/fusee-secondary/src/nxfs.c b/fusee/fusee-secondary/src/nxfs.c index 701523fd2..129210901 100644 --- a/fusee/fusee-secondary/src/nxfs.c +++ b/fusee/fusee-secondary/src/nxfs.c @@ -26,6 +26,8 @@ #include "utils.h" #include "sdmmc/sdmmc.h" +#include "lib/fatfs/ff.h" + static bool g_ahb_redirect_enabled = false; static bool g_sd_device_initialized = false; static bool g_emmc_device_initialized = false; @@ -154,6 +156,7 @@ static int mmc_partition_write(device_partition_t *devpart, const void *src, uin } static int emummc_partition_initialize(device_partition_t *devpart) { + /* Allocate the crypto work buffer. */ if ((devpart->read_cipher != NULL) || (devpart->write_cipher != NULL)) { devpart->crypto_work_buffer = memalign(16, devpart->sector_size * 16); if (devpart->crypto_work_buffer == NULL) { @@ -166,11 +169,15 @@ static int emummc_partition_initialize(device_partition_t *devpart) { devpart->crypto_work_buffer_num_sectors = 0; } devpart->initialized = true; + return 0; } -static void emummc_partition_finalize(device_partition_t *devpart) { - free(devpart->crypto_work_buffer); +static void emummc_partition_finalize(device_partition_t *devpart) { + /* Free the crypto work buffer. */ + if (devpart->crypto_work_buffer != NULL) { + free(devpart->crypto_work_buffer); + } } static int nxfs_bis_crypto_decrypt(device_partition_t *devpart, uint64_t sector, uint64_t num_sectors) { @@ -566,6 +573,30 @@ int nxfs_mount_emu_emmc(const char *emunand_boot0_path, const char *emunand_boot model.num_sectors = (256ull << 30) / model.sector_size; if (!is_exfat) { + /* For multiple parts we want a folder with the archive bit set. */ + rc = fsdev_get_attr(emunand_rawnand_base_path); + + /* Failed to get file DOS attributes. */ + if (rc == -1) { + return -1; + } + + /* Our path is not a directory. */ + if (!(rc & AM_DIR)) { + return -1; + } + + /* Check if the archive bit is not set. */ + if (!(rc & AM_ARC)) { + /* Try to set the archive bit. */ + rc = fsdev_set_attr(emunand_rawnand_base_path, AM_ARC, AM_ARC); + + /* Failed to set file DOS attributes. */ + if (rc == -1) { + return -1; + } + } + /* Mount emulated raw NAND device from multiple parts. */ rc = emudev_mount_device_multipart("rawnand", &model, emunand_rawnand_base_path, num_parts, part_limit);