Skip to content

Commit

Permalink
wutdevoptab: Implement devoptab using FSA functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Maschell committed Feb 18, 2023
1 parent 2862b79 commit f9fdc1a
Show file tree
Hide file tree
Showing 27 changed files with 766 additions and 513 deletions.
25 changes: 25 additions & 0 deletions libraries/wutdevoptab/MutexWrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <coreinit/mutex.h>
#include "coreinit/cache.h"

class MutexWrapper {
public:
MutexWrapper() = default;

void init(const char *name) {
OSInitMutexEx(&mutex, name);
}

void lock() {
OSLockMutex(&mutex);
}

void unlock() {
OSUnlockMutex(&mutex);
OSMemoryBarrier();
}

private:
OSMutex mutex{};
};
186 changes: 88 additions & 98 deletions libraries/wutdevoptab/devoptab_fsa.cpp
Original file line number Diff line number Diff line change
@@ -1,130 +1,120 @@
#include "devoptab_fsa.h"

static devoptab_t
__wut_fs_devoptab =
{
.name = "fs",
.structSize = sizeof(__wut_fs_file_t),
.open_r = __wut_fs_open,
.close_r = __wut_fs_close,
.write_r = __wut_fs_write,
.read_r = __wut_fs_read,
.seek_r = __wut_fs_seek,
.fstat_r = __wut_fs_fstat,
.stat_r = __wut_fs_stat,
.link_r = __wut_fs_link,
.unlink_r = __wut_fs_unlink,
.chdir_r = __wut_fs_chdir,
.rename_r = __wut_fs_rename,
.mkdir_r = __wut_fs_mkdir,
.dirStateSize = sizeof(__wut_fs_dir_t),
.diropen_r = __wut_fs_diropen,
.dirreset_r = __wut_fs_dirreset,
.dirnext_r = __wut_fs_dirnext,
.dirclose_r = __wut_fs_dirclose,
.statvfs_r = __wut_fs_statvfs,
.ftruncate_r = __wut_fs_ftruncate,
.fsync_r = __wut_fs_fsync,
.lstat_r = __wut_fs_stat,
.deviceData = NULL,
.chmod_r = __wut_fs_chmod,
.fchmod_r = __wut_fs_fchmod,
.rmdir_r = __wut_fs_rmdir,
.utimes_r = __wut_fs_utimes,
};

FSClient *
__wut_devoptab_fs_client = NULL;

static BOOL
__wut_fs_initialised = FALSE;

static BOOL
__wut_sd_mounted = FALSE;

static char
sMountPath[0x80];

