From 02ce33bf20829c663619217f4ea53497308a69ca Mon Sep 17 00:00:00 2001 From: Rajko Stojadinovic Date: Thu, 19 Jul 2018 17:56:40 +0200 Subject: [PATCH] Fix ncmContentMetaDatabaseSet/ncmContentMetaDatabaseGet, add ncmContentMetaDatabaseList --- nx/include/switch/services/ncm.h | 12 +++++-- nx/source/services/ncm.c | 58 +++++++++++++++++++++++++++++--- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/nx/include/switch/services/ncm.h b/nx/include/switch/services/ncm.h index 1d0f7db3..7c4807b1 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; //of 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 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..f86daaf7 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,56 @@ 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 TID; + u64 TID_LOW; + u64 TID_HIGH; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 5; + raw->titleType = titleType; + raw->TID = titleIdExact; + raw->TID_LOW = titleIdLow; + raw->TID_HIGH = 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);