Line 290: |
Line 290: |
| | 0 || [[#GeneratePlaceHolderId]] || Returns a random UUID for the Content Storage. | | | 0 || [[#GeneratePlaceHolderId]] || Returns a random UUID for the Content Storage. |
| |- | | |- |
− | | 1 || CreatePlaceHolder || Takes two [[#NcaID]]s, and a u64 filesize. | + | | 1 || CreatePlaceHolder || Takes a [[#ContentId]], a [[#PlaceHolderId]], and a u64 filesize. |
| |- | | |- |
− | | 2 || DeletePlaceHolder || Takes a [[#NcaID]]. | + | | 2 || DeletePlaceHolder || Takes a [[#PlaceHolderId]]. |
| |- | | |- |
− | | 3 || HasPlaceHolder || Takes a [[#NcaID]]. | + | | 3 || HasPlaceHolder || Takes a [[#PlaceHolderId]] and returns an output u8 bool. |
| |- | | |- |
− | | 4 || WritePlaceHolder || Takes a [[#NcaID]], a u64-offset, and type 5 buffer. Writes the buffer to the file for the NcaID's placeholder path at the specified offset. | + | | 4 || WritePlaceHolder || Takes a [[#PlaceHolderId]], a u64-offset, and type-0x5 input buffer. Writes the buffer to the file for the placeholder path at the specified offset. |
| |- | | |- |
− | | 5 || Register || Takes two [[#NcaID]]s, moves the Placeholder NCA content to the registered NCA path. | + | | 5 || Register || Takes a [[#ContentId]] and a [[#PlaceHolderId]], no output. Moves the Placeholder NCA content to the registered NCA path. |
| |- | | |- |
− | | 6 || Delete || Takes a [[#NcaID]]. | + | | 6 || Delete || Takes a [[#ContentId]]. |
| |- | | |- |
− | | 7 || Has || Takes a [[#NcaID]]. | + | | 7 || Has || Takes a [[#ContentId]]. |
| |- | | |- |
− | | 8 || GetPath || Takes a [[#NcaID]]. Returns a [[Filesystem_services#ContentPath|Content Path]]. | + | | 8 || GetPath || Takes a [[#ContentId]] and a type-0x1A output buffer containing a [[#Path]]. |
| |- | | |- |
− | | 9 || GetPlaceHolderPath || Takes a [[#NcaID]]. Returns a [[Filesystem_services#ContentPath|Content Path]]. | + | | 9 || GetPlaceHolderPath || Takes a [[#PlaceHolderId]] and a type-0x1A output buffer containing a [[#Path]]. |
| |- | | |- |
− | | 10 || CleanupAllPlaceHolder || Deletes and re-creates the Placeholder directory. | + | | 10 || CleanupAllPlaceHolder || No input/output. Deletes and re-creates the Placeholder directory. |
| |- | | |- |
| | 11 || ListPlaceHolder || This is like [[#GetNumberOfRegisteredEntries]], but for the Placeholder directory. | | | 11 || ListPlaceHolder || This is like [[#GetNumberOfRegisteredEntries]], but for the Placeholder directory. |
Line 318: |
Line 318: |
| | 14 || [[#GetSizeFromContentId]] || | | | 14 || [[#GetSizeFromContentId]] || |
| |- | | |- |
− | | 15 || DisableForcibly || Closes/Flushes all resources for the storage, and causes all future IPC commands to the current session to return error 0xC805. | + | | 15 || DisableForcibly || No input/output. Closes/Flushes all resources for the storage, and causes all future IPC commands to the current session to return error 0xC805. |
| |- | | |- |
− | | 16 || [2.0.0+] RevertToPlaceHolder || Takes three 0x10-sized [[#NcaID]]s. Creates the registered directory NCA path, and renames the placeholder path to the registered NCA path. | + | | 16 || [2.0.0+] RevertToPlaceHolder || Takes a [[#ContentId]], a [[#ContentId]], and a [[#PlaceHolderId]], no output. Creates the registered directory NCA path, and renames the placeholder path to the registered NCA path. |
| |- | | |- |
− | | 17 || [2.0.0+] SetPlaceHolderSize || Takes a [[#NcaID]], and a u64 size | + | | 17 || [2.0.0+] SetPlaceHolderSize || Takes a [[#PlaceHolderId]], and a s64 size, no output. |
| |- | | |- |
| | 18 || [2.0.0+] [[#ReadContentIdFile]] || | | | 18 || [2.0.0+] [[#ReadContentIdFile]] || |
Line 330: |
Line 330: |
| | 20 || [2.0.0+] [[#GetRightsIdFromContentId]] || | | | 20 || [2.0.0+] [[#GetRightsIdFromContentId]] || |
| |- | | |- |
− | | 21 || [2.0.0+] WriteContentForDebug || Takes a [[#NcaID]], a u64 offset, and a type 5 buffer. On debug units, writes the buffer to the NCA's registered path. On retail units, this just aborts. | + | | 21 || [2.0.0+] WriteContentForDebug || Takes a [[#ContentId]], a u64 offset, and a type-0x5 input buffer. On debug units, writes the buffer to the NCA's registered path. On retail units, this just aborts. |
| |- | | |- |
| | 22 || [2.0.0+] GetFreeSpaceSize || Gets free space for the storage. | | | 22 || [2.0.0+] GetFreeSpaceSize || Gets free space for the storage. |
Line 346: |
Line 346: |
| | | |
| ==== GeneratePlaceHolderId ==== | | ==== GeneratePlaceHolderId ==== |
− | Generates a random [[#NcaID]] for use as a placeholder. | + | Generates a random [[#PlaceHolderId]] for use as a placeholder. |
| | | |
| Calls nn::util::GenerateUuid(), which internally calls nn::os::GenerateRandomBytes(16); | | Calls nn::util::GenerateUuid(), which internally calls nn::os::GenerateRandomBytes(16); |
Line 354: |
Line 354: |
| | | |
| ==== ListContentId==== | | ==== ListContentId==== |
− | Takes an output buffer, u32 offset and gets all entries starting at that offset. | + | Takes an output buffer, s32 offset and gets all entries starting at that offset. |
| Returns number of entries read. | | Returns number of entries read. |
| | | |
− | Each entry is a [[#NcaID]]. | + | Each entry is a [[#ContentId]]. |
| | | |
| The total read entries is exactly the same as the number of "<hex>.nca" directories in the storage FS(or at least under the "registered" directory?). | | The total read entries is exactly the same as the number of "<hex>.nca" directories in the storage FS(or at least under the "registered" directory?). |
| | | |
| ==== GetSizeFromContentId ==== | | ==== GetSizeFromContentId ==== |
− | Takes a [[#NcaID]] as input. | + | Takes a [[#ContentId]] as input. |
| | | |
− | Returns the total size readable by [[#ReadContentIdFile]]. This is the same as the size-field in the [[NAX0]] "<NcaID>.nca/00" file. | + | Returns the total size readable by [[#ReadContentIdFile]]. This is the same as the size-field in the [[NAX0]] "<ContentId>.nca/00" file. |
| | | |
| ==== ReadContentIdFile ==== | | ==== ReadContentIdFile ==== |
− | Takes an output buffer, a [[#NcaID]] as input, and a u64 file offset. | + | Takes a type-0x6 output buffer, a [[#ContentId]] as input, and a s64 file offset. |
| | | |
− | Reads plaintext NCA file contents from the Registered path for the NcaID. | + | Reads plaintext NCA file contents from the Registered path for the ContentId. |
| | | |
| ==== GetRightsIdFromPlaceHolderId ==== | | ==== GetRightsIdFromPlaceHolderId ==== |
− | Takes a total of 0x10-bytes of input, returns a total of 0x10-bytes of output. | + | Takes a [[#PlaceHolderId]], returns a [[#RightsId]]. |
| | | |
− | [3.0.0+] Returns an additional 8-bytes of output.
| + | Gets the Rights ID for the [[#PlaceHolderId]]'s placeholder path. |
− | | |
− | Gets the Rights ID for the [[#NcaID]]'s placeholder path. | |
| | | |
| ==== GetRightsIdFromContentId ==== | | ==== GetRightsIdFromContentId ==== |
− | Takes a total of 0x10-bytes of input, returns a total of 0x10-bytes of output. | + | Takes a [[#ContentId]], returns a [[#RightsId]]. |
| | | |
− | [3.0.0+] Returns an additional 8-bytes of output.
| + | Gets the Rights ID for the [[#ContentId]]'s registered path |
− | | |
− | Gets the Rights ID for the [[#NcaID]]'s registered path | |
| | | |
| === IContentMetaDatabase === | | === IContentMetaDatabase === |
Line 398: |
Line 394: |
| | 2 || Remove || Takes a [[#ContentMetaKey|Content Meta Key]], and removes the associated record. | | | 2 || Remove || Takes a [[#ContentMetaKey|Content Meta Key]], and removes the associated record. |
| |- | | |- |
− | | 3 || GetContentIdByType || Takes a [[#ContentMetaKey|Content Meta Key]] and a u8 [[#ContentMetaType|Content Meta Type]]. Returns a [[#NcaID]]. | + | | 3 || GetContentIdByType || Takes a [[#ContentMetaKey|Content Meta Key]] and a u8 [[#ContentMetaType|Content Meta Type]]. Returns a [[#ContentId]]. |
| |- | | |- |
− | | 4 || ListContentInfo || Takes a type-6 buffer to write [[CNMT#Content_records|Content Record]] entries to, a [[#ContentMetaKey|Content Meta Key]], and a u32 index into the Content Record entries to start copying from. Returns a u32 entries_read. | + | | 4 || ListContentInfo || Takes a type-6 buffer to write [[CNMT#Content_records|Content Record]] entries to, a [[#ContentMetaKey|Content Meta Key]], and a s32 index into the Content Record entries to start copying from. Returns a s32 entries_read. |
| |- | | |- |
− | | 5 || List || Takes a type-6 buffer to write [[#ContentMetaKey|Content Meta Key]]s to, a u32 [[#ContentMetaType|Content Meta Type]], a u64 TID, a u64 TID_LOW, and u64 TID_HIGH. Writes into the buffer all Content Meta Keys with low <= record->title_id <= high, and record->type == type. Returns u32 numEntriesTotal, numEntriesWritten. Additionally requires record->title_id == TID, if record->type is Application, Patch, Add-On, or Delta, otherwise, you can pass 0 for type to ignore the type and list them all in the range. | + | | 5 || List || Takes a type-6 buffer to write [[#ContentMetaKey|Content Meta Key]]s to, a u32 [[#ContentMetaType|Content Meta Type]], a u64 TID, a u64 TID_LOW, and u64 TID_HIGH. Writes into the buffer all Content Meta Keys with low <= record->title_id <= high, and record->type == type. Returns s32 numEntriesTotal, numEntriesWritten. Additionally requires record->title_id == TID, if record->type is Application, Patch, Add-On, or Delta, otherwise, you can pass 0 for type to ignore the type and list them all in the range. |
| |- | | |- |
| | 6 || GetLatestContentMetaKey || Takes a u64 title id, and returns the [[#ContentMetaKey|Content Meta Key]] with the highest version field for that title id. | | | 6 || GetLatestContentMetaKey || Takes a u64 title id, and returns the [[#ContentMetaKey|Content Meta Key]] with the highest version field for that title id. |
Line 408: |
Line 404: |
| | 7 || [[#ListApplication]] || | | | 7 || [[#ListApplication]] || |
| |- | | |- |
− | | 8 || Has || Takes a [[#ContentMetaKey|Content Meta Key]] and returns whether that record is present in the database. | + | | 8 || Has || Takes a [[#ContentMetaKey|Content Meta Key]] and returns an output u8 bool indicating whether that record is present in the database. |
| |- | | |- |
− | | 9 || HasAll || Takes a type-5 buffer containing [[#ContentMetaKey|Content Meta Key]] (code assumes there are size/sizeof(meta_record) records in the buffer), and returns whether all of those records are present in the database. | + | | 9 || HasAll || Takes a type-0x5 input buffer containing an array of [[#ContentMetaKey|Content Meta Key]], and returns whether all of those records are present in the database. |
| |- | | |- |
| | 10 || GetSize || Takes a [[#ContentMetaKey|Content Meta Key]], and returns the size of the associated [[CNMT#Content_records|Content Records]]. | | | 10 || GetSize || Takes a [[#ContentMetaKey|Content Meta Key]], and returns the size of the associated [[CNMT#Content_records|Content Records]]. |
Line 420: |
Line 416: |
| | 13 || DisableForcibly || Closes the meta database, and causes all future IPC commands to the current session to return error 0xDC05. | | | 13 || DisableForcibly || Closes the meta database, and causes all future IPC commands to the current session to return error 0xDC05. |
| |- | | |- |
− | | 14 || [[#LookupOrphanContent]] || Takes a type-6 byte buffer, and a type-5 buffer of [[#NcaID]]s. | + | | 14 || [[#LookupOrphanContent]] || Takes a type-6 byte buffer, and a type-5 buffer of [[#ContentId]]s. |
| |- | | |- |
| | 15 || Commit || Flushes the in-memory database to savedata. | | | 15 || Commit || Flushes the in-memory database to savedata. |
| |- | | |- |
− | | 16 || HasContent || Takes a [[#ContentMetaKey|Content Meta Key]] and an [[#NcaID]]. Returns whether the content records for that content meta key contain the NcaID. | + | | 16 || HasContent || Takes a [[#ContentMetaKey|Content Meta Key]] and an [[#ContentId]]. Returns whether the content records for that content meta key contain the ContentId. |
| |- | | |- |
− | | 17 || ListContentMetaInfo || Takes a type-6 [[#ContentMetaKey|Content Meta Key]] output buffer, a u32 offset into that buffer, and an input [[#ContentMetaKey|Content Meta Key]]. | + | | 17 || ListContentMetaInfo || Takes a type-6 [[#ContentMetaKey|Content Meta Key]] output buffer, a s32 offset into that buffer, and an input [[#ContentMetaKey|Content Meta Key]]. |
| |- | | |- |
| | 18 || GetAttributes || Takes a [[#ContentMetaKey|Content Meta Key]], and returns u8 from ContentRecords + 6. | | | 18 || GetAttributes || Takes a [[#ContentMetaKey|Content Meta Key]], and returns u8 from ContentRecords + 6. |
Line 442: |
Line 438: |
| This function takes in a type 6 buffer to write entries to, and a u8 "filter" [[#Title_Types|type]]. If filter is zero, all update records will be copied to to the output buffer (space permitting). Otherwise, only titles with type == filter_type will be copied to the output buffer. | | This function takes in a type 6 buffer to write entries to, and a u8 "filter" [[#Title_Types|type]]. If filter is zero, all update records will be copied to to the output buffer (space permitting). Otherwise, only titles with type == filter_type will be copied to the output buffer. |
| | | |
− | This func returns a u32 num_entries_total, and a u32 num_entries_written. | + | This func returns a s32 num_entries_total, and a s32 num_entries_written. |
| | | |
| ==== ReadEntryMetaRecords ==== | | ==== ReadEntryMetaRecords ==== |
− | Takes a type-6 [[#ContentMetaKey|Content Meta Key]] output buffer, a u32 offset into that buffer, and an input [[#ContentMetaKey|Content Meta Key]] entry. Returns a u32 for total_read_entries. | + | Takes a type-6 [[#ContentMetaKey|Content Meta Key]] output buffer, a s32 offset into that buffer, and an input [[#ContentMetaKey|Content Meta Key]] entry. Returns a s32 for total_read_entries. |
| | | |
| Reads the content meta keys stored in the entry's content records into the output buffer. | | Reads the content meta keys stored in the entry's content records into the output buffer. |
Line 452: |
Line 448: |
| | | |
| ==== LookupOrphanContent ==== | | ==== LookupOrphanContent ==== |
− | Takes a type-6 byte buffer, and a type-5 buffer containing [[#NcaID]]s. | + | Takes a type-6 byte buffer, and a type-0x5 buffer containing an array of [[#ContentId]]. |
| | | |
| This function was stubbed to return 0xDC05 in [[2.0.0]]. | | This function was stubbed to return 0xDC05 in [[2.0.0]]. |
| | | |
− | On 1.0.0: Initialized the output buffer to all 1s. Then, for each [[#NcaID]] in the input buffer, it checks if that NcaID is present anywhere in the database, and if so writes 0 to the corresponding output byte. | + | On 1.0.0: Initialized the output buffer to all 1s. Then, for each [[#ContentId]] in the input buffer, it checks if that ContentId is present anywhere in the database, and if so writes 0 to the corresponding output byte. |
| | | |
| In pseudocode, the function basically does the following: | | In pseudocode, the function basically does the following: |
Line 463: |
Line 459: |
| out_buf[i] = 1 | | out_buf[i] = 1 |
| | | |
− | for i, NcaID in NcaIDs: | + | for i, ContentId in ContentId: |
− | if is_present_in_database(NcaID): | + | if is_present_in_database(ContentId): |
| out_buf[i] = 0 | | out_buf[i] = 0 |
| | | |
− | === NcaID === | + | === ContentId === |
− | This is a 0x10-byte entry. This is originally from the hex portion of "<hex>.nca" directory-names from this storage FS(like [[SD_Filesystem|SD]]). This is also referred to as "ContentId" in the official SDK. | + | This is "nn::ncm::ContentId". |
| | | |
− | The NcaID is the same as the first 0x10-bytes from the calculated SHA256 hash, from hashing the entire output from [[#ReadContentIdFile]]. | + | This is a 0x10-byte entry. This is originally from the hex portion of "<hex>.nca" directory-names from this storage FS(like [[SD_Filesystem|SD]]). |
| + | |
| + | The ContentId is the same as the first 0x10-bytes from the calculated SHA256 hash, from hashing the entire output from [[#ReadContentIdFile]]. |
| + | |
| + | === PlaceHolderId === |
| + | This is "nn::ncm::PlaceHolderId". |
| + | |
| + | This is the same as [[#ContentId]], except this is for placeholder content and originates from [[#GeneratePlaceHolderId]]. |
| | | |
| == ContentInstallType == | | == ContentInstallType == |
Line 573: |
Line 576: |
| |- | | |- |
| | 0x9 || 0x7 || Padding | | | 0x9 || 0x7 || Padding |
| + | |} |
| + | |
| + | == Path == |
| + | This is "nn::ncm::Path". |
| + | |
| + | This is a 0x300-byte structure, which contains a [[Filesystem_services#ContentPath|Content Path]]. |
| + | |
| + | == RightsId == |
| + | This is "nn::ncm::RightsId". This is a 0x10-byte struct. [3.0.0+] This is a 0x18-byte struct. |
| + | |
| + | {| class="wikitable" border="1" |
| + | |- |
| + | ! Offset |
| + | ! Size |
| + | ! Description |
| + | |- |
| + | | 0x0 || 0x10 || FS Rights ID |
| + | |- |
| + | | 0x10 || 0x1 || [3.0.0+] key_generation |
| + | |- |
| + | | 0x11 || 0x7 || [3.0.0+] Padding |
| |} | | |} |
| | | |