-
Notifications
You must be signed in to change notification settings - Fork 1
/
nsp.go
102 lines (91 loc) · 3.28 KB
/
nsp.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package formats
import (
"bytes"
"fmt"
"io"
"strings"
cnmt "github.com/ralim/switchhost/formats/CNMT"
nacp "github.com/ralim/switchhost/formats/NACP"
nca "github.com/ralim/switchhost/formats/NCA"
partitionfs "github.com/ralim/switchhost/formats/partitionFS"
"github.com/ralim/switchhost/keystore"
"github.com/ralim/switchhost/settings"
"github.com/rs/zerolog/log"
)
//Implements the minimum to parse the details we care about out of an NSP file
func ParseNSPToMetaData(keystore *keystore.Keystore, settings *settings.Settings, reader io.ReaderAt) (FileInfo, error) {
info := FileInfo{}
pfs0Header, err := partitionfs.ReadSection(reader, 0)
if err != nil {
return info, fmt.Errorf("reading NSP PartionFS failed with - %w", err)
}
for _, pfs0File := range pfs0Header.FileEntryTable {
if strings.HasSuffix(pfs0File.Name, "cnmt.nca") {
NCAMetaHeader, err := nca.ParseNCAEncryptedHeader(keystore, reader, pfs0File.StartOffset)
if err != nil {
return info, fmt.Errorf("ParseNCAEncryptedHeader failed with - %w", err)
}
section, err := nca.DecryptMetaNCADataSection(keystore, reader, NCAMetaHeader, pfs0File.StartOffset)
if err != nil {
return info, fmt.Errorf("DecryptMetaNCADataSection failed with - %w", err)
}
currpfs0, err := partitionfs.ReadSection(bytes.NewReader(section), 0x0)
if err != nil {
return info, fmt.Errorf("ReadSection failed with - %w", err)
}
currCnmt, err := cnmt.ParseBinary(currpfs0, section)
if err != nil {
return info, fmt.Errorf("ParseBinary failed with - %w", err)
}
if currCnmt.Type != cnmt.DLC {
nacp, err := nacp.ExtractNACP(keystore, currCnmt, reader, pfs0Header, 0)
if err != nil {
log.Warn().Int("type", int(currCnmt.Type)).Err(err).Msg("Failed to extract NACP info from file")
} else {
// currCnmt.Ncap = nacp
info.EmbeddedTitle = nacp.GetSuggestedTitle(settings)
}
}
//Update the info
info.TitleID = currCnmt.TitleId
info.Version = currCnmt.Version
info.Type = currCnmt.Type
}
}
return info, nil
}
func ValidateNSPHash(keystore *keystore.Keystore, settings *settings.Settings, reader ReaderRequired) error {
pfs0Header, err := partitionfs.ReadSection(reader, 0)
if err != nil {
return fmt.Errorf("reading NSP PartionFS failed with - %w", err)
}
var fileCNMT *cnmt.ContentMetaAttributes
fileCNMT = nil
for _, pfs0File := range pfs0Header.FileEntryTable {
if strings.HasSuffix(pfs0File.Name, "cnmt.nca") {
NCAMetaHeader, err := nca.ParseNCAEncryptedHeader(keystore, reader, pfs0File.StartOffset)
if err != nil {
return fmt.Errorf("ParseNCAEncryptedHeader failed with - %w", err)
}
section, err := nca.DecryptMetaNCADataSection(keystore, reader, NCAMetaHeader, pfs0File.StartOffset)
if err != nil {
return fmt.Errorf("DecryptMetaNCADataSection failed with - %w", err)
}
currpfs0, err := partitionfs.ReadSection(bytes.NewReader(section), 0x0)
if err != nil {
return fmt.Errorf("ReadSection failed with - %w", err)
}
currCnmt, err := cnmt.ParseBinary(currpfs0, section)
if err != nil {
return fmt.Errorf("ParseBinary failed with - %w", err)
}
fileCNMT = currCnmt
}
}
for _, pfs0File := range pfs0Header.FileEntryTable {
if err := validatePFS0File(pfs0File, reader, fileCNMT, 0); err != nil {
return err
}
}
return nil
}