Difference between revisions of "NCM services"

From Nintendo Switch Brew
Jump to navigation Jump to search
(IContentManager for 1.0.0)
(nn::ncm::IContentStorage -- commands > 15 don't exist on 1.0.0)
Line 110: Line 110:
 
| 5 || GetIContentMetaDatabase || Takes a [[Filesystem_services#StorageId|StorageID]].
 
| 5 || GetIContentMetaDatabase || Takes a [[Filesystem_services#StorageId|StorageID]].
 
|-
 
|-
| ([[1.0.0]]) 6 || CloseAndLockIContentStorage || Takes a [[Filesystem_services#StorageId|StorageID]]. Calls IContentStorage->CloseStorage().
+
| ([[1.0.0]]) 6 || CloseAndLockIContentStorage || Takes a [[Filesystem_services#StorageId|StorageID]]. Calls IContentStorage->CloseAndFlushStorage().
 
|-
 
|-
 
| ([[1.0.0]]) 7 || CloseAndLockIContentMetaDatabase || Takes a [[Filesystem_services#StorageId|StorageID]].  Calls IContentMetaDatabase->CloseMetaDatabase().
 
| ([[1.0.0]]) 7 || CloseAndLockIContentMetaDatabase || Takes a [[Filesystem_services#StorageId|StorageID]].  Calls IContentMetaDatabase->CloseMetaDatabase().
Line 134: Line 134:
 
! Cmd || Name || Notes
 
! Cmd || Name || Notes
 
|-
 
|-
| 0 || [[#GetRootEntry]] ||
+
| 0 || [[#GetUUID]] || Returns a random UUID for the Content Storage.
 
|-
 
|-
| 1 || || Takes two 0x10-sized entries, and a u64.
+
| 1 || CreatePlaceholderEntryAndRegisteredDirectoryEntry || Takes two [[#NcaID]]s, and a u64 filesize.
 
|-
 
|-
| 2 || DeletePlaceholderEntry || Takes a 0x10-sized entry.
+
| 2 || DeletePlaceholderEntry || Takes a [[#NcaID]].
 
|-
 
|-
| 3 || GetEntryType || Takes a 0x10-sized entry, returns a bool/u8.
+
| 3 || DoesPlaceholderEntryExist || Takes a [[#NcaID]].
 
|-
 
|-
 
| 4 || WritePlaceholderEntry || Takes a [[#NcaID]], a u64-offset, and type-5 array.
 
| 4 || WritePlaceholderEntry || Takes a [[#NcaID]], a u64-offset, and type-5 array.
 
|-
 
|-
| 5 || MovePlaceholderToRegistered || Takes two 0x10-sized entries.
+
| 5 || MovePlaceholderToRegistered || Takes two [[#NcaID]]s, moves the Placeholder NCA content to the registered NCA path.
 
|-
 
|-
| 6 || DeleteContent? || Takes a 0x10-sized entry.
+
| 6 || DeleteRegisteredEntry || Takes a [[#NcaID]].
 
|-
 
|-
| 7 || IsNcaEntryValid || Takes a [[#NcaID]], returns a bool.
+
| 7 || DoesRegisteredEntryExist || Takes a [[#NcaID]].
 
|-
 
|-
| 8 || GetPath || Takes a [[#NcaID]]. Returns a [[Filesystem_services#ContentPath|Content Path]].
+
| 8 || GetPathForRegisteredEntry || Takes a [[#NcaID]]. Returns a [[Filesystem_services#ContentPath|Content Path]].
 
|-
 
|-
| 9 || GetPlaceholderPath || Takes a [[#NcaID]]. Returns a [[Filesystem_services#ContentPath|Content Path]].
+
| 9 || GetPathForPlaceholderEntry || Takes a [[#NcaID]]. Returns a [[Filesystem_services#ContentPath|Content Path]].
 
|-
 
|-
| 10 || CleanPlaceholderDirectory || Deletes the Placeholder directory.
+
| 10 || CleanPlaceholderDirectory || Deletes and re-creates the Placeholder directory.
 
|-
 
|-
| 11 || GetPlaceholderEntries || This is like [[#GetEntries]], but for the Placeholder directory.
+
| 11 || GetNumberOfRegisteredEntries || This is like [[#GetRegisteredEntries]], but for the Placeholder directory.
 
|-
 
|-
| 12 || [[#GetNumberOfEntries]] ||
+
| 12 || [[#GetNumberOfRegisteredEntries]] ||
 
|-
 
|-
| 13 || [[#GetEntries]] ||
+
| 13 || [[#GetRegisteredEntries]] ||
 
|-
 
|-
| 14 || [[#GetEntrySize]] ||
+
| 14 || [[#GetRegisteredEntrySize]] ||  
 
|-
 
|-
| 15 || CloseStorage || Closes/Flushes all resources for the storage, and causes all future IPC commands to the current session to return error 0xC805.
+
| 15 || CloseAndFlushStorage || 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 || || Takes three 0x10-sized entries.
 
|-
 
|-
| 17 || SetPlaceholderSize || Takes a [[#NcaID]], and a u64 size
+
| 17 || SetPlaceholderEntrySize || Takes a [[#NcaID]], and a u64 size
 
|-
 
|-
| 18 || [[#ReadEntryRaw]] ||
+
| 18 || [[#ReadRegisteredEntryRaw]] ||
 
|-
 
|-
| 19 || GetPlaceholderRightsID || Gets the Rights ID for the [[#NcaID]]'s placeholder path.
+
| 19 || GetPlaceholderEntryRightsID || Gets the Rights ID for the [[#NcaID]]'s placeholder path.
 
|-
 
|-
| 20 || GetRegisteredRightsID || Gets the Rights ID for the [[#NcaID]]'s registered path
+
| 20 || GetRegisteredEntryRightsID || Gets the Rights ID for the [[#NcaID]]'s registered path
 
|-
 
|-
 
| 21 || WriteRegisteredPathForDebug || Takes a [[#NcaID]], a u64 size, and a type 5 buffer. On debug units, writes the buffer to the NCA's registered path. On retail units, this just aborts.
 
| 21 || WriteRegisteredPathForDebug || Takes a [[#NcaID]], a u64 size, 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 ||
+
| 22 || GetFreeSpace || Gets free space for the storage.
 
|-
 
|-
| 23 || GetTotalSpace ||
+
| 23 || GetTotalSpace || Gets total space for the storage.
 +
|-
 +
| 24 || FlushStorage || Flushes resources for the storage without closing it.
 
|}
 
|}
  
Line 188: Line 190:
 
Changes on reboot?
 
Changes on reboot?
  
==== GetNumberOfEntries ====
+
==== GetNumberOfRegisteredEntries ====
 
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.
  
==== GetEntries ====
+
==== GetRegisteredEntries ====
 
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 199: Line 201:
 
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?).
  
==== GetEntrySize ====
+
==== GetRegisteredEntrySize ====
 
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 ReadEntryRaw. This is the same as the size-field in the [[NAX0]] "<NcaID>.nca/00" file.
  
==== ReadEntryRaw ====
+
==== ReadRegisteredEntryRaw ====
 
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.
  

Revision as of 08:26, 8 February 2018

NCM contains services for internal file path and content management.

Location Resolver services

lr

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

Cmd Name Arguments Notes
0 GetLocationResolver StorageID
1 GetRegisteredLocationResolver None
2 CheckStorage StorageID
3 GetAddOnContentLocationResolver 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 Arguments Notes
0 GetProgramNcaPath u64 TID + C descriptor Used for NCA-type1.
1 SetProgramNcaPath u64 TID + X descriptor ContentPath Used for NCA-type1.
2 GetUserControlNcaPath u64 TID + C descriptor Used for NCA-type3 (gamecard only?).
3 GetDocHtmlNcaPath u64 TID + C descriptor Used for NCA-type4.
4 GetControlNcaPath u64 TID + C descriptor Used for NCA-type3. Stubbed, only returns error 0x608.
5 SetControlNcaPath u64 TID + X descriptor ContentPath Used for NCA-type3.
6 SetDocHtmlNcaPath u64 TID + X descriptor ContentPath Used for NCA-type4.
7 GetInfoHtmlNcaPath u64 TID + C descriptor Used for NCA-type5.
8 SetInfoHtmlNcaPath u64 TID + X descriptor ContentPath Used for NCA-type5.
9 ClearLocationResolver None Clears all NCA paths set.

These get-commands load the 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.

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.

IRegisteredLocationResolver

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

Cmd Name Arguments Notes
0 GetPatchType0NcaPath u64 TID + C descriptor Used for NCA-type1.
1 SetPatchType0NcaPath u64 TID + X descriptor ContentPath
2 RegisterPatchTitle0 u64 TID
3 SetPatchTitle0NcaPath u64 TID + X descriptor ContentPath
4 GetPatchType1NcaPath u64 TID + C descriptor
5 SetPatchType1NcaPath u64 TID + X descriptor ContentPath
6 RegisterPatchTitle1 u64 TID
7 SetPatchTitle1NcaPath u64 TID + X descriptor ContentPath

IAddOnContentLocationResolver

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

Cmd Name Arguments Notes
0 GetAddOnContentNcaPath u64 TID + C descriptor
1 RegisterAddOnContent StorageID + u64 TID
2 ClearAddOnContentLocationResolver None Clears all registered titles here.

Content Manager services

ncm

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

Cmd Name Notes
0 CreatePlaceholderAndRegisteredDirectoriesForMediaId Takes a StorageID.
1 CreateSaveDataDirectoryForMediaId Takes a StorageID.
2 GetExistsPlaceholderAndRegisteredDirectoriesForMediaId Takes a StorageID.
3 GetExistsSaveDataDirectoryForMediaId Takes a StorageID.
4 GetIContentStorage Takes a StorageID.
5 GetIContentMetaDatabase Takes a StorageID.
(1.0.0) 6 CloseAndLockIContentStorage Takes a StorageID. Calls IContentStorage->CloseAndFlushStorage().
(1.0.0) 7 CloseAndLockIContentMetaDatabase Takes a StorageID. Calls IContentMetaDatabase->CloseMetaDatabase().
8 DeleteSaveDataForMediaId Takes a StorageID, and deletes the associated savedata.
(2.0.0+?) 9 MountStorageForMediaId
(2.0.0+?) 10 UnmountStorageForMediaId
(2.0.0+?) 11 MountDatabaseForMediaId
(2.0.0+?) 12 UnmountDatabaseForMediaId

All of the above cmds takes a u8 as input.

IContentStorage

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

Cmd Name Notes
0 #GetUUID Returns a random UUID for the Content Storage.
1 CreatePlaceholderEntryAndRegisteredDirectoryEntry Takes two #NcaIDs, and a u64 filesize.
2 DeletePlaceholderEntry Takes a #NcaID.
3 DoesPlaceholderEntryExist Takes a #NcaID.
4 WritePlaceholderEntry Takes a #NcaID, a u64-offset, and type-5 array.
5 MovePlaceholderToRegistered Takes two #NcaIDs, moves the Placeholder NCA content to the registered NCA path.
6 DeleteRegisteredEntry Takes a #NcaID.
7 DoesRegisteredEntryExist Takes a #NcaID.
8 GetPathForRegisteredEntry Takes a #NcaID. Returns a Content Path.
9 GetPathForPlaceholderEntry Takes a #NcaID. Returns a Content Path.
10 CleanPlaceholderDirectory Deletes and re-creates the Placeholder directory.
11 GetNumberOfRegisteredEntries This is like #GetRegisteredEntries, but for the Placeholder directory.
12 #GetNumberOfRegisteredEntries
13 #GetRegisteredEntries
14 #GetRegisteredEntrySize
15 CloseAndFlushStorage 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.
17 SetPlaceholderEntrySize Takes a #NcaID, and a u64 size
18 #ReadRegisteredEntryRaw
19 GetPlaceholderEntryRightsID Gets the Rights ID for the #NcaID's placeholder path.
20 GetRegisteredEntryRightsID Gets the Rights ID for the #NcaID's registered path
21 WriteRegisteredPathForDebug Takes a #NcaID, a u64 size, 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.
23 GetTotalSpace Gets total space for the storage.
24 FlushStorage Flushes resources for the storage without closing it.

GetRootEntry

Returns an entry of 16 completely random-looking bytes. It is not possible to read this entry.

Changes on reboot?

GetNumberOfRegisteredEntries

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

GetRegisteredEntries

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

GetRegisteredEntrySize

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.

ReadRegisteredEntryRaw

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.

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.

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

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.

See GetEntrySize for the total size readable with this.

IContentMetaDatabase

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

Cmd Name Notes
0 InsertContentEntry? Takes a 0x10-sized entry, a type-5 buffer and a u64.
1 Takes a 0x10-sized entry, a type-6 buffer and a u64. Returns a u64.
2 Takes a 0x10-sized entry.
3 UpdateContentEntry Takes a meta record entry and a u8. Returns a #NcaID.
4 Takes a type-6 buffer, each entry being 24 bytes, 0x10-sized entry and a u32. Returns a u32.
5 Iterate Takes a type-6 buffer, each entry being 16 bytes, a 0x10-sized entry, and a u32. Returns a u32.
6 #GetTitleIdInfo
7 #GetTitleList Takes a type-6 buffer, each entry being 24 bytes, and a u8/bool. Returns two u32's.
8 Takes a 0x10-sized entry. Returns a bool/u8.
9 Takes a type-5 buffer, each entry being 16 bytes. Returns a bool/u8.
10 Takes a 0x10-sized entry. Returns a u64.
11 Takes a 0x10-sized entry. Returns a u32.
12 Takes a 0x10-sized entry. Returns a u64.
13 CloseMetaDatabase Closes/Flushes all resources for the meta database, and causes all future IPC commands to the current session to return error 0xDC05.
14 Takes a type-6 byte buffer, and a type-5 buffer with each entry being 16 bytes.
15 EndIteration Void.
16 Takes two 0x10-sized entries. Returns a bool/u8.
17 #GetUpdateTitleList
18 Takes a 0x10-sized entry. Returns a bool/u8.
19 Takes a 0x10-sized entry. Returns a u32.

GetTitleIdInfo

Takes a u64 title-id as input, returns same title-id together with info struct.

struct title_info {
  u32  version;
  u8   type;
  u8   pad[3];
};

GetTitleList

Each 24-byte entries is as follows:

 u64    title_id_update;
 struct title_info info;
 u64    title_id;


GetUpdateTitleList

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 010000000000081B, where it's 1)

See NCA#Meta_records.

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

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

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

Enums

Title Types

Value Description
0x01 System Programs (System Modules or System Applets)
0x02 System Data Archives
0x03 System Update
0x04 Firmware package A
0x05 Firmware package B
0x80 Regular application
0x81 Update title
0x82 Add-on content
0x83 Delta title

ncm:v