Difference between revisions of "NCM services"

From Nintendo Switch Brew
Jump to navigation Jump to search
(GetTitleUpdateRecords)
(48 intermediate revisions by 8 users not shown)
Line 9: Line 9:
 
! Cmd || Name || Arguments || Notes
 
! Cmd || Name || Arguments || Notes
 
|-
 
|-
| 0 || GetLocationResolver || [[Filesystem_services#StorageId|StorageID]] ||
+
| 0 || OpenLocationResolver || [[Filesystem_services#StorageId|StorageID]] ||
 
|-
 
|-
| 1 || GetRegisteredLocationResolver || None ||  
+
| 1 || OpenRegisteredLocationResolver || None ||  
 
|-
 
|-
| 2 || CheckStorage || [[Filesystem_services#StorageId|StorageID]] ||
+
| 2 || RefreshLocationResolver || [[Filesystem_services#StorageId|StorageID]] ||
 
|-
 
|-
| 3 || GetAddOnContentLocationResolver || None  ||
+
| 3 || [2.0.0+] OpenAddOnContentLocationResolver || None  ||
 
|}
 
|}
  
Line 25: Line 25:
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Arguments || Notes
+
! Cmd || Name || Notes
 +
|-
 +
| 0 || [[#ResolveProgramPath]] ||
 +
|-
 +
| 1 || [[#RedirectProgramPath]] ||
 +
|-
 +
| 2 || [[#ResolveApplicationControlPath]] ||
 +
|-
 +
| 3 || [[#ResolveApplicationHtmlDocumentPath]] ||
 +
|-
 +
| 4 || [[#ResolveDataPath]] ||
 +
|-
 +
| 5 || [[#RedirectApplicationControlPath]] ||
 +
|-
 +
| 6 || [[#RedirectApplicationHtmlDocumentPath]] ||
 +
|-
 +
| 7 || [[#ResolveApplicationLegalInformationPath]] ||
 +
|-
 +
| 8 || [[#RedirectApplicationLegalInformationPath]] ||
 +
|-
 +
| 9 || [[#Refresh]] ||
 
|-
 
|-
| 0 || GetProgramNcaPath || u64 TID + C descriptor || Used for [[NCA_Content_FS#NCA-type1|NCA-type1]].
+
| 10 || [5.0.0+] [[#RedirectApplicationProgramPath]] ||
 
|-
 
|-
| 1 || SetProgramNcaPath || u64 TID + X descriptor [[Filesystem_services#ContentPath|ContentPath]] || Used for [[NCA_Content_FS#NCA-type1|NCA-type1]].
+
| 11 || [5.0.0+] [[#ClearApplicationRedirection]] ||
 
|-
 
|-
| 2 || GetUserControlNcaPath || u64 TID + C descriptor || Used for [[NCA_Content_FS#NCA-type3|NCA-type3]] (gamecard only?).
+
| 12 || [5.0.0+] [[#EraseProgramRedirection]] ||
 
|-
 
|-
| 3 || GetDocHtmlNcaPath || u64 TID + C descriptor || Used for [[NCA_Content_FS#NCA-type4|NCA-type4]].
+
| 13 || [5.0.0+] [[#EraseApplicationControlRedirection]] ||
 
|-
 
|-
| 4 || GetControlNcaPath || u64 TID + C descriptor || Used for [[NCA_Content_FS#NCA-type3|NCA-type3]]. Stubbed, only returns error 0x608.
+
| 14 || [5.0.0+] [[#EraseApplicationHtmlDocumentRedirection]] ||
 
|-
 
|-
| 5 || SetControlNcaPath || u64 TID + X descriptor [[Filesystem_services#ContentPath|ContentPath]] || Used for [[NCA_Content_FS#NCA-type3|NCA-type3]].
+
| 15 || [5.0.0+] [[#EraseApplicationLegalInformationRedirection]] ||
 
|-
 
|-
| 6 || SetDocHtmlNcaPath || u64 TID + X descriptor [[Filesystem_services#ContentPath|ContentPath]] || Used for [[NCA_Content_FS#NCA-type4|NCA-type4]].
+
| 16 || [7.0.0+] [[#ResolveProgramPathForDebug]] || Unofficial name
 
|-
 
|-
| 7 || GetInfoHtmlNcaPath || u64 TID + C descriptor || Used for [[NCA_Content_FS#NCA-type5|NCA-type5]].
+
| 17 || [7.0.0+] [[#RedirectProgramPathForDebug]] || Unofficial name
 
|-
 
|-
| 8 || SetInfoHtmlNcaPath || u64 TID + X descriptor [[Filesystem_services#ContentPath|ContentPath]] || Used for [[NCA_Content_FS#NCA-type5|NCA-type5]].
+
| 18 || [7.0.0+] [[#RedirectApplicationProgramPathForDebug]] || Unofficial name
 
|-
 
|-
| 9 || ClearLocationResolver || None || Clears all NCA paths set.
+
| 19 || [7.0.0+] [[#EraseProgramRedirectionForDebug]] || Unofficial name
 
|}
 
|}
  
These get-commands load the [[Filesystem_services|ContentPath]] from linked-lists in memory using the input titleID. The set-commands add a new entry to the list, if a matching entry is found it's removed first. ClearLocationResolver frees all entries in all of these linked-lists. The ContentPath is only used with memcpy() here with size=0x300, nothing more.
+
If the supplied [[Filesystem_services#StorageId|StorageID]] is 1 (Host), a different set of internal functions is used to handle these commands. In this more restricted set of functions, GetControlNcaPath is stubbed and only returns error 0x608.
+
 
The set commands always return 0. When the get-commands fail to find an entry for the specified titleID, 0x408 is returned for GetProgramNcaPath, while the rest of the commands return 0xA08.
+
The Get* commands load the [[Filesystem_services|ContentPath]] from linked-lists' [[#Location_List_Entry|entries]] in memory using the input TitleID. When the command fails to find an entry for the specified TitleID, 0x408 is returned for GetProgramNcaPath 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 u64 '''TitleID''' and a C descriptor. Used for [[NCA_Content_FS#NCA-type1|NCA-type1]].
 +
 
 +
==== RedirectProgramPath ====
 +
Takes an u64 '''TitleID''' and a X descriptor with a [[Filesystem_services#ContentPath|ContentPath]]. Used for [[NCA_Content_FS#NCA-type1|NCA-type1]].
 +
 
 +
Inserts a new [[#Location_List_Entry|entry]] with '''flag''' set to 0.
 +
 
 +
==== ResolveApplicationControlPath ====
 +
Takes an u64 '''TitleID''' and a C descriptor. Used for [[NCA_Content_FS#NCA-type3|NCA-type3]].
 +
 
 +
==== ResolveApplicationHtmlDocumentPath====
 +
Takes an u64 '''TitleID''' and a C descriptor. Used for [[NCA_Content_FS#NCA-type4|NCA-type4]].
 +
 
 +
==== ResolveDataPath ====
 +
Takes an u64 '''TitleID''' and a C descriptor. Used for [[NCA_Content_FS#NCA-type3|NCA-type3]].
 +
 
 +
==== RedirectApplicationControlPath ====
 +
Takes an u64 '''TitleID''' and a X descriptor with a [[Filesystem_services#ContentPath|ContentPath]]. Used for [[NCA_Content_FS#NCA-type3|NCA-type3]].
 +
 
 +
[9.0.0+] Now takes an additional 8-bytes of input.
 +
 
 +
Inserts a new [[#Location_List_Entry|entry]] with '''flag''' set to 1.
 +
 
 +
==== RedirectApplicationHtmlDocumentPath ====
 +
Takes an u64 '''TitleID''' and a X descriptor with a [[Filesystem_services#ContentPath|ContentPath]]. Used for [[NCA_Content_FS#NCA-type4|NCA-type4]].
 +
 
 +
[9.0.0+] Now takes an additional 8-bytes of input.
 +
 
 +
Inserts a new [[#Location_List_Entry|entry]] with '''flag''' set to 1.
 +
 
 +
==== ResolveApplicationLegalInformationPath ====
 +
Takes an u64 '''TitleID''' and a C descriptor. Used for [[NCA_Content_FS#NCA-type5|NCA-type5]].
 +
 
 +
==== RedirectApplicationLegalInformationPath ====
 +
Takes an u64 '''TitleID''' and a X descriptor with a [[Filesystem_services#ContentPath|ContentPath]]. Used for [[NCA_Content_FS#NCA-type5|NCA-type5]].
 +
 
 +
[9.0.0+] Now takes an additional 8-bytes of input.
 +
 
 +
Inserts a new [[#Location_List_Entry|entry]] with '''flag''' set to 1.
 +
 
 +
==== Refresh ====
 +
Takes no input. Frees all linked-lists' entries that have '''flag''' set to 0.
 +
 
 +
==== RedirectApplicationProgramPath ====
 +
Same as [[#RedirectProgramPath|RedirectProgramPath]], but inserts a new [[#Location_List_Entry|entry]] with '''flag''' set to 1.
 +
 
 +
[9.0.0+] Now takes an additional 8-bytes of input.
 +
 
 +
==== ClearApplicationRedirection ====
 +
Takes no input. Frees all linked-lists' entries that have '''flag''' set to 1.
 +
 
 +
[9.0.0+] Now takes a type-0x5 input buffer, no output.
 +
 
 +
==== EraseProgramRedirection ====
 +
Takes an u64 '''TitleID'''. Used for [[NCA_Content_FS#NCA-type1|NCA-type1]].
 +
 
 +
Removes the [[#Location_List_Entry|entry]] that matches the input TitleID.
 +
 
 +
==== EraseApplicationControlRedirection ====
 +
Takes an u64 '''TitleID'''. Used for [[NCA_Content_FS#NCA-type3|NCA-type3]].
 +
 
 +
Removes the [[#Location_List_Entry|entry]] that matches the input TitleID.
 +
 
 +
==== EraseApplicationHtmlDocumentRedirection ====
 +
Takes an u64 '''TitleID'''. Used for [[NCA_Content_FS#NCA-type4|NCA-type4]].
 +
 
 +
Removes the [[#Location_List_Entry|entry]] that matches the input TitleID.
 +
 
 +
==== EraseApplicationLegalInformationRedirection ====
 +
Takes an u64 '''TitleID'''. Used for [[NCA_Content_FS#NCA-type5|NCA-type5]].
 +
 
 +
Removes the [[#Location_List_Entry|entry]] that matches the input TitleID.
 +
 
 +
==== ResolveProgramPathForDebug ====
 +
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 ====
 +
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 ====
 +
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 ====
 +
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.
  
 
=== IRegisteredLocationResolver ===
 
=== IRegisteredLocationResolver ===
Line 61: Line 179:
 
! Cmd || Name || Arguments || Notes
 
! Cmd || Name || Arguments || Notes
 
|-
 
|-
| 0 || GetPatchType0NcaPath || u64 TID + C descriptor || Used for [[NCA_Content_FS#NCA-type1|NCA-type1]].
+
| 0 || ResolveProgramPath || u64 TitleID + C descriptor || Used for [[NCA_Content_FS#NCA-type1|NCA-type1]].
 +
|-
 +
| 1 || RegisterProgramPath || u64 TitleID + 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.
 +
|-
 +
| 2 || UnregisterProgramPath || u64 TitleID || If the Type 0 fallback TID is == argument TID, unregisters the fallback path. Otherwise, noop.
 
|-
 
|-
| 1 || RegisterPatchType0FallbackPath || u64 TID + X descriptor [[Filesystem_services#ContentPath|ContentPath]] || Sets the Type 0 fallback TID and path to the provided arguments.
+
| 3 || RedirectProgramPath || u64 TitleID + X descriptor [[Filesystem_services#ContentPath|ContentPath]] [9.0.0+] Now takes an additional 8-bytes of input. ||
 
|-
 
|-
| 2 || UnregisterPatchType0FallbackPath || u64 TID || If the Type 0 fallback TID is == argument TID, unregisters the fallback path. Otherwise, noop.
+
| 4 || [2.0.0+] ResolveHtmlDocumentPath || u64 TitleID + C descriptor ||
 
|-
 
|-
| 3 || SetPatchType0NcaPath || u64 TID + X descriptor [[Filesystem_services#ContentPath|ContentPath]] ||
+
| 5 || [2.0.0+] RegisterHtmlDocumentPath || u64 TitleID + 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.
 
|-
 
|-
| ([[2.0.0]]+) 4 || GetPatchType1NcaPath || u64 TID + C descriptor ||
+
| 6 || [2.0.0+] UnregisterHtmlDocumentPath || u64 TitleID || If the Type 1 fallback TID is == argument TID, unregisters the fallback path. Otherwise, noop.
 
|-
 
|-
| ([[2.0.0]]+) 5 || RegisterPatchType1FallbackPath || u64 TID + X descriptor [[Filesystem_services#ContentPath|ContentPath]] || Sets the Type 1 fallback TID and path to the provided arguments.
+
| 7 || [2.0.0+] RedirectHtmlDocumentPath || u64 TitleID + X descriptor [[Filesystem_services#ContentPath|ContentPath]] [9.0.0+] Now takes an additional 8-bytes of input. ||
 
|-
 
|-
| ([[2.0.0]]+) 6 || UnregisterPatchType1FallbackPath || u64 TID || If the Type 1 fallback TID is == argument TID, unregisters the fallback path. Otherwise, noop.
+
| 8 || [7.0.0+] Refresh || No input/output. ||  
 
|-
 
|-
| ([[2.0.0]]+) 7 || SetPatchType1NcaPath || u64 TID + X descriptor [[Filesystem_services#ContentPath|ContentPath]] ||
+
| 9 || [9.0.0+] || ||
 
|}
 
|}
  
Line 85: Line 207:
 
! Cmd || Name || Arguments || Notes
 
! Cmd || Name || Arguments || Notes
 
|-
 
|-
| 0 || GetAddOnContentNcaPath || u64 TID + C descriptor ||  
+
| 0 || ResolveAddOnContentPath || u64 TitleID + C descriptor ||  
 +
|-
 +
| 1 || RegisterAddOnContentStorage || [[Filesystem_services#StorageId|StorageID]] + u64 TitleID [9.0.0+] Now takes an additional u64 TitleID for the owner application. ||
 +
|-
 +
| 2 || UnregisterAllAddOnContentPath || None || Clears all registered titles here.
 +
|-
 +
| 3 || [9.0.0+] [[#RefreshApplicationAddOnContent]] || Type-5 buffer || Unofficial name
 +
|-
 +
| 4 || [9.0.0+] [[#UnregisterApplicationAddOnContent]] || u64 TitleID || Unofficial name
 +
|}
 +
 
 +
==== RefreshApplicationAddOnContent ====
 +
Takes an type-5 buffer containing application title ids. Unregisters entries with application ids absent from the input buffer.
 +
 
 +
==== UnregisterApplicationAddOnContent====
 +
Takes an u64 '''TitleID''' for the application to unregister add on content entries for.
 +
 
 +
=== Location List Entry ===
 +
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|| TitleID
 
|-
 
|-
| 1 || RegisterAddOnContent || [[Filesystem_services#StorageId|StorageID]] + u64 TID ||
+
| 0x18 || 0x300 || [[Filesystem_services|ContentPath]]
 
|-
 
|-
| 2 || ClearAddOnContentLocationResolver || None || Clears all registered titles here.
+
| 0x318 || 0x4 || Flag
 +
|-
 +
| 0x31C || 0x4 || Padding
 
|}
 
|}
  
Line 100: Line 252:
 
! Cmd || Name || Notes
 
! Cmd || Name || Notes
 
|-
 
|-
| 0 || CreatePlaceholderAndRegisteredDirectoriesForMediaId || Takes a [[Filesystem_services#StorageId|StorageID]].
+
| 0 || CreateContentStorage || Takes a [[Filesystem_services#StorageId|StorageID]].
 
|-
 
|-
| 1 || CreateSaveDataDirectoryForMediaId || Takes a [[Filesystem_services#StorageId|StorageID]].
+
| 1 || CreateContentMetaDatabase || Takes a [[Filesystem_services#StorageId|StorageID]].
 
|-
 
|-
| 2 || GetExistsPlaceholderAndRegisteredDirectoriesForMediaId || Takes a [[Filesystem_services#StorageId|StorageID]].
+
| 2 || VerifyContentStorage || Takes a [[Filesystem_services#StorageId|StorageID]].
 
|-
 
|-
| 3 || GetExistsSaveDataDirectoryForMediaId || Takes a [[Filesystem_services#StorageId|StorageID]].
+
| 3 || VerifyContentMetaDatabase || Takes a [[Filesystem_services#StorageId|StorageID]].
 
|-
 
|-
| 4 || GetIContentStorage || Takes a [[Filesystem_services#StorageId|StorageID]].
+
| 4 || OpenContentStorage || Takes a [[Filesystem_services#StorageId|StorageID]], [2.0.0+] Only returns a storage if one has previously been opened globally via OpenIContentStorage.
 
|-
 
|-
| 5 || GetIContentMetaDatabase || Takes a [[Filesystem_services#StorageId|StorageID]].
+
| 5 || OpenContentMetaDatabase || Takes a [[Filesystem_services#StorageId|StorageID]], [2.0.0+] Only returns a storage if one has previously been opened globally via OpenIContentStorage.
 
|-
 
|-
| ([[1.0.0]]) 6 || CloseAndLockIContentStorage || Takes a [[Filesystem_services#StorageId|StorageID]]. Calls IContentStorage->CloseAndFlushStorage().
+
| 6 || [1.0.0] CloseContentStorageForcibly || Takes a [[Filesystem_services#StorageId|StorageID]]. Calls IContentStorage->CloseAndFlushStorage().
 
|-
 
|-
| ([[1.0.0]]) 7 || CloseAndLockIContentMetaDatabase || Takes a [[Filesystem_services#StorageId|StorageID]].  Calls IContentMetaDatabase->CloseMetaDatabase().
+
| 7 || [1.0.0] CloseContentMetaDatabaseForcibly || Takes a [[Filesystem_services#StorageId|StorageID]].  Calls IContentMetaDatabase->CloseMetaDatabase().
 
|-
 
|-
| 8 || DeleteSaveDataForMediaId || Takes a [[Filesystem_services#StorageId|StorageID]], and deletes the associated savedata.
+
| 8 || CleanupContentMetaDatabase || Takes a [[Filesystem_services#StorageId|StorageID]], and deletes the associated savedata.
 
|-
 
|-
| (2.0.0+?) 9 || MountStorageForMediaId ||
+
| 9 || [2.0.0+] ActivateContentStorage || Takes a [[Filesystem_services#StorageId|StorageID]], and opens an IContentStorage for the StorageID to be gotten with GetIContentStorage. Note: Name is not official.
 
|-
 
|-
| (2.0.0+?) 10 || UnmountStorageForMediaId ||
+
| 10 || [2.0.0+] InactivateContentStorage || Takes a [[Filesystem_services#StorageId|StorageID]], and closes the associated IContentStorage. Note: Name is not official.
 
|-
 
|-
| (2.0.0+?) 11 || MountDatabaseForMediaId ||
+
| 11 || [2.0.0+] ActivateContentMetaDatabase || Takes a [[Filesystem_services#StorageId|StorageID]], and opens an IContentMetaDatabase for the StorageID to be gotten with GetIContentMetaDatabase. Note: Name is not official.
 
|-
 
|-
| (2.0.0+?) 12 || UnmountDatabaseForMediaId ||
+
| 12 || [2.0.0+] InactivateContentMetaDatabase || Takes a [[Filesystem_services#StorageId|StorageID]], and closes the associated IContentMetaDatabase. Note: Name is not official.
 +
|-
 +
| 13 || [9.0.0+] InvalidateRightsIdCache ||
 
|}
 
|}
 
All of the above cmds takes a u8 as input.
 
  
 
=== IContentStorage ===
 
=== IContentStorage ===
Line 136: Line 288:
 
! Cmd || Name || Notes
 
! Cmd || Name || Notes
 
|-
 
|-
| 0 || [[#GetUUID]] || Returns a random UUID for the Content Storage.
+
| 0 || [[#GeneratePlaceHolderId]] || Returns a random UUID for the Content Storage.
 
|-
 
|-
| 1 || CreatePlaceholderEntryAndRegisteredDirectoryEntry || Takes two [[#NcaID]]s, and a u64 filesize.
+
| 1 || CreatePlaceHolder || Takes two [[#NcaID]]s, and a u64 filesize.
 
|-
 
|-
| 2 || DeletePlaceholderEntry || Takes a [[#NcaID]].
+
| 2 || DeletePlaceHolder || Takes a [[#NcaID]].
 
|-
 
|-
| 3 || DoesPlaceholderEntryExist ||  Takes a [[#NcaID]].
+
| 3 || HasPlaceHolder ||  Takes a [[#NcaID]].
 
|-
 
|-
| 4 || WritePlaceholderEntry || Takes a [[#NcaID]], a u64-offset, and type 5 buffer. Writes the buffer to the file for the NcaID's placeholder path at the specified offset.
+
| 4 || WritePlaceHolder || Takes a [[#NcaID]], a u64-offset, and type 5 buffer. Writes the buffer to the file for the NcaID's placeholder path at the specified offset.
 
|-
 
|-
| 5 || MovePlaceholderToRegistered || Takes two [[#NcaID]]s, moves the Placeholder NCA content to the registered NCA path.
+
| 5 || Register || Takes two [[#NcaID]]s, moves the Placeholder NCA content to the registered NCA path.
 
|-
 
|-
| 6 || DeleteRegisteredEntry || Takes a [[#NcaID]].
+
| 6 || Delete || Takes a [[#NcaID]].
 
|-
 
|-
| 7 || DoesRegisteredEntryExist || Takes a [[#NcaID]].
+
| 7 || Has || Takes a [[#NcaID]].
 
|-
 
|-
| 8 || GetPathForRegisteredEntry || Takes a [[#NcaID]]. Returns a [[Filesystem_services#ContentPath|Content Path]].
+
| 8 || GetPath || Takes a [[#NcaID]]. Returns a [[Filesystem_services#ContentPath|Content Path]].
 
|-
 
|-
| 9 || GetPathForPlaceholderEntry || Takes a [[#NcaID]]. Returns a [[Filesystem_services#ContentPath|Content Path]].
+
| 9 || GetPlaceHolderPath || Takes a [[#NcaID]]. Returns a [[Filesystem_services#ContentPath|Content Path]].
 
|-
 
|-
| 10 || CleanPlaceholderDirectory || Deletes and re-creates the Placeholder directory.
+
| 10 || CleanupAllPlaceHolder || Deletes and re-creates the Placeholder directory.
 
|-
 
|-
| 11 || GetNumberOfRegisteredEntries || This is like [[#GetRegisteredEntries]], but for the Placeholder directory.
+
| 11 || ListPlaceHolder || This is like [[#GetNumberOfRegisteredEntries]], but for the Placeholder directory.
 
|-
 
|-
| 12 || [[#GetNumberOfRegisteredEntries]] ||
+
| 12 || [[#GetContentCount]] ||
 
|-
 
|-
| 13 || [[#GetRegisteredEntries]] ||
+
| 13 || [[#ListContentId]] ||
 
|-
 
|-
| 14 || [[#GetRegisteredEntrySize]] ||  
+
| 14 || [[#GetSizeFromContentId]] ||  
 
|-
 
|-
| 15 || CloseAndFlushStorage || Closes/Flushes all resources for the storage, and causes all future IPC commands to the current session to return error 0xC805.
+
| 15 || DisableForcibly || Closes/Flushes all resources for the storage, and causes all future IPC commands to the current session to return error 0xC805.
 
|-
 
|-
| 16 || || Takes three 0x10-sized entries.
+
| 16 || [2.0.0+] RevertToPlaceHolder || Takes three 0x10-sized [[#NcaID]]s. Creates the registered directory NCA path, and renames the placeholder path to the registered NCA path.
 
|-
 
|-
| 17 || SetPlaceholderEntrySize || Takes a [[#NcaID]], and a u64 size
+
| 17 || [2.0.0+] SetPlaceHolderSize || Takes a [[#NcaID]], and a u64 size
 
|-
 
|-
| 18 || [[#ReadRegisteredEntryRaw]] ||
+
| 18 || [2.0.0+] [[#ReadContentIdFile]] ||
 
|-
 
|-
| 19 || GetPlaceholderEntryRightsID || Gets the Rights ID for the [[#NcaID]]'s placeholder path.
+
| 19 || [2.0.0+] [[#GetRightsIdFromPlaceHolderId]] ||
 
|-
 
|-
| 20 || GetRegisteredEntryRightsID || Gets the Rights ID for the [[#NcaID]]'s registered path
+
| 20 || [2.0.0+] [[#GetRightsIdFromContentId]] ||
 
|-
 
|-
| 21 || WriteRegisteredPathForDebug || Takes a [[#NcaID]], a u64 offset, and a type 5 buffer. On debug units, writes the buffer to the NCA's registered path. On retail units, this just aborts.
+
| 21 || [2.0.0+] WriteContentForDebug || Takes a [[#NcaID]], a u64 offset, and a type 5 buffer. On debug units, writes the buffer to the NCA's registered path. On retail units, this just aborts.
 
|-
 
|-
| 22 || GetFreeSpace || Gets free space for the storage.
+
| 22 || [2.0.0+] GetFreeSpaceSize || Gets free space for the storage.
 
|-
 
|-
| 23 || GetTotalSpace || Gets total space for the storage.
+
| 23 || [2.0.0+] GetTotalSpaceSize || Gets total space for the storage.
 
|-
 
|-
| 24 || FlushStorage || Flushes resources for the storage without closing it.
+
| 24 || [3.0.0+] FlushPlaceHolder || Flushes resources for the storage without closing it.
 +
|-
 +
| 25 || [4.0.0+] GetSizeFromPlaceHolderId ||
 +
|-
 +
| 26 || [4.0.0+] RepairInvalidFileAttribute ||
 +
|-
 +
| 27 || [8.0.0+] GetRightsIdFromPlaceHolderIdWithCache ||
 
|}
 
|}
  
==== GetUUID ====
+
==== GeneratePlaceHolderId ====
Calls nn::util::GenerateUuid(), which internally calls nn::os::GenerateRandomBytes(16);
+
Generates a random [[#NcaID]] for use as a placeholder.
 +
 
 +
Calls nn::util::GenerateUuid(), which internally calls nn::os::GenerateRandomBytes(16);
  
==== GetNumberOfRegisteredEntries ====
+
==== GetContentCount ====
 
Writes the total number of entries which can be read by GetEntries, to cmdreply <SFCO_offset>+0x10.
 
Writes the total number of entries which can be read by GetEntries, to cmdreply <SFCO_offset>+0x10.
  
==== GetRegisteredEntries ====
+
==== ListContentId====
 
Takes an output buffer, u32 offset and gets all entries starting at that offset.
 
Takes an output buffer, u32 offset and gets all entries starting at that offset.
 
Returns number of entries read.
 
Returns number of entries read.
Line 201: Line 361:
 
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?).
  
==== GetRegisteredEntrySize ====
+
==== GetSizeFromContentId ====
 
Takes a [[#NcaID]] as input.
 
Takes a [[#NcaID]] as input.
  
Returns the total size readable by ReadEntryRaw. This is the same as the size-field in the [[NAX0]] "<NcaID>.nca/00" file.
+
Returns the total size readable by [[#ReadContentIdFile]]. This is the same as the size-field in the [[NAX0]] "<NcaID>.nca/00" file.
  
==== ReadRegisteredEntryRaw ====
+
==== ReadContentIdFile ====
 
Takes an output buffer, a [[#NcaID]] as input, and a u64 file offset.
 
Takes an output buffer, a [[#NcaID]] as input, and a u64 file offset.
  
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.
+
Reads plaintext NCA file contents from the Registered path for the NcaID.
 +
 
 +
==== GetRightsIdFromPlaceHolderId ====
 +
Takes a total of 0x10-bytes of input, returns a total of 0x10-bytes of 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.
+
[3.0.0+] Returns an additional 8-bytes of 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).
+
Gets the Rights ID for the [[#NcaID]]'s placeholder path.
  
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.
+
==== GetRightsIdFromContentId ====
 +
Takes a total of 0x10-bytes of input, returns a total of 0x10-bytes of output.
  
See GetEntrySize for the total size readable with this.
+
[3.0.0+] Returns an additional 8-bytes of output.
 +
 
 +
Gets the Rights ID for the [[#NcaID]]'s registered path
  
 
=== IContentMetaDatabase ===
 
=== IContentMetaDatabase ===
Line 226: Line 392:
 
! Cmd || Name || Notes
 
! Cmd || Name || Notes
 
|-
 
|-
| 0 || InsertContentRecords || Takes a [[NCA#Meta_records|Meta Record]], a type-5 [[NCA#Content_records|Content Records]] buffer and a u64 size.
+
| 0 || Set || Takes a [[#ContentMetaKey|Content Meta Key]], a type-5 [[CNMT#Content_records|Content Records]] buffer and a u64 size.
 +
|-
 +
| 1 || Get || Takes a [[#ContentMetaKey|Content Meta Key]], 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 || ReadContentRecords || Takes a [[NCA#Meta_records|Meta Record]], a type-6 buffer to write [[NCA#Content_records|Content Records]] to and a u64 size. Returns the actual Content Records size read.
+
| 2 || Remove || Takes a [[#ContentMetaKey|Content Meta Key]], and removes the associated record.
 
|-
 
|-
| 2 || RemoveContentRecords || Takes a [[NCA#Meta_records|Meta Record]], and removes the associated record.
+
| 3 || GetContentIdByType || Takes a [[#ContentMetaKey|Content Meta Key]] and a u8 [[#ContentMetaType|Content Meta Type]]. Returns a [[#NcaID]].
 
|-
 
|-
| 3 || GetContentNcaId || Takes a [[NCA#Meta_records|Meta Record]] and a u8 [[#Title_Types|Title Type]]. Returns a [[#NcaID]].
+
| 4 || ListContentInfo || Takes a type-6 buffer to write [[CNMT#Content_records|Content Record]] entries to, a [[#ContentMetaKey|Content Meta Key]], and a u32 index into the Content Record entries to start copying from. Returns a u32 entries_read.
 
|-
 
|-
| 4 || || Takes a type-6 buffer, each entry being 24 bytes, 0x10-sized entry and a u32. Returns a u32.
+
| 5 || List || Takes a type-6 buffer to write [[#ContentMetaKey|Content Meta Key]]s to, a u32 [[#ContentMetaType|Content Meta Type]], a u64 TID, a u64 TID_LOW, and u64 TID_HIGH. Writes into the buffer all Content Meta Keys with low <= record->title_id <= high, and record->type == type. Returns u32 numEntriesTotal, numEntriesWritten. Additionally requires record->title_id == TID, if record->type is Application, Patch, Add-On, or Delta, otherwise, you can pass 0 for type to ignore the type and list them all in the range.
 
|-
 
|-
| 5 || Iterate || Takes a type-6 buffer, each entry being 16 bytes, a 0x10-sized entry, and a u32. Returns a u32.
+
| 6 || GetLatestContentMetaKey || Takes a u64 title id, and returns the [[#ContentMetaKey|Content Meta Key]] with the highest version field for that title id.
 
|-
 
|-
| 6 || GetMetaRecord || Takes a u64 title id, and returns the [[NCA#Meta_records|Meta Record]] with the highest version field for that title id.
+
| 7 || [[#ListApplication]] ||
 
|-
 
|-
| 7 || [[#GetTitleUpdateRecords]] ||
+
| 8 || Has || Takes a [[#ContentMetaKey|Content Meta Key]] and returns whether that record is present in the database.
 
|-
 
|-
| 8 || || Takes a 0x10-sized entry. Returns a bool/u8.
+
| 9 || HasAll || Takes a type-5 buffer containing [[#ContentMetaKey|Content Meta Key]] (code assumes there are size/sizeof(meta_record) records in the buffer), and returns whether all of those records are present in the database.
 
|-
 
|-
| 9 || || Takes a type-5 buffer, each entry being 16 bytes. Returns a bool/u8.
+
| 10 || GetSize || Takes a [[#ContentMetaKey|Content Meta Key]], and returns the size of the associated [[CNMT#Content_records|Content Records]].
 
|-
 
|-
| 10 || || Takes a 0x10-sized entry. Returns a u64.
+
| 11 || GetRequiredSystemVersion || Takes a [[#ContentMetaKey|Content Meta Key]], and returns u32 from ContentRecords + 16 (only if the content meta key has type Application or Patch).
 
|-
 
|-
| 11 || || Takes a 0x10-sized entry. Returns a u32.
+
| 12 || GetPatchId || Takes a [[#ContentMetaKey|Content Meta Key]], and returns the update title id for that record.
 
|-
 
|-
| 12 || || Takes a 0x10-sized entry. Returns a u64.
+
| 13 || DisableForcibly || Closes the meta database, and causes all future IPC commands to the current session to return error 0xDC05.
 
|-
 
|-
| 13 || CloseMetaDatabase || Closes the meta database, and causes all future IPC commands to the current session to return error 0xDC05.
+
| 14 || [[#LookupOrphanContent]] || Takes a type-6 byte buffer, and a type-5 buffer of [[#NcaID]]s.
 
|-
 
|-
| 14 || || Takes a type-6 byte buffer, and a type-5 buffer with each entry being 16 bytes.
+
| 15 || Commit || Flushes the in-memory database to savedata.
 
|-
 
|-
| 15 || SaveMetaDatabase || Flushes the in-memory database to savedata.
+
| 16 || HasContent || Takes a [[#ContentMetaKey|Content Meta Key]] and an [[#NcaID]]. Returns whether the content records for that content meta key contain the NcaID.
 
|-
 
|-
| 16 || || Takes two 0x10-sized entries. Returns a bool/u8.
+
| 17 || ListContentMetaInfo || Takes a type-6 [[#ContentMetaKey|Content Meta Key]] output buffer, a u32 offset into that buffer, and an input [[#ContentMetaKey|Content Meta Key]].
 
|-
 
|-
| 17 || [[#GetUpdateTitleList]] ||
+
| 18 || GetAttributes || Takes a [[#ContentMetaKey|Content Meta Key]], and returns u8 from ContentRecords + 6.
 
|-
 
|-
| 18 || || Takes a 0x10-sized entry. Returns a bool/u8.
+
| 19 || [2.0.0+] GetRequiredApplicationVersion || Does the same thing as GetEntryUnknownRecordSize, but for AddOnContents.
 
|-
 
|-
| 19 || || Takes a 0x10-sized entry. Returns a u32.
+
| 20 || [5.0.0+] GetContentIdByTypeAndIdOffset ||
 
|}
 
|}
  
 +
==== ListApplication ====
 +
Each 24-byte entry (officially "ApplicationContentMetaKey") is as follows:
 +
  [[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.
 +
 +
This func returns a u32 num_entries_total, and a u32 num_entries_written.
  
==== GetTitleUpdateRecords ====
+
==== ReadEntryMetaRecords ====
Each 24-byte entry is as follows:
+
Takes a type-6 [[#ContentMetaKey|Content Meta Key]] output buffer, a u32 offset into that buffer, and an input [[#ContentMetaKey|Content Meta Key]] entry. Returns a u32 for total_read_entries.
  [[NCA#Meta_records|meta_record]] meta_record;
 
  u64    update_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.
+
Reads the content meta keys stored in the entry's content records into the output buffer.
 +
 
 +
This is used, for example, with System Update title 0100000000000816, which contains content meta keys for all other systitles in its Content Records.
  
This func returns a u32 num_entries_written, and a u32 num_entries_total.
+
==== LookupOrphanContent ====
 +
Takes a type-6 byte buffer, and a type-5 buffer containing [[#NcaID]]s.
  
 +
This function was stubbed to return 0xDC05 in [[2.0.0]].
  
==== GetUpdateTitleList ====
+
On 1.0.0: Initialized the output buffer to all 1s. Then, for each [[#NcaID]] in the input buffer, it checks if that NcaID is present anywhere in the database, and if so writes 0 to the corresponding output byte.
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.
 
  
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)
+
In pseudocode, the function basically does the following:
  
See [[NCA#Meta_records]].
+
for i in range(len(out_buf)):
 +
    out_buf[i] = 1
  
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).
+
for i, NcaID in NcaIDs:
 +
    if is_present_in_database(NcaID):
 +
        out_buf[i] = 0
  
 
=== NcaID ===
 
=== 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]]). This is also referred to as "ContentId" in the official SDK.
  
The NcaID is the same as the first 0x10-bytes from the calculated SHA256 hash, from hashing the entire output from ReadEntryRaw.
+
The NcaID is the same as the first 0x10-bytes from the calculated SHA256 hash, from hashing the entire output from [[#ReadContentIdFile]].
 +
 
 +
== ContentInstallType ==
 +
This is "nn::ncm::ContentInstallType"
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value
 +
! Description
 +
|-
 +
| 0x0
 +
| Full
 +
|-
 +
| 0x1
 +
| FragmentOnly
 +
|-
 +
| 0x7
 +
| Unknown (Invalid Content Install Type)
 +
|}
  
=== Enums ===
+
== ContentMetaType ==
==== Title Types ====
+
This is "nn::ncm::ContentMetaType"
  
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 299: Line 497:
 
! 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
 
| 0x83
| Delta title
+
| Delta
 +
|}
 +
 
 +
== ContentMetaKey ==
 +
This is "nn::ncm::ContentMetaKey"
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x8
 +
| Title id
 +
|-
 +
| 0x8
 +
| 0x4
 +
| Version
 +
|-
 +
| 0xC
 +
| 0x1
 +
| [[#ContentMetaType|Content Meta Type]]
 +
|-
 +
| 0xD
 +
| 0x1
 +
| [[#ContentInstallType|Content Install Type]]
 
|-
 
|-
 +
| 0xE
 +
| 0x2
 +
| Padding
 
|}
 
|}
  
 
== ncm:v ==
 
== ncm:v ==
 +
This service doesn't normally exist on retail.
  
 
[[Category:Services]]
 
[[Category:Services]]

Revision as of 14:47, 12 September 2019

NCM contains services for internal file path and content management.

Location Resolver services

lr

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

Cmd Name Arguments Notes
0 OpenLocationResolver StorageID
1 OpenRegisteredLocationResolver None
2 RefreshLocationResolver StorageID
3 [2.0.0+] OpenAddOnContentLocationResolver None

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

ILocationResolver

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

Cmd Name Notes
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 Unofficial name
17 [7.0.0+] #RedirectProgramPathForDebug Unofficial name
18 [7.0.0+] #RedirectApplicationProgramPathForDebug Unofficial name
19 [7.0.0+] #EraseProgramRedirectionForDebug Unofficial name

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, GetControlNcaPath is stubbed and only returns error 0x608.

The Get* commands load the ContentPath from linked-lists' entries in memory using the input TitleID. When the command fails to find an entry for the specified TitleID, 0x408 is returned for GetProgramNcaPath 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 u64 TitleID and a C descriptor. Used for NCA-type1.

RedirectProgramPath

Takes an u64 TitleID and a X descriptor with a ContentPath. Used for NCA-type1.

Inserts a new entry with flag set to 0.

ResolveApplicationControlPath

Takes an u64 TitleID and a C descriptor. Used for NCA-type3.

ResolveApplicationHtmlDocumentPath

Takes an u64 TitleID and a C descriptor. Used for NCA-type4.

ResolveDataPath

Takes an u64 TitleID and a C descriptor. Used for NCA-type3.

RedirectApplicationControlPath

Takes an u64 TitleID and a X descriptor with a ContentPath. Used for NCA-type3.

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

Inserts a new entry with flag set to 1.

RedirectApplicationHtmlDocumentPath

Takes an u64 TitleID and a X descriptor with a ContentPath. Used for NCA-type4.

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

Inserts a new entry with flag set to 1.

ResolveApplicationLegalInformationPath

Takes an u64 TitleID and a C descriptor. Used for NCA-type5.

RedirectApplicationLegalInformationPath

Takes an u64 TitleID and a X descriptor with a ContentPath. Used for NCA-type5.

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

Inserts a new entry with flag set to 1.

Refresh

Takes no input. 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

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

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

EraseProgramRedirection

Takes an u64 TitleID. Used for NCA-type1.

Removes the entry that matches the input TitleID.

EraseApplicationControlRedirection

Takes an u64 TitleID. Used for NCA-type3.

Removes the entry that matches the input TitleID.

EraseApplicationHtmlDocumentRedirection

Takes an u64 TitleID. Used for NCA-type4.

Removes the entry that matches the input TitleID.

EraseApplicationLegalInformationRedirection

Takes an u64 TitleID. Used for NCA-type5.

Removes the entry that matches the input TitleID.

ResolveProgramPathForDebug

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

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

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

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.

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 title ID at a time.

Cmd Name Arguments Notes
0 ResolveProgramPath u64 TitleID + C descriptor Used for NCA-type1.
1 RegisterProgramPath u64 TitleID + X descriptor ContentPath [9.0.0+] Now takes an additional 8-bytes of input. Sets the Type 0 fallback TID and path to the provided arguments.
2 UnregisterProgramPath u64 TitleID If the Type 0 fallback TID is == argument TID, unregisters the fallback path. Otherwise, noop.
3 RedirectProgramPath u64 TitleID + X descriptor ContentPath [9.0.0+] Now takes an additional 8-bytes of input.
4 [2.0.0+] ResolveHtmlDocumentPath u64 TitleID + C descriptor
5 [2.0.0+] RegisterHtmlDocumentPath u64 TitleID + X descriptor ContentPath [9.0.0+] Now takes an additional 8-bytes of input. Sets the Type 1 fallback TID and path to the provided arguments.
6 [2.0.0+] UnregisterHtmlDocumentPath u64 TitleID If the Type 1 fallback TID is == argument TID, unregisters the fallback path. Otherwise, noop.
7 [2.0.0+] RedirectHtmlDocumentPath u64 TitleID + X descriptor ContentPath [9.0.0+] Now takes an additional 8-bytes of input.
8 [7.0.0+] Refresh No input/output.
9 [9.0.0+]

IAddOnContentLocationResolver

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

Cmd Name Arguments Notes
0 ResolveAddOnContentPath u64 TitleID + C descriptor
1 RegisterAddOnContentStorage StorageID + u64 TitleID [9.0.0+] Now takes an additional u64 TitleID for the owner application.
2 UnregisterAllAddOnContentPath None Clears all registered titles here.
3 [9.0.0+] #RefreshApplicationAddOnContent Type-5 buffer Unofficial name
4 [9.0.0+] #UnregisterApplicationAddOnContent u64 TitleID Unofficial name

RefreshApplicationAddOnContent

Takes an type-5 buffer containing application title ids. Unregisters entries with application ids absent from the input buffer.

UnregisterApplicationAddOnContent

Takes an u64 TitleID for the application to unregister add on content entries for.

Location List Entry

Total size is 0x320 bytes.

Offset Size Description
0x0 0x8 Pointer to previous entry
0x8 0x8 Pointer to next entry
0x10 0x8 TitleID
0x18 0x300 ContentPath
0x318 0x4 Flag
0x31C 0x4 Padding

Content Manager services

ncm

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

Cmd Name Notes
0 CreateContentStorage Takes a StorageID.
1 CreateContentMetaDatabase Takes a StorageID.
2 VerifyContentStorage Takes a StorageID.
3 VerifyContentMetaDatabase Takes a StorageID.
4 OpenContentStorage Takes a StorageID, [2.0.0+] Only returns a storage if one has previously been opened globally via OpenIContentStorage.
5 OpenContentMetaDatabase Takes a StorageID, [2.0.0+] Only returns a storage if one has previously been opened globally via OpenIContentStorage.
6 [1.0.0] CloseContentStorageForcibly Takes a StorageID. Calls IContentStorage->CloseAndFlushStorage().
7 [1.0.0] CloseContentMetaDatabaseForcibly Takes a StorageID. Calls IContentMetaDatabase->CloseMetaDatabase().
8 CleanupContentMetaDatabase Takes a StorageID, and deletes the associated savedata.
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.
10 [2.0.0+] InactivateContentStorage Takes a StorageID, and closes the associated IContentStorage. Note: Name is not official.
11 [2.0.0+] ActivateContentMetaDatabase Takes a StorageID, and opens an IContentMetaDatabase for the StorageID to be gotten with GetIContentMetaDatabase. Note: Name is not official.
12 [2.0.0+] InactivateContentMetaDatabase Takes a StorageID, and closes the associated IContentMetaDatabase. Note: Name is not official.
13 [9.0.0+] InvalidateRightsIdCache

IContentStorage

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

Cmd Name Notes
0 #GeneratePlaceHolderId Returns a random UUID for the Content Storage.
1 CreatePlaceHolder Takes two #NcaIDs, and a u64 filesize.
2 DeletePlaceHolder Takes a #NcaID.
3 HasPlaceHolder Takes a #NcaID.
4 WritePlaceHolder Takes a #NcaID, a u64-offset, and type 5 buffer. Writes the buffer to the file for the NcaID's placeholder path at the specified offset.
5 Register Takes two #NcaIDs, moves the Placeholder NCA content to the registered NCA path.
6 Delete Takes a #NcaID.
7 Has Takes a #NcaID.
8 GetPath Takes a #NcaID. Returns a Content Path.
9 GetPlaceHolderPath Takes a #NcaID. Returns a Content Path.
10 CleanupAllPlaceHolder Deletes and re-creates the Placeholder directory.
11 ListPlaceHolder This is like #GetNumberOfRegisteredEntries, but for the Placeholder directory.
12 #GetContentCount
13 #ListContentId
14 #GetSizeFromContentId
15 DisableForcibly Closes/Flushes all resources for the storage, and causes all future IPC commands to the current session to return error 0xC805.
16 [2.0.0+] RevertToPlaceHolder Takes three 0x10-sized #NcaIDs. Creates the registered directory NCA path, and renames the placeholder path to the registered NCA path.
17 [2.0.0+] SetPlaceHolderSize Takes a #NcaID, and a u64 size
18 [2.0.0+] #ReadContentIdFile
19 [2.0.0+] #GetRightsIdFromPlaceHolderId
20 [2.0.0+] #GetRightsIdFromContentId
21 [2.0.0+] WriteContentForDebug Takes a #NcaID, a u64 offset, and a type 5 buffer. On debug units, writes the buffer to the NCA's registered path. On retail units, this just aborts.
22 [2.0.0+] GetFreeSpaceSize Gets free space for the storage.
23 [2.0.0+] GetTotalSpaceSize Gets total space for the storage.
24 [3.0.0+] FlushPlaceHolder Flushes resources for the storage without closing it.
25 [4.0.0+] GetSizeFromPlaceHolderId
26 [4.0.0+] RepairInvalidFileAttribute
27 [8.0.0+] GetRightsIdFromPlaceHolderIdWithCache

GeneratePlaceHolderId

Generates a random #NcaID for use as a placeholder.

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

GetContentCount

Writes the total number of entries which can be read by GetEntries, to cmdreply <SFCO_offset>+0x10.

ListContentId

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

Each entry is a #NcaID.

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 #NcaID as input.

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

ReadContentIdFile

Takes an output buffer, a #NcaID as input, and a u64 file offset.

Reads plaintext NCA file contents from the Registered path for the NcaID.

GetRightsIdFromPlaceHolderId

Takes a total of 0x10-bytes of input, returns a total of 0x10-bytes of output.

[3.0.0+] Returns an additional 8-bytes of output.

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

GetRightsIdFromContentId

Takes a total of 0x10-bytes of input, returns a total of 0x10-bytes of output.

[3.0.0+] Returns an additional 8-bytes of output.

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

IContentMetaDatabase

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

Cmd Name Notes
0 Set Takes a Content Meta Key, a type-5 Content Records buffer and a u64 size.
1 Get Takes a Content Meta Key, a type-6 buffer to write 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.
2 Remove Takes a Content Meta Key, and removes the associated record.
3 GetContentIdByType Takes a Content Meta Key and a u8 Content Meta Type. Returns a #NcaID.
4 ListContentInfo Takes a type-6 buffer to write Content Record entries to, a Content Meta Key, and a u32 index into the Content Record entries to start copying from. Returns a u32 entries_read.
5 List Takes a type-6 buffer to write Content Meta Keys to, a u32 Content Meta Type, a u64 TID, a u64 TID_LOW, and u64 TID_HIGH. Writes into the buffer all Content Meta Keys with low <= record->title_id <= high, and record->type == type. Returns u32 numEntriesTotal, numEntriesWritten. Additionally requires record->title_id == TID, if record->type is Application, Patch, Add-On, or Delta, otherwise, you can pass 0 for type to ignore the type and list them all in the range.
6 GetLatestContentMetaKey Takes a u64 title id, and returns the Content Meta Key with the highest version field for that title id.
7 #ListApplication
8 Has Takes a Content Meta Key and returns whether that record is present in the database.
9 HasAll Takes a type-5 buffer containing Content Meta Key (code assumes there are size/sizeof(meta_record) records in the buffer), and returns whether all of those records are present in the database.
10 GetSize Takes a Content Meta Key, and returns the size of the associated Content Records.
11 GetRequiredSystemVersion Takes a Content Meta Key, and returns u32 from ContentRecords + 16 (only if the content meta key has type Application or Patch).
12 GetPatchId Takes a Content Meta Key, and returns the update title id for that record.
13 DisableForcibly Closes the meta database, and causes all future IPC commands to the current session to return error 0xDC05.
14 #LookupOrphanContent Takes a type-6 byte buffer, and a type-5 buffer of #NcaIDs.
15 Commit Flushes the in-memory database to savedata.
16 HasContent Takes a Content Meta Key and an #NcaID. Returns whether the content records for that content meta key contain the NcaID.
17 ListContentMetaInfo Takes a type-6 Content Meta Key output buffer, a u32 offset into that buffer, and an input Content Meta Key.
18 GetAttributes Takes a Content Meta Key, and returns u8 from ContentRecords + 6.
19 [2.0.0+] GetRequiredApplicationVersion Does the same thing as GetEntryUnknownRecordSize, but for AddOnContents.
20 [5.0.0+] GetContentIdByTypeAndIdOffset

ListApplication

Each 24-byte entry (officially "ApplicationContentMetaKey") is as follows:

 meta_record meta_record;
 u64    base_title_id;

This function takes in a type 6 buffer to write entries to, and a u8 "filter" type. If filter is zero, all update records will be copied to to the output buffer (space permitting). Otherwise, only titles with type == filter_type will be copied to the output buffer.

This func returns a u32 num_entries_total, and a u32 num_entries_written.

ReadEntryMetaRecords

Takes a type-6 Content Meta Key output buffer, a u32 offset into that buffer, and an input Content Meta Key entry. Returns a u32 for total_read_entries.

Reads the content meta keys stored in the entry's content records into the output buffer.

This is used, for example, with System Update title 0100000000000816, which contains content meta keys for all other systitles in its Content Records.

LookupOrphanContent

Takes a type-6 byte buffer, and a type-5 buffer containing #NcaIDs.

This function was stubbed to return 0xDC05 in 2.0.0.

On 1.0.0: Initialized the output buffer to all 1s. Then, for each #NcaID in the input buffer, it checks if that NcaID is present anywhere in the database, and if so writes 0 to the corresponding output byte.

In pseudocode, the function basically does the following:

for i in range(len(out_buf)):

   out_buf[i] = 1

for i, NcaID in NcaIDs:

   if is_present_in_database(NcaID):
       out_buf[i] = 0

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). This is also referred to as "ContentId" in the official SDK.

The NcaID is the same as the first 0x10-bytes from the calculated SHA256 hash, from hashing the entire output from #ReadContentIdFile.

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

ContentMetaKey

This is "nn::ncm::ContentMetaKey"

Offset Size Description
0x0 0x8 Title id
0x8 0x4 Version
0xC 0x1 Content Meta Type
0xD 0x1 Content Install Type
0xE 0x2 Padding

ncm:v

This service doesn't normally exist on retail.