Implement fsOpenContentStorageFileSystem, fsGetRightsIdByPath & fsGetRightsIdAndKeyGenerationByPath (#288)

* Implement fsOpenContentStorageFileSystem, fsGetRightsIdByPath & fsGetRightsIdAndKeyGenerationByPath
This commit is contained in:
Adubbz 2019-06-04 04:51:21 +10:00 committed by yellows8
parent 3afc9ae371
commit 8cf419802a
4 changed files with 140 additions and 8 deletions

View File

@ -20,6 +20,10 @@
/// For use with \ref FsSave and \ref FsSaveDataInfo.
#define FS_SAVEDATA_USERID_COMMONSAVE 0
typedef struct {
u8 c[0x10];
} FsRightsId;
typedef struct {
Service s;
} FsFileSystem;
@ -230,10 +234,17 @@ Result fsMountSdcard(FsFileSystem* out);
Result fsMountSaveData(FsFileSystem* out, u8 inval, FsSave *save);
Result fsMountSystemSaveData(FsFileSystem* out, u8 inval, FsSave *save);
Result fsOpenSaveDataIterator(FsSaveDataIterator* out, s32 SaveDataSpaceId);
Result fsOpenContentStorageFileSystem(FsFileSystem* out, FsContentStorageId content_storage_id);
Result fsOpenDataStorageByCurrentProcess(FsStorage* out);
Result fsOpenDataStorageByDataId(FsStorage* out, u64 dataId, FsStorageId storageId);
Result fsOpenDeviceOperator(FsDeviceOperator* out);
Result fsOpenSdCardDetectionEventNotifier(FsEventNotifier* out);
/// Retrieves the rights id corresponding to the content path. Only available on [2.0.0+].
Result fsGetRightsIdByPath(const char* path, FsRightsId* out_rights_id);
/// Retrieves the rights id and key generation corresponding to the content path. Only available on [3.0.0+].
Result fsGetRightsIdAndKeyGenerationByPath(const char* path, u8* out_key_generation, FsRightsId* out_rights_id);
// todo: Rest of commands here
/// FsFileSystem can be mounted with fs_dev for use with stdio, see fs_dev.h.

View File

@ -74,10 +74,6 @@ typedef struct {
u64 baseTitleId;
} NcmApplicationContentMetaKey;
typedef struct {
u8 c[0x10];
} NcmRightsId;
Result ncmInitialize(void);
void ncmExit(void);
@ -97,7 +93,7 @@ Result ncmContentStorageCleanupAllPlaceHolder(NcmContentStorage* cs);
Result ncmContentStorageGetSize(NcmContentStorage* cs, const NcmNcaId* ncaId, u64* out);
Result ncmContentStorageDisableForcibly(NcmContentStorage* cs);
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 ncmContentStorageGetRightsIdFromContentId(NcmContentStorage* cs, const NcmNcaId* ncaId, FsRightsId* rightsIdOut, u32* keyGenerationOut);
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);

View File

@ -317,6 +317,44 @@ Result fsOpenSaveDataIterator(FsSaveDataIterator* out, s32 SaveDataSpaceId) {
return rc;
}
Result fsOpenContentStorageFileSystem(FsFileSystem* out, FsContentStorageId content_storage_id) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u32 content_storage_id;
} *raw;
raw = serviceIpcPrepareHeader(&g_fsSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 110;
raw->content_storage_id = content_storage_id;
Result rc = serviceIpcDispatch(&g_fsSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
} *resp;
serviceIpcParse(&g_fsSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
serviceCreateSubservice(&out->s, &g_fsSrv, &r, 0);
}
}
return rc;
}
Result fsOpenDataStorageByCurrentProcess(FsStorage* out) {
IpcCommand c;
ipcInitialize(&c);
@ -465,6 +503,93 @@ Result fsOpenSdCardDetectionEventNotifier(FsEventNotifier* out) {
return rc;
}
Result fsGetRightsIdByPath(const char* path, FsRightsId* out_rights_id) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
char send_path[FS_MAX_PATH] = {0};
IpcCommand c;
ipcInitialize(&c);
ipcAddSendStatic(&c, send_path, FS_MAX_PATH, 0);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = serviceIpcPrepareHeader(&g_fsSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 609;
strncpy(send_path, path, FS_MAX_PATH-1);
Result rc = serviceIpcDispatch(&g_fsSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
FsRightsId rights_id;
} *resp;
serviceIpcParse(&g_fsSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
if (out_rights_id) *out_rights_id = resp->rights_id;
}
}
return rc;
}
Result fsGetRightsIdAndKeyGenerationByPath(const char* path, u8* out_key_generation, FsRightsId* out_rights_id) {
if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
char send_path[FS_MAX_PATH] = {0};
IpcCommand c;
ipcInitialize(&c);
ipcAddSendStatic(&c, send_path, FS_MAX_PATH, 0);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = serviceIpcPrepareHeader(&g_fsSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 610;
strncpy(send_path, path, FS_MAX_PATH-1);
Result rc = serviceIpcDispatch(&g_fsSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
u8 key_generation;
u8 padding[0x7];
FsRightsId rights_id;
} *resp;
serviceIpcParse(&g_fsSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
if (out_key_generation) *out_key_generation = resp->key_generation;
if (out_rights_id) *out_rights_id = resp->rights_id;
}
}
return rc;
}
Result fsIsExFatSupported(bool* out)
{
if (hosversionBefore(2,0,0)) {

View File

@ -542,7 +542,7 @@ Result ncmContentStorageReadContentIdFile(NcmContentStorage* cs, const NcmNcaId*
return rc;
}
Result ncmContentStorageGetRightsIdFromContentId(NcmContentStorage* cs, const NcmNcaId* ncaId, NcmRightsId* rightsIdOut, u32* keyGenerationOut) {
Result ncmContentStorageGetRightsIdFromContentId(NcmContentStorage* cs, const NcmNcaId* ncaId, FsRightsId* rightsIdOut, u32* keyGenerationOut) {
IpcCommand c;
ipcInitialize(&c);
@ -566,14 +566,14 @@ Result ncmContentStorageGetRightsIdFromContentId(NcmContentStorage* cs, const Nc
struct {
u64 magic;
u64 result;
NcmRightsId rights_id;
FsRightsId rights_id;
u32 key_generation;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
if (rightsIdOut) memcpy(rightsIdOut, &resp->rights_id, sizeof(NcmRightsId));
if (rightsIdOut) memcpy(rightsIdOut, &resp->rights_id, sizeof(FsRightsId));
if (keyGenerationOut) *keyGenerationOut = resp->key_generation;
}
}