diff --git a/Dockerfile b/Dockerfile index 9941cb4..64707eb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM wiiuenv/devkitppc:20211229 +FROM wiiuenv/devkitppc:20220507 WORKDIR tmp_build COPY . . diff --git a/Dockerfile.buildlocal b/Dockerfile.buildlocal index 080eec7..8ec2277 100644 --- a/Dockerfile.buildlocal +++ b/Dockerfile.buildlocal @@ -1,3 +1,3 @@ -FROM wiiuenv/devkitppc:20211229 +FROM wiiuenv/devkitppc:20220507 WORKDIR project \ No newline at end of file diff --git a/README.md b/README.md index a8e6cfe..933bae0 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,9 @@ Make you to have [wut](https://github.com/devkitPro/wut/) installed and use the ``` make install ``` +Note: +You might have to build the latest wut from source if you use the prebuild devkitpro packages until it has a new release. +It won't work with wut versions like wut 1.0.0-beta12 and older. ## Use this lib in Dockerfiles. A prebuilt version of this lib can found on dockerhub. To use it for your projects, add this to your Dockerfile. diff --git a/include/iosuhax.h b/include/iosuhax.h index 6ee6763..4d82752 100644 --- a/include/iosuhax.h +++ b/include/iosuhax.h @@ -23,32 +23,17 @@ ***************************************************************************/ #pragma once +#include #include #ifdef __cplusplus extern "C" { #endif -typedef struct { - uint32_t flag; - uint32_t permission; - uint32_t owner_id; - uint32_t group_id; - uint32_t size; // size in bytes - uint32_t physsize; // physical size on disk in bytes - uint32_t unk[3]; - uint32_t id; - uint32_t ctime; - uint32_t mtime; - uint32_t unk2[0x0D]; -} fileStat_s; - -typedef struct { - fileStat_s stat; - char name[0x100]; -} directoryEntry_s; - -#define DIR_ENTRY_IS_DIRECTORY 0x80000000 +// Deprecated: Use FS_STAT_DIRECTORY +#ifndef DIR_ENTRY_IS_DIRECTORY +#define DIR_ENTRY_IS_DIRECTORY FS_STAT_FILE +#endif #define FSA_MOUNTFLAGS_BINDMOUNT (1 << 0) #define FSA_MOUNTFLAGS_GLOBAL (1 << 1) @@ -88,7 +73,7 @@ int IOSUHAX_FSA_MakeDir(int fsaFd, const char *path, uint32_t flags); int IOSUHAX_FSA_OpenDir(int fsaFd, const char *path, int *outHandle); -int IOSUHAX_FSA_ReadDir(int fsaFd, int handle, directoryEntry_s *out_data); +int IOSUHAX_FSA_ReadDir(int fsaFd, int handle, FSDirectoryEntry *out_data); int IOSUHAX_FSA_RewindDir(int fsaFd, int dirHandle); @@ -102,13 +87,13 @@ int IOSUHAX_FSA_ReadFile(int fsaFd, void *data, uint32_t size, uint32_t cnt, int int IOSUHAX_FSA_WriteFile(int fsaFd, const void *data, uint32_t size, uint32_t cnt, int fileHandle, uint32_t flags); -int IOSUHAX_FSA_StatFile(int fsaFd, int fileHandle, fileStat_s *out_data); +int IOSUHAX_FSA_StatFile(int fsaFd, int fileHandle, FSStat *out_data); int IOSUHAX_FSA_CloseFile(int fsaFd, int fileHandle); int IOSUHAX_FSA_SetFilePos(int fsaFd, int fileHandle, uint32_t position); -int IOSUHAX_FSA_GetStat(int fsaFd, const char *path, fileStat_s *out_data); +int IOSUHAX_FSA_GetStat(int fsaFd, const char *path, FSStat *out_data); int IOSUHAX_FSA_Remove(int fsaFd, const char *path); diff --git a/source/iosuhax.c b/source/iosuhax.c index 6825d3d..6e65f80 100644 --- a/source/iosuhax.c +++ b/source/iosuhax.c @@ -465,7 +465,7 @@ int IOSUHAX_FSA_OpenDir(int fsaFd, const char *path, int *outHandle) { return result_vec[0]; } -int IOSUHAX_FSA_ReadDir(int fsaFd, int handle, directoryEntry_s *out_data) { +int IOSUHAX_FSA_ReadDir(int fsaFd, int handle, FSDirectoryEntry *out_data) { if (iosuhaxHandle < 0) return iosuhaxHandle; @@ -480,7 +480,7 @@ int IOSUHAX_FSA_ReadDir(int fsaFd, int handle, directoryEntry_s *out_data) { io_buf[0] = fsaFd; io_buf[1] = handle; - int result_vec_size = 4 + sizeof(directoryEntry_s); + int result_vec_size = 4 + sizeof(FSDirectoryEntry); uint8_t *result_vec = (uint8_t *) memalign(0x20, result_vec_size); if (!result_vec) { free(io_buf); @@ -495,7 +495,7 @@ int IOSUHAX_FSA_ReadDir(int fsaFd, int handle, directoryEntry_s *out_data) { } int result = *(int *) result_vec; - memcpy(out_data, result_vec + 4, sizeof(directoryEntry_s)); + memcpy(out_data, result_vec + 4, sizeof(FSDirectoryEntry)); free(io_buf); free(result_vec); return result; @@ -688,7 +688,7 @@ int IOSUHAX_FSA_WriteFile(int fsaFd, const void *data, uint32_t size, uint32_t c return result; } -int IOSUHAX_FSA_StatFile(int fsaFd, int fileHandle, fileStat_s *out_data) { +int IOSUHAX_FSA_StatFile(int fsaFd, int fileHandle, FSStat *out_data) { if (iosuhaxHandle < 0) return iosuhaxHandle; @@ -703,7 +703,7 @@ int IOSUHAX_FSA_StatFile(int fsaFd, int fileHandle, fileStat_s *out_data) { io_buf[0] = fsaFd; io_buf[1] = fileHandle; - int out_buf_size = 4 + sizeof(fileStat_s); + int out_buf_size = 4 + sizeof(FSStat); uint32_t *out_buffer = (uint32_t *) memalign(0x20, out_buf_size); if (!out_buffer) { free(io_buf); @@ -718,7 +718,7 @@ int IOSUHAX_FSA_StatFile(int fsaFd, int fileHandle, fileStat_s *out_data) { } int result = out_buffer[0]; - memcpy(out_data, out_buffer + 1, sizeof(fileStat_s)); + memcpy(out_data, out_buffer + 1, sizeof(FSStat)); free(io_buf); free(out_buffer); @@ -780,7 +780,7 @@ int IOSUHAX_FSA_SetFilePos(int fsaFd, int fileHandle, uint32_t position) { return result; } -int IOSUHAX_FSA_GetStat(int fsaFd, const char *path, fileStat_s *out_data) { +int IOSUHAX_FSA_GetStat(int fsaFd, const char *path, FSStat *out_data) { if (iosuhaxHandle < 0) return iosuhaxHandle; @@ -796,7 +796,7 @@ int IOSUHAX_FSA_GetStat(int fsaFd, const char *path, fileStat_s *out_data) { io_buf[1] = sizeof(uint32_t) * input_cnt; strcpy(((char *) io_buf) + io_buf[1], path); - int out_buf_size = 4 + sizeof(fileStat_s); + int out_buf_size = 4 + sizeof(FSStat); uint32_t *out_buffer = (uint32_t *) memalign(0x20, out_buf_size); if (!out_buffer) { free(io_buf); @@ -811,7 +811,7 @@ int IOSUHAX_FSA_GetStat(int fsaFd, const char *path, fileStat_s *out_data) { } int result = out_buffer[0]; - memcpy(out_data, out_buffer + 1, sizeof(fileStat_s)); + memcpy(out_data, out_buffer + 1, sizeof(FSStat)); free(io_buf); free(out_buffer); diff --git a/source/iosuhax_devoptab.c b/source/iosuhax_devoptab.c index 5be2a50..ca80462 100644 --- a/source/iosuhax_devoptab.c +++ b/source/iosuhax_devoptab.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -44,9 +45,9 @@ typedef struct _fs_dev_file_state_t { fs_dev_private_t *dev; int fd; /* File descriptor */ int flags; /* Opening flags */ - int read; /* True if allowed to read from file */ - int write; /* True if allowed to write to file */ - int append; /* True if allowed to append to file */ + bool read; /* True if allowed to read from file */ + bool write; /* True if allowed to write to file */ + bool append; /* True if allowed to append to file */ uint32_t pos; /* Current position within the file (in bytes) */ uint32_t len; /* Total length of the file (in bytes) */ struct _fs_dev_file_state_t *prevOpenFile; /* The previous entry in a double-linked FILO list of open files */ @@ -104,6 +105,85 @@ static char *fs_dev_real_path(const char *path, fs_dev_private_t *dev) { return new_name; } +static int fs_dev_translate_error(FSStatus error) { + switch ((int) error) { + case FS_STATUS_END: + return ENOENT; + case FS_STATUS_CANCELLED: + return ECANCELED; + case FS_STATUS_EXISTS: + return EEXIST; + case FS_STATUS_MEDIA_ERROR: + return EIO; + case FS_STATUS_NOT_FOUND: + return ENOENT; + case FS_STATUS_PERMISSION_ERROR: + return EPERM; + case FS_STATUS_STORAGE_FULL: + return ENOSPC; + case FS_STATUS_FILE_TOO_BIG: + return EFBIG; + case FS_STATUS_NOT_DIR: + return ENOTDIR; + case FS_STATUS_NOT_FILE: + return EISDIR; + case FS_STATUS_MAX: + return ENFILE; + case FS_STATUS_ACCESS_ERROR: + return EACCES; + case FS_STATUS_JOURNAL_FULL: + return ENOSPC; + case FS_STATUS_UNSUPPORTED_CMD: + return ENOTSUP; + case FS_STATUS_MEDIA_NOT_READY: + return EOWNERDEAD; + case FS_STATUS_ALREADY_OPEN: + case FS_STATUS_CORRUPTED: + case FS_STATUS_FATAL_ERROR: + return EIO; + } + return (int) error; +} + +static mode_t fs_dev_translate_stat_mode(FSStat fileStat, bool isRootDirectory) { + // Convert file types + mode_t typeMode = 0; + if (isRootDirectory) { + typeMode |= S_IFDIR; + } else if ((fileStat.flags & FS_STAT_LINK) == FS_STAT_LINK) { + typeMode |= S_IFLNK; + } else if ((fileStat.flags & FS_STAT_DIRECTORY) == FS_STAT_DIRECTORY) { + typeMode |= S_IFDIR; + } else if ((fileStat.flags & FS_STAT_FILE) == FS_STAT_FILE) { + typeMode |= S_IFREG; + } + + // Convert normal CafeOS hexadecimal permission bits into Unix octal permission bits + mode_t permissionMode = (((fileStat.mode >> 2) & S_IRWXU) | ((fileStat.mode >> 1) & S_IRWXG) | (fileStat.mode & S_IRWXO)); + + return typeMode | permissionMode; +} + +static FSMode fs_dev_translate_permission_mode(mode_t mode) { + // Convert normal Unix octal permission bits into CafeOS hexadecimal permission bits + return (FSMode) (((mode & S_IRWXU) << 2) | ((mode & S_IRWXG) << 1) | (mode & S_IRWXO)); +} + +static time_t fs_dev_translate_time(FSTime timeValue) { + OSCalendarTime fileTime; + FSTimeToCalendarTime(timeValue, &fileTime); + struct tm posixTime = {0}; + posixTime.tm_year = fileTime.tm_year - 1900; + posixTime.tm_mon = fileTime.tm_mon; + posixTime.tm_mday = fileTime.tm_mday; + posixTime.tm_hour = fileTime.tm_hour; + posixTime.tm_min = fileTime.tm_min; + posixTime.tm_sec = fileTime.tm_sec; + posixTime.tm_yday = fileTime.tm_yday; + posixTime.tm_wday = fileTime.tm_wday; + return mktime(&posixTime); +} + static int fs_dev_open_r(struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { fs_dev_private_t *dev = fs_dev_get_device_data(path); if (!dev) { @@ -121,34 +201,34 @@ static int fs_dev_open_r(struct _reent *r, void *fileStruct, const char *path, i // Map flags to open modes if (flags == 0) { - file->read = 1; - file->write = 0; - file->append = 0; + file->read = true; + file->write = false; + file->append = false; fsMode = "r"; } else if (flags == 2) { - file->read = 1; - file->write = 1; - file->append = 0; + file->read = true; + file->write = true; + file->append = false; fsMode = "r+"; } else if (flags == 0x601) { - file->read = 0; - file->write = 1; - file->append = 0; + file->read = false; + file->write = true; + file->append = false; fsMode = "w"; } else if (flags == 0x602) { - file->read = 1; - file->write = 1; - file->append = 0; + file->read = true; + file->write = true; + file->append = false; fsMode = "w+"; } else if (flags == 0x209) { - file->read = 0; - file->write = 1; - file->append = 1; + file->read = false; + file->write = true; + file->append = true; fsMode = "a"; } else if (flags == 0x20A) { - file->read = 1; - file->write = 1; - file->append = 1; + file->read = true; + file->write = true; + file->append = true; fsMode = "a+"; } else { r->_errno = EINVAL; @@ -172,11 +252,11 @@ static int fs_dev_open_r(struct _reent *r, void *fileStruct, const char *path, i free(real_path); if (result == 0) { - fileStat_s stats; + FSStat stats; result = IOSUHAX_FSA_StatFile(dev->fsaFd, fd, &stats); if (result != 0) { IOSUHAX_FSA_CloseFile(dev->fsaFd, fd); - r->_errno = result; + r->_errno = fs_dev_translate_error(result); OSUnlockMutex(dev->pMutex); return -1; } @@ -187,7 +267,7 @@ static int fs_dev_open_r(struct _reent *r, void *fileStruct, const char *path, i return (int) file; } - r->_errno = result; + r->_errno = fs_dev_translate_error(result); OSUnlockMutex(dev->pMutex); return -1; } @@ -207,7 +287,7 @@ static int fs_dev_close_r(struct _reent *r, void *fd) { OSUnlockMutex(file->dev->pMutex); if (result < 0) { - r->_errno = result; + r->_errno = fs_dev_translate_error(result); return -1; } return 0; @@ -269,7 +349,7 @@ static ssize_t fs_dev_write_r(struct _reent *r, void *fd, const char *ptr, size_ int result = IOSUHAX_FSA_WriteFile(file->dev->fsaFd, ptr + done, 0x01, write_size, file->fd, 0); if (result < 0) { - r->_errno = result; + r->_errno = fs_dev_translate_error(result); break; } else if (result == 0) { if (write_size > 0) @@ -306,7 +386,7 @@ static ssize_t fs_dev_read_r(struct _reent *r, void *fd, char *ptr, size_t len) int result = IOSUHAX_FSA_ReadFile(file->dev->fsaFd, ptr + done, 0x01, read_size, file->fd, 0); if (result < 0) { - r->_errno = result; + r->_errno = fs_dev_translate_error(result); done = 0; break; } else if (result == 0) { @@ -335,55 +415,32 @@ static int fs_dev_fstat_r(struct _reent *r, void *fd, struct stat *st) { // Zero out the stat buffer memset(st, 0, sizeof(struct stat)); - fileStat_s stats; + FSStat stats; int result = IOSUHAX_FSA_StatFile(file->dev->fsaFd, (int) fd, &stats); if (result != 0) { - r->_errno = result; + r->_errno = fs_dev_translate_error(result); OSUnlockMutex(file->dev->pMutex); return -1; } - st->st_mode = S_IFREG; - st->st_size = stats.size; - st->st_blocks = (stats.size + 511) >> 9; - st->st_nlink = 1; - - // Fill in the generic entry stats - st->st_dev = stats.id; - st->st_uid = stats.owner_id; - st->st_gid = stats.group_id; - st->st_ino = stats.id; - st->st_atime = stats.mtime; - st->st_ctime = stats.ctime; - st->st_mtime = stats.mtime; + // Convert fields to posix stat + st->st_dev = (dev_t) file->dev; + st->st_ino = stats.entryId; + st->st_mode = fs_dev_translate_stat_mode(stats, false); + st->st_nlink = 1; + st->st_uid = stats.owner; + st->st_gid = stats.group; + st->st_rdev = st->st_dev; + st->st_size = stats.size; + st->st_blksize = 512; + st->st_blocks = (st->st_size + st->st_blksize - 1) / st->st_blksize; + st->st_atime = fs_dev_translate_time(stats.modified); + st->st_ctime = fs_dev_translate_time(stats.created); + st->st_mtime = fs_dev_translate_time(stats.modified); OSUnlockMutex(file->dev->pMutex); return 0; } -static int fs_dev_ftruncate_r(struct _reent *r, void *fd, off_t len) { - fs_dev_file_state_t *file = (fs_dev_file_state_t *) fd; - if (!file->dev) { - r->_errno = ENODEV; - return -1; - } - - r->_errno = ENOTSUP; - // TODO - return -1; -} - -static int fs_dev_fsync_r(struct _reent *r, void *fd) { - fs_dev_file_state_t *file = (fs_dev_file_state_t *) fd; - if (!file->dev) { - r->_errno = ENODEV; - return -1; - } - - r->_errno = ENOTSUP; - // TODO - return -1; -} - static int fs_dev_stat_r(struct _reent *r, const char *path, struct stat *st) { fs_dev_private_t *dev = fs_dev_get_device_data(path); if (!dev) { @@ -403,34 +460,78 @@ static int fs_dev_stat_r(struct _reent *r, const char *path, struct stat *st) { return -1; } - fileStat_s stats; - + FSStat stats; int result = IOSUHAX_FSA_GetStat(dev->fsaFd, real_path, &stats); - free(real_path); - if (result < 0) { - r->_errno = result; + r->_errno = fs_dev_translate_error(result); OSUnlockMutex(dev->pMutex); return -1; } - // mark root also as directory - st->st_mode = ((stats.flag & 0x80000000) || (strlen(dev->mount_path) + 1 == strlen(real_path))) ? S_IFDIR : S_IFREG; - st->st_nlink = 1; - st->st_size = stats.size; - st->st_blocks = (stats.size + 511) >> 9; - // Fill in the generic entry stats - st->st_dev = stats.id; - st->st_uid = stats.owner_id; - st->st_gid = stats.group_id; - st->st_ino = stats.id; - st->st_atime = stats.mtime; - st->st_ctime = stats.ctime; - st->st_mtime = stats.mtime; + // Convert fields to posix stat + st->st_dev = (dev_t) dev; + st->st_ino = stats.entryId; + st->st_mode = fs_dev_translate_stat_mode(stats, (strlen(dev->mount_path) + 1 == strlen(real_path))); + st->st_nlink = 1; + st->st_uid = stats.owner; + st->st_gid = stats.group; + st->st_rdev = st->st_dev; + st->st_size = stats.size; + st->st_blksize = 512; + st->st_blocks = (st->st_size + st->st_blksize - 1) / st->st_blksize; + st->st_atime = fs_dev_translate_time(stats.modified); + st->st_ctime = fs_dev_translate_time(stats.created); + st->st_mtime = fs_dev_translate_time(stats.modified); OSUnlockMutex(dev->pMutex); + return 0; +} +static int fs_dev_lstat_r(struct _reent *r, const char *path, struct stat *st) { + fs_dev_private_t *dev = fs_dev_get_device_data(path); + if (!dev) { + r->_errno = ENODEV; + return -1; + } + + OSLockMutex(dev->pMutex); + + // Zero out the stat buffer + memset(st, 0, sizeof(struct stat)); + + char *real_path = fs_dev_real_path(path, dev); + if (!real_path) { + r->_errno = ENOMEM; + OSUnlockMutex(dev->pMutex); + return -1; + } + + FSStat stats; + int result = IOSUHAX_FSA_GetStat(dev->fsaFd, real_path, &stats); + free(real_path); + if (result < 0) { + r->_errno = fs_dev_translate_error(result); + OSUnlockMutex(dev->pMutex); + return -1; + } + + // Convert fields to posix stat + st->st_dev = (dev_t) dev; + st->st_ino = stats.entryId; + st->st_mode = fs_dev_translate_stat_mode(stats, (strlen(dev->mount_path) + 1 == strlen(real_path))); + st->st_nlink = 1; + st->st_uid = stats.owner; + st->st_gid = stats.group; + st->st_rdev = st->st_dev; + st->st_size = stats.size; + st->st_blksize = 512; + st->st_blocks = (st->st_size + st->st_blksize - 1) / st->st_blksize; + st->st_atime = fs_dev_translate_time(stats.modified); + st->st_ctime = fs_dev_translate_time(stats.created); + st->st_mtime = fs_dev_translate_time(stats.modified); + + OSUnlockMutex(dev->pMutex); return 0; } @@ -462,7 +563,7 @@ static int fs_dev_unlink_r(struct _reent *r, const char *name) { OSUnlockMutex(dev->pMutex); if (result < 0) { - r->_errno = result; + r->_errno = fs_dev_translate_error(result); return -1; } @@ -492,7 +593,7 @@ static int fs_dev_chdir_r(struct _reent *r, const char *name) { OSUnlockMutex(dev->pMutex); if (result < 0) { - r->_errno = result; + r->_errno = fs_dev_translate_error(result); return -1; } @@ -523,7 +624,7 @@ static int fs_dev_rename_r(struct _reent *r, const char *oldName, const char *ne } //! TODO - int result = -ENOTSUP; + int result = FS_ERROR_UNSUPPORTED_COMMAND; free(real_oldpath); free(real_newpath); @@ -531,7 +632,7 @@ static int fs_dev_rename_r(struct _reent *r, const char *oldName, const char *ne OSUnlockMutex(dev->pMutex); if (result < 0) { - r->_errno = result; + r->_errno = fs_dev_translate_error(result); return -1; } @@ -554,21 +655,20 @@ static int fs_dev_mkdir_r(struct _reent *r, const char *path, int mode) { return -1; } - int result = IOSUHAX_FSA_MakeDir(dev->fsaFd, real_path, mode); - + int result = IOSUHAX_FSA_MakeDir(dev->fsaFd, real_path, fs_dev_translate_permission_mode(mode)); free(real_path); OSUnlockMutex(dev->pMutex); if (result < 0) { - r->_errno = result; + r->_errno = fs_dev_translate_error(result); return -1; } return 0; } -static int fs_dev_chmod_r(struct _reent *r, const char *path, int mode) { +static int fs_dev_chmod_r(struct _reent *r, const char *path, mode_t mode) { fs_dev_private_t *dev = fs_dev_get_device_data(path); if (!dev) { r->_errno = ENODEV; @@ -584,14 +684,13 @@ static int fs_dev_chmod_r(struct _reent *r, const char *path, int mode) { return -1; } - int result = IOSUHAX_FSA_ChangeMode(dev->fsaFd, real_path, mode); - + int result = IOSUHAX_FSA_ChangeMode(dev->fsaFd, real_path, fs_dev_translate_permission_mode(mode)); free(real_path); OSUnlockMutex(dev->pMutex); if (result < 0) { - r->_errno = result; + r->_errno = fs_dev_translate_error(result); return -1; } @@ -624,7 +723,7 @@ static int fs_dev_statvfs_r(struct _reent *r, const char *path, struct statvfs * free(real_path); if (result < 0) { - r->_errno = result; + r->_errno = fs_dev_translate_error(result); OSUnlockMutex(dev->pMutex); return -1; } @@ -688,7 +787,7 @@ static DIR_ITER *fs_dev_diropen_r(struct _reent *r, DIR_ITER *dirState, const ch OSUnlockMutex(dev->pMutex); if (result < 0) { - r->_errno = result; + r->_errno = fs_dev_translate_error(result); return NULL; } @@ -712,7 +811,7 @@ static int fs_dev_dirclose_r(struct _reent *r, DIR_ITER *dirState) { OSUnlockMutex(dirIter->dev->pMutex); if (result < 0) { - r->_errno = result; + r->_errno = fs_dev_translate_error(result); return -1; } return 0; @@ -732,7 +831,7 @@ static int fs_dev_dirreset_r(struct _reent *r, DIR_ITER *dirState) { OSUnlockMutex(dirIter->dev->pMutex); if (result < 0) { - r->_errno = result; + r->_errno = fs_dev_translate_error(result); return -1; } return 0; @@ -747,12 +846,12 @@ static int fs_dev_dirnext_r(struct _reent *r, DIR_ITER *dirState, char *filename OSLockMutex(dirIter->dev->pMutex); - directoryEntry_s *dir_entry = malloc(sizeof(directoryEntry_s)); + FSDirectoryEntry *dir_entry = malloc(sizeof(FSDirectoryEntry)); int result = IOSUHAX_FSA_ReadDir(dirIter->dev->fsaFd, dirIter->dirHandle, dir_entry); if (result < 0) { free(dir_entry); - r->_errno = result; + r->_errno = fs_dev_translate_error(result); OSUnlockMutex(dirIter->dev->pMutex); return -1; } @@ -762,17 +861,21 @@ static int fs_dev_dirnext_r(struct _reent *r, DIR_ITER *dirState, char *filename if (st) { memset(st, 0, sizeof(struct stat)); - st->st_mode = (dir_entry->stat.flag & 0x80000000) ? S_IFDIR : S_IFREG; - st->st_nlink = 1; - st->st_size = dir_entry->stat.size; - st->st_blocks = (dir_entry->stat.size + 511) >> 9; - st->st_dev = dir_entry->stat.id; - st->st_uid = dir_entry->stat.owner_id; - st->st_gid = dir_entry->stat.group_id; - st->st_ino = dir_entry->stat.id; - st->st_atime = dir_entry->stat.mtime; - st->st_ctime = dir_entry->stat.ctime; - st->st_mtime = dir_entry->stat.mtime; + + // Convert fields to posix stat + st->st_dev = (dev_t) dirIter->dev; + st->st_ino = dir_entry->info.entryId; + st->st_mode = fs_dev_translate_stat_mode(dir_entry->info, false); + st->st_nlink = 1; + st->st_uid = dir_entry->info.owner; + st->st_gid = dir_entry->info.group; + st->st_rdev = st->st_dev; + st->st_size = dir_entry->info.size; + st->st_blksize = 512; + st->st_blocks = (st->st_size + st->st_blksize - 1) / st->st_blksize; + st->st_atime = fs_dev_translate_time(dir_entry->info.modified); + st->st_ctime = fs_dev_translate_time(dir_entry->info.created); + st->st_mtime = fs_dev_translate_time(dir_entry->info.modified); } free(dir_entry); @@ -780,33 +883,35 @@ static int fs_dev_dirnext_r(struct _reent *r, DIR_ITER *dirState, char *filename return 0; } -// NTFS device driver devoptab static const devoptab_t devops_fs = { - NULL, /* Device name */ - sizeof(fs_dev_file_state_t), - fs_dev_open_r, - fs_dev_close_r, - fs_dev_write_r, - fs_dev_read_r, - fs_dev_seek_r, - fs_dev_fstat_r, - fs_dev_stat_r, - fs_dev_link_r, - fs_dev_unlink_r, - fs_dev_chdir_r, - fs_dev_rename_r, - fs_dev_mkdir_r, - sizeof(fs_dev_dir_entry_t), - fs_dev_diropen_r, - fs_dev_dirreset_r, - fs_dev_dirnext_r, - fs_dev_dirclose_r, - fs_dev_statvfs_r, - fs_dev_ftruncate_r, - fs_dev_fsync_r, - fs_dev_chmod_r, - NULL, /* fs_dev_fchmod_r */ - NULL /* Device data */ + .name = NULL, /* Device name */ + .structSize = sizeof(fs_dev_file_state_t), + .open_r = fs_dev_open_r, + .close_r = fs_dev_close_r, + .write_r = fs_dev_write_r, + .read_r = fs_dev_read_r, + .seek_r = fs_dev_seek_r, + .fstat_r = fs_dev_fstat_r, + .stat_r = fs_dev_stat_r, + .link_r = fs_dev_link_r, + .unlink_r = fs_dev_unlink_r, + .chdir_r = fs_dev_chdir_r, + .rename_r = fs_dev_rename_r, + .mkdir_r = fs_dev_mkdir_r, + .dirStateSize = sizeof(fs_dev_dir_entry_t), + .diropen_r = fs_dev_diropen_r, + .dirreset_r = fs_dev_dirreset_r, + .dirnext_r = fs_dev_dirnext_r, + .dirclose_r = fs_dev_dirclose_r, + .statvfs_r = fs_dev_statvfs_r, + .ftruncate_r = NULL, // fs_dev_ftruncate_r, + .fsync_r = NULL, // fs_dev_fsync_r, + .deviceData = NULL, + .chmod_r = fs_dev_chmod_r, + .fchmod_r = NULL, // fs_dev_fchmod_r, + .rmdir_r = NULL, // fs_dev_rmdir_r, + .lstat_r = fs_dev_lstat_r, + .utimes_r = NULL, }; static int fs_dev_add_device(const char *name, const char *mount_path, int fsaFd, int isMounted) { diff --git a/source/iosuhax_disc_interface.c b/source/iosuhax_disc_interface.c index 64ed372..1624013 100644 --- a/source/iosuhax_disc_interface.c +++ b/source/iosuhax_disc_interface.c @@ -143,16 +143,15 @@ static bool IOSUHAX_sdio_writeSectors(uint32_t sector, uint32_t numSectors, cons return true; } -const DISC_INTERFACE IOSUHAX_sdio_disc_interface = - { - DEVICE_TYPE_WII_U_SD, - FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_U_SD, - IOSUHAX_sdio_startup, - IOSUHAX_sdio_isInserted, - IOSUHAX_sdio_readSectors, - IOSUHAX_sdio_writeSectors, - IOSUHAX_sdio_clearStatus, - IOSUHAX_sdio_shutdown}; +const DISC_INTERFACE IOSUHAX_sdio_disc_interface = { + DEVICE_TYPE_WII_U_SD, + FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_U_SD, + IOSUHAX_sdio_startup, + IOSUHAX_sdio_isInserted, + IOSUHAX_sdio_readSectors, + IOSUHAX_sdio_writeSectors, + IOSUHAX_sdio_clearStatus, + IOSUHAX_sdio_shutdown}; static bool IOSUHAX_usb_startup(void) { if (!IOSUHAX_disc_io_fsa_open(FSA_REF_USB)) @@ -213,13 +212,12 @@ static bool IOSUHAX_usb_writeSectors(uint32_t sector, uint32_t numSectors, const return true; } -const DISC_INTERFACE IOSUHAX_usb_disc_interface = - { - DEVICE_TYPE_WII_U_USB, - FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_U_USB, - IOSUHAX_usb_startup, - IOSUHAX_usb_isInserted, - IOSUHAX_usb_readSectors, - IOSUHAX_usb_writeSectors, - IOSUHAX_usb_clearStatus, - IOSUHAX_usb_shutdown}; +const DISC_INTERFACE IOSUHAX_usb_disc_interface = { + DEVICE_TYPE_WII_U_USB, + FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_U_USB, + IOSUHAX_usb_startup, + IOSUHAX_usb_isInserted, + IOSUHAX_usb_readSectors, + IOSUHAX_usb_writeSectors, + IOSUHAX_usb_clearStatus, + IOSUHAX_usb_shutdown};