mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
Major cleanup and refactor of fsdev and romfsdev, see details:
fsdev: - Removed fsdevGetDefaultFileSystem and default-fs handling - Refactored CWD support to have (dynamically allocated) per-device CWDs (CWD support as a whole can be turned off with __nx_fsdev_support_cwd) - Optimized calls by passing pointer to device through r->deviceData - Use the per-thread path buffer directly as the argument to FS functions - Removed redundant cross-device check in fsdev_rename - Fixed string comparison logic in fsdevFindDevice - fsdev_fixpath now accepts an input device in order to skip device lookup (extensively used along with r->deviceData) - Mounting a filesystem now automatically sets the default device if there wasn't any previous default device (or if it's stdnull) - fsdevMountSdmc no longer sets cwd to the folder containing the executable - this logic was moved to a new internal function called on startup by default (and it is now disabled for NSOs) - Other miscellaneous optimizations romfsdev: - Cleaned up romfsMount* functions, removed unused/unnecessary logic - Changed romfsMount* functions to return real result codes - Renamed romfsMount to romfsMountSelf and improved documentation - Removed romfsInitFromFile and romfsInitFromStorage (use Mount instead) - Added documentation for romfsInit and romfsExit
This commit is contained in:
parent
0403c988ba
commit
c77b88d868
@ -27,7 +27,7 @@ NX_CONSTEXPR FsDirectoryEntry* fsdevDirGetEntries(fsdev_dir_t *dir)
|
|||||||
return (FsDirectoryEntry*)(void*)(dir+1);
|
return (FsDirectoryEntry*)(void*)(dir+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes and mounts the sdmc device if accessible. Also initializes current working directory to point to the folder containing the path to the executable (argv[0]), if it is provided by the environment.
|
/// Initializes and mounts the sdmc device if accessible.
|
||||||
Result fsdevMountSdmc(void);
|
Result fsdevMountSdmc(void);
|
||||||
|
|
||||||
/// Mounts the input fs with the specified device name. fsdev will handle closing the fs when required, including when fsdevMountDevice() fails.
|
/// Mounts the input fs with the specified device name. fsdev will handle closing the fs when required, including when fsdevMountDevice() fails.
|
||||||
@ -44,9 +44,6 @@ Result fsdevCommitDevice(const char *name);
|
|||||||
/// Returns the FsFileSystem for the specified device. Returns NULL when the specified device isn't found.
|
/// Returns the FsFileSystem for the specified device. Returns NULL when the specified device isn't found.
|
||||||
FsFileSystem* fsdevGetDeviceFileSystem(const char *name);
|
FsFileSystem* fsdevGetDeviceFileSystem(const char *name);
|
||||||
|
|
||||||
/// Returns the FsFileSystem for the default device (SD card), if mounted. Used internally by romfs_dev.
|
|
||||||
FsFileSystem* fsdevGetDefaultFileSystem(void);
|
|
||||||
|
|
||||||
/// Writes the FS-path to outpath (which has buffer size FS_MAX_PATH), for the input path (as used in stdio). The FsFileSystem is also written to device when not NULL.
|
/// Writes the FS-path to outpath (which has buffer size FS_MAX_PATH), for the input path (as used in stdio). The FsFileSystem is also written to device when not NULL.
|
||||||
int fsdevTranslatePath(const char *path, FsFileSystem** device, char *outpath);
|
int fsdevTranslatePath(const char *path, FsFileSystem** device, char *outpath);
|
||||||
|
|
||||||
|
@ -53,12 +53,11 @@ typedef struct
|
|||||||
/**
|
/**
|
||||||
* @brief Mounts the Application's RomFS.
|
* @brief Mounts the Application's RomFS.
|
||||||
* @param name Device mount name.
|
* @param name Device mount name.
|
||||||
|
* @remark This function is intended to be used to access one's own RomFS.
|
||||||
|
* If the application is running as NRO, it mounts the embedded RomFS section inside the NRO.
|
||||||
|
* If on the other hand it's an NSO, it behaves identically to \ref romfsMountFromCurrentProcess.
|
||||||
*/
|
*/
|
||||||
Result romfsMount(const char *name);
|
Result romfsMountSelf(const char *name);
|
||||||
static inline Result romfsInit(void)
|
|
||||||
{
|
|
||||||
return romfsMount("romfs");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Mounts RomFS from an open file.
|
* @brief Mounts RomFS from an open file.
|
||||||
@ -67,10 +66,6 @@ static inline Result romfsInit(void)
|
|||||||
* @param name Device mount name.
|
* @param name Device mount name.
|
||||||
*/
|
*/
|
||||||
Result romfsMountFromFile(FsFile file, u64 offset, const char *name);
|
Result romfsMountFromFile(FsFile file, u64 offset, const char *name);
|
||||||
static inline Result romfsInitFromFile(FsFile file, u64 offset)
|
|
||||||
{
|
|
||||||
return romfsMountFromFile(file, offset, "romfs");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Mounts RomFS from an open storage.
|
* @brief Mounts RomFS from an open storage.
|
||||||
@ -79,10 +74,6 @@ static inline Result romfsInitFromFile(FsFile file, u64 offset)
|
|||||||
* @param name Device mount name.
|
* @param name Device mount name.
|
||||||
*/
|
*/
|
||||||
Result romfsMountFromStorage(FsStorage storage, u64 offset, const char *name);
|
Result romfsMountFromStorage(FsStorage storage, u64 offset, const char *name);
|
||||||
static inline Result romfsInitFromStorage(FsStorage storage, u64 offset)
|
|
||||||
{
|
|
||||||
return romfsMountFromStorage(storage, offset, "romfs");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Mounts RomFS using the current process host title RomFS.
|
* @brief Mounts RomFS using the current process host title RomFS.
|
||||||
@ -108,8 +99,15 @@ Result romfsMountFromDataArchive(u64 dataId, FsStorageId storageId, const char *
|
|||||||
|
|
||||||
/// Unmounts the RomFS device.
|
/// Unmounts the RomFS device.
|
||||||
Result romfsUnmount(const char *name);
|
Result romfsUnmount(const char *name);
|
||||||
|
|
||||||
|
/// Wrapper for \ref romfsMountSelf with the default "romfs" device name.
|
||||||
|
static inline Result romfsInit(void)
|
||||||
|
{
|
||||||
|
return romfsMountSelf("romfs");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Wrapper for \ref romfsUnmount with the default "romfs" device name.
|
||||||
static inline Result romfsExit(void)
|
static inline Result romfsExit(void)
|
||||||
{
|
{
|
||||||
return romfsUnmount("romfs");
|
return romfsUnmount("romfs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "runtime/devices/fs_dev.h"
|
#include "runtime/devices/fs_dev.h"
|
||||||
#include "runtime/util/utf.h"
|
#include "runtime/util/utf.h"
|
||||||
|
#include "runtime/env.h"
|
||||||
#include "services/fs.h"
|
#include "services/fs.h"
|
||||||
#include "services/time.h"
|
#include "services/time.h"
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ typedef struct
|
|||||||
} fsdev_file_t;
|
} fsdev_file_t;
|
||||||
|
|
||||||
/*! fsdev devoptab */
|
/*! fsdev devoptab */
|
||||||
static devoptab_t
|
static const devoptab_t
|
||||||
fsdev_devoptab =
|
fsdev_devoptab =
|
||||||
{
|
{
|
||||||
.structSize = sizeof(fsdev_file_t),
|
.structSize = sizeof(fsdev_file_t),
|
||||||
@ -94,24 +95,25 @@ fsdev_devoptab =
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
bool setup;
|
bool setup;
|
||||||
s32 id;
|
s32 id;
|
||||||
devoptab_t device;
|
devoptab_t device;
|
||||||
FsFileSystem fs;
|
FsFileSystem fs;
|
||||||
char name[32];
|
char *cwd;
|
||||||
|
char name[32];
|
||||||
} fsdev_fsdevice;
|
} fsdev_fsdevice;
|
||||||
|
|
||||||
static bool fsdev_initialised = false;
|
static bool fsdev_initialised = false;
|
||||||
static s32 fsdev_fsdevice_default = -1;
|
static s32 fsdev_fsdevice_cwd;
|
||||||
static s32 fsdev_fsdevice_cwd = -1;
|
|
||||||
static __thread Result fsdev_last_result = 0;
|
static __thread Result fsdev_last_result = 0;
|
||||||
static fsdev_fsdevice fsdev_fsdevices[32];
|
static fsdev_fsdevice fsdev_fsdevices[32];
|
||||||
|
|
||||||
/*! @endcond */
|
/*! @endcond */
|
||||||
|
|
||||||
static char __cwd[PATH_MAX+1] = "/";
|
_Static_assert((PATH_MAX+1) >= FS_MAX_PATH, "PATH_MAX is too small");
|
||||||
|
|
||||||
__attribute__((weak)) u32 __nx_fsdev_direntry_cache_size = 32;
|
__attribute__((weak)) u32 __nx_fsdev_direntry_cache_size = 32;
|
||||||
|
__attribute__((weak)) bool __nx_fsdev_support_cwd = true;
|
||||||
|
|
||||||
static fsdev_fsdevice *fsdevFindDevice(const char *name)
|
static fsdev_fsdevice *fsdevFindDevice(const char *name)
|
||||||
{
|
{
|
||||||
@ -122,18 +124,6 @@ static fsdev_fsdevice *fsdevFindDevice(const char *name)
|
|||||||
if(!fsdev_initialised)
|
if(!fsdev_initialised)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(name && name[0] == '/') //Return the default device.
|
|
||||||
{
|
|
||||||
if(fsdev_fsdevice_default==-1)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
device = &fsdev_fsdevices[fsdev_fsdevice_default];
|
|
||||||
if(!device->setup)
|
|
||||||
device = NULL;
|
|
||||||
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i=0; i<total; i++)
|
for(i=0; i<total; i++)
|
||||||
{
|
{
|
||||||
device = &fsdev_fsdevices[i];
|
device = &fsdev_fsdevices[i];
|
||||||
@ -145,7 +135,8 @@ static fsdev_fsdevice *fsdevFindDevice(const char *name)
|
|||||||
}
|
}
|
||||||
else if(device->setup) //Find the device with the input name.
|
else if(device->setup) //Find the device with the input name.
|
||||||
{
|
{
|
||||||
if(strncmp(device->name, name, strlen(device->name))==0)
|
size_t devnamelen = strlen(device->name);
|
||||||
|
if(strncmp(device->name, name, devnamelen)==0 && (name[devnamelen]=='\0' || name[devnamelen]==':'))
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,13 +192,27 @@ fsdev_fixpath(struct _reent *r,
|
|||||||
p += units;
|
p += units;
|
||||||
} while(code != 0);
|
} while(code != 0);
|
||||||
|
|
||||||
|
fsdev_fsdevice *dev = NULL;
|
||||||
|
if(device && *device != NULL)
|
||||||
|
dev = *device;
|
||||||
|
else if(path != device_path)
|
||||||
|
dev = fsdevFindDevice(device_path);
|
||||||
|
else if(fsdev_fsdevice_cwd != -1)
|
||||||
|
dev = &fsdev_fsdevices[fsdev_fsdevice_cwd];
|
||||||
|
if(dev == NULL)
|
||||||
|
{
|
||||||
|
r->_errno = ENODEV;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if(path[0] == '/')
|
if(path[0] == '/')
|
||||||
strncpy(__nx_dev_path_buf, path, PATH_MAX);
|
strncpy(__nx_dev_path_buf, path, PATH_MAX);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strncpy(__nx_dev_path_buf, __cwd, PATH_MAX);
|
const char* cwd = dev->cwd ? dev->cwd : "/";
|
||||||
|
strncpy(__nx_dev_path_buf, cwd, PATH_MAX);
|
||||||
__nx_dev_path_buf[PATH_MAX] = '\0';
|
__nx_dev_path_buf[PATH_MAX] = '\0';
|
||||||
strncat(__nx_dev_path_buf, path, PATH_MAX - strlen(__cwd));
|
strncat(__nx_dev_path_buf, path, PATH_MAX - strlen(cwd));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(__nx_dev_path_buf[PATH_MAX] != 0)
|
if(__nx_dev_path_buf[PATH_MAX] != 0)
|
||||||
@ -218,23 +223,7 @@ fsdev_fixpath(struct _reent *r,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(device)
|
if(device)
|
||||||
{
|
*device = dev;
|
||||||
if(path[0] == '/')
|
|
||||||
{
|
|
||||||
*device = fsdevFindDevice(device_path);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*device = NULL;
|
|
||||||
if(fsdev_fsdevice_cwd != -1)
|
|
||||||
*device = &fsdev_fsdevices[fsdev_fsdevice_cwd];
|
|
||||||
}
|
|
||||||
if(*device == NULL)
|
|
||||||
{
|
|
||||||
r->_errno = ENODEV;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return __nx_dev_path_buf;
|
return __nx_dev_path_buf;
|
||||||
}
|
}
|
||||||
@ -248,7 +237,8 @@ fsdev_getfspath(struct _reent *r,
|
|||||||
if(fsdev_fixpath(r, path, device) == NULL)
|
if(fsdev_fixpath(r, path, device) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memcpy(outpath, __nx_dev_path_buf,FS_MAX_PATH-1);
|
if(outpath != __nx_dev_path_buf)
|
||||||
|
memcpy(outpath, __nx_dev_path_buf, FS_MAX_PATH-1);
|
||||||
outpath[FS_MAX_PATH-1] = '\0';
|
outpath[FS_MAX_PATH-1] = '\0';
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -302,10 +292,11 @@ static void _fsdevInit(void)
|
|||||||
memcpy(&fsdev_fsdevices[i].device, &fsdev_devoptab, sizeof(fsdev_devoptab));
|
memcpy(&fsdev_fsdevices[i].device, &fsdev_devoptab, sizeof(fsdev_devoptab));
|
||||||
fsdev_fsdevices[i].device.name = fsdev_fsdevices[i].name;
|
fsdev_fsdevices[i].device.name = fsdev_fsdevices[i].name;
|
||||||
fsdev_fsdevices[i].device.dirStateSize += sizeof(FsDirectoryEntry)*__nx_fsdev_direntry_cache_size;
|
fsdev_fsdevices[i].device.dirStateSize += sizeof(FsDirectoryEntry)*__nx_fsdev_direntry_cache_size;
|
||||||
|
fsdev_fsdevices[i].device.deviceData = &fsdev_fsdevices[i];
|
||||||
fsdev_fsdevices[i].id = i;
|
fsdev_fsdevices[i].id = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
fsdev_fsdevice_default = -1;
|
fsdev_fsdevice_cwd = -1;
|
||||||
fsdev_initialised = true;
|
fsdev_initialised = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -314,20 +305,14 @@ static int _fsdevMountDevice(const char *name, FsFileSystem fs, fsdev_fsdevice *
|
|||||||
{
|
{
|
||||||
fsdev_fsdevice *device = NULL;
|
fsdev_fsdevice *device = NULL;
|
||||||
|
|
||||||
_fsdevInit(); //Ensure fsdev is initialized
|
|
||||||
|
|
||||||
if(fsdevFindDevice(name)) //Device is already mounted with the same name.
|
if(fsdevFindDevice(name)) //Device is already mounted with the same name.
|
||||||
{
|
goto _fail;
|
||||||
fsFsClose(&fs);
|
|
||||||
return -1;
|
_fsdevInit(); //Ensure fsdev is initialized
|
||||||
}
|
|
||||||
|
|
||||||
device = fsdevFindDevice(NULL);
|
device = fsdevFindDevice(NULL);
|
||||||
if(device==NULL)
|
if(device==NULL)
|
||||||
{
|
goto _fail;
|
||||||
fsFsClose(&fs);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
device->fs = fs;
|
device->fs = fs;
|
||||||
memset(device->name, 0, sizeof(device->name));
|
memset(device->name, 0, sizeof(device->name));
|
||||||
@ -335,17 +320,31 @@ static int _fsdevMountDevice(const char *name, FsFileSystem fs, fsdev_fsdevice *
|
|||||||
|
|
||||||
int dev = AddDevice(&device->device);
|
int dev = AddDevice(&device->device);
|
||||||
if(dev==-1)
|
if(dev==-1)
|
||||||
{
|
goto _fail;
|
||||||
fsFsClose(&device->fs);
|
|
||||||
return dev;
|
|
||||||
}
|
|
||||||
|
|
||||||
device->setup = 1;
|
device->setup = 1;
|
||||||
|
device->cwd = __nx_fsdev_support_cwd ? malloc(FS_MAX_PATH) : NULL;
|
||||||
|
if(device->cwd!=NULL)
|
||||||
|
{
|
||||||
|
device->cwd[0] = '/';
|
||||||
|
device->cwd[1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fsdev_fsdevice_cwd==-1)
|
||||||
|
fsdev_fsdevice_cwd = device->id;
|
||||||
|
|
||||||
|
const devoptab_t *default_dev = GetDeviceOpTab("");
|
||||||
|
if(default_dev==NULL || strcmp(default_dev->name, "stdnull")==0)
|
||||||
|
setDefaultDevice(dev);
|
||||||
|
|
||||||
if(out_device)
|
if(out_device)
|
||||||
*out_device = device;
|
*out_device = device;
|
||||||
|
|
||||||
return dev;
|
return dev;
|
||||||
|
|
||||||
|
_fail:
|
||||||
|
fsFsClose(&fs);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fsdevMountDevice(const char *name, FsFileSystem fs)
|
int fsdevMountDevice(const char *name, FsFileSystem fs)
|
||||||
@ -365,13 +364,11 @@ static int _fsdevUnmountDeviceStruct(fsdev_fsdevice *device)
|
|||||||
strncat(name, ":", sizeof(name)-strlen(name)-1);
|
strncat(name, ":", sizeof(name)-strlen(name)-1);
|
||||||
|
|
||||||
RemoveDevice(name);
|
RemoveDevice(name);
|
||||||
|
free(device->cwd);
|
||||||
fsFsClose(&device->fs);
|
fsFsClose(&device->fs);
|
||||||
|
|
||||||
if(device->id == fsdev_fsdevice_default)
|
|
||||||
fsdev_fsdevice_default = -1;
|
|
||||||
|
|
||||||
if(device->id == fsdev_fsdevice_cwd)
|
if(device->id == fsdev_fsdevice_cwd)
|
||||||
fsdev_fsdevice_cwd = fsdev_fsdevice_default;
|
fsdev_fsdevice_cwd = -1;
|
||||||
|
|
||||||
device->setup = 0;
|
device->setup = 0;
|
||||||
memset(device->name, 0, sizeof(device->name));
|
memset(device->name, 0, sizeof(device->name));
|
||||||
@ -402,7 +399,7 @@ Result fsdevCommitDevice(const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result fsdevSetArchiveBit(const char *path) {
|
Result fsdevSetArchiveBit(const char *path) {
|
||||||
char fs_path[FS_MAX_PATH];
|
char *fs_path = __nx_dev_path_buf;
|
||||||
fsdev_fsdevice *device = NULL;
|
fsdev_fsdevice *device = NULL;
|
||||||
|
|
||||||
if(fsdev_getfspath(_REENT, path, &device, fs_path)==-1)
|
if(fsdev_getfspath(_REENT, path, &device, fs_path)==-1)
|
||||||
@ -412,7 +409,7 @@ Result fsdevSetArchiveBit(const char *path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result fsdevCreateFile(const char* path, size_t size, u32 flags) {
|
Result fsdevCreateFile(const char* path, size_t size, u32 flags) {
|
||||||
char fs_path[FS_MAX_PATH];
|
char *fs_path = __nx_dev_path_buf;
|
||||||
fsdev_fsdevice *device = NULL;
|
fsdev_fsdevice *device = NULL;
|
||||||
|
|
||||||
if(fsdev_getfspath(_REENT, path, &device, fs_path)==-1)
|
if(fsdev_getfspath(_REENT, path, &device, fs_path)==-1)
|
||||||
@ -422,7 +419,7 @@ Result fsdevCreateFile(const char* path, size_t size, u32 flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result fsdevDeleteDirectoryRecursively(const char *path) {
|
Result fsdevDeleteDirectoryRecursively(const char *path) {
|
||||||
char fs_path[FS_MAX_PATH];
|
char *fs_path = __nx_dev_path_buf;
|
||||||
fsdev_fsdevice *device = NULL;
|
fsdev_fsdevice *device = NULL;
|
||||||
|
|
||||||
if(fsdev_getfspath(_REENT, path, &device, fs_path)==-1)
|
if(fsdev_getfspath(_REENT, path, &device, fs_path)==-1)
|
||||||
@ -434,72 +431,49 @@ Result fsdevDeleteDirectoryRecursively(const char *path) {
|
|||||||
/*! Initialize SDMC device */
|
/*! Initialize SDMC device */
|
||||||
Result fsdevMountSdmc(void)
|
Result fsdevMountSdmc(void)
|
||||||
{
|
{
|
||||||
ssize_t units;
|
|
||||||
uint32_t code;
|
|
||||||
char *p;
|
|
||||||
Result rc = 0;
|
|
||||||
FsFileSystem fs;
|
FsFileSystem fs;
|
||||||
fsdev_fsdevice *device = NULL;
|
Result rc = fsMountSdcard(&fs);
|
||||||
|
|
||||||
if(fsdevFindDevice("sdmc"))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
rc = fsMountSdcard(&fs);
|
|
||||||
if(R_SUCCEEDED(rc))
|
if(R_SUCCEEDED(rc))
|
||||||
{
|
{
|
||||||
int dev = _fsdevMountDevice("sdmc", fs, &device);
|
int ret = fsdevMountDevice("sdmc", fs);
|
||||||
|
if(ret==-1)
|
||||||
if(dev != -1)
|
rc = MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
|
||||||
{
|
|
||||||
setDefaultDevice(dev);
|
|
||||||
if(device)
|
|
||||||
{
|
|
||||||
fsdev_fsdevice_default = device->id;
|
|
||||||
fsdev_fsdevice_cwd = fsdev_fsdevice_default;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(__system_argc != 0 && __system_argv[0] != NULL)
|
|
||||||
{
|
|
||||||
if(FindDevice(__system_argv[0]) == dev)
|
|
||||||
{
|
|
||||||
strncpy(__nx_dev_path_buf,__system_argv[0],PATH_MAX);
|
|
||||||
if(__nx_dev_path_buf[PATH_MAX] != 0)
|
|
||||||
{
|
|
||||||
__nx_dev_path_buf[PATH_MAX] = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char *last_slash = NULL;
|
|
||||||
p = __nx_dev_path_buf;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
units = decode_utf8(&code, (const uint8_t*)p);
|
|
||||||
if(units < 0)
|
|
||||||
{
|
|
||||||
last_slash = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(code == '/')
|
|
||||||
last_slash = p;
|
|
||||||
|
|
||||||
p += units;
|
|
||||||
} while(code != 0);
|
|
||||||
|
|
||||||
if(last_slash != NULL)
|
|
||||||
{
|
|
||||||
last_slash[0] = 0;
|
|
||||||
chdir(__nx_dev_path_buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __libnx_init_cwd(void)
|
||||||
|
{
|
||||||
|
if(envIsNso() || __system_argc==0 || __system_argv[0] == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char *last_slash = NULL;
|
||||||
|
char *p = __system_argv[0];
|
||||||
|
uint32_t code;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ssize_t units = decode_utf8(&code, (const uint8_t*)p);
|
||||||
|
if(units < 0)
|
||||||
|
{
|
||||||
|
last_slash = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(code == '/')
|
||||||
|
last_slash = p;
|
||||||
|
|
||||||
|
p += units;
|
||||||
|
} while(code != 0);
|
||||||
|
|
||||||
|
if(last_slash != NULL)
|
||||||
|
{
|
||||||
|
last_slash[0] = 0;
|
||||||
|
chdir(__system_argv[0]);
|
||||||
|
last_slash[0] = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*! Clean up fsdev devices */
|
/*! Clean up fsdev devices */
|
||||||
Result fsdevUnmountAll(void)
|
Result fsdevUnmountAll(void)
|
||||||
{
|
{
|
||||||
@ -530,14 +504,6 @@ FsFileSystem* fsdevGetDeviceFileSystem(const char *name)
|
|||||||
return &device->fs;
|
return &device->fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
FsFileSystem* fsdevGetDefaultFileSystem(void)
|
|
||||||
{
|
|
||||||
if(!fsdev_initialised) return NULL;
|
|
||||||
if(fsdev_fsdevice_default==-1) return NULL;
|
|
||||||
|
|
||||||
return &fsdev_fsdevices[fsdev_fsdevice_default].fs;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fsdevTranslatePath(const char *path, FsFileSystem** device, char *outpath)
|
int fsdevTranslatePath(const char *path, FsFileSystem** device, char *outpath)
|
||||||
{
|
{
|
||||||
fsdev_fsdevice *tmpdev = NULL;
|
fsdev_fsdevice *tmpdev = NULL;
|
||||||
@ -571,8 +537,8 @@ fsdev_open(struct _reent *r,
|
|||||||
Result rc;
|
Result rc;
|
||||||
u32 fsdev_flags = 0;
|
u32 fsdev_flags = 0;
|
||||||
u32 attributes = 0;
|
u32 attributes = 0;
|
||||||
char fs_path[FS_MAX_PATH];
|
char *fs_path = __nx_dev_path_buf;
|
||||||
fsdev_fsdevice *device = NULL;
|
fsdev_fsdevice *device = r->deviceData;
|
||||||
|
|
||||||
if(fsdev_getfspath(r, path, &device, fs_path)==-1)
|
if(fsdev_getfspath(r, path, &device, fs_path)==-1)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1025,8 +991,8 @@ fsdev_stat(struct _reent *r,
|
|||||||
FsDir fdir;
|
FsDir fdir;
|
||||||
Result rc;
|
Result rc;
|
||||||
int ret=0;
|
int ret=0;
|
||||||
char fs_path[FS_MAX_PATH];
|
char *fs_path = __nx_dev_path_buf;
|
||||||
fsdev_fsdevice *device = NULL;
|
fsdev_fsdevice *device = r->deviceData;
|
||||||
FsTimeStampRaw timestamps = {0};
|
FsTimeStampRaw timestamps = {0};
|
||||||
FsDirEntryType type;
|
FsDirEntryType type;
|
||||||
|
|
||||||
@ -1111,8 +1077,8 @@ fsdev_unlink(struct _reent *r,
|
|||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
Result rc;
|
Result rc;
|
||||||
char fs_path[FS_MAX_PATH];
|
char *fs_path = __nx_dev_path_buf;
|
||||||
fsdev_fsdevice *device = NULL;
|
fsdev_fsdevice *device = r->deviceData;
|
||||||
|
|
||||||
if(fsdev_getfspath(r, name, &device, fs_path)==-1)
|
if(fsdev_getfspath(r, name, &device, fs_path)==-1)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1139,8 +1105,14 @@ fsdev_chdir(struct _reent *r,
|
|||||||
{
|
{
|
||||||
FsDir fd;
|
FsDir fd;
|
||||||
Result rc;
|
Result rc;
|
||||||
char fs_path[FS_MAX_PATH];
|
char *fs_path = __nx_dev_path_buf;
|
||||||
fsdev_fsdevice *device = NULL;
|
fsdev_fsdevice *device = r->deviceData;
|
||||||
|
|
||||||
|
if(device->cwd==NULL)
|
||||||
|
{
|
||||||
|
r->_errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if(fsdev_getfspath(r, name, &device, fs_path)==-1)
|
if(fsdev_getfspath(r, name, &device, fs_path)==-1)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1149,15 +1121,13 @@ fsdev_chdir(struct _reent *r,
|
|||||||
if(R_SUCCEEDED(rc))
|
if(R_SUCCEEDED(rc))
|
||||||
{
|
{
|
||||||
fsDirClose(&fd);
|
fsDirClose(&fd);
|
||||||
strncpy(__cwd, fs_path, PATH_MAX);
|
memcpy(device->cwd, fs_path, FS_MAX_PATH);
|
||||||
__cwd[PATH_MAX] = '\0';
|
|
||||||
|
|
||||||
size_t __cwd_len = strlen(__cwd);
|
size_t cwdlen = strlen(fs_path);
|
||||||
|
if (device->cwd[cwdlen-1] != '/' && cwdlen < FS_MAX_PATH-1)
|
||||||
if (__cwd[__cwd_len-1] != '/' && __cwd_len < PATH_MAX)
|
|
||||||
{
|
{
|
||||||
__cwd[__cwd_len] = '/';
|
device->cwd[cwdlen] = '/';
|
||||||
__cwd[__cwd_len+1] = '\0';
|
device->cwd[cwdlen+1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
fsdev_fsdevice_cwd = device->id;
|
fsdev_fsdevice_cwd = device->id;
|
||||||
@ -1184,34 +1154,28 @@ fsdev_rename(struct _reent *r,
|
|||||||
{
|
{
|
||||||
Result rc;
|
Result rc;
|
||||||
FsDirEntryType type;
|
FsDirEntryType type;
|
||||||
fsdev_fsdevice *device_old = NULL, *device_new = NULL;
|
fsdev_fsdevice *device = r->deviceData;
|
||||||
char fs_path_old[FS_MAX_PATH];
|
char fs_path_old[FS_MAX_PATH];
|
||||||
char fs_path_new[FS_MAX_PATH];
|
char*fs_path_new = __nx_dev_path_buf;
|
||||||
|
|
||||||
if(fsdev_getfspath(r, oldName, &device_old, fs_path_old)==-1)
|
if(fsdev_getfspath(r, oldName, &device, fs_path_old)==-1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(fsdev_getfspath(r, newName, &device_new, fs_path_new)==-1)
|
if(fsdev_getfspath(r, newName, &device, fs_path_new)==-1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(device_old->id != device_new->id)
|
rc = fsFsGetEntryType(&device->fs, fs_path_old, &type);
|
||||||
{
|
|
||||||
r->_errno = EXDEV;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = fsFsGetEntryType(&device_old->fs, fs_path_old, &type);
|
|
||||||
if(R_SUCCEEDED(rc))
|
if(R_SUCCEEDED(rc))
|
||||||
{
|
{
|
||||||
if(type == FsDirEntryType_Dir)
|
if(type == FsDirEntryType_Dir)
|
||||||
{
|
{
|
||||||
rc = fsFsRenameDirectory(&device_old->fs, fs_path_old, fs_path_new);
|
rc = fsFsRenameDirectory(&device->fs, fs_path_old, fs_path_new);
|
||||||
if(R_SUCCEEDED(rc))
|
if(R_SUCCEEDED(rc))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if(type == FsDirEntryType_File)
|
else if(type == FsDirEntryType_File)
|
||||||
{
|
{
|
||||||
rc = fsFsRenameFile(&device_old->fs, fs_path_old, fs_path_new);
|
rc = fsFsRenameFile(&device->fs, fs_path_old, fs_path_new);
|
||||||
if(R_SUCCEEDED(rc))
|
if(R_SUCCEEDED(rc))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1241,8 +1205,8 @@ fsdev_mkdir(struct _reent *r,
|
|||||||
int mode)
|
int mode)
|
||||||
{
|
{
|
||||||
Result rc;
|
Result rc;
|
||||||
char fs_path[FS_MAX_PATH];
|
char *fs_path = __nx_dev_path_buf;
|
||||||
fsdev_fsdevice *device = NULL;
|
fsdev_fsdevice *device = r->deviceData;
|
||||||
|
|
||||||
if(fsdev_getfspath(r, path, &device, fs_path)==-1)
|
if(fsdev_getfspath(r, path, &device, fs_path)==-1)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1271,8 +1235,8 @@ fsdev_diropen(struct _reent *r,
|
|||||||
{
|
{
|
||||||
FsDir fd;
|
FsDir fd;
|
||||||
Result rc;
|
Result rc;
|
||||||
char fs_path[FS_MAX_PATH];
|
char *fs_path = __nx_dev_path_buf;
|
||||||
fsdev_fsdevice *device = NULL;
|
fsdev_fsdevice *device = r->deviceData;
|
||||||
|
|
||||||
if(fsdev_getfspath(r, path, &device, fs_path)==-1)
|
if(fsdev_getfspath(r, path, &device, fs_path)==-1)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1449,8 +1413,8 @@ fsdev_statvfs(struct _reent *r,
|
|||||||
struct statvfs *buf)
|
struct statvfs *buf)
|
||||||
{
|
{
|
||||||
Result rc=0;
|
Result rc=0;
|
||||||
char fs_path[FS_MAX_PATH];
|
char *fs_path = __nx_dev_path_buf;
|
||||||
fsdev_fsdevice *device = NULL;
|
fsdev_fsdevice *device = r->deviceData;
|
||||||
u64 freespace = 0, total_space = 0;
|
u64 freespace = 0, total_space = 0;
|
||||||
|
|
||||||
if(fsdev_getfspath(r, path, &device, fs_path)==-1)
|
if(fsdev_getfspath(r, path, &device, fs_path)==-1)
|
||||||
@ -1591,8 +1555,8 @@ fsdev_rmdir(struct _reent *r,
|
|||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
Result rc;
|
Result rc;
|
||||||
char fs_path[FS_MAX_PATH];
|
char *fs_path = __nx_dev_path_buf;
|
||||||
fsdev_fsdevice *device = NULL;
|
fsdev_fsdevice *device = r->deviceData;
|
||||||
|
|
||||||
if(fsdev_getfspath(r, name, &device, fs_path)==-1)
|
if(fsdev_getfspath(r, name, &device, fs_path)==-1)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -102,7 +102,7 @@ typedef struct
|
|||||||
u32 childFile;
|
u32 childFile;
|
||||||
} romfs_diriter;
|
} romfs_diriter;
|
||||||
|
|
||||||
static devoptab_t romFS_devoptab =
|
static const devoptab_t romFS_devoptab =
|
||||||
{
|
{
|
||||||
.structSize = sizeof(romfs_fileobj),
|
.structSize = sizeof(romfs_fileobj),
|
||||||
.open_r = romfs_open,
|
.open_r = romfs_open,
|
||||||
@ -201,101 +201,63 @@ static void romfs_mountclose(romfs_mount *mount)
|
|||||||
romfs_free(mount);
|
romfs_free(mount);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result romfsMount(const char *name)
|
Result romfsMountSelf(const char *name)
|
||||||
{
|
{
|
||||||
romfs_mount *mount = romfs_alloc();
|
// Check whether we are a NSO; if so then just mount the RomFS from the current process
|
||||||
if(mount == NULL)
|
if (envIsNso())
|
||||||
return 99;
|
return romfsMountFromCurrentProcess(name);
|
||||||
|
|
||||||
if (!envIsNso())
|
// Otherwise, we are a homebrew NRO and we need to use our embedded RomFS
|
||||||
{
|
// Retrieve the filename of our NRO
|
||||||
// RomFS embedded in a NRO
|
const char* filename = __romfs_path;
|
||||||
|
if (__system_argc > 0 && __system_argv[0])
|
||||||
|
filename = __system_argv[0];
|
||||||
|
if (!filename)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotFound);
|
||||||
|
|
||||||
mount->fd_type = RomfsSource_FsFile;
|
// Retrieve IFileSystem object + fixed path for our NRO
|
||||||
|
FsFileSystem *tmpfs = NULL;
|
||||||
|
char* path_buf = __nx_dev_path_buf;
|
||||||
|
if(fsdevTranslatePath(filename, &tmpfs, path_buf)==-1)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
|
||||||
FsFileSystem *sdfs = fsdevGetDefaultFileSystem();
|
// Open the NRO file
|
||||||
if(sdfs==NULL)
|
FsFile nro_file;
|
||||||
{
|
Result rc = fsFsOpenFile(tmpfs, path_buf, FsOpenMode_Read, &nro_file);
|
||||||
romfs_free(mount);
|
if (R_FAILED(rc))
|
||||||
return 1;
|
return rc;
|
||||||
}
|
|
||||||
|
|
||||||
const char* filename = __romfs_path;
|
// Read and parse the header
|
||||||
if (__system_argc > 0 && __system_argv[0])
|
NroHeader hdr;
|
||||||
filename = __system_argv[0];
|
u64 readbytes = 0;
|
||||||
if (!filename)
|
rc = fsFileRead(&nro_file, sizeof(NroStart), &hdr, sizeof(hdr), FsReadOption_None, &readbytes);
|
||||||
{
|
if (R_FAILED(rc) || readbytes != sizeof(hdr)) goto _fail_io;
|
||||||
romfs_free(mount);
|
if (hdr.magic != NROHEADER_MAGIC) goto _fail_io;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp(filename, "sdmc:/", 6) == 0)
|
// Read and parse the asset header
|
||||||
filename += 5;
|
NroAssetHeader asset_header;
|
||||||
else if (strncmp(filename, "nxlink:/", 8) == 0)
|
rc = fsFileRead(&nro_file, hdr.size, &asset_header, sizeof(asset_header), FsReadOption_None, &readbytes);
|
||||||
{
|
if (R_FAILED(rc) || readbytes != sizeof(asset_header)) goto _fail_io;
|
||||||
strncpy(__nx_dev_path_buf, "/switch", PATH_MAX);
|
if (asset_header.magic != NROASSETHEADER_MAGIC
|
||||||
strncat(__nx_dev_path_buf, filename+7, PATH_MAX);
|
|| asset_header.version > NROASSETHEADER_VERSION
|
||||||
__nx_dev_path_buf[PATH_MAX] = 0;
|
|| asset_header.romfs.offset == 0
|
||||||
filename = __nx_dev_path_buf;
|
|| asset_header.romfs.size == 0)
|
||||||
}
|
goto _fail_io;
|
||||||
else
|
|
||||||
{
|
|
||||||
romfs_free(mount);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result rc = fsFsOpenFile(sdfs, filename, FsOpenMode_Read, &mount->fd);
|
// Calculate the start offset of the embedded RomFS and mount it
|
||||||
if (R_FAILED(rc))
|
u64 romfs_offset = hdr.size + asset_header.romfs.offset;
|
||||||
{
|
return romfsMountFromFile(nro_file, romfs_offset, name);
|
||||||
romfs_free(mount);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
romfsInitMtime(mount);
|
_fail_io:
|
||||||
|
fsFileClose(&nro_file);
|
||||||
NroHeader hdr;
|
return MAKERESULT(Module_Libnx, LibnxError_IoError);
|
||||||
NroAssetHeader asset_header;
|
|
||||||
|
|
||||||
if (!_romfs_read_chk(mount, sizeof(NroStart), &hdr, sizeof(hdr))) goto _fail0;
|
|
||||||
if (hdr.magic != NROHEADER_MAGIC) goto _fail0;
|
|
||||||
if (!_romfs_read_chk(mount, hdr.size, &asset_header, sizeof(asset_header))) goto _fail0;
|
|
||||||
|
|
||||||
if (asset_header.magic != NROASSETHEADER_MAGIC
|
|
||||||
|| asset_header.version > NROASSETHEADER_VERSION
|
|
||||||
|| asset_header.romfs.offset == 0
|
|
||||||
|| asset_header.romfs.size == 0)
|
|
||||||
goto _fail0;
|
|
||||||
|
|
||||||
mount->offset = hdr.size + asset_header.romfs.offset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Regular RomFS
|
|
||||||
|
|
||||||
mount->fd_type = RomfsSource_FsStorage;
|
|
||||||
|
|
||||||
Result rc = fsOpenDataStorageByCurrentProcess(&mount->fd_storage);
|
|
||||||
if (R_FAILED(rc))
|
|
||||||
{
|
|
||||||
romfs_free(mount);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
romfsInitMtime(mount);
|
|
||||||
}
|
|
||||||
|
|
||||||
return romfsMountCommon(name, mount);
|
|
||||||
|
|
||||||
_fail0:
|
|
||||||
romfs_mountclose(mount);
|
|
||||||
return 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result romfsMountFromFile(FsFile file, u64 offset, const char *name)
|
Result romfsMountFromFile(FsFile file, u64 offset, const char *name)
|
||||||
{
|
{
|
||||||
romfs_mount *mount = romfs_alloc();
|
romfs_mount *mount = romfs_alloc();
|
||||||
if(mount == NULL)
|
if(mount == NULL)
|
||||||
return 99;
|
return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
|
||||||
|
|
||||||
mount->fd_type = RomfsSource_FsFile;
|
mount->fd_type = RomfsSource_FsFile;
|
||||||
mount->fd = file;
|
mount->fd = file;
|
||||||
@ -308,7 +270,7 @@ Result romfsMountFromStorage(FsStorage storage, u64 offset, const char *name)
|
|||||||
{
|
{
|
||||||
romfs_mount *mount = romfs_alloc();
|
romfs_mount *mount = romfs_alloc();
|
||||||
if(mount == NULL)
|
if(mount == NULL)
|
||||||
return 99;
|
return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
|
||||||
|
|
||||||
mount->fd_type = RomfsSource_FsStorage;
|
mount->fd_type = RomfsSource_FsStorage;
|
||||||
mount->fd_storage = storage;
|
mount->fd_storage = storage;
|
||||||
@ -330,21 +292,17 @@ Result romfsMountFromCurrentProcess(const char *name) {
|
|||||||
Result romfsMountFromFsdev(const char *path, u64 offset, const char *name)
|
Result romfsMountFromFsdev(const char *path, u64 offset, const char *name)
|
||||||
{
|
{
|
||||||
FsFileSystem *tmpfs = NULL;
|
FsFileSystem *tmpfs = NULL;
|
||||||
char filepath[FS_MAX_PATH];
|
if(fsdevTranslatePath(path, &tmpfs, __nx_dev_path_buf)==-1)
|
||||||
|
|
||||||
memset(filepath, 0, sizeof(filepath));
|
|
||||||
|
|
||||||
if(fsdevTranslatePath(path, &tmpfs, filepath)==-1)
|
|
||||||
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
|
||||||
romfs_mount *mount = romfs_alloc();
|
romfs_mount *mount = romfs_alloc();
|
||||||
if(mount == NULL)
|
if(mount == NULL)
|
||||||
return 99;
|
return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
|
||||||
|
|
||||||
mount->fd_type = RomfsSource_FsFile;
|
mount->fd_type = RomfsSource_FsFile;
|
||||||
mount->offset = offset;
|
mount->offset = offset;
|
||||||
|
|
||||||
Result rc = fsFsOpenFile(tmpfs, filepath, FsOpenMode_Read, &mount->fd);
|
Result rc = fsFsOpenFile(tmpfs, __nx_dev_path_buf, FsOpenMode_Read, &mount->fd);
|
||||||
if (R_FAILED(rc))
|
if (R_FAILED(rc))
|
||||||
{
|
{
|
||||||
romfs_free(mount);
|
romfs_free(mount);
|
||||||
@ -369,45 +327,50 @@ Result romfsMountCommon(const char *name, romfs_mount *mount)
|
|||||||
memset(mount->name, 0, sizeof(mount->name));
|
memset(mount->name, 0, sizeof(mount->name));
|
||||||
strncpy(mount->name, name, sizeof(mount->name)-1);
|
strncpy(mount->name, name, sizeof(mount->name)-1);
|
||||||
|
|
||||||
|
romfsInitMtime(mount);
|
||||||
|
|
||||||
if (_romfs_read(mount, 0, &mount->header, sizeof(mount->header)) != sizeof(mount->header))
|
if (_romfs_read(mount, 0, &mount->header, sizeof(mount->header)) != sizeof(mount->header))
|
||||||
goto fail;
|
goto fail_io;
|
||||||
|
|
||||||
mount->dirHashTable = (u32*)malloc(mount->header.dirHashTableSize);
|
mount->dirHashTable = (u32*)malloc(mount->header.dirHashTableSize);
|
||||||
if (!mount->dirHashTable)
|
if (!mount->dirHashTable)
|
||||||
goto fail;
|
goto fail_oom;
|
||||||
if (!_romfs_read_chk(mount, mount->header.dirHashTableOff, mount->dirHashTable, mount->header.dirHashTableSize))
|
if (!_romfs_read_chk(mount, mount->header.dirHashTableOff, mount->dirHashTable, mount->header.dirHashTableSize))
|
||||||
goto fail;
|
goto fail_io;
|
||||||
|
|
||||||
mount->dirTable = malloc(mount->header.dirTableSize);
|
mount->dirTable = malloc(mount->header.dirTableSize);
|
||||||
if (!mount->dirTable)
|
if (!mount->dirTable)
|
||||||
goto fail;
|
goto fail_oom;
|
||||||
if (!_romfs_read_chk(mount, mount->header.dirTableOff, mount->dirTable, mount->header.dirTableSize))
|
if (!_romfs_read_chk(mount, mount->header.dirTableOff, mount->dirTable, mount->header.dirTableSize))
|
||||||
goto fail;
|
goto fail_io;
|
||||||
|
|
||||||
mount->fileHashTable = (u32*)malloc(mount->header.fileHashTableSize);
|
mount->fileHashTable = (u32*)malloc(mount->header.fileHashTableSize);
|
||||||
if (!mount->fileHashTable)
|
if (!mount->fileHashTable)
|
||||||
goto fail;
|
goto fail_oom;
|
||||||
if (!_romfs_read_chk(mount, mount->header.fileHashTableOff, mount->fileHashTable, mount->header.fileHashTableSize))
|
if (!_romfs_read_chk(mount, mount->header.fileHashTableOff, mount->fileHashTable, mount->header.fileHashTableSize))
|
||||||
goto fail;
|
goto fail_io;
|
||||||
|
|
||||||
mount->fileTable = malloc(mount->header.fileTableSize);
|
mount->fileTable = malloc(mount->header.fileTableSize);
|
||||||
if (!mount->fileTable)
|
if (!mount->fileTable)
|
||||||
goto fail;
|
goto fail_oom;
|
||||||
if (!_romfs_read_chk(mount, mount->header.fileTableOff, mount->fileTable, mount->header.fileTableSize))
|
if (!_romfs_read_chk(mount, mount->header.fileTableOff, mount->fileTable, mount->header.fileTableSize))
|
||||||
goto fail;
|
goto fail_io;
|
||||||
|
|
||||||
mount->cwd = romFS_root(mount);
|
mount->cwd = romFS_root(mount);
|
||||||
|
|
||||||
// add device if this is the first one
|
|
||||||
if(AddDevice(&mount->device) < 0)
|
if(AddDevice(&mount->device) < 0)
|
||||||
goto fail;
|
goto fail_oom;
|
||||||
|
|
||||||
mount->setup = true;
|
mount->setup = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail_oom:
|
||||||
romfs_mountclose(mount);
|
romfs_mountclose(mount);
|
||||||
return 10;
|
return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
|
||||||
|
|
||||||
|
fail_io:
|
||||||
|
romfs_mountclose(mount);
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_IoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void romfsInitMtime(romfs_mount *mount)
|
static void romfsInitMtime(romfs_mount *mount)
|
||||||
@ -422,7 +385,7 @@ Result romfsUnmount(const char *name)
|
|||||||
|
|
||||||
mount = romfsFindMount(name);
|
mount = romfsFindMount(name);
|
||||||
if (mount == NULL)
|
if (mount == NULL)
|
||||||
return -1;
|
return MAKERESULT(Module_Libnx, LibnxError_NotFound);
|
||||||
|
|
||||||
// Remove device
|
// Remove device
|
||||||
memset(tmpname, 0, sizeof(tmpname));
|
memset(tmpname, 0, sizeof(tmpname));
|
||||||
|
@ -17,6 +17,7 @@ void virtmemSetup(void);
|
|||||||
void newlibSetup(void);
|
void newlibSetup(void);
|
||||||
void argvSetup(void);
|
void argvSetup(void);
|
||||||
void __libnx_init_time(void);
|
void __libnx_init_time(void);
|
||||||
|
void __libnx_init_cwd(void);
|
||||||
|
|
||||||
extern u32 __nx_applet_type;
|
extern u32 __nx_applet_type;
|
||||||
|
|
||||||
@ -141,6 +142,7 @@ void __attribute__((weak)) __appInit(void)
|
|||||||
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS));
|
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS));
|
||||||
|
|
||||||
fsdevMountSdmc();
|
fsdevMountSdmc();
|
||||||
|
__libnx_init_cwd();
|
||||||
|
|
||||||
if (&__nx_win_init) __nx_win_init();
|
if (&__nx_win_init) __nx_win_init();
|
||||||
if (&userAppInit) userAppInit();
|
if (&userAppInit) userAppInit();
|
||||||
|
Loading…
Reference in New Issue
Block a user