konogonka/src/main/java/konogonka/Tools/XCI/XCIProvider.java

100 lines
4.4 KiB
Java

package konogonka.Tools.XCI;
import java.io.*;
import java.nio.charset.StandardCharsets;
public class XCIProvider{
// TODO: Since LOGO partition added, we have to handle it properly. Is it works??
//private BufferedInputStream xciBIS;
private XCIGamecardHeader xciGamecardHeader;
private XCIGamecardInfo xciGamecardInfo;
private XCIGamecardCert xciGamecardCert;
private HFS0Provider hfs0ProviderMain,
hfs0ProviderUpdate,
hfs0ProviderNormal,
hfs0ProviderSecure,
hfs0ProviderLogo;
public XCIProvider(File file, String XCI_HEADER_KEY) throws Exception{ // TODO: ADD FILE SIZE CHECK !!! Check xciHdrKey
RandomAccessFile raf;
try {
//xciBIS = new BufferedInputStream(new FileInputStream(file));
raf = new RandomAccessFile(file, "r");
}
catch (FileNotFoundException fnfe){
throw new Exception("XCI File not found: \n "+fnfe.getMessage());
}
if (file.length() < 0xf010)
throw new Exception("XCI File is too small.");
try{
byte[] gamecardHeaderBytes = new byte[400];
byte[] gamecardInfoBytes = new byte[112];
byte[] gamecardCertBytes = new byte[512];
// Creating GC Header class
if (raf.read(gamecardHeaderBytes) != 400) {
raf.close();
throw new Exception("XCI Can't read Gamecard Header bytes.");
}
xciGamecardHeader = new XCIGamecardHeader(gamecardHeaderBytes); // throws exception
// Creating GC Info class
if (raf.read(gamecardInfoBytes) != 112) {
raf.close();
throw new Exception("XCI Can't read Gamecard Header bytes.");
}
xciGamecardInfo = new XCIGamecardInfo(gamecardInfoBytes, xciGamecardHeader.getGcInfoIV(), XCI_HEADER_KEY);
// Creating GC Cerfificate class
raf.seek(0x7000);
if (raf.read(gamecardCertBytes) != 512) {
raf.close();
throw new Exception("XCI Can't read Gamecard certificate bytes.");
}
xciGamecardCert = new XCIGamecardCert(gamecardCertBytes);
hfs0ProviderMain = new HFS0Provider(0xf000, raf);
if (hfs0ProviderMain.getFilesCnt() < 3){
raf.close();
throw new Exception("XCI Can't read Gamecard certificate bytes.");
}
// Get all partitions from the main HFS0 file
String partition;
for (HFS0File hfs0File: hfs0ProviderMain.getHfs0Files()){
partition = hfs0File.getName();
if (partition.equals("update")) {
hfs0ProviderUpdate = new HFS0Provider(hfs0ProviderMain.getRawFileDataStart() + hfs0File.getOffset(), raf);
continue;
}
if (partition.equals("normal")) {
hfs0ProviderNormal = new HFS0Provider(hfs0ProviderMain.getRawFileDataStart() + hfs0File.getOffset(), raf);
continue;
}
if (partition.equals("secure")) {
hfs0ProviderSecure = new HFS0Provider(hfs0ProviderMain.getRawFileDataStart() + hfs0File.getOffset(), raf);
continue;
}
if (partition.equals("logo")) {
hfs0ProviderLogo = new HFS0Provider(hfs0ProviderMain.getRawFileDataStart() + hfs0File.getOffset(), raf);
}
}
raf.close();
}
catch (IOException ioe){
throw new Exception("XCI Failed file analyze for ["+file.getName()+"]\n "+ioe.getMessage());
}
}
/**
* Getters
* */
public XCIGamecardHeader getGCHeader(){ return this.xciGamecardHeader; }
public XCIGamecardInfo getGCInfo(){ return this.xciGamecardInfo; }
public XCIGamecardCert getGCCert(){ return this.xciGamecardCert; }
public HFS0Provider getHfs0ProviderMain() { return this.hfs0ProviderMain; }
public HFS0Provider getHfs0ProviderUpdate() { return this.hfs0ProviderUpdate; }
public HFS0Provider getHfs0ProviderNormal() { return this.hfs0ProviderNormal; }
public HFS0Provider getHfs0ProviderSecure() { return this.hfs0ProviderSecure; }
public HFS0Provider getHfs0ProviderLogo() { return this.hfs0ProviderLogo; }
}