Difference between revisions of "CNMT"

From Nintendo Switch Brew
Jump to navigation Jump to search
(Fix new field name)
(38 intermediate revisions by 11 users not shown)
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>. This seems to replace the TMD format.
 
  
There's at least 3 different filenames used for ".cnmt":
+
= PackagedContentMetaHeader =
* "Application_{lower-case hex titleID}.cnmt"
+
This is "nn::ncm::PackagedContentMetaHeader".
* "Patch_{lower-case hex titleID}.cnmt"
 
* "SystemUpdate_{hex titleID}.cnmt"
 
  
It starts with a header:
 
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 17: 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
|
+
| 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
 
|}
 
|}
  
An optional header can follow, depending on the title type.
+
= DataPatchMetaExtendedHeader =
 +
This is "nn::ncm::DataPatchMetaExtendedHeader".
  
At the end of the file following the entries is a 0x20-byte block, presumably a hash.
+
This was added with [15.0.0+].  
  
With update-format, there's additional data after the end of the entries specified in the header and before the ending hash.
+
{| 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".
  
== Application header ==
 
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 58: Line 212:
 
! Description
 
! Description
 
|-
 
|-
 +
| 0x0
 
| 0x20
 
| 0x20
| 8
+
| Hash (SHA256 of the referenced content)
| Patch title ID
+
|-
 +
| 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#Title_Types|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)
 +
|}
 +
 
 +
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)
 +
|}
 +
 
 +
== FirmwareVariationInfo ==
 +
This is "FirmwareVariationInfo ".
 +
 
 +
If the Version field is 1, the format is:
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x4
 +
| FirmwareVariationId
 +
|-
 +
| 0x4
 +
| 0x1C
 +
| Reserved
 +
|}
 +
 
 +
If the Version field is 2, the format is:
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! 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]]
 
|-
 
|-
| 0x28
+
| Variable
| 8
+
| 0x4 * FragmentIndicatorCount (from [[#FragmentSet|FragmentSet]])
|
+
| [[#FragmentIndicator|FragmentIndicator]]
 
|}
 
|}
  
== Patch header ==
+
== PatchHistoryHeader ==
 +
This is "nn::ncm::PatchHistoryHeader".
 +
 
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 74: Line 438:
 
! Description
 
! Description
 
|-
 
|-
 +
| 0x0
 +
| 0x10
 +
| ContentMetaKey
 +
|-
 +
| 0x10
 
| 0x20
 
| 0x20
 +
| Digest
 +
|-
 +
| 0x30
 +
| 0x2
 +
| ContentInfoCount
 +
|-
 +
| 0x32
 +
| 0x6
 +
| Reserved
 +
|}
 +
 +
== PatchDeltaHistory ==
 +
This is "nn::ncm::PatchDeltaHistory".
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x8
 +
| SourcePatchId
 +
|-
 +
| 0x8
 +
| 0x8
 +
| DestinationPatchId
 +
|-
 +
| 0x10
 +
| 0x4
 +
| SourceVersion
 +
|-
 +
| 0x14
 +
| 0x4
 +
| DestinationVersion
 +
|-
 +
| 0x18
 +
| 0x8
 +
| DownloadSize
 +
|-
 +
| 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 89: 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 110: 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 =
 +
Always found at the end of the file.
 +
 
 +
{| 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
 
|}
 
|}

Revision as of 19:28, 18 October 2022

This is the metadata file that ends in ".cnmt{.nca}" or "meta0.ncd". This seems to replace the TMD format.

The official name for CNMT is "PackagedContentMeta".

PackagedContentMetaHeader

This is "nn::ncm::PackagedContentMetaHeader".

Offset Size Description
0x0 0x8 Id
0x8 0x4 Version
0xC 0x1 ContentMetaType
0xD 0x1 Reserved
0xE 0x2 ExtendedHeaderSize
0x10 0x2 ContentCount
0x12 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".

Offset Size Description
0x0 0x4 ExtendedDataSize

ApplicationMetaExtendedHeader

This is "nn::ncm::ApplicationMetaExtendedHeader".

Offset Size Description
0x0 0x8 PatchId
0x8 0x4 RequiredSystemVersion
0xC 0x4 RequiredApplicationVersion

PatchMetaExtendedHeader

This is "nn::ncm::PatchMetaExtendedHeader".

Offset Size Description
0x0 0x8 ApplicationId
0x8 0x4 RequiredSystemVersion
0xC 0x4 ExtendedDataSize
0x10 0x8 Reserved

AddOnContentMetaExtendedHeader

This is "nn::ncm::AddOnContentMetaExtendedHeader".

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

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+].

