From 1320ccdb0cf547819ea8e9db88bda017dcedf348 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 21 Feb 2023 16:04:47 -0700 Subject: [PATCH] ncm: Add ActivateFsContentStorage ncm: update bindings for 16.0.0 changes ncm: fix missing rename on GetPatchContentMetaId ncm: they broke serialization ordering by changing type alignment ncm: remove alignment on content id/placeholder id --- nx/include/switch/services/fs.h | 9 +- nx/include/switch/services/ncm.h | 9 +- nx/include/switch/services/ncm_types.h | 4 +- nx/source/services/ncm.c | 119 ++++++++++++++++++------- 4 files changed, 100 insertions(+), 41 deletions(-) diff --git a/nx/include/switch/services/fs.h b/nx/include/switch/services/fs.h index fd11c90f..f92e893e 100644 --- a/nx/include/switch/services/fs.h +++ b/nx/include/switch/services/fs.h @@ -184,9 +184,10 @@ typedef enum { } FsWriteOption; typedef enum { - FsContentStorageId_System = 0, - FsContentStorageId_User = 1, - FsContentStorageId_SdCard = 2, + FsContentStorageId_System = 0, ///< System + FsContentStorageId_User = 1, ///< User + FsContentStorageId_SdCard = 2, ///< SdCard + FsContentStorageId_System0 = 3, ///< [16.0.0+] System0 } FsContentStorageId; typedef enum { @@ -298,6 +299,8 @@ typedef enum { FsBisPartitionId_SystemProperEncryption = 32, FsBisPartitionId_SystemProperPartition = 33, FsBisPartitionId_SignedSystemPartitionOnSafeMode = 34, + FsBisPartitionId_DeviceTreeBlob = 35, + FsBisPartitionId_System0 = 36, } FsBisPartitionId; /// FileSystemType diff --git a/nx/include/switch/services/ncm.h b/nx/include/switch/services/ncm.h index 4134670f..7df2a870 100644 --- a/nx/include/switch/services/ncm.h +++ b/nx/include/switch/services/ncm.h @@ -50,6 +50,7 @@ Result ncmInactivateContentStorage(NcmStorageId storage_id); ///< [2.0.0+] Result ncmActivateContentMetaDatabase(NcmStorageId storage_id); ///< [2.0.0+] Result ncmInactivateContentMetaDatabase(NcmStorageId storage_id); ///< [2.0.0+] Result ncmInvalidateRightsIdCache(void); ///< [9.0.0+] +Result ncmActivateFsContentStorage(FsContentStorageId fs_storage_id); ///< [16.0.0+] void ncmContentStorageClose(NcmContentStorage* cs); Result ncmContentStorageGeneratePlaceHolderId(NcmContentStorage* cs, NcmPlaceHolderId* out_id); @@ -71,15 +72,15 @@ Result ncmContentStorageDisableForcibly(NcmContentStorage* cs); Result ncmContentStorageRevertToPlaceHolder(NcmContentStorage* cs, const NcmPlaceHolderId* placeholder_id, const NcmContentId* old_content_id, const NcmContentId* new_content_id); ///< [2.0.0+] Result ncmContentStorageSetPlaceHolderSize(NcmContentStorage* cs, const NcmPlaceHolderId* placeholder_id, s64 size); ///< [2.0.0+] Result ncmContentStorageReadContentIdFile(NcmContentStorage* cs, void* out_data, size_t out_data_size, const NcmContentId* content_id, s64 offset); ///< [2.0.0+] -Result ncmContentStorageGetRightsIdFromPlaceHolderId(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmPlaceHolderId* placeholder_id); ///< [2.0.0+] -Result ncmContentStorageGetRightsIdFromContentId(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmContentId* content_id); ///< [2.0.0+] +Result ncmContentStorageGetRightsIdFromPlaceHolderId(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmPlaceHolderId* placeholder_id, FsContentAttributes attr); ///< [2.0.0+] +Result ncmContentStorageGetRightsIdFromContentId(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmContentId* content_id, FsContentAttributes attr); ///< [2.0.0+] Result ncmContentStorageWriteContentForDebug(NcmContentStorage* cs, const NcmContentId* content_id, s64 offset, const void* data, size_t data_size); ///< [2.0.0+] Result ncmContentStorageGetFreeSpaceSize(NcmContentStorage* cs, s64* out_size); ///< [2.0.0+] Result ncmContentStorageGetTotalSpaceSize(NcmContentStorage* cs, s64* out_size); ///< [2.0.0+] Result ncmContentStorageFlushPlaceHolder(NcmContentStorage* cs); ///< [3.0.0+] Result ncmContentStorageGetSizeFromPlaceHolderId(NcmContentStorage* cs, s64* out_size, const NcmPlaceHolderId* placeholder_id); ///< [4.0.0+] Result ncmContentStorageRepairInvalidFileAttribute(NcmContentStorage* cs); ///< [4.0.0+] -Result ncmContentStorageGetRightsIdFromPlaceHolderIdWithCache(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmPlaceHolderId* placeholder_id, const NcmContentId* cache_content_id); ///< [8.0.0+] +Result ncmContentStorageGetRightsIdFromPlaceHolderIdWithCache(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmPlaceHolderId* placeholder_id, const NcmContentId* cache_content_id, FsContentAttributes attr); ///< [8.0.0+] Result ncmContentStorageRegisterPath(NcmContentStorage* cs, const NcmContentId* content_id, const char *path); ///< [13.0.0+] Result ncmContentStorageClearRegisteredPath(NcmContentStorage* cs); ///< [13.0.0+] @@ -96,7 +97,7 @@ Result ncmContentMetaDatabaseHas(NcmContentMetaDatabase* db, bool* out, const Nc Result ncmContentMetaDatabaseHasAll(NcmContentMetaDatabase* db, bool* out, const NcmContentMetaKey* keys, s32 count); Result ncmContentMetaDatabaseGetSize(NcmContentMetaDatabase* db, u64* out_size, const NcmContentMetaKey* key); Result ncmContentMetaDatabaseGetRequiredSystemVersion(NcmContentMetaDatabase* db, u32* out_version, const NcmContentMetaKey* key); -Result ncmContentMetaDatabaseGetPatchId(NcmContentMetaDatabase* db, u64* out_patch_id, const NcmContentMetaKey* key); +Result ncmContentMetaDatabaseGetPatchContentMetaId(NcmContentMetaDatabase* db, u64* out_patch_id, const NcmContentMetaKey* key); Result ncmContentMetaDatabaseDisableForcibly(NcmContentMetaDatabase* db); Result ncmContentMetaDatabaseLookupOrphanContent(NcmContentMetaDatabase* db, bool* out_orphaned, const NcmContentId* content_ids, s32 count); Result ncmContentMetaDatabaseCommit(NcmContentMetaDatabase* db); diff --git a/nx/include/switch/services/ncm_types.h b/nx/include/switch/services/ncm_types.h index f9ab8f4e..49a5bf9e 100644 --- a/nx/include/switch/services/ncm_types.h +++ b/nx/include/switch/services/ncm_types.h @@ -62,12 +62,12 @@ typedef enum { /// ContentId typedef struct { - alignas(4) u8 c[0x10]; ///< Id + u8 c[0x10]; ///< Id } NcmContentId; /// PlaceHolderId typedef struct { - alignas(8) Uuid uuid; ///< UUID + Uuid uuid; ///< UUID } NcmPlaceHolderId; /// ContentMetaKey diff --git a/nx/source/services/ncm.c b/nx/source/services/ncm.c index 04f8710c..18ad3ee6 100644 --- a/nx/source/services/ncm.c +++ b/nx/source/services/ncm.c @@ -43,6 +43,10 @@ static Result _ncmCmdInU8(Service* srv, u8 inval, u32 cmd_id) { return serviceDispatchIn(srv, cmd_id, inval); } +static Result _ncmCmdInU32(Service* srv, u32 inval, u32 cmd_id) { + return serviceDispatchIn(srv, cmd_id, inval); +} + static Result _ncmCmdInContentId(Service* srv, const NcmContentId* inval, u32 cmd_id) { return serviceDispatchIn(srv, cmd_id, *inval); } @@ -122,6 +126,11 @@ Result ncmInvalidateRightsIdCache(void) { return _ncmCmdNoIO(&g_ncmSrv, 13); } +Result ncmActivateFsContentStorage(FsContentStorageId fs_storage_id) { + if (!hosversionIsAtmosphere() && hosversionBefore(16,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _ncmCmdInU32(&g_ncmSrv, fs_storage_id, 15); +} + void ncmContentStorageClose(NcmContentStorage* cs) { serviceClose(&cs->s); } @@ -131,12 +140,21 @@ Result ncmContentStorageGeneratePlaceHolderId(NcmContentStorage* cs, NcmPlaceHol } Result ncmContentStorageCreatePlaceHolder(NcmContentStorage* cs, const NcmContentId* content_id, const NcmPlaceHolderId* placeholder_id, s64 size) { - const struct { - NcmContentId content_id; - NcmPlaceHolderId placeholder_id; - s64 size; - } in = { *content_id, *placeholder_id, size }; - return serviceDispatchIn(&cs->s, 1, in); + if (hosversionBefore(16,0,0)) { + const struct { + NcmContentId content_id; + NcmPlaceHolderId placeholder_id; + s64 size; + } in = { *content_id, *placeholder_id, size }; + return serviceDispatchIn(&cs->s, 1, in); + } else { + const struct { + NcmPlaceHolderId placeholder_id; + NcmContentId content_id; + s64 size; + } in = { *placeholder_id, *content_id, size }; + return serviceDispatchIn(&cs->s, 1, in); + } } Result ncmContentStorageDeletePlaceHolder(NcmContentStorage* cs, const NcmPlaceHolderId* placeholder_id) { @@ -162,11 +180,19 @@ Result ncmContentStorageWritePlaceHolder(NcmContentStorage* cs, const NcmPlaceHo } Result ncmContentStorageRegister(NcmContentStorage* cs, const NcmContentId* content_id, const NcmPlaceHolderId* placeholder_id) { - const struct { - NcmContentId content_id; - NcmPlaceHolderId placeholder_id; - } in = { *content_id, *placeholder_id }; - return serviceDispatchIn(&cs->s, 5, in); + if (hosversionBefore(16,0,0)) { + const struct { + NcmContentId content_id; + NcmPlaceHolderId placeholder_id; + } in = { *content_id, *placeholder_id }; + return serviceDispatchIn(&cs->s, 5, in); + } else { + const struct { + NcmPlaceHolderId placeholder_id; + NcmContentId content_id; + } in = { *placeholder_id, *content_id }; + return serviceDispatchIn(&cs->s, 5, in); + } } Result ncmContentStorageDelete(NcmContentStorage* cs, const NcmContentId* content_id) { @@ -238,12 +264,22 @@ Result ncmContentStorageDisableForcibly(NcmContentStorage* cs) { Result ncmContentStorageRevertToPlaceHolder(NcmContentStorage* cs, const NcmPlaceHolderId* placeholder_id, const NcmContentId* old_content_id, const NcmContentId* new_content_id) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - const struct { - NcmContentId old_content_id; - NcmContentId new_content_id; - NcmPlaceHolderId placeholder_id; - } in = { *old_content_id, *new_content_id, *placeholder_id }; - return serviceDispatchIn(&cs->s, 16, in); + + if (hosversionBefore(16,0,0)) { + const struct { + NcmContentId old_content_id; + NcmContentId new_content_id; + NcmPlaceHolderId placeholder_id; + } in = { *old_content_id, *new_content_id, *placeholder_id }; + return serviceDispatchIn(&cs->s, 16, in); + } else { + const struct { + NcmPlaceHolderId placeholder_id; + NcmContentId old_content_id; + NcmContentId new_content_id; + } in = { *placeholder_id, *old_content_id, *new_content_id }; + return serviceDispatchIn(&cs->s, 16, in); + } } Result ncmContentStorageSetPlaceHolderSize(NcmContentStorage* cs, const NcmPlaceHolderId* placeholder_id, s64 size) { @@ -267,21 +303,33 @@ Result ncmContentStorageReadContentIdFile(NcmContentStorage* cs, void* out_data, ); } -Result ncmContentStorageGetRightsIdFromPlaceHolderId(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmPlaceHolderId* placeholder_id) { +Result ncmContentStorageGetRightsIdFromPlaceHolderId(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmPlaceHolderId* placeholder_id, FsContentAttributes attr) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + const struct { + NcmPlaceHolderId placeholder_id; + u8 attr; + } in = { *placeholder_id, attr }; + if (hosversionBefore(3,0,0)) - return serviceDispatchInOut(&cs->s, 19, *placeholder_id, out_rights_id->rights_id); + return serviceDispatchInOut(&cs->s, 19, in, out_rights_id->rights_id); else - return serviceDispatchInOut(&cs->s, 19, *placeholder_id, *out_rights_id); + return serviceDispatchInOut(&cs->s, 19, in, *out_rights_id); } -Result ncmContentStorageGetRightsIdFromContentId(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmContentId* content_id) { +Result ncmContentStorageGetRightsIdFromContentId(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmContentId* content_id, FsContentAttributes attr) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); memset(out_rights_id, 0, sizeof(*out_rights_id)); + + const struct { + NcmContentId content_id; + u8 attr; + } in = { *content_id, attr }; + if (hosversionBefore(3,0,0)) - return serviceDispatchInOut(&cs->s, 20, *content_id, out_rights_id->rights_id); + return serviceDispatchInOut(&cs->s, 20, in, out_rights_id->rights_id); else - return serviceDispatchInOut(&cs->s, 20, *content_id, *out_rights_id); + return serviceDispatchInOut(&cs->s, 20, in, *out_rights_id); } Result ncmContentStorageWriteContentForDebug(NcmContentStorage* cs, const NcmContentId* content_id, s64 offset, const void* data, size_t data_size) { @@ -321,17 +369,24 @@ Result ncmContentStorageRepairInvalidFileAttribute(NcmContentStorage* cs) { return _ncmCmdNoIO(&cs->s, 26); } -Result ncmContentStorageGetRightsIdFromPlaceHolderIdWithCache(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmPlaceHolderId* placeholder_id, const NcmContentId* cache_content_id) { +Result ncmContentStorageGetRightsIdFromPlaceHolderIdWithCache(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmPlaceHolderId* placeholder_id, const NcmContentId* cache_content_id, FsContentAttributes attr) { if (hosversionBefore(8,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - const struct { - NcmContentId cache_content_id; - NcmPlaceHolderId placeholder_id; - } in = { *cache_content_id, *placeholder_id }; - if (hosversionBefore(3,0,0)) - return serviceDispatchInOut(&cs->s, 27, in, out_rights_id->rights_id); - else + if (hosversionBefore(16,0,0)) { + const struct { + NcmContentId cache_content_id; + NcmPlaceHolderId placeholder_id; + } in = { *cache_content_id, *placeholder_id }; + return serviceDispatchInOut(&cs->s, 27, in, *out_rights_id); + } else { + const struct { + NcmPlaceHolderId placeholder_id; + NcmContentId cache_content_id; + u8 attr; + } in = { *placeholder_id, *cache_content_id, attr }; + return serviceDispatchInOut(&cs->s, 27, in, *out_rights_id); + } } Result ncmContentStorageRegisterPath(NcmContentStorage* cs, const NcmContentId* content_id, const char *path) { @@ -464,7 +519,7 @@ Result ncmContentMetaDatabaseGetRequiredSystemVersion(NcmContentMetaDatabase* db return serviceDispatchInOut(&db->s, 11, *key, *out_version); } -Result ncmContentMetaDatabaseGetPatchId(NcmContentMetaDatabase* db, u64* out_patch_id, const NcmContentMetaKey* key) { +Result ncmContentMetaDatabaseGetPatchContentMetaId(NcmContentMetaDatabase* db, u64* out_patch_id, const NcmContentMetaKey* key) { return serviceDispatchInOut(&db->s, 12, *key, *out_patch_id); }