FSStatus
__init_wut_devoptab()
{
FSStatus rc = 0;

if (__wut_fs_initialised) {
__wut_fsa_devoptab =
{
.name = "fs",
.structSize = sizeof(__wut_fsa_file_t),
.open_r = __wut_fsa_open,
.close_r = __wut_fsa_close,
.write_r = __wut_fsa_write,
.read_r = __wut_fsa_read,
.seek_r = __wut_fsa_seek,
.fstat_r = __wut_fsa_fstat,
.stat_r = __wut_fsa_stat,
.link_r = __wut_fsa_link,
.unlink_r = __wut_fsa_unlink,
.chdir_r = __wut_fsa_chdir,
.rename_r = __wut_fsa_rename,
.mkdir_r = __wut_fsa_mkdir,
.dirStateSize = sizeof(__wut_fsa_dir_t),
.diropen_r = __wut_fsa_diropen,
.dirreset_r = __wut_fsa_dirreset,
.dirnext_r = __wut_fsa_dirnext,
.dirclose_r = __wut_fsa_dirclose,
.statvfs_r = __wut_fsa_statvfs,
.ftruncate_r = __wut_fsa_ftruncate,
.fsync_r = __wut_fsa_fsync,
.lstat_r = __wut_fsa_stat,
.deviceData = nullptr,
.chmod_r = __wut_fsa_chmod,
.fchmod_r = __wut_fsa_fchmod,
.rmdir_r = __wut_fsa_rmdir,
.lstat_r = __wut_fsa_stat,
.utimes_r = __wut_fsa_utimes,
};


__wut_fsa_device_t __wut_fsa_device_data = {};

FSError __init_wut_devoptab() {
FSError rc = FS_ERROR_OK;

if (__wut_fsa_device_data.setup) {
return rc;
}

__wut_devoptab_fs_client = memalign(0x20, sizeof(FSClient));
FSCmdBlock fsCmd;
FSMountSource mountSource;
char workDir[0x83];

FSInit();
rc = FSAddClient(__wut_devoptab_fs_client, -1);

if (rc < 0) {
free(__wut_devoptab_fs_client);
__wut_fsa_device_data = {};
memcpy(&__wut_fsa_device_data.device, &__wut_fsa_devoptab, sizeof(__wut_fsa_devoptab));
__wut_fsa_device_data.device.deviceData = &__wut_fsa_device_data;
strncpy(__wut_fsa_device_data.name, "fs", sizeof(__wut_fsa_device_data.name) - 1);
__wut_fsa_device_data.device.name = __wut_fsa_device_data.name;
__wut_fsa_device_data.setup = false;
__wut_fsa_device_data.mounted = false;
__wut_fsa_device_data.isSDCard = false;

FSAInit();
__wut_fsa_device_data.clientHandle = FSAAddClient(nullptr);
if (__wut_fsa_device_data.clientHandle == 0) {
OSReport("FSAAddClient() failed: %s", FSAGetStatusStr(static_cast<FSError>(__wut_fsa_device_data.clientHandle)));
return rc;
}

FSInitCmdBlock(&fsCmd);

if (rc >= 0) {
int dev = AddDevice(&__wut_fs_devoptab);
int dev = AddDevice(&__wut_fsa_device_data.device);

if(dev != -1) {
setDefaultDevice(dev);
__wut_fs_initialised = TRUE;
if (dev != -1) {
setDefaultDevice(dev);
__wut_fsa_device_data.setup = true;
strncpy(__wut_fsa_device_data.mountPath, "/vol/external01", sizeof(__wut_fsa_device_data.mountPath) - 1);

// Mount the SD card
rc = FSGetMountSource(__wut_devoptab_fs_client, &fsCmd, FS_MOUNT_SOURCE_SD, &mountSource, -1);
rc = FSAMount(__wut_fsa_device_data.clientHandle, "/dev/sdcard01", __wut_fsa_device_data.mountPath, (FSAMountFlags) 0, nullptr, 0);

if (rc < 0) {
return rc;
}
if (rc < 0 && rc != FS_ERROR_ALREADY_EXISTS) {
OSReport("FSAMount(0x%08X, \"/dev/sdcard01\", %s, %08X, %08X, %08X) failed: %s\n", __wut_fsa_device_data.clientHandle, __wut_fsa_device_data.mountPath, 0, 0, 0, FSAGetStatusStr(rc));
return rc;
}

rc = FSMount(__wut_devoptab_fs_client, &fsCmd, &mountSource, sMountPath, sizeof(sMountPath), FS_ERROR_FLAG_ALL);
__wut_fsa_device_data.isSDCard = true;
__wut_fsa_device_data.mounted = true;
chdir("fs:/vol/external01");

if (rc >= 0) {
__wut_sd_mounted = TRUE;
// chdir to SD root for general use
strcpy(workDir, "fs:");
strcat(workDir, sMountPath);
chdir(workDir);
}
FSADeviceInfo deviceInfo;
if ((rc = FSAGetDeviceInfo(__wut_fsa_device_data.clientHandle, __wut_fsa_device_data.mountPath, &deviceInfo)) >= 0) {
__wut_fsa_device_data.deviceSizeInSectors = deviceInfo.deviceSizeInSectors;
__wut_fsa_device_data.deviceSectorSize = deviceInfo.deviceSectorSize;
} else {
FSDelClient(__wut_devoptab_fs_client, FS_ERROR_FLAG_ALL);
free(__wut_devoptab_fs_client);
return dev;
__wut_fsa_device_data.deviceSizeInSectors = 0xFFFFFFFF;
__wut_fsa_device_data.deviceSectorSize = 512;
OSReport("Failed to get DeviceInfo for %s: %s\n", __wut_fsa_device_data.mountPath, FSAGetStatusStr(rc));
}

} else {
FSADelClient(__wut_fsa_device_data.clientHandle);
__wut_fsa_device_data.clientHandle = 0;
return FS_ERROR_MAX_CLIENTS;
}

return rc;
}

FSStatus
__fini_wut_devoptab()
{
FSStatus rc = 0;
FSError
__fini_wut_devoptab() {
FSError rc = FS_ERROR_OK;

if (!__wut_fs_initialised) {
if (!__wut_fsa_device_data.setup) {
return rc;
}

FSCmdBlock fsCmd;
if(__wut_sd_mounted) {
FSInitCmdBlock(&fsCmd);
FSUnmount(__wut_devoptab_fs_client, &fsCmd, sMountPath, FS_ERROR_FLAG_ALL);
__wut_sd_mounted = FALSE;
if (__wut_fsa_device_data.mounted) {
FSAUnmount(__wut_fsa_device_data.clientHandle, __wut_fsa_device_data.mountPath, FSA_UNMOUNT_FLAG_BIND_MOUNT);
__wut_fsa_device_data.mounted = false;
}

FSDelClient(__wut_devoptab_fs_client, FS_ERROR_FLAG_ALL);
free(__wut_devoptab_fs_client);
FSADelClient(__wut_fsa_device_data.clientHandle);

RemoveDevice(__wut_fs_devoptab.name);
RemoveDevice(__wut_fsa_device_data.device.name);

__wut_devoptab_fs_client = NULL;
__wut_fs_initialised = FALSE;
__wut_fsa_device_data.setup = false;

return rc;
}
Loading

0 comments on commit f9fdc1a

Please sign in to comment.