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);
/// 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);

View File

@ -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+].

View File

@ -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);

View File

@ -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)

View File

@ -1,3 +1,3 @@
#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
#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
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)
{

View File

@ -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;
}

View File

@ -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,