Skip to content

Basic support for 20.0.0 #671

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion nx/include/switch/services/fsldr.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "../sf/service.h"
#include "../services/fs.h"
#include "../crypto/sha256.h"
#include "../services/ncm_types.h"

typedef struct {
u8 signature[0x100];
Expand All @@ -26,5 +27,5 @@ void fsldrExit(void);
/// Gets the Service object for the actual fsp-ldr service session.
Service* fsldrGetServiceSession(void);

Result fsldrOpenCodeFileSystem(FsCodeInfo* out_code_info, u64 tid, const char *path, FsContentAttributes attr, FsFileSystem* out);
Result fsldrOpenCodeFileSystem(FsCodeInfo* out_code_info, u64 tid, NcmStorageId storage_id, const char *path, FsContentAttributes attr, FsFileSystem* out);
Result fsldrIsArchivedProgram(u64 pid, bool *out);
2 changes: 1 addition & 1 deletion nx/include/switch/services/fspr.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ void fsprExit(void);
/// Gets the Service object for the actual fsp-pr service session.
Service* fsprGetServiceSession(void);

Result fsprRegisterProgram(u64 pid, u64 tid, NcmStorageId sid, const void *fs_access_header, size_t fah_size, const void *fs_access_control, size_t fac_size);
Result fsprRegisterProgram(u64 pid, u64 tid, NcmStorageId sid, const void *fs_access_header, size_t fah_size, const void *fs_access_control, size_t fac_size, u8 fs_access_control_restriction_mode);
Result fsprUnregisterProgram(u64 pid);
Result fsprSetCurrentProcess(void);
Result fsprSetEnabledProgramVerification(bool enabled);
9 changes: 7 additions & 2 deletions nx/include/switch/services/ldr.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ typedef struct {
u64 size;
} LoaderModuleInfo;

typedef struct {
u8 platform; ///< NcmContentMetaPlatform
u8 content_attributes; ///< FsContentAttributes
} LoaderProgramAttributes;

/// Initialize ldr:shel.
Result ldrShellInitialize(void);

Expand Down Expand Up @@ -76,8 +81,8 @@ Result ldrDmntSetProgramArguments(u64 program_id, const void *args, size_t args_
Result ldrDmntFlushArguments(void);
Result ldrDmntGetProcessModuleInfo(u64 pid, LoaderModuleInfo *out_module_infos, size_t max_out_modules, s32 *num_out);

Result ldrPmCreateProcess(u64 pin_id, u32 flags, Handle reslimit_h, Handle *out_process_h);
Result ldrPmGetProgramInfo(const NcmProgramLocation *loc, LoaderProgramInfo *out_program_info); ///< [19.0.0+/Atmosphere]
Result ldrPmCreateProcess(u64 pin_id, u32 flags, Handle reslimit_h, const LoaderProgramAttributes *attrs, Handle *out_process_h);
Result ldrPmGetProgramInfo(const NcmProgramLocation *loc, const LoaderProgramAttributes *attrs, LoaderProgramInfo *out_program_info); ///< [19.0.0+/Atmosphere]
Result ldrPmGetProgramInfoV1(const NcmProgramLocation *loc, LoaderProgramInfoV1 *out_program_info); ///< [1.0.0-18.1.0/Non-Atmosphere]
Result ldrPmPinProgram(const NcmProgramLocation *loc, u64 *out_pin_id);
Result ldrPmUnpinProgram(u64 pin_id);
Expand Down
25 changes: 22 additions & 3 deletions nx/source/services/fsldr.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,32 @@ Service* fsldrGetServiceSession(void) {
return &g_fsldrSrv;
}

Result fsldrOpenCodeFileSystem(FsCodeInfo* out_code_info, u64 tid, const char *path, FsContentAttributes attr, FsFileSystem* out) {
Result fsldrOpenCodeFileSystem(FsCodeInfo* out_code_info, u64 tid, NcmStorageId storage_id, const char *path, FsContentAttributes attr, FsFileSystem* out) {
memset(out_code_info, 0, sizeof(*out_code_info));

char send_path[FS_MAX_PATH]={0};
strncpy(send_path, path, FS_MAX_PATH-1);
if (hosversionBefore(20,0,0))
strncpy(send_path, path, FS_MAX_PATH-1);

if (hosversionAtLeast(17,0,0)) {
if (hosversionAtLeast(20,0,0)) {
const struct {
u8 attr;
u8 storage_id;
u64 tid;
} in = { attr, storage_id, tid };

serviceAssumeDomain(&g_fsldrSrv);
return serviceDispatchIn(&g_fsldrSrv, 0, in,
.buffer_attrs = {
SfBufferAttr_HipcMapAlias | SfBufferAttr_Out,
},
.buffers = {
{ out_code_info, sizeof(*out_code_info) },
},
.out_num_objects = 1,
.out_objects = &out->s,
);
} else if (hosversionAtLeast(17,0,0)) {
const struct {
u8 attr;
u64 tid;
Expand Down
7 changes: 4 additions & 3 deletions nx/source/services/fspr.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Service* fsprGetServiceSession(void) {
static const uint32_t g_fspr_default_fah[] = {0x1, 0xFFFFFFFF, 0xFFFFFFFF, 0x1C, 0, 0x1C, 0};
static const uint32_t g_fspr_default_fac[] = {0x1, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF};

Result fsprRegisterProgram(u64 pid, u64 tid, NcmStorageId sid, const void *fs_access_header, size_t fah_size, const void *fs_access_control, size_t fac_size) {
Result fsprRegisterProgram(u64 pid, u64 tid, NcmStorageId sid, const void *fs_access_header, size_t fah_size, const void *fs_access_control, size_t fac_size, u8 fs_access_control_restriction_mode) {
if (fs_access_header == NULL) {
fs_access_header = g_fspr_default_fah;
fah_size = sizeof(g_fspr_default_fah);
Expand All @@ -44,12 +44,13 @@ Result fsprRegisterProgram(u64 pid, u64 tid, NcmStorageId sid, const void *fs_ac

const struct {
u8 sid;
u8 pad[7];
u8 fs_access_control_restriction_mode;
u8 pad[6];
u64 pid;
u64 tid;
u64 fah_size;
u64 fac_size;
} in = { sid, {0}, pid, tid, fah_size, fac_size };
} in = { sid, fs_access_control_restriction_mode, {0}, pid, tid, fah_size, fac_size };
serviceAssumeDomain(&g_fsprSrv);
return serviceDispatchIn(&g_fsprSrv, 0, in,
.buffer_attrs = {
Expand Down
63 changes: 46 additions & 17 deletions nx/source/services/ldr.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,28 +79,57 @@ Result ldrDmntGetProcessModuleInfo(u64 pid, LoaderModuleInfo *out_module_infos,
);
}

Result ldrPmCreateProcess(u64 pin_id, u32 flags, Handle reslimit_h, Handle *out_process_h) {
const struct {
u32 flags;
u32 pad;
u64 pin_id;
} in = { flags, 0, pin_id };
return serviceDispatchIn(&g_ldrPmSrv, 0, in,
.in_num_handles = 1,
.in_handles = { reslimit_h },
.out_handle_attrs = { SfOutHandleAttr_HipcMove },
.out_handles = out_process_h,
);
Result ldrPmCreateProcess(u64 pin_id, u32 flags, Handle reslimit_h, const LoaderProgramAttributes *attrs, Handle *out_process_h) {
if (hosversionIsAtmosphere() || hosversionAtLeast(20,0,0)) {
const struct {
LoaderProgramAttributes attr;
u16 pad;
u32 flags;
u64 pin_id;
} in = { *attrs, 0, flags, pin_id };
return serviceDispatchIn(&g_ldrPmSrv, 0, in,
.in_num_handles = 1,
.in_handles = { reslimit_h },
.out_handle_attrs = { SfOutHandleAttr_HipcMove },
.out_handles = out_process_h,
);
} else {
const struct {
u32 flags;
u32 pad;
u64 pin_id;
} in = { flags, 0, pin_id };
return serviceDispatchIn(&g_ldrPmSrv, 0, in,
.in_num_handles = 1,
.in_handles = { reslimit_h },
.out_handle_attrs = { SfOutHandleAttr_HipcMove },
.out_handles = out_process_h,
);
}
}

Result ldrPmGetProgramInfo(const NcmProgramLocation *loc, LoaderProgramInfo *out_program_info) {
Result ldrPmGetProgramInfo(const NcmProgramLocation *loc, const LoaderProgramAttributes *attrs, LoaderProgramInfo *out_program_info) {
if (!hosversionIsAtmosphere() && hosversionBefore(19, 0, 0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);

return serviceDispatchIn(&g_ldrPmSrv, 1, *loc,
.buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
.buffers = { { out_program_info, sizeof(*out_program_info) } },
);
if (hosversionIsAtmosphere() || hosversionAtLeast(20,0,0)) {
const struct {
LoaderProgramAttributes attr;
u16 pad1;
u32 pad2;
NcmProgramLocation loc;
} in = { *attrs, 0, 0, *loc };
_Static_assert(sizeof(in) == 0x18);
return serviceDispatchIn(&g_ldrPmSrv, 1, in,
.buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
.buffers = { { out_program_info, sizeof(*out_program_info) } },
);
} else {
return serviceDispatchIn(&g_ldrPmSrv, 1, *loc,
.buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
.buffers = { { out_program_info, sizeof(*out_program_info) } },
);
}
}

Result ldrPmGetProgramInfoV1(const NcmProgramLocation *loc, LoaderProgramInfoV1 *out_program_info) {
Expand Down