Difference between revisions of "NCM services"

From Nintendo Switch Brew
Jump to navigation Jump to search
(→‎lr: cross-reference link to StorageID)
 
(102 intermediate revisions by 10 users not shown)
Line 1: Line 1:
LR (Location Resolver) contains services for internal file path and content management.
+
NCM contains services for internal file path and content management.
 +
 
 +
= lr =
 +
This is "nn::lr::ILocationResolverManager".
  
= LR services =
 
== lr ==
 
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name
 
|-
 
|-
| 0 || GetPathResolverForStorage || Takes a [[Filesystem_services#StorageId|StorageID]]
+
| 0 || [[#OpenLocationResolver|OpenLocationResolver]]
 
|-
 
|-
| 1 || GetPatchPathResolver? ||  
+
| 1 || [[#OpenRegisteredLocationResolver|OpenRegisteredLocationResolver]]
 
|-
 
|-
| 2 || CheckStorage || Takes a [[Filesystem_services#StorageId|StorageID]]
+
| 2 || [[#RefreshLocationResolver|RefreshLocationResolver]]
 
|-
 
|-
| 3 || ||  
+
| 3 || [2.0.0+] [[#OpenAddOnContentLocationResolver|OpenAddOnContentLocationResolver]]
 +
|-
 +
| 4 || [15.0.0+] [[#SetEnabled|SetEnabled]]
 
|}
 
|}
  
=== IPathResolver ===
+
The only sysmodules which use this service are [[Filesystem_services|FS]], [[Loader_services|Loader]], and [[NS_Services|NS]]. [[boot2]] has access but doesn't use it.
 +
 
 +
== OpenLocationResolver ==
 +
Takes an input [[#StorageId]]. Returns an [[#ILocationResolver]].
 +
 
 +
== OpenRegisteredLocationResolver ==
 +
No input. Returns an [[#IRegisteredLocationResolver]].
 +
 
 +
== RefreshLocationResolver ==
 +
Takes an input [[#StorageId]]. No output.
 +
 
 +
== OpenAddOnContentLocationResolver ==
 +
No input. Returns an [[#IAddOnContentLocationResolver]].
 +
 
 +
== SetEnabled ==
 +
Unofficial name.
 +
 
 +
Takes a type-0x5 input buffer containing an array of [[#StorageId]]. No output.
 +
 
 +
== ILocationResolver ==
 +
This is "nn::lr::ILocationResolver".
 +
 
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name
 
|-
 
|-
| 0 || GetProgramNcaPath ||
+
| 0 || [[#ResolveProgramPath|ResolveProgramPath]]
 
|-
 
|-
| 1 || SetProgramNcaPath ||
+
| 1 || [[#RedirectProgramPath|RedirectProgramPath]]
 
|-
 
|-
| 2 || ||
+
| 2 || [[#ResolveApplicationControlPath|ResolveApplicationControlPath]]
 
|-
 
|-
| 3 || ||
+
| 3 || [[#ResolveApplicationHtmlDocumentPath|ResolveApplicationHtmlDocumentPath]]
 
|-
 
|-
| 4 || GetControlNcaPath ||
+
| 4 || [[#ResolveDataPath|ResolveDataPath]]
 
|-
 
|-
| 5 || SetControlNcaPath ||
+
| 5 || [[#RedirectApplicationControlPath|RedirectApplicationControlPath]]
 
|-
 
|-
| 6 || ||
+
| 6 || [[#RedirectApplicationHtmlDocumentPath|RedirectApplicationHtmlDocumentPath]]
 
|-
 
|-
| 7 || ||
+
| 7 || [[#ResolveApplicationLegalInformationPath|ResolveApplicationLegalInformationPath]]
 
|-
 
|-
| 8 || ||
+
| 8 || [[#RedirectApplicationLegalInformationPath|RedirectApplicationLegalInformationPath]]
 
|-
 
|-
| 9 || ||
+
| 9 || [[#Refresh|Refresh]]
 +
|-
 +
| 10 || [5.0.0+] [[#RedirectApplicationProgramPath|RedirectApplicationProgramPath]]
 +
|-
 +
| 11 || [5.0.0+] [[#ClearApplicationRedirection|ClearApplicationRedirection]]
 +
|-
 +
| 12 || [5.0.0+] [[#EraseProgramRedirection|EraseProgramRedirection]]
 +
|-
 +
| 13 || [5.0.0+] [[#EraseApplicationControlRedirection|EraseApplicationControlRedirection]]
 +
|-
 +
| 14 || [5.0.0+] [[#EraseApplicationHtmlDocumentRedirection|EraseApplicationHtmlDocumentRedirection]]
 +
|-
 +
| 15 || [5.0.0+] [[#EraseApplicationLegalInformationRedirection|EraseApplicationLegalInformationRedirection]]
 +
|-
 +
| 16 || [7.0.0+] [[#ResolveProgramPathForDebug|ResolveProgramPathForDebug]]
 +
|-
 +
| 17 || [7.0.0+] [[#RedirectProgramPathForDebug|RedirectProgramPathForDebug]]
 +
|-
 +
| 18 || [7.0.0+] [[#RedirectApplicationProgramPathForDebug|RedirectApplicationProgramPathForDebug]]
 +
|-
 +
| 19 || [7.0.0+] [[#EraseProgramRedirectionForDebug|EraseProgramRedirectionForDebug]]
 +
|-
 +
| 20 || [15.0.0+] [[#Disable|Disable]]
 
|}
 
|}
  
= Content Manager services =
+
If the supplied [[#StorageId]] is 1 (Host), a different set of internal functions is used to handle these commands. In this more restricted set of functions, [[#ResolveApplicationControlPath|ResolveApplicationControlPath]] is stubbed and only returns error 0x608.
== ncm ==
+
 
 +
The Get* commands load the [[#Path|Path]] from linked-lists' [[#LocationListEntry|entries]] in memory using the input [[#ProgramId]]. When the command fails to find an entry for the specified [[#ProgramId]], 0x408 is returned for [[#ResolveProgramPath|ResolveProgramPath]] and 0xA08 is returned for the rest.
 +
 
 +
The Set* commands always return 0 and add a new entry to the list. If a matching entry is found, it's removed first.
 +
 
 +
=== ResolveProgramPath ===
 +
Takes an input [[#ProgramId]] and a type-0x1A output buffer. No output.
 +
 
 +
=== RedirectProgramPath ===
 +
Takes an input [[#ProgramId]] and a type-0x19 input buffer containing a [[#Path|Path]]. No output.
 +
 
 +
Inserts a new [[#LocationListEntry|entry]] with '''flag''' set to 0.
 +
 
 +
=== ResolveApplicationControlPath ===
 +
Takes an input [[#ApplicationId]] and a type-0x1A output buffer. No output.
 +
 
 +
=== ResolveApplicationHtmlDocumentPath ===
 +
Takes an input [[#ApplicationId]] and a type-0x1A output buffer. No output.
 +
 
 +
=== ResolveDataPath ===
 +
Takes an input [[#DataId]] and a type-0x1A output buffer. No output.
 +
 
 +
=== RedirectApplicationControlPath ===
 +
Takes an input [[#ApplicationId]] and a type-0x19 input buffer containing a [[#Path|Path]]. No output.
 +
 
 +
[9.0.0+] Now takes an additional 8-bytes of input.
 +
 
 +
Inserts a new [[#LocationListEntry|entry]] with '''flag''' set to 1.
 +
 
 +
=== RedirectApplicationHtmlDocumentPath ===
 +
Takes an input [[#ApplicationId]] and a type-0x19 input buffer containing a [[#Path|Path]]. No output.
 +
 
 +
[9.0.0+] Now takes an additional 8-bytes of input.
 +
 
 +
Inserts a new [[#LocationListEntry|entry]] with '''flag''' set to 1.
 +
 
 +
=== ResolveApplicationLegalInformationPath ===
 +
Takes an input [[#ApplicationId]] and a type-0x1A output buffer. No output.
 +
 
 +
=== RedirectApplicationLegalInformationPath ===
 +
Takes an input [[#ApplicationId]] and a type-0x19 input buffer containing a [[#Path|Path]]. No output.
 +
 
 +
[9.0.0+] Now takes an additional 8-bytes of input.
 +
 
 +
Inserts a new [[#LocationListEntry|entry]] with '''flag''' set to 1.
 +
 
 +
=== Refresh ===
 +
No input/output.
 +
 
 +
Frees all linked-lists' entries that have '''flag''' set to 0.
 +
 
 +
=== RedirectApplicationProgramPath ===
 +
Same as [[#RedirectProgramPath|RedirectProgramPath]], but inserts a new [[#LocationListEntry|entry]] with '''flag''' set to 1.
 +
 
 +
[9.0.0+] Now takes an additional 8-bytes of input.
 +
 
 +
=== ClearApplicationRedirection ===
 +
No input/output.
 +
 
 +
Frees all linked-lists' entries that have '''flag''' set to 1.
 +
 
 +
[9.0.0+] Now takes a type-0x5 input buffer.
 +
 
 +
=== EraseProgramRedirection ===
 +
Takes an input [[#ProgramId]]. No output.
 +
 
 +
Removes the [[#LocationListEntry|entry]] that matches the input [[#ProgramId]].
 +
 
 +
=== EraseApplicationControlRedirection ===
 +
Takes an input [[#ApplicationId]]. No output.
 +
 
 +
Removes the [[#LocationListEntry|entry]] that matches the input [[#ApplicationId]].
 +
 
 +
=== EraseApplicationHtmlDocumentRedirection ===
 +
Takes an input [[#ApplicationId]]. No output.
 +
 
 +
Removes the [[#LocationListEntry|entry]] that matches the input [[#ApplicationId]].
 +
 
 +
=== EraseApplicationLegalInformationRedirection ===
 +
Takes an input [[#ApplicationId]]. No output.
 +
 
 +
Removes the [[#LocationListEntry|entry]] that matches the input [[#ApplicationId]].
 +
 
 +
=== ResolveProgramPathForDebug ===
 +
Unofficial name.
 +
 
 +
Same as [[#ResolveProgramPath|ResolveProgramPath]], but uses a redirection shim on top of the real program path.
 +
 
 +
[[NS_Services|NS]] uses this command if [[System_Settings#ns.application|ns.application!redirected_rom_storage_id_for_debug]] is different than 0x00.
 +
 
 +
=== RedirectProgramPathForDebug ===
 +
Unofficial name.
 +
 
 +
Same as [[#RedirectProgramPath|RedirectProgramPath]], but uses a redirection shim on top of the real program path.
 +
 
 +
[[NS_Services|NS]] uses this command if [[System_Settings#ns.application|ns.application!redirected_rom_storage_id_for_debug]] is different than 0x00.
 +
 
 +
=== RedirectApplicationProgramPathForDebug ===
 +
Unofficial name.
 +
 
 +
Same as [[#RedirectApplicationProgramPath|RedirectApplicationProgramPath]], but uses a redirection shim on top of the real program path.
 +
 
 +
[9.0.0+] Like [[#RedirectApplicationProgramPath]] this now takes an additional 8-bytes of input.
 +
 
 +
[[NS_Services|NS]] uses this command if [[System_Settings#ns.application|ns.application!redirected_rom_storage_id_for_debug]] is different than 0x00.
 +
 
 +
=== EraseProgramRedirectionForDebug ===
 +
Unofficial name.
 +
 
 +
Same as [[#EraseProgramRedirection|EraseProgramRedirection]], but uses a redirection shim on top of the real program path.
 +
 
 +
[[NS_Services|NS]] uses this command if [[System_Settings#ns.application|ns.application!redirected_rom_storage_id_for_debug]] is different than 0x00.
 +
 
 +
=== Disable ===
 +
Unofficial name.
 +
 
 +
No input/output.
 +
 
 +
== IRegisteredLocationResolver ==
 +
This is "nn::lr::IRegisteredLocationResolver".
 +
 
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name
|-
 
| 0 || ||
 
 
|-
 
|-
| 1 || ||  
+
| 0 || [[#ResolveProgramPath_2|ResolveProgramPath]]
 
|-
 
|-
| 2 || ||  
+
| 1 || [[#RegisterProgramPath|RegisterProgramPath]]
 
|-
 
|-
| 3 || ||  
+
| 2 || [[#UnregisterProgramPath|UnregisterProgramPath]]
 
|-
 
|-
| 4 || GetIContentStorage ||
+
| 3 || [[#RedirectProgramPath_2|RedirectProgramPath]]
 
|-
 
|-
| 5 || GetIContentMetaDatabase ||
+
| 4 || [2.0.0+] [[#ResolveHtmlDocumentPath|ResolveHtmlDocumentPath]]
 
|-
 
|-
| 8 || ||  
+
| 5 || [2.0.0+] [[#RegisterHtmlDocumentPath|RegisterHtmlDocumentPath]]
 
|-
 
|-
| 9 || InitializeStorageForMediaId ||
+
| 6 || [2.0.0+] [[#UnregisterHtmlDocumentPath|UnregisterHtmlDocumentPath]]
 
|-
 
|-
| 10 || UninitializeStorageForMediaId ||
+
| 7 || [2.0.0+] [[#RedirectHtmlDocumentPath|RedirectHtmlDocumentPath]]
 
|-
 
|-
| 11 || InitializeDatabaseForMediaId ||
+
| 8 || [7.0.0+] [[#Refresh_2|Refresh]]
 
|-
 
|-
| 12 || UninitializeDatabaseForMediaId ||
+
| 9 || [9.0.0+] [[#RefreshExcluding|RefreshExcluding]]
 
|}
 
|}
  
All of the above cmds takes a u8 as input.
+
This works like [[#ILocationResolver]], but only two types of NCA paths can be gotten/set. In addition, each type has a fallback path that can be set for a single [[#ProgramId]] at a time.
 +
 
 +
=== ResolveProgramPath ===
 +
Takes an input [[#ProgramId]] and a type-0x1A output buffer. No output.
 +
 
 +
=== RegisterProgramPath ===
 +
Takes an input [[#ProgramId]] and a type-0x19 input buffer containing a [[#Path|Path]]. No output.
 +
 
 +
[9.0.0+] Now takes an additional 8-bytes of input.
 +
 
 +
=== UnregisterProgramPath ===
 +
Takes an input [[#ProgramId]]. No output.
 +
 
 +
=== RedirectProgramPath ===
 +
Takes an input [[#ProgramId]] and a type-0x19 input buffer containing a [[#Path|Path]]. No output.
 +
 
 +
[9.0.0+] Now takes an additional 8-bytes of input.
 +
 
 +
=== ResolveHtmlDocumentPath ===
 +
Takes an input [[#ApplicationId]] and a type-0x1A output buffer. No output.
 +
 
 +
=== RegisterHtmlDocumentPath ===
 +
Takes an input [[#ApplicationId]] and a type-0x19 input buffer containing a [[#Path|Path]]. No output.
 +
 
 +
[9.0.0+] Now takes an additional 8-bytes of input.
 +
 
 +
=== UnregisterHtmlDocumentPath ===
 +
Takes an input [[#ApplicationId]]. No output.
 +
 
 +
=== RedirectHtmlDocumentPath ===
 +
Takes an input [[#ApplicationId]] and a type-0x19 input buffer containing a [[#Path|Path]]. No output.
 +
 
 +
[9.0.0+] Now takes an additional 8-bytes of input.
 +
 
 +
=== Refresh ===
 +
No input/output.
 +
 
 +
=== RefreshExcluding ===
 +
Unofficial name.
 +
 
 +
Takes a type-0x5 input buffer containing an array of [[#ProgramId]]. No output.
 +
 
 +
== IAddOnContentLocationResolver ==
 +
This is "nn::lr::IAddOnContentLocationResolver".
  
=== IContentStorage ===
 
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name
 
|-
 
|-
| 0 || [[#GetRootEntry]] ||
+
| 0 || [[#ResolveAddOnContentPath|ResolveAddOnContentPath]]
 
|-
 
|-
| 1 || || Takes two 0x10-sized entries, and a u64.
+
| 1 || [[#RegisterAddOnContentStorage|RegisterAddOnContentStorage]]
 
|-
 
|-
| 2 || || Takes a 0x10-sized entry.
+
| 2 || [[#UnregisterAllAddOnContentPath|UnregisterAllAddOnContentPath]]
 
|-
 
|-
| 3 || || Takes a 0x10-sized entry, returns a bool/u8.
+
| 3 || [9.0.0+] [[#RefreshApplicationAddOnContent|RefreshApplicationAddOnContent]]
 
|-
 
|-
| 4 || || Takes a 0x10-sized entry, a u64-offset, and type-5 array.
+
| 4 || [9.0.0+] [[#UnregisterApplicationAddOnContent|UnregisterApplicationAddOnContent]]
 
|-
 
|-
| 5 || || Takes two 0x10-sized entries.
+
| 5 || [15.0.0+] [[#GetRegisteredAddOnContentPaths|GetRegisteredAddOnContentPaths]]
 
|-
 
|-
| 6 || DeleteContent? || Takes a 0x10-sized entry.
+
| 6 || [15.0.0+] [[#RegisterAddOnContentPath|RegisterAddOnContentPath]]
 
|-
 
|-
| 7 || IsNcaEntryValid || Takes a 0x10-sized entry, returns a bool/u8.
+
| 7 || [15.0.0+] [[#RegisterAddOnContentPaths|RegisterAddOnContentPaths]]
 +
|}
 +
 
 +
=== ResolveAddOnContentPath ===
 +
Takes an input [[#DataId]] and a type-0x1A output buffer. No output.
 +
 
 +
=== RegisterAddOnContentStorage ===
 +
Takes an input [[#StorageId]] and an input [[#DataId]]. No output.
 +
 
 +
[9.0.0+] Now takes an additional input [[#ApplicationId]] for the owner application.
 +
 
 +
=== UnregisterAllAddOnContentPath ===
 +
No input/output.
 +
 
 +
=== RefreshApplicationAddOnContent ===
 +
Unofficial name.
 +
 
 +
Takes a type-0x5 input buffer containing an array of [[#ApplicationId]]. No output.
 +
 
 +
Unregisters entries with IDs absent from the input buffer.
 +
 
 +
=== UnregisterApplicationAddOnContent ===
 +
Unofficial name.
 +
 
 +
Takes an input [[#ApplicationId]]. No output.
 +
 
 +
Unregisters add on content entries for the input [[#ApplicationId]].
 +
 
 +
=== GetRegisteredAddOnContentPaths ===
 +
Unofficial name.
 +
 
 +
Takes an input [[#DataId]] and two type-0x16 output buffers. No output.
 +
 
 +
=== RegisterAddOnContentPath ===
 +
Unofficial name.
 +
 
 +
Takes an input [[#DataId]], an input [[#ApplicationId]] and a type-0x15 input buffer. No output.
 +
 
 +
=== RegisterAddOnContentPaths ===
 +
Unofficial name.
 +
 
 +
Takes an input [[#DataId]], an input [[#ApplicationId]] and two type-0x15 input buffers. No output.
 +
 
 +
= ncm =
 +
This is "nn::ncm::IContentManager".
 +
 
 +
{| class="wikitable" border="1"
 
|-
 
|-
| 8 || MakeNcaRegisteredPath || Takes a type-0x1A string and a 0x10-sized entry.
+
! Cmd || Name
 
|-
 
|-
| 9 || MakeNcaPlaceholderPath || Takes a type-0x1A string and a 0x10-sized entry.
+
| 0 || [[#CreateContentStorage|CreateContentStorage]]
 
|-
 
|-
| 10 || || Void.
+
| 1 || [[#CreateContentMetaDatabase|CreateContentMetaDatabase]]
 
|-
 
|-
| 11 || || Takes a type-6 buffer, each entry 0x10 bytes, and returns a u32.
+
| 2 || [[#VerifyContentStorage|VerifyContentStorage]]
 
|-
 
|-
| 12 || [[#GetNumberOfEntries]] ||
+
| 3 || [[#VerifyContentMetaDatabase|VerifyContentMetaDatabase]]
 
|-
 
|-
| 13 || [[#GetEntries]] ||
+
| 4 || [[#OpenContentStorage|OpenContentStorage]]
 
|-
 
|-
| 14 || [[#GetEntrySize]] ||
+
| 5 || [[#OpenContentMetaDatabase|OpenContentMetaDatabase]]
 
|-
 
|-
| 15 || || Void.
+
| 6 || [1.0.0] [[#CloseContentStorageForcibly|CloseContentStorageForcibly]]
 
|-
 
|-
| 16 || || Takes three 0x10-sized entries.
+
| 7 || [1.0.0] [[#CloseContentMetaDatabaseForcibly|CloseContentMetaDatabaseForcibly]]
 
|-
 
|-
| 17 || || Takes a 0x10-sized entry and a u64.
+
| 8 || [[#CleanupContentMetaDatabase|CleanupContentMetaDatabase]]
 
|-
 
|-
| 18 || [[#ReadEntryRaw]] ||
+
| 9 || [2.0.0+] [[#ActivateContentStorage|ActivateContentStorage]]
 
|-
 
|-
| 19 || || Takes a 0x10-sized entry and returns another 0x10-sized entry.
+
| 10 || [2.0.0+] [[#InactivateContentStorage|InactivateContentStorage]]
 
|-
 
|-
| 20 || [[#GetNcaTitleInfo]] ||
+
| 11 || [2.0.0+] [[#ActivateContentMetaDatabase|ActivateContentMetaDatabase]]
 
|-
 
|-
| 21 || || Takes a 0x10-sized entry, a u64, and a type5 buffer.
+
| 12 || [2.0.0+] [[#InactivateContentMetaDatabase|InactivateContentMetaDatabase]]
 
|-
 
|-
| 22 || GetFreeSpace ||
+
| 13 || [9.0.0+] [[#InvalidateRightsIdCache|InvalidateRightsIdCache]]
 
|-
 
|-
| 23 || GetTotalSpace ||
+
| 14 || [10.0.0+] [[#GetMemoryReport|GetMemoryReport]]
 
|}
 
|}
  
==== GetRootEntry ====
+
== CreateContentStorage ==
Returns an entry of 16 completely random-looking bytes. It is not possible to read this entry.
+
Takes an input [[#StorageId]]. No output.
  
Changes on reboot?
+
== CreateContentMetaDatabase ==
 +
Takes an input [[#StorageId]]. No output.
  
==== GetNumberOfEntries ====
+
== VerifyContentStorage ==
Writes the total number of entries which can be read by GetEntries, to cmdreply <SFCO_offset>+0x10.
+
Takes an input [[#StorageId]]. No output.
  
==== GetEntries ====
+
== VerifyContentMetaDatabase ==
Takes an output buffer, u32 offset and gets all entries starting at that offset.
+
Takes an input [[#StorageId]]. No output.
Returns number of entries read.
 
  
Each entry is a [[#NcaID]].
+
== OpenContentStorage ==
 +
Takes an input [[#StorageId]]. Returns an [[#IContentStorage]].
  
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?).
+
[2.0.0+] Only returns a storage if one has previously been opened globally via [[#CreateContentStorage|CreateContentStorage]].
 +
 
 +
== OpenContentMetaDatabase ==
 +
Takes an input [[#StorageId]]. Returns an [[#IContentMetaDatabase]].
 +
 
 +
[2.0.0+] Only returns a storage if one has previously been opened globally via [[#CreateContentStorage|CreateContentStorage]].
  
==== GetEntrySize ====
+
== CloseContentStorageForcibly ==
Takes a [[#NcaID]] as input.
+
Takes an input [[#StorageId]]. No output.
  
Returns the total size readable by ReadEntryRaw. This is the same as the size-field in the [[NAX0]] "<NcaID>.nca/00" file.
+
== CloseContentMetaDatabaseForcibly ==
 +
Takes an input [[#StorageId]]. No output.
  
==== ReadEntryRaw ====
+
== CleanupContentMetaDatabase ==
Takes an output buffer, a [[#NcaID]] as input, and a u64 file offset.
+
Takes an input [[#StorageId]]. No output.
  
Returns encrypted looking data from the content in the [[NAX0]]. Doesn't match the encrypted raw data in the [[NAX0]] "<NcaID>.nca/00" file. Seems to be at least one crypto layer below the initial NAX0 layer, since the data doesn't change after NAX0 recreation.
+
== ActivateContentStorage ==
 +
Takes an input [[#StorageId]]. No output.
  
Manually modifying the content in the NAX0(starting at offset 0x4000) results in different output data being returned by this cmd. Changing any data within the first 0x10-bytes results in the entire 0x10-byte block changing. Likewise for offset 0x4010 size 0x1, entire 0x10-byte block at 0x4010 changes. Changing the first 0x20-bytes at 0x4000 to zeros has the same combined changed output, as when offset 0x4000 size 0x10 and offset 0x4010 size 0x10 were changed to zeros separately. Output BlockA and BlockB are completely different, where the raw NAX0 data for those blocks are all-zero.
+
== InactivateContentStorage ==
 +
Takes an input [[#StorageId]]. No output.
  
Overwriting the entire raw NAX0 content with zeros results in output data which doesn't seem to have any duplicate blocks/data. When changing the previously mentioned raw content for the first 8 blocks to last-block-byte = 1<<i, where i is 0-7, none of the changed output blocks match any output blocks from the previously mentioned output(all-zero raw content).
+
== ActivateContentMetaDatabase ==
 +
Takes an input [[#StorageId]]. No output.
  
This implies that that an AES mode is being used which isn't CTR, where changing data in one block doesn't affect other blocks.
+
== InactivateContentMetaDatabase ==
 +
Takes an input [[#StorageId]]. No output.
  
See GetEntrySize for the total size readable with this.
+
== InvalidateRightsIdCache ==
 +
No input/output.
  
==== GetNcaTitleInfo ====
+
== GetMemoryReport ==
Takes a [[#NcaID]] and returns the following 0x10-sized entry.
+
No input. Returns an output [[#MemoryReport]].
  
With some NcaIDs this may return 0 with an all-zero output entry. This seems to be the case for most/all (?) NandSystem NcaIds? This seems to be only usable with NcaIds which have [[NCA|type]] 1 or 4.
+
== IContentStorage ==
 +
This is "nn::ncm::IContentStorage".
  
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Offset
+
! Cmd || Name
! Size
+
|-
! Description
+
| 0 || [[#GeneratePlaceHolderId|GeneratePlaceHolderId]]
 +
|-
 +
| 1 || [[#CreatePlaceHolder|CreatePlaceHolder]]
 +
|-
 +
| 2 || [[#DeletePlaceHolder|DeletePlaceHolder]]
 +
|-
 +
| 3 || [[#HasPlaceHolder|HasPlaceHolder]]
 +
|-
 +
| 4 || [[#WritePlaceHolder|WritePlaceHolder]]
 +
|-
 +
| 5 || [[#Register|Register]]
 +
|-
 +
| 6 || [[#Delete|Delete]]
 +
|-
 +
| 7 || [[#Has|Has]]
 +
|-
 +
| 8 || [[#GetPath|GetPath]]
 +
|-
 +
| 9 || [[#GetPlaceHolderPath|GetPlaceHolderPath]]
 +
|-
 +
| 10 || [[#CleanupAllPlaceHolder|CleanupAllPlaceHolder]]
 +
|-
 +
| 11 || [[#ListPlaceHolder|ListPlaceHolder]]
 +
|-
 +
| 12 || [[#GetContentCount|GetContentCount]]
 +
|-
 +
| 13 || [[#ListContentId|ListContentId]]
 +
|-
 +
| 14 || [[#GetSizeFromContentId|GetSizeFromContentId]]
 +
|-
 +
| 15 || [[#DisableForcibly|DisableForcibly]]
 +
|-
 +
| 16 || [2.0.0+] [[#RevertToPlaceHolder|RevertToPlaceHolder]]
 +
|-
 +
| 17 || [2.0.0+] [[#SetPlaceHolderSize|SetPlaceHolderSize]]
 +
|-
 +
| 18 || [2.0.0+] [[#ReadContentIdFile|ReadContentIdFile]]
 +
|-
 +
| 19 || [2.0.0+] [[#GetRightsIdFromPlaceHolderId|GetRightsIdFromPlaceHolderId]]
 +
|-
 +
| 20 || [2.0.0+] [[#GetRightsIdFromContentId|GetRightsIdFromContentId]]
 +
|-
 +
| 21 || [2.0.0+] [[#WriteContentForDebug|WriteContentForDebug]]
 +
|-
 +
| 22 || [2.0.0+] GetFreeSpaceSize
 +
|-
 +
| 23 || [2.0.0+] GetTotalSpaceSize
 +
|-
 +
| 24 || [3.0.0+] FlushPlaceHolder
 +
|-
 +
| 25 || [4.0.0+] GetSizeFromPlaceHolderId
 +
|-
 +
| 26 || [4.0.0+] RepairInvalidFileAttribute
 +
|-
 +
| 27 || [8.0.0+] GetRightsIdFromPlaceHolderIdWithCache
 
|-
 
|-
| 0x0
+
| 28 || [13.0.0+] RegisterPath
| 0x8
 
| Big-endian titleID
 
 
|-
 
|-
| 0x8
+
| 29 || [13.0.0+] ClearRegisteredPath
| 0x8
 
| Unknown. Usually zero?
 
 
|}
 
|}
  
=== IContentMetaDatabase ===
+
=== GeneratePlaceHolderId ===
 +
No input. Returns an output [[#PlaceHolderId]].
 +
 
 +
Calls nn::util::GenerateUuid(), which internally calls nn::os::GenerateRandomBytes(16);
 +
 
 +
=== CreatePlaceHolder ===
 +
Takes an input [[#ContentId]], an input [[#PlaceHolderId]] and an input s64 '''FileSize'''. No output.
 +
 
 +
=== DeletePlaceHolder ===
 +
Takes an input [[#PlaceHolderId]]. No output.
 +
 
 +
=== HasPlaceHolder ===
 +
Takes an input [[#PlaceHolderId]]. Returns an output bool.
 +
 
 +
=== WritePlaceHolder ===
 +
Takes an input [[#PlaceHolderId]], an input u64 '''Offset''' and a type-0x5 input buffer. No output.
 +
 
 +
Writes the buffer to the file for the placeholder path at the specified offset.
 +
 
 +
=== Register ===
 +
Takes a [[#ContentId]] and a [[#PlaceHolderId]], no output. Moves the Placeholder NCA content to the registered NCA path.
 +
 
 +
=== Delete ===
 +
Takes a [[#ContentId]].
 +
 
 +
=== Has ===
 +
Takes a [[#ContentId]].
 +
 
 +
=== GetPath ===
 +
Takes a [[#ContentId]] and a type-0x1A output buffer containing a [[#Path|Path]].
 +
 
 +
=== GetPlaceHolderPath ===
 +
Takes a [[#PlaceHolderId]] and a type-0x1A output buffer containing a [[#Path|Path]].
 +
 
 +
=== CleanupAllPlaceHolder ===
 +
No input/output.
 +
 
 +
Deletes and re-creates the "Placeholder" directory.
 +
 
 +
=== ListPlaceHolder ===
 +
This is like [[#GetNumberOfRegisteredEntries|GetNumberOfRegisteredEntries]], but for the "Placeholder" directory.
 +
 
 +
=== GetContentCount ===
 +
No input. Returns an output u32 '''Count'''.
 +
 
 +
=== ListContentId ===
 +
Takes an output buffer, s32 offset and gets all entries starting at that offset. Returns number of entries read.
 +
 
 +
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?).
 +
 
 +
=== GetSizeFromContentId ===
 +
Takes a [[#ContentId]] as input.
 +
 
 +
Returns the total size readable by [[#ReadContentIdFile]]. This is the same as the size-field in the [[NAX0]] "<ContentId>.nca/00" file.
 +
 
 +
=== 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.
 +
 
 +
=== RevertToPlaceHolder ===
 +
Takes two [[#ContentId]] and a [[#PlaceHolderId]], no output.
 +
 
 +
Creates the registered directory NCA path, and renames the placeholder path to the registered NCA path.
 +
 
 +
=== SetPlaceHolderSize ===
 +
Takes a [[#PlaceHolderId]], and a s64 size, no output.
 +
 
 +
=== ReadContentIdFile ===
 +
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 ContentId.
 +
 
 +
=== GetRightsIdFromPlaceHolderId ===
 +
Takes a [[#PlaceHolderId]], returns a [[#RightsId]].
 +
 
 +
Gets the Rights ID for the [[#PlaceHolderId]]'s placeholder path.
 +
 
 +
=== GetRightsIdFromContentId ===
 +
Takes a [[#ContentId]], returns a [[#RightsId]].
 +
 
 +
Gets the Rights ID for the [[#ContentId]]'s registered path
 +
 
 +
=== 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.
 +
 
 +
== IContentMetaDatabase ==
 +
This is "nn::ncm::IContentMetaDatabase".
 +
 
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name
 +
|-
 +
| 0 || [[#Set|Set]]
 +
|-
 +
| 1 || [[#Get|Get]]
 +
|-
 +
| 2 || [[#Remove|Remove]]
 +
|-
 +
| 3 || [[#GetContentIdByType|GetContentIdByType]]
 +
|-
 +
| 4 || [[#ListContentInfo|ListContentInfo]]
 
|-
 
|-
| 0 || InsertContentEntry? || Takes a 0x10-sized entry, a type-5 buffer and a u64.
+
| 5 || [[#List|List]]
 
|-
 
|-
| 1 || || Takes a 0x10-sized entry, a type-6 buffer and a u64. Returns a u64.
+
| 6 || [[#GetLatestContentMetaKey|GetLatestContentMetaKey]]
 
|-
 
|-
| 2 || || Takes a 0x10-sized entry.
+
| 7 || [[#ListApplication|ListApplication]]
 
|-
 
|-
| 3 || || Takes a 0x10-sized entry and a bool/u8. Returns an 0x10-sized entry.
+
| 8 || [[#Has|Has]]
 
|-
 
|-
| 4 || || Takes a type-6 buffer, each entry being 24 bytes, 0x10-sized entry and a u32. Returns a u32.
+
| 9 || [[#HasAll|HasAll]]
 
|-
 
|-
| 5 || Iterate || Takes a type-6 buffer, each entry being 16 bytes, a 0x10-sized entry, and a u32. Returns a u32.
+
| 10 || [[#GetSize|GetSize]]
 
|-
 
|-
| 6 || [[#GetTitleIdInfo]] ||
+
| 11 || [[#GetRequiredSystemVersion|GetRequiredSystemVersion]]
 
|-
 
|-
| 7 || [[#GetTitleList]] || Takes a type-6 buffer, each entry being 24 bytes, and a u8/bool. Returns two u32's.
+
| 12 || [[#GetPatchId|GetPatchId]]
 
|-
 
|-
| 8 || || Takes a 0x10-sized entry. Returns a bool/u8.
+
| 13 || [[#DisableForcibly|DisableForcibly]]
 
|-
 
|-
| 9 || || Takes a type-5 buffer, each entry being 16 bytes. Returns a bool/u8.
+
| 14 || [[#LookupOrphanContent|LookupOrphanContent]]
 
|-
 
|-
| 10 || || Takes a 0x10-sized entry. Returns a u64.
+
| 15 || [[#Commit|Commit]]
 
|-
 
|-
| 11 || || Takes a 0x10-sized entry. Returns a u32.
+
| 16 || [[#HasContent|HasContent]]
 
|-
 
|-
| 12 || || Takes a 0x10-sized entry. Returns a u64.
+
| 17 || [[#ListContentMetaInfo|ListContentMetaInfo]]
 
|-
 
|-
| 13 || || Void.
+
| 18 || [[#GetAttributes|GetAttributes]]
 
|-
 
|-
| 14 || || Takes a type-6 byte buffer, and a type-5 buffer with each entry being 16 bytes.
+
| 19 || [2.0.0+] [[#GetRequiredApplicationVersion|GetRequiredApplicationVersion]]
 
|-
 
|-
| 15 || EndIteration || Void.
+
| 20 || [5.0.0+] [[#GetContentIdByTypeAndIdOffset|GetContentIdByTypeAndIdOffset]]
 
|-
 
|-
| 16 || || Takes two 0x10-sized entries. Returns a bool/u8.
+
| 21 || [10.0.0+] [[#GetCount|GetCount]]
 
|-
 
|-
| 17 || [[#GetUpdateTitleList]] ||
+
| 22 || [10.0.0+] [[#GetOwnerApplicationId|GetOwnerApplicationId]]  
 
|-
 
|-
| 18 || || Takes a 0x10-sized entry. Returns a bool/u8.
+
| 23 || [15.0.0+] GetContentAccessibilities
 
|-
 
|-
| 19 || || Takes a 0x10-sized entry. Returns a u32.
+
| 24 || [15.0.0+] GetContentInfoByType
 +
|-
 +
| 25 || [15.0.0+] GetContentInfoByTypeAndIdOffset
 
|}
 
|}
  
==== GetTitleIdInfo ====
+
=== Set ===
Takes a u64 title-id as input, returns same title-id together with info struct.
+
Takes a [[#ContentMetaKey]], a type-5 [[CNMT#PackagedContentInfo|PackagedContentInfo]] buffer and a u64 size.
 +
 
 +
=== Get ===
 +
Takes a [[#ContentMetaKey]], a type-6 buffer to write [[CNMT#PackagedContentInfo|PackagedContentInfo]] to and a u64 size. Returns the actual number of bytes read into the buffer.
 +
 
 +
First 8 bytes of the data is header (u16 numExtraDataBytes, numContentRecords, numMetaRecords, padding). After the header is numExtraDataBytes of additional data, after which follow content records and content meta keys. Set takes this same data as input.
 +
 
 +
=== Remove ===
 +
Takes a [[#ContentMetaKey]], and removes the associated record.
 +
 
 +
=== GetContentIdByType ===
 +
Takes a [[#ContentMetaKey]] and a u8 [[#ContentType]]. Returns a [[#ContentId]].
 +
 
 +
=== ListContentInfo ===
 +
Takes a type-6 buffer to write [[CNMT#PackagedContentInfo|PackagedContentInfo]] entries to, a [[#ContentMetaKey]], and a s32 index into the entries to start copying from. Returns a s32 entries_read.
 +
 
 +
=== List ===
 +
Takes a type-6 buffer to write [[#ContentMetaKey]]s to, a u32 [[#ContentMetaType]], a [[#ProgramId]], a u64 ProgramId_Low, and u64 ProgramId_High. Returns s32 numEntriesTotal, numEntriesWritten.
 +
 
 +
Writes into the buffer all Content Meta Keys with low <= record->title_id <= high, and record->type == type. 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.
 +
 
 +
=== GetLatestContentMetaKey ===
 +
Takes a [[#ProgramId]], and returns the [[#ContentMetaKey]] with the highest version field for that [[#ProgramId]].
 +
 
 +
=== ListApplication ===
 +
This function takes in a type 6 buffer to write [[#ApplicationContentMetaKey|ApplicationContentMetaKey]] entries to, and a u8 "filter". 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 s32 num_entries_total, and a s32 num_entries_written.
 +
 
 +
=== Has ===
 +
Takes a [[#ContentMetaKey]] and returns an output u8 bool indicating whether that record is present in the database.
 +
 
 +
=== HasAll ===
 +
Takes a type-0x5 input buffer containing an array of [[#ContentMetaKey]], and returns whether all of those records are present in the database.
 +
 
 +
=== GetSize ===
 +
Takes a [[#ContentMetaKey]], and returns the size of the associated [[CNMT#PackagedContentInfo|PackagedContentInfo]].
 +
 
 +
=== GetRequiredSystemVersion ===
 +
Takes an input [[#ContentMetaKey]]. Returns an output u32 '''RequiredSystemVersion'''.
 +
 
 +
=== GetPatchId ===
 +
Takes a [[#ContentMetaKey]], and returns the update [[#ProgramId]] for that record.
 +
 
 +
=== DisableForcibly ===
 +
Closes the meta database, and causes all future IPC commands to the current session to return error 0xDC05.
 +
 
 +
=== LookupOrphanContent ===
 +
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]].
 +
 
 +
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:
 +
 
 +
for i in range(len(out_buf)):
 +
    out_buf[i] = 1
 +
 +
for i, ContentId in ContentId:
 +
    if is_present_in_database(ContentId):
 +
        out_buf[i] = 0
 +
 
 +
=== Commit ===
 +
Flushes the in-memory database to savedata.
 +
 
 +
=== HasContent ===
 +
Takes a [[#ContentMetaKey]] and an [[#ContentId]]. Returns whether the content records for that content meta key contain the [[#ContentId]].
 +
 
 +
=== ListContentMetaInfo ===
 +
Takes a type-6 [[#ContentMetaKey]] output buffer, a s32 offset into that buffer, and an input [[#ContentMetaKey]].
 +
 
 +
=== GetAttributes ===
 +
Takes an input [[#ContentMetaKey]]. Returns an output u8 '''Attributes'''.
  
struct title_info {
+
=== GetRequiredApplicationVersion ===
  u32  version;
+
Does the same thing as [[#GetRequiredSystemVersion|GetRequiredSystemVersion]], but for AddOnContents.
  u8  type;
 
  u8  pad[3];
 
};
 
  
==== GetTitleList ====
+
=== GetContentIdByTypeAndIdOffset ===
Each 24-byte entries is as follows:
+
Takes a [[#ContentMetaKey]], a u8 [[#ContentType]] and a u8 id_offset. Returns a [[#ContentId]].
  
  u64    title_id_update;
+
=== GetCount ===
  struct title_info info;
+
Returns a u32 count.
  u64    title_id;
 
  
 +
=== GetOwnerApplicationId ===
 +
Takes a [[#ContentMetaKey]]. Returns a [[#ApplicationId]].
  
==== GetUpdateTitleList ====
+
= ncm:v =
Takes a type-6 output buffer, each entry being 0x10-byte bytes, a u32 entryoffset and a 0x10-sized entry. Returns a u32 for total_read_entries.
+
This is "nn::ncm::ISystemVersionManager".
  
The input entry is the output entry from [[#GetTitleIdInfo]] starting at the TID. The output 0x10-bytes entries are the same as the output from [[#GetTitleIdInfo]] starting at the TID. However, "pad[0]" is used for something else it seems?(0 for everything except for TID [[Title_list|010000000000081B]], where it's 1)
+
This service doesn't exist on retail.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || [[#GetSystemVersion|GetSystemVersion]]
 +
|}
  
See [[NCA#Meta_records]].
+
== GetSystemVersion ==
 +
No input. Returns an output u32 '''SystemVersion'''.
 +
 
 +
= LocationListEntry =
 +
Total size is 0x320 bytes.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x8|| Pointer to previous entry
 +
|-
 +
| 0x8 || 0x8|| Pointer to next entry
 +
|-
 +
| 0x10 || 0x8|| [[#ProgramId]]
 +
|-
 +
| 0x18 || 0x300 || [[#Path|Path]]
 +
|-
 +
| 0x318 || 0x4 || Flag
 +
|-
 +
| 0x31C || 0x4 || Padding
 +
|}
  
This reads the titlelist stored in the specified title, normally a title with title-type 3, which is sysupdate-title 0100000000000816. Returns 0 with total_read_entries=0 when used with other title(s).
+
= ContentId =
 +
This is "nn::ncm::ContentId".
  
=== NcaID ===
 
 
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 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 NcaID is the same as the first 0x10-bytes from the calculated SHA256 hash, from hashing the entire output from ReadEntryRaw.
+
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]].
 +
 
 +
= ProgramId =
 +
This is "nn::ncm::ProgramId" or "nn::ncm::SystemProgramId".
 +
 
 +
This is an u64 ID bound to a [[Title_list#System_Modules|program]].
 +
 
 +
= DataId =
 +
This is "nn::ncm::DataId" or "nn::ncm::SystemDataId".
 +
 
 +
This is an u64 ID bound to a [[Title_list#System_Data_Archives|data archive]].
 +
 
 +
= ApplicationId =
 +
This is "nn::ncm::ApplicationId" or "nn::ncm::SystemApplicationId".
 +
 
 +
This is an u64 ID bound to an [[Title_list#System_Applications|application]].
 +
 
 +
Value 0 is invalid.
 +
 
 +
= PatchId =
 +
This is "nn::ncm::PatchId".
 +
 
 +
This is an u64 ID bound to a program patch.
 +
 
 +
= DeltaId =
 +
This is "nn::ncm::DeltaId".
 +
 
 +
This is an u64 ID bound to a program delta fragment.
 +
 
 +
= AddOnContentId =
 +
This is "nn::ncm::AddOnContentId".
 +
 
 +
This is an u64 ID bound to add-on content data.
 +
 
 +
= SystemUpdateId =
 +
This is "nn::ncm::SystemUpdateId".
 +
 
 +
This is an u64 ID bound to system update data.
 +
 
 +
= DataPatchId =
 +
This is "nn::ncm::DataPatchId".
 +
 
 +
This was added with [15.0.0+].
 +
 
 +
This is an u64 ID bound to a data patch.
 +
 
 +
= StorageId =
 +
This is "nn::ncm::StorageId".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value || Name
 +
|-
 +
| 0 || None
 +
|-
 +
| 1 || Host
 +
|-
 +
| 2 || GameCard
 +
|-
 +
| 3 || BuiltInSystem
 +
|-
 +
| 4 || BuiltInUser
 +
|-
 +
| 5 || SdCard
 +
|-
 +
| 6 || Any
 +
|}
 +
 
 +
"None" and "Any" are meta storages.
  
=== Enums ===
+
nn::ncm::IsInstallableStorage returns true for BuiltInSystem, BuiltInUser, SdCard, and Any.
==== Title Types ====
+
 
 +
nn::ncm::IsUniqueStorage returns true for != None && != Any.
 +
 
 +
= 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+] KeyGeneration
 +
|-
 +
| 0x11 || 0x7 || [3.0.0+] Padding
 +
|}
 +
 
 +
= ProgramLocation =
 +
This is "nn::ncm::ProgramLocation".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x8 || [[#ProgramId]]
 +
|-
 +
| 0x8 || 0x1 || [[#StorageId]]
 +
|-
 +
| 0x9 || 0x7 || Padding
 +
|}
 +
 
 +
= Path =
 +
This is "nn::ncm::Path".
 +
 
 +
This is a 0x300-byte structure, which contains a [[Filesystem_services#ContentPath|ContentPath]].
 +
 
 +
= ContentInstallType =
 +
This is "nn::ncm::ContentInstallType".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value
 +
! Description
 +
|-
 +
| 0x0
 +
| Full
 +
|-
 +
| 0x1
 +
| FragmentOnly
 +
|-
 +
| 0x7
 +
| Unknown (Invalid Content Install Type)
 +
|}
 +
 
 +
= ContentMetaType =
 +
This is "nn::ncm::ContentMetaType".
  
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 265: Line 917:
 
! Value
 
! Value
 
! Description
 
! Description
 +
|-
 +
| 0x00
 +
| Unknown (Invalid Content Meta Type)
 
|-
 
|-
 
| 0x01
 
| 0x01
| System Programs ([[Title_list#System_Modules|System Modules]] or [[Title_list#System_Applets|System Applets]])
+
| SystemProgram ([[Title_list#System_Modules|System Modules]] or [[Title_list#System_Applets|System Applets]])
 
|-
 
|-
 
| 0x02
 
| 0x02
| [[Title_list#System_Data_Archives|System Data Archives]]
+
| SystemData ([[Title_list#System_Data_Archives|System Data Archives]])
 
|-
 
|-
 
| 0x03
 
| 0x03
| System Update
+
| SystemUpdate
 
|-
 
|-
 
| 0x04
 
| 0x04
| [[Title_list|Firmware package A]]
+
| BootImagePackage ([[Title_list|Firmware package A or C]])
 
|-
 
|-
 
| 0x05
 
| 0x05
| [[Title_list|Firmware package B]]
+
| BootImagePackageSafe ([[Title_list|Firmware package B or D]])
 
|-
 
|-
 
| 0x80
 
| 0x80
| Regular application
+
| Application
 
|-
 
|-
 
| 0x81
 
| 0x81
| Update title
+
| Patch
 
|-
 
|-
 
| 0x82
 
| 0x82
| Add-on content
+
| AddOnContent
 +
|-
 +
| 0x83
 +
| Delta
 +
|-
 +
| 0x84
 +
| [15.0.0+] DataPatch
 
|}
 
|}
  
== ncm:v ==
+
= ContentType =
 +
This is "nn::ncm::ContentType".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value
 +
! Description
 +
|-
 +
| 0
 +
| Meta
 +
|-
 +
| 1
 +
| Program
 +
|-
 +
| 2
 +
| Data
 +
|-
 +
| 3
 +
| Control
 +
|-
 +
| 4
 +
| HtmlDocument
 +
|-
 +
| 5
 +
| LegalInformation
 +
|-
 +
| 6
 +
| DeltaFragment
 +
|}
 +
 
 +
= ContentMetaKey =
 +
This is "nn::ncm::ContentMetaKey".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x8
 +
| [[#ProgramId]]
 +
|-
 +
| 0x8
 +
| 0x4
 +
| Version
 +
|-
 +
| 0xC
 +
| 0x1
 +
| [[#ContentMetaType]]
 +
|-
 +
| 0xD
 +
| 0x1
 +
| [[#ContentInstallType]]
 +
|-
 +
| 0xE
 +
| 0x2
 +
| Padding
 +
|}
 +
 
 +
= ApplicationContentMetaKey =
 +
This is "nn::ncm::ApplicationContentMetaKey".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x10
 +
| [[#ContentMetaKey|ContentMetaKey]]
 +
|-
 +
| 0x10
 +
| 0x8
 +
| [[#ApplicationId|ApplicationId]]
 +
|}
 +
 
 +
= MemoryReport =
 +
This is "nn::ncm::MemoryReport".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x20
 +
| [[#MemoryResourceState|SystemContentMetaResourceState]]
 +
|-
 +
| 0x20
 +
| 0x20
 +
| [[#MemoryResourceState|SdAndUserContentMetaResourceState]]
 +
|-
 +
| 0x40
 +
| 0x20
 +
| [[#MemoryResourceState|GamecardContentMetaResourceState]]
 +
|-
 +
| 0x60
 +
| 0x20
 +
| [[#MemoryResourceState|HeapResourceState]]
 +
|}
 +
 
 +
== MemoryResourceState ==
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x8
 +
| PeakTotalAllocSize
 +
|-
 +
| 0x8
 +
| 0x8
 +
| PeakAllocSize
 +
|-
 +
| 0x10
 +
| 0x8
 +
| AllocatableSize
 +
|-
 +
| 0x18
 +
| 0x8
 +
| TotalFreeSize
 +
|}
  
 
[[Category:Services]]
 
[[Category:Services]]

Latest revision as of 22:05, 18 October 2022

NCM contains services for internal file path and content management.

lr

This is "nn::lr::ILocationResolverManager".

Cmd Name
0 OpenLocationResolver
1 OpenRegisteredLocationResolver
2 RefreshLocationResolver
3 [2.0.0+] OpenAddOnContentLocationResolver
4 [15.0.0+] SetEnabled

The only sysmodules which use this service are FS, Loader, and NS. boot2 has access but doesn't use it.

OpenLocationResolver

Takes an input #StorageId. Returns an #ILocationResolver.

OpenRegisteredLocationResolver

No input. Returns an #IRegisteredLocationResolver.

RefreshLocationResolver

Takes an input #StorageId. No output.

OpenAddOnContentLocationResolver

No input. Returns an #IAddOnContentLocationResolver.

SetEnabled

Unofficial name.

Takes a type-0x5 input buffer containing an array of #StorageId. No output.

ILocationResolver

This is "nn::lr::ILocationResolver".

Cmd Name
0 ResolveProgramPath
1 RedirectProgramPath
2 ResolveApplicationControlPath
3 ResolveApplicationHtmlDocumentPath
4 ResolveDataPath
5 RedirectApplicationControlPath
6 RedirectApplicationHtmlDocumentPath
7 ResolveApplicationLegalInformationPath
8 RedirectApplicationLegalInformationPath
9 Refresh
10 [5.0.0+] RedirectApplicationProgramPath
11 [5.0.0+] ClearApplicationRedirection
12 [5.0.0+] EraseProgramRedirection
13 [5.0.0+] EraseApplicationControlRedirection
14 [5.0.0+] EraseApplicationHtmlDocumentRedirection
15 [5.0.0+] EraseApplicationLegalInformationRedirection
16 [7.0.0+] ResolveProgramPathForDebug
17 [7.0.0+] RedirectProgramPathForDebug
18 [7.0.0+] RedirectApplicationProgramPathForDebug
19 [7.0.0+] EraseProgramRedirectionForDebug
20 [15.0.0+] Disable

If the supplied #StorageId is 1 (Host), a different set of internal functions is used to handle these commands. In this more restricted set of functions, ResolveApplicationControlPath is stubbed and only returns error 0x608.

The Get* commands load the Path from linked-lists' entries in memory using the input #ProgramId. When the command fails to find an entry for the specified #ProgramId, 0x408 is returned for ResolveProgramPath and 0xA08 is returned for the rest.

The Set* commands always return 0 and add a new entry to the list. If a matching entry is found, it's removed first.

ResolveProgramPath

Takes an input #ProgramId and a type-0x1A output buffer. No output.

RedirectProgramPath

Takes an input #ProgramId and a type-0x19 input buffer containing a Path. No output.

Inserts a new entry with flag set to 0.

ResolveApplicationControlPath

Takes an input #ApplicationId and a type-0x1A output buffer. No output.

ResolveApplicationHtmlDocumentPath

Takes an input #ApplicationId and a type-0x1A output buffer. No output.

ResolveDataPath

Takes an input #DataId and a type-0x1A output buffer. No output.

RedirectApplicationControlPath

Takes an input #ApplicationId and a type-0x19 input buffer containing a Path. No output.

[9.0.0+] Now takes an additional 8-bytes of input.

Inserts a new entry with flag set to 1.

RedirectApplicationHtmlDocumentPath

Takes an input #ApplicationId and a type-0x19 input buffer containing a Path. No output.

[9.0.0+] Now takes an additional 8-bytes of input.

Inserts a new entry with flag set to 1.

ResolveApplicationLegalInformationPath

Takes an input #ApplicationId and a type-0x1A output buffer. No output.

RedirectApplicationLegalInformationPath

Takes an input #ApplicationId and a type-0x19 input buffer containing a Path. No output.

[9.0.0+] Now takes an additional 8-bytes of input.

Inserts a new entry with flag set to 1.

Refresh

No input/output.

Frees all linked-lists' entries that have flag set to 0.

RedirectApplicationProgramPath

Same as RedirectProgramPath, but inserts a new entry with flag set to 1.

[9.0.0+] Now takes an additional 8-bytes of input.

ClearApplicationRedirection

No input/output.

Frees all linked-lists' entries that have flag set to 1.

[9.0.0+] Now takes a type-0x5 input buffer.

EraseProgramRedirection

Takes an input #ProgramId. No output.

Removes the entry that matches the input #ProgramId.

EraseApplicationControlRedirection

Takes an input #ApplicationId. No output.

Removes the entry that matches the input #ApplicationId.

EraseApplicationHtmlDocumentRedirection

Takes an input #ApplicationId. No output.

Removes the entry that matches the input #ApplicationId.

EraseApplicationLegalInformationRedirection

Takes an input #ApplicationId. No output.

Removes the entry that matches the input #ApplicationId.

ResolveProgramPathForDebug

Unofficial name.

Same as ResolveProgramPath, but uses a redirection shim on top of the real program path.

NS uses this command if ns.application!redirected_rom_storage_id_for_debug is different than 0x00.

RedirectProgramPathForDebug

Unofficial name.

Same as RedirectProgramPath, but uses a redirection shim on top of the real program path.

NS uses this command if ns.application!redirected_rom_storage_id_for_debug is different than 0x00.

RedirectApplicationProgramPathForDebug

Unofficial name.

Same as RedirectApplicationProgramPath, but uses a redirection shim on top of the real program path.

[9.0.0+] Like #RedirectApplicationProgramPath this now takes an additional 8-bytes of input.

NS uses this command if ns.application!redirected_rom_storage_id_for_debug is different than 0x00.

EraseProgramRedirectionForDebug

Unofficial name.

Same as EraseProgramRedirection, but uses a redirection shim on top of the real program path.

NS uses this command if ns.application!redirected_rom_storage_id_for_debug is different than 0x00.

Disable

Unofficial name.

No input/output.

IRegisteredLocationResolver

This is "nn::lr::IRegisteredLocationResolver".

Cmd Name
0 ResolveProgramPath
1 RegisterProgramPath
2 UnregisterProgramPath
3 RedirectProgramPath
4 [2.0.0+] ResolveHtmlDocumentPath
5 [2.0.0+] RegisterHtmlDocumentPath
6 [2.0.0+] UnregisterHtmlDocumentPath
7 [2.0.0+] RedirectHtmlDocumentPath
8 [7.0.0+] Refresh
9 [9.0.0+] RefreshExcluding

This works like #ILocationResolver, but only two types of NCA paths can be gotten/set. In addition, each type has a fallback path that can be set for a single #ProgramId at a time.

ResolveProgramPath

Takes an input #ProgramId and a type-0x1A output buffer. No output.

RegisterProgramPath

Takes an input #ProgramId and a type-0x19 input buffer containing a Path. No output.

[9.0.0+] Now takes an additional 8-bytes of input.

UnregisterProgramPath

Takes an input #ProgramId. No output.

RedirectProgramPath

Takes an input #ProgramId and a type-0x19 input buffer containing a Path. No output.

[9.0.0+] Now takes an additional 8-bytes of input.

ResolveHtmlDocumentPath

Takes an input #ApplicationId and a type-0x1A output buffer. No output.

RegisterHtmlDocumentPath

Takes an input #ApplicationId and a type-0x19 input buffer containing a Path. No output.

[9.0.0+] Now takes an additional 8-bytes of input.

UnregisterHtmlDocumentPath

Takes an input #ApplicationId. No output.

RedirectHtmlDocumentPath

Takes an input #ApplicationId and a type-0x19 input buffer containing a Path. No output.

[9.0.0+] Now takes an additional 8-bytes of input.

Refresh

No input/output.

RefreshExcluding

Unofficial name.

Takes a type-0x5 input buffer containing an array of #ProgramId. No output.

IAddOnContentLocationResolver

This is "nn::lr::IAddOnContentLocationResolver".

Cmd Name
0 ResolveAddOnContentPath
1 RegisterAddOnContentStorage
2 UnregisterAllAddOnContentPath
3 [9.0.0+] RefreshApplicationAddOnContent
4 [9.0.0+] UnregisterApplicationAddOnContent
5 [15.0.0+] GetRegisteredAddOnContentPaths
6 [15.0.0+] RegisterAddOnContentPath
7 [15.0.0+] RegisterAddOnContentPaths

ResolveAddOnContentPath

Takes an input #DataId and a type-0x1A output buffer. No output.

RegisterAddOnContentStorage

Takes an input #StorageId and an input #DataId. No output.

[9.0.0+] Now takes an additional input #ApplicationId for the owner application.

UnregisterAllAddOnContentPath

No input/output.

RefreshApplicationAddOnContent

Unofficial name.

Takes a type-0x5 input buffer containing an array of #ApplicationId. No output.

Unregisters entries with IDs absent from the input buffer.

UnregisterApplicationAddOnContent

Unofficial name.

Takes an input #ApplicationId. No output.

Unregisters add on content entries for the input #ApplicationId.

GetRegisteredAddOnContentPaths

Unofficial name.

Takes an input #DataId and two type-0x16 output buffers. No output.

RegisterAddOnContentPath

Unofficial name.

Takes an input #DataId, an input #ApplicationId and a type-0x15 input buffer. No output.

RegisterAddOnContentPaths

Unofficial name.

Takes an input #DataId, an input #ApplicationId and two type-0x15 input buffers. No output.

ncm

This is "nn::ncm::IContentManager".

Cmd Name
0 CreateContentStorage
1 CreateContentMetaDatabase
2 VerifyContentStorage
3 VerifyContentMetaDatabase
4 OpenContentStorage
5 OpenContentMetaDatabase
6 [1.0.0] CloseContentStorageForcibly
7 [1.0.0] CloseContentMetaDatabaseForcibly
8 CleanupContentMetaDatabase
9 [2.0.0+] ActivateContentStorage
10 [2.0.0+] InactivateContentStorage
11 [2.0.0+] ActivateContentMetaDatabase
12 [2.0.0+] InactivateContentMetaDatabase
13 [9.0.0+] InvalidateRightsIdCache
14 [10.0.0+] GetMemoryReport

CreateContentStorage

Takes an input #StorageId. No output.

CreateContentMetaDatabase

Takes an input #StorageId. No output.

VerifyContentStorage

Takes an input #StorageId. No output.

VerifyContentMetaDatabase

Takes an input #StorageId. No output.

OpenContentStorage

Takes an input #StorageId. Returns an #IContentStorage.

[2.0.0+] Only returns a storage if one has previously been opened globally via CreateContentStorage.

OpenContentMetaDatabase

Takes an input #StorageId. Returns an #IContentMetaDatabase.

[2.0.0+] Only returns a storage if one has previously been opened globally via CreateContentStorage.

CloseContentStorageForcibly

Takes an input #StorageId. No output.

CloseContentMetaDatabaseForcibly

Takes an input #StorageId. No output.

CleanupContentMetaDatabase

Takes an input #StorageId. No output.

ActivateContentStorage

Takes an input #StorageId. No output.

InactivateContentStorage

Takes an input #StorageId. No output.

ActivateContentMetaDatabase

Takes an input #StorageId. No output.

InactivateContentMetaDatabase

Takes an input #StorageId. No output.

InvalidateRightsIdCache

No input/output.

GetMemoryReport

No input. Returns an output #MemoryReport.

IContentStorage

This is "nn::ncm::IContentStorage".

Cmd Name
0 GeneratePlaceHolderId
1 CreatePlaceHolder
2 DeletePlaceHolder
3 HasPlaceHolder
4 WritePlaceHolder
5 Register
6 Delete
7 Has
8 GetPath
9 GetPlaceHolderPath
10 CleanupAllPlaceHolder
11 ListPlaceHolder
12 GetContentCount
13 ListContentId
14 GetSizeFromContentId
15 DisableForcibly
16 [2.0.0+] RevertToPlaceHolder
17 [2.0.0+] SetPlaceHolderSize
18 [2.0.0+] ReadContentIdFile
19 [2.0.0+] GetRightsIdFromPlaceHolderId
20 [2.0.0+] GetRightsIdFromContentId
21 [2.0.0+] WriteContentForDebug
22 [2.0.0+] GetFreeSpaceSize
23 [2.0.0+] GetTotalSpaceSize
24 [3.0.0+] FlushPlaceHolder
25 [4.0.0+] GetSizeFromPlaceHolderId
26 [4.0.0+] RepairInvalidFileAttribute
27 [8.0.0+] GetRightsIdFromPlaceHolderIdWithCache
28 [13.0.0+] RegisterPath
29 [13.0.0+] ClearRegisteredPath

GeneratePlaceHolderId

No input. Returns an output #PlaceHolderId.

Calls nn::util::GenerateUuid(), which internally calls nn::os::GenerateRandomBytes(16);

CreatePlaceHolder

Takes an input #ContentId, an input #PlaceHolderId and an input s64 FileSize. No output.

DeletePlaceHolder

Takes an input #PlaceHolderId. No output.

HasPlaceHolder

Takes an input #PlaceHolderId. Returns an output bool.

WritePlaceHolder

Takes an input #PlaceHolderId, an input u64 Offset and a type-0x5 input buffer. No output.

Writes the buffer to the file for the placeholder path at the specified offset.

Register

Takes a #ContentId and a #PlaceHolderId, no output. Moves the Placeholder NCA content to the registered NCA path.

Delete

Takes a #ContentId.

Has

Takes a #ContentId.

GetPath

Takes a #ContentId and a type-0x1A output buffer containing a Path.

GetPlaceHolderPath

Takes a #PlaceHolderId and a type-0x1A output buffer containing a Path.

CleanupAllPlaceHolder

No input/output.

Deletes and re-creates the "Placeholder" directory.

ListPlaceHolder

This is like GetNumberOfRegisteredEntries, but for the "Placeholder" directory.

GetContentCount

No input. Returns an output u32 Count.

ListContentId

Takes an output buffer, s32 offset and gets all entries starting at that offset. Returns number of entries read.

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?).

GetSizeFromContentId

Takes a #ContentId as input.

Returns the total size readable by #ReadContentIdFile. This is the same as the size-field in the NAX0 "<ContentId>.nca/00" file.

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.

RevertToPlaceHolder

Takes two #ContentId and a #PlaceHolderId, no output.

Creates the registered directory NCA path, and renames the placeholder path to the registered NCA path.

SetPlaceHolderSize

Takes a #PlaceHolderId, and a s64 size, no output.

ReadContentIdFile

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 ContentId.

GetRightsIdFromPlaceHolderId

Takes a #PlaceHolderId, returns a #RightsId.

Gets the Rights ID for the #PlaceHolderId's placeholder path.

GetRightsIdFromContentId

Takes a #ContentId, returns a #RightsId.

Gets the Rights ID for the #ContentId's registered path

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.

IContentMetaDatabase

This is "nn::ncm::IContentMetaDatabase".

Cmd Name
0 Set
1 Get
2 Remove
3 GetContentIdByType
4 ListContentInfo
5 List
6 GetLatestContentMetaKey
7 ListApplication
8 Has
9 HasAll
10 GetSize
11 GetRequiredSystemVersion
12 GetPatchId
13 DisableForcibly
14 LookupOrphanContent
15 Commit
16 HasContent
17 ListContentMetaInfo
18 GetAttributes
19 [2.0.0+] GetRequiredApplicationVersion
20 [5.0.0+] GetContentIdByTypeAndIdOffset
21 [10.0.0+] GetCount
22 [10.0.0+] GetOwnerApplicationId
23 [15.0.0+] GetContentAccessibilities
24 [15.0.0+] GetContentInfoByType
25 [15.0.0+] GetContentInfoByTypeAndIdOffset

Set

Takes a #ContentMetaKey, a type-5 PackagedContentInfo buffer and a u64 size.

Get

Takes a #ContentMetaKey, a type-6 buffer to write PackagedContentInfo to and a u64 size. Returns the actual number of bytes read into the buffer.

First 8 bytes of the data is header (u16 numExtraDataBytes, numContentRecords, numMetaRecords, padding). After the header is numExtraDataBytes of additional data, after which follow content records and content meta keys. Set takes this same data as input.

Remove

Takes a #ContentMetaKey, and removes the associated record.

GetContentIdByType

Takes a #ContentMetaKey and a u8 #ContentType. Returns a #ContentId.

ListContentInfo

Takes a type-6 buffer to write PackagedContentInfo entries to, a #ContentMetaKey, and a s32 index into the entries to start copying from. Returns a s32 entries_read.

List

Takes a type-6 buffer to write #ContentMetaKeys to, a u32 #ContentMetaType, a #ProgramId, a u64 ProgramId_Low, and u64 ProgramId_High. Returns s32 numEntriesTotal, numEntriesWritten.

Writes into the buffer all Content Meta Keys with low <= record->title_id <= high, and record->type == type. 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.

GetLatestContentMetaKey

Takes a #ProgramId, and returns the #ContentMetaKey with the highest version field for that #ProgramId.

ListApplication

This function takes in a type 6 buffer to write ApplicationContentMetaKey entries to, and a u8 "filter". 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 s32 num_entries_total, and a s32 num_entries_written.

Has

Takes a #ContentMetaKey and returns an output u8 bool indicating whether that record is present in the database.

HasAll

Takes a type-0x5 input buffer containing an array of #ContentMetaKey, and returns whether all of those records are present in the database.

GetSize

Takes a #ContentMetaKey, and returns the size of the associated PackagedContentInfo.

GetRequiredSystemVersion

Takes an input #ContentMetaKey. Returns an output u32 RequiredSystemVersion.

GetPatchId

Takes a #ContentMetaKey, and returns the update #ProgramId for that record.

DisableForcibly

Closes the meta database, and causes all future IPC commands to the current session to return error 0xDC05.

LookupOrphanContent

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.

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:

for i in range(len(out_buf)):
    out_buf[i] = 1

for i, ContentId in ContentId:
    if is_present_in_database(ContentId):
        out_buf[i] = 0

Commit

Flushes the in-memory database to savedata.

HasContent

Takes a #ContentMetaKey and an #ContentId. Returns whether the content records for that content meta key contain the #ContentId.

ListContentMetaInfo

Takes a type-6 #ContentMetaKey output buffer, a s32 offset into that buffer, and an input #ContentMetaKey.

GetAttributes

Takes an input #ContentMetaKey. Returns an output u8 Attributes.

GetRequiredApplicationVersion

Does the same thing as GetRequiredSystemVersion, but for AddOnContents.

GetContentIdByTypeAndIdOffset

Takes a #ContentMetaKey, a u8 #ContentType and a u8 id_offset. Returns a #ContentId.

GetCount

Returns a u32 count.

GetOwnerApplicationId

Takes a #ContentMetaKey. Returns a #ApplicationId.

ncm:v

This is "nn::ncm::ISystemVersionManager".

This service doesn't exist on retail.

Cmd Name
0 GetSystemVersion

GetSystemVersion

No input. Returns an output u32 SystemVersion.

LocationListEntry

Total size is 0x320 bytes.

Offset Size Description
0x0 0x8 Pointer to previous entry
0x8 0x8 Pointer to next entry
0x10 0x8 #ProgramId
0x18 0x300 Path
0x318 0x4 Flag
0x31C 0x4 Padding

ContentId

This is "nn::ncm::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).

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.

ProgramId

This is "nn::ncm::ProgramId" or "nn::ncm::SystemProgramId".

This is an u64 ID bound to a program.

DataId

This is "nn::ncm::DataId" or "nn::ncm::SystemDataId".

This is an u64 ID bound to a data archive.

ApplicationId

This is "nn::ncm::ApplicationId" or "nn::ncm::SystemApplicationId".

This is an u64 ID bound to an application.

Value 0 is invalid.

PatchId

This is "nn::ncm::PatchId".

This is an u64 ID bound to a program patch.

DeltaId

This is "nn::ncm::DeltaId".

This is an u64 ID bound to a program delta fragment.

AddOnContentId

This is "nn::ncm::AddOnContentId".

This is an u64 ID bound to add-on content data.

SystemUpdateId

This is "nn::ncm::SystemUpdateId".

This is an u64 ID bound to system update data.

DataPatchId

This is "nn::ncm::DataPatchId".

This was added with [15.0.0+].

This is an u64 ID bound to a data patch.

StorageId

This is "nn::ncm::StorageId".

Value Name
0 None
1 Host
2 GameCard
3 BuiltInSystem
4 BuiltInUser
5 SdCard
6 Any

"None" and "Any" are meta storages.

nn::ncm::IsInstallableStorage returns true for BuiltInSystem, BuiltInUser, SdCard, and Any.

nn::ncm::IsUniqueStorage returns true for != None && != Any.

RightsId

This is "nn::ncm::RightsId".

This is a 0x10-byte struct. [3.0.0+] This is a 0x18-byte struct.

Offset Size Description
0x0 0x10 FS Rights ID
0x10 0x1 [3.0.0+] KeyGeneration
0x11 0x7 [3.0.0+] Padding

ProgramLocation

This is "nn::ncm::ProgramLocation".

Offset Size Description
0x0 0x8 #ProgramId
0x8 0x1 #StorageId
0x9 0x7 Padding

Path

This is "nn::ncm::Path".

This is a 0x300-byte structure, which contains a ContentPath.

ContentInstallType

This is "nn::ncm::ContentInstallType".

Value Description
0x0 Full
0x1 FragmentOnly
0x7 Unknown (Invalid Content Install Type)

ContentMetaType

This is "nn::ncm::ContentMetaType".

Value Description
0x00 Unknown (Invalid Content Meta Type)
0x01 SystemProgram (System Modules or System Applets)
0x02 SystemData (System Data Archives)
0x03 SystemUpdate
0x04 BootImagePackage (Firmware package A or C)
0x05 BootImagePackageSafe (Firmware package B or D)
0x80 Application
0x81 Patch
0x82 AddOnContent
0x83 Delta
0x84 [15.0.0+] DataPatch

ContentType

This is "nn::ncm::ContentType".

Value Description
0 Meta
1 Program
2 Data
3 Control
4 HtmlDocument
5 LegalInformation
6 DeltaFragment

ContentMetaKey

This is "nn::ncm::ContentMetaKey".

Offset Size Description
0x0 0x8 #ProgramId
0x8 0x4 Version
0xC 0x1 #ContentMetaType
0xD 0x1 #ContentInstallType
0xE 0x2 Padding

ApplicationContentMetaKey

This is "nn::ncm::ApplicationContentMetaKey".

Offset Size Description
0x0 0x10 ContentMetaKey
0x10 0x8 ApplicationId

MemoryReport

This is "nn::ncm::MemoryReport".

Offset Size Description
0x0 0x20 SystemContentMetaResourceState
0x20 0x20 SdAndUserContentMetaResourceState
0x40 0x20 GamecardContentMetaResourceState
0x60 0x20 HeapResourceState

MemoryResourceState

Offset Size Description
0x0 0x8 PeakTotalAllocSize
0x8 0x8 PeakAllocSize
0x10 0x8 AllocatableSize
0x18 0x8 TotalFreeSize