Skip to content

Instantly share code, notes, and snippets.

@profi200
Last active February 16, 2022 06:53
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save profi200/d0d092c11d0eb0692748 to your computer and use it in GitHub Desktop.
Save profi200/d0d092c11d0eb0692748 to your computer and use it in GitHub Desktop.
#include <cstdio>
#include <string>
#include <3ds.h>
#include "fs.h"
#include "misc.h"
u8 sysLang = 0;
// Override the default service init/exit functions
extern "C"
{
u32 __stacksize__ = 0x40000;
void __appInit()
{
// Initialize services
srvInit();
aptInit();
gfxInit(GSP_RGB565_OES, GSP_RGB565_OES, false);
hidInit(NULL);
fsInit();
sdmcArchiveInit();
}
void __appExit()
{
// Exit services
sdmcArchiveExit();
fsExit();
hidExit();
gfxExit();
aptExit();
srvExit();
}
}
Result _srvGetServiceHandle(Handle* out, const char* name)
{
Result rc = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x50100;
strcpy((char*)&cmdbuf[1], name);
cmdbuf[3] = strlen(name);
cmdbuf[4] = 0;
if((rc = svcSendSyncRequest(*srvGetSessionHandle()))) return rc;
*out = cmdbuf[3];
return cmdbuf[1];
}
void callback(const std::u16string& fsObject, u32 totalPercent, u32 filePercent)
{
Buffer<char> str(256);
utf16_to_utf8((u8*)&str, (u16*)fsObject.c_str(), 255);
printf("\x1b[1;0H%s %u%%\nTotal: %u", &str, filePercent, totalPercent);
gfxFlushBuffers();
gfxSwapBuffers();
}
int main()
{
Handle fsUHandle = 0;
Result res = _srvGetServiceHandle(&fsUHandle, "fs:USER"); // Get a handle for the process we run under
consoleInit(GFX_TOP, nullptr);
printf("Get fs:USER handle: 0x%X\n", res);
res = FSUSER_Initialize(&fsUHandle);
printf("FSUSER_Initialize: 0x%X\n", res);
FS_archive saveArchive = {ARCH_SAVEDATA, {PATH_EMPTY, 0, nullptr}};
res = FSUSER_OpenArchive(&fsUHandle, &saveArchive);
printf("Open archive: 0x%X\n", res);
if(!res) printf("\x1b[2JA Backup save data.\nB Import save data.\nX Exit.");
else
{
printf("Could not access the savedata archive! Press X to exit.\n");
while(true)
{
hidScanInput();
if(hidKeysDown() & KEY_X) goto exit;
}
}
while(aptMainLoop())
{
hidScanInput();
u32 kDown = hidKeysDown();
if(kDown & KEY_A)
{
try
{
printf("\x1b[2JBacking up save data...");
fs::copyDir(fsUHandle, *fsGetSessionHandle(), u"/", u"/saveDataBackup", callback, saveArchive);
printf("\x1b[2JA Backup save data.\nB Import save data.\nX Exit.");
}
catch(std::exception& e)
{
printf("\n%s\n", e.what());
}
}
if(kDown & KEY_B)
{
try
{
printf("\x1b[2JRestoring save data...");
fs::copyDir(*fsGetSessionHandle(), fsUHandle, u"/saveDataBackup", u"/", callback, sdmcArchive, saveArchive);
res = FSUSER_ControlArchive(fsUHandle, &saveArchive);
printf("Control archive: 0x%X\n", res);
printf("\x1b[2JA Backup save data.\nB Import save data.\nX Exit.");
}
catch(std::exception& e)
{
printf("\n%s\n", e.what());
}
}
if(kDown & KEY_X) break;
gfxFlushBuffers();
gfxSwapBuffers();
gspWaitForVBlank();
}
exit:
FSUSER_CloseArchive(&fsUHandle, &saveArchive);
svcCloseHandle(fsUHandle);
return 0;
}
@ratijas
Copy link

ratijas commented Mar 8, 2019

Hello,
I'm relatively new to the 3DS hacking/homebrew scene. I know about derKitPro and <3ds.h>, but what about "fs.h" and "misc.h"? where do they come from?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment