From e1d50dc12954189d48c3712303f9685af5b0dfbb Mon Sep 17 00:00:00 2001 From: Rajko Stojadinovic Date: Thu, 26 Jul 2018 02:15:54 +0200 Subject: [PATCH] Fix signature of ncmContentMetaDatabaseSet/Get, add ncmContentMetaDatabaseList (#134) * Fix ncmContentMetaDatabaseSet/ncmContentMetaDatabaseGet, add ncmContentMetaDatabaseList --- nx/include/switch/services/ncm.h | 12 +++++-- nx/source/services/ncm.c | 56 +++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/nx/include/switch/services/ncm.h b/nx/include/switch/services/ncm.h index 1d0f7db3..d635c3d0 100644 --- a/nx/include/switch/services/ncm.h +++ b/nx/include/switch/services/ncm.h @@ -45,6 +45,13 @@ typedef struct { u8 padding; } NcmContentRecord; +typedef struct { + u16 numExtraBytes; ///< Size of optional struct that comes after this one. + u16 numContentRecords; ///< Number of NcmContentRecord entries after the extra bytes. + u16 numMetaRecords; ///< Number of NcmMetaRecord entries that come after the NcmContentRecords. + u16 padding; ///< Always zero. +} NcmContentMetaRecordsHeader; + typedef struct { NcmMetaRecord metaRecord; u64 baseTitleId; @@ -66,11 +73,12 @@ Result ncmContentStorageGetSize(NcmContentStorage* cs, const NcmNcaId* ncaId, u6 Result ncmContentStorageReadContentIdFile(NcmContentStorage* cs, const NcmNcaId* ncaId, u64 offset, void* outBuf, size_t bufSize); Result ncmContentStorageGetRightsIdFromContentId(NcmContentStorage* cs, const NcmNcaId* ncaId, NcmRightsId* rightsIdOut, u32* keyGenerationOut); -Result ncmContentMetaDatabaseSet(NcmContentMetaDatabase* db, const NcmMetaRecord* record, u64 contentRecordSize, NcmContentRecord* contentRecords); -Result ncmContentMetaDatabaseGet(NcmContentMetaDatabase* db, const NcmMetaRecord* record, u64 contentRecordSize, NcmContentRecord* contentRecordsOut, u64* sizeRead); +Result ncmContentMetaDatabaseSet(NcmContentMetaDatabase* db, const NcmMetaRecord* record, u64 inDataSize, const NcmContentMetaRecordsHeader* srcRecordsData); +Result ncmContentMetaDatabaseGet(NcmContentMetaDatabase* db, const NcmMetaRecord* record, u64 outDataSize, NcmContentMetaRecordsHeader* outRecordsData, u64* sizeRead); Result ncmContentMetaDatabaseRemove(NcmContentMetaDatabase* db, const NcmMetaRecord *record); Result ncmContentMetaDatabaseGetContentIdByType(NcmContentMetaDatabase* db, NcmContentType contentType, const NcmMetaRecord* record, NcmNcaId* out); Result ncmContentMetaDatabaseListContentInfo(NcmContentMetaDatabase* db, const NcmMetaRecord* record, u32 index, NcmContentRecord* contentRecordsOut, size_t contentRecordsBufSize, u32* numEntriesRead); +Result ncmContentMetaDatabaseList(NcmContentMetaDatabase* db, u32 titleType, u64 titleIdExact, u64 titleIdLow, u64 titleIdHigh, NcmMetaRecord* metaRecordsOut, size_t metaRecordsBufSize, u32* numEntriesWritten, u32* numEntriesTotal); Result ncmContentMetaDatabaseGetLatestContentMetaKey(NcmContentMetaDatabase* db, u64 titleId, NcmMetaRecord* out); Result ncmContentMetaDatabaseListApplication(NcmContentMetaDatabase* db, u8 filter, NcmApplicationContentMetaKey* outBuf, size_t outBufSize, u32* numEntriesWritten, u32* numEntriesTotal); Result ncmContentMetaDatabaseHas(NcmContentMetaDatabase* db, const NcmMetaRecord* record, bool* out); diff --git a/nx/source/services/ncm.c b/nx/source/services/ncm.c index 33678812..2bd503ff 100644 --- a/nx/source/services/ncm.c +++ b/nx/source/services/ncm.c @@ -279,10 +279,10 @@ Result ncmContentStorageGetRightsIdFromContentId(NcmContentStorage* cs, const Nc return rc; } -Result ncmContentMetaDatabaseSet(NcmContentMetaDatabase* db, const NcmMetaRecord* record, u64 contentRecordSize, NcmContentRecord* contentRecords) { +Result ncmContentMetaDatabaseSet(NcmContentMetaDatabase* db, const NcmMetaRecord* record, u64 inDataSize, const NcmContentMetaRecordsHeader* srcRecordsData) { IpcCommand c; ipcInitialize(&c); - ipcAddSendBuffer(&c, contentRecords, contentRecordSize, BufferType_Normal); + ipcAddSendBuffer(&c, srcRecordsData, inDataSize, BufferType_Normal); struct { u64 magic; @@ -312,10 +312,10 @@ Result ncmContentMetaDatabaseSet(NcmContentMetaDatabase* db, const NcmMetaRecord return rc; } -Result ncmContentMetaDatabaseGet(NcmContentMetaDatabase* db, const NcmMetaRecord* record, u64 contentRecordSize, NcmContentRecord* contentRecordsOut, u64* sizeRead) { +Result ncmContentMetaDatabaseGet(NcmContentMetaDatabase* db, const NcmMetaRecord* record, u64 outDataSize, NcmContentMetaRecordsHeader* outRecordsData, u64* sizeRead) { IpcCommand c; ipcInitialize(&c); - ipcAddRecvBuffer(&c, contentRecordsOut, contentRecordSize, BufferType_Normal); + ipcAddRecvBuffer(&c, outRecordsData, outDataSize, BufferType_Normal); struct { u64 magic; @@ -463,6 +463,54 @@ Result ncmContentMetaDatabaseListContentInfo(NcmContentMetaDatabase* db, const N return rc; } +Result ncmContentMetaDatabaseList(NcmContentMetaDatabase* db, u32 titleType, u64 titleIdExact, u64 titleIdLow, u64 titleIdHigh, NcmMetaRecord* metaRecordsOut, size_t metaRecordsBufSize, u32* numEntriesWritten, u32* numEntriesTotal) { + IpcCommand c; + ipcInitialize(&c); + ipcAddRecvBuffer(&c, metaRecordsOut, metaRecordsBufSize, BufferType_Normal); + + struct { + u64 magic; + u64 cmd_id; + u32 titleType; + u64 titleIdExact; + u64 titleIdLow; + u64 titleIdHigh; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 5; + raw->titleType = titleType; + raw->titleIdExact = titleIdExact; + raw->titleIdLow = titleIdLow; + raw->titleIdHigh = titleIdHigh; + + Result rc = serviceIpcDispatch(&db->s); + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + u32 numEntriesTotal; + u32 numEntriesWritten; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + if (numEntriesTotal) + *numEntriesTotal = resp->numEntriesTotal; + if (numEntriesWritten) + *numEntriesWritten = resp->numEntriesWritten; + } + } + + return rc; +} + Result ncmContentMetaDatabaseGetLatestContentMetaKey(NcmContentMetaDatabase* db, u64 titleId, NcmMetaRecord* out) { IpcCommand c; ipcInitialize(&c);