libctru/libctru/source/services/fs.c
2016-08-25 08:39:26 +02:00

1870 lines
45 KiB
C

#include <string.h>
#include <3ds/types.h>
#include <3ds/result.h>
#include <3ds/svc.h>
#include <3ds/srv.h>
#include <3ds/synchronization.h>
#include <3ds/services/fs.h>
#include <3ds/ipc.h>
#include <3ds/env.h>
#include "../internal.h"
#define FS_MAX_EXEMPT_ARCHIVE_HANDLES 16
static Handle fsuHandle;
static int fsuRefCount;
static FS_Archive fsExemptArchives[FS_MAX_EXEMPT_ARCHIVE_HANDLES];
static Handle fsSession(void)
{
ThreadVars* tv = getThreadVars();
if (tv->fs_magic == FS_OVERRIDE_MAGIC)
return tv->fs_session;
return fsuHandle;
}
static Handle fsSessionForArchive(FS_Archive archive)
{
for (int i = 0; i < FS_MAX_EXEMPT_ARCHIVE_HANDLES; i++)
{
if (fsExemptArchives[i] == archive)
return fsuHandle;
}
return fsSession();
}
Result fsInit(void)
{
Result ret = 0;
if (AtomicPostIncrement(&fsuRefCount)) return 0;
ret = srvGetServiceHandle(&fsuHandle, "fs:USER");
if (R_SUCCEEDED(ret) && envGetHandle("fs:USER") == 0)
{
ret = FSUSER_Initialize(fsuHandle);
if (R_FAILED(ret)) svcCloseHandle(fsuHandle);
}
if (R_FAILED(ret)) AtomicDecrement(&fsuRefCount);
return ret;
}
void fsExit(void)
{
if (AtomicDecrement(&fsuRefCount)) return;
svcCloseHandle(fsuHandle);
}
void fsUseSession(Handle session)
{
ThreadVars* tv = getThreadVars();
tv->fs_magic = FS_OVERRIDE_MAGIC;
tv->fs_session = session;
}
void fsEndUseSession(void)
{
ThreadVars* tv = getThreadVars();
tv->fs_magic = 0;
}
void fsExemptFromSession(FS_Archive archive)
{
int freeIndex = -1;
for (int i = 0; i < FS_MAX_EXEMPT_ARCHIVE_HANDLES; i++)
{
if (fsExemptArchives[i] == archive)
return;
if (freeIndex == -1 && fsExemptArchives[i] == 0)
freeIndex = i;
}
if (freeIndex != -1)
fsExemptArchives[freeIndex] = archive;
}
void fsUnexemptFromSession(FS_Archive archive)
{
for (int i = 0; i < FS_MAX_EXEMPT_ARCHIVE_HANDLES; i++)
{
if (fsExemptArchives[i] == archive)
{
fsExemptArchives[i] = 0;
break;
}
}
}
FS_Path fsMakePath(FS_PathType type, const void* path)
{
FS_Path p = { type, 0, path };
switch (type)
{
case PATH_ASCII:
p.size = strlen((const char*)path)+1;
break;
case PATH_UTF16:
{
const u16* str = (const u16*)path;
while (*str++) p.size++;
p.size = (p.size+1)*2;
break;
}
case PATH_EMPTY:
p.size = 1;
p.data = "";
default:
break;
}
return p;
}
Handle* fsGetSessionHandle(void)
{
return &fsuHandle;
}
Result FSUSER_Control(FS_Action action, void* input, u32 inputSize, void* output, u32 outputSize)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x401,3,4); // 0x40100C4
cmdbuf[1] = action;
cmdbuf[2] = inputSize;
cmdbuf[3] = outputSize;
cmdbuf[4] = IPC_Desc_Buffer(inputSize, IPC_BUFFER_R);
cmdbuf[5] = (u32) input;
cmdbuf[6] = IPC_Desc_Buffer(outputSize, IPC_BUFFER_W);
cmdbuf[7] = (u32) output;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_Initialize(Handle session)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x801,0,2); // 0x8010002
cmdbuf[1] = IPC_Desc_CurProcessHandle();
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(session))) return ret;
return cmdbuf[1];
}
Result FSUSER_OpenFile(Handle* out, FS_Archive archive, FS_Path path, u32 openFlags, u32 attributes)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x802,7,2); // 0x80201C2
cmdbuf[1] = 0;
cmdbuf[2] = (u32) archive;
cmdbuf[3] = (u32) (archive >> 32);
cmdbuf[4] = path.type;
cmdbuf[5] = path.size;
cmdbuf[6] = openFlags;
cmdbuf[7] = attributes;
cmdbuf[8] = IPC_Desc_StaticBuffer(path.size, 0);
cmdbuf[9] = (u32) path.data;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret;
if(out) *out = cmdbuf[3];
return cmdbuf[1];
}
Result FSUSER_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(fsSession()))) return ret;
if(out) *out = cmdbuf[3];
return cmdbuf[1];
}
Result FSUSER_DeleteFile(FS_Archive archive, FS_Path path)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x804,5,2); // 0x8040142
cmdbuf[1] = 0;
cmdbuf[2] = (u32) archive;
cmdbuf[3] = (u32) (archive >> 32);
cmdbuf[4] = path.type;
cmdbuf[5] = path.size;
cmdbuf[6] = IPC_Desc_StaticBuffer(path.size, 0);
cmdbuf[7] = (u32) path.data;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret;
return cmdbuf[1];
}
Result FSUSER_RenameFile(FS_Archive srcArchive, FS_Path srcPath, FS_Archive dstArchive, FS_Path dstPath)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x805,9,4); // 0x8050244
cmdbuf[1] = 0;
cmdbuf[2] = (u32) srcArchive;
cmdbuf[3] = (u32) (srcArchive >> 32);
cmdbuf[4] = srcPath.type;
cmdbuf[5] = srcPath.size;
cmdbuf[6] = (u32) dstArchive;
cmdbuf[7] = (u32) (dstArchive >> 32);
cmdbuf[8] = dstPath.type;
cmdbuf[9] = dstPath.size;
cmdbuf[10] = IPC_Desc_StaticBuffer(srcPath.size, 1);
cmdbuf[11] = (u32) srcPath.data;
cmdbuf[12] = IPC_Desc_StaticBuffer(dstPath.size, 2);
cmdbuf[13] = (u32) dstPath.data;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(srcArchive)))) return ret;
return cmdbuf[1];
}
Result FSUSER_DeleteDirectory(FS_Archive archive, FS_Path path)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x806,5,2); // 0x8060142
cmdbuf[1] = 0;
cmdbuf[2] = (u32) archive;
cmdbuf[3] = (u32) (archive >> 32);
cmdbuf[4] = path.type;
cmdbuf[5] = path.size;
cmdbuf[6] = IPC_Desc_StaticBuffer(path.size, 0);
cmdbuf[7] = (u32) path.data;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret;
return cmdbuf[1];
}
Result FSUSER_DeleteDirectoryRecursively(FS_Archive archive, FS_Path path)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x807,5,2); // 0x8070142
cmdbuf[1] = 0;
cmdbuf[2] = (u32) archive;
cmdbuf[3] = (u32) (archive >> 32);
cmdbuf[4] = path.type;
cmdbuf[5] = path.size;
cmdbuf[6] = IPC_Desc_StaticBuffer(path.size, 0);
cmdbuf[7] = (u32) path.data;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret;
return cmdbuf[1];
}
Result FSUSER_CreateFile(FS_Archive archive, FS_Path path, u32 attributes, u64 fileSize)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x808,8,2); // 0x8080202
cmdbuf[1] = 0;
cmdbuf[2] = (u32) archive;
cmdbuf[3] = (u32) (archive >> 32);
cmdbuf[4] = path.type;
cmdbuf[5] = path.size;
cmdbuf[6] = attributes;
cmdbuf[7] = (u32) fileSize;
cmdbuf[8] = (u32) (fileSize >> 32);
cmdbuf[9] = IPC_Desc_StaticBuffer(path.size, 0);
cmdbuf[10] = (u32) path.data;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret;
return cmdbuf[1];
}
Result FSUSER_CreateDirectory(FS_Archive archive, FS_Path path, u32 attributes)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x809,6,2); // 0x8090182
cmdbuf[1] = 0;
cmdbuf[2] = (u32) archive;
cmdbuf[3] = (u32) (archive >> 32);
cmdbuf[4] = path.type;
cmdbuf[5] = path.size;
cmdbuf[6] = attributes;
cmdbuf[7] = IPC_Desc_StaticBuffer(path.size, 0);
cmdbuf[8] = (u32) path.data;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret;
return cmdbuf[1];
}
Result FSUSER_RenameDirectory(FS_Archive srcArchive, FS_Path srcPath, FS_Archive dstArchive, FS_Path dstPath)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x80A,9,4); // 0x80A0244
cmdbuf[1] = 0;
cmdbuf[2] = (u32) srcArchive;
cmdbuf[3] = (u32) (srcArchive >> 32);
cmdbuf[4] = srcPath.type;
cmdbuf[5] = srcPath.size;
cmdbuf[6] = (u32) dstArchive;
cmdbuf[7] = (u32) (dstArchive >> 32);
cmdbuf[8] = dstPath.type;
cmdbuf[9] = dstPath.size;
cmdbuf[10] = IPC_Desc_StaticBuffer(srcPath.size, 1);
cmdbuf[11] = (u32) srcPath.data;
cmdbuf[12] = IPC_Desc_StaticBuffer(dstPath.size, 2);
cmdbuf[13] = (u32) dstPath.data;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(srcArchive)))) return ret;
return cmdbuf[1];
}
Result FSUSER_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(fsSessionForArchive(archive)))) return ret;
if(out) *out = cmdbuf[3];
return cmdbuf[1];
}
Result FSUSER_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(fsSession()))) return ret;
if(archive) *archive = cmdbuf[2] | ((u64) cmdbuf[3] << 32);
return cmdbuf[1];
}
Result FSUSER_ControlArchive(FS_Archive archive, FS_ArchiveAction action, void* input, u32 inputSize, void* output, u32 outputSize)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x80D,5,4); // 0x80D0144
cmdbuf[1] = (u32) archive;
cmdbuf[2] = (u32) (archive >> 32);
cmdbuf[3] = action;
cmdbuf[4] = inputSize;
cmdbuf[5] = outputSize;
cmdbuf[6] = IPC_Desc_Buffer(inputSize, IPC_BUFFER_R);
cmdbuf[7] = (u32) input;
cmdbuf[8] = IPC_Desc_Buffer(outputSize, IPC_BUFFER_W);
cmdbuf[9] = (u32) output;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret;
return cmdbuf[1];
}
Result FSUSER_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(fsSessionForArchive(archive)))) return ret;
return cmdbuf[1];
}
Result FSUSER_GetFreeBytes(u64* freeBytes, FS_Archive archive)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x812,2,0); // 0x8120080
cmdbuf[1] = (u32) archive;
cmdbuf[2] = (u32) (archive >> 32);
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret;
if(freeBytes) *freeBytes = cmdbuf[2] | ((u64) cmdbuf[3] << 32);
return cmdbuf[1];
}
Result FSUSER_GetCardType(FS_CardType* type)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x813,0,0); // 0x8130000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(type) *type = cmdbuf[2] & 0xFF;
return cmdbuf[1];
}
Result FSUSER_GetSdmcArchiveResource(FS_ArchiveResource* archiveResource)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x814,0,0); // 0x8140000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(archiveResource) memcpy(archiveResource, &cmdbuf[2], sizeof(FS_ArchiveResource));
return cmdbuf[1];
}
Result FSUSER_GetNandArchiveResource(FS_ArchiveResource* archiveResource)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x815,0,0); // 0x8150000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(archiveResource) memcpy(archiveResource, &cmdbuf[2], sizeof(FS_ArchiveResource));
return cmdbuf[1];
}
Result FSUSER_GetSdmcFatfsError(u32* error)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x816,0,0); // 0x8160000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(error) *error = cmdbuf[2];
return cmdbuf[1];
}
Result FSUSER_IsSdmcDetected(bool *detected)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x817,0,0); // 0x8170000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(detected) *detected = cmdbuf[2] & 0xFF;
return cmdbuf[1];
}
Result FSUSER_IsSdmcWritable(bool *writable)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x818,0,0); // 0x8180000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(writable) *writable = cmdbuf[2] & 0xFF;
return cmdbuf[1];
}
Result FSUSER_GetSdmcCid(u8* out, u32 length)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x819,1,2); // 0x8190042
cmdbuf[1] = length;
cmdbuf[2] = IPC_Desc_Buffer(length, IPC_BUFFER_W);
cmdbuf[3] = (u32) out;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_GetNandCid(u8* out, u32 length)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x81A,1,2); // 0x81A0042
cmdbuf[1] = length;
cmdbuf[2] = IPC_Desc_Buffer(length, IPC_BUFFER_W);
cmdbuf[3] = (u32) out;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_GetSdmcSpeedInfo(u32 *speedInfo)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x81B,0,0); // 0x81B0000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(speedInfo) *speedInfo = cmdbuf[2];
return cmdbuf[1];
}
Result FSUSER_GetNandSpeedInfo(u32 *speedInfo)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x81C,0,0); // 0x81C0000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(speedInfo) *speedInfo = cmdbuf[2];
return cmdbuf[1];
}
Result FSUSER_GetSdmcLog(u8* out, u32 length)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x81D,1,2); // 0x81D0042
cmdbuf[1] = length;
cmdbuf[2] = IPC_Desc_Buffer(length, IPC_BUFFER_W);
cmdbuf[3] = (u32) out;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_GetNandLog(u8* out, u32 length)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x81E,1,2); // 0x81E0042
cmdbuf[1] = length;
cmdbuf[2] = IPC_Desc_Buffer(length, IPC_BUFFER_W);
cmdbuf[3] = (u32) out;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_ClearSdmcLog(void)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x81F,0,0); // 0x81F0000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_ClearNandLog(void)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x820,0,0); // 0x8200000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_CardSlotIsInserted(bool* inserted)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x821,0,0); // 0x8210000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(inserted) *inserted = cmdbuf[2] & 0xFF;
return cmdbuf[1];
}
Result FSUSER_CardSlotPowerOn(bool* status)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x822,0,0); // 0x8220000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(status) *status = cmdbuf[2] & 0xFF;
return cmdbuf[1];
}
Result FSUSER_CardSlotPowerOff(bool* status)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x823,0,0); // 0x8230000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(status) *status = cmdbuf[2] & 0xFF;
return cmdbuf[1];
}
Result FSUSER_CardSlotGetCardIFPowerStatus(bool* status)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x824,0,0); // 0x8240000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(status) *status = cmdbuf[2] & 0xFF;
return cmdbuf[1];
}
Result FSUSER_CardNorDirectCommand(u8 commandId)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x825,1,0); // 0x8250040
cmdbuf[1] = commandId;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_CardNorDirectCommandWithAddress(u8 commandId, u32 address)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x826,2,0); // 0x8260080
cmdbuf[1] = commandId;
cmdbuf[2] = address;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_CardNorDirectRead(u8 commandId, u32 size, u8* output)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x827,2,2); // 0x8270082
cmdbuf[1] = commandId;
cmdbuf[2] = size;
cmdbuf[3] = IPC_Desc_Buffer(size * sizeof(u32), IPC_BUFFER_W);
cmdbuf[4] = (u32) output;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_CardNorDirectReadWithAddress(u8 commandId, u32 address, u32 size, u8* output)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x828,3,2); // 0x82800C2
cmdbuf[1] = commandId;
cmdbuf[2] = address;
cmdbuf[3] = size;
cmdbuf[4] = IPC_Desc_Buffer(size * sizeof(u32), IPC_BUFFER_W);
cmdbuf[5] = (u32) output;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_CardNorDirectWrite(u8 commandId, u32 size, u8* input)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x829,2,2); // 0x8290082
cmdbuf[1] = commandId;
cmdbuf[2] = size;
cmdbuf[3] = IPC_Desc_Buffer(size * sizeof(u32), IPC_BUFFER_R);
cmdbuf[4] = (u32) input;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_CardNorDirectWriteWithAddress(u8 commandId, u32 address, u32 size, u8* input)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x82A,3,2); // 0x82A00C2
cmdbuf[1] = commandId;
cmdbuf[2] = address;
cmdbuf[3] = size;
cmdbuf[4] = IPC_Desc_Buffer(size * sizeof(u32), IPC_BUFFER_R);
cmdbuf[5] = (u32) input;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_CardNorDirectRead_4xIO(u8 commandId, u32 address, u32 size, u8* output)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x82B,3,2); // 0x82B00C2
cmdbuf[1] = commandId;
cmdbuf[2] = address;
cmdbuf[3] = size;
cmdbuf[4] = IPC_Desc_Buffer(size * sizeof(u32), IPC_BUFFER_W);
cmdbuf[5] = (u32) output;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_CardNorDirectCpuWriteWithoutVerify(u32 address, u32 size, u8* input)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x82C,2,2); // 0x82C0082
cmdbuf[1] = address;
cmdbuf[2] = size;
cmdbuf[3] = IPC_Desc_Buffer(size * sizeof(u32), IPC_BUFFER_R);
cmdbuf[4] = (u32) input;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_CardNorDirectSectorEraseWithoutVerify(u32 address)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x82D,1,0); // 0x82D0040
cmdbuf[1] = address;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_GetProductInfo(FS_ProductInfo* info, u32 processId)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x82E,1,0); // 0x82E0040
cmdbuf[1] = processId;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(info) memcpy(info, &cmdbuf[2], sizeof(FS_ProductInfo));
return cmdbuf[1];
}
Result FSUSER_GetProgramLaunchInfo(FS_ProgramInfo* info, u32 processId)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x82F,1,0); // 0x82F0040
cmdbuf[1] = processId;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(info) memcpy(info, &cmdbuf[2], sizeof(FS_ProgramInfo));
return cmdbuf[1];
}
Result FSUSER_SetCardSpiBaudRate(FS_CardSpiBaudRate baudRate)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x837,1,0); // 0x8370040
cmdbuf[1] = baudRate;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_SetCardSpiBusMode(FS_CardSpiBusMode busMode)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x838,1,0); // 0x8380040
cmdbuf[1] = busMode;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_SendInitializeInfoTo9(void)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x839,0,0); // 0x8390000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_GetSpecialContentIndex(u16* index, FS_MediaType mediaType, u64 programId, FS_SpecialContentType type)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x83A,4,0); // 0x83A0100
cmdbuf[1] = mediaType;
cmdbuf[2] = (u32) programId;
cmdbuf[3] = (u32) (programId >> 32);
cmdbuf[4] = type;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(index) *index = cmdbuf[2] & 0xFFFF;
return cmdbuf[1];
}
Result FSUSER_GetLegacyRomHeader(FS_MediaType mediaType, u64 programId, u8* header)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x83B,3,2); // 0x83B00C2
cmdbuf[1] = mediaType;
cmdbuf[2] = (u32) programId;
cmdbuf[3] = (u32) (programId >> 32);
cmdbuf[4] = IPC_Desc_Buffer(0x3B4, IPC_BUFFER_W);
cmdbuf[5] = (u32) header;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_GetLegacyBannerData(FS_MediaType mediaType, u64 programId, u8* banner)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x83C,3,2); // 0x83C00C2
cmdbuf[1] = mediaType;
cmdbuf[2] = (u32) programId;
cmdbuf[3] = (u32) (programId >> 32);
cmdbuf[4] = IPC_Desc_Buffer(0x23C0, IPC_BUFFER_W);
cmdbuf[5] = (u32) banner;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_CheckAuthorityToAccessExtSaveData(bool* access, FS_MediaType mediaType, u64 saveId, u32 processId)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x83D,4,0); // 0x83D0100
cmdbuf[1] = mediaType;
cmdbuf[2] = (u32) saveId;
cmdbuf[3] = (u32) (saveId >> 32);
cmdbuf[4] = processId;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(access) *access = cmdbuf[2] & 0xFF;
return cmdbuf[1];
}
Result FSUSER_QueryTotalQuotaSize(u64* quotaSize, u32 directories, u32 files, u32 fileSizeCount, u64* fileSizes)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x83E,3,2); // 0x83E00C2
cmdbuf[1] = directories;
cmdbuf[2] = files;
cmdbuf[3] = fileSizeCount;
cmdbuf[4] = IPC_Desc_Buffer(fileSizeCount * 8, IPC_BUFFER_R);
cmdbuf[5] = (u32) fileSizes;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(quotaSize) *quotaSize = cmdbuf[2] | ((u64) cmdbuf[3] << 32);
return cmdbuf[1];
}
Result FSUSER_AbnegateAccessRight(u32 accessRight)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x840,1,0); // 0x8400040
cmdbuf[1] = accessRight;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_DeleteSdmcRoot(void)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x841,0,0); // 0x8410000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_DeleteAllExtSaveDataOnNand(void)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x842,1,0); // 0x8420040
cmdbuf[1] = 0;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_InitializeCtrFileSystem(void)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x843,0,0); // 0x8430000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_CreateSeed(void)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x844,0,0); // 0x8440000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_GetFormatInfo(u32* totalSize, u32* directories, u32* files, bool* duplicateData, FS_ArchiveID archiveId, FS_Path path)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x845,3,2); // 0x84500C2
cmdbuf[1] = archiveId;
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(fsSession()))) return ret;
if(totalSize) *totalSize = cmdbuf[2];
if(directories) *directories = cmdbuf[3];
if(files) *files = cmdbuf[4];
if(duplicateData) *duplicateData = cmdbuf[5] & 0xFF;
return cmdbuf[1];
}
Result FSUSER_GetLegacyRomHeader2(u32 headerSize, FS_MediaType mediaType, u64 programId, u8* header)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x846,4,2); // 0x8460102
cmdbuf[1] = headerSize;
cmdbuf[2] = mediaType;
cmdbuf[3] = (u32) programId;
cmdbuf[4] = (u32) (programId >> 32);
cmdbuf[5] = IPC_Desc_Buffer(headerSize, IPC_BUFFER_W);
cmdbuf[6] = (u32) header;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_GetSdmcCtrRootPath(u8* out, u32 length)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x848,1,2); // 0x8480042
cmdbuf[1] = length;
cmdbuf[2] = IPC_Desc_Buffer(length, IPC_BUFFER_W);
cmdbuf[3] = (u32) out;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_GetArchiveResource(FS_ArchiveResource* archiveResource, FS_SystemMediaType mediaType)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x849,1,0); // 0x8490040
cmdbuf[1] = mediaType;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(archiveResource) memcpy(archiveResource, &cmdbuf[2], sizeof(FS_ArchiveResource));
return cmdbuf[1];
}
Result FSUSER_ExportIntegrityVerificationSeed(FS_IntegrityVerificationSeed* seed)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x84A,0,2); // 0x84A0002
cmdbuf[1] = IPC_Desc_Buffer(sizeof(FS_IntegrityVerificationSeed), IPC_BUFFER_W);
cmdbuf[2] = (u32) seed;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_ImportIntegrityVerificationSeed(FS_IntegrityVerificationSeed* seed)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x84B,0,2); // 0x84B0002
cmdbuf[1] = IPC_Desc_Buffer(sizeof(FS_IntegrityVerificationSeed), IPC_BUFFER_R);
cmdbuf[2] = (u32) seed;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_FormatSaveData(FS_ArchiveID archiveId, FS_Path path, u32 blocks, u32 directories, u32 files, u32 directoryBuckets, u32 fileBuckets, bool duplicateData)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x84C,9,2); // 0x84C0242
cmdbuf[1] = archiveId;
cmdbuf[2] = path.type;
cmdbuf[3] = path.size;
cmdbuf[4] = blocks;
cmdbuf[5] = directories;
cmdbuf[6] = files;
cmdbuf[7] = directoryBuckets;
cmdbuf[8] = fileBuckets;
cmdbuf[9] = duplicateData;
cmdbuf[10] = IPC_Desc_StaticBuffer(path.size, 0);
cmdbuf[11] = (u32) path.data;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_GetLegacySubBannerData(u32 bannerSize, FS_MediaType mediaType, u64 programId, u8* banner)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x84D,4,2); // 0x84D0102
cmdbuf[1] = bannerSize;
cmdbuf[2] = mediaType;
cmdbuf[3] = (u32) programId;
cmdbuf[4] = (u32) (programId >> 32);
cmdbuf[5] = IPC_Desc_Buffer(bannerSize, IPC_BUFFER_W);
cmdbuf[6] = (u32) banner;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_UpdateSha256Context(const void* data, u32 inputSize, u8* hash)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x84E, 13, 2); // 0x84E0342
cmdbuf[9] = inputSize;
cmdbuf[10] = 0;
cmdbuf[11] = 0;
cmdbuf[12] = 0;
cmdbuf[13] = 1;
cmdbuf[14] = IPC_Desc_Buffer(inputSize, IPC_BUFFER_R);
cmdbuf[15] = (u32)data;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(hash) memcpy(hash, &cmdbuf[2], 0x20);
return cmdbuf[1];
}
Result FSUSER_ReadSpecialFile(u32* bytesRead, u64 fileOffset, u32 size, u8* data)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x84F,4,2); // 0x84F0102
cmdbuf[1] = 0;
cmdbuf[2] = (u32) fileOffset;
cmdbuf[3] = (u32) (fileOffset >> 32);
cmdbuf[4] = size;
cmdbuf[5] = IPC_Desc_Buffer(size, IPC_BUFFER_W);
cmdbuf[6] = (u32) data;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(bytesRead) *bytesRead = cmdbuf[2];
return cmdbuf[1];
}
Result FSUSER_GetSpecialFileSize(u64* fileSize)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x850,1,0); // 0x8500040
cmdbuf[1] = 0;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(fileSize) *fileSize = cmdbuf[2] | ((u64) cmdbuf[3] << 32);
return cmdbuf[1];
}
Result FSUSER_CreateExtSaveData(FS_ExtSaveDataInfo info, u32 directories, u32 files, u64 sizeLimit, u32 smdhSize, u8* smdh)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x851,9,2); // 0x8510242
memcpy(&cmdbuf[1], &info, sizeof(FS_ExtSaveDataInfo));
cmdbuf[5] = directories;
cmdbuf[6] = files;
cmdbuf[7] = (u32) sizeLimit;
cmdbuf[8] = (u32) (sizeLimit >> 32);
cmdbuf[9] = smdhSize;
cmdbuf[10] = IPC_Desc_Buffer(smdhSize, IPC_BUFFER_R);
cmdbuf[11] = (u32) smdh;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_DeleteExtSaveData(FS_ExtSaveDataInfo info)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x852,4,0); // 0x8520100
memcpy(&cmdbuf[1], &info, sizeof(FS_ExtSaveDataInfo));
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_ReadExtSaveDataIcon(u32* bytesRead, FS_ExtSaveDataInfo info, u32 smdhSize, u8* smdh)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x853,5,2); // 0x8530142
memcpy(&cmdbuf[1], &info, sizeof(FS_ExtSaveDataInfo));
cmdbuf[5] = smdhSize;
cmdbuf[6] = IPC_Desc_Buffer(smdhSize, IPC_BUFFER_W);
cmdbuf[7] = (u32) smdh;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(bytesRead) *bytesRead = cmdbuf[2];
return cmdbuf[1];
}
Result FSUSER_GetExtDataBlockSize(u64* totalBlocks, u64* freeBlocks, u32* blockSize, FS_ExtSaveDataInfo info)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x854,4,0); // 0x8540100
memcpy(&cmdbuf[1], &info, sizeof(FS_ExtSaveDataInfo));
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(totalBlocks) *totalBlocks = cmdbuf[2] | ((u64) cmdbuf[3] << 32);
if(freeBlocks) *freeBlocks = cmdbuf[4] | ((u64) cmdbuf[5] << 32);
if(blockSize) *blockSize = cmdbuf[6];
return cmdbuf[1];
}
Result FSUSER_EnumerateExtSaveData(u32* idsWritten, u32 idsSize, FS_MediaType mediaType, u32 idSize, bool shared, u8* ids)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x855,4,2); // 0x8550102
cmdbuf[1] = idsSize;
cmdbuf[2] = mediaType;
cmdbuf[3] = idSize;
cmdbuf[4] = shared;
cmdbuf[5] = IPC_Desc_Buffer(idsSize, IPC_BUFFER_W);
cmdbuf[6] = (u32) ids;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(idsWritten) *idsWritten = cmdbuf[2];
return cmdbuf[1];
}
Result FSUSER_CreateSystemSaveData(FS_SystemSaveDataInfo info, u32 totalSize, u32 blockSize, u32 directories, u32 files, u32 directoryBuckets, u32 fileBuckets, bool duplicateData)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x856,9,0); // 0x8560240
memcpy(&cmdbuf[1], &info, sizeof(FS_SystemSaveDataInfo));
cmdbuf[3] = totalSize;
cmdbuf[4] = blockSize;
cmdbuf[5] = directories;
cmdbuf[6] = files;
cmdbuf[7] = directoryBuckets;
cmdbuf[8] = fileBuckets;
cmdbuf[9] = duplicateData;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_DeleteSystemSaveData(FS_SystemSaveDataInfo info)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x857,2,0); // 0x8570080
memcpy(&cmdbuf[1], &info, sizeof(FS_SystemSaveDataInfo));
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_StartDeviceMoveAsSource(FS_DeviceMoveContext* context)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x858,0,0); // 0x8580000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(context) memcpy(context, &cmdbuf[2], sizeof(FS_DeviceMoveContext));
return cmdbuf[1];
}
Result FSUSER_StartDeviceMoveAsDestination(FS_DeviceMoveContext context, bool clear)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x859,9,0); // 0x8590240
memcpy(&cmdbuf[1], &context, sizeof(FS_DeviceMoveContext));
cmdbuf[9] = clear;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_SetArchivePriority(FS_Archive archive, u32 priority)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x85A,3,0); // 0x85A00C0
cmdbuf[1] = (u32) archive;
cmdbuf[2] = (u32) (archive >> 32);
cmdbuf[3] = priority;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret;
return cmdbuf[1];
}
Result FSUSER_GetArchivePriority(u32* priority, FS_Archive archive)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x85B,2,0); // 0x85B0080
cmdbuf[1] = (u32) archive;
cmdbuf[2] = (u32) (archive >> 32);
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret;
if(priority) *priority = cmdbuf[2];
return cmdbuf[1];
}
Result FSUSER_SetCtrCardLatencyParameter(u64 latency, bool emulateEndurance)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x85C,3,0); // 0x85C00C0
cmdbuf[1] = (u32) latency;
cmdbuf[2] = (u32) (latency >> 32);
cmdbuf[3] = emulateEndurance;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_SwitchCleanupInvalidSaveData(bool enable)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x85F,1,0); // 0x85F0040
cmdbuf[1] = enable;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_EnumerateSystemSaveData(u32* idsWritten, u32 idsSize, u32* ids)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x860,1,2); // 0x8600042
cmdbuf[1] = idsSize;
cmdbuf[2] = IPC_Desc_Buffer(idsSize, IPC_BUFFER_W);
cmdbuf[3] = (u32) ids;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(idsWritten) *idsWritten = cmdbuf[2];
return cmdbuf[1];
}
Result FSUSER_InitializeWithSdkVersion(Handle session, u32 version)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x861,1,2); // 0x8610042
cmdbuf[1] = version;
cmdbuf[2] = IPC_Desc_CurProcessHandle();
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(session))) return ret;
return cmdbuf[1];
}
Result FSUSER_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(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_GetPriority(u32* priority)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x863,0,0); // 0x8630000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(priority) *priority = cmdbuf[2];
return cmdbuf[1];
}
Result FSUSER_SetSaveDataSecureValue(u64 value, FS_SecureValueSlot slot, u32 titleUniqueId, u8 titleVariation)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x865,5,0); // 0x8650140
cmdbuf[1] = (u32) value;
cmdbuf[2] = (u32) (value >> 32);
cmdbuf[3] = slot;
cmdbuf[4] = titleUniqueId;
cmdbuf[5] = titleVariation;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_GetSaveDataSecureValue(bool* exists, u64* value, FS_SecureValueSlot slot, u32 titleUniqueId, u8 titleVariation)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x866,3,0); // 0x86600C0
cmdbuf[1] = slot;
cmdbuf[2] = titleUniqueId;
cmdbuf[3] = titleVariation;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(exists) *exists = cmdbuf[2] & 0xFF;
if(value) *value = cmdbuf[3] | ((u64) cmdbuf[4] << 32);
return cmdbuf[1];
}
Result FSUSER_ControlSecureSave(FS_SecureSaveAction action, void* input, u32 inputSize, void* output, u32 outputSize)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x867,3,4); // 0x86700C4
cmdbuf[1] = action;
cmdbuf[2] = inputSize;
cmdbuf[3] = outputSize;
cmdbuf[4] = IPC_Desc_Buffer(inputSize, IPC_BUFFER_R);
cmdbuf[5] = (u32) input;
cmdbuf[6] = IPC_Desc_Buffer(outputSize, IPC_BUFFER_W);
cmdbuf[7] = (u32) output;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
return cmdbuf[1];
}
Result FSUSER_GetMediaType(FS_MediaType* mediaType)
{
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x868,0,0); // 0x8680000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret;
if(mediaType) *mediaType = cmdbuf[2] & 0xFF;
return cmdbuf[1];
}
Result FSFILE_Control(Handle handle, FS_FileAction action, void* input, u32 inputSize, void* output, u32 outputSize)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x401,3,4); // 0x40100C4
cmdbuf[1] = action;
cmdbuf[2] = inputSize;
cmdbuf[3] = outputSize;
cmdbuf[4] = IPC_Desc_Buffer(inputSize, IPC_BUFFER_R);
cmdbuf[5] = (u32) input;
cmdbuf[6] = IPC_Desc_Buffer(outputSize, IPC_BUFFER_W);
cmdbuf[7] = (u32) output;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
return cmdbuf[1];
}
Result FSFILE_OpenSubFile(Handle handle, Handle* subFile, u64 offset, u64 size)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x801,4,0); // 0x8010100
cmdbuf[1] = (u32) offset;
cmdbuf[2] = (u32) (offset >> 32);
cmdbuf[3] = (u32) size;
cmdbuf[4] = (u32) (size >> 32);
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
if(subFile) *subFile = cmdbuf[3];
return cmdbuf[1];
}
Result FSFILE_Read(Handle handle, u32* bytesRead, u64 offset, void* buffer, u32 size)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x802,3,2); // 0x80200C2
cmdbuf[1] = (u32) offset;
cmdbuf[2] = (u32) (offset >> 32);
cmdbuf[3] = size;
cmdbuf[4] = IPC_Desc_Buffer(size, IPC_BUFFER_W);
cmdbuf[5] = (u32) buffer;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
if(bytesRead) *bytesRead = cmdbuf[2];
return cmdbuf[1];
}
Result FSFILE_Write(Handle handle, u32* bytesWritten, u64 offset, const void* buffer, u32 size, u32 flags)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x803,4,2); // 0x8030102
cmdbuf[1] = (u32) offset;
cmdbuf[2] = (u32) (offset >> 32);
cmdbuf[3] = size;
cmdbuf[4] = flags;
cmdbuf[5] = IPC_Desc_Buffer(size, IPC_BUFFER_R);
cmdbuf[6] = (u32) buffer;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
if(bytesWritten) *bytesWritten = cmdbuf[2];
return cmdbuf[1];
}
Result FSFILE_GetSize(Handle handle, u64* size)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x804,0,0); // 0x8040000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
if(size) *size = cmdbuf[2] | ((u64) cmdbuf[3] << 32);
return cmdbuf[1];
}
Result FSFILE_SetSize(Handle handle, u64 size)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x805,2,0); // 0x8050080
cmdbuf[1] = (u32) size;
cmdbuf[2] = (u32) (size >> 32);
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
return cmdbuf[1];
}
Result FSFILE_GetAttributes(Handle handle, u32* attributes)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x806,0,0); // 0x8060000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
if(attributes) *attributes = cmdbuf[2];
return cmdbuf[1];
}
Result FSFILE_SetAttributes(Handle handle, u32 attributes)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x807,1,0); // 0x8070040
cmdbuf[1] = attributes;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
return cmdbuf[1];
}
Result FSFILE_Close(Handle handle)
{
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x808,0,0); // 0x8080000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
ret = cmdbuf[1];
if(R_SUCCEEDED(ret)) ret = svcCloseHandle(handle);
return ret;
}
Result FSFILE_Flush(Handle handle)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x809,0,0); // 0x8090000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
return cmdbuf[1];
}
Result FSFILE_SetPriority(Handle handle, u32 priority)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x80A,1,0); // 0x80A0040
cmdbuf[1] = priority;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
return cmdbuf[1];
}
Result FSFILE_GetPriority(Handle handle, u32* priority)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x80B,0,0); // 0x80B0000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
if(priority) *priority = cmdbuf[2];
return cmdbuf[1];
}
Result FSFILE_OpenLinkFile(Handle handle, Handle* linkFile)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x80C,0,0); // 0x80C0000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
if(linkFile) *linkFile = cmdbuf[3];
return cmdbuf[1];
}
Result FSDIR_Control(Handle handle, FS_DirectoryAction action, void* input, u32 inputSize, void* output, u32 outputSize)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x401,3,4); // 0x40100C4
cmdbuf[1] = action;
cmdbuf[2] = inputSize;
cmdbuf[3] = outputSize;
cmdbuf[4] = IPC_Desc_Buffer(inputSize, IPC_BUFFER_R);
cmdbuf[5] = (u32) input;
cmdbuf[6] = IPC_Desc_Buffer(outputSize, IPC_BUFFER_W);
cmdbuf[7] = (u32) output;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
return cmdbuf[1];
}
Result FSDIR_Read(Handle handle, u32* entriesRead, u32 entryCount, FS_DirectoryEntry* entries)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x801,1,2); // 0x8010042
cmdbuf[1] = entryCount;
cmdbuf[2] = IPC_Desc_Buffer(entryCount * sizeof(FS_DirectoryEntry), IPC_BUFFER_W);
cmdbuf[3] = (u32) entries;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
if(entriesRead) *entriesRead = cmdbuf[2];
return cmdbuf[1];
}
Result FSDIR_Close(Handle handle)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x802,0,0); // 0x8020000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
ret = cmdbuf[1];
if(R_SUCCEEDED(ret)) ret = svcCloseHandle(handle);
return ret;
}
Result FSDIR_SetPriority(Handle handle, u32 priority)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x803,1,0); // 0x8030040
cmdbuf[1] = priority;
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
return cmdbuf[1];
}
Result FSDIR_GetPriority(Handle handle, u32* priority)
{
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x804,0,0); // 0x8040000
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(handle))) return ret;
if(priority) *priority = cmdbuf[2];
return cmdbuf[1];
}