Change directory structure
This commit is contained in:
166
sysmodules/loader/source/fsldr.c
Normal file
166
sysmodules/loader/source/fsldr.c
Normal file
@@ -0,0 +1,166 @@
|
||||
#include <3ds.h>
|
||||
#include "fsldr.h"
|
||||
#include "fsreg.h"
|
||||
#include "srvsys.h"
|
||||
|
||||
#define SDK_VERSION 0x70200C8
|
||||
|
||||
static Handle fsldrHandle;
|
||||
static int fsldrRefCount;
|
||||
|
||||
// MAKE SURE fsreg has been init before calling this
|
||||
static Result fsldrPatchPermissions(void)
|
||||
{
|
||||
u32 pid;
|
||||
Result res;
|
||||
FS_ProgramInfo info;
|
||||
u32 storage[8] = {0};
|
||||
|
||||
storage[6] = 0x680; // SDMC access and NAND access flag
|
||||
info.programId = 0x0004013000001302LL; // loader PID
|
||||
info.mediaType = MEDIATYPE_NAND;
|
||||
res = svcGetProcessId(&pid, 0xFFFF8001);
|
||||
if (R_SUCCEEDED(res))
|
||||
{
|
||||
res = FSREG_Register(pid, 0xFFFF000000000000LL, &info, (u8 *)storage);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
Result fsldrInit(void)
|
||||
{
|
||||
Result ret = 0;
|
||||
|
||||
if (AtomicPostIncrement(&fsldrRefCount)) return 0;
|
||||
|
||||
ret = srvSysGetServiceHandle(&fsldrHandle, "fs:LDR");
|
||||
if (R_SUCCEEDED(ret))
|
||||
{
|
||||
fsldrPatchPermissions();
|
||||
ret = FSLDR_InitializeWithSdkVersion(fsldrHandle, SDK_VERSION);
|
||||
ret = FSLDR_SetPriority(0);
|
||||
if (R_FAILED(ret)) svcBreak(USERBREAK_ASSERT);
|
||||
}
|
||||
else
|
||||
{
|
||||
AtomicDecrement(&fsldrRefCount);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fsldrExit(void)
|
||||
{
|
||||
if (AtomicDecrement(&fsldrRefCount)) return;
|
||||
svcCloseHandle(fsldrHandle);
|
||||
}
|
||||
|
||||
Result FSLDR_InitializeWithSdkVersion(Handle session, u32 version)
|
||||
{
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x861,1,2); // 0x8610042
|
||||
cmdbuf[1] = version;
|
||||
cmdbuf[2] = 32;
|
||||
|
||||
Result ret = 0;
|
||||
if(R_FAILED(ret = svcSendSyncRequest(session))) return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result FSLDR_SetPriority(u32 priority)
|
||||
{
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x862,1,0); // 0x8620040
|
||||
cmdbuf[1] = priority;
|
||||
|
||||
Result ret = 0;
|
||||
if(R_FAILED(ret = svcSendSyncRequest(fsldrHandle))) return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result FSLDR_OpenFileDirectly(Handle* out, FS_ArchiveID archiveId, FS_Path archivePath, FS_Path filePath, u32 openFlags, u32 attributes)
|
||||
{
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x803,8,4); // 0x8030204
|
||||
cmdbuf[1] = 0;
|
||||
cmdbuf[2] = archiveId;
|
||||
cmdbuf[3] = archivePath.type;
|
||||
cmdbuf[4] = archivePath.size;
|
||||
cmdbuf[5] = filePath.type;
|
||||
cmdbuf[6] = filePath.size;
|
||||
cmdbuf[7] = openFlags;
|
||||
cmdbuf[8] = attributes;
|
||||
cmdbuf[9] = IPC_Desc_StaticBuffer(archivePath.size, 2);
|
||||
cmdbuf[10] = (u32)archivePath.data;
|
||||
cmdbuf[11] = IPC_Desc_StaticBuffer(filePath.size, 0);
|
||||
cmdbuf[12] = (u32)filePath.data;
|
||||
|
||||
Result ret = 0;
|
||||
if(R_FAILED(ret = svcSendSyncRequest(fsldrHandle))) return ret;
|
||||
|
||||
if(out) *out = cmdbuf[3];
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result FSLDR_OpenArchive(FS_Archive* archive, FS_ArchiveID id, FS_Path path)
|
||||
{
|
||||
if(!archive) return -2;
|
||||
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x80C,3,2); // 0x80C00C2
|
||||
cmdbuf[1] = id;
|
||||
cmdbuf[2] = path.type;
|
||||
cmdbuf[3] = path.size;
|
||||
cmdbuf[4] = IPC_Desc_StaticBuffer(path.size, 0);
|
||||
cmdbuf[5] = (u32) path.data;
|
||||
|
||||
Result ret = 0;
|
||||
if(R_FAILED(ret = svcSendSyncRequest(fsldrHandle))) return ret;
|
||||
|
||||
if(archive) *archive = cmdbuf[2] | ((u64) cmdbuf[3] << 32);
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result FSLDR_CloseArchive(FS_Archive archive)
|
||||
{
|
||||
if(!archive) return -2;
|
||||
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x80E,2,0); // 0x80E0080
|
||||
cmdbuf[1] = (u32) archive;
|
||||
cmdbuf[2] = (u32) (archive >> 32);
|
||||
|
||||
Result ret = 0;
|
||||
if(R_FAILED(ret = svcSendSyncRequest(fsldrHandle))) return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result FSLDR_OpenDirectory(Handle* out, FS_Archive archive, FS_Path path)
|
||||
{
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x80B,4,2); // 0x80B0102
|
||||
cmdbuf[1] = (u32) archive;
|
||||
cmdbuf[2] = (u32) (archive >> 32);
|
||||
cmdbuf[3] = path.type;
|
||||
cmdbuf[4] = path.size;
|
||||
cmdbuf[5] = IPC_Desc_StaticBuffer(path.size, 0);
|
||||
cmdbuf[6] = (u32) path.data;
|
||||
|
||||
Result ret = 0;
|
||||
if(R_FAILED(ret = svcSendSyncRequest(fsldrHandle))) return ret;
|
||||
|
||||
if(out) *out = cmdbuf[3];
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
Reference in New Issue
Block a user