From c1da2db4cd04837e07b6898f8a2ef017be9c07c0 Mon Sep 17 00:00:00 2001 From: Maschell Date: Fri, 3 Jun 2022 17:17:15 +0200 Subject: [PATCH] Remove devoptab --- source/iosuhax_devoptab.c | 1049 ------------------------------------- 1 file changed, 1049 deletions(-) delete mode 100644 source/iosuhax_devoptab.c diff --git a/source/iosuhax_devoptab.c b/source/iosuhax_devoptab.c deleted file mode 100644 index aed1280..0000000 --- a/source/iosuhax_devoptab.c +++ /dev/null @@ -1,1049 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 - * by Dimok - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - ***************************************************************************/ -#include "iosuhax.h" -#include "os_functions.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct _fs_dev_private_t { - char *mount_path; - int fsaFd; - int mounted; - void *pMutex; -} fs_dev_private_t; - -typedef struct _fs_dev_file_state_t { - fs_dev_private_t *dev; - int fd; /* File descriptor */ - int flags; /* Opening flags */ - 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 */ - struct _fs_dev_file_state_t *nextOpenFile; /* The next entry in a double-linked FILO list of open files */ -} fs_dev_file_state_t; - -typedef struct _fs_dev_dir_entry_t { - fs_dev_private_t *dev; - int dirHandle; -} fs_dev_dir_entry_t; - -static fs_dev_private_t *fs_dev_get_device_data(const char *path) { - const devoptab_t *devoptab = NULL; - char name[128] = {0}; - int i; - - // Get the device name from the path - strncpy(name, path, 127); - strtok(name, ":/"); - - // Search the devoptab table for the specified device name - // NOTE: We do this manually due to a 'bug' in GetDeviceOpTab - // which ignores names with suffixes and causes names - // like "ntfs" and "ntfs1" to be seen as equals - for (i = 3; i < STD_MAX; i++) { - devoptab = devoptab_list[i]; - if (devoptab && devoptab->name) { - if (strcmp(name, devoptab->name) == 0) { - return (fs_dev_private_t *) devoptab->deviceData; - } - } - } - - return NULL; -} - -static char *fs_dev_real_path(const char *path, fs_dev_private_t *dev) { - // Sanity check - if (!path) - return NULL; - - // Move the path pointer to the start of the actual path - if (strchr(path, ':') != NULL) { - path = strchr(path, ':') + 1; - } - - int mount_len = strlen(dev->mount_path); - - char *new_name = (char *) malloc(mount_len + strlen(path) + 1); - if (new_name) { - strcpy(new_name, dev->mount_path); - strcpy(new_name + mount_len, path); - return new_name; - } - 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) { - r->_errno = ENODEV; - return -1; - } - - fs_dev_file_state_t *file = (fs_dev_file_state_t *) fileStruct; - - file->dev = dev; - // Determine which mode the file is opened for - file->flags = flags; - - const char *fsMode; - - // Map flags to open modes - if (flags == 0) { - file->read = true; - file->write = false; - file->append = false; - fsMode = "r"; - } else if (flags == 2) { - file->read = true; - file->write = true; - file->append = false; - fsMode = "r+"; - } else if (flags == 0x601) { - file->read = false; - file->write = true; - file->append = false; - fsMode = "w"; - } else if (flags == 0x602) { - file->read = true; - file->write = true; - file->append = false; - fsMode = "w+"; - } else if (flags == 0x209) { - file->read = false; - file->write = true; - file->append = true; - fsMode = "a"; - } else if (flags == 0x20A) { - file->read = true; - file->write = true; - file->append = true; - fsMode = "a+"; - } else { - r->_errno = EINVAL; - return -1; - } - - - int fd = -1; - - OSLockMutex(dev->pMutex); - - char *real_path = fs_dev_real_path(path, dev); - if (!path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = IOSUHAX_FSA_OpenFile(dev->fsaFd, real_path, fsMode, &fd); - - free(real_path); - - if (result == 0) { - FSStat stats; - result = IOSUHAX_FSA_StatFile(dev->fsaFd, fd, &stats); - if (result != 0) { - IOSUHAX_FSA_CloseFile(dev->fsaFd, fd); - r->_errno = fs_dev_translate_error(result); - OSUnlockMutex(dev->pMutex); - return -1; - } - file->fd = fd; - file->pos = 0; - file->len = stats.size; - OSUnlockMutex(dev->pMutex); - return (int) file; - } - - r->_errno = fs_dev_translate_error(result); - OSUnlockMutex(dev->pMutex); - return -1; -} - - -static int fs_dev_close_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; - } - - OSLockMutex(file->dev->pMutex); - - int result = IOSUHAX_FSA_CloseFile(file->dev->fsaFd, file->fd); - - OSUnlockMutex(file->dev->pMutex); - - if (result < 0) { - r->_errno = fs_dev_translate_error(result); - return -1; - } - return 0; -} - -static off_t fs_dev_seek_r(struct _reent *r, void *fd, off_t pos, int dir) { - fs_dev_file_state_t *file = (fs_dev_file_state_t *) fd; - if (!file->dev) { - r->_errno = ENODEV; - return 0; - } - - OSLockMutex(file->dev->pMutex); - - switch (dir) { - case SEEK_SET: - file->pos = pos; - break; - case SEEK_CUR: - file->pos += pos; - break; - case SEEK_END: - file->pos = file->len + pos; - break; - default: - r->_errno = EINVAL; - return -1; - } - - int result = IOSUHAX_FSA_SetFilePos(file->dev->fsaFd, file->fd, file->pos); - - OSUnlockMutex(file->dev->pMutex); - - if (result == 0) { - return file->pos; - } - - return result; -} - -static ssize_t fs_dev_write_r(struct _reent *r, void *fd, const char *ptr, size_t len) { - fs_dev_file_state_t *file = (fs_dev_file_state_t *) fd; - if (!file->dev) { - r->_errno = ENODEV; - return 0; - } - - if (!file->write) { - r->_errno = EACCES; - return 0; - } - - OSLockMutex(file->dev->pMutex); - - size_t done = 0; - - while (done < len) { - size_t write_size = len - done; - - int result = IOSUHAX_FSA_WriteFile(file->dev->fsaFd, ptr + done, 0x01, write_size, file->fd, 0); - if (result < 0) { - r->_errno = fs_dev_translate_error(result); - break; - } else if (result == 0) { - if (write_size > 0) - done = 0; - break; - } else { - done += result; - file->pos += result; - } - } - - OSUnlockMutex(file->dev->pMutex); - return done; -} - -static ssize_t fs_dev_read_r(struct _reent *r, void *fd, char *ptr, size_t len) { - fs_dev_file_state_t *file = (fs_dev_file_state_t *) fd; - if (!file->dev) { - r->_errno = ENODEV; - return 0; - } - - if (!file->read) { - r->_errno = EACCES; - return 0; - } - - OSLockMutex(file->dev->pMutex); - - size_t done = 0; - - while (done < len) { - size_t read_size = len - done; - - int result = IOSUHAX_FSA_ReadFile(file->dev->fsaFd, ptr + done, 0x01, read_size, file->fd, 0); - if (result < 0) { - r->_errno = fs_dev_translate_error(result); - done = 0; - break; - } else if (result == 0) { - //! TODO: error on read_size > 0 - break; - } else { - done += result; - file->pos += result; - } - } - - OSUnlockMutex(file->dev->pMutex); - return done; -} - - -static int fs_dev_fstat_r(struct _reent *r, void *fd, struct stat *st) { - fs_dev_file_state_t *file = (fs_dev_file_state_t *) fd; - if (!file->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(file->dev->pMutex); - - // Zero out the stat buffer - memset(st, 0, sizeof(struct stat)); - - FSStat stats; - int result = IOSUHAX_FSA_StatFile(file->dev->fsaFd, (int) fd, &stats); - if (result != 0) { - r->_errno = fs_dev_translate_error(result); - OSUnlockMutex(file->dev->pMutex); - return -1; - } - - // 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_stat_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); - - if (result < 0) { - free(real_path); - 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); - - free(real_path); - - 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); - if (result < 0) { - free(real_path); - 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); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - return 0; -} - -static int fs_dev_link_r(struct _reent *r, const char *existing, const char *newLink) { - r->_errno = ENOTSUP; - return -1; -} - -static int fs_dev_unlink_r(struct _reent *r, const char *name) { - fs_dev_private_t *dev = fs_dev_get_device_data(name); - if (!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = fs_dev_real_path(name, dev); - if (!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = IOSUHAX_FSA_Remove(dev->fsaFd, real_path); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if (result < 0) { - r->_errno = fs_dev_translate_error(result); - return -1; - } - - return result; -} - -static int fs_dev_chdir_r(struct _reent *r, const char *name) { - fs_dev_private_t *dev = fs_dev_get_device_data(name); - if (!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = fs_dev_real_path(name, dev); - if (!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = IOSUHAX_FSA_ChangeDir(dev->fsaFd, real_path); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if (result < 0) { - r->_errno = fs_dev_translate_error(result); - return -1; - } - - return 0; -} - -static int fs_dev_rename_r(struct _reent *r, const char *oldName, const char *newName) { - fs_dev_private_t *dev = fs_dev_get_device_data(oldName); - if (!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_oldpath = fs_dev_real_path(oldName, dev); - if (!real_oldpath) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - char *real_newpath = fs_dev_real_path(newName, dev); - if (!real_newpath) { - r->_errno = ENOMEM; - free(real_oldpath); - OSUnlockMutex(dev->pMutex); - return -1; - } - - //! TODO - int result = FS_ERROR_UNSUPPORTED_COMMAND; - - free(real_oldpath); - free(real_newpath); - - OSUnlockMutex(dev->pMutex); - - if (result < 0) { - r->_errno = fs_dev_translate_error(result); - return -1; - } - - return 0; -} - -static int fs_dev_mkdir_r(struct _reent *r, const char *path, int mode) { - fs_dev_private_t *dev = fs_dev_get_device_data(path); - if (!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = fs_dev_real_path(path, dev); - if (!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - 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 = fs_dev_translate_error(result); - return -1; - } - - return 0; -} - -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; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = fs_dev_real_path(path, dev); - if (!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - 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 = fs_dev_translate_error(result); - return -1; - } - - return 0; -} - -static int fs_dev_statvfs_r(struct _reent *r, const char *path, struct statvfs *buf) { - 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(buf, 0, sizeof(struct statvfs)); - - char *real_path = fs_dev_real_path(path, dev); - if (!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - uint64_t size; - - int result = IOSUHAX_FSA_GetDeviceInfo(dev->fsaFd, real_path, 0x00, (uint32_t *) &size); - - free(real_path); - - if (result < 0) { - r->_errno = fs_dev_translate_error(result); - OSUnlockMutex(dev->pMutex); - return -1; - } - - // File system block size - buf->f_bsize = 512; - - // Fundamental file system block size - buf->f_frsize = 512; - - // Total number of blocks on file system in units of f_frsize - buf->f_blocks = size >> 9; // this is unknown - - // Free blocks available for all and for non-privileged processes - buf->f_bfree = buf->f_bavail = size >> 9; - - // Number of inodes at this point in time - buf->f_files = 0xffffffff; - - // Free inodes available for all and for non-privileged processes - buf->f_ffree = 0xffffffff; - - // File system id - buf->f_fsid = (int) dev; - - // Bit mask of f_flag values. - buf->f_flag = 0; - - // Maximum length of filenames - buf->f_namemax = 255; - - OSUnlockMutex(dev->pMutex); - - return 0; -} - -static DIR_ITER *fs_dev_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path) { - fs_dev_private_t *dev = fs_dev_get_device_data(path); - if (!dev) { - r->_errno = ENODEV; - return NULL; - } - - fs_dev_dir_entry_t *dirIter = (fs_dev_dir_entry_t *) dirState->dirStruct; - - OSLockMutex(dev->pMutex); - - char *real_path = fs_dev_real_path(path, dev); - if (!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return NULL; - } - - int dirHandle; - - int result = IOSUHAX_FSA_OpenDir(dev->fsaFd, real_path, &dirHandle); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if (result < 0) { - r->_errno = fs_dev_translate_error(result); - return NULL; - } - - dirIter->dev = dev; - dirIter->dirHandle = dirHandle; - - return dirState; -} - -static int fs_dev_dirclose_r(struct _reent *r, DIR_ITER *dirState) { - fs_dev_dir_entry_t *dirIter = (fs_dev_dir_entry_t *) dirState->dirStruct; - if (!dirIter->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dirIter->dev->pMutex); - - int result = IOSUHAX_FSA_CloseDir(dirIter->dev->fsaFd, dirIter->dirHandle); - - OSUnlockMutex(dirIter->dev->pMutex); - - if (result < 0) { - r->_errno = fs_dev_translate_error(result); - return -1; - } - return 0; -} - -static int fs_dev_dirreset_r(struct _reent *r, DIR_ITER *dirState) { - fs_dev_dir_entry_t *dirIter = (fs_dev_dir_entry_t *) dirState->dirStruct; - if (!dirIter->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dirIter->dev->pMutex); - - int result = IOSUHAX_FSA_RewindDir(dirIter->dev->fsaFd, dirIter->dirHandle); - - OSUnlockMutex(dirIter->dev->pMutex); - - if (result < 0) { - r->_errno = fs_dev_translate_error(result); - return -1; - } - return 0; -} - -static int fs_dev_dirnext_r(struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *st) { - fs_dev_dir_entry_t *dirIter = (fs_dev_dir_entry_t *) dirState->dirStruct; - if (!dirIter->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dirIter->dev->pMutex); - - 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 = fs_dev_translate_error(result); - OSUnlockMutex(dirIter->dev->pMutex); - return -1; - } - - // Fetch the current entry - strcpy(filename, dir_entry->name); - - if (st) { - memset(st, 0, sizeof(struct stat)); - - // 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); - OSUnlockMutex(dirIter->dev->pMutex); - return 0; -} - -static const devoptab_t devops_fs = { - .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) { - devoptab_t *dev = NULL; - char *devname = NULL; - char *devpath = NULL; - int i; - - // Sanity check - if (!name) { - errno = EINVAL; - return -1; - } - - // Allocate a devoptab for this device - dev = (devoptab_t *) malloc(sizeof(devoptab_t) + strlen(name) + 1); - if (!dev) { - errno = ENOMEM; - return -1; - } - - // Use the space allocated at the end of the devoptab for storing the device name - devname = (char *) (dev + 1); - strcpy(devname, name); - - // create private data - fs_dev_private_t *priv = (fs_dev_private_t *) malloc(sizeof(fs_dev_private_t) + strlen(mount_path) + 1); - if (!priv) { - free(dev); - errno = ENOMEM; - return -1; - } - - devpath = (char *) (priv + 1); - strcpy(devpath, mount_path); - - // setup private data - priv->mount_path = devpath; - priv->fsaFd = fsaFd; - priv->mounted = isMounted; - priv->pMutex = malloc(OS_MUTEX_SIZE); - - if (!priv->pMutex) { - free(dev); - free(priv); - errno = ENOMEM; - return -1; - } - - OSInitMutex(priv->pMutex); - - // Setup the devoptab - memcpy(dev, &devops_fs, sizeof(devoptab_t)); - dev->name = devname; - dev->deviceData = priv; - - // Add the device to the devoptab table (if there is a free slot) - for (i = 3; i < STD_MAX; i++) { - if (devoptab_list[i] == devoptab_list[0]) { - devoptab_list[i] = dev; - return 0; - } - } - - // failure, free all memory - free(priv); - free(dev); - - // If we reach here then there are no free slots in the devoptab table for this device - errno = EADDRNOTAVAIL; - return -1; -} - -static int fs_dev_remove_device(const char *path) { - const devoptab_t *devoptab = NULL; - char name[128] = {0}; - int i; - - // Get the device name from the path - strncpy(name, path, 127); - strtok(name, ":/"); - - // Find and remove the specified device from the devoptab table - // NOTE: We do this manually due to a 'bug' in RemoveDevice - // which ignores names with suffixes and causes names - // like "ntfs" and "ntfs1" to be seen as equals - for (i = 3; i < STD_MAX; i++) { - devoptab = devoptab_list[i]; - if (devoptab && devoptab->name) { - if (strcmp(name, devoptab->name) == 0) { - devoptab_list[i] = devoptab_list[0]; - - if (devoptab->deviceData) { - fs_dev_private_t *priv = (fs_dev_private_t *) devoptab->deviceData; - - if (priv->mounted) - IOSUHAX_FSA_Unmount(priv->fsaFd, priv->mount_path, 2); - - if (priv->pMutex) - free(priv->pMutex); - free(devoptab->deviceData); - } - - free((devoptab_t *) devoptab); - return 0; - } - } - } - - return -1; -} - -int mount_fs(const char *virt_name, int fsaFd, const char *dev_path, const char *mount_path) { - int isMounted = 0; - - if (dev_path) { - isMounted = 1; - - int res = IOSUHAX_FSA_Mount(fsaFd, dev_path, mount_path, 2, 0, 0); - if (res != 0) { - return res; - } - } - - return fs_dev_add_device(virt_name, mount_path, fsaFd, isMounted); -} - -int unmount_fs(const char *virt_name) { - return fs_dev_remove_device(virt_name); -}