diff --git a/nx/include/switch/runtime/devices/fs_dev.h b/nx/include/switch/runtime/devices/fs_dev.h index 78f7e009..d1b82026 100644 --- a/nx/include/switch/runtime/devices/fs_dev.h +++ b/nx/include/switch/runtime/devices/fs_dev.h @@ -52,7 +52,7 @@ Result fsdevCommitDevice(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. -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). Result fsdevSetConcatenationFileAttribute(const char *path); diff --git a/nx/include/switch/services/fs.h b/nx/include/switch/services/fs.h index d570ce84..e620402b 100644 --- a/nx/include/switch/services/fs.h +++ b/nx/include/switch/services/fs.h @@ -13,13 +13,49 @@ #include "../services/acc.h" #include "../sf/service.h" -// We use wrapped handles for type safety. - #define FS_MAX_PATH 0x301 /// For use with \ref FsSaveDataAttribute. #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 { u8 c[0x10]; } FsRightsId; @@ -54,7 +90,7 @@ typedef struct { /// Directory entry. typedef struct { - char name[FS_MAX_PATH]; ///< Entry name. + FsPath name; ///< Entry name. u8 pad[3]; s8 type; ///< See FsDirEntryType. u8 pad2[3]; ///< ? @@ -307,11 +343,11 @@ Service* fsGetServiceSession(void); void fsSetPriority(FsPriority prio); /// 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 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); /// Do not call this directly, see fs_dev.h. @@ -348,10 +384,10 @@ Result fsOpenSdCardDetectionEventNotifier(FsEventNotifier* out); Result fsIsSignedSystemPartitionOnSdCardValid(bool *out); /// 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+]. -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); @@ -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); // IFileSystem -Result fsFsCreateFile(FsFileSystem* fs, const char* path, s64 size, u32 option); -Result fsFsDeleteFile(FsFileSystem* fs, const char* path); -Result fsFsCreateDirectory(FsFileSystem* fs, const char* path); -Result fsFsDeleteDirectory(FsFileSystem* fs, const char* path); -Result fsFsDeleteDirectoryRecursively(FsFileSystem* fs, const char* path); -Result fsFsRenameFile(FsFileSystem* fs, const char* cur_path, const char* new_path); -Result fsFsRenameDirectory(FsFileSystem* fs, const char* cur_path, const char* new_path); -Result fsFsGetEntryType(FsFileSystem* fs, const char* path, FsDirEntryType* out); -Result fsFsOpenFile(FsFileSystem* fs, const char* path, u32 mode, FsFile* out); -Result fsFsOpenDirectory(FsFileSystem* fs, const char* path, u32 mode, FsDir* out); +Result fsFsCreateFile(FsFileSystem* fs, FsPath* path, s64 size, u32 option); +Result fsFsDeleteFile(FsFileSystem* fs, FsPath* path); +Result fsFsCreateDirectory(FsFileSystem* fs, FsPath* path); +Result fsFsDeleteDirectory(FsFileSystem* fs, FsPath* path); +Result fsFsDeleteDirectoryRecursively(FsFileSystem* fs, FsPath* path); +Result fsFsRenameFile(FsFileSystem* fs, FsPath* cur_path, FsPath* new_path); +Result fsFsRenameDirectory(FsFileSystem* fs, FsPath* cur_path, FsPath* new_path); +Result fsFsGetEntryType(FsFileSystem* fs, FsPath* path, FsDirEntryType* out); +Result fsFsOpenFile(FsFileSystem* fs, FsPath* path, u32 mode, FsFile* out); +Result fsFsOpenDirectory(FsFileSystem* fs, FsPath* path, u32 mode, FsDir* out); Result fsFsCommit(FsFileSystem* fs); -Result fsFsGetFreeSpace(FsFileSystem* fs, const char* path, s64* out); -Result fsFsGetTotalSpace(FsFileSystem* fs, const char* path, s64* out); -Result fsFsGetFileTimeStampRaw(FsFileSystem* fs, const char* path, FsTimeStampRaw *out); ///< [3.0.0+] -Result fsFsCleanDirectoryRecursively(FsFileSystem* fs, const char* 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 fsFsGetFreeSpace(FsFileSystem* fs, FsPath* path, s64* out); +Result fsFsGetTotalSpace(FsFileSystem* fs, FsPath* path, s64* out); +Result fsFsGetFileTimeStampRaw(FsFileSystem* fs, FsPath* path, FsTimeStampRaw *out); ///< [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, FsPath* path, FsFileSystemQueryId query_id); ///< [4.0.0+] void fsFsClose(FsFileSystem* fs); /// 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. -Result fsFsSetConcatenationFileAttribute(FsFileSystem* fs, const char *path); +Result fsFsSetConcatenationFileAttribute(FsFileSystem* fs, FsPath* path); /// Wrapper for fsFsQueryEntry with FsFileSystemQueryId_IsValidSignedSystemPartitionOnSdCard. /// Only available on [8.0.0+]. diff --git a/nx/include/switch/services/fsldr.h b/nx/include/switch/services/fsldr.h index c022a093..b3501a85 100644 --- a/nx/include/switch/services/fsldr.h +++ b/nx/include/switch/services/fsldr.h @@ -18,5 +18,5 @@ void fsldrExit(void); /// Gets the Service object for the actual fsp-ldr service session. 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); diff --git a/nx/source/runtime/devices/fs_dev.c b/nx/source/runtime/devices/fs_dev.c index a70b7418..9698daa1 100644 --- a/nx/source/runtime/devices/fs_dev.c +++ b/nx/source/runtime/devices/fs_dev.c @@ -205,18 +205,18 @@ fsdev_fixpath(struct _reent *r, } if(path[0] == '/') - strncpy(__nx_dev_path_buf, path, PATH_MAX); + strncpy(__nx_dev_path_buf.unix_path, path, PATH_MAX); else { const char* cwd = dev->cwd ? dev->cwd : "/"; - strncpy(__nx_dev_path_buf, cwd, PATH_MAX); - __nx_dev_path_buf[PATH_MAX] = '\0'; - strncat(__nx_dev_path_buf, path, PATH_MAX - strlen(cwd)); + strncpy(__nx_dev_path_buf.unix_path, cwd, PATH_MAX); + __nx_dev_path_buf.unix_path[PATH_MAX] = '\0'; + 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; return NULL; } @@ -224,29 +224,30 @@ fsdev_fixpath(struct _reent *r, if(device) *device = dev; - return __nx_dev_path_buf; + return __nx_dev_path_buf.unix_path; } static int fsdev_getfspath(struct _reent *r, const char *path, fsdev_fsdevice **device, - char *outpath) + FsPath *outpath) { if(fsdev_fixpath(r, path, device) == NULL) return -1; - if(outpath != __nx_dev_path_buf) - memcpy(outpath, __nx_dev_path_buf, FS_MAX_PATH-1); - outpath[FS_MAX_PATH-1] = '\0'; + if(outpath != &__nx_dev_path_buf.nx_path) + memcpy(outpath, &__nx_dev_path_buf.nx_path, FS_MAX_PATH-1); + + outpath->path[FS_MAX_PATH-1] = '\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); - memcpy(out, in, inlen); + ssize_t inlen = strnlen((char*)in->path, len); + memcpy(out, in->path, inlen); if (inlen < len) out[inlen+1] = 0; return inlen; @@ -398,7 +399,7 @@ Result fsdevCommitDevice(const char *name) } 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; 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) { - char *fs_path = __nx_dev_path_buf; + FsPath *fs_path = &__nx_dev_path_buf.nx_path; fsdev_fsdevice *device = NULL; 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) { - char *fs_path = __nx_dev_path_buf; + FsPath *fs_path = &__nx_dev_path_buf.nx_path; fsdev_fsdevice *device = NULL; if(fsdev_getfspath(_REENT, path, &device, fs_path)==-1) @@ -539,7 +540,7 @@ FsFileSystem* fsdevGetDeviceFileSystem(const char *name) 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; @@ -572,7 +573,7 @@ fsdev_open(struct _reent *r, Result rc; u32 fsdev_flags = 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; if(fsdev_getfspath(r, path, &device, fs_path)==-1) @@ -1026,7 +1027,7 @@ fsdev_stat(struct _reent *r, FsDir fdir; Result rc; int ret=0; - char *fs_path = __nx_dev_path_buf; + FsPath *fs_path = &__nx_dev_path_buf.nx_path; fsdev_fsdevice *device = r->deviceData; FsTimeStampRaw timestamps = {0}; FsDirEntryType type; @@ -1112,7 +1113,7 @@ fsdev_unlink(struct _reent *r, const char *name) { Result rc; - char *fs_path = __nx_dev_path_buf; + FsPath *fs_path = &__nx_dev_path_buf.nx_path; fsdev_fsdevice *device = r->deviceData; if(fsdev_getfspath(r, name, &device, fs_path)==-1) @@ -1140,7 +1141,7 @@ fsdev_chdir(struct _reent *r, { FsDir fd; Result rc; - char *fs_path = __nx_dev_path_buf; + FsPath *fs_path = &__nx_dev_path_buf.nx_path; fsdev_fsdevice *device = r->deviceData; if(device->cwd==NULL) @@ -1158,7 +1159,7 @@ fsdev_chdir(struct _reent *r, fsDirClose(&fd); 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) { device->cwd[cwdlen] = '/'; @@ -1190,27 +1191,27 @@ fsdev_rename(struct _reent *r, Result rc; FsDirEntryType type; fsdev_fsdevice *device = r->deviceData; - char fs_path_old[FS_MAX_PATH]; - char*fs_path_new = __nx_dev_path_buf; + FsPath fs_path_old; + 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; if(fsdev_getfspath(r, newName, &device, fs_path_new)==-1) return -1; - rc = fsFsGetEntryType(&device->fs, fs_path_old, &type); + rc = fsFsGetEntryType(&device->fs, &fs_path_old, &type); if(R_SUCCEEDED(rc)) { 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)) return 0; } 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)) return 0; } @@ -1240,7 +1241,7 @@ fsdev_mkdir(struct _reent *r, int mode) { Result rc; - char *fs_path = __nx_dev_path_buf; + FsPath *fs_path = &__nx_dev_path_buf.nx_path; fsdev_fsdevice *device = r->deviceData; if(fsdev_getfspath(r, path, &device, fs_path)==-1) @@ -1270,7 +1271,7 @@ fsdev_diropen(struct _reent *r, { FsDir fd; Result rc; - char *fs_path = __nx_dev_path_buf; + FsPath *fs_path = &__nx_dev_path_buf.nx_path; fsdev_fsdevice *device = r->deviceData; 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 */ 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) { r->_errno = EILSEQ; @@ -1448,7 +1449,7 @@ fsdev_statvfs(struct _reent *r, struct statvfs *buf) { Result rc=0; - char *fs_path = __nx_dev_path_buf; + FsPath *fs_path = &__nx_dev_path_buf.nx_path; fsdev_fsdevice *device = r->deviceData; s64 freespace = 0, total_space = 0; @@ -1590,7 +1591,7 @@ fsdev_rmdir(struct _reent *r, const char *name) { Result rc; - char *fs_path = __nx_dev_path_buf; + FsPath *fs_path = &__nx_dev_path_buf.nx_path; fsdev_fsdevice *device = r->deviceData; if(fsdev_getfspath(r, name, &device, fs_path)==-1) diff --git a/nx/source/runtime/devices/path_buf.c b/nx/source/runtime/devices/path_buf.c index b03dbb53..9d2468ce 100644 --- a/nx/source/runtime/devices/path_buf.c +++ b/nx/source/runtime/devices/path_buf.c @@ -1,3 +1,3 @@ #include "path_buf.h" -char __thread __nx_dev_path_buf[PATH_MAX+1]; +PathBuf __thread __nx_dev_path_buf; diff --git a/nx/source/runtime/devices/path_buf.h b/nx/source/runtime/devices/path_buf.h index dcf0b1eb..bc4893d8 100644 --- a/nx/source/runtime/devices/path_buf.h +++ b/nx/source/runtime/devices/path_buf.h @@ -1,4 +1,11 @@ #pragma once #include -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; diff --git a/nx/source/runtime/devices/romfs_dev.c b/nx/source/runtime/devices/romfs_dev.c index 43dcff0f..6398a506 100644 --- a/nx/source/runtime/devices/romfs_dev.c +++ b/nx/source/runtime/devices/romfs_dev.c @@ -268,7 +268,7 @@ Result romfsMountSelf(const char *name) // Retrieve IFileSystem object + fixed path for our NRO 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) 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) { 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); 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->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)) { romfs_free(mount); @@ -521,7 +521,7 @@ static int navigateToDir(romfs_mount *mount, romfs_dir** ppDir, const char** pPa while (**pPath) { char* slashPos = strchr(*pPath, '/'); - char* component = __nx_dev_path_buf; + char* component = __nx_dev_path_buf.unix_path; if (slashPos) { diff --git a/nx/source/services/fs.c b/nx/source/services/fs.c index ebeef80f..d19fbf39 100644 --- a/nx/source/services/fs.c +++ b/nx/source/services/fs.c @@ -132,15 +132,15 @@ static Result _fsCmdNoInOutBool(Service* srv, bool *out, u32 cmd_id) { // IFileSystemProxy //----------------------------------------------------------------------------- -Result fsOpenFileSystem(FsFileSystem* out, FsFileSystemType fsType, const char* contentPath) { +Result fsOpenFileSystem(FsFileSystem* out, FsFileSystemType fsType, FsPath* 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; return _fsObjectDispatchIn(&g_fsSrv, 0, tmp, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, - .buffers = { { contentPath, FS_MAX_PATH } }, + .buffers = { { contentPath, sizeof(*contentPath) } }, .out_num_objects = 1, .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 { u32 fsType; u64 id; @@ -169,30 +169,24 @@ static Result _fsOpenFileSystemWithId(FsFileSystem* out, u64 id, FsFileSystemTyp return _fsObjectDispatchIn(&g_fsSrv, 8, in, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, - .buffers = { { contentPath, FS_MAX_PATH } }, + .buffers = { { contentPath, sizeof(*contentPath) } }, .out_num_objects = 1, .out_objects = &out->s, ); } -Result fsOpenFileSystemWithId(FsFileSystem* out, u64 id, FsFileSystemType fsType, const char* contentPath) { - char sendStr[FS_MAX_PATH] = {0}; - strncpy(sendStr, contentPath, sizeof(sendStr)-1); - +Result fsOpenFileSystemWithId(FsFileSystem* out, u64 id, FsFileSystemType fsType, FsPath* contentPath) { if (hosversionAtLeast(2,0,0)) - return _fsOpenFileSystemWithId(out, id, fsType, sendStr); + return _fsOpenFileSystemWithId(out, id, fsType, contentPath); else - return _fsOpenFileSystem(out, fsType, sendStr); + return _fsOpenFileSystem(out, fsType, contentPath); } -Result fsOpenBisFileSystem(FsFileSystem* out, FsBisPartitionId partitionId, const char* string) { - char tmpstr[FS_MAX_PATH] = {0}; - strncpy(tmpstr, string, sizeof(tmpstr)-1); - +Result fsOpenBisFileSystem(FsFileSystem* out, FsBisPartitionId partitionId, FsPath* path) { u32 tmp=partitionId; return _fsObjectDispatchIn(&g_fsSrv, 11, tmp, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, - .buffers = { { tmpstr, sizeof(tmpstr) } }, + .buffers = { { path, sizeof(*path) } }, .out_num_objects = 1, .out_objects = &out->s, ); @@ -409,26 +403,20 @@ Result fsIsSignedSystemPartitionOnSdCardValid(bool *out) { 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)) 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, .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)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - char send_path[FS_MAX_PATH] = {0}; - strncpy(send_path, path, FS_MAX_PATH-1); - struct { u8 key_generation; u8 padding[0x7]; @@ -437,7 +425,7 @@ Result fsGetRightsIdAndKeyGenerationByPath(const char* path, u8* out_key_generat Result rc = _fsObjectDispatchOut(&g_fsSrv, 610, out, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, - .buffers = { { send_path, sizeof(send_path) } }, + .buffers = { { path, sizeof(*path) } }, ); if (R_SUCCEEDED(rc)) { @@ -509,7 +497,7 @@ Result fsOpen_SystemSaveData(FsFileSystem* out, FsSaveDataSpaceId save_data_spac // IFileSystem //----------------------------------------------------------------------------- -Result fsFsCreateFile(FsFileSystem* fs, const char* path, s64 size, u32 option) { +Result fsFsCreateFile(FsFileSystem* fs, FsPath* path, s64 size, u32 option) { const struct { u32 option; u64 size; @@ -517,75 +505,75 @@ Result fsFsCreateFile(FsFileSystem* fs, const char* path, s64 size, u32 option) return _fsObjectDispatchIn(&fs->s, 0, 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, .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); } -Result fsFsCreateDirectory(FsFileSystem* fs, const char* path) { +Result fsFsCreateDirectory(FsFileSystem* fs, FsPath* path) { return _fsFsCmdWithInPath(fs, path, 2); } -Result fsFsDeleteDirectory(FsFileSystem* fs, const char* path) { +Result fsFsDeleteDirectory(FsFileSystem* fs, FsPath* path) { return _fsFsCmdWithInPath(fs, path, 3); } -Result fsFsDeleteDirectoryRecursively(FsFileSystem* fs, const char* path) { +Result fsFsDeleteDirectoryRecursively(FsFileSystem* fs, FsPath* path) { 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, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In, SfBufferAttr_HipcPointer | SfBufferAttr_In, }, .buffers = { - { cur_path, FS_MAX_PATH }, - { new_path, FS_MAX_PATH }, + { cur_path, sizeof(*cur_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); } -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); } -Result fsFsGetEntryType(FsFileSystem* fs, const char* path, FsDirEntryType* out) { +Result fsFsGetEntryType(FsFileSystem* fs, FsPath* path, FsDirEntryType* out) { return _fsObjectDispatchOut(&fs->s, 7, *out, .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, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, - .buffers = { { path, FS_MAX_PATH } }, + .buffers = { { path, sizeof(*path) } }, .out_num_objects = 1, .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); } -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); } @@ -593,45 +581,42 @@ Result fsFsCommit(FsFileSystem* fs) { 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, .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); } -Result fsFsGetTotalSpace(FsFileSystem* fs, const char* path, s64* out) { +Result fsFsGetTotalSpace(FsFileSystem* fs, FsPath* path, s64* out) { 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)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); 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)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return _fsObjectDispatchOut(&fs->s, 14, *out, .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)) 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, .buffer_attrs = { 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, }, .buffers = { - { send_path, sizeof(send_path) }, - { in, in_size }, - { out, out_size }, + { path, sizeof(*path) }, + { in, in_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); } @@ -654,8 +639,10 @@ Result fsFsIsValidSignedSystemPartitionOnSdCard(FsFileSystem* fs, bool *out) { if (hosversionBefore(8,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + FsPath root_path = fsPathFromLiteralSafe("/"); + 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; return rc; } diff --git a/nx/source/services/fsldr.c b/nx/source/services/fsldr.c index 08adedb5..a3f4601f 100644 --- a/nx/source/services/fsldr.c +++ b/nx/source/services/fsldr.c @@ -32,17 +32,14 @@ Service* fsldrGetServiceSession(void) { return &g_fsldrSrv; } -Result fsldrOpenCodeFileSystem(u64 tid, const char *path, FsFileSystem* out) { - char send_path[FS_MAX_PATH]={0}; - strncpy(send_path, path, FS_MAX_PATH-1); - +Result fsldrOpenCodeFileSystem(u64 tid, FsPath* path, FsFileSystem* out) { serviceAssumeDomain(&g_fsldrSrv); return serviceDispatchIn(&g_fsldrSrv, 0, tid, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In, }, .buffers = { - { send_path, FS_MAX_PATH }, + { path, sizeof(*path) }, }, .out_num_objects = 1, .out_objects = &out->s,