From cf91be5041cc7f9f816021d5ca5af5b7338fd89a Mon Sep 17 00:00:00 2001 From: Steven Smith Date: Thu, 28 Apr 2016 20:38:15 -0700 Subject: [PATCH] Separate information required to open an archive from the actual opened handle. --- libctru/include/3ds/services/fs.h | 48 +++++--- libctru/source/internal.h | 1 - libctru/source/ndsp/ndsp.c | 6 +- libctru/source/os-versionbin.c | 19 +-- libctru/source/romfs_dev.c | 27 ++--- libctru/source/sdmc_dev.c | 19 ++- libctru/source/services/fs.c | 185 ++++++++++++++++++------------ 7 files changed, 174 insertions(+), 131 deletions(-) diff --git a/libctru/include/3ds/services/fs.h b/libctru/include/3ds/services/fs.h index 2db8f81..f1f1189 100644 --- a/libctru/include/3ds/services/fs.h +++ b/libctru/include/3ds/services/fs.h @@ -226,7 +226,7 @@ typedef struct u8 encryptParameter[0x10]; ///< Encrypt parameter. } FS_DeviceMoveContext; -/// FS path. +/// Filesystem path data, detailing the specific target of an operation. typedef struct { FS_PathType type; ///< FS path type. @@ -234,13 +234,8 @@ typedef struct const void* data; ///< Pointer to FS path data. } FS_Path; -/// FS archive. -typedef struct -{ - u32 id; ///< Archive ID. - FS_Path lowPath; ///< FS path. - u64 handle; ///< Handle. -} FS_Archive; +/// Filesystem archive handle, providing access to a filesystem's contents. +typedef u64 FS_Archive; /// Initializes FS. Result fsInit(void); @@ -251,13 +246,25 @@ void fsExit(void); /** * @brief Sets the FSUSER session to use in the current thread. * @param session The handle of the FSUSER session to use. - * @param sdmc When true, SDMC archive commands are redirected to this session too. Otherwise the default session is used. */ -void fsUseSession(Handle session, bool sdmc); +void fsUseSession(Handle session); /// Disables the FSUSER session override in the current thread. void fsEndUseSession(void); +/** + * @brief Exempts an archive from using alternate FS session handles provided with @ref fsUseSession + * Instead, the archive will use the default FS session handle, opened with @ref srvGetSessionHandle + * @param archive Archive to exempt. + */ +void fsExemptFromSession(FS_Archive archive); + +/** + * @brief Unexempts an archive from using alternate FS session handles provided with @ref fsUseSession + * @param archive Archive to remove from the exemption list. + */ +void fsUnexemptFromSession(FS_Archive archive); + /** * @brief Creates an FS_Path instance. * @param type Type of path. @@ -299,14 +306,15 @@ Result FSUSER_Initialize(Handle session); Result FSUSER_OpenFile(Handle* out, FS_Archive archive, FS_Path path, u32 openFlags, u32 attributes); /** - * @brief Opens a file directly. + * @brief Opens a file directly, bypassing the requirement of an opened archive handle. * @param out Pointer to output the file handle to. - * @param archive Archive containing the file. - * @param path Path of the file. + * @param archiveId ID of the archive containing the file. + * @param archivePath Path of the archive containing the file. + * @param filePath Path of the file. * @param openFlags Flags to open the file with. * @param attributes Attributes of the file. */ -Result FSUSER_OpenFileDirectly(Handle* out, FS_Archive archive, FS_Path path, u32 openFlags, u32 attributes); +Result FSUSER_OpenFileDirectly(Handle* out, FS_ArchiveID archiveId, FS_Path archivePath, FS_Path filePath, u32 openFlags, u32 attributes); /** * @brief Deletes a file. @@ -340,7 +348,7 @@ Result FSUSER_DeleteDirectoryRecursively(FS_Archive archive, FS_Path path); /** * @brief Creates a file. - * @param archive Archive containing the file. + * @param archive Archive to create the file in. * @param path Path of the file. * @param attributes Attributes of the file. * @param fileSize Size of the file. @@ -349,7 +357,7 @@ Result FSUSER_CreateFile(FS_Archive archive, FS_Path path, u32 attributes, u64 f /** * @brief Creates a directory - * @param archive Archive containing the directory. + * @param archive Archive to create the directory in. * @param path Path of the directory. * @param attributes Attributes of the directory. */ @@ -374,9 +382,11 @@ Result FSUSER_OpenDirectory(Handle *out, FS_Archive archive, FS_Path path); /** * @brief Opens an archive. - * @param archive Archive to open. + * @param archive Pointer to output the opened archive to. + * @param id ID of the archive. + * @param path Path of the archive. */ -Result FSUSER_OpenArchive(FS_Archive* archive); +Result FSUSER_OpenArchive(FS_Archive* archive, FS_ArchiveID id, FS_Path path); /** * @brief Performs a control operation on an archive. @@ -393,7 +403,7 @@ Result FSUSER_ControlArchive(FS_Archive archive, FS_ArchiveAction action, void* * @brief Closes an archive. * @param archive Archive to close. */ -Result FSUSER_CloseArchive(FS_Archive* archive); +Result FSUSER_CloseArchive(FS_Archive archive); /** * @brief Gets the number of free bytes within an archive. diff --git a/libctru/source/internal.h b/libctru/source/internal.h index 65ba9a6..09316d1 100644 --- a/libctru/source/internal.h +++ b/libctru/source/internal.h @@ -26,7 +26,6 @@ typedef struct // FS session override u32 fs_magic; Handle fs_session; - bool fs_sdmc; } ThreadVars; static inline ThreadVars* getThreadVars(void) diff --git a/libctru/source/ndsp/ndsp.c b/libctru/source/ndsp/ndsp.c index 1b5fce1..867eeb5 100644 --- a/libctru/source/ndsp/ndsp.c +++ b/libctru/source/ndsp/ndsp.c @@ -398,10 +398,10 @@ static bool ndspFindAndLoadComponent(void) do { static const char dsp_filename[] = "/3ds/dspfirm.cdc"; - FS_Archive arch = { ARCHIVE_SDMC, { PATH_EMPTY, 1, (u8*)"" }, 0 }; - FS_Path path = { PATH_ASCII, sizeof(dsp_filename), (u8*)dsp_filename }; + FS_Path archPath = { PATH_EMPTY, 1, (u8*)"" }; + FS_Path filePath = { PATH_ASCII, sizeof(dsp_filename), (u8*)dsp_filename }; - rc = FSUSER_OpenFileDirectly(&rsrc, arch, path, FS_OPEN_READ, 0); + rc = FSUSER_OpenFileDirectly(&rsrc, ARCHIVE_SDMC, archPath, filePath, FS_OPEN_READ, 0); if (R_FAILED(rc)) break; u64 size = 0; diff --git a/libctru/source/os-versionbin.c b/libctru/source/os-versionbin.c index 464903d..a7fe0a5 100644 --- a/libctru/source/os-versionbin.c +++ b/libctru/source/os-versionbin.c @@ -36,13 +36,13 @@ static u32 __CVer_tidlow_regionarray[7] = { }; -static Result __read_versionbin(FS_Archive archive, FS_Path fileLowPath, OS_VersionBin *versionbin) +static Result __read_versionbin(FS_ArchiveID archiveId, FS_Path archivePath, FS_Path fileLowPath, OS_VersionBin *versionbin) { Result ret = 0; Handle filehandle = 0; FILE *f = NULL; - ret = FSUSER_OpenFileDirectly(&filehandle, archive, fileLowPath, FS_OPEN_READ, 0x0); + ret = FSUSER_OpenFileDirectly(&filehandle, archiveId, archivePath, fileLowPath, FS_OPEN_READ, 0x0); if(R_FAILED(ret))return ret; ret = romfsInitFromFile(filehandle, 0x0); @@ -72,16 +72,17 @@ Result osGetSystemVersionData(OS_VersionBin *nver_versionbin, OS_VersionBin *cve u32 archive_lowpath_data[0x10>>2]; u32 file_lowpath_data[0x14>>2]; - FS_Archive archive; + FS_ArchiveID archiveId; + FS_Path archivePath; FS_Path fileLowPath; memset(archive_lowpath_data, 0, sizeof(archive_lowpath_data)); memset(file_lowpath_data, 0, sizeof(file_lowpath_data)); - archive.id = 0x2345678a; - archive.lowPath.type = PATH_BINARY; - archive.lowPath.size = 0x10; - archive.lowPath.data = archive_lowpath_data; + archiveId = 0x2345678a; + archivePath.type = PATH_BINARY; + archivePath.size = 0x10; + archivePath.data = archive_lowpath_data; fileLowPath.type = PATH_BINARY; fileLowPath.size = 0x14; @@ -100,11 +101,11 @@ Result osGetSystemVersionData(OS_VersionBin *nver_versionbin, OS_VersionBin *cve cfguExit(); archive_lowpath_data[0] = __NVer_tidlow_regionarray[region]; - ret = __read_versionbin(archive, fileLowPath, nver_versionbin); + ret = __read_versionbin(archiveId, archivePath, fileLowPath, nver_versionbin); if(R_FAILED(ret))return ret; archive_lowpath_data[0] = __CVer_tidlow_regionarray[region]; - ret = __read_versionbin(archive, fileLowPath, cver_versionbin); + ret = __read_versionbin(archiveId, archivePath, fileLowPath, cver_versionbin); return ret; } diff --git a/libctru/source/romfs_dev.c b/libctru/source/romfs_dev.c index 7006e71..a7d0e69 100644 --- a/libctru/source/romfs_dev.c +++ b/libctru/source/romfs_dev.c @@ -121,7 +121,7 @@ typedef struct } _3DSX_Header; static Result romfsInitCommon(void); -static void romfsInitMtime(FS_Archive arch, FS_Path path); +static void romfsInitMtime(FS_ArchiveID archId, FS_Path archPath, FS_Path filePath); __attribute__((weak)) const char* __romfs_path = NULL; @@ -152,13 +152,13 @@ Result romfsInit(void) if (units >= PATH_MAX) return 4; __utf16path[units] = 0; - FS_Archive arch = { ARCHIVE_SDMC, { PATH_EMPTY, 1, (u8*)"" }, 0 }; - FS_Path path = { PATH_UTF16, (units+1)*2, (u8*)__utf16path }; + FS_Path archPath = { PATH_EMPTY, 1, (u8*)"" }; + FS_Path filePath = { PATH_UTF16, (units+1)*2, (u8*)__utf16path }; - Result rc = FSUSER_OpenFileDirectly(&romFS_file, arch, path, FS_OPEN_READ, 0); + Result rc = FSUSER_OpenFileDirectly(&romFS_file, ARCHIVE_SDMC, archPath, filePath, FS_OPEN_READ, 0); if (R_FAILED(rc)) return rc; - romfsInitMtime(arch, path); + romfsInitMtime(ARCHIVE_SDMC, archPath, filePath); _3DSX_Header hdr; if (!_romfs_read_chk(0, &hdr, sizeof(hdr))) goto _fail0; @@ -172,13 +172,13 @@ Result romfsInit(void) u8 zeros[0xC]; memset(zeros, 0, sizeof(zeros)); - FS_Archive arch = { ARCHIVE_ROMFS, { PATH_EMPTY, 1, (u8*)"" }, 0 }; - FS_Path path = { PATH_BINARY, sizeof(zeros), zeros }; + FS_Path archPath = { PATH_EMPTY, 1, (u8*)"" }; + FS_Path filePath = { PATH_BINARY, sizeof(zeros), zeros }; - Result rc = FSUSER_OpenFileDirectly(&romFS_file, arch, path, FS_OPEN_READ, 0); + Result rc = FSUSER_OpenFileDirectly(&romFS_file, ARCHIVE_ROMFS, archPath, filePath, FS_OPEN_READ, 0); if (R_FAILED(rc)) return rc; - romfsInitMtime(arch, path); + romfsInitMtime(ARCHIVE_ROMFS, archPath, filePath); } return romfsInitCommon(); @@ -237,20 +237,21 @@ _fail0: return 10; } -static void romfsInitMtime(FS_Archive arch, FS_Path path) +static void romfsInitMtime(FS_ArchiveID archId, FS_Path archPath, FS_Path filePath) { u64 mtime; + FS_Archive arch; Result rc; romFS_mtime = time(NULL); - rc = FSUSER_OpenArchive(&arch); + rc = FSUSER_OpenArchive(&arch, archId, archPath); if (R_FAILED(rc)) return; rc = FSUSER_ControlArchive(arch, ARCHIVE_ACTION_GET_TIMESTAMP, - (void*)path.data, path.size, + (void*)filePath.data, filePath.size, &mtime, sizeof(mtime)); - FSUSER_CloseArchive(&arch); + FSUSER_CloseArchive(arch); if (R_FAILED(rc)) return; diff --git a/libctru/source/sdmc_dev.c b/libctru/source/sdmc_dev.c index fa9af99..fbc6df8 100644 --- a/libctru/source/sdmc_dev.c +++ b/libctru/source/sdmc_dev.c @@ -91,16 +91,7 @@ sdmc_devoptab = }; /*! SDMC archive handle */ -static FS_Archive sdmcArchive = -{ - .id = ARCHIVE_SDMC, - .lowPath = - { - .type = PATH_EMPTY, - .size = 1, - .data = (u8*)"", - }, -}; +static FS_Archive sdmcArchive; /*! @endcond */ @@ -216,14 +207,17 @@ Result sdmcInit(void) ssize_t units; uint32_t code; char *p; + FS_Path sdmcPath = { PATH_EMPTY, 1, (u8*)"" }; Result rc = 0; if(sdmcInitialised) return rc; - rc = FSUSER_OpenArchive(&sdmcArchive); + + rc = FSUSER_OpenArchive(&sdmcArchive, ARCHIVE_SDMC, sdmcPath); if(R_SUCCEEDED(rc)) { + fsExemptFromSession(sdmcArchive); int dev = AddDevice(&sdmc_devoptab); @@ -296,9 +290,10 @@ Result sdmcExit(void) if(!sdmcInitialised) return rc; - rc = FSUSER_CloseArchive(&sdmcArchive); + rc = FSUSER_CloseArchive(sdmcArchive); if(R_SUCCEEDED(rc)) { + fsUnexemptFromSession(sdmcArchive); RemoveDevice("sdmc:"); sdmcInitialised = false; } diff --git a/libctru/source/services/fs.c b/libctru/source/services/fs.c index fb622f3..3470283 100644 --- a/libctru/source/services/fs.c +++ b/libctru/source/services/fs.c @@ -9,20 +9,30 @@ #include <3ds/env.h> #include "../internal.h" +#define FS_MAX_EXEMPT_ARCHIVE_HANDLES 16 + static Handle fsuHandle; static int fsuRefCount; -static Handle fsSessionForArchive(FS_ArchiveID arch) +static FS_Archive fsExemptArchives[FS_MAX_EXEMPT_ARCHIVE_HANDLES]; + +static Handle fsSession(void) { ThreadVars* tv = getThreadVars(); - if (tv->fs_magic == FS_OVERRIDE_MAGIC && (arch != ARCHIVE_SDMC || tv->fs_sdmc)) + if (tv->fs_magic == FS_OVERRIDE_MAGIC) return tv->fs_session; return fsuHandle; } -static Handle fsSession(void) +static Handle fsSessionForArchive(FS_Archive archive) { - return fsSessionForArchive(0); + for (int i = 0; i < FS_MAX_EXEMPT_ARCHIVE_HANDLES; i++) + { + if (fsExemptArchives[i] == archive) + return fsuHandle; + } + + return fsSession(); } Result fsInit(void) @@ -48,12 +58,11 @@ void fsExit(void) svcCloseHandle(fsuHandle); } -void fsUseSession(Handle session, bool sdmc) +void fsUseSession(Handle session) { ThreadVars* tv = getThreadVars(); tv->fs_magic = FS_OVERRIDE_MAGIC; tv->fs_session = session; - tv->fs_sdmc = sdmc; } void fsEndUseSession(void) @@ -62,6 +71,34 @@ void fsEndUseSession(void) 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 }; @@ -129,8 +166,8 @@ Result FSUSER_OpenFile(Handle* out, FS_Archive archive, FS_Path path, u32 openFl cmdbuf[0] = IPC_MakeHeader(0x802,7,2); // 0x80201C2 cmdbuf[1] = 0; - cmdbuf[2] = (u32) archive.handle; - cmdbuf[3] = (u32) (archive.handle >> 32); + cmdbuf[2] = (u32) archive; + cmdbuf[3] = (u32) (archive >> 32); cmdbuf[4] = path.type; cmdbuf[5] = path.size; cmdbuf[6] = openFlags; @@ -139,33 +176,33 @@ Result FSUSER_OpenFile(Handle* out, FS_Archive archive, FS_Path path, u32 openFl cmdbuf[9] = (u32) path.data; Result ret = 0; - if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive.id)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret; if(out) *out = cmdbuf[3]; return cmdbuf[1]; } -Result FSUSER_OpenFileDirectly(Handle* out, FS_Archive archive, FS_Path path, u32 openFlags, u32 attributes) +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] = archive.id; - cmdbuf[3] = archive.lowPath.type; - cmdbuf[4] = archive.lowPath.size; - cmdbuf[5] = path.type; - cmdbuf[6] = path.size; + 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(archive.lowPath.size, 2); - cmdbuf[10] = (u32) archive.lowPath.data; - cmdbuf[11] = IPC_Desc_StaticBuffer(path.size, 0); - cmdbuf[12] = (u32) path.data; + 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(fsSessionForArchive(archive.id)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret; if(out) *out = cmdbuf[3]; @@ -178,15 +215,15 @@ Result FSUSER_DeleteFile(FS_Archive archive, FS_Path path) cmdbuf[0] = IPC_MakeHeader(0x804,5,2); // 0x8040142 cmdbuf[1] = 0; - cmdbuf[2] = (u32) archive.handle; - cmdbuf[3] = (u32) (archive.handle >> 32); + 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.id)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret; return cmdbuf[1]; } @@ -197,12 +234,12 @@ Result FSUSER_RenameFile(FS_Archive srcArchive, FS_Path srcPath, FS_Archive dstA cmdbuf[0] = IPC_MakeHeader(0x805,9,4); // 0x8050244 cmdbuf[1] = 0; - cmdbuf[2] = (u32) srcArchive.handle; - cmdbuf[3] = (u32) (srcArchive.handle >> 32); + cmdbuf[2] = (u32) srcArchive; + cmdbuf[3] = (u32) (srcArchive >> 32); cmdbuf[4] = srcPath.type; cmdbuf[5] = srcPath.size; - cmdbuf[6] = (u32) dstArchive.handle; - cmdbuf[7] = (u32) (dstArchive.handle >> 32); + 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); @@ -211,7 +248,7 @@ Result FSUSER_RenameFile(FS_Archive srcArchive, FS_Path srcPath, FS_Archive dstA cmdbuf[13] = (u32) dstPath.data; Result ret = 0; - if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(srcArchive.id)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(srcArchive)))) return ret; return cmdbuf[1]; } @@ -222,15 +259,15 @@ Result FSUSER_DeleteDirectory(FS_Archive archive, FS_Path path) cmdbuf[0] = IPC_MakeHeader(0x806,5,2); // 0x8060142 cmdbuf[1] = 0; - cmdbuf[2] = (u32) archive.handle; - cmdbuf[3] = (u32) (archive.handle >> 32); + 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.id)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret; return cmdbuf[1]; } @@ -241,15 +278,15 @@ Result FSUSER_DeleteDirectoryRecursively(FS_Archive archive, FS_Path path) cmdbuf[0] = IPC_MakeHeader(0x807,5,2); // 0x8070142 cmdbuf[1] = 0; - cmdbuf[2] = (u32) archive.handle; - cmdbuf[3] = (u32) (archive.handle >> 32); + 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.id)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret; return cmdbuf[1]; } @@ -260,8 +297,8 @@ Result FSUSER_CreateFile(FS_Archive archive, FS_Path path, u32 attributes, u64 f cmdbuf[0] = IPC_MakeHeader(0x808,8,2); // 0x8080202 cmdbuf[1] = 0; - cmdbuf[2] = (u32) archive.handle; - cmdbuf[3] = (u32) (archive.handle >> 32); + cmdbuf[2] = (u32) archive; + cmdbuf[3] = (u32) (archive >> 32); cmdbuf[4] = path.type; cmdbuf[5] = path.size; cmdbuf[6] = attributes; @@ -271,7 +308,7 @@ Result FSUSER_CreateFile(FS_Archive archive, FS_Path path, u32 attributes, u64 f cmdbuf[10] = (u32) path.data; Result ret = 0; - if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive.id)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret; return cmdbuf[1]; } @@ -282,8 +319,8 @@ Result FSUSER_CreateDirectory(FS_Archive archive, FS_Path path, u32 attributes) cmdbuf[0] = IPC_MakeHeader(0x809,6,2); // 0x8090182 cmdbuf[1] = 0; - cmdbuf[2] = (u32) archive.handle; - cmdbuf[3] = (u32) (archive.handle >> 32); + cmdbuf[2] = (u32) archive; + cmdbuf[3] = (u32) (archive >> 32); cmdbuf[4] = path.type; cmdbuf[5] = path.size; cmdbuf[6] = attributes; @@ -291,7 +328,7 @@ Result FSUSER_CreateDirectory(FS_Archive archive, FS_Path path, u32 attributes) cmdbuf[8] = (u32) path.data; Result ret = 0; - if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive.id)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret; return cmdbuf[1]; } @@ -302,12 +339,12 @@ Result FSUSER_RenameDirectory(FS_Archive srcArchive, FS_Path srcPath, FS_Archive cmdbuf[0] = IPC_MakeHeader(0x80A,9,4); // 0x80A0244 cmdbuf[1] = 0; - cmdbuf[2] = (u32) srcArchive.handle; - cmdbuf[3] = (u32) (srcArchive.handle >> 32); + cmdbuf[2] = (u32) srcArchive; + cmdbuf[3] = (u32) (srcArchive >> 32); cmdbuf[4] = srcPath.type; cmdbuf[5] = srcPath.size; - cmdbuf[6] = (u32) dstArchive.handle; - cmdbuf[7] = (u32) (dstArchive.handle >> 32); + 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); @@ -316,7 +353,7 @@ Result FSUSER_RenameDirectory(FS_Archive srcArchive, FS_Path srcPath, FS_Archive cmdbuf[13] = (u32) dstPath.data; Result ret = 0; - if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(srcArchive.id)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(srcArchive)))) return ret; return cmdbuf[1]; } @@ -326,38 +363,38 @@ 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.handle; - cmdbuf[2] = (u32) (archive.handle >> 32); + 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.id)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret; if(out) *out = cmdbuf[3]; return cmdbuf[1]; } -Result FSUSER_OpenArchive(FS_Archive* archive) +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] = archive->id; - cmdbuf[2] = archive->lowPath.type; - cmdbuf[3] = archive->lowPath.size; - cmdbuf[4] = IPC_Desc_StaticBuffer(archive->lowPath.size, 0); - cmdbuf[5] = (u32) archive->lowPath.data; + 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(fsSessionForArchive(archive->id)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret; - archive->handle = cmdbuf[2] | ((u64) cmdbuf[3] << 32); + if(archive) *archive = cmdbuf[2] | ((u64) cmdbuf[3] << 32); return cmdbuf[1]; } @@ -367,8 +404,8 @@ Result FSUSER_ControlArchive(FS_Archive archive, FS_ArchiveAction action, void* u32 *cmdbuf = getThreadCommandBuffer(); cmdbuf[0] = IPC_MakeHeader(0x80D,5,4); // 0x80D0144 - cmdbuf[1] = (u32) archive.handle; - cmdbuf[2] = (u32) (archive.handle >> 32); + cmdbuf[1] = (u32) archive; + cmdbuf[2] = (u32) (archive >> 32); cmdbuf[3] = action; cmdbuf[4] = inputSize; cmdbuf[5] = outputSize; @@ -378,23 +415,23 @@ Result FSUSER_ControlArchive(FS_Archive archive, FS_ArchiveAction action, void* cmdbuf[9] = (u32) output; Result ret = 0; - if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive.id)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret; return cmdbuf[1]; } -Result FSUSER_CloseArchive(FS_Archive* archive) +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->handle; - cmdbuf[2] = (u32) (archive->handle >> 32); + cmdbuf[1] = (u32) archive; + cmdbuf[2] = (u32) (archive >> 32); Result ret = 0; - if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive->id)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret; return cmdbuf[1]; } @@ -404,11 +441,11 @@ Result FSUSER_GetFreeBytes(u64* freeBytes, FS_Archive archive) u32 *cmdbuf = getThreadCommandBuffer(); cmdbuf[0] = IPC_MakeHeader(0x812,2,0); // 0x8120080 - cmdbuf[1] = (u32) archive.handle; - cmdbuf[2] = (u32) (archive.handle >> 32); + cmdbuf[1] = (u32) archive; + cmdbuf[2] = (u32) (archive >> 32); Result ret = 0; - if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive.id)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret; if(freeBytes) *freeBytes = cmdbuf[2] | ((u64) cmdbuf[3] << 32); @@ -436,7 +473,7 @@ Result FSUSER_GetSdmcArchiveResource(FS_ArchiveResource* archiveResource) cmdbuf[0] = IPC_MakeHeader(0x814,0,0); // 0x8140000 Result ret = 0; - if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(ARCHIVE_SDMC)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret; if(archiveResource) memcpy(archiveResource, &cmdbuf[2], sizeof(FS_ArchiveResource)); @@ -1037,7 +1074,7 @@ Result FSUSER_GetFormatInfo(u32* totalSize, u32* directories, u32* files, bool* cmdbuf[5] = (u32) path.data; Result ret = 0; - if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archiveId)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret; if(totalSize) *totalSize = cmdbuf[2]; if(directories) *directories = cmdbuf[3]; @@ -1353,12 +1390,12 @@ Result FSUSER_SetArchivePriority(FS_Archive archive, u32 priority) u32 *cmdbuf = getThreadCommandBuffer(); cmdbuf[0] = IPC_MakeHeader(0x85A,3,0); // 0x85A00C0 - cmdbuf[1] = (u32) archive.handle; - cmdbuf[2] = (u32) (archive.handle >> 32); + cmdbuf[1] = (u32) archive; + cmdbuf[2] = (u32) (archive >> 32); cmdbuf[3] = priority; Result ret = 0; - if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret; return cmdbuf[1]; } @@ -1368,11 +1405,11 @@ Result FSUSER_GetArchivePriority(u32* priority, FS_Archive archive) u32 *cmdbuf = getThreadCommandBuffer(); cmdbuf[0] = IPC_MakeHeader(0x85B,2,0); // 0x85B0080 - cmdbuf[1] = (u32) archive.handle; - cmdbuf[2] = (u32) (archive.handle >> 32); + cmdbuf[1] = (u32) archive; + cmdbuf[2] = (u32) (archive >> 32); Result ret = 0; - if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive.id)))) return ret; + if(R_FAILED(ret = svcSendSyncRequest(fsSessionForArchive(archive)))) return ret; if(priority) *priority = cmdbuf[2];