diff --git a/nx/include/switch/services/ncm.h b/nx/include/switch/services/ncm.h index cc926206..73c47bf6 100644 --- a/nx/include/switch/services/ncm.h +++ b/nx/include/switch/services/ncm.h @@ -58,10 +58,10 @@ typedef enum { NcmContentInstallType_Unknown = 7, ///< Unknown } NcmContentInstallType; -/// NcaId +/// ContentId typedef struct { u8 c[0x10]; ///< Id -} NcmNcaId; +} NcmContentId; /// ContentMetaKey typedef struct { @@ -80,7 +80,7 @@ typedef struct { /// ContentInfo typedef struct { - NcmNcaId content_id; ///< \ref NcmNcaId + NcmContentId content_id; ///< \ref NcmContentId u8 size[0x6]; ///< Content size. u8 content_type; ///< \ref NcmContentType. u8 id_offset; ///< Offset of this content. Unused by most applications. @@ -125,6 +125,13 @@ typedef struct { u32 extended_data_size; ///< Size of the extended data after NcmContentInfos and NcmContentMetaInfos. } NcmSystemUpdateMetaExtendedHeader; +/// RightsId +typedef struct { + FsRightsId rights_id; + u32 key_generation; ///< [3.0.0+] + u8 pad[7]; ///< [3.0.0+] +} NcmRightsId; + Result ncmInitialize(void); void ncmExit(void); Service* ncmGetServiceSession(void); @@ -145,54 +152,54 @@ Result ncmInactivateContentMetaDatabase(FsStorageId storage_id); ///< [2.0.0+] Result ncmInvalidateRightsIdCache(void); ///< [9.0.0+] void ncmContentStorageClose(NcmContentStorage* cs); -Result ncmContentStorageGeneratePlaceHolderId(NcmContentStorage* cs, NcmNcaId* out_id); -Result ncmContentStorageCreatePlaceHolder(NcmContentStorage* cs, const NcmNcaId* content_id, const NcmNcaId* placeholder_id, u64 size); -Result ncmContentStorageDeletePlaceHolder(NcmContentStorage* cs, const NcmNcaId* placeholder_id); -Result ncmContentStorageHasPlaceHolder(NcmContentStorage* cs, bool* out, const NcmNcaId* placeholder_id); -Result ncmContentStorageWritePlaceHolder(NcmContentStorage* cs, const NcmNcaId* placeholder_id, u64 offset, const void* data, size_t data_size); -Result ncmContentStorageRegister(NcmContentStorage* cs, const NcmNcaId* content_id, const NcmNcaId* placeholder_id); -Result ncmContentStorageDelete(NcmContentStorage* cs, const NcmNcaId* content_id); -Result ncmContentStorageHas(NcmContentStorage* cs, bool* out, const NcmNcaId* content_id); -Result ncmContentStorageGetPath(NcmContentStorage* cs, char* out_path, size_t out_size, const NcmNcaId* content_id); -Result ncmContentStorageGetPlaceHolderPath(NcmContentStorage* cs, const char* out_path, size_t out_size, const NcmNcaId* placeholder_id); +Result ncmContentStorageGeneratePlaceHolderId(NcmContentStorage* cs, NcmContentId* out_id); +Result ncmContentStorageCreatePlaceHolder(NcmContentStorage* cs, const NcmContentId* content_id, const NcmContentId* placeholder_id, u64 size); +Result ncmContentStorageDeletePlaceHolder(NcmContentStorage* cs, const NcmContentId* placeholder_id); +Result ncmContentStorageHasPlaceHolder(NcmContentStorage* cs, bool* out, const NcmContentId* placeholder_id); +Result ncmContentStorageWritePlaceHolder(NcmContentStorage* cs, const NcmContentId* placeholder_id, u64 offset, const void* data, size_t data_size); +Result ncmContentStorageRegister(NcmContentStorage* cs, const NcmContentId* content_id, const NcmContentId* placeholder_id); +Result ncmContentStorageDelete(NcmContentStorage* cs, const NcmContentId* content_id); +Result ncmContentStorageHas(NcmContentStorage* cs, bool* out, const NcmContentId* content_id); +Result ncmContentStorageGetPath(NcmContentStorage* cs, char* out_path, size_t out_size, const NcmContentId* content_id); +Result ncmContentStorageGetPlaceHolderPath(NcmContentStorage* cs, char* out_path, size_t out_size, const NcmContentId* placeholder_id); Result ncmContentStorageCleanupAllPlaceHolder(NcmContentStorage* cs); -Result ncmContentStorageListPlaceHolder(NcmContentStorage* cs, NcmNcaId* out_ids, size_t out_ids_size, u32* out_count); -Result ncmContentStorageGetContentCount(NcmContentStorage* cs, u32* out_count); -Result ncmContentStorageListContentId(NcmContentStorage* cs, NcmNcaId* out_ids, size_t out_ids_size, u32* out_count, u32 start_offset); -Result ncmContentStorageGetSizeFromContentId(NcmContentStorage* cs, u64* out_size, const NcmNcaId* content_id); +Result ncmContentStorageListPlaceHolder(NcmContentStorage* cs, NcmContentId* out_ids, s32 count, s32* out_count); +Result ncmContentStorageGetContentCount(NcmContentStorage* cs, s32* out_count); +Result ncmContentStorageListContentId(NcmContentStorage* cs, NcmContentId* out_ids, s32 count, s32* out_count, s32 start_offset); +Result ncmContentStorageGetSizeFromContentId(NcmContentStorage* cs, s64* out_size, const NcmContentId* content_id); Result ncmContentStorageDisableForcibly(NcmContentStorage* cs); -Result ncmContentStorageRevertToPlaceHolder(NcmContentStorage* cs, const NcmNcaId* placeholder_id, const NcmNcaId* old_content_id, const NcmNcaId* new_content_id); ///< [2.0.0+] -Result ncmContentStorageSetPlaceHolderSize(NcmContentStorage* cs, const NcmNcaId* placeholder_id, u64 size); ///< [2.0.0+] -Result ncmContentStorageReadContentIdFile(NcmContentStorage* cs, void* out_data, size_t out_data_size, const NcmNcaId* content_id, u64 offset); ///< [2.0.0+] -Result ncmContentStorageGetRightsIdFromPlaceHolderId(NcmContentStorage* cs, FsRightsId* out_rights_id, u32* out_key_generation, const NcmNcaId* placeholder_id); ///< [2.0.0+] -Result ncmContentStorageGetRightsIdFromContentId(NcmContentStorage* cs, FsRightsId* out_rights_id, u32* out_key_generation, const NcmNcaId* content_id); ///< [2.0.0+] -Result ncmContentStorageWriteContentForDebug(NcmContentStorage* cs, const NcmNcaId* content_id, u64 offset, const void* data, size_t data_size); ///< [2.0.0+] -Result ncmContentStorageGetFreeSpaceSize(NcmContentStorage* cs, u64* out_size); ///< [2.0.0+] -Result ncmContentStorageGetTotalSpaceSize(NcmContentStorage* cs, u64* out_size); ///< [2.0.0+] +Result ncmContentStorageRevertToPlaceHolder(NcmContentStorage* cs, const NcmContentId* placeholder_id, const NcmContentId* old_content_id, const NcmContentId* new_content_id); ///< [2.0.0+] +Result ncmContentStorageSetPlaceHolderSize(NcmContentStorage* cs, const NcmContentId* 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 NcmContentId* placeholder_id); ///< [2.0.0+] +Result ncmContentStorageGetRightsIdFromContentId(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmContentId* content_id); ///< [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, u64* out_size, const NcmNcaId* placeholder_id); ///< [4.0.0+] +Result ncmContentStorageGetSizeFromPlaceHolderId(NcmContentStorage* cs, s64* out_size, const NcmContentId* placeholder_id); ///< [4.0.0+] Result ncmContentStorageRepairInvalidFileAttribute(NcmContentStorage* cs); ///< [4.0.0+] -Result ncmContentStorageGetRightsIdFromPlaceHolderIdWithCache(NcmContentStorage* cs, FsRightsId* out_rights_id, u32* out_key_generation, const NcmNcaId* placeholder_id, const NcmNcaId* cache_content_id); ///< [8.0.0+] +Result ncmContentStorageGetRightsIdFromPlaceHolderIdWithCache(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmContentId* placeholder_id, const NcmContentId* cache_content_id); ///< [8.0.0+] void ncmContentMetaDatabaseClose(NcmContentMetaDatabase* db); Result ncmContentMetaDatabaseSet(NcmContentMetaDatabase* db, const NcmContentMetaKey* key, const void* data, u64 data_size); Result ncmContentMetaDatabaseGet(NcmContentMetaDatabase* db, const NcmContentMetaKey* key, u64* out_size, void* out_data, u64 out_data_size); Result ncmContentMetaDatabaseRemove(NcmContentMetaDatabase* db, const NcmContentMetaKey *key); -Result ncmContentMetaDatabaseGetContentIdByType(NcmContentMetaDatabase* db, NcmNcaId* out_content_id, const NcmContentMetaKey* key, NcmContentType type); -Result ncmContentMetaDatabaseListContentInfo(NcmContentMetaDatabase* db, u32* out_entries_written, NcmContentInfo* out_info, size_t out_info_size, const NcmContentMetaKey* key, u32 start_index); -Result ncmContentMetaDatabaseList(NcmContentMetaDatabase* db, u32* out_entries_total, u32* out_entries_written, NcmContentMetaKey* out_keys, size_t out_keys_size, NcmContentMetaType meta_type, u64 application_title_id, u64 title_id_min, u64 title_id_max, NcmContentInstallType install_type); +Result ncmContentMetaDatabaseGetContentIdByType(NcmContentMetaDatabase* db, NcmContentId* out_content_id, const NcmContentMetaKey* key, NcmContentType type); +Result ncmContentMetaDatabaseListContentInfo(NcmContentMetaDatabase* db, s32* out_entries_written, NcmContentInfo* out_info, s32 count, const NcmContentMetaKey* key, s32 start_index); +Result ncmContentMetaDatabaseList(NcmContentMetaDatabase* db, s32* out_entries_total, s32* out_entries_written, NcmContentMetaKey* out_keys, s32 count, NcmContentMetaType meta_type, u64 application_title_id, u64 title_id_min, u64 title_id_max, NcmContentInstallType install_type); Result ncmContentMetaDatabaseGetLatestContentMetaKey(NcmContentMetaDatabase* db, NcmContentMetaKey* out_key, u64 title_id); -Result ncmContentMetaDatabaseListApplication(NcmContentMetaDatabase* db, u32* out_entries_total, u32* out_entries_written, NcmApplicationContentMetaKey* out_keys, size_t out_keys_size, NcmContentMetaType meta_type); +Result ncmContentMetaDatabaseListApplication(NcmContentMetaDatabase* db, s32* out_entries_total, s32* out_entries_written, NcmApplicationContentMetaKey* out_keys, s32 count, NcmContentMetaType meta_type); Result ncmContentMetaDatabaseHas(NcmContentMetaDatabase* db, bool* out, const NcmContentMetaKey* key); -Result ncmContentMetaDatabaseHasAll(NcmContentMetaDatabase* db, bool* out, const NcmContentMetaKey* keys, size_t keys_size); +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, u64* out_version, 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 ncmContentMetaDatabaseDisableForcibly(NcmContentMetaDatabase* db); -Result ncmContentMetaDatabaseLookupOrphanContent(NcmContentMetaDatabase* db, bool* out_orphaned, size_t out_orphaned_size, const NcmNcaId* content_ids, size_t content_ids_size); +Result ncmContentMetaDatabaseLookupOrphanContent(NcmContentMetaDatabase* db, bool* out_orphaned, const NcmContentId* content_ids, s32 count); Result ncmContentMetaDatabaseCommit(NcmContentMetaDatabase* db); -Result ncmContentMetaDatabaseHasContent(NcmContentMetaDatabase* db, bool* out, const NcmContentMetaKey* key, const NcmNcaId* content_id); -Result ncmContentMetaDatabaseListContentMetaInfo(NcmContentMetaDatabase* db, u32* out_entries_written, void* out_meta_info, size_t out_meta_info_size, const NcmContentMetaKey* key, u32 start_index); +Result ncmContentMetaDatabaseHasContent(NcmContentMetaDatabase* db, bool* out, const NcmContentMetaKey* key, const NcmContentId* content_id); +Result ncmContentMetaDatabaseListContentMetaInfo(NcmContentMetaDatabase* db, s32* out_entries_written, void* out_meta_info, s32 count, const NcmContentMetaKey* key, s32 start_index); Result ncmContentMetaDatabaseGetAttributes(NcmContentMetaDatabase* db, const NcmContentMetaKey* key, u8* out); -Result ncmContentMetaDatabaseGetRequiredApplicationVersion(NcmContentMetaDatabase* db, u64* out_version, const NcmContentMetaKey* key); ///< [2.0.0+] -Result ncmContentMetaDatabaseGetContentIdByTypeAndIdOffset(NcmContentMetaDatabase* db, NcmNcaId* out_content_id, const NcmContentMetaKey* key, NcmContentType type, u8 id_offset); ///< [5.0.0+] +Result ncmContentMetaDatabaseGetRequiredApplicationVersion(NcmContentMetaDatabase* db, u32* out_version, const NcmContentMetaKey* key); ///< [2.0.0+] +Result ncmContentMetaDatabaseGetContentIdByTypeAndIdOffset(NcmContentMetaDatabase* db, NcmContentId* out_content_id, const NcmContentMetaKey* key, NcmContentType type, u8 id_offset); ///< [5.0.0+] diff --git a/nx/source/services/ncm.c b/nx/source/services/ncm.c index 4c18b354..778064df 100644 --- a/nx/source/services/ncm.c +++ b/nx/source/services/ncm.c @@ -27,7 +27,7 @@ static Result _ncmGetInterfaceInU8(Service* srv_out, u32 cmd_id, u8 inval) { ); } -static Result _ncmCmdNoIo(Service* srv, u32 cmd_id) { +static Result _ncmCmdNoIO(Service* srv, u32 cmd_id) { return serviceDispatch(srv, cmd_id); } @@ -35,7 +35,7 @@ static Result _ncmCmdNoInOutU64(Service* srv, u32 cmd_id, u64* outval) { return serviceDispatchOut(srv, cmd_id, *outval); } -static Result _ncmCmdOutNcaId(Service* srv, u32 cmd_id, NcmNcaId* outval) { +static Result _ncmCmdOutContentId(Service* srv, u32 cmd_id, NcmContentId* outval) { return serviceDispatchOut(srv, cmd_id, *outval); } @@ -43,11 +43,11 @@ static Result _ncmCmdInU8(Service* srv, u32 cmd_id, u8 inval) { return serviceDispatchIn(srv, cmd_id, inval); } -static Result _ncmCmdInNcaId(Service* srv, u32 cmd_id, const NcmNcaId* inval) { +static Result _ncmCmdInContentId(Service* srv, u32 cmd_id, const NcmContentId* inval) { return serviceDispatchIn(srv, cmd_id, *inval); } -static Result _ncmCmdInNcaIdOutU64(Service* srv, u32 cmd_id, const NcmNcaId* inval, u64* outval) { +static Result _ncmCmdInContentIdOutU64(Service* srv, u32 cmd_id, const NcmContentId* inval, u64* outval) { return serviceDispatchInOut(srv, cmd_id, *inval, *outval); } @@ -111,37 +111,40 @@ Result ncmInactivateContentMetaDatabase(FsStorageId storage_id) { Result ncmInvalidateRightsIdCache(void) { if (hosversionBefore(9,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _ncmCmdNoIo(&g_ncmSrv, 13); + return _ncmCmdNoIO(&g_ncmSrv, 13); } void ncmContentStorageClose(NcmContentStorage* cs) { serviceClose(&cs->s); } -Result ncmContentStorageGeneratePlaceHolderId(NcmContentStorage* cs, NcmNcaId* out_id) { - return _ncmCmdOutNcaId(&cs->s, 0, out_id); +Result ncmContentStorageGeneratePlaceHolderId(NcmContentStorage* cs, NcmContentId* out_id) { + return _ncmCmdOutContentId(&cs->s, 0, out_id); } -Result ncmContentStorageCreatePlaceHolder(NcmContentStorage* cs, const NcmNcaId* content_id, const NcmNcaId* placeholder_id, u64 size) { +Result ncmContentStorageCreatePlaceHolder(NcmContentStorage* cs, const NcmContentId* content_id, const NcmContentId* placeholder_id, u64 size) { const struct { - NcmNcaId content_id; - NcmNcaId placeholder_id; + NcmContentId content_id; + NcmContentId placeholder_id; u64 size; } in = { *content_id, *placeholder_id, size }; return serviceDispatchIn(&cs->s, 1, in); } -Result ncmContentStorageDeletePlaceHolder(NcmContentStorage* cs, const NcmNcaId* placeholder_id) { - return _ncmCmdInNcaId(&cs->s, 2, placeholder_id); +Result ncmContentStorageDeletePlaceHolder(NcmContentStorage* cs, const NcmContentId* placeholder_id) { + return _ncmCmdInContentId(&cs->s, 2, placeholder_id); } -Result ncmContentStorageHasPlaceHolder(NcmContentStorage* cs, bool* out, const NcmNcaId* placeholder_id) { - return serviceDispatchInOut(&cs->s, 3, *placeholder_id, *out); +Result ncmContentStorageHasPlaceHolder(NcmContentStorage* cs, bool* out, const NcmContentId* placeholder_id) { + u8 tmp=0; + Result rc = serviceDispatchInOut(&cs->s, 3, *placeholder_id, tmp); + if (R_SUCCEEDED(rc) && out) *out = tmp & 1; + return rc; } -Result ncmContentStorageWritePlaceHolder(NcmContentStorage* cs, const NcmNcaId* placeholder_id, u64 offset, const void* data, size_t data_size) { +Result ncmContentStorageWritePlaceHolder(NcmContentStorage* cs, const NcmContentId* placeholder_id, u64 offset, const void* data, size_t data_size) { const struct { - NcmNcaId placeholder_id; + NcmContentId placeholder_id; u64 offset; } in = { *placeholder_id, offset }; return serviceDispatchIn(&cs->s, 4, in, @@ -150,90 +153,105 @@ Result ncmContentStorageWritePlaceHolder(NcmContentStorage* cs, const NcmNcaId* ); } -Result ncmContentStorageRegister(NcmContentStorage* cs, const NcmNcaId* content_id, const NcmNcaId* placeholder_id) { +Result ncmContentStorageRegister(NcmContentStorage* cs, const NcmContentId* content_id, const NcmContentId* placeholder_id) { const struct { - NcmNcaId content_id; - NcmNcaId placeholder_id; + NcmContentId content_id; + NcmContentId placeholder_id; } in = { *content_id, *placeholder_id }; return serviceDispatchIn(&cs->s, 5, in); } -Result ncmContentStorageDelete(NcmContentStorage* cs, const NcmNcaId* content_id) { - return _ncmCmdInNcaId(&cs->s, 6, content_id); +Result ncmContentStorageDelete(NcmContentStorage* cs, const NcmContentId* content_id) { + return _ncmCmdInContentId(&cs->s, 6, content_id); } -Result ncmContentStorageHas(NcmContentStorage* cs, bool* out, const NcmNcaId* content_id) { - return serviceDispatchInOut(&cs->s, 7, *content_id, *out); +Result ncmContentStorageHas(NcmContentStorage* cs, bool* out, const NcmContentId* content_id) { + u8 tmp=0; + Result rc = serviceDispatchInOut(&cs->s, 7, *content_id, tmp); + if (R_SUCCEEDED(rc) && out) *out = tmp & 1; + return rc; } -Result ncmContentStorageGetPath(NcmContentStorage* cs, char* out_path, size_t out_size, const NcmNcaId* content_id) { - return serviceDispatchIn(&cs->s, 8, *content_id, +Result ncmContentStorageGetPath(NcmContentStorage* cs, char* out_path, size_t out_size, const NcmContentId* content_id) { + char tmpbuf[0x300]={0}; + Result rc = serviceDispatchIn(&cs->s, 8, *content_id, .buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_Out }, - .buffers = { { out_path, out_size } }, + .buffers = { { tmpbuf, sizeof(tmpbuf) } }, ); + if (R_SUCCEEDED(rc) && out_path) { + strncpy(out_path, tmpbuf, out_size-1); + out_path[out_size-1] = 0; + } + return rc; } -Result ncmContentStorageGetPlaceHolderPath(NcmContentStorage* cs, const char* out_path, size_t out_size, const NcmNcaId* placeholder_id) { - return serviceDispatchIn(&cs->s, 9, *placeholder_id, +Result ncmContentStorageGetPlaceHolderPath(NcmContentStorage* cs, char* out_path, size_t out_size, const NcmContentId* placeholder_id) { + char tmpbuf[0x300]={0}; + Result rc = serviceDispatchIn(&cs->s, 9, *placeholder_id, .buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_Out }, - .buffers = { { out_path, out_size } }, + .buffers = { { tmpbuf, sizeof(tmpbuf) } }, ); + if (R_SUCCEEDED(rc) && out_path) { + strncpy(out_path, tmpbuf, out_size-1); + out_path[out_size-1] = 0; + } + return rc; } Result ncmContentStorageCleanupAllPlaceHolder(NcmContentStorage* cs) { - return _ncmCmdNoIo(&cs->s, 10); + return _ncmCmdNoIO(&cs->s, 10); } -Result ncmContentStorageListPlaceHolder(NcmContentStorage* cs, NcmNcaId* out_ids, size_t out_ids_size, u32* out_count) { +Result ncmContentStorageListPlaceHolder(NcmContentStorage* cs, NcmContentId* out_ids, s32 count, s32* out_count) { return serviceDispatchOut(&cs->s, 11, *out_count, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { out_ids, out_ids_size } }, + .buffers = { { out_ids, count*sizeof(NcmContentId) } }, ); } -Result ncmContentStorageGetContentCount(NcmContentStorage* cs, u32* out_count) { +Result ncmContentStorageGetContentCount(NcmContentStorage* cs, s32* out_count) { return serviceDispatchOut(&cs->s, 12, *out_count); } -Result ncmContentStorageListContentId(NcmContentStorage* cs, NcmNcaId* out_ids, size_t out_ids_size, u32* out_count, u32 start_offset) { +Result ncmContentStorageListContentId(NcmContentStorage* cs, NcmContentId* out_ids, s32 count, s32* out_count, s32 start_offset) { return serviceDispatchInOut(&cs->s, 13, start_offset, *out_count, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { out_ids, out_ids_size } }, + .buffers = { { out_ids, count*sizeof(NcmContentId) } }, ); } -Result ncmContentStorageGetSizeFromContentId(NcmContentStorage* cs, u64* out_size, const NcmNcaId* content_id) { - return _ncmCmdInNcaIdOutU64(&cs->s, 14, content_id, out_size); +Result ncmContentStorageGetSizeFromContentId(NcmContentStorage* cs, s64* out_size, const NcmContentId* content_id) { + return _ncmCmdInContentIdOutU64(&cs->s, 14, content_id, (u64*)out_size); } Result ncmContentStorageDisableForcibly(NcmContentStorage* cs) { - return _ncmCmdNoIo(&cs->s, 15); + return _ncmCmdNoIO(&cs->s, 15); } -Result ncmContentStorageRevertToPlaceHolder(NcmContentStorage* cs, const NcmNcaId* placeholder_id, const NcmNcaId* old_content_id, const NcmNcaId* new_content_id) { +Result ncmContentStorageRevertToPlaceHolder(NcmContentStorage* cs, const NcmContentId* 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 { - NcmNcaId old_content_id; - NcmNcaId new_content_id; - NcmNcaId placeholder_id; + NcmContentId old_content_id; + NcmContentId new_content_id; + NcmContentId placeholder_id; } in = { *old_content_id, *new_content_id, *placeholder_id }; return serviceDispatchIn(&cs->s, 16, in); } -Result ncmContentStorageSetPlaceHolderSize(NcmContentStorage* cs, const NcmNcaId* placeholder_id, u64 size) { +Result ncmContentStorageSetPlaceHolderSize(NcmContentStorage* cs, const NcmContentId* placeholder_id, s64 size) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); const struct { - NcmNcaId placeholder_id; - u64 size; + NcmContentId placeholder_id; + s64 size; } in = { *placeholder_id, size }; return serviceDispatchIn(&cs->s, 17, in); } -Result ncmContentStorageReadContentIdFile(NcmContentStorage* cs, void* out_data, size_t out_data_size, const NcmNcaId* content_id, u64 offset) { +Result ncmContentStorageReadContentIdFile(NcmContentStorage* cs, void* out_data, size_t out_data_size, const NcmContentId* content_id, s64 offset) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); const struct { - NcmNcaId content_id; - u64 offset; + NcmContentId content_id; + s64 offset; } in = { *content_id, offset }; return serviceDispatchIn(&cs->s, 18, in, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, @@ -241,39 +259,28 @@ Result ncmContentStorageReadContentIdFile(NcmContentStorage* cs, void* out_data, ); } -Result ncmContentStorageGetRightsIdFromPlaceHolderId(NcmContentStorage* cs, FsRightsId* out_rights_id, u32* out_key_generation, const NcmNcaId* placeholder_id) { +Result ncmContentStorageGetRightsIdFromPlaceHolderId(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmContentId* placeholder_id) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - struct { - FsRightsId rights_id; - u32 key_generation; - } out; - Result rc = serviceDispatchInOut(&cs->s, 19, *placeholder_id, out); - if (R_SUCCEEDED(rc)) { - if (out_rights_id) *out_rights_id = out.rights_id; - if (out_key_generation) *out_key_generation = out.key_generation; - } - return rc; + if (hosversionBefore(3,0,0)) + return serviceDispatchInOut(&cs->s, 19, *placeholder_id, out_rights_id->rights_id); + else + return serviceDispatchInOut(&cs->s, 19, *placeholder_id, *out_rights_id); } -Result ncmContentStorageGetRightsIdFromContentId(NcmContentStorage* cs, FsRightsId* out_rights_id, u32* out_key_generation, const NcmNcaId* content_id) { +Result ncmContentStorageGetRightsIdFromContentId(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmContentId* content_id) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - struct { - FsRightsId rights_id; - u32 key_generation; - } out; - Result rc = serviceDispatchInOut(&cs->s, 20, *content_id, out); - if (R_SUCCEEDED(rc)) { - if (out_rights_id) *out_rights_id = out.rights_id; - if (out_key_generation) *out_key_generation = out.key_generation; - } - return rc; + memset(out_rights_id, 0, sizeof(*out_rights_id)); + if (hosversionBefore(3,0,0)) + return serviceDispatchInOut(&cs->s, 20, *content_id, out_rights_id->rights_id); + else + return serviceDispatchInOut(&cs->s, 20, *content_id, *out_rights_id); } -Result ncmContentStorageWriteContentForDebug(NcmContentStorage* cs, const NcmNcaId* content_id, u64 offset, const void* data, size_t data_size) { +Result ncmContentStorageWriteContentForDebug(NcmContentStorage* cs, const NcmContentId* content_id, s64 offset, const void* data, size_t data_size) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); const struct { - NcmNcaId content_id; - u64 offset; + NcmContentId content_id; + s64 offset; } in = { *content_id, offset }; return serviceDispatchIn(&cs->s, 21, in, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, @@ -281,47 +288,42 @@ Result ncmContentStorageWriteContentForDebug(NcmContentStorage* cs, const NcmNca ); } -Result ncmContentStorageGetFreeSpaceSize(NcmContentStorage* cs, u64* out_size) { +Result ncmContentStorageGetFreeSpaceSize(NcmContentStorage* cs, s64* out_size) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _ncmCmdNoInOutU64(&cs->s, 22, out_size); + return _ncmCmdNoInOutU64(&cs->s, 22, (u64*)out_size); } -Result ncmContentStorageGetTotalSpaceSize(NcmContentStorage* cs, u64* out_size) { +Result ncmContentStorageGetTotalSpaceSize(NcmContentStorage* cs, s64* out_size) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _ncmCmdNoInOutU64(&cs->s, 23, out_size); + return _ncmCmdNoInOutU64(&cs->s, 23, (u64*)out_size); } Result ncmContentStorageFlushPlaceHolder(NcmContentStorage* cs) { if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _ncmCmdNoIo(&cs->s, 24); + return _ncmCmdNoIO(&cs->s, 24); } -Result ncmContentStorageGetSizeFromPlaceHolderId(NcmContentStorage* cs, u64* out_size, const NcmNcaId* placeholder_id) { +Result ncmContentStorageGetSizeFromPlaceHolderId(NcmContentStorage* cs, s64* out_size, const NcmContentId* placeholder_id) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _ncmCmdInNcaIdOutU64(&cs->s, 25, placeholder_id, out_size); + return _ncmCmdInContentIdOutU64(&cs->s, 25, placeholder_id, (u64*)out_size); } Result ncmContentStorageRepairInvalidFileAttribute(NcmContentStorage* cs) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _ncmCmdNoIo(&cs->s, 26); + return _ncmCmdNoIO(&cs->s, 26); } -Result ncmContentStorageGetRightsIdFromPlaceHolderIdWithCache(NcmContentStorage* cs, FsRightsId* out_rights_id, u32* out_key_generation, const NcmNcaId* placeholder_id, const NcmNcaId* cache_content_id) { +Result ncmContentStorageGetRightsIdFromPlaceHolderIdWithCache(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmContentId* placeholder_id, const NcmContentId* cache_content_id) { if (hosversionBefore(8,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); const struct { - NcmNcaId cache_content_id; - NcmNcaId placeholder_id; + NcmContentId cache_content_id; + NcmContentId placeholder_id; } in = { *cache_content_id, *placeholder_id }; - struct { - FsRightsId rights_id; - u32 key_generation; - } out; - Result rc = serviceDispatchInOut(&cs->s, 27, in, out); - if (R_SUCCEEDED(rc)) { - if (out_rights_id) *out_rights_id = out.rights_id; - if (out_key_generation) *out_key_generation = out.key_generation; - } - return rc; + + if (hosversionBefore(3,0,0)) + return serviceDispatchInOut(&cs->s, 27, in, out_rights_id->rights_id); + else + return serviceDispatchInOut(&cs->s, 27, in, *out_rights_id); } void ncmContentMetaDatabaseClose(NcmContentMetaDatabase* db) { @@ -346,7 +348,7 @@ Result ncmContentMetaDatabaseRemove(NcmContentMetaDatabase* db, const NcmContent return serviceDispatchIn(&db->s, 2, *key); } -Result ncmContentMetaDatabaseGetContentIdByType(NcmContentMetaDatabase* db, NcmNcaId* out_content_id, const NcmContentMetaKey* key, NcmContentType type) { +Result ncmContentMetaDatabaseGetContentIdByType(NcmContentMetaDatabase* db, NcmContentId* out_content_id, const NcmContentMetaKey* key, NcmContentType type) { const struct { u8 type; u8 padding[7]; @@ -355,32 +357,34 @@ Result ncmContentMetaDatabaseGetContentIdByType(NcmContentMetaDatabase* db, NcmN return serviceDispatchInOut(&db->s, 3, in, *out_content_id); } -Result ncmContentMetaDatabaseListContentInfo(NcmContentMetaDatabase* db, u32* out_entries_written, NcmContentInfo* out_info, size_t out_info_size, const NcmContentMetaKey* key, u32 start_index) { +Result ncmContentMetaDatabaseListContentInfo(NcmContentMetaDatabase* db, s32* out_entries_written, NcmContentInfo* out_info, s32 count, const NcmContentMetaKey* key, s32 start_index) { const struct { - u32 start_index; + s32 start_index; + u32 pad; NcmContentMetaKey key; - } in = { start_index, *key }; + } in = { start_index, 0, *key }; return serviceDispatchInOut(&db->s, 4, in, *out_entries_written, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { out_info, out_info_size } }, + .buffers = { { out_info, count*sizeof(NcmContentInfo) } }, ); } -Result ncmContentMetaDatabaseList(NcmContentMetaDatabase* db, u32* out_entries_total, u32* out_entries_written, NcmContentMetaKey* out_keys, size_t out_keys_size, NcmContentMetaType meta_type, u64 application_title_id, u64 title_id_min, u64 title_id_max, NcmContentInstallType install_type) { + +Result ncmContentMetaDatabaseList(NcmContentMetaDatabase* db, s32* out_entries_total, s32* out_entries_written, NcmContentMetaKey* out_keys, s32 count, NcmContentMetaType meta_type, u64 application_title_id, u64 title_id_min, u64 title_id_max, NcmContentInstallType install_type) { const struct { u8 meta_type; u8 install_type; - u16 padding; + u8 padding[6]; u64 application_title_id; u64 title_id_min; u64 title_id_max; - } in = { meta_type, install_type, 0, application_title_id, title_id_min, title_id_max }; + } in = { meta_type, install_type, {0}, application_title_id, title_id_min, title_id_max }; struct { - u32 out_entries_total; - u32 out_entries_written; + s32 out_entries_total; + s32 out_entries_written; } out; return serviceDispatchInOut(&db->s, 5, in, out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { out_keys, out_keys_size } }, + .buffers = { { out_keys, count*sizeof(NcmContentMetaKey) } }, ); } @@ -388,33 +392,39 @@ Result ncmContentMetaDatabaseGetLatestContentMetaKey(NcmContentMetaDatabase* db, return serviceDispatchInOut(&db->s, 6, title_id, *out_key); } -Result ncmContentMetaDatabaseListApplication(NcmContentMetaDatabase* db, u32* out_entries_total, u32* out_entries_written, NcmApplicationContentMetaKey* out_keys, size_t out_keys_size, NcmContentMetaType meta_type) { +Result ncmContentMetaDatabaseListApplication(NcmContentMetaDatabase* db, s32* out_entries_total, s32* out_entries_written, NcmApplicationContentMetaKey* out_keys, s32 count, NcmContentMetaType meta_type) { struct { - u32 out_entries_total; - u32 out_entries_written; + s32 out_entries_total; + s32 out_entries_written; } out; return serviceDispatchInOut(&db->s, 7, meta_type, out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { out_keys, out_keys_size } }, + .buffers = { { out_keys, count*sizeof(NcmApplicationContentMetaKey) } }, ); } Result ncmContentMetaDatabaseHas(NcmContentMetaDatabase* db, bool* out, const NcmContentMetaKey* key) { - return serviceDispatchInOut(&db->s, 8, *key, *out); + u8 tmp=0; + Result rc = serviceDispatchInOut(&db->s, 8, *key, tmp); + if (R_SUCCEEDED(rc) && out) *out = tmp & 1; + return rc; } -Result ncmContentMetaDatabaseHasAll(NcmContentMetaDatabase* db, bool* out, const NcmContentMetaKey* keys, size_t keys_size) { - return serviceDispatchOut(&db->s, 9, *out, +Result ncmContentMetaDatabaseHasAll(NcmContentMetaDatabase* db, bool* out, const NcmContentMetaKey* keys, s32 count) { + u8 tmp=0; + Result rc = serviceDispatchOut(&db->s, 9, *out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, - .buffers = { { keys, keys_size } }, + .buffers = { { keys, count*sizeof(NcmContentMetaKey) } }, ); + if (R_SUCCEEDED(rc) && out) *out = tmp & 1; + return rc; } Result ncmContentMetaDatabaseGetSize(NcmContentMetaDatabase* db, u64* out_size, const NcmContentMetaKey* key) { return serviceDispatchInOut(&db->s, 10, *key, *out_size); } -Result ncmContentMetaDatabaseGetRequiredSystemVersion(NcmContentMetaDatabase* db, u64* out_version, const NcmContentMetaKey* key) { +Result ncmContentMetaDatabaseGetRequiredSystemVersion(NcmContentMetaDatabase* db, u32* out_version, const NcmContentMetaKey* key) { return serviceDispatchInOut(&db->s, 11, *key, *out_version); } @@ -423,43 +433,46 @@ Result ncmContentMetaDatabaseGetPatchId(NcmContentMetaDatabase* db, u64* out_pat } Result ncmContentMetaDatabaseDisableForcibly(NcmContentMetaDatabase* db) { - return _ncmCmdNoIo(&db->s, 13); + return _ncmCmdNoIO(&db->s, 13); } -Result ncmContentMetaDatabaseLookupOrphanContent(NcmContentMetaDatabase* db, bool* out_orphaned, size_t out_orphaned_size, const NcmNcaId* content_ids, size_t content_ids_size) { +Result ncmContentMetaDatabaseLookupOrphanContent(NcmContentMetaDatabase* db, bool* out_orphaned, const NcmContentId* content_ids, s32 count) { return serviceDispatch(&db->s, 14, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out, SfBufferAttr_HipcMapAlias | SfBufferAttr_In, }, .buffers = { - { out_orphaned, out_orphaned_size }, - { content_ids, content_ids_size }, + { out_orphaned, count }, + { content_ids, count*sizeof(NcmContentId) }, }, ); } Result ncmContentMetaDatabaseCommit(NcmContentMetaDatabase* db) { - return _ncmCmdNoIo(&db->s, 15); + return _ncmCmdNoIO(&db->s, 15); } -Result ncmContentMetaDatabaseHasContent(NcmContentMetaDatabase* db, bool* out, const NcmContentMetaKey* key, const NcmNcaId* content_id) { +Result ncmContentMetaDatabaseHasContent(NcmContentMetaDatabase* db, bool* out, const NcmContentMetaKey* key, const NcmContentId* content_id) { const struct { - NcmNcaId content_id; + NcmContentId content_id; NcmContentMetaKey key; } in = { *content_id, *key }; - return serviceDispatchInOut(&db->s, 16, in, *out); + u8 tmp=0; + Result rc = serviceDispatchInOut(&db->s, 16, in, tmp); + if (R_SUCCEEDED(rc) && out) *out = tmp & 1; + return rc; } -Result ncmContentMetaDatabaseListContentMetaInfo(NcmContentMetaDatabase* db, u32* out_entries_written, void* out_meta_info, size_t out_meta_info_size, const NcmContentMetaKey* key, u32 start_index) { +Result ncmContentMetaDatabaseListContentMetaInfo(NcmContentMetaDatabase* db, s32* out_entries_written, void* out_meta_info, s32 count, const NcmContentMetaKey* key, s32 start_index) { const struct { - u32 start_index; + s32 start_index; u32 padding; NcmContentMetaKey key; } in = { start_index, 0, *key }; return serviceDispatchInOut(&db->s, 17, in, *out_entries_written, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { out_meta_info, out_meta_info_size } }, + .buffers = { { out_meta_info, count*sizeof(NcmContentMetaInfo) } }, ); } @@ -467,12 +480,12 @@ Result ncmContentMetaDatabaseGetAttributes(NcmContentMetaDatabase* db, const Ncm return serviceDispatchInOut(&db->s, 18, *key, *out); } -Result ncmContentMetaDatabaseGetRequiredApplicationVersion(NcmContentMetaDatabase* db, u64* out_version, const NcmContentMetaKey* key) { +Result ncmContentMetaDatabaseGetRequiredApplicationVersion(NcmContentMetaDatabase* db, u32* out_version, const NcmContentMetaKey* key) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return serviceDispatchInOut(&db->s, 19, *key, *out_version); } -Result ncmContentMetaDatabaseGetContentIdByTypeAndIdOffset(NcmContentMetaDatabase* db, NcmNcaId* out_content_id, const NcmContentMetaKey* key, NcmContentType type, u8 id_offset) { +Result ncmContentMetaDatabaseGetContentIdByTypeAndIdOffset(NcmContentMetaDatabase* db, NcmContentId* out_content_id, const NcmContentMetaKey* key, NcmContentType type, u8 id_offset) { if (hosversionBefore(5,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); const struct { u8 type;