Drafts for RomFs support
This commit is contained in:
parent
24d0925dda
commit
33ef6c5bf8
15 changed files with 445 additions and 38 deletions
|
@ -28,6 +28,7 @@ import konogonka.Child.ChildWindow;
|
||||||
import konogonka.Controllers.NCA.NCAController;
|
import konogonka.Controllers.NCA.NCAController;
|
||||||
import konogonka.Controllers.NPDM.NPDMController;
|
import konogonka.Controllers.NPDM.NPDMController;
|
||||||
import konogonka.Controllers.NSP.NSPController;
|
import konogonka.Controllers.NSP.NSPController;
|
||||||
|
import konogonka.Controllers.RFS.RomFsController;
|
||||||
import konogonka.Controllers.TIK.TIKController;
|
import konogonka.Controllers.TIK.TIKController;
|
||||||
import konogonka.Controllers.XCI.XCIController;
|
import konogonka.Controllers.XCI.XCIController;
|
||||||
import konogonka.Controllers.XML.XMLController;
|
import konogonka.Controllers.XML.XMLController;
|
||||||
|
@ -71,6 +72,8 @@ public class MainController implements Initializable {
|
||||||
private XMLController XMLTabController;
|
private XMLController XMLTabController;
|
||||||
@FXML
|
@FXML
|
||||||
private NPDMController NPDMTabController;
|
private NPDMController NPDMTabController;
|
||||||
|
@FXML
|
||||||
|
private RomFsController RFSTabController;
|
||||||
|
|
||||||
private File selectedFile;
|
private File selectedFile;
|
||||||
|
|
||||||
|
@ -104,10 +107,23 @@ public class MainController implements Initializable {
|
||||||
else
|
else
|
||||||
fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
|
fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
|
||||||
|
|
||||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NS files", "*.nsp", "*.nsz", "*.xci", "*.nca", "*.tik", "*.xml", "*.npdm"));
|
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NS files",
|
||||||
|
"*.nsp", "*.nsz", "*.xci", "*.nca", "*.tik", "*.xml", "*.npdm", "*.romfs"));
|
||||||
|
|
||||||
this.selectedFile = fileChooser.showOpenDialog(analyzeBtn.getScene().getWindow());
|
this.selectedFile = fileChooser.showOpenDialog(analyzeBtn.getScene().getWindow());
|
||||||
// todo: fix
|
|
||||||
|
if (this.selectedFile != null && this.selectedFile.exists()) {
|
||||||
|
resetAllTabsContent();
|
||||||
|
filenameSelected.setText(this.selectedFile.getAbsolutePath());
|
||||||
|
previouslyOpenedPath = this.selectedFile.getParent();
|
||||||
|
analyzeBtn.setDisable(false);
|
||||||
|
String fileExtension = this.selectedFile.getName().toLowerCase().replaceAll("^.*\\.", "");
|
||||||
|
setFocusOnPane(fileExtension);
|
||||||
|
}
|
||||||
|
|
||||||
|
logArea.clear();
|
||||||
|
}
|
||||||
|
private void resetAllTabsContent(){
|
||||||
analyzeBtn.setDisable(true);
|
analyzeBtn.setDisable(true);
|
||||||
NSPTabController.resetTab();
|
NSPTabController.resetTab();
|
||||||
XCITabController.resetTab();
|
XCITabController.resetTab();
|
||||||
|
@ -115,36 +131,32 @@ public class MainController implements Initializable {
|
||||||
TIKTabController.resetTab();
|
TIKTabController.resetTab();
|
||||||
XMLTabController.resetTab();
|
XMLTabController.resetTab();
|
||||||
NPDMTabController.resetTab();
|
NPDMTabController.resetTab();
|
||||||
|
RFSTabController.resetTab();
|
||||||
if (this.selectedFile != null && this.selectedFile.exists()) {
|
}
|
||||||
filenameSelected.setText(this.selectedFile.getAbsolutePath());
|
private void setFocusOnPane(String fileExtension){
|
||||||
previouslyOpenedPath = this.selectedFile.getParent();
|
switch (fileExtension){
|
||||||
analyzeBtn.setDisable(false);
|
case "nsp":
|
||||||
String fileExtension = this.selectedFile.getName().toLowerCase().replaceAll("^.*\\.", "");
|
case "nsz":
|
||||||
switch (fileExtension){
|
tabPane.getSelectionModel().select(0);
|
||||||
case "nsp":
|
break;
|
||||||
case "nsz":
|
case "xci":
|
||||||
tabPane.getSelectionModel().select(0);
|
tabPane.getSelectionModel().select(1);
|
||||||
break;
|
break;
|
||||||
case "xci":
|
case "nca":
|
||||||
tabPane.getSelectionModel().select(1);
|
tabPane.getSelectionModel().select(2);
|
||||||
break;
|
break;
|
||||||
case "nca":
|
case "tic":
|
||||||
tabPane.getSelectionModel().select(2);
|
tabPane.getSelectionModel().select(3);
|
||||||
break;
|
break;
|
||||||
case "tic":
|
case "xml":
|
||||||
tabPane.getSelectionModel().select(3);
|
tabPane.getSelectionModel().select(4);
|
||||||
break;
|
break;
|
||||||
case "xml":
|
case "npdm":
|
||||||
tabPane.getSelectionModel().select(4);
|
tabPane.getSelectionModel().select(5);
|
||||||
break;
|
break;
|
||||||
case "npdm":
|
case "romfs":
|
||||||
tabPane.getSelectionModel().select(5);
|
tabPane.getSelectionModel().select(6);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logArea.clear();
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Start analyze
|
* Start analyze
|
||||||
|
@ -154,7 +166,7 @@ public class MainController implements Initializable {
|
||||||
switch (fileExtension){
|
switch (fileExtension){
|
||||||
case "nsp":
|
case "nsp":
|
||||||
case "nsz":
|
case "nsz":
|
||||||
NSPTabController.analyze(selectedFile); // TODO: NSP OR XCI
|
NSPTabController.analyze(selectedFile); // TODO: NSP OR NSZ ?
|
||||||
break;
|
break;
|
||||||
case "xci":
|
case "xci":
|
||||||
XCITabController.analyze(selectedFile);
|
XCITabController.analyze(selectedFile);
|
||||||
|
@ -171,6 +183,8 @@ public class MainController implements Initializable {
|
||||||
case "npdm":
|
case "npdm":
|
||||||
NPDMTabController.analyze(selectedFile);
|
NPDMTabController.analyze(selectedFile);
|
||||||
break;
|
break;
|
||||||
|
case "romfs":
|
||||||
|
RFSTabController.analyze(selectedFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@FXML
|
@FXML
|
||||||
|
|
36
src/main/java/konogonka/Controllers/RFS/RFSFolderEntry.java
Normal file
36
src/main/java/konogonka/Controllers/RFS/RFSFolderEntry.java
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019-2020 Dmitry Isaenko
|
||||||
|
|
||||||
|
This file is part of Konogonka.
|
||||||
|
|
||||||
|
Konogonka is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Konogonka is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Konogonka. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package konogonka.Controllers.RFS;
|
||||||
|
|
||||||
|
public class RFSFolderEntry {
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public RFSFolderEntry(String name){
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(){
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
81
src/main/java/konogonka/Controllers/RFS/RomFsController.java
Normal file
81
src/main/java/konogonka/Controllers/RFS/RomFsController.java
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019-2020 Dmitry Isaenko
|
||||||
|
|
||||||
|
This file is part of Konogonka.
|
||||||
|
|
||||||
|
Konogonka is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Konogonka is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Konogonka. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package konogonka.Controllers.RFS;
|
||||||
|
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.control.TreeItem;
|
||||||
|
import javafx.scene.control.TreeView;
|
||||||
|
import javafx.scene.layout.Region;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
import konogonka.Controllers.ITabController;
|
||||||
|
import konogonka.Tools.ISuperProvider;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
public class RomFsController implements ITabController {
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private TreeView<RFSFolderEntry> filesTreeView;
|
||||||
|
@FXML
|
||||||
|
private VBox folderContentVBox;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||||
|
TreeItem<RFSFolderEntry> rootTest = getEmptyRoot();
|
||||||
|
TreeItem<RFSFolderEntry> test = new TreeItem<>(new RFSFolderEntry("WIP"), getFolderImage());
|
||||||
|
|
||||||
|
rootTest.getChildren().add(test);
|
||||||
|
|
||||||
|
filesTreeView.setRoot(rootTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void analyze(File file) {
|
||||||
|
this.analyze(file, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void analyze(File file, long offset) {
|
||||||
|
TreeItem<RFSFolderEntry> rootItem = getEmptyRoot();
|
||||||
|
|
||||||
|
filesTreeView.setRoot(rootItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void analyze(ISuperProvider parentProvider, int fileNo) throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetTab() {
|
||||||
|
filesTreeView.setRoot(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Region getFolderImage(){
|
||||||
|
final Region folderImage = new Region();
|
||||||
|
folderImage.getStyleClass().add("regionFolder");
|
||||||
|
return folderImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TreeItem<RFSFolderEntry> getEmptyRoot(){
|
||||||
|
return new TreeItem<>(new RFSFolderEntry("/"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ import java.nio.charset.StandardCharsets;
|
||||||
/**
|
/**
|
||||||
* Debug tool like hexdump <3
|
* Debug tool like hexdump <3
|
||||||
*/
|
*/
|
||||||
public class RainbowHexDump {
|
public class RainbowDump {
|
||||||
private static final String ANSI_RESET = "\u001B[0m";
|
private static final String ANSI_RESET = "\u001B[0m";
|
||||||
private static final String ANSI_BLACK = "\u001B[30m";
|
private static final String ANSI_BLACK = "\u001B[30m";
|
||||||
private static final String ANSI_RED = "\u001B[31m";
|
private static final String ANSI_RED = "\u001B[31m";
|
||||||
|
@ -55,4 +55,8 @@ public class RainbowHexDump {
|
||||||
public static void octDumpLong(long value){
|
public static void octDumpLong(long value){
|
||||||
System.out.println(String.format("%64s", Long.toBinaryString( value )).replace(' ', '0')+" | "+value);
|
System.out.println(String.format("%64s", Long.toBinaryString( value )).replace(' ', '0')+" | "+value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String formatDecHexString(long value){
|
||||||
|
return String.format("%-20d 0x%x", value, value);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -313,7 +313,6 @@ public class NCAContent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private class CryptoSection03RomFS{
|
private class CryptoSection03RomFS{
|
||||||
|
|
||||||
CryptoSection03RomFS(File file,
|
CryptoSection03RomFS(File file,
|
||||||
long offsetPosition,
|
long offsetPosition,
|
||||||
byte[] decryptedKey,
|
byte[] decryptedKey,
|
||||||
|
|
|
@ -19,12 +19,9 @@
|
||||||
package konogonka.Tools.NPDM;
|
package konogonka.Tools.NPDM;
|
||||||
|
|
||||||
import konogonka.LoperConverter;
|
import konogonka.LoperConverter;
|
||||||
import konogonka.RainbowHexDump;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NOTE: This implementation is extremely bad for using application as library. Use raw for own purposes.
|
NOTE: This implementation is extremely bad for using application as library. Use raw for own purposes.
|
||||||
|
|
29
src/main/java/konogonka/Tools/RomFs/FileMeta.java
Normal file
29
src/main/java/konogonka/Tools/RomFs/FileMeta.java
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019-2020 Dmitry Isaenko
|
||||||
|
|
||||||
|
This file is part of Konogonka.
|
||||||
|
|
||||||
|
Konogonka is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Konogonka is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Konogonka. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package konogonka.Tools.RomFs;
|
||||||
|
|
||||||
|
public class FileMeta {
|
||||||
|
private int containingDirectoryOffset;
|
||||||
|
private int nextSiblingFileOffset;
|
||||||
|
private long fileDataOffset;
|
||||||
|
private long fileDataLength;
|
||||||
|
private int nextFileOffset;
|
||||||
|
private int fileNameLength;
|
||||||
|
private String fileName;
|
||||||
|
}
|
29
src/main/java/konogonka/Tools/RomFs/FolderMeta.java
Normal file
29
src/main/java/konogonka/Tools/RomFs/FolderMeta.java
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019-2020 Dmitry Isaenko
|
||||||
|
|
||||||
|
This file is part of Konogonka.
|
||||||
|
|
||||||
|
Konogonka is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Konogonka is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Konogonka. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package konogonka.Tools.RomFs;
|
||||||
|
|
||||||
|
public class FolderMeta {
|
||||||
|
private int parentDirectoryOffset;
|
||||||
|
private int nextSiblingDirectoryOffset;
|
||||||
|
private int firstSubdirectoryOffset;
|
||||||
|
private int firstFileOffset;
|
||||||
|
private int nextDirectoryOffset;
|
||||||
|
private int dirNameLength;
|
||||||
|
private String dirName;
|
||||||
|
}
|
84
src/main/java/konogonka/Tools/RomFs/Level6Header.java
Normal file
84
src/main/java/konogonka/Tools/RomFs/Level6Header.java
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Dmitry Isaenko
|
||||||
|
*
|
||||||
|
* This file is part of Konogonka.
|
||||||
|
*
|
||||||
|
* Konogonka is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Konogonka is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Konogonka. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package konogonka.Tools.RomFs;
|
||||||
|
|
||||||
|
import konogonka.LoperConverter;
|
||||||
|
import konogonka.RainbowDump;
|
||||||
|
|
||||||
|
public class Level6Header {
|
||||||
|
private long headerHeaderLength;
|
||||||
|
private long headerDirectoryHashTableOffset;
|
||||||
|
private long headerDirectoryHashTableLength;
|
||||||
|
private long headerDirectoryMetadataTableOffset;
|
||||||
|
private long headerDirectoryMetadataTableLength;
|
||||||
|
private long headerFileHashTableOffset;
|
||||||
|
private long headerFileHashTableLength;
|
||||||
|
private long headerFileMetadataTableOffset;
|
||||||
|
private long headerFileMetadataTableLength;
|
||||||
|
private long headerFileDataOffset;
|
||||||
|
|
||||||
|
Level6Header(byte[] headerBytes){
|
||||||
|
int i = 0;
|
||||||
|
headerHeaderLength = LoperConverter.getLEint(headerBytes, i);
|
||||||
|
i += 0x8;
|
||||||
|
headerDirectoryHashTableOffset = LoperConverter.getLEint(headerBytes, i);
|
||||||
|
i += 0x8;
|
||||||
|
headerDirectoryHashTableLength = LoperConverter.getLEint(headerBytes, i);
|
||||||
|
i += 0x8;
|
||||||
|
headerDirectoryMetadataTableOffset = LoperConverter.getLEint(headerBytes, i);
|
||||||
|
i += 0x8;
|
||||||
|
headerDirectoryMetadataTableLength = LoperConverter.getLEint(headerBytes, i);
|
||||||
|
i += 0x8;
|
||||||
|
headerFileHashTableOffset = LoperConverter.getLEint(headerBytes, i);
|
||||||
|
i += 0x8;
|
||||||
|
headerFileHashTableLength = LoperConverter.getLEint(headerBytes, i);
|
||||||
|
i += 0x8;
|
||||||
|
headerFileMetadataTableOffset = LoperConverter.getLEint(headerBytes, i);
|
||||||
|
i += 0x8;
|
||||||
|
headerFileMetadataTableLength = LoperConverter.getLEint(headerBytes, i);
|
||||||
|
i += 0x8;
|
||||||
|
headerFileDataOffset = LoperConverter.getLEint(headerBytes, i);
|
||||||
|
|
||||||
|
System.out.println("== Level 6 Header ==\n" +
|
||||||
|
"Header Length (always 0x50 ?) "+ RainbowDump.formatDecHexString(headerHeaderLength)+" (size of this structure within first 0x200 block of LEVEL 6 part)\n" +
|
||||||
|
"Directory Hash Table Offset "+ RainbowDump.formatDecHexString(headerDirectoryHashTableOffset)+" (against THIS block where HEADER contains)\n" +
|
||||||
|
"Directory Hash Table Length "+ RainbowDump.formatDecHexString(headerDirectoryHashTableLength) + "\n" +
|
||||||
|
"Directory Metadata Table Offset "+ RainbowDump.formatDecHexString(headerDirectoryMetadataTableOffset) + "\n" +
|
||||||
|
"Directory Metadata Table Length "+ RainbowDump.formatDecHexString(headerDirectoryMetadataTableLength) + "\n" +
|
||||||
|
"File Hash Table Offset "+ RainbowDump.formatDecHexString(headerFileHashTableOffset) + "\n" +
|
||||||
|
"File Hash Table Length "+ RainbowDump.formatDecHexString(headerFileHashTableLength) + "\n" +
|
||||||
|
"File Metadata Table Offset "+ RainbowDump.formatDecHexString(headerFileMetadataTableOffset) + "\n" +
|
||||||
|
"File Metadata Table Length "+ RainbowDump.formatDecHexString(headerFileMetadataTableLength) + "\n" +
|
||||||
|
"File Data Offset "+ RainbowDump.formatDecHexString(headerFileDataOffset) + "\n" +
|
||||||
|
"-------------------------------------------------------------"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getHeaderHeaderLength() { return headerHeaderLength; }
|
||||||
|
public long getHeaderDirectoryHashTableOffset() { return headerDirectoryHashTableOffset; }
|
||||||
|
public long getHeaderDirectoryHashTableLength() { return headerDirectoryHashTableLength; }
|
||||||
|
public long getHeaderDirectoryMetadataTableOffset() { return headerDirectoryMetadataTableOffset; }
|
||||||
|
public long getHeaderDirectoryMetadataTableLength() { return headerDirectoryMetadataTableLength; }
|
||||||
|
public long getHeaderFileHashTableOffset() { return headerFileHashTableOffset; }
|
||||||
|
public long getHeaderFileHashTableLength() { return headerFileHashTableLength; }
|
||||||
|
public long getHeaderFileMetadataTableOffset() { return headerFileMetadataTableOffset; }
|
||||||
|
public long getHeaderFileMetadataTableLength() { return headerFileMetadataTableLength; }
|
||||||
|
public long getHeaderFileDataOffset() { return headerFileDataOffset; }
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Dmitry Isaenko
|
||||||
|
*
|
||||||
|
* This file is part of Konogonka.
|
||||||
|
*
|
||||||
|
* Konogonka is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Konogonka is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Konogonka. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package konogonka.Tools.RomFs;
|
||||||
|
|
||||||
|
import konogonka.Tools.ISuperProvider;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.PipedInputStream;
|
||||||
|
|
||||||
|
public class RomFsDecryptedProvider implements ISuperProvider {
|
||||||
|
|
||||||
|
private static final long LEVEL_6_DEFAULT_OFFSET = 0x14000;
|
||||||
|
|
||||||
|
private File decryptedFSImage;
|
||||||
|
private Level6Header header;
|
||||||
|
|
||||||
|
public RomFsDecryptedProvider(File decryptedFSImage) throws Exception{ // TODO: add default setup AND using meta-data headers from NCA RomFs section (?)
|
||||||
|
this.decryptedFSImage = decryptedFSImage;
|
||||||
|
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(decryptedFSImage));
|
||||||
|
|
||||||
|
skipTo(bis, LEVEL_6_DEFAULT_OFFSET);
|
||||||
|
|
||||||
|
byte[] rawDataChunk = new byte[0x50];
|
||||||
|
|
||||||
|
if (bis.read(rawDataChunk) != 0x50)
|
||||||
|
throw new Exception("Failed to read header (0x50)");
|
||||||
|
|
||||||
|
this.header = new Level6Header(rawDataChunk);
|
||||||
|
|
||||||
|
bis.close();
|
||||||
|
}
|
||||||
|
private void skipTo(BufferedInputStream bis, long size) throws Exception{
|
||||||
|
long mustSkip = size;
|
||||||
|
long skipped = 0;
|
||||||
|
while (mustSkip > 0){
|
||||||
|
skipped += bis.skip(mustSkip);
|
||||||
|
mustSkip = size - skipped;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private int getRealNameSize(int value){
|
||||||
|
if (value % 4 == 0)
|
||||||
|
return value;
|
||||||
|
return value + 4 - value % 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Level6Header getHeader() { return header; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PipedInputStream getProviderSubFilePipedInpStream(String subFileName) throws Exception {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PipedInputStream getProviderSubFilePipedInpStream(int subFileNumber) throws Exception {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getFile() {
|
||||||
|
return decryptedFSImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getRawFileDataStart() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package konogonka.Tools.XCI;
|
package konogonka.Tools.XCI;
|
||||||
|
|
||||||
import konogonka.RainbowHexDump;
|
|
||||||
import konogonka.Tools.ISuperProvider;
|
import konogonka.Tools.ISuperProvider;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
<?import javafx.scene.control.Button?>
|
<?import javafx.scene.control.Button?>
|
||||||
<?import javafx.scene.control.Label?>
|
<?import javafx.scene.control.Label?>
|
||||||
<?import javafx.scene.control.Separator?>
|
<?import javafx.scene.control.Separator?>
|
||||||
|
<?import javafx.scene.control.SplitPane?>
|
||||||
|
<?import javafx.scene.control.TableView?>
|
||||||
<?import javafx.scene.control.TitledPane?>
|
<?import javafx.scene.control.TitledPane?>
|
||||||
|
<?import javafx.scene.control.TreeView?>
|
||||||
<?import javafx.scene.layout.BorderPane?>
|
<?import javafx.scene.layout.BorderPane?>
|
||||||
<?import javafx.scene.layout.HBox?>
|
<?import javafx.scene.layout.HBox?>
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
@ -61,5 +64,20 @@
|
||||||
<fx:include fx:id="SectionPFS0" source="../NSP/NSPTab.fxml" />
|
<fx:include fx:id="SectionPFS0" source="../NSP/NSPTab.fxml" />
|
||||||
</VBox>
|
</VBox>
|
||||||
</content></TitledPane>
|
</content></TitledPane>
|
||||||
|
<TitledPane prefHeight="200.0" prefWidth="200.0" text="'RomFS'">
|
||||||
|
<content>
|
||||||
|
<VBox spacing="5.0">
|
||||||
|
<children>
|
||||||
|
<Label text="WIP" />
|
||||||
|
<SplitPane dividerPositions="0.5" prefHeight="160.0" prefWidth="200.0">
|
||||||
|
<items>
|
||||||
|
<TreeView prefHeight="200.0" prefWidth="200.0" />
|
||||||
|
<TableView prefHeight="200.0" prefWidth="200.0" />
|
||||||
|
</items>
|
||||||
|
</SplitPane>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
</content>
|
||||||
|
</TitledPane>
|
||||||
</children>
|
</children>
|
||||||
</VBox>
|
</VBox>
|
||||||
|
|
15
src/main/resources/FXML/RomFS/RFSTab.fxml
Normal file
15
src/main/resources/FXML/RomFS/RFSTab.fxml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.scene.control.SplitPane?>
|
||||||
|
<?import javafx.scene.control.TreeView?>
|
||||||
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
|
||||||
|
<SplitPane dividerPositions="0.2" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="konogonka.Controllers.RFS.RomFsController">
|
||||||
|
<items>
|
||||||
|
<TreeView fx:id="filesTreeView" />
|
||||||
|
<VBox fx:id="folderContentVBox">
|
||||||
|
|
||||||
|
</VBox>
|
||||||
|
</items>
|
||||||
|
|
||||||
|
</SplitPane>
|
|
@ -95,6 +95,14 @@
|
||||||
<Label text="NPDM" />
|
<Label text="NPDM" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Tab>
|
</Tab>
|
||||||
|
<Tab styleClass="tab-sub">
|
||||||
|
<content>
|
||||||
|
<fx:include fx:id="RFSTab" source="RomFS/RFSTab.fxml" />
|
||||||
|
</content>
|
||||||
|
<graphic>
|
||||||
|
<Label text="RomFS" />
|
||||||
|
</graphic>
|
||||||
|
</Tab>
|
||||||
</tabs>
|
</tabs>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
<AnchorPane fx:id="logPane" prefHeight="200.0" prefWidth="200.0">
|
<AnchorPane fx:id="logPane" prefHeight="200.0" prefWidth="200.0">
|
||||||
|
|
|
@ -426,4 +426,11 @@
|
||||||
.titled-pane:focused > .title > .arrow-button .arrow
|
.titled-pane:focused > .title > .arrow-button .arrow
|
||||||
{
|
{
|
||||||
-fx-background-color: white, white;
|
-fx-background-color: white, white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.regionFolder {
|
||||||
|
-fx-shape: "M10,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V8C22,6.89 21.1,6 20,6H12L10,4Z";
|
||||||
|
-fx-background-color: #ffbf00;
|
||||||
|
-fx-min-height: 17.0;
|
||||||
|
-fx-min-width: 17.5;
|
||||||
}
|
}
|
Loading…
Reference in a new issue