ctrulib changes
This commit is contained in:
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2019 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include <3ds.h>
|
||||
#include <string.h>
|
||||
#include "fsreg.h"
|
||||
#include "services.h"
|
||||
#include "csvc.h"
|
||||
|
||||
static Handle fsregHandle;
|
||||
static int fsregRefCount;
|
||||
|
||||
Result fsregInit(void)
|
||||
{
|
||||
Result ret = 0;
|
||||
|
||||
if(AtomicPostIncrement(&fsregRefCount))
|
||||
return 0;
|
||||
|
||||
ret = svcControlService(SERVICEOP_STEAL_CLIENT_SESSION, &fsregHandle, "fs:REG");
|
||||
while(ret == 0x9401BFE)
|
||||
{
|
||||
svcSleepThread(500 * 1000LL);
|
||||
ret = svcControlService(SERVICEOP_STEAL_CLIENT_SESSION, &fsregHandle, "fs:REG");
|
||||
}
|
||||
|
||||
if(R_FAILED(ret))
|
||||
AtomicDecrement(&fsregRefCount);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fsregExit(void)
|
||||
{
|
||||
if(AtomicDecrement(&fsregRefCount) || !fsregHandle)
|
||||
return;
|
||||
svcCloseHandle(fsregHandle);
|
||||
}
|
||||
|
||||
Handle fsregGetHandle(void)
|
||||
{
|
||||
return fsregHandle;
|
||||
}
|
||||
|
||||
Result fsregSetupPermissions(void)
|
||||
{
|
||||
u32 pid;
|
||||
Result res;
|
||||
FS_ProgramInfo info;
|
||||
ExHeader_Arm11StorageInfo storage = {0};
|
||||
|
||||
// SDMC access and NAND access flags
|
||||
storage.fs_access_info = FSACCESS_NANDRW | FSACCESS_NANDRO_RW |
|
||||
FSACCESS_SDMC_RW | FSACCESS_CATEGORY_SYSTEM_APPLICATION;
|
||||
info.programId = 0x0004013000006902LL; // Rosalina TID
|
||||
info.mediaType = MEDIATYPE_NAND;
|
||||
|
||||
if(R_SUCCEEDED(res = svcGetProcessId(&pid, CUR_PROCESS_HANDLE))) // 0xFFFF8001 is an handle to the active process
|
||||
res = FSREG_Register(pid, 0xFFFF000000000000LL, &info, &storage);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Result FSREG_CheckHostLoadId(u64 prog_handle)
|
||||
{
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x406,2,0); // 0x4060080
|
||||
cmdbuf[1] = (u32) (prog_handle);
|
||||
cmdbuf[2] = (u32) (prog_handle >> 32);
|
||||
|
||||
Result ret = 0;
|
||||
if(R_FAILED(ret = svcSendSyncRequest(fsregHandle)))
|
||||
return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result FSREG_LoadProgram(u64 *prog_handle, FS_ProgramInfo *title)
|
||||
{
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x404,4,0); // 0x4040100
|
||||
memcpy(&cmdbuf[1], &title->programId, sizeof(u64));
|
||||
*(u8 *)&cmdbuf[3] = title->mediaType;
|
||||
memcpy(((u8 *)&cmdbuf[3])+1, &title->padding, 7);
|
||||
|
||||
Result ret = 0;
|
||||
if(R_FAILED(ret = svcSendSyncRequest(fsregHandle)))
|
||||
return ret;
|
||||
*prog_handle = *(u64 *)&cmdbuf[2];
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result FSREG_GetProgramInfo(ExHeader *exheader, u32 entry_count, u64 prog_handle)
|
||||
{
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x403,3,0); // 0x40300C0
|
||||
cmdbuf[1] = entry_count;
|
||||
*(u64 *)&cmdbuf[2] = prog_handle;
|
||||
cmdbuf[64] = ((entry_count << 10) << 14) | 2;
|
||||
cmdbuf[65] = (u32) exheader;
|
||||
|
||||
Result ret = 0;
|
||||
if(R_FAILED(ret = svcSendSyncRequest(fsregHandle)))
|
||||
return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result FSREG_UnloadProgram(u64 prog_handle)
|
||||
{
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x405,2,0); // 0x4050080
|
||||
cmdbuf[1] = (u32) (prog_handle);
|
||||
cmdbuf[2] = (u32) (prog_handle >> 32);
|
||||
|
||||
Result ret = 0;
|
||||
if(R_FAILED(ret = svcSendSyncRequest(fsregHandle)))
|
||||
return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result FSREG_Unregister(u32 pid)
|
||||
{
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x402,1,0); // 0x4020040
|
||||
cmdbuf[1] = pid;
|
||||
|
||||
Result ret = 0;
|
||||
if(R_FAILED(ret = svcSendSyncRequest(fsregHandle)))
|
||||
return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result FSREG_Register(u32 pid, u64 prog_handle, FS_ProgramInfo *info, void *storageinfo)
|
||||
{
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x401,0xf,0); // 0x40103C0
|
||||
cmdbuf[1] = pid;
|
||||
*(u64 *)&cmdbuf[2] = prog_handle;
|
||||
memcpy(&cmdbuf[4], &info->programId, sizeof(u64));
|
||||
*(u8 *)&cmdbuf[6] = info->mediaType;
|
||||
memcpy(((u8 *)&cmdbuf[6])+1, &info->padding, 7);
|
||||
memcpy((u8 *)&cmdbuf[8], storageinfo, 32);
|
||||
|
||||
Result ret = 0;
|
||||
if(R_FAILED(ret = svcSendSyncRequest(fsregHandle)))
|
||||
return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
@@ -246,21 +246,21 @@ void HBLDR_HandleCommands(void *ctx)
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
if (cmdbuf[0] != IPC_MakeHeader(4, 0, 2) || cmdbuf[1] != IPC_Desc_Buffer(sizeof(ExHeader), IPC_BUFFER_RW))
|
||||
if (cmdbuf[0] != IPC_MakeHeader(4, 0, 2) || cmdbuf[1] != IPC_Desc_Buffer(sizeof(ExHeader_Info), IPC_BUFFER_RW))
|
||||
{
|
||||
error(cmdbuf, 0xD9001830);
|
||||
break;
|
||||
}
|
||||
|
||||
// Perform ExHeader patches
|
||||
ExHeader* exh = (ExHeader*)cmdbuf[2];
|
||||
memcpy(exh->info.sci.codeset_info.name, "3dsx_app", 8);
|
||||
exh->info.sci.codeset_info.stack_size = 0x1000; // 3dsx/libctru don't require anymore than this
|
||||
memset(&exh->info.sci.dependencies, 0, sizeof(exh->info.sci.dependencies));
|
||||
memcpy(exh->info.sci.dependencies, dependencyList, sizeof(dependencyList));
|
||||
ExHeader_Info* exh = (ExHeader_Info*)cmdbuf[2];
|
||||
u32 stacksize = 4096; // 3dsx/libctru don't require anymore than this
|
||||
memcpy(exh->sci.codeset_info.name, "3dsx_app", 8);
|
||||
memcpy(&exh->sci.codeset_info.stack_size, &stacksize, 4);
|
||||
memset(&exh->sci.dependencies, 0, sizeof(exh->sci.dependencies));
|
||||
memcpy(exh->sci.dependencies, dependencyList, sizeof(dependencyList));
|
||||
|
||||
ExHeader_Arm11SystemLocalCapabilities* localcaps0 = &exh->info.aci.local_caps;
|
||||
ExHeader_Arm11SystemLocalCapabilities* localcaps1 = &exh->access_descriptor.acli.local_caps;
|
||||
ExHeader_Arm11SystemLocalCapabilities* localcaps0 = &exh->aci.local_caps;
|
||||
|
||||
localcaps0->core_info.core_version = 2;
|
||||
localcaps0->core_info.use_cpu_clockrate_804MHz = false;
|
||||
@@ -271,65 +271,41 @@ void HBLDR_HandleCommands(void *ctx)
|
||||
localcaps0->core_info.o3ds_system_mode = SYSMODE_O3DS_PROD;
|
||||
localcaps0->core_info.priority = 0x30;
|
||||
|
||||
localcaps1->core_info.core_version = 2;
|
||||
localcaps1->core_info.use_cpu_clockrate_804MHz = false;
|
||||
localcaps1->core_info.enable_l2c = false;
|
||||
localcaps1->core_info.n3ds_system_mode = SYSMODE_N3DS_PROD;
|
||||
localcaps1->core_info.ideal_processor = BIT(0); // Intended, this is an oddity of the ExHeader
|
||||
localcaps1->core_info.affinity_mask = BIT(0);
|
||||
localcaps1->core_info.o3ds_system_mode = SYSMODE_O3DS_PROD;
|
||||
localcaps1->core_info.priority = 0; // Intended
|
||||
|
||||
memset(localcaps0->reslimits, 0, sizeof(localcaps0->reslimits));
|
||||
memset(localcaps1->reslimits, 0, sizeof(localcaps0->reslimits));
|
||||
|
||||
localcaps0->reslimits[0] = 0x9E; // Stuff needed to run stuff on core1
|
||||
localcaps1->reslimits[1] = 0x9E;
|
||||
|
||||
localcaps0->storage_info.fs_access_info = 0xFFFFFFFF; // Give access to everything
|
||||
localcaps0->storage_info.no_romfs = true;
|
||||
localcaps0->storage_info.use_extended_savedata_access = true; // Whatever
|
||||
|
||||
localcaps1->storage_info.fs_access_info = 0xFFFFFFFF; // Give access to everything
|
||||
localcaps0->storage_info.no_romfs = true;
|
||||
localcaps0->storage_info.use_extended_savedata_access = true; // Whatever
|
||||
|
||||
/* We have a patched SM, so whatever... */
|
||||
memset(localcaps0->service_access, 0, sizeof(localcaps0->service_access));
|
||||
memcpy(localcaps0->service_access, serviceList, sizeof(serviceList));
|
||||
|
||||
memset(localcaps1->service_access, 0, sizeof(localcaps0->service_access));
|
||||
memcpy(localcaps1->service_access, serviceList, sizeof(serviceList));
|
||||
|
||||
localcaps0->reslimit_category = RESLIMIT_CATEGORY_APPLICATION;
|
||||
localcaps1->reslimit_category = RESLIMIT_CATEGORY_APPLICATION;
|
||||
|
||||
ExHeader_Arm11KernelCapabilities* kcaps0 = &exh->info.aci.kernel_caps;
|
||||
ExHeader_Arm11KernelCapabilities* kcaps1 = &exh->access_descriptor.acli.kernel_caps;
|
||||
ExHeader_Arm11KernelCapabilities* kcaps0 = &exh->aci.kernel_caps;
|
||||
memset(kcaps0->descriptors, 0xFF, sizeof(kcaps0->descriptors));
|
||||
memset(kcaps1->descriptors, 0xFF, sizeof(kcaps1->descriptors));
|
||||
memcpy(kcaps0->descriptors, kernelCaps, sizeof(kernelCaps));
|
||||
memcpy(kcaps1->descriptors, kernelCaps, sizeof(kernelCaps));
|
||||
|
||||
u64 lastdep = sizeof(dependencyList)/8;
|
||||
if (osGetFirmVersion() >= SYSTEM_VERSION(2,50,0)) // 9.6+ FIRM
|
||||
{
|
||||
exh->info.sci.dependencies[lastdep++] = 0x0004013000004002ULL; // nfc
|
||||
exh->sci.dependencies[lastdep++] = 0x0004013000004002ULL; // nfc
|
||||
strncpy((char*)&localcaps0->service_access[0x20], "nfc:u", 8);
|
||||
strncpy((char*)&localcaps1->service_access[0x20], "nfc:u", 8);
|
||||
s64 dummy = 0;
|
||||
bool isN3DS = svcGetSystemInfo(&dummy, 0x10001, 0) == 0;
|
||||
if (isN3DS)
|
||||
{
|
||||
exh->info.sci.dependencies[lastdep++] = 0x0004013020004102ULL; // mvd
|
||||
exh->sci.dependencies[lastdep++] = 0x0004013020004102ULL; // mvd
|
||||
strncpy((char*)&localcaps0->service_access[0x21], "mvd:STD", 8);
|
||||
strncpy((char*)&localcaps1->service_access[0x21], "mvd:STD", 8);
|
||||
}
|
||||
}
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(4, 1, 2);
|
||||
cmdbuf[1] = 0;
|
||||
cmdbuf[2] = IPC_Desc_Buffer(sizeof(ExHeader), IPC_BUFFER_RW);
|
||||
cmdbuf[2] = IPC_Desc_Buffer(sizeof(ExHeader_Info), IPC_BUFFER_RW);
|
||||
cmdbuf[3] = (u32)exh;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
|
||||
#include <3ds.h>
|
||||
#include "memory.h"
|
||||
#include "services.h"
|
||||
#include "fsreg.h"
|
||||
#include "menu.h"
|
||||
#include "service_manager.h"
|
||||
#include "errdisp.h"
|
||||
@@ -40,22 +38,61 @@
|
||||
#include "menus/screen_filters.h"
|
||||
#include "shell_open.h"
|
||||
|
||||
static Result stealFsReg(void)
|
||||
{
|
||||
Result ret = 0;
|
||||
|
||||
ret = svcControlService(SERVICEOP_STEAL_CLIENT_SESSION, fsRegGetSessionHandle(), "fs:REG");
|
||||
while(ret == 0x9401BFE)
|
||||
{
|
||||
svcSleepThread(500 * 1000LL);
|
||||
ret = svcControlService(SERVICEOP_STEAL_CLIENT_SESSION, fsRegGetSessionHandle(), "fs:REG");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result fsRegSetupPermissions(void)
|
||||
{
|
||||
u32 pid;
|
||||
Result res;
|
||||
FS_ProgramInfo info;
|
||||
|
||||
ExHeader_Arm11StorageInfo storageInfo = {
|
||||
.fs_access_info = FSACCESS_NANDRO_RW | FSACCESS_NANDRW | FSACCESS_SDMC_RW,
|
||||
};
|
||||
|
||||
info.programId = 0x0004013000006902LL; // Rosalina TID
|
||||
info.mediaType = MEDIATYPE_NAND;
|
||||
|
||||
if(R_SUCCEEDED(res = svcGetProcessId(&pid, CUR_PROCESS_HANDLE)))
|
||||
res = FSREG_Register(pid, 0xFFFF000000000000LL, &info, &storageInfo);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// this is called before main
|
||||
bool isN3DS;
|
||||
void __appInit()
|
||||
{
|
||||
srvSysInit();
|
||||
fsregInit();
|
||||
Result res;
|
||||
for(res = 0xD88007FA; res == (Result)0xD88007FA; svcSleepThread(500 * 1000LL))
|
||||
{
|
||||
res = srvInit();
|
||||
if(R_FAILED(res) && res != (Result)0xD88007FA)
|
||||
svcBreak(USERBREAK_PANIC);
|
||||
}
|
||||
|
||||
fsSysInit();
|
||||
if (R_FAILED(stealFsReg()) || R_FAILED(fsRegSetupPermissions()) || R_FAILED(fsInit()))
|
||||
svcBreak(USERBREAK_PANIC);
|
||||
}
|
||||
|
||||
// this is called after main exits
|
||||
void __appExit()
|
||||
{
|
||||
fsExit();
|
||||
fsregExit();
|
||||
srvSysExit();
|
||||
svcCloseHandle(*fsRegGetSessionHandle());
|
||||
srvExit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ static Result SOCU_Initialize(Handle memhandle, u32 memsize)
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x1,1,4); // 0x10044
|
||||
cmdbuf[1] = memsize;
|
||||
cmdbuf[2] = IPC_Desc_CurProcessHandle();
|
||||
cmdbuf[2] = IPC_Desc_CurProcessId();
|
||||
cmdbuf[4] = IPC_Desc_SharedHandles(1);
|
||||
cmdbuf[5] = memhandle;
|
||||
|
||||
@@ -180,7 +180,7 @@ int socSocket(int domain, int type, int protocol)
|
||||
cmdbuf[1] = domain;
|
||||
cmdbuf[2] = type;
|
||||
cmdbuf[3] = protocol;
|
||||
cmdbuf[4] = IPC_Desc_CurProcessHandle();
|
||||
cmdbuf[4] = IPC_Desc_CurProcessId();
|
||||
|
||||
ret = svcSendSyncRequest(SOCU_handle);
|
||||
if(ret != 0)
|
||||
@@ -228,7 +228,7 @@ int socBind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
cmdbuf[0] = IPC_MakeHeader(0x5,2,4); // 0x50084
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)tmp_addrlen;
|
||||
cmdbuf[3] = IPC_Desc_CurProcessHandle();
|
||||
cmdbuf[3] = IPC_Desc_CurProcessId();
|
||||
cmdbuf[5] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
|
||||
cmdbuf[6] = (u32)tmpaddr;
|
||||
|
||||
@@ -258,7 +258,7 @@ int socListen(int sockfd, int max_connections)
|
||||
cmdbuf[0] = IPC_MakeHeader(0x3,2,2); // 0x30082
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)max_connections;
|
||||
cmdbuf[3] = IPC_Desc_CurProcessHandle();
|
||||
cmdbuf[3] = IPC_Desc_CurProcessId();
|
||||
|
||||
ret = svcSendSyncRequest(SOCU_handle);
|
||||
if(ret != 0)
|
||||
@@ -293,7 +293,7 @@ int socAccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
||||
cmdbuf[0] = IPC_MakeHeader(0x4,2,2); // 0x40082
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)tmp_addrlen;
|
||||
cmdbuf[3] = IPC_Desc_CurProcessHandle();
|
||||
cmdbuf[3] = IPC_Desc_CurProcessId();
|
||||
|
||||
u32 *staticbufs = getThreadStaticBuffers();
|
||||
saved_threadstorage[0] = staticbufs[0];
|
||||
@@ -350,7 +350,7 @@ int socPoll(struct pollfd *fds, nfds_t nfds, int timeout)
|
||||
cmdbuf[0] = IPC_MakeHeader(0x14,2,4); // 0x140084
|
||||
cmdbuf[1] = (u32)nfds;
|
||||
cmdbuf[2] = (u32)timeout;
|
||||
cmdbuf[3] = IPC_Desc_CurProcessHandle();
|
||||
cmdbuf[3] = IPC_Desc_CurProcessId();
|
||||
cmdbuf[5] = IPC_Desc_StaticBuffer(size,10);
|
||||
cmdbuf[6] = (u32)fds;
|
||||
|
||||
@@ -389,7 +389,7 @@ int socClose(int sockfd)
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0xB,1,2); // 0xB0042
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = IPC_Desc_CurProcessHandle();
|
||||
cmdbuf[2] = IPC_Desc_CurProcessId();
|
||||
|
||||
ret = svcSendSyncRequest(SOCU_handle);
|
||||
if(ret != 0) {
|
||||
@@ -419,7 +419,7 @@ int socSetsockopt(int sockfd, int level, int optname, const void *optval, sockle
|
||||
cmdbuf[2] = (u32)level;
|
||||
cmdbuf[3] = (u32)optname;
|
||||
cmdbuf[4] = (u32)optlen;
|
||||
cmdbuf[5] = IPC_Desc_CurProcessHandle();
|
||||
cmdbuf[5] = IPC_Desc_CurProcessId();
|
||||
cmdbuf[7] = IPC_Desc_StaticBuffer(optlen,9);
|
||||
cmdbuf[8] = (u32)optval;
|
||||
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2019 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include <3ds.h>
|
||||
#include <string.h>
|
||||
#include "fsreg.h"
|
||||
#include "services.h"
|
||||
|
||||
static Handle *srvHandlePtr;
|
||||
static int srvRefCount;
|
||||
static RecursiveLock initLock;
|
||||
static int initLockinit = 0;
|
||||
|
||||
Result srvSysInit(void)
|
||||
{
|
||||
Result rc = 0;
|
||||
|
||||
if (!initLockinit)
|
||||
RecursiveLock_Init(&initLock);
|
||||
|
||||
RecursiveLock_Lock(&initLock);
|
||||
|
||||
if (srvRefCount > 0)
|
||||
{
|
||||
RecursiveLock_Unlock(&initLock);
|
||||
return MAKERESULT(RL_INFO, RS_NOP, 25, RD_ALREADY_INITIALIZED);
|
||||
}
|
||||
|
||||
srvHandlePtr = srvGetSessionHandle();
|
||||
|
||||
while(1)
|
||||
{
|
||||
rc = svcConnectToPort(srvHandlePtr, "srv:");
|
||||
if (R_LEVEL(rc) != RL_PERMANENT ||
|
||||
R_SUMMARY(rc) != RS_NOTFOUND ||
|
||||
R_DESCRIPTION(rc) != RD_NOT_FOUND
|
||||
) break;
|
||||
svcSleepThread(500 * 1000LL);
|
||||
}
|
||||
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
rc = srvRegisterClient();
|
||||
srvRefCount++;
|
||||
}
|
||||
|
||||
RecursiveLock_Unlock(&initLock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result srvSysExit(void)
|
||||
{
|
||||
Result rc = 0;
|
||||
RecursiveLock_Lock(&initLock);
|
||||
|
||||
if(srvRefCount > 1)
|
||||
{
|
||||
srvRefCount--;
|
||||
RecursiveLock_Unlock(&initLock);
|
||||
return MAKERESULT(RL_INFO, RS_NOP, 25, RD_BUSY);
|
||||
}
|
||||
|
||||
if(srvHandlePtr != 0)
|
||||
svcCloseHandle(*srvHandlePtr);
|
||||
else
|
||||
svcBreak(USERBREAK_ASSERT);
|
||||
|
||||
srvHandlePtr = 0;
|
||||
srvRefCount--;
|
||||
|
||||
RecursiveLock_Unlock(&initLock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void fsSysInit(void)
|
||||
{
|
||||
if(R_FAILED(fsregSetupPermissions()))
|
||||
svcBreak(USERBREAK_ASSERT);
|
||||
|
||||
Handle *fsHandlePtr = fsGetSessionHandle();
|
||||
srvGetServiceHandle(fsHandlePtr, "fs:USER");
|
||||
|
||||
FSUSER_InitializeWithSdkVersion(*fsHandlePtr, SDK_VERSION);
|
||||
FSUSER_SetPriority(0);
|
||||
}
|
||||
Reference in New Issue
Block a user