Safe strings for FS ipc

This commit is contained in:
plutooo 2020-03-07 16:55:22 -08:00
parent c3b0b63471
commit ec85a2fa5c
9 changed files with 160 additions and 132 deletions

View File

@ -52,7 +52,7 @@ Result fsdevCommitDevice(const char *name);
FsFileSystem* fsdevGetDeviceFileSystem(const char *name); FsFileSystem* fsdevGetDeviceFileSystem(const char *name);
/// 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, FsPath* outpath);
/// This calls fsFsSetConcatenationFileAttribute on the filesystem specified by the input path (as used in stdio). /// This calls fsFsSetConcatenationFileAttribute on the filesystem specified by the input path (as used in stdio).
Result fsdevSetConcatenationFileAttribute(const char *path); Result fsdevSetConcatenationFileAttribute(const char *path);

View File

@ -13,13 +13,49 @@
#include "../services/acc.h" #include "../services/acc.h"
#include "../sf/service.h" #include "../sf/service.h"
// We use wrapped handles for type safety.
#define FS_MAX_PATH 0x301 #define FS_MAX_PATH 0x301
/// For use with \ref FsSaveDataAttribute. /// For use with \ref FsSaveDataAttribute.
#define FS_SAVEDATA_CURRENT_APPLICATIONID 0 #define FS_SAVEDATA_CURRENT_APPLICATIONID 0
typedef struct {
char path[FS_MAX_PATH];
} FsPath;
/**
* @brief For file paths, a statically sized buffer of 0x301 bytes is sent over
* IPC. For string literals, less than 0x301 bytes are allocated. When
* the linker/compiler allocates a string literal next to an unmapped
* 4K page this causes correct code to fail. To get around this, all
* literal paths (and otherwise) have to be padded in order to be safely
* transferred.
* @param literal String to convert
* @return Path object
*/
static inline FsPath fsPathFromLiteralSafe(const char* literal) {
FsPath ret;
size_t i = 0;
while (1)
{
ret.path[i] = literal[i];
if (literal[i] == 0)
break;
if (i == FS_MAX_PATH-1) {
ret.path[i] = 0;
break;
}
i++;
}
return ret;
}
// We use wrapped handles for type safety.
typedef struct { typedef struct {
u8 c[0x10]; u8 c[0x10];
} FsRightsId; } FsRightsId;
@ -54,7 +90,7 @@ typedef struct {
/// Directory entry. /// Directory entry.
typedef struct { typedef struct {
char name[FS_MAX_PATH]; ///< Entry name. FsPath name; ///< Entry name.
u8 pad[3]; u8 pad[3];
s8 type; ///< See FsDirEntryType. s8 type; ///< See FsDirEntryType.
u8 pad2[3]; ///< ? u8 pad2[3]; ///< ?
@ -307,11 +343,11 @@ Service* fsGetServiceSession(void);
void fsSetPriority(FsPriority prio); void fsSetPriority(FsPriority prio);
/// Mount requested filesystem type from content file /// Mount requested filesystem type from content file
Result fsOpenFileSystem(FsFileSystem* out, FsFileSystemType fsType, const char* contentPath); ///< same as calling fsOpenFileSystemWithId with 0 as id Result fsOpenFileSystem(FsFileSystem* out, FsFileSystemType fsType, FsPath* contentPath); ///< same as calling fsOpenFileSystemWithId with 0 as id
Result fsOpenFileSystemWithPatch(FsFileSystem* out, u64 id, FsFileSystemType fsType); ///< [2.0.0+], like OpenFileSystemWithId but without content path. Result fsOpenFileSystemWithPatch(FsFileSystem* out, u64 id, FsFileSystemType fsType); ///< [2.0.0+], like OpenFileSystemWithId but without content path.
Result fsOpenFileSystemWithId(FsFileSystem* out, u64 id, FsFileSystemType fsType, const char* contentPath); ///< works on all firmwares, id is ignored on [1.0.0] Result fsOpenFileSystemWithId(FsFileSystem* out, u64 id, FsFileSystemType fsType, FsPath* contentPath); ///< works on all firmwares, id is ignored on [1.0.0]
Result fsOpenBisFileSystem(FsFileSystem* out, FsBisPartitionId partitionId, const char* string); Result fsOpenBisFileSystem(FsFileSystem* out, FsBisPartitionId partitionId, FsPath* string);
Result fsOpenBisStorage(FsStorage* out, FsBisPartitionId partitionId); Result fsOpenBisStorage(FsStorage* out, FsBisPartitionId partitionId);
/// Do not call this directly, see fs_dev.h. /// Do not call this directly, see fs_dev.h.
@ -348,10 +384,10 @@ Result fsOpenSdCardDetectionEventNotifier(FsEventNotifier* out);
Result fsIsSignedSystemPartitionOnSdCardValid(bool *out); Result fsIsSignedSystemPartitionOnSdCardValid(bool *out);
/// Retrieves the rights id corresponding to the content path. Only available on [2.0.0+]. /// Retrieves the rights id corresponding to the content path. Only available on [2.0.0+].
Result fsGetRightsIdByPath(const char* path, FsRightsId* out_rights_id); Result fsGetRightsIdByPath(FsPath* path, FsRightsId* out_rights_id);
/// Retrieves the rights id and key generation corresponding to the content path. Only available on [3.0.0+]. /// Retrieves the rights id and key generation corresponding to the content path. Only available on [3.0.0+].
Result fsGetRightsIdAndKeyGenerationByPath(const char* path, u8* out_key_generation, FsRightsId* out_rights_id); Result fsGetRightsIdAndKeyGenerationByPath(FsPath* path, u8* out_key_generation, FsRightsId* out_rights_id);
Result fsDisableAutoSaveDataCreation(void); Result fsDisableAutoSaveDataCreation(void);
@ -371,27 +407,27 @@ Result fsOpen_SaveData(FsFileSystem* out, u64 application_id, AccountUid uid);
Result fsOpen_SystemSaveData(FsFileSystem* out, FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, AccountUid uid); Result fsOpen_SystemSaveData(FsFileSystem* out, FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, AccountUid uid);
// IFileSystem // IFileSystem
Result fsFsCreateFile(FsFileSystem* fs, const char* path, s64 size, u32 option); Result fsFsCreateFile(FsFileSystem* fs, FsPath* path, s64 size, u32 option);
Result fsFsDeleteFile(FsFileSystem* fs, const char* path); Result fsFsDeleteFile(FsFileSystem* fs, FsPath* path);
Result fsFsCreateDirectory(FsFileSystem* fs, const char* path); Result fsFsCreateDirectory(FsFileSystem* fs, FsPath* path);
Result fsFsDeleteDirectory(FsFileSystem* fs, const char* path); Result fsFsDeleteDirectory(FsFileSystem* fs, FsPath* path);
Result fsFsDeleteDirectoryRecursively(FsFileSystem* fs, const char* path); Result fsFsDeleteDirectoryRecursively(FsFileSystem* fs, FsPath* path);
Result fsFsRenameFile(FsFileSystem* fs, const char* cur_path, const char* new_path); Result fsFsRenameFile(FsFileSystem* fs, FsPath* cur_path, FsPath* new_path);
Result fsFsRenameDirectory(FsFileSystem* fs, const char* cur_path, const char* new_path); Result fsFsRenameDirectory(FsFileSystem* fs, FsPath* cur_path, FsPath* new_path);
Result fsFsGetEntryType(FsFileSystem* fs, const char* path, FsDirEntryType* out); Result fsFsGetEntryType(FsFileSystem* fs, FsPath* path, FsDirEntryType* out);
Result fsFsOpenFile(FsFileSystem* fs, const char* path, u32 mode, FsFile* out); Result fsFsOpenFile(FsFileSystem* fs, FsPath* path, u32 mode, FsFile* out);
Result fsFsOpenDirectory(FsFileSystem* fs, const char* path, u32 mode, FsDir* out); Result fsFsOpenDirectory(FsFileSystem* fs, FsPath* path, u32 mode, FsDir* out);
Result fsFsCommit(FsFileSystem* fs); Result fsFsCommit(FsFileSystem* fs);
Result fsFsGetFreeSpace(FsFileSystem* fs, const char* path, s64* out); Result fsFsGetFreeSpace(FsFileSystem* fs, FsPath* path, s64* out);
Result fsFsGetTotalSpace(FsFileSystem* fs, const char* path, s64* out); Result fsFsGetTotalSpace(FsFileSystem* fs, FsPath* path, s64* out);
Result fsFsGetFileTimeStampRaw(FsFileSystem* fs, const char* path, FsTimeStampRaw *out); ///< [3.0.0+] Result fsFsGetFileTimeStampRaw(FsFileSystem* fs, FsPath* path, FsTimeStampRaw *out); ///< [3.0.0+]
Result fsFsCleanDirectoryRecursively(FsFileSystem* fs, const char* path); ///< [3.0.0+] Result fsFsCleanDirectoryRecursively(FsFileSystem* fs, FsPath* path); ///< [3.0.0+]
Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void *in, size_t in_size, const char* path, FsFileSystemQueryId query_id); ///< [4.0.0+] Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void *in, size_t in_size, FsPath* path, FsFileSystemQueryId query_id); ///< [4.0.0+]
void fsFsClose(FsFileSystem* fs); void fsFsClose(FsFileSystem* fs);
/// Uses \ref fsFsQueryEntry to set the archive bit on the specified absolute directory path. /// Uses \ref fsFsQueryEntry to set the archive bit on the specified absolute directory path.
/// This will cause HOS to treat the directory as if it were a file containing the directory's concatenated contents. /// This will cause HOS to treat the directory as if it were a file containing the directory's concatenated contents.
Result fsFsSetConcatenationFileAttribute(FsFileSystem* fs, const char *path); Result fsFsSetConcatenationFileAttribute(FsFileSystem* fs, FsPath* path);
/// Wrapper for fsFsQueryEntry with FsFileSystemQueryId_IsValidSignedSystemPartitionOnSdCard. /// Wrapper for fsFsQueryEntry with FsFileSystemQueryId_IsValidSignedSystemPartitionOnSdCard.
/// Only available on [8.0.0+]. /// Only available on [8.0.0+].

View File

@ -18,5 +18,5 @@ void fsldrExit(void);
/// Gets the Service object for the actual fsp-ldr service session. /// Gets the Service object for the actual fsp-ldr service session.
Service* fsldrGetServiceSession(void); Service* fsldrGetServiceSession(void);
Result fsldrOpenCodeFileSystem(u64 tid, const char *path, FsFileSystem* out); Result fsldrOpenCodeFileSystem(u64 tid, FsPath* path, FsFileSystem* out);
Result fsldrIsArchivedProgram(u64 pid, bool *out); Result fsldrIsArchivedProgram(u64 pid, bool *out);

View File

@ -205,18 +205,18 @@ fsdev_fixpath(struct _reent *r,
} }
if(path[0] == '/') if(path[0] == '/')
strncpy(__nx_dev_path_buf, path, PATH_MAX); strncpy(__nx_dev_path_buf.unix_path, path, PATH_MAX);
else else
{ {
const char* cwd = dev->cwd ? dev->cwd : "/"; const char* cwd = dev->cwd ? dev->cwd : "/";
strncpy(__nx_dev_path_buf, cwd, PATH_MAX); strncpy(__nx_dev_path_buf.unix_path, cwd, PATH_MAX);
__nx_dev_path_buf[PATH_MAX] = '\0'; __nx_dev_path_buf.unix_path[PATH_MAX] = '\0';
strncat(__nx_dev_path_buf, path, PATH_MAX - strlen(cwd)); strncat(__nx_dev_path_buf.unix_path, path, PATH_MAX - strlen(cwd));
} }
if(__nx_dev_path_buf[PATH_MAX] != 0) if(__nx_dev_path_buf.unix_path[PATH_MAX] != 0)
{ {
__nx_dev_path_buf[PATH_MAX] = 0; __nx_dev_path_buf.unix_path[PATH_MAX] = 0;
r->_errno = ENAMETOOLONG; r->_errno = ENAMETOOLONG;
return NULL; return NULL;
} }
@ -224,29 +224,30 @@ fsdev_fixpath(struct _reent *r,
if(device) if(device)
*device = dev; *device = dev;
return __nx_dev_path_buf; return __nx_dev_path_buf.unix_path;
} }
static int static int
fsdev_getfspath(struct _reent *r, fsdev_getfspath(struct _reent *r,
const char *path, const char *path,
fsdev_fsdevice **device, fsdev_fsdevice **device,
char *outpath) FsPath *outpath)
{ {
if(fsdev_fixpath(r, path, device) == NULL) if(fsdev_fixpath(r, path, device) == NULL)
return -1; return -1;
if(outpath != __nx_dev_path_buf) if(outpath != &__nx_dev_path_buf.nx_path)
memcpy(outpath, __nx_dev_path_buf, FS_MAX_PATH-1); memcpy(outpath, &__nx_dev_path_buf.nx_path, FS_MAX_PATH-1);
outpath[FS_MAX_PATH-1] = '\0';
outpath->path[FS_MAX_PATH-1] = '\0';
return 0; return 0;
} }
static ssize_t fsdev_convertfromfspath(uint8_t *out, uint8_t *in, size_t len) static ssize_t fsdev_convertfromfspath(uint8_t *out, FsPath* in, size_t len)
{ {
ssize_t inlen = strnlen((char*)in, len); ssize_t inlen = strnlen((char*)in->path, len);
memcpy(out, in, inlen); memcpy(out, in->path, inlen);
if (inlen < len) if (inlen < len)
out[inlen+1] = 0; out[inlen+1] = 0;
return inlen; return inlen;
@ -398,7 +399,7 @@ Result fsdevCommitDevice(const char *name)
} }
Result fsdevSetConcatenationFileAttribute(const char *path) { Result fsdevSetConcatenationFileAttribute(const char *path) {
char *fs_path = __nx_dev_path_buf; FsPath *fs_path = &__nx_dev_path_buf.nx_path;
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)
@ -418,7 +419,7 @@ Result fsdevIsValidSignedSystemPartitionOnSdCard(const char *name, bool *out) {
} }
Result fsdevCreateFile(const char* path, size_t size, u32 flags) { Result fsdevCreateFile(const char* path, size_t size, u32 flags) {
char *fs_path = __nx_dev_path_buf; FsPath *fs_path = &__nx_dev_path_buf.nx_path;
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)
@ -428,7 +429,7 @@ Result fsdevCreateFile(const char* path, size_t size, u32 flags) {
} }
Result fsdevDeleteDirectoryRecursively(const char *path) { Result fsdevDeleteDirectoryRecursively(const char *path) {
char *fs_path = __nx_dev_path_buf; FsPath *fs_path = &__nx_dev_path_buf.nx_path;
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)
@ -539,7 +540,7 @@ FsFileSystem* fsdevGetDeviceFileSystem(const char *name)
return &device->fs; return &device->fs;
} }
int fsdevTranslatePath(const char *path, FsFileSystem** device, char *outpath) int fsdevTranslatePath(const char *path, FsFileSystem** device, FsPath* outpath)
{ {
fsdev_fsdevice *tmpdev = NULL; fsdev_fsdevice *tmpdev = NULL;
@ -572,7 +573,7 @@ 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 = __nx_dev_path_buf; FsPath *fs_path = &__nx_dev_path_buf.nx_path;
fsdev_fsdevice *device = r->deviceData; fsdev_fsdevice *device = r->deviceData;
if(fsdev_getfspath(r, path, &device, fs_path)==-1) if(fsdev_getfspath(r, path, &device, fs_path)==-1)
@ -1026,7 +1027,7 @@ fsdev_stat(struct _reent *r,
FsDir fdir; FsDir fdir;
Result rc; Result rc;
int ret=0; int ret=0;
char *fs_path = __nx_dev_path_buf; FsPath *fs_path = &__nx_dev_path_buf.nx_path;
fsdev_fsdevice *device = r->deviceData; fsdev_fsdevice *device = r->deviceData;
FsTimeStampRaw timestamps = {0}; FsTimeStampRaw timestamps = {0};
FsDirEntryType type; FsDirEntryType type;
@ -1112,7 +1113,7 @@ fsdev_unlink(struct _reent *r,
const char *name) const char *name)
{ {
Result rc; Result rc;
char *fs_path = __nx_dev_path_buf; FsPath *fs_path = &__nx_dev_path_buf.nx_path;
fsdev_fsdevice *device = r->deviceData; fsdev_fsdevice *device = r->deviceData;
if(fsdev_getfspath(r, name, &device, fs_path)==-1) if(fsdev_getfspath(r, name, &device, fs_path)==-1)
@ -1140,7 +1141,7 @@ fsdev_chdir(struct _reent *r,
{ {
FsDir fd; FsDir fd;
Result rc; Result rc;
char *fs_path = __nx_dev_path_buf; FsPath *fs_path = &__nx_dev_path_buf.nx_path;
fsdev_fsdevice *device = r->deviceData; fsdev_fsdevice *device = r->deviceData;
if(device->cwd==NULL) if(device->cwd==NULL)
@ -1158,7 +1159,7 @@ fsdev_chdir(struct _reent *r,
fsDirClose(&fd); fsDirClose(&fd);
memcpy(device->cwd, fs_path, FS_MAX_PATH); memcpy(device->cwd, fs_path, FS_MAX_PATH);
size_t cwdlen = strlen(fs_path); size_t cwdlen = strlen(fs_path->path);
if (device->cwd[cwdlen-1] != '/' && cwdlen < FS_MAX_PATH-1) if (device->cwd[cwdlen-1] != '/' && cwdlen < FS_MAX_PATH-1)
{ {
device->cwd[cwdlen] = '/'; device->cwd[cwdlen] = '/';
@ -1190,27 +1191,27 @@ fsdev_rename(struct _reent *r,
Result rc; Result rc;
FsDirEntryType type; FsDirEntryType type;
fsdev_fsdevice *device = r->deviceData; fsdev_fsdevice *device = r->deviceData;
char fs_path_old[FS_MAX_PATH]; FsPath fs_path_old;
char*fs_path_new = __nx_dev_path_buf; FsPath* fs_path_new = &__nx_dev_path_buf.nx_path;
if(fsdev_getfspath(r, oldName, &device, fs_path_old)==-1) if(fsdev_getfspath(r, oldName, &device, &fs_path_old)==-1)
return -1; return -1;
if(fsdev_getfspath(r, newName, &device, fs_path_new)==-1) if(fsdev_getfspath(r, newName, &device, fs_path_new)==-1)
return -1; return -1;
rc = fsFsGetEntryType(&device->fs, fs_path_old, &type); rc = fsFsGetEntryType(&device->fs, &fs_path_old, &type);
if(R_SUCCEEDED(rc)) if(R_SUCCEEDED(rc))
{ {
if(type == FsDirEntryType_Dir) if(type == FsDirEntryType_Dir)
{ {
rc = fsFsRenameDirectory(&device->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->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;
} }
@ -1240,7 +1241,7 @@ fsdev_mkdir(struct _reent *r,
int mode) int mode)
{ {
Result rc; Result rc;
char *fs_path = __nx_dev_path_buf; FsPath *fs_path = &__nx_dev_path_buf.nx_path;
fsdev_fsdevice *device = r->deviceData; fsdev_fsdevice *device = r->deviceData;
if(fsdev_getfspath(r, path, &device, fs_path)==-1) if(fsdev_getfspath(r, path, &device, fs_path)==-1)
@ -1270,7 +1271,7 @@ fsdev_diropen(struct _reent *r,
{ {
FsDir fd; FsDir fd;
Result rc; Result rc;
char *fs_path = __nx_dev_path_buf; FsPath *fs_path = &__nx_dev_path_buf.nx_path;
fsdev_fsdevice *device = r->deviceData; fsdev_fsdevice *device = r->deviceData;
if(fsdev_getfspath(r, path, &device, fs_path)==-1) if(fsdev_getfspath(r, path, &device, fs_path)==-1)
@ -1387,7 +1388,7 @@ fsdev_dirnext(struct _reent *r,
/* convert name from fs-path to UTF-8 */ /* convert name from fs-path to UTF-8 */
memset(filename, 0, NAME_MAX); memset(filename, 0, NAME_MAX);
units = fsdev_convertfromfspath((uint8_t*)filename, (uint8_t*)entry->name, NAME_MAX); units = fsdev_convertfromfspath((uint8_t*)filename, &entry->name, NAME_MAX);
if(units < 0) if(units < 0)
{ {
r->_errno = EILSEQ; r->_errno = EILSEQ;
@ -1448,7 +1449,7 @@ fsdev_statvfs(struct _reent *r,
struct statvfs *buf) struct statvfs *buf)
{ {
Result rc=0; Result rc=0;
char *fs_path = __nx_dev_path_buf; FsPath *fs_path = &__nx_dev_path_buf.nx_path;
fsdev_fsdevice *device = r->deviceData; fsdev_fsdevice *device = r->deviceData;
s64 freespace = 0, total_space = 0; s64 freespace = 0, total_space = 0;
@ -1590,7 +1591,7 @@ fsdev_rmdir(struct _reent *r,
const char *name) const char *name)
{ {
Result rc; Result rc;
char *fs_path = __nx_dev_path_buf; FsPath *fs_path = &__nx_dev_path_buf.nx_path;
fsdev_fsdevice *device = r->deviceData; fsdev_fsdevice *device = r->deviceData;
if(fsdev_getfspath(r, name, &device, fs_path)==-1) if(fsdev_getfspath(r, name, &device, fs_path)==-1)

View File

@ -1,3 +1,3 @@
#include "path_buf.h" #include "path_buf.h"
char __thread __nx_dev_path_buf[PATH_MAX+1]; PathBuf __thread __nx_dev_path_buf;

View File

@ -1,4 +1,11 @@
#pragma once #pragma once
#include <limits.h> #include <limits.h>
extern char __thread __nx_dev_path_buf[PATH_MAX+1]; #include "services/fs.h"
typedef union {
char unix_path[PATH_MAX+1];
FsPath nx_path;
} PathBuf;
extern __thread PathBuf __nx_dev_path_buf;

View File

@ -268,7 +268,7 @@ Result romfsMountSelf(const char *name)
// Retrieve IFileSystem object + fixed path for our NRO // Retrieve IFileSystem object + fixed path for our NRO
FsFileSystem *tmpfs = NULL; FsFileSystem *tmpfs = NULL;
char* path_buf = __nx_dev_path_buf; FsPath* path_buf = &__nx_dev_path_buf.nx_path;
if(fsdevTranslatePath(filename, &tmpfs, path_buf)==-1) if(fsdevTranslatePath(filename, &tmpfs, path_buf)==-1)
return MAKERESULT(Module_Libnx, LibnxError_BadInput); return MAKERESULT(Module_Libnx, LibnxError_BadInput);
@ -343,7 +343,7 @@ 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;
if(fsdevTranslatePath(path, &tmpfs, __nx_dev_path_buf)==-1) if(fsdevTranslatePath(path, &tmpfs, &__nx_dev_path_buf.nx_path)==-1)
return MAKERESULT(Module_Libnx, LibnxError_BadInput); return MAKERESULT(Module_Libnx, LibnxError_BadInput);
romfs_mount *mount = romfs_alloc(); romfs_mount *mount = romfs_alloc();
@ -353,7 +353,7 @@ Result romfsMountFromFsdev(const char *path, u64 offset, const char *name)
mount->fd_type = RomfsSource_FsFile; mount->fd_type = RomfsSource_FsFile;
mount->offset = offset; mount->offset = offset;
Result rc = fsFsOpenFile(tmpfs, __nx_dev_path_buf, FsOpenMode_Read, &mount->fd); Result rc = fsFsOpenFile(tmpfs, &__nx_dev_path_buf.nx_path, FsOpenMode_Read, &mount->fd);
if (R_FAILED(rc)) if (R_FAILED(rc))
{ {
romfs_free(mount); romfs_free(mount);
@ -521,7 +521,7 @@ static int navigateToDir(romfs_mount *mount, romfs_dir** ppDir, const char** pPa
while (**pPath) while (**pPath)
{ {
char* slashPos = strchr(*pPath, '/'); char* slashPos = strchr(*pPath, '/');
char* component = __nx_dev_path_buf; char* component = __nx_dev_path_buf.unix_path;
if (slashPos) if (slashPos)
{ {

View File

@ -132,15 +132,15 @@ static Result _fsCmdNoInOutBool(Service* srv, bool *out, u32 cmd_id) {
// IFileSystemProxy // IFileSystemProxy
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
Result fsOpenFileSystem(FsFileSystem* out, FsFileSystemType fsType, const char* contentPath) { Result fsOpenFileSystem(FsFileSystem* out, FsFileSystemType fsType, FsPath* contentPath) {
return fsOpenFileSystemWithId(out, 0, fsType, contentPath); return fsOpenFileSystemWithId(out, 0, fsType, contentPath);
} }
static Result _fsOpenFileSystem(FsFileSystem* out, FsFileSystemType fsType, const char* contentPath) { static Result _fsOpenFileSystem(FsFileSystem* out, FsFileSystemType fsType, FsPath* contentPath) {
u32 tmp=fsType; u32 tmp=fsType;
return _fsObjectDispatchIn(&g_fsSrv, 0, tmp, return _fsObjectDispatchIn(&g_fsSrv, 0, tmp,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
.buffers = { { contentPath, FS_MAX_PATH } }, .buffers = { { contentPath, sizeof(*contentPath) } },
.out_num_objects = 1, .out_num_objects = 1,
.out_objects = &out->s, .out_objects = &out->s,
); );
@ -161,7 +161,7 @@ Result fsOpenFileSystemWithPatch(FsFileSystem* out, u64 id, FsFileSystemType fsT
); );
} }
static Result _fsOpenFileSystemWithId(FsFileSystem* out, u64 id, FsFileSystemType fsType, const char* contentPath) { static Result _fsOpenFileSystemWithId(FsFileSystem* out, u64 id, FsFileSystemType fsType, FsPath* contentPath) {
const struct { const struct {
u32 fsType; u32 fsType;
u64 id; u64 id;
@ -169,30 +169,24 @@ static Result _fsOpenFileSystemWithId(FsFileSystem* out, u64 id, FsFileSystemTyp
return _fsObjectDispatchIn(&g_fsSrv, 8, in, return _fsObjectDispatchIn(&g_fsSrv, 8, in,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
.buffers = { { contentPath, FS_MAX_PATH } }, .buffers = { { contentPath, sizeof(*contentPath) } },
.out_num_objects = 1, .out_num_objects = 1,
.out_objects = &out->s, .out_objects = &out->s,
); );
} }
Result fsOpenFileSystemWithId(FsFileSystem* out, u64 id, FsFileSystemType fsType, const char* contentPath) { Result fsOpenFileSystemWithId(FsFileSystem* out, u64 id, FsFileSystemType fsType, FsPath* contentPath) {
char sendStr[FS_MAX_PATH] = {0};
strncpy(sendStr, contentPath, sizeof(sendStr)-1);
if (hosversionAtLeast(2,0,0)) if (hosversionAtLeast(2,0,0))
return _fsOpenFileSystemWithId(out, id, fsType, sendStr); return _fsOpenFileSystemWithId(out, id, fsType, contentPath);
else else
return _fsOpenFileSystem(out, fsType, sendStr); return _fsOpenFileSystem(out, fsType, contentPath);
} }
Result fsOpenBisFileSystem(FsFileSystem* out, FsBisPartitionId partitionId, const char* string) { Result fsOpenBisFileSystem(FsFileSystem* out, FsBisPartitionId partitionId, FsPath* path) {
char tmpstr[FS_MAX_PATH] = {0};
strncpy(tmpstr, string, sizeof(tmpstr)-1);
u32 tmp=partitionId; u32 tmp=partitionId;
return _fsObjectDispatchIn(&g_fsSrv, 11, tmp, return _fsObjectDispatchIn(&g_fsSrv, 11, tmp,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
.buffers = { { tmpstr, sizeof(tmpstr) } }, .buffers = { { path, sizeof(*path) } },
.out_num_objects = 1, .out_num_objects = 1,
.out_objects = &out->s, .out_objects = &out->s,
); );
@ -409,26 +403,20 @@ Result fsIsSignedSystemPartitionOnSdCardValid(bool *out) {
return _fsCmdNoInOutBool(&g_fsSrv, out, 640); return _fsCmdNoInOutBool(&g_fsSrv, out, 640);
} }
Result fsGetRightsIdByPath(const char* path, FsRightsId* out_rights_id) { Result fsGetRightsIdByPath(FsPath* path, FsRightsId* out_rights_id) {
if (hosversionBefore(2,0,0)) if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
char send_path[FS_MAX_PATH] = {0};
strncpy(send_path, path, FS_MAX_PATH-1);
return _fsObjectDispatchOut(&g_fsSrv, 609, *out_rights_id, return _fsObjectDispatchOut(&g_fsSrv, 609, *out_rights_id,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
.buffers = { { send_path, sizeof(send_path) } }, .buffers = { { path, sizeof(*path) } },
); );
} }
Result fsGetRightsIdAndKeyGenerationByPath(const char* path, u8* out_key_generation, FsRightsId* out_rights_id) { Result fsGetRightsIdAndKeyGenerationByPath(FsPath* path, u8* out_key_generation, FsRightsId* out_rights_id) {
if (hosversionBefore(3,0,0)) if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
char send_path[FS_MAX_PATH] = {0};
strncpy(send_path, path, FS_MAX_PATH-1);
struct { struct {
u8 key_generation; u8 key_generation;
u8 padding[0x7]; u8 padding[0x7];
@ -437,7 +425,7 @@ Result fsGetRightsIdAndKeyGenerationByPath(const char* path, u8* out_key_generat
Result rc = _fsObjectDispatchOut(&g_fsSrv, 610, out, Result rc = _fsObjectDispatchOut(&g_fsSrv, 610, out,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
.buffers = { { send_path, sizeof(send_path) } }, .buffers = { { path, sizeof(*path) } },
); );
if (R_SUCCEEDED(rc)) { if (R_SUCCEEDED(rc)) {
@ -509,7 +497,7 @@ Result fsOpen_SystemSaveData(FsFileSystem* out, FsSaveDataSpaceId save_data_spac
// IFileSystem // IFileSystem
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
Result fsFsCreateFile(FsFileSystem* fs, const char* path, s64 size, u32 option) { Result fsFsCreateFile(FsFileSystem* fs, FsPath* path, s64 size, u32 option) {
const struct { const struct {
u32 option; u32 option;
u64 size; u64 size;
@ -517,75 +505,75 @@ Result fsFsCreateFile(FsFileSystem* fs, const char* path, s64 size, u32 option)
return _fsObjectDispatchIn(&fs->s, 0, in, return _fsObjectDispatchIn(&fs->s, 0, in,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
.buffers = { { path, FS_MAX_PATH } }, .buffers = { { path, sizeof(*path) } },
); );
} }
static Result _fsFsCmdWithInPath(FsFileSystem* fs, const char* path, u32 cmd_id) { static Result _fsFsCmdWithInPath(FsFileSystem* fs, FsPath* path, u32 cmd_id) {
return _fsObjectDispatch(&fs->s, cmd_id, return _fsObjectDispatch(&fs->s, cmd_id,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
.buffers = { { path, FS_MAX_PATH } }, .buffers = { { path, sizeof(*path) } },
); );
} }
Result fsFsDeleteFile(FsFileSystem* fs, const char* path) { Result fsFsDeleteFile(FsFileSystem* fs, FsPath* path) {
return _fsFsCmdWithInPath(fs, path, 1); return _fsFsCmdWithInPath(fs, path, 1);
} }
Result fsFsCreateDirectory(FsFileSystem* fs, const char* path) { Result fsFsCreateDirectory(FsFileSystem* fs, FsPath* path) {
return _fsFsCmdWithInPath(fs, path, 2); return _fsFsCmdWithInPath(fs, path, 2);
} }
Result fsFsDeleteDirectory(FsFileSystem* fs, const char* path) { Result fsFsDeleteDirectory(FsFileSystem* fs, FsPath* path) {
return _fsFsCmdWithInPath(fs, path, 3); return _fsFsCmdWithInPath(fs, path, 3);
} }
Result fsFsDeleteDirectoryRecursively(FsFileSystem* fs, const char* path) { Result fsFsDeleteDirectoryRecursively(FsFileSystem* fs, FsPath* path) {
return _fsFsCmdWithInPath(fs, path, 4); return _fsFsCmdWithInPath(fs, path, 4);
} }
static Result _fsFsCmdWithTwoInPaths(FsFileSystem* fs, const char* cur_path, const char* new_path, u32 cmd_id) { static Result _fsFsCmdWithTwoInPaths(FsFileSystem* fs, FsPath* cur_path, FsPath* new_path, u32 cmd_id) {
return _fsObjectDispatch(&fs->s, cmd_id, return _fsObjectDispatch(&fs->s, cmd_id,
.buffer_attrs = { .buffer_attrs = {
SfBufferAttr_HipcPointer | SfBufferAttr_In, SfBufferAttr_HipcPointer | SfBufferAttr_In,
SfBufferAttr_HipcPointer | SfBufferAttr_In, SfBufferAttr_HipcPointer | SfBufferAttr_In,
}, },
.buffers = { .buffers = {
{ cur_path, FS_MAX_PATH }, { cur_path, sizeof(*cur_path) },
{ new_path, FS_MAX_PATH }, { new_path, sizeof(*new_path) },
}, },
); );
} }
Result fsFsRenameFile(FsFileSystem* fs, const char* cur_path, const char* new_path) { Result fsFsRenameFile(FsFileSystem* fs, FsPath* cur_path, FsPath* new_path) {
return _fsFsCmdWithTwoInPaths(fs, cur_path, new_path, 5); return _fsFsCmdWithTwoInPaths(fs, cur_path, new_path, 5);
} }
Result fsFsRenameDirectory(FsFileSystem* fs, const char* cur_path, const char* new_path) { Result fsFsRenameDirectory(FsFileSystem* fs, FsPath* cur_path, FsPath* new_path) {
return _fsFsCmdWithTwoInPaths(fs, cur_path, new_path, 6); return _fsFsCmdWithTwoInPaths(fs, cur_path, new_path, 6);
} }
Result fsFsGetEntryType(FsFileSystem* fs, const char* path, FsDirEntryType* out) { Result fsFsGetEntryType(FsFileSystem* fs, FsPath* path, FsDirEntryType* out) {
return _fsObjectDispatchOut(&fs->s, 7, *out, return _fsObjectDispatchOut(&fs->s, 7, *out,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
.buffers = { { path, FS_MAX_PATH } }, .buffers = { { path, sizeof(*path) } },
); );
} }
static Result _fsFsOpenCommon(FsFileSystem* fs, const char* path, u32 flags, Service* out, u32 cmd_id) { static Result _fsFsOpenCommon(FsFileSystem* fs, FsPath* path, u32 flags, Service* out, u32 cmd_id) {
return _fsObjectDispatchIn(&fs->s, cmd_id, flags, return _fsObjectDispatchIn(&fs->s, cmd_id, flags,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
.buffers = { { path, FS_MAX_PATH } }, .buffers = { { path, sizeof(*path) } },
.out_num_objects = 1, .out_num_objects = 1,
.out_objects = out, .out_objects = out,
); );
} }
Result fsFsOpenFile(FsFileSystem* fs, const char* path, u32 mode, FsFile* out) { Result fsFsOpenFile(FsFileSystem* fs, FsPath* path, u32 mode, FsFile* out) {
return _fsFsOpenCommon(fs, path, mode, &out->s, 8); return _fsFsOpenCommon(fs, path, mode, &out->s, 8);
} }
Result fsFsOpenDirectory(FsFileSystem* fs, const char* path, u32 mode, FsDir* out) { Result fsFsOpenDirectory(FsFileSystem* fs, FsPath* path, u32 mode, FsDir* out) {
return _fsFsOpenCommon(fs, path, mode, &out->s, 9); return _fsFsOpenCommon(fs, path, mode, &out->s, 9);
} }
@ -593,45 +581,42 @@ Result fsFsCommit(FsFileSystem* fs) {
return _fsCmdNoIO(&fs->s, 10); return _fsCmdNoIO(&fs->s, 10);
} }
static Result _fsFsCmdWithInPathAndOutU64(FsFileSystem* fs, const char* path, u64* out, u32 cmd_id) { static Result _fsFsCmdWithInPathAndOutU64(FsFileSystem* fs, FsPath* path, u64* out, u32 cmd_id) {
return _fsObjectDispatchOut(&fs->s, cmd_id, *out, return _fsObjectDispatchOut(&fs->s, cmd_id, *out,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
.buffers = { { path, FS_MAX_PATH } }, .buffers = { { path, sizeof(*path) } },
); );
} }
Result fsFsGetFreeSpace(FsFileSystem* fs, const char* path, s64* out) { Result fsFsGetFreeSpace(FsFileSystem* fs, FsPath* path, s64* out) {
return _fsFsCmdWithInPathAndOutU64(fs, path, (u64*)out, 11); return _fsFsCmdWithInPathAndOutU64(fs, path, (u64*)out, 11);
} }
Result fsFsGetTotalSpace(FsFileSystem* fs, const char* path, s64* out) { Result fsFsGetTotalSpace(FsFileSystem* fs, FsPath* path, s64* out) {
return _fsFsCmdWithInPathAndOutU64(fs, path, (u64*)out, 12); return _fsFsCmdWithInPathAndOutU64(fs, path, (u64*)out, 12);
} }
Result fsFsCleanDirectoryRecursively(FsFileSystem* fs, const char* path) { Result fsFsCleanDirectoryRecursively(FsFileSystem* fs, FsPath* path) {
if (hosversionBefore(3,0,0)) if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _fsFsCmdWithInPath(fs, path, 13); return _fsFsCmdWithInPath(fs, path, 13);
} }
Result fsFsGetFileTimeStampRaw(FsFileSystem* fs, const char* path, FsTimeStampRaw *out) { Result fsFsGetFileTimeStampRaw(FsFileSystem* fs, FsPath* path, FsTimeStampRaw *out) {
if (hosversionBefore(3,0,0)) if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _fsObjectDispatchOut(&fs->s, 14, *out, return _fsObjectDispatchOut(&fs->s, 14, *out,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
.buffers = { { path, FS_MAX_PATH } }, .buffers = { { path, sizeof(*path) } },
); );
} }
Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void *in, size_t in_size, const char* path, FsFileSystemQueryId query_id) { Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void *in, size_t in_size, FsPath* path, FsFileSystemQueryId query_id) {
if (hosversionBefore(4,0,0)) if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
char send_path[FS_MAX_PATH] = {0};
strncpy(send_path, path, sizeof(send_path)-1);
return _fsObjectDispatchIn(&fs->s, 15, query_id, return _fsObjectDispatchIn(&fs->s, 15, query_id,
.buffer_attrs = { .buffer_attrs = {
SfBufferAttr_HipcPointer | SfBufferAttr_In, SfBufferAttr_HipcPointer | SfBufferAttr_In,
@ -639,14 +624,14 @@ Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void *
SfBufferAttr_HipcMapAlias | SfBufferAttr_Out | SfBufferAttr_HipcMapTransferAllowsNonSecure, SfBufferAttr_HipcMapAlias | SfBufferAttr_Out | SfBufferAttr_HipcMapTransferAllowsNonSecure,
}, },
.buffers = { .buffers = {
{ send_path, sizeof(send_path) }, { path, sizeof(*path) },
{ in, in_size }, { in, in_size },
{ out, out_size }, { out, out_size },
}, },
); );
} }
Result fsFsSetConcatenationFileAttribute(FsFileSystem* fs, const char *path) { Result fsFsSetConcatenationFileAttribute(FsFileSystem* fs, FsPath* path) {
return fsFsQueryEntry(fs, NULL, 0, NULL, 0, path, FsFileSystemQueryId_SetConcatenationFileAttribute); return fsFsQueryEntry(fs, NULL, 0, NULL, 0, path, FsFileSystemQueryId_SetConcatenationFileAttribute);
} }
@ -654,8 +639,10 @@ Result fsFsIsValidSignedSystemPartitionOnSdCard(FsFileSystem* fs, bool *out) {
if (hosversionBefore(8,0,0)) if (hosversionBefore(8,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
FsPath root_path = fsPathFromLiteralSafe("/");
u8 tmp=0; u8 tmp=0;
Result rc = fsFsQueryEntry(fs, &tmp, sizeof(tmp), NULL, 0, "/", FsFileSystemQueryId_IsValidSignedSystemPartitionOnSdCard); Result rc = fsFsQueryEntry(fs, &tmp, sizeof(tmp), NULL, 0, &root_path, FsFileSystemQueryId_IsValidSignedSystemPartitionOnSdCard);
if (R_SUCCEEDED(rc) && out) *out = tmp & 1; if (R_SUCCEEDED(rc) && out) *out = tmp & 1;
return rc; return rc;
} }

View File

@ -32,17 +32,14 @@ Service* fsldrGetServiceSession(void) {
return &g_fsldrSrv; return &g_fsldrSrv;
} }
Result fsldrOpenCodeFileSystem(u64 tid, const char *path, FsFileSystem* out) { Result fsldrOpenCodeFileSystem(u64 tid, FsPath* path, FsFileSystem* out) {
char send_path[FS_MAX_PATH]={0};
strncpy(send_path, path, FS_MAX_PATH-1);
serviceAssumeDomain(&g_fsldrSrv); serviceAssumeDomain(&g_fsldrSrv);
return serviceDispatchIn(&g_fsldrSrv, 0, tid, return serviceDispatchIn(&g_fsldrSrv, 0, tid,
.buffer_attrs = { .buffer_attrs = {
SfBufferAttr_HipcPointer | SfBufferAttr_In, SfBufferAttr_HipcPointer | SfBufferAttr_In,
}, },
.buffers = { .buffers = {
{ send_path, FS_MAX_PATH }, { path, sizeof(*path) },
}, },
.out_num_objects = 1, .out_num_objects = 1,
.out_objects = &out->s, .out_objects = &out->s,