Changes

4,247 bytes added ,  22:05, 18 October 2022
no edit summary
Line 1: Line 1:  
NCM contains services for internal file path and content management.
 
NCM contains services for internal file path and content management.
   −
= Location Resolver services =
+
= lr =
== lr ==
   
This is "nn::lr::ILocationResolverManager".
 
This is "nn::lr::ILocationResolverManager".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Arguments || Notes
+
! Cmd || Name
 
|-
 
|-
| 0 || OpenLocationResolver || [[#StorageId]] ||
+
| 0 || [[#OpenLocationResolver|OpenLocationResolver]]
 
|-
 
|-
| 1 || OpenRegisteredLocationResolver || None ||
+
| 1 || [[#OpenRegisteredLocationResolver|OpenRegisteredLocationResolver]]
 
|-
 
|-
| 2 || RefreshLocationResolver || [[#StorageId]] ||
+
| 2 || [[#RefreshLocationResolver|RefreshLocationResolver]]
 
|-
 
|-
| 3 || [2.0.0+] OpenAddOnContentLocationResolver || None ||
+
| 3 || [2.0.0+] [[#OpenAddOnContentLocationResolver|OpenAddOnContentLocationResolver]]
 
|-
 
|-
| 4 || [15.0.0+] SetEnabled || || Unofficial name
+
| 4 || [15.0.0+] [[#SetEnabled|SetEnabled]]
 
|}
 
|}
    
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.
 
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.
   −
=== ILocationResolver ===
+
== 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".
 
This is "nn::lr::ILocationResolver".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name
 
|-
 
|-
| 0 || [[#ResolveProgramPath]] ||
+
| 0 || [[#ResolveProgramPath|ResolveProgramPath]]
 
|-
 
|-
| 1 || [[#RedirectProgramPath]] ||
+
| 1 || [[#RedirectProgramPath|RedirectProgramPath]]
 
|-
 
|-
| 2 || [[#ResolveApplicationControlPath]] ||
+
| 2 || [[#ResolveApplicationControlPath|ResolveApplicationControlPath]]
 
|-
 
|-
| 3 || [[#ResolveApplicationHtmlDocumentPath]] ||
+
| 3 || [[#ResolveApplicationHtmlDocumentPath|ResolveApplicationHtmlDocumentPath]]
 
|-
 
|-
| 4 || [[#ResolveDataPath]] ||
+
| 4 || [[#ResolveDataPath|ResolveDataPath]]
 
|-
 
|-
| 5 || [[#RedirectApplicationControlPath]] ||
+
| 5 || [[#RedirectApplicationControlPath|RedirectApplicationControlPath]]
 
|-
 
|-
| 6 || [[#RedirectApplicationHtmlDocumentPath]] ||
+
| 6 || [[#RedirectApplicationHtmlDocumentPath|RedirectApplicationHtmlDocumentPath]]
 
|-
 
|-
| 7 || [[#ResolveApplicationLegalInformationPath]] ||
+
| 7 || [[#ResolveApplicationLegalInformationPath|ResolveApplicationLegalInformationPath]]
 
|-
 
|-
| 8 || [[#RedirectApplicationLegalInformationPath]] ||
+
| 8 || [[#RedirectApplicationLegalInformationPath|RedirectApplicationLegalInformationPath]]
 
|-
 
|-
| 9 || [[#Refresh]] ||
+
| 9 || [[#Refresh|Refresh]]
 
|-
 
|-
| 10 || [5.0.0+] [[#RedirectApplicationProgramPath]] ||
+
| 10 || [5.0.0+] [[#RedirectApplicationProgramPath|RedirectApplicationProgramPath]]
 
|-
 
|-
| 11 || [5.0.0+] [[#ClearApplicationRedirection]] ||
+
| 11 || [5.0.0+] [[#ClearApplicationRedirection|ClearApplicationRedirection]]
 
|-
 
|-
| 12 || [5.0.0+] [[#EraseProgramRedirection]] ||
+
| 12 || [5.0.0+] [[#EraseProgramRedirection|EraseProgramRedirection]]
 
|-
 
|-
| 13 || [5.0.0+] [[#EraseApplicationControlRedirection]] ||
+
| 13 || [5.0.0+] [[#EraseApplicationControlRedirection|EraseApplicationControlRedirection]]
 
|-
 
|-
| 14 || [5.0.0+] [[#EraseApplicationHtmlDocumentRedirection]] ||
+
| 14 || [5.0.0+] [[#EraseApplicationHtmlDocumentRedirection|EraseApplicationHtmlDocumentRedirection]]
 
|-
 
|-
| 15 || [5.0.0+] [[#EraseApplicationLegalInformationRedirection]] ||
+
| 15 || [5.0.0+] [[#EraseApplicationLegalInformationRedirection|EraseApplicationLegalInformationRedirection]]
 
|-
 
|-
| 16 || [7.0.0+] [[#ResolveProgramPathForDebug]] || Unofficial name
+
| 16 || [7.0.0+] [[#ResolveProgramPathForDebug|ResolveProgramPathForDebug]]
 
|-
 
|-
| 17 || [7.0.0+] [[#RedirectProgramPathForDebug]] || Unofficial name
+
| 17 || [7.0.0+] [[#RedirectProgramPathForDebug|RedirectProgramPathForDebug]]
 
|-
 
|-
| 18 || [7.0.0+] [[#RedirectApplicationProgramPathForDebug]] || Unofficial name
+
| 18 || [7.0.0+] [[#RedirectApplicationProgramPathForDebug|RedirectApplicationProgramPathForDebug]]
 
|-
 
|-
| 19 || [7.0.0+] [[#EraseProgramRedirectionForDebug]] || Unofficial name
+
| 19 || [7.0.0+] [[#EraseProgramRedirectionForDebug|EraseProgramRedirectionForDebug]]
 
|-
 
|-
| 20 || [15.0.0+] Disable || Unofficial name
+
| 20 || [15.0.0+] [[#Disable|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.
+
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.
   −
The Get* commands load the [[Filesystem_services#ContentPath|ContentPath]] from linked-lists' [[#Location_List_Entry|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 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.
 
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 ====
+
=== ResolveProgramPath ===
Takes an [[#ProgramId]] and a C descriptor. Used for [[NCA_Content_FS#NCA-type1|NCA-type1]].
+
Takes an input [[#ProgramId]] and a type-0x1A output buffer. No output.
   −
==== RedirectProgramPath ====
+
=== RedirectProgramPath ===
Takes an [[#ProgramId]] and a X descriptor with a [[Filesystem_services#ContentPath|ContentPath]]. Used for [[NCA_Content_FS#NCA-type1|NCA-type1]].
+
Takes an input [[#ProgramId]] and a type-0x19 input buffer containing a [[#Path|Path]]. No output.
   −
Inserts a new [[#Location_List_Entry|entry]] with '''flag''' set to 0.
+
Inserts a new [[#LocationListEntry|entry]] with '''flag''' set to 0.
   −
==== ResolveApplicationControlPath ====
+
=== ResolveApplicationControlPath ===
Takes an [[#ApplicationId]] and a C descriptor. Used for [[NCA_Content_FS#NCA-type3|NCA-type3]].
+
Takes an input [[#ApplicationId]] and a type-0x1A output buffer. No output.
   −
==== ResolveApplicationHtmlDocumentPath====
+
=== ResolveApplicationHtmlDocumentPath ===
Takes an [[#ApplicationId]] and a C descriptor. Used for [[NCA_Content_FS#NCA-type4|NCA-type4]].
+
Takes an input [[#ApplicationId]] and a type-0x1A output buffer. No output.
   −
==== ResolveDataPath ====
+
=== ResolveDataPath ===
Takes an [[#DataId]] and a C descriptor. Used for [[NCA_Content_FS#NCA-type3|NCA-type3]].
+
Takes an input [[#DataId]] and a type-0x1A output buffer. No output.
   −
==== RedirectApplicationControlPath ====
+
=== RedirectApplicationControlPath ===
Takes an [[#ApplicationId]] and a X descriptor with a [[Filesystem_services#ContentPath|ContentPath]]. Used for [[NCA_Content_FS#NCA-type3|NCA-type3]].
+
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.
 
[9.0.0+] Now takes an additional 8-bytes of input.
   −
Inserts a new [[#Location_List_Entry|entry]] with '''flag''' set to 1.
+
Inserts a new [[#LocationListEntry|entry]] with '''flag''' set to 1.
   −
==== RedirectApplicationHtmlDocumentPath ====
+
=== RedirectApplicationHtmlDocumentPath ===
Takes an [[#ApplicationId]] and a X descriptor with a [[Filesystem_services#ContentPath|ContentPath]]. Used for [[NCA_Content_FS#NCA-type4|NCA-type4]].
+
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.
 
[9.0.0+] Now takes an additional 8-bytes of input.
   −
Inserts a new [[#Location_List_Entry|entry]] with '''flag''' set to 1.
+
Inserts a new [[#LocationListEntry|entry]] with '''flag''' set to 1.
   −
==== ResolveApplicationLegalInformationPath ====
+
=== ResolveApplicationLegalInformationPath ===
Takes an [[#ApplicationId]] and a C descriptor. Used for [[NCA_Content_FS#NCA-type5|NCA-type5]].
+
Takes an input [[#ApplicationId]] and a type-0x1A output buffer. No output.
   −
==== RedirectApplicationLegalInformationPath ====
+
=== RedirectApplicationLegalInformationPath ===
Takes an [[#ApplicationId]] and a X descriptor with a [[Filesystem_services#ContentPath|ContentPath]]. Used for [[NCA_Content_FS#NCA-type5|NCA-type5]].
+
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.
 
[9.0.0+] Now takes an additional 8-bytes of input.
   −
Inserts a new [[#Location_List_Entry|entry]] with '''flag''' set to 1.
+
Inserts a new [[#LocationListEntry|entry]] with '''flag''' set to 1.
 +
 
 +
=== Refresh ===
 +
No input/output.
   −
==== Refresh ====
+
Frees all linked-lists' entries that have '''flag''' set to 0.
Takes no input. Frees all linked-lists' entries that have '''flag''' set to 0.
     −
==== RedirectApplicationProgramPath ====
+
=== RedirectApplicationProgramPath ===
Same as [[#RedirectProgramPath|RedirectProgramPath]], but inserts a new [[#Location_List_Entry|entry]] with '''flag''' set to 1.
+
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.
 
[9.0.0+] Now takes an additional 8-bytes of input.
   −
==== ClearApplicationRedirection ====
+
=== ClearApplicationRedirection ===
Takes no input. Frees all linked-lists' entries that have '''flag''' set to 1.
+
No input/output.
 +
 
 +
Frees all linked-lists' entries that have '''flag''' set to 1.
 +
 
 +
[9.0.0+] Now takes a type-0x5 input buffer.
   −
[9.0.0+] Now takes a type-0x5 input buffer, no output.
+
=== EraseProgramRedirection ===
 +
Takes an input [[#ProgramId]]. No output.
   −
==== EraseProgramRedirection ====
+
Removes the [[#LocationListEntry|entry]] that matches the input [[#ProgramId]].
Takes an [[#ProgramnId]]. Used for [[NCA_Content_FS#NCA-type1|NCA-type1]].
     −
Removes the [[#Location_List_Entry|entry]] that matches the input ProgramId.
+
=== EraseApplicationControlRedirection ===
 +
Takes an input [[#ApplicationId]]. No output.
   −
==== EraseApplicationControlRedirection ====
+
Removes the [[#LocationListEntry|entry]] that matches the input [[#ApplicationId]].
Takes an [[#ApplicationId]]. Used for [[NCA_Content_FS#NCA-type3|NCA-type3]].
     −
Removes the [[#Location_List_Entry|entry]] that matches the input ApplicationId.
+
=== EraseApplicationHtmlDocumentRedirection ===
 +
Takes an input [[#ApplicationId]]. No output.
   −
==== EraseApplicationHtmlDocumentRedirection ====
+
Removes the [[#LocationListEntry|entry]] that matches the input [[#ApplicationId]].
Takes an [[#ApplicationId]]. Used for [[NCA_Content_FS#NCA-type4|NCA-type4]].
     −
Removes the [[#Location_List_Entry|entry]] that matches the input ApplicationId.
+
=== EraseApplicationLegalInformationRedirection ===
 +
Takes an input [[#ApplicationId]]. No output.
   −
==== EraseApplicationLegalInformationRedirection ====
+
Removes the [[#LocationListEntry|entry]] that matches the input [[#ApplicationId]].
Takes an [[#ApplicationId]]. Used for [[NCA_Content_FS#NCA-type5|NCA-type5]].
     −
Removes the [[#Location_List_Entry|entry]] that matches the input ApplicationId.
+
=== ResolveProgramPathForDebug ===
 +
Unofficial name.
   −
==== ResolveProgramPathForDebug ====
   
Same as [[#ResolveProgramPath|ResolveProgramPath]], but uses a redirection shim on top of the real program path.
 
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.
 
[[NS_Services|NS]] uses this command if [[System_Settings#ns.application|ns.application!redirected_rom_storage_id_for_debug]] is different than 0x00.
   −
==== RedirectProgramPathForDebug ====
+
=== RedirectProgramPathForDebug ===
 +
Unofficial name.
 +
 
 
Same as [[#RedirectProgramPath|RedirectProgramPath]], but uses a redirection shim on top of the real program path.
 
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.
 
[[NS_Services|NS]] uses this command if [[System_Settings#ns.application|ns.application!redirected_rom_storage_id_for_debug]] is different than 0x00.
   −
==== RedirectApplicationProgramPathForDebug ====
+
=== RedirectApplicationProgramPathForDebug ===
Same as [[#RedirectApplicationProgramPath |RedirectApplicationProgramPath ]], but uses a redirection shim on top of the real program path.
+
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.
 
[9.0.0+] Like [[#RedirectApplicationProgramPath]] this now takes an additional 8-bytes of input.
Line 169: Line 195:  
[[NS_Services|NS]] uses this command if [[System_Settings#ns.application|ns.application!redirected_rom_storage_id_for_debug]] is different than 0x00.
 
[[NS_Services|NS]] uses this command if [[System_Settings#ns.application|ns.application!redirected_rom_storage_id_for_debug]] is different than 0x00.
   −
==== EraseProgramRedirectionForDebug ====
+
=== EraseProgramRedirectionForDebug ===
Same as [[#EraseProgramRedirection |EraseProgramRedirection ]], but uses a redirection shim on top of the real program path.
+
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.
 
[[NS_Services|NS]] uses this command if [[System_Settings#ns.application|ns.application!redirected_rom_storage_id_for_debug]] is different than 0x00.
   −
=== IRegisteredLocationResolver ===
+
=== Disable ===
 +
Unofficial name.
 +
 
 +
No input/output.
 +
 
 +
== IRegisteredLocationResolver ==
 
This is "nn::lr::IRegisteredLocationResolver".
 
This is "nn::lr::IRegisteredLocationResolver".
  −
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.
      
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Arguments || Notes
+
! Cmd || Name
 
|-
 
|-
| 0 || ResolveProgramPath || [[#ProgramId]] + C descriptor || Used for [[NCA_Content_FS#NCA-type1|NCA-type1]].
+
| 0 || [[#ResolveProgramPath_2|ResolveProgramPath]]
 
|-
 
|-
| 1 || RegisterProgramPath || [[#ProgramId]] + X descriptor [[Filesystem_services#ContentPath|ContentPath]] [9.0.0+] Now takes an additional 8-bytes of input. || Sets the Type 0 fallback TID and path to the provided arguments.
+
| 1 || [[#RegisterProgramPath|RegisterProgramPath]]
 
|-
 
|-
| 2 || UnregisterProgramPath || [[#ProgramId]] || If the Type 0 fallback TID is == argument TID, unregisters the fallback path. Otherwise, noop.
+
| 2 || [[#UnregisterProgramPath|UnregisterProgramPath]]
 
|-
 
|-
| 3 || RedirectProgramPath || [[#ProgramId]] + X descriptor [[Filesystem_services#ContentPath|ContentPath]] [9.0.0+] Now takes an additional 8-bytes of input. ||
+
| 3 || [[#RedirectProgramPath_2|RedirectProgramPath]]
 
|-
 
|-
| 4 || [2.0.0+] ResolveHtmlDocumentPath || [[#ApplicationId]] + C descriptor ||
+
| 4 || [2.0.0+] [[#ResolveHtmlDocumentPath|ResolveHtmlDocumentPath]]
 
|-
 
|-
| 5 || [2.0.0+] RegisterHtmlDocumentPath || [[#ApplicationId]] + X descriptor [[Filesystem_services#ContentPath|ContentPath]] [9.0.0+] Now takes an additional 8-bytes of input. || Sets the Type 1 fallback TID and path to the provided arguments.
+
| 5 || [2.0.0+] [[#RegisterHtmlDocumentPath|RegisterHtmlDocumentPath]]
 
|-
 
|-
| 6 || [2.0.0+] UnregisterHtmlDocumentPath || [[#ApplicationId]] || If the Type 1 fallback TID is == argument TID, unregisters the fallback path. Otherwise, noop.
+
| 6 || [2.0.0+] [[#UnregisterHtmlDocumentPath|UnregisterHtmlDocumentPath]]
 
|-
 
|-
| 7 || [2.0.0+] RedirectHtmlDocumentPath || [[#ApplicationId]] + X descriptor [[Filesystem_services#ContentPath|ContentPath]] [9.0.0+] Now takes an additional 8-bytes of input. ||
+
| 7 || [2.0.0+] [[#RedirectHtmlDocumentPath|RedirectHtmlDocumentPath]]
 
|-
 
|-
| 8 || [7.0.0+] Refresh || No input/output. ||
+
| 8 || [7.0.0+] [[#Refresh_2|Refresh]]
 
|-
 
|-
| 9 || [9.0.0+] RefreshExcluding || Type-5 buffer || Unofficial name. Refreshes entries excluding those with application ProgramIds contained in the buffer.
+
| 9 || [9.0.0+] [[#RefreshExcluding|RefreshExcluding]]
 
|}
 
|}
   −
=== IAddOnContentLocationResolver ===
+
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".
 
This is "nn::lr::IAddOnContentLocationResolver".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Arguments || Notes
+
! Cmd || Name
 
|-
 
|-
| 0 || ResolveAddOnContentPath || [[#ApplicationId]] + C descriptor ||
+
| 0 || [[#ResolveAddOnContentPath|ResolveAddOnContentPath]]
 
|-
 
|-
| 1 || RegisterAddOnContentStorage || [[#StorageId]] + [[#ApplicationId]] [9.0.0+] Now takes an additional [[#ApplicationId]] for the owner application. ||
+
| 1 || [[#RegisterAddOnContentStorage|RegisterAddOnContentStorage]]
 
|-
 
|-
| 2 || UnregisterAllAddOnContentPath || None || Clears all registered titles here.
+
| 2 || [[#UnregisterAllAddOnContentPath|UnregisterAllAddOnContentPath]]
 
|-
 
|-
| 3 || [9.0.0+] [[#RefreshApplicationAddOnContent]] || Type-5 buffer || Unofficial name
+
| 3 || [9.0.0+] [[#RefreshApplicationAddOnContent|RefreshApplicationAddOnContent]]
 
|-
 
|-
| 4 || [9.0.0+] [[#UnregisterApplicationAddOnContent]] || [[#ApplicationId]] || Unofficial name
+
| 4 || [9.0.0+] [[#UnregisterApplicationAddOnContent|UnregisterApplicationAddOnContent]]
 
|-
 
|-
| 5 || [15.0.0+] GetRegisteredAddOnContentPaths || || Unofficial name
+
| 5 || [15.0.0+] [[#GetRegisteredAddOnContentPaths|GetRegisteredAddOnContentPaths]]
 
|-
 
|-
| 6 || [15.0.0+] RegisterAddOnContentPath || || Unofficial name
+
| 6 || [15.0.0+] [[#RegisterAddOnContentPath|RegisterAddOnContentPath]]
 
|-
 
|-
| 7 || [15.0.0+] RegisterAddOnContentPaths || || Unofficial name
+
| 7 || [15.0.0+] [[#RegisterAddOnContentPaths|RegisterAddOnContentPaths]]
 
|}
 
|}
   −
==== RefreshApplicationAddOnContent ====
+
=== ResolveAddOnContentPath ===
Takes an type-5 buffer containing an array of [[#ApplicationId]]. Unregisters entries with IDs absent from the input buffer.
+
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.
   −
==== UnregisterApplicationAddOnContent====
+
Takes an input [[#DataId]], an input [[#ApplicationId]] and a type-0x15 input buffer. No output.
Takes an [[#ApplicationId]] for the application to unregister add on content entries for.
     −
=== Location List Entry ===
+
=== RegisterAddOnContentPaths ===
Total size is 0x320 bytes.  
+
Unofficial name.
   −
{| class="wikitable" border="1"
+
Takes an input [[#DataId]], an input [[#ApplicationId]] and two type-0x15 input buffers. No output.
|-
  −
! Offset || Size || Description
  −
|-
  −
| 0x0 || 0x8|| Pointer to previous entry
  −
|-
  −
| 0x8 || 0x8|| Pointer to next entry
  −
|-
  −
| 0x10 || 0x8|| [[#ProgramId]]
  −
|-
  −
| 0x18 || 0x300 || [[Filesystem_services#ContentPath|ContentPath]]
  −
|-
  −
| 0x318 || 0x4 || Flag
  −
|-
  −
| 0x31C || 0x4 || Padding
  −
|}
     −
= Content Manager services =
+
= ncm =
== ncm ==
   
This is "nn::ncm::IContentManager".
 
This is "nn::ncm::IContentManager".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name
 
|-
 
|-
| 0 || CreateContentStorage || Takes a [[#StorageId]].
+
| 0 || [[#CreateContentStorage|CreateContentStorage]]
 
|-
 
|-
| 1 || CreateContentMetaDatabase || Takes a [[#StorageId]].
+
| 1 || [[#CreateContentMetaDatabase|CreateContentMetaDatabase]]
 
|-
 
|-
| 2 || VerifyContentStorage || Takes a [[#StorageId]].
+
| 2 || [[#VerifyContentStorage|VerifyContentStorage]]
 
|-
 
|-
| 3 || VerifyContentMetaDatabase || Takes a [[#StorageId]].
+
| 3 || [[#VerifyContentMetaDatabase|VerifyContentMetaDatabase]]
 
|-
 
|-
| 4 || OpenContentStorage || Takes a [[#StorageId]], [2.0.0+] Only returns a storage if one has previously been opened globally via CreateContentStorage.
+
| 4 || [[#OpenContentStorage|OpenContentStorage]]
 
|-
 
|-
| 5 || OpenContentMetaDatabase || Takes a [[#StorageId]], [2.0.0+] Only returns a storage if one has previously been opened globally via CreateContentStorage.
+
| 5 || [[#OpenContentMetaDatabase|OpenContentMetaDatabase]]
 
|-
 
|-
| 6 || [1.0.0] CloseContentStorageForcibly || Takes a [[#StorageId]]. Calls IContentStorage->DisableForcibly().
+
| 6 || [1.0.0] [[#CloseContentStorageForcibly|CloseContentStorageForcibly]]
 
|-
 
|-
| 7 || [1.0.0] CloseContentMetaDatabaseForcibly || Takes a [[#StorageId]].  Calls IContentMetaDatabase->DisableForcibly().
+
| 7 || [1.0.0] [[#CloseContentMetaDatabaseForcibly|CloseContentMetaDatabaseForcibly]]
 
|-
 
|-
| 8 || CleanupContentMetaDatabase || Takes a [[#StorageId]], and deletes the associated savedata.
+
| 8 || [[#CleanupContentMetaDatabase|CleanupContentMetaDatabase]]
 
|-
 
|-
| 9 || [2.0.0+] ActivateContentStorage || Takes a [[#StorageId]], and opens an IContentStorage for the StorageID to be gotten with GetIContentStorage. Note: Name is not official.
+
| 9 || [2.0.0+] [[#ActivateContentStorage|ActivateContentStorage]]
 
|-
 
|-
| 10 || [2.0.0+] InactivateContentStorage || Takes a [[#StorageId]], and closes the associated IContentStorage.
+
| 10 || [2.0.0+] [[#InactivateContentStorage|InactivateContentStorage]]
 
|-
 
|-
| 11 || [2.0.0+] ActivateContentMetaDatabase || Takes a [[#StorageId]], and opens an IContentMetaDatabase for the StorageID to be gotten with CreateContentMetaDatabase.
+
| 11 || [2.0.0+] [[#ActivateContentMetaDatabase|ActivateContentMetaDatabase]]
 
|-
 
|-
| 12 || [2.0.0+] InactivateContentMetaDatabase || Takes a [[#StorageId]], and closes the associated IContentMetaDatabase.
+
| 12 || [2.0.0+] [[#InactivateContentMetaDatabase|InactivateContentMetaDatabase]]
 
|-
 
|-
| 13 || [9.0.0+] InvalidateRightsIdCache ||
+
| 13 || [9.0.0+] [[#InvalidateRightsIdCache|InvalidateRightsIdCache]]
 
|-
 
|-
| 14 || [10.0.0+] GetMemoryReport ||
+
| 14 || [10.0.0+] [[#GetMemoryReport|GetMemoryReport]]
 
|}
 
|}
   −
=== IContentStorage ===
+
== 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|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]].
 +
 
 +
== 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".
 
This is "nn::ncm::IContentStorage".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name
 
|-
 
|-
| 0 || [[#GeneratePlaceHolderId]] || Returns a random UUID for the Content Storage.
+
| 0 || [[#GeneratePlaceHolderId|GeneratePlaceHolderId]]
 
|-
 
|-
| 1 || CreatePlaceHolder || Takes a [[#ContentId]], a [[#PlaceHolderId]], and a s64 filesize.
+
| 1 || [[#CreatePlaceHolder|CreatePlaceHolder]]
 
|-
 
|-
| 2 || DeletePlaceHolder || Takes a [[#PlaceHolderId]].
+
| 2 || [[#DeletePlaceHolder|DeletePlaceHolder]]
 
|-
 
|-
| 3 || HasPlaceHolder ||  Takes a [[#PlaceHolderId]] and returns an output u8 bool.
+
| 3 || [[#HasPlaceHolder|HasPlaceHolder]]
 
|-
 
|-
| 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.
+
| 4 || [[#WritePlaceHolder|WritePlaceHolder]]
 
|-
 
|-
| 5 || Register || Takes a [[#ContentId]] and a [[#PlaceHolderId]], no output. Moves the Placeholder NCA content to the registered NCA path.
+
| 5 || [[#Register|Register]]
 
|-
 
|-
| 6 || Delete || Takes a [[#ContentId]].
+
| 6 || [[#Delete|Delete]]
 
|-
 
|-
| 7 || Has || Takes a [[#ContentId]].
+
| 7 || [[#Has|Has]]
 
|-
 
|-
| 8 || GetPath || Takes a [[#ContentId]] and a type-0x1A output buffer containing a [[Filesystem_services#ContentPath|ContentPath]].
+
| 8 || [[#GetPath|GetPath]]
 
|-
 
|-
| 9 || GetPlaceHolderPath || Takes a [[#PlaceHolderId]] and a type-0x1A output buffer containing a [[Filesystem_services#ContentPath|ContentPath]].
+
| 9 || [[#GetPlaceHolderPath|GetPlaceHolderPath]]
 
|-
 
|-
| 10 || CleanupAllPlaceHolder || No input/output. Deletes and re-creates the Placeholder directory.
+
| 10 || [[#CleanupAllPlaceHolder|CleanupAllPlaceHolder]]
 
|-
 
|-
| 11 || ListPlaceHolder || This is like [[#GetNumberOfRegisteredEntries]], but for the Placeholder directory.
+
| 11 || [[#ListPlaceHolder|ListPlaceHolder]]
 
|-
 
|-
| 12 || [[#GetContentCount]] ||
+
| 12 || [[#GetContentCount|GetContentCount]]
 
|-
 
|-
| 13 || [[#ListContentId]] ||
+
| 13 || [[#ListContentId|ListContentId]]
 
|-
 
|-
| 14 || [[#GetSizeFromContentId]] ||
+
| 14 || [[#GetSizeFromContentId|GetSizeFromContentId]]
 
|-
 
|-
| 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.
+
| 15 || [[#DisableForcibly|DisableForcibly]]
 
|-
 
|-
| 16 || [2.0.0+] 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.
+
| 16 || [2.0.0+] [[#RevertToPlaceHolder|RevertToPlaceHolder]]
 
|-
 
|-
| 17 || [2.0.0+] SetPlaceHolderSize || Takes a [[#PlaceHolderId]], and a s64 size, no output.
+
| 17 || [2.0.0+] [[#SetPlaceHolderSize|SetPlaceHolderSize]]
 
|-
 
|-
| 18 || [2.0.0+] [[#ReadContentIdFile]] ||
+
| 18 || [2.0.0+] [[#ReadContentIdFile|ReadContentIdFile]]
 
|-
 
|-
| 19 || [2.0.0+] [[#GetRightsIdFromPlaceHolderId]] ||
+
| 19 || [2.0.0+] [[#GetRightsIdFromPlaceHolderId|GetRightsIdFromPlaceHolderId]]
 
|-
 
|-
| 20 || [2.0.0+] [[#GetRightsIdFromContentId]] ||
+
| 20 || [2.0.0+] [[#GetRightsIdFromContentId|GetRightsIdFromContentId]]
 
|-
 
|-
| 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.
+
| 21 || [2.0.0+] [[#WriteContentForDebug|WriteContentForDebug]]
 
|-
 
|-
| 22 || [2.0.0+] GetFreeSpaceSize || Gets free space for the storage.
+
| 22 || [2.0.0+] GetFreeSpaceSize
 
|-
 
|-
| 23 || [2.0.0+] GetTotalSpaceSize || Gets total space for the storage.
+
| 23 || [2.0.0+] GetTotalSpaceSize
 
|-
 
|-
| 24 || [3.0.0+] FlushPlaceHolder || Flushes resources for the storage without closing it.
+
| 24 || [3.0.0+] FlushPlaceHolder
 
|-
 
|-
| 25 || [4.0.0+] GetSizeFromPlaceHolderId ||
+
| 25 || [4.0.0+] GetSizeFromPlaceHolderId
 
|-
 
|-
| 26 || [4.0.0+] RepairInvalidFileAttribute ||
+
| 26 || [4.0.0+] RepairInvalidFileAttribute
 
|-
 
|-
| 27 || [8.0.0+] GetRightsIdFromPlaceHolderIdWithCache ||
+
| 27 || [8.0.0+] GetRightsIdFromPlaceHolderIdWithCache
 
|-
 
|-
| 28 || [13.0.0+] RegisterPath ||
+
| 28 || [13.0.0+] RegisterPath
 
|-
 
|-
| 29 || [13.0.0+] ClearRegisteredPath ||
+
| 29 || [13.0.0+] ClearRegisteredPath
 
|}
 
|}
   −
==== GeneratePlaceHolderId ====
+
=== GeneratePlaceHolderId ===
Generates a random [[#PlaceHolderId]] for use as a placeholder.
+
No input. Returns an output [[#PlaceHolderId]].
    
Calls nn::util::GenerateUuid(), which internally calls nn::os::GenerateRandomBytes(16);
 
Calls nn::util::GenerateUuid(), which internally calls nn::os::GenerateRandomBytes(16);
   −
==== GetContentCount ====
+
=== CreatePlaceHolder ===
Writes the total number of entries which can be read by GetEntries, to cmdreply <SFCO_offset>+0x10.
+
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.
   −
==== ListContentId====
+
Writes the buffer to the file for the placeholder path at the specified offset.
Takes an output buffer, s32 offset and gets all entries starting at that offset.
+
 
Returns number of entries read.
+
=== 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]].
 
Each entry is a [[#ContentId]].
Line 377: Line 548:  
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 [[#ContentId]] 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]] "<ContentId>.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 ====
+
=== 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.
 
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.
+
Reads plaintext NCA file contents from the "Registered" path for the ContentId.
   −
==== GetRightsIdFromPlaceHolderId ====
+
=== GetRightsIdFromPlaceHolderId ===
 
Takes a [[#PlaceHolderId]], returns a [[#RightsId]].
 
Takes a [[#PlaceHolderId]], returns a [[#RightsId]].
    
Gets the Rights ID for the [[#PlaceHolderId]]'s placeholder path.
 
Gets the Rights ID for the [[#PlaceHolderId]]'s placeholder path.
   −
==== GetRightsIdFromContentId ====
+
=== GetRightsIdFromContentId ===
 
Takes a [[#ContentId]], returns a [[#RightsId]].
 
Takes a [[#ContentId]], returns a [[#RightsId]].
    
Gets the Rights ID for the [[#ContentId]]'s registered path
 
Gets the Rights ID for the [[#ContentId]]'s registered path
   −
=== IContentMetaDatabase ===
+
=== 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".
 
This is "nn::ncm::IContentMetaDatabase".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name
 
|-
 
|-
| 0 || Set || Takes a [[#ContentMetaKey]], a type-5 [[CNMT#Content_Records|Content Records]] buffer and a u64 size.
+
| 0 || [[#Set|Set]]
 
|-
 
|-
| 1 || Get || Takes a [[#ContentMetaKey]], a type-6 buffer to write [[CNMT#Content_Records|Content Records]] 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.
+
| 1 || [[#Get|Get]]
 
|-
 
|-
| 2 || Remove || Takes a [[#ContentMetaKey]], and removes the associated record.
+
| 2 || [[#Remove|Remove]]
 
|-
 
|-
| 3 || GetContentIdByType || Takes a [[#ContentMetaKey]] and a u8 [[#ContentType]]. Returns a [[#ContentId]].
+
| 3 || [[#GetContentIdByType|GetContentIdByType]]
 
|-
 
|-
| 4 || ListContentInfo || Takes a type-6 buffer to write [[CNMT#Content_Records|Content Record]] entries to, a [[#ContentMetaKey]], and a s32 index into the Content Record entries to start copying from. Returns a s32 entries_read.
+
| 4 || [[#ListContentInfo|ListContentInfo]]
 
|-
 
|-
| 5 || List || Takes a type-6 buffer to write [[#ContentMetaKey]]s to, a u32 [[#ContentMetaType]], a [[#ProgramId]], a u64 ProgramId_Low, and u64 ProgramId_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.
+
| 5 || [[#List|List]]
 
|-
 
|-
| 6 || GetLatestContentMetaKey || Takes a [[#ProgramId]], and returns the [[#ContentMetaKey]] with the highest version field for that ProgramId.
+
| 6 || [[#GetLatestContentMetaKey|GetLatestContentMetaKey]]
 
|-
 
|-
| 7 || [[#ListApplication]] ||
+
| 7 || [[#ListApplication|ListApplication]]
 
|-
 
|-
| 8 || Has || Takes a [[#ContentMetaKey]] and returns an output u8 bool indicating whether that record is present in the database.
+
| 8 || [[#Has|Has]]  
 
|-
 
|-
| 9 || HasAll || Takes a type-0x5 input buffer containing an array of [[#ContentMetaKey]], and returns whether all of those records are present in the database.
+
| 9 || [[#HasAll|HasAll]]  
 
|-
 
|-
| 10 || GetSize || Takes a [[#ContentMetaKey]], and returns the size of the associated [[CNMT#Content_Records|Content Records]].
+
| 10 || [[#GetSize|GetSize]]  
 
|-
 
|-
| 11 || GetRequiredSystemVersion || Takes a [[#ContentMetaKey]], and returns u32 from ContentRecords + 16 (only if the content meta key has type Application or Patch).
+
| 11 || [[#GetRequiredSystemVersion|GetRequiredSystemVersion]]
 
|-
 
|-
| 12 || GetPatchId || Takes a [[#ContentMetaKey]], and returns the update [[#ProgramId]] for that record.
+
| 12 || [[#GetPatchId|GetPatchId]]
 
|-
 
|-
| 13 || DisableForcibly || Closes the meta database, and causes all future IPC commands to the current session to return error 0xDC05.
+
| 13 || [[#DisableForcibly|DisableForcibly]]
 
|-
 
|-
| 14 || [[#LookupOrphanContent]] || Takes a type-6 byte buffer, and a type-5 buffer of [[#ContentId]]s.
+
| 14 || [[#LookupOrphanContent|LookupOrphanContent]]
 
|-
 
|-
| 15 || Commit || Flushes the in-memory database to savedata.
+
| 15 || [[#Commit|Commit]]
 
|-
 
|-
| 16 || HasContent || Takes a [[#ContentMetaKey]] and an [[#ContentId]]. Returns whether the content records for that content meta key contain the ContentId.
+
| 16 || [[#HasContent|HasContent]]  
 
|-
 
|-
| 17 || ListContentMetaInfo || Takes a type-6 [[#ContentMetaKey]] output buffer, a s32 offset into that buffer, and an input [[#ContentMetaKey]].
+
| 17 || [[#ListContentMetaInfo|ListContentMetaInfo]]
 
|-
 
|-
| 18 || GetAttributes || Takes a [[#ContentMetaKey]], and returns u8 from ContentRecords + 6.
+
| 18 || [[#GetAttributes|GetAttributes]]
 
|-
 
|-
| 19 || [2.0.0+] GetRequiredApplicationVersion || Does the same thing as GetRequiredSystemVersion, but for AddOnContents.
+
| 19 || [2.0.0+] [[#GetRequiredApplicationVersion|GetRequiredApplicationVersion]]
 
|-
 
|-
| 20 || [5.0.0+] GetContentIdByTypeAndIdOffset || Takes a [[#ContentMetaKey]], a u8 [[#ContentType]] and a u8 id_offset. Returns a [[#ContentId]].
+
| 20 || [5.0.0+] [[#GetContentIdByTypeAndIdOffset|GetContentIdByTypeAndIdOffset]]  
 
|-
 
|-
| 21 || [10.0.0+] GetCount || Returns a u32 count.
+
| 21 || [10.0.0+] [[#GetCount|GetCount]]
 
|-
 
|-
| 22 || [10.0.0+] GetOwnerApplicationId || Takes a [[#ContentMetaKey]]. Returns a [[#ApplicationId]].
+
| 22 || [10.0.0+] [[#GetOwnerApplicationId|GetOwnerApplicationId]]  
 
|-
 
|-
| 23 || [15.0.0+] GetContentAccessibilities ||
+
| 23 || [15.0.0+] GetContentAccessibilities
 
|-
 
|-
| 24 || [15.0.0+] GetContentInfoByType ||
+
| 24 || [15.0.0+] GetContentInfoByType
 
|-
 
|-
| 25 || [15.0.0+] GetContentInfoByTypeAndIdOffset ||
+
| 25 || [15.0.0+] GetContentInfoByTypeAndIdOffset
 
|}
 
|}
   −
==== ListApplication ====
+
=== Set ===
Each 24-byte entry (officially "ApplicationContentMetaKey") is as follows:
+
Takes a [[#ContentMetaKey]], a type-5 [[CNMT#PackagedContentInfo|PackagedContentInfo]] buffer and a u64 size.
  [[CNMT#Meta_records|meta_record]] meta_record;
  −
  u64   base_title_id;
     −
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.
+
=== 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.
 
This func returns a s32 num_entries_total, and a s32 num_entries_written.
   −
==== ReadEntryMetaRecords ====
+
=== Has ===
Takes a type-6 [[#ContentMetaKey]] output buffer, a s32 offset into that buffer, and an input [[#ContentMetaKey]] entry. Returns a s32 for total_read_entries.
+
Takes a [[#ContentMetaKey]] and returns an output u8 bool indicating whether that record is present in the database.
   −
Reads the content meta keys stored in the entry's content records into the output buffer.
+
=== HasAll ===
 +
Takes a type-0x5 input buffer containing an array of [[#ContentMetaKey]], and returns whether all of those records are present in the database.
   −
This is used, for example, with System Update title 0100000000000816, which contains content meta keys for all other systitles in its Content Records.
+
=== GetSize ===
 +
Takes a [[#ContentMetaKey]], and returns the size of the associated [[CNMT#PackagedContentInfo|PackagedContentInfo]].
   −
==== LookupOrphanContent ====
+
=== 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]].
 
Takes a type-6 byte buffer, and a type-0x5 buffer containing an array of [[#ContentId]].
   Line 482: Line 703:  
In pseudocode, the function basically does the following:
 
In pseudocode, the function basically does the following:
   −
for i in range(len(out_buf)):
+
for i in range(len(out_buf)):
    out_buf[i] = 1
+
    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|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".
   −
for i, ContentId in ContentId:
+
This service doesn't exist on retail.
    if is_present_in_database(ContentId):
+
 
        out_buf[i] = 0
+
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || [[#GetSystemVersion|GetSystemVersion]]
 +
|}
   −
=== ContentId ===
+
== 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
 +
|}
 +
 
 +
= ContentId =
 
This is "nn::ncm::ContentId".
 
This is "nn::ncm::ContentId".
   Line 496: Line 776:  
The ContentId is the same as the first 0x10-bytes from the calculated SHA256 hash, from hashing the entire output from [[#ReadContentIdFile]].
 
The ContentId is the same as the first 0x10-bytes from the calculated SHA256 hash, from hashing the entire output from [[#ReadContentIdFile]].
   −
=== PlaceHolderId ===
+
= PlaceHolderId =
 
This is "nn::ncm::PlaceHolderId".
 
This is "nn::ncm::PlaceHolderId".
    
This is the same as [[#ContentId]], except this is for placeholder content and originates from [[#GeneratePlaceHolderId]].
 
This is the same as [[#ContentId]], except this is for placeholder content and originates from [[#GeneratePlaceHolderId]].
   −
== ProgramId ==
+
= ProgramId =
 
This is "nn::ncm::ProgramId" or "nn::ncm::SystemProgramId".
 
This is "nn::ncm::ProgramId" or "nn::ncm::SystemProgramId".
    
This is an u64 ID bound to a [[Title_list#System_Modules|program]].
 
This is an u64 ID bound to a [[Title_list#System_Modules|program]].
   −
== DataId ==
+
= DataId =
 
This is "nn::ncm::DataId" or "nn::ncm::SystemDataId".
 
This is "nn::ncm::DataId" or "nn::ncm::SystemDataId".
    
This is an u64 ID bound to a [[Title_list#System_Data_Archives|data archive]].
 
This is an u64 ID bound to a [[Title_list#System_Data_Archives|data archive]].
   −
== ApplicationId ==
+
= ApplicationId =
 
This is "nn::ncm::ApplicationId" or "nn::ncm::SystemApplicationId".
 
This is "nn::ncm::ApplicationId" or "nn::ncm::SystemApplicationId".
   Line 518: Line 798:  
Value 0 is invalid.
 
Value 0 is invalid.
   −
== PatchId ==
+
= PatchId =
 
This is "nn::ncm::PatchId".
 
This is "nn::ncm::PatchId".
    
This is an u64 ID bound to a program patch.
 
This is an u64 ID bound to a program patch.
   −
== DeltaId ==
+
= DeltaId =
 
This is "nn::ncm::DeltaId".
 
This is "nn::ncm::DeltaId".
    
This is an u64 ID bound to a program delta fragment.
 
This is an u64 ID bound to a program delta fragment.
   −
== AddOnContentId ==
+
= AddOnContentId =
 
This is "nn::ncm::AddOnContentId".
 
This is "nn::ncm::AddOnContentId".
    
This is an u64 ID bound to add-on content data.
 
This is an u64 ID bound to add-on content data.
   −
== SystemUpdateId ==
+
= SystemUpdateId =
 
This is "nn::ncm::SystemUpdateId".
 
This is "nn::ncm::SystemUpdateId".
    
This is an u64 ID bound to system update data.
 
This is an u64 ID bound to system update data.
   −
== DataPatchId ==
+
= DataPatchId =
 
This is "nn::ncm::DataPatchId".
 
This is "nn::ncm::DataPatchId".
   Line 545: Line 825:  
This is an u64 ID bound to a data patch.
 
This is an u64 ID bound to a data patch.
   −
== StorageId ==
+
= StorageId =
 
This is "nn::ncm::StorageId".
 
This is "nn::ncm::StorageId".
   Line 573: Line 853:  
nn::ncm::IsUniqueStorage returns true for != None && != Any.
 
nn::ncm::IsUniqueStorage returns true for != None && != Any.
   −
== RightsId ==
+
= RightsId =
 
This is "nn::ncm::RightsId".
 
This is "nn::ncm::RightsId".
   Line 591: Line 871:  
|}
 
|}
   −
== ProgramLocation ==
+
= ProgramLocation =
 
This is "nn::ncm::ProgramLocation".
 
This is "nn::ncm::ProgramLocation".
   Line 607: Line 887:  
|}
 
|}
   −
== Path ==
+
= Path =
 
This is "nn::ncm::Path".
 
This is "nn::ncm::Path".
    
This is a 0x300-byte structure, which contains a [[Filesystem_services#ContentPath|ContentPath]].
 
This is a 0x300-byte structure, which contains a [[Filesystem_services#ContentPath|ContentPath]].
   −
== ContentInstallType ==
+
= ContentInstallType =
This is "nn::ncm::ContentInstallType"
+
This is "nn::ncm::ContentInstallType".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 630: Line 910:  
|}
 
|}
   −
== ContentMetaType ==
+
= ContentMetaType =
This is "nn::ncm::ContentMetaType"
+
This is "nn::ncm::ContentMetaType".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 672: Line 952:  
|}
 
|}
   −
== ContentType ==
+
= ContentType =
This is "nn::ncm::ContentType"
+
This is "nn::ncm::ContentType".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 702: Line 982:  
|}
 
|}
   −
== ContentMetaKey ==
+
= ContentMetaKey =
This is "nn::ncm::ContentMetaKey"
+
This is "nn::ncm::ContentMetaKey".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 732: Line 1,012:  
|}
 
|}
   −
== ncm:v ==
+
= ApplicationContentMetaKey =
This service doesn't normally exist on retail.
+
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]]