Offset Size Description
0x0 0x8 DataId
0x8 0x8 ApplicationId
0x10 0x4 RequiredApplicationVersion
0x14 0x4 ExtendedDataSize
0x18 0x8 Reserved

PackagedContentInfo

This is "nn::ncm::PackagedContentInfo".

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=HtmlDocument, 5=LegalInformation, 6=DeltaFragment)
0x37 0x1 IdOffset

ContentMetaInfo

This is "nn::ncm::ContentMetaInfo".

Offset Size Description
0x0 0x8 Id
0x8 0x4 Version
0xC 0x1 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:

Offset Size Description
0x0 0x4 Version
0x4 0x4 VariationCount
0x8 0x20 * VariationCount FirmwareVariationInfo (Version 1)

If the Version field is 2, the format is:

Offset Size Description
0x0 0x4 Version
0x4 0x4 VariationCount
0x8 0x4 * VariationCount FirmwareVariationId
Variable 0x20 * VariationCount FirmwareVariationInfo (Version 2)
Variable 0x10 * MetaCount (from FirmwareVariationInfo (Version 2)) ContentMetaInfo (if ReferToBase is False)

FirmwareVariationInfo

This is "FirmwareVariationInfo ".

If the Version field is 1, the format is:

Offset Size Description
0x0 0x4 FirmwareVariationId
0x4 0x1C Reserved

If the Version field is 2, the format is:

Offset Size Description
0x0 0x1 ReferToBase (0=False, 1=True)
0x1 0x3 Reserved
0x4 0x4 MetaCount
0x8 0x18 Reserved

PatchMetaExtendedData

This is "nn::ncm::PatchMetaExtendedData".

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
Variable 0x28 * PatchDeltaHistoryCount PatchDeltaHistory
Variable 0x28 * PatchDeltaHeaderCount PatchDeltaHeader
Variable 0x34 * FragmentSetCount FragmentSet
Variable 0x18 * PatchHistoryContentInfoCount PatchHistoryContentInfo (PackagedContentInfo without the Hash entry)
Variable 0x38 * PatchDeltaPackagedContentInfoCount PatchDeltaPackagedContentInfo
Variable 0x4 * FragmentIndicatorCount (from FragmentSet) FragmentIndicator

PatchHistoryHeader

This is "nn::ncm::PatchHistoryHeader".

Offset Size Description
0x0 0x10 ContentMetaKey
0x10 0x20 Digest
0x30 0x2 ContentInfoCount
0x32 0x6 Reserved

PatchDeltaHistory

This is "nn::ncm::PatchDeltaHistory".

Offset Size Description
0x0 0x8 SourcePatchId
0x8 0x8 DestinationPatchId
0x10 0x4 SourceVersion
0x14 0x4 DestinationVersion
0x18 0x8 DownloadSize
0x20 0x8 Reserved

PatchDeltaHeader

This is "nn::ncm::PatchDeltaHeader".

Offset Size Description
0x0 0x8 SourcePatchId
0x8 8 DestinationPatchId
0x10 0x4 SourceVersion
0x14 0x4 DestinationVersion
0x18 0x2 FragmentSetCount
0x1A 0x6 Reserved
0x20 0x2 ContentInfoCount
0x22 0x6 Reserved

FragmentSet

This is "nn::ncm::FragmentSet".

Offset Size Description
0x0 0x10 SourceContentId
0x10 0x10 DestinationContentId
0x20 0x6 SourceSize
0x26 0x6 DestinationSize
0x2C 0x2 FragmentIndicatorCount
0x2E 0x1 FragmentTargetContentType (0=Meta, 1=Program, 2=Data, 3=Control, 4=HtmlDocument, 5=LegalInformation, 6=DeltaFragment)
0x2F 0x1 UpdateType (0=ApplyAsDelta, 1=Overwrite, 2=Create)
0x30 0x4 Reserved

FragmentIndicator

This is "nn::ncm::FragmentIndicator".

Offset Size Description
0x0 0x2 ContentInfoIndex
0x2 0x2 FragmentIndex

DeltaMetaExtendedData

This is "nn::ncm::DeltaMetaExtendedData".

Offset Size Description
0x0 0x8 SourcePatchId
0x8 0x8 DestinationPatchId
0x10 0x4 SourceVersion
0x14 0x4 DestinationVersion
0x18 0x2 FragmentSetCount
0x1A 0x6 Reserved
0x20 0x34 * FragmentSetCount FragmentSet
Variable 0x4 * FragmentIndicatorCount (from FragmentSet) FragmentIndicator

Digest

Always found at the end of the file.

Offset Size Description
0x0 0x20 Digest