TuxSH ceea6afa05 loader: add external CXI loading.
When "load external firms and modules" is enabled, Loader will load the
sysmodule from /luma/sysmodule/<titleid>.cxi (all uppercase, and with
the N3DS title ID bit if relevant) and skip patching. Note that this is
a title ID here, not a process name (unlike what we do for KIPs).

While this is aimed at enabling people to easily load replacements for
official sysmodules, you can load your own custom sysmodules that don't
correspond to anything installed. You can use gdb to do so:

  set remote exec-file <tid>
  run
2023-01-23 19:53:01 +00:00

138 lines
2.4 KiB
C

#include <3ds.h>
#include "ifile.h"
Result IFile_Open(IFile *file, FS_ArchiveID archiveId, FS_Path archivePath, FS_Path filePath, u32 flags)
{
Result res;
res = FSUSER_OpenFileDirectly(&file->handle, archiveId, archivePath, filePath, flags, 0);
file->pos = 0;
file->size = 0;
return res;
}
Result IFile_OpenFromArchive(IFile *file, FS_Archive archive, FS_Path filePath, u32 flags)
{
Result res;
res = FSUSER_OpenFile(&file->handle, archive, filePath, flags, 0);
file->pos = 0;
file->size = 0;
return res;
}
Result IFile_Close(IFile *file)
{
return FSFILE_Close(file->handle);
}
Result IFile_GetSize(IFile *file, u64 *size)
{
Result res;
res = FSFILE_GetSize(file->handle, size);
if (R_SUCCEEDED(res)) file->size = *size;
return res;
}
Result IFile_SetSize(IFile *file, u64 size)
{
Result res;
res = FSFILE_SetSize(file->handle, size);
if (R_SUCCEEDED(res)) file->size = size;
return res;
}
Result IFile_Read(IFile *file, u64 *total, void *buffer, u32 len)
{
u32 read;
u32 left;
char *buf;
u64 cur;
Result res;
if (len == 0)
{
*total = 0;
return 0;
}
buf = (char *)buffer;
cur = 0;
left = len;
while (1)
{
res = FSFILE_Read(file->handle, &read, file->pos, buf, left);
if (R_FAILED(res) || read == 0)
{
break;
}
cur += read;
file->pos += read;
if (read == left)
{
break;
}
buf += read;
left -= read;
}
*total = cur;
return res;
}
Result IFile_Write(IFile *file, u64 *total, const void *buffer, u32 len, u32 flags)
{
u32 written;
u32 left;
char *buf;
u64 cur;
Result res;
if (len == 0)
{
*total = 0;
return 0;
}
buf = (char *)buffer;
cur = 0;
left = len;
while (1)
{
res = FSFILE_Write(file->handle, &written, file->pos, buf, left, flags);
if (R_FAILED(res))
{
break;
}
cur += written;
file->pos += written;
if (written == left)
{
break;
}
buf += written;
left -= written;
}
*total = cur;
return res;
}
Result IFile_ReadAt(IFile *file, u64 *total, void *buffer, u32 offset, u32 len)
{
*total = 0;
file->pos = offset;
return IFile_Read(file, total, buffer, len);
}
u32 IFile_Read2(IFile *file, void *buffer, u32 size, u32 offset)
{
u64 total = 0;
Result res = IFile_ReadAt(file, &total, buffer, offset, size);
return R_SUCCEEDED(res) ? (u32)total : 0;
}