From c3278ffd3472cb7d2f45f3c584a2f050aa3a7b48 Mon Sep 17 00:00:00 2001 From: Rajko Stojadinovic Date: Thu, 26 Jul 2018 03:12:14 +0200 Subject: [PATCH] Add ncmContentStorage functions needed for writing content --- nx/include/switch/services/ncm.h | 6 + nx/source/services/ncm.c | 203 +++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+) diff --git a/nx/include/switch/services/ncm.h b/nx/include/switch/services/ncm.h index d635c3d0..8f7ea1cc 100644 --- a/nx/include/switch/services/ncm.h +++ b/nx/include/switch/services/ncm.h @@ -67,6 +67,12 @@ void ncmExit(void); Result ncmOpenContentStorage(FsStorageId storage, NcmContentStorage* out); Result ncmOpenContentMetaDatabase(FsStorageId storage, NcmContentMetaDatabase* out); +Result ncmContentStorageGeneratePlaceHolderId(NcmContentStorage* cs, NcmNcaId* outputId); +Result ncmContentStorageCreatePlaceHolder(NcmContentStorage* cs, const NcmNcaId* registeredId, const NcmNcaId* placeholderId, u64 size); +Result ncmContentStorageDeletePlaceHolder(NcmContentStorage* cs, const NcmNcaId* placeholderId); +Result ncmContentStorageWritePlaceHolder(NcmContentStorage* cs, const NcmNcaId* placeholderId, u64 offset, const void* srcData, size_t srcDataSize); +Result ncmContentStorageRegister(NcmContentStorage* cs, const NcmNcaId* registeredId, const NcmNcaId* placeholderId); +Result ncmContentStorageDelete(NcmContentStorage* cs, const NcmNcaId* registeredId); Result ncmContentStorageHas(NcmContentStorage* cs, const NcmNcaId* ncaId, bool* out); Result ncmContentStorageGetPath(NcmContentStorage* cs, const NcmNcaId* ncaId, char* out, size_t outSize); Result ncmContentStorageGetSize(NcmContentStorage* cs, const NcmNcaId* ncaId, u64* out); diff --git a/nx/source/services/ncm.c b/nx/source/services/ncm.c index 2bd503ff..4308cb3b 100644 --- a/nx/source/services/ncm.c +++ b/nx/source/services/ncm.c @@ -92,6 +92,209 @@ Result ncmOpenContentMetaDatabase(FsStorageId storage, NcmContentMetaDatabase* o return rc; } +Result ncmContentStorageGeneratePlaceHolderId(NcmContentStorage* cs, NcmNcaId* outputId) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 0; + + Result rc = serviceIpcDispatch(&cs->s); + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + NcmNcaId outputId; + } *resp = r.Raw; + + rc = resp->result; + if (R_SUCCEEDED(rc)) { + memcpy(outputId, &resp->outputId, sizeof(NcmNcaId)); + } + } + + return rc; +} + +Result ncmContentStorageCreatePlaceHolder(NcmContentStorage* cs, const NcmNcaId* registeredId, const NcmNcaId* placeholderId, u64 size) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + NcmNcaId registeredId; + NcmNcaId placeholderId; + u64 size; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + raw->magic = SFCI_MAGIC; + raw->cmd_id = 1; + memcpy(&raw->registeredId, registeredId, sizeof(NcmNcaId)); + memcpy(&raw->placeholderId, placeholderId, sizeof(NcmNcaId)); + raw->size = size; + + Result rc = serviceIpcDispatch(&cs->s); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result ncmContentStorageDeletePlaceHolder(NcmContentStorage* cs, const NcmNcaId* placeholderId) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + NcmNcaId placeholderId; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + raw->magic = SFCI_MAGIC; + raw->cmd_id = 2; + memcpy(&raw->placeholderId, placeholderId, sizeof(NcmNcaId)); + + Result rc = serviceIpcDispatch(&cs->s); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result ncmContentStorageWritePlaceHolder(NcmContentStorage* cs, const NcmNcaId* placeholderId, u64 offset, const void* srcData, size_t srcDataSize) { + IpcCommand c; + ipcInitialize(&c); + ipcAddSendBuffer(&c, srcData, srcDataSize, BufferType_Normal); + + struct { + u64 magic; + u64 cmd_id; + NcmNcaId placeholderId; + u64 offset; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + raw->magic = SFCI_MAGIC; + raw->cmd_id = 4; + memcpy(&raw->placeholderId, placeholderId, sizeof(NcmNcaId)); + raw->offset = offset; + + Result rc = serviceIpcDispatch(&cs->s); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result ncmContentStorageRegister(NcmContentStorage* cs, const NcmNcaId* registeredId, const NcmNcaId* placeholderId) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + NcmNcaId registeredId; + NcmNcaId placeholderId; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + raw->magic = SFCI_MAGIC; + raw->cmd_id = 5; + memcpy(&raw->registeredId, registeredId, sizeof(NcmNcaId)); + memcpy(&raw->placeholderId, placeholderId, sizeof(NcmNcaId)); + + Result rc = serviceIpcDispatch(&cs->s); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result ncmContentStorageDelete(NcmContentStorage* cs, const NcmNcaId* registeredId) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + NcmNcaId registeredId; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + raw->magic = SFCI_MAGIC; + raw->cmd_id = 6; + memcpy(&raw->registeredId, registeredId, sizeof(NcmNcaId)); + + Result rc = serviceIpcDispatch(&cs->s); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + Result ncmContentStorageHas(NcmContentStorage* cs, const NcmNcaId* ncaId, bool* out) { IpcCommand c; ipcInitialize(&c);