Changes

Jump to navigation Jump to search
6,914 bytes added ,  21:27, 15 October 2023
no edit summary
Line 1: Line 1: −
For the content of the NCA FS which can be [[Filesystem_services|mounted]], see [[NCA_Content_FS|here]].
+
This is the metadata file that ends in <code>".cnmt{.nca}"</code> or <code>"meta0.ncd"</code>. This seems to replace the TMD format.
   −
= Metadata file =
+
The official name for CNMT is "PackagedContentMeta".
This is the file that ends in <code>".cnmt{.nca}"</code> or <code>"meta0.ncd"</code>.
+
 
 +
= PackagedContentMetaHeader =
 +
This is "nn::ncm::PackagedContentMetaHeader".
   −
It starts with a header:
   
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 12: Line 13:  
|-
 
|-
 
| 0x0
 
| 0x0
| 8
+
| 0x8
| Title ID
+
| Id
 
|-
 
|-
 
| 0x8
 
| 0x8
| 4
+
| 0x4
|
+
| Version
 
|-
 
|-
 
| 0xC
 
| 0xC
| 1
+
| 0x1
| Type (see [[Content_Manager_services#Title_Types|Title Types]])
+
| [[NCM_services#ContentMetaType|ContentMetaType]]
 
|-
 
|-
 
| 0xD
 
| 0xD
| 1
+
| 0x1
|
+
| [17.0.0+] [[NCM_services#ContentMetaPlatform|ContentMetaPlatform]] ([1.0.0-16.1.0] Reserved)
 
|-
 
|-
 
| 0xE
 
| 0xE
| 2
+
| 0x2
| Offset to table relative to the end of this 0x20-byte header.
+
| ExtendedHeaderSize
 
|-
 
|-
 
| 0x10
 
| 0x10
| 2
+
| 0x2
| Number of entries
+
| ContentCount
 
|-
 
|-
 
| 0x12
 
| 0x12
| 14
+
| 0x2
|
+
| ContentMetaCount
 +
|-
 +
| 0x14
 +
| 0x1
 +
| ContentMetaAttributes (0=None, 1=IncludesExFatDriver, 2=Rebootless, 4=Compacted)
 +
|-
 +
| 0x15
 +
| 0x3
 +
| Reserved
 +
|-
 +
| 0x18
 +
| 0x4
 +
| RequiredDownloadSystemVersion
 +
|-
 +
| 0x1C
 +
| 0x4
 +
| Reserved
 +
|}
 +
 
 +
= SystemUpdateMetaExtendedHeader =
 +
This is "nn::ncm::SystemUpdateMetaExtendedHeader".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x4
 +
| ExtendedDataSize
 +
|}
 +
 
 +
= ApplicationMetaExtendedHeader =
 +
This is "nn::ncm::ApplicationMetaExtendedHeader".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x8
 +
| PatchId
 +
|-
 +
| 0x8
 +
| 0x4
 +
| RequiredSystemVersion
 +
|-
 +
| 0xC
 +
| 0x4
 +
| RequiredApplicationVersion
 +
|}
 +
 
 +
= PatchMetaExtendedHeader =
 +
This is "nn::ncm::PatchMetaExtendedHeader".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x8
 +
| ApplicationId
 +
|-
 +
| 0x8
 +
| 0x4
 +
| RequiredSystemVersion
 +
|-
 +
| 0xC
 +
| 0x4
 +
| ExtendedDataSize
 +
|-
 +
| 0x10
 +
| 0x8
 +
| Reserved
 +
|}
 +
 
 +
= AddOnContentMetaExtendedHeader =
 +
This is "nn::ncm::AddOnContentMetaExtendedHeader".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x8
 +
| ApplicationId
 +
|-
 +
| 0x8
 +
| 0x4
 +
| RequiredApplicationVersion
 +
|-
 +
| 0xC
 +
| 0x1
 +
| [15.0.0+] ContentAccessibilities ([1.0.0-14.1.2] Reserved)
 +
|-
 +
| 0xD
 +
| 0x3
 +
| Reserved
 +
|-
 +
| 0x10
 +
| 0x8
 +
| [15.0.0+] DataPatchId
 +
|}
 +
 
 +
= DeltaMetaExtendedHeader =
 +
This is "nn::ncm::DeltaMetaExtendedHeader".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x8
 +
| ApplicationId
 +
|-
 +
| 0x8
 +
| 0x4
 +
| ExtendedDataSize
 +
|-
 +
| 0xC
 +
| 0x4
 +
| Reserved
 +
|}
 +
 
 +
= DataPatchMetaExtendedHeader =
 +
This is "nn::ncm::DataPatchMetaExtendedHeader".
 +
 
 +
This was added with [15.0.0+].
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x8
 +
| DataId
 +
|-
 +
| 0x8
 +
| 0x8
 +
| ApplicationId
 +
|-
 +
| 0x10
 +
| 0x4
 +
| RequiredApplicationVersion
 +
|-
 +
| 0x14
 +
| 0x4
 +
| ExtendedDataSize
 +
|-
 +
| 0x18
 +
| 0x8
 +
| Reserved
 +
|}
 +
 
 +
