Changes

737 bytes added ,  02:07, 27 October 2019
no edit summary
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
 
|}
 
|}