mirror of
https://github.com/Maschell/JNUSTool.git
synced 2024-06-02 15:38:47 +02:00
153 lines
4.5 KiB
Java
153 lines
4.5 KiB
Java
import java.io.File;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.RandomAccessFile;
|
|
|
|
public class TitleMetaData {
|
|
int signatureType; // 0x000
|
|
byte[] signature = new byte[0x100]; // 0x004
|
|
byte[] issuer = new byte[0x40]; // 0x140
|
|
byte version; // 0x180
|
|
byte CACRLVersion; // 0x181
|
|
byte signerCRLVersion; // 0x182
|
|
long systemVersion; // 0x184
|
|
long titleID; // 0x18C
|
|
int titleType; // 0x194
|
|
short groupID; // 0x198
|
|
byte[] reserved = new byte[62]; // 0x19A
|
|
int accessRights; // 0x1D8
|
|
short titleVersion; // 0x1DC
|
|
short contentCount; // 0x1DE
|
|
short bootIndex; // 0x1E0
|
|
byte[] SHA2 = new byte[32]; // 0x1E4
|
|
ContentInfo[] contentInfos = new ContentInfo[64]; // 0x1E4
|
|
Content[] contents; // 0x1E4
|
|
|
|
|
|
private long totalContentSize;
|
|
|
|
public TitleMetaData(File tmd) throws IOException {
|
|
parse(tmd);
|
|
setTotalContentSize();
|
|
}
|
|
|
|
public TitleMetaData(byte[] downloadTMDToByteArray) throws IOException {
|
|
if(downloadTMDToByteArray != null){
|
|
File tempFile = File.createTempFile("bla","blubb");
|
|
FileOutputStream fos = new FileOutputStream(tempFile);
|
|
fos.write(downloadTMDToByteArray);
|
|
fos.close();
|
|
parse(tempFile);
|
|
setTotalContentSize();
|
|
}else{
|
|
System.err.println("Invalid TMD");
|
|
throw new IllegalArgumentException("Invalid TMD");
|
|
}
|
|
}
|
|
|
|
private void parse(File tmd) throws IOException {
|
|
RandomAccessFile f = new RandomAccessFile(tmd, "r");
|
|
f.seek(0);
|
|
this.signatureType = f.readInt();
|
|
|
|
f.read(signature, 0, 0x100);
|
|
f.seek(0x140);
|
|
f.read(issuer, 0, 0x40);
|
|
|
|
f.seek(0x180);
|
|
this.version = f.readByte();
|
|
this.CACRLVersion = f.readByte();
|
|
this.signerCRLVersion = f.readByte();
|
|
f.seek(0x184);
|
|
this.systemVersion = f.readLong();
|
|
this.titleID = f.readLong();
|
|
this.titleType = f.readInt();
|
|
this.groupID = f.readShort();
|
|
f.seek(0x19A);
|
|
f.read(reserved, 0, 62);
|
|
f.seek(0x1D8);
|
|
this.accessRights = f.readInt();
|
|
this.titleVersion = f.readShort();
|
|
this.contentCount = f.readShort();
|
|
this.bootIndex = f.readShort();
|
|
f.seek(0x1E4);
|
|
f.read(SHA2, 0, 32);
|
|
f.seek(0x204);
|
|
|
|
short indexOffset;
|
|
short commandCount;
|
|
|
|
for(int i =0;i<64;i++){
|
|
f.seek(0x204+(0x24*i));
|
|
indexOffset =f.readShort();
|
|
commandCount =f.readShort();
|
|
byte[] buffer = new byte[0x20]; // 16 0xB14
|
|
f.read(buffer, 0, 0x20);
|
|
this.contentInfos[i] = new ContentInfo(indexOffset,commandCount,buffer);
|
|
}
|
|
this.contents = new Content[contentCount];
|
|
|
|
int ID; // 0 0xB04
|
|
short index; // 4 0xB08
|
|
short type; // 6 0xB0A
|
|
long size; // 8 0xB0C
|
|
|
|
|
|
for(int i =0;i<contentCount;i++){
|
|
f.seek(0xB04+(0x30*i));
|
|
ID = f.readInt();
|
|
index = f.readShort();
|
|
type = f.readShort();
|
|
size = f.readLong();
|
|
byte[] buffer = new byte[0x20]; // 16 0xB14
|
|
f.read(buffer,0, 0x20);
|
|
|
|
|
|
this.contents[i] = new Content(ID,index,type,size,buffer);
|
|
}
|
|
f.close();
|
|
}
|
|
|
|
@Override
|
|
public String toString(){
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append("signatureType: " + signatureType +"\n");
|
|
sb.append("signature: " + Util.ByteArrayToString(signature) +"\n");
|
|
sb.append("issuer: " + Util.ByteArrayToString(issuer) +"\n");
|
|
sb.append("version: " + version +"\n");
|
|
sb.append("CACRLVersion: " + CACRLVersion +"\n");
|
|
sb.append("signerCRLVersion: " + signerCRLVersion +"\n");
|
|
sb.append("systemVersion: " + String.format("%8X",systemVersion) +"\n");
|
|
sb.append("titleID: " + String.format("%8X",titleID) +"\n");
|
|
sb.append("titleType: " + titleType +"\n");
|
|
sb.append("groupID: " + groupID +"\n");
|
|
sb.append("reserved: " + Util.ByteArrayToString(reserved) +"\n");
|
|
sb.append("accessRights: " + accessRights +"\n");
|
|
sb.append("titleVersion: " + titleVersion +"\n");
|
|
sb.append("contentCount: " + contentCount +"\n");
|
|
sb.append("bootIndex: " + bootIndex +"\n");
|
|
sb.append("SHA2: " + Util.ByteArrayToString(SHA2) +"\n");
|
|
sb.append("contentInfos: \n");
|
|
for(int i = 0; i<contents.length-1;i++){
|
|
sb.append(" " + contentInfos[i] +"\n");
|
|
}
|
|
sb.append("contents: \n");
|
|
for(int i = 0; i<contents.length-1;i++){
|
|
sb.append(" " + contents[i] +"\n");
|
|
}
|
|
return sb.toString();
|
|
}
|
|
public void setTotalContentSize(){
|
|
this.totalContentSize = 0;
|
|
for(int i = 0; i <contents.length-1;i++){
|
|
this.totalContentSize += contents[i].size;
|
|
}
|
|
}
|
|
|
|
public long getTotalContentSize() {
|
|
return totalContentSize;
|
|
}
|
|
|
|
|
|
}
|