= PackagedContentInfo =
 +
This is "nn::ncm::PackagedContentInfo".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x20
 +
| Hash (SHA256 of the referenced content)
 +
|-
 +
| 0x20
 +
| 0x10
 +
| ContentId
 +
|-
 +
| 0x30
 +
| [15.0.0+] 0x5 ([1.0.0-14.1.2] 0x6)
 +
| Size
 +
|-
 +
| 0x35
 +
| 0x1
 +
| [15.0.0+] ContentAttributes
 +
|-
 +
| 0x36
 +
| 0x1
 +
| ContentType (0=Meta, 1=Program, 2=Data, 3=Control, 4=[[Internet_Browser|HtmlDocument]], 5=[[Internet_Browser|LegalInformation]], 6=[[NCA_Format|DeltaFragment]])
 +
|-
 +
| 0x37
 +
| 0x1
 +
| IdOffset
 +
|}
 +
 
 +
= ContentMetaInfo =
 +
This is "nn::ncm::ContentMetaInfo".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x8
 +
| Id
 +
|-
 +
| 0x8
 +
| 0x4
 +
| Version
 +
|-
 +
| 0xC
 +
| 0x1
 +
| [[NCM_services#ContentMetaType|ContentMetaType]]
 +
|-
 +
| 0xD
 +
| 0x1
 +
| ContentMetaAttributes (0=None, 1=IncludesExFatDriver, 2=Rebootless, 4=Compacted)
 +
|-
 +
| 0xE
 +
| 0x2
 +
| Reserved
 +
|}
 +
 
 +
This is used for SystemUpdate, see here: [[NCM_services#ReadEntryMetaRecords]].
 +
 
 +
= SystemUpdateMetaExtendedData =
 +
This is "nn::ncm::SystemUpdateMetaExtendedData".
 +
 
 +
If the Version field is 1, the format is:
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x4
 +
| Version
 +
|-
 +
| 0x4
 +
| 0x4
 +
| VariationCount
 +
|-
 +
| 0x8
 +
| 0x20 * VariationCount
 +
| [[#FirmwareVariationInfo|FirmwareVariationInfo]] (Version 1)
 
|}
 
|}
   −
An optional header can follow, depending on the title type.
+
If the Version field is 2, the format is:
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x4
 +
| Version
 +
|-
 +
| 0x4
 +
| 0x4
 +
| VariationCount
 +
|-
 +
| 0x8
 +
| 0x4 * VariationCount
 +
| FirmwareVariationId
 +
|-
 +
| Variable
 +
| 0x20 * VariationCount
 +
| [[#FirmwareVariationInfo|FirmwareVariationInfo]] (Version 2)
 +
|-
 +
| Variable
 +
| 0x10 * MetaCount (from [[#FirmwareVariationInfo|FirmwareVariationInfo]] (Version 2))
 +
| [[#ContentMetaInfo|ContentMetaInfo]] (if ReferToBase is False)
 +
|}
   −
At the end of the file following the entries is a 0x20-byte block, presumably a hash.
+
== FirmwareVariationInfo ==
 +
This is "FirmwareVariationInfo ".
   −
With update-format, there's additional data after the end of the entries specified in the header and before the ending hash.
+
If the Version field is 1, the format is:
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x4
 +
| FirmwareVariationId
 +
|-
 +
| 0x4
 +
| 0x1C
 +
| Reserved
 +
|}
   −
== Application header ==
+
If the Version field is 2, the format is:
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 53: Line 346:  
! Description
 
! Description
 
|-
 
|-
 +
| 0x0
 +
| 0x1
 +
| ReferToBase (0=False, 1=True)
 +
|-
 +
| 0x1
 +
| 0x3
 +
| Reserved
 +
|-
 +
| 0x4
 +
| 0x4
 +
| MetaCount
 +
|-
 +
| 0x8
 +
| 0x18
 +
| Reserved
 +
|}
 +
 +
= PatchMetaExtendedData =
 +
This is "nn::ncm::PatchMetaExtendedData".
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x4
 +
| PatchHistoryHeaderCount
 +
|-
 +
| 0x4
 +
| 0x4
 +
| PatchDeltaHistoryCount
 +
|-
 +
| 0x8
 +
| 0x4
 +
| PatchDeltaHeaderCount
 +
|-
 +
| 0xC
 +
| 0x4
 +
| FragmentSetCount
 +
|-
 +
| 0x10
 +
| 0x4
 +
| PatchHistoryContentInfoCount
 +
|-
 +
| 0x14
 +
| 0x4
 +
| PatchDeltaPackagedContentInfoCount
 +
|-
 +
| 0x18
 +
| 0x4
 +
| Reserved
 +
|-
 +
| 0x1C
 +
| 0x38 * PatchHistoryHeaderCount
 +
| [[#PatchHistoryHeader|PatchHistoryHeader]]
 +
|-
 +
| Variable
 +
| 0x28 * PatchDeltaHistoryCount
 +
| [[#PatchDeltaHistory|PatchDeltaHistory]]
 +
|-
 +
| Variable
 +
| 0x28 * PatchDeltaHeaderCount
 +
| [[#PatchDeltaHeader|PatchDeltaHeader]]
 +
|-
 +
| Variable
 +
| 0x34 * FragmentSetCount
 +
| [[#FragmentSet|FragmentSet]]
 +
|-
 +
| Variable
 +
| 0x18 * PatchHistoryContentInfoCount
 +
| [[#PackagedContentInfo|PatchHistoryContentInfo]] ([[#PackagedContentInfo|PackagedContentInfo]] without the Hash entry)
 +
|-
 +
| Variable
 +
| 0x38 * PatchDeltaPackagedContentInfoCount
 +
| [[#PackagedContentInfo|PatchDeltaPackagedContentInfo]]
 +
|-
 +
| Variable
 +
| 0x4 * FragmentIndicatorCount (from [[#FragmentSet|FragmentSet]])
 +
| [[#FragmentIndicator|FragmentIndicator]]
 +
|}
 +
 +
== PatchHistoryHeader ==
 +
This is "nn::ncm::PatchHistoryHeader".
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x10
 +
| ContentMetaKey
 +
|-
 +
| 0x10
 
| 0x20
 
| 0x20
| 8
+
| Digest
| Patch title ID
+
|-
 +
| 0x30
 +
| 0x2
 +
| ContentInfoCount
 
|-
 
|-
| 0x28
+
| 0x32
| 8
+
| 0x6
|
+
| Reserved
 
|}
 
|}
   −
== Patch header ==
+
== PatchDeltaHistory ==
 +
This is "nn::ncm::PatchDeltaHistory".
 +
 
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 68: Line 463:  
! Size
 
! Size
 
! Description
 
! Description
 +
|-
 +
| 0x0
 +
| 0x8
 +
| SourcePatchId
 +
|-
 +
| 0x8
 +
| 0x8
 +
| DestinationPatchId
 +
|-
 +
| 0x10
 +
| 0x4
 +
| SourceVersion
 +
|-
 +
| 0x14
 +
| 0x4
 +
| DestinationVersion
 +
|-
 +
| 0x18
 +
| 0x8
 +
| DownloadSize
 
|-
 
|-
 
| 0x20
 
| 0x20
 +
| 0x8
 +
| Reserved
 +
|}
 +
 +
== PatchDeltaHeader ==
 +
This is "nn::ncm::PatchDeltaHeader".
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x8
 +
| SourcePatchId
 +
|-
 +
| 0x8
 
| 8
 
| 8
| Original title ID
+
| DestinationPatchId
 +
|-
 +
| 0x10
 +
| 0x4
 +
| SourceVersion
 
|-
 
|-
| 0x28
+
| 0x14
| 8
+
| 0x4
|
+
| DestinationVersion
 +
|-
 +
| 0x18
 +
| 0x2
 +
| FragmentSetCount
 +
|-
 +
| 0x1A
 +
| 0x6
 +
| Reserved
 +
|-
 +
| 0x20
 +
| 0x2
 +
| ContentInfoCount
 +
|-
 +
| 0x22
 +
| 0x6
 +
| Reserved
 
|}
 
|}
   −
== Add-on content header ==
+
== FragmentSet ==
 +
This is "nn::ncm::FragmentSet".
 +
 
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 84: Line 539:  
! Size
 
! Size
 
! Description
 
! Description
 +
|-
 +
| 0x0
 +
| 0x10
 +
| SourceContentId
 +
|-
 +
| 0x10
 +
| 0x10
 +
| DestinationContentId
 
|-
 
|-
 
| 0x20
 
| 0x20
| 8
+
| 0x6
| Application title ID
+
| SourceSize
 +
|-
 +
| 0x26
 +
| 0x6
 +
| DestinationSize
 +
|-
 +
| 0x2C
 +
| 0x2
 +
| FragmentIndicatorCount
 +
|-
 +
| 0x2E
 +
| 0x1
 +
| FragmentTargetContentType (0=Meta, 1=Program, 2=Data, 3=Control, 4=[[Internet_Browser|HtmlDocument]], 5=[[Internet_Browser|LegalInformation]], 6=[[NCA_Format|DeltaFragment]])
 +
|-
 +
| 0x2F
 +
| 0x1
 +
| UpdateType (0=ApplyAsDelta, 1=Overwrite, 2=Create)
 
|-
 
|-
| 0x28
+
| 0x30
| 8
+
| 0x4
|
+
| Reserved
 
|}
 
|}
   −
== Content records ==
+
== FragmentIndicator ==
 +
This is "nn::ncm::FragmentIndicator".
   −
Each entry is 0x38 bytes:
+
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x2
 +
| ContentInfoIndex
 +
|-
 +
| 0x2
 +
| 0x2
 +
| FragmentIndex
 +
|}
 +
 
 +
= DeltaMetaExtendedData =
 +
This is "nn::ncm::DeltaMetaExtendedData".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 105: Line 601:  
|-
 
|-
 
| 0x0
 
| 0x0
| 32
+
| 0x8
| Hash
+
| SourcePatchId
 +
|-
 +
| 0x8
 +
| 0x8
 +
| DestinationPatchId
 +
|-
 +
| 0x10
 +
| 0x4
 +
| SourceVersion
 +
|-
 +
| 0x14
 +
| 0x4
 +
| DestinationVersion
 +
|-
 +
| 0x18
 +
| 0x2
 +
| FragmentSetCount
 +
|-
 +
| 0x1A
 +
| 0x6
 +
| Reserved
 
|-
 
|-
 
| 0x20
 
| 0x20
| 16
+
| 0x34 * FragmentSetCount
| NcaId [same as first 16-bytes of hash]
+
| [[#FragmentSet|FragmentSet]]
 
|-
 
|-
| 0x30
+
| Variable
| 6
+
| 0x4 * FragmentIndicatorCount (from [[#FragmentSet|FragmentSet]])
| Size, same as the output from [[Content_Manager_services#GetEntrySize]].
+
| [[#FragmentIndicator|FragmentIndicator]]
 +
|}
 +
 
 +
= Digest =
 +
{| class="wikitable" border="1"
 
|-
 
|-
| 0x36
+
! Offset
| 1
+
! Size
| Type (0=meta, 1=program, 2=data, 3=control, 4=offline-manual [[Internet_Browser|html]], 5=legal [[Internet_Browser|html]])
+
! Description
 
|-
 
|-
| 0x37
+
| 0x0
| 1
+
| 0x20
|
+
| Digest
 
|}
 
|}
 +
 +
This is a SHA-256 hash always found at the end of the file. The hash is calculated over the CNMT file's contents, but this is only done for the development version of the file which results in its production version counterpart sharing the same hash value.

Navigation menu