parent
ee478dfc9f
commit
5408d66a9e
7 changed files with 1274 additions and 139 deletions
14
README.md
14
README.md
|
@ -47,12 +47,16 @@ JRE/JDK 8u60 or higher.
|
|||
| GoldLeaf version | NS-USBloader version |
|
||||
| ---------------- | -------------------- |
|
||||
| v0.5 | v0.4 - v0.5.2, v0.8+ |
|
||||
| v0.6 | none |
|
||||
| v0.6.1 | v0.6 |
|
||||
| v0.7 - 0.7.3 | v0.7 - v0.8+ |
|
||||
| v0.7 - 0.7.3 | v0.7+ |
|
||||
| v0.8 | v1.0+ |
|
||||
|
||||
### Awoo support
|
||||
where '+' means 'any next NS-USBloader version'.
|
||||
|
||||
Awoo-installer uses the same command-set (or 'protocol') to TinFoil. So just select 'TinFoil' in case you're going to use Awoo.
|
||||
### Awoo Installer support
|
||||
|
||||
Awoo Installer uses the same command-set (or 'protocol') to TinFoil. So just select 'TinFoil' in case you're going to use Awoo.
|
||||
|
||||
Also, please go to 'Settings' tab of NS-USBloader after first installation and check 'Allow XCI / NSZ / XCZ files selection for TinFoil' option. This installer can install not only NSPs but a way more formats!
|
||||
|
||||
|
@ -63,13 +67,15 @@ Also, please go to 'Settings' tab of NS-USBloader after first installation and c
|
|||
|
||||
2. `root # java -jar /path/to/NS-USBloader.jar`
|
||||
|
||||
3. Optional. Add user to 'udev' rules to use NS not-from-root-account
|
||||
3. Optional: add user to 'udev' rules to use NS not-from-root-account
|
||||
```
|
||||
root # vim /etc/udev/rules.d/99-NS.rules
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="3000", GROUP="plugdev"
|
||||
root # udevadm control --reload-rules && udevadm trigger
|
||||
```
|
||||
|
||||
Please note: you may have to change 'plugdev' group from example above to the different one. It's depends on you linux distro.
|
||||
|
||||
##### macOS
|
||||
|
||||
Double-click on downloaded .jar file. Follow instructions. Or see 'Linux' section.
|
||||
|
|
6
pom.xml
6
pom.xml
|
@ -8,7 +8,7 @@
|
|||
<name>NS-USBloader</name>
|
||||
|
||||
<artifactId>ns-usbloader</artifactId>
|
||||
<version>0.9.1-SNAPSHOT</version>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
|
||||
<url>https://github.com/developersu/ns-usbloader/</url>
|
||||
<description>
|
||||
|
@ -218,11 +218,11 @@
|
|||
<minVersion>1.8</minVersion>
|
||||
</jre>
|
||||
<versionInfo>
|
||||
<fileVersion>0.8.0.0</fileVersion>
|
||||
<fileVersion>1.0.0.0</fileVersion>
|
||||
<txtFileVersion>${project.version}</txtFileVersion>
|
||||
<fileDescription>TinFoil and GoldLeaf installer for your NS</fileDescription>
|
||||
<copyright>GNU General Public License v3, 2019 ${organization.name}. Russia/LPR.</copyright>
|
||||
<productVersion>0.8.0.0</productVersion>
|
||||
<productVersion>1.0.0.0</productVersion>
|
||||
<txtProductVersion>${project.version}</txtProductVersion>
|
||||
<companyName>${organization.name}</companyName>
|
||||
<productName>${project.name}</productName>
|
||||
|
|
|
@ -19,14 +19,14 @@ import java.util.*;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* GoldLeaf 0.7 - 0.7.3 processing
|
||||
* GoldLeaf 0.8 processing
|
||||
*/
|
||||
class GoldLeaf extends TransferModule {
|
||||
private boolean nspFilterForGl;
|
||||
|
||||
// CMD
|
||||
private final byte[] CMD_GLCO_SUCCESS = new byte[]{0x47, 0x4c, 0x43, 0x4F, 0x00, 0x00, 0x00, 0x00}; // used @ writeToUsb_GLCMD
|
||||
private final byte[] CMD_GLCO_FAILURE = new byte[]{0x47, 0x4c, 0x43, 0x4F, 0x64, (byte) 0xcb, 0x00, 0x00}; // used @ writeToUsb_GLCMD
|
||||
private final byte[] CMD_GLCO_FAILURE = new byte[]{0x47, 0x4c, 0x43, 0x4F, 0x00, 0x00, (byte) 0xAD, (byte) 0xDE}; // used @ writeToUsb_GLCMD TODO: TEST
|
||||
|
||||
// System.out.println((356 & 0x1FF) | ((1 + 100) & 0x1FFF) << 9); // 52068 // 0x00 0x00 0xCB 0x64
|
||||
private final byte[] GL_OBJ_TYPE_FILE = new byte[]{0x01, 0x00, 0x00, 0x00};
|
||||
|
@ -54,28 +54,31 @@ class GoldLeaf extends TransferModule {
|
|||
GoldLeaf(DeviceHandle handler, LinkedHashMap<String, File> nspMap, Task<Void> task, LogPrinter logPrinter, boolean nspFilter){
|
||||
super(handler, nspMap, task, logPrinter);
|
||||
|
||||
final byte CMD_GetDriveCount = 0x00;
|
||||
final byte CMD_GetDriveInfo = 0x01;
|
||||
final byte CMD_StatPath = 0x02; // proxy done [proxy: in case if folder contains ENG+RUS+UKR file names works incorrect]
|
||||
final byte CMD_GetFileCount = 0x03;
|
||||
final byte CMD_GetFile = 0x04; // proxy done
|
||||
final byte CMD_GetDirectoryCount = 0x05;
|
||||
final byte CMD_GetDirectory = 0x06; // proxy done
|
||||
final byte CMD_ReadFile = 0x07; // no way to do poxy
|
||||
final byte CMD_WriteFile = 0x08; // add predictable behavior
|
||||
final byte CMD_Create = 0x09;
|
||||
final byte CMD_Delete = 0x0a;//10
|
||||
final byte CMD_Rename = 0x0b;//11
|
||||
final byte CMD_GetSpecialPathCount = 0x0c;//12 // Special folders count; simplified usage @ NS-UL
|
||||
final byte CMD_GetSpecialPath = 0x0d;//13 // Information about special folders; simplified usage @ NS-UL
|
||||
final byte CMD_SelectFile = 0x0e;//14
|
||||
//final byte CMD_Max = 0x0f;//15 // not used @ NS-UL & GT
|
||||
final byte CMD_GetDriveCount = 1;
|
||||
final byte CMD_GetDriveInfo = 2;
|
||||
final byte CMD_StatPath = 3;
|
||||
final byte CMD_GetFileCount = 4;
|
||||
final byte CMD_GetFile = 5;
|
||||
final byte CMD_GetDirectoryCount = 6;
|
||||
final byte CMD_GetDirectory = 7;
|
||||
final byte CMD_StartFile = 8; // 1 -open read RAF; 2 open write RAF; 3 open write RAF and seek to EOF (???).
|
||||
final byte CMD_ReadFile = 9;
|
||||
final byte CMD_WriteFile = 10;
|
||||
final byte CMD_EndFile = 11; // 1 - closed read RAF; 2 close write RAF.
|
||||
final byte CMD_Create = 12;
|
||||
final byte CMD_Delete = 13;
|
||||
final byte CMD_Rename = 14;
|
||||
final byte CMD_GetSpecialPathCount = 15;
|
||||
final byte CMD_GetSpecialPath = 16;
|
||||
final byte CMD_SelectFile = 17;
|
||||
|
||||
final byte[] CMD_GLCI = new byte[]{0x47, 0x4c, 0x43, 0x49};
|
||||
|
||||
this.nspFilterForGl = nspFilter;
|
||||
|
||||
logPrinter.print("============= GoldLeaf =============\n\tVIRT:/ equals files added into the application\n\tHOME:/ equals "
|
||||
logPrinter.print("============= GoldLeaf v0.8 =============\n\t" +
|
||||
"VIRT:/ equals files added into the application\n\t" +
|
||||
"HOME:/ equals "
|
||||
+System.getProperty("user.home"), EMsgType.INFO);
|
||||
|
||||
// Let's collect file names to the array to simplify our life
|
||||
|
@ -196,6 +199,11 @@ class GoldLeaf extends TransferModule {
|
|||
if (selectFile())
|
||||
break main_loop;
|
||||
break;
|
||||
case CMD_StartFile:
|
||||
case CMD_EndFile:
|
||||
if (startOrEndFile())
|
||||
break main_loop;
|
||||
break;
|
||||
default:
|
||||
writeGL_FAIL("GL Unknown command: "+readByte[4]+" [it's a very bad sign]");
|
||||
}
|
||||
|
@ -230,6 +238,19 @@ class GoldLeaf extends TransferModule {
|
|||
splitReader = null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Handle StartFile & EndFile
|
||||
* NOTE: It's something internal for GL and used somehow by GL-PC-app, so just ignore this, at least for v0.8.
|
||||
* @return true if failed
|
||||
* false if everything is ok
|
||||
* */
|
||||
private boolean startOrEndFile(){
|
||||
if (writeGL_PASS()){
|
||||
logPrinter.print("GL Handle 'StartFile' command", EMsgType.FAIL);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Handle GetDriveCount
|
||||
* @return true if failed
|
||||
|
@ -714,7 +735,7 @@ class GoldLeaf extends TransferModule {
|
|||
* false if everything is ok
|
||||
* */
|
||||
private boolean readFile(String fileName, long offset, long size) {
|
||||
//System.out.println("readFile "+fileName+" "+offset+" "+size+"\n");
|
||||
//System.out.println("readFile "+fileName+"\t"+offset+"\t"+size+"\n");
|
||||
if (fileName.startsWith("VIRT:/")){
|
||||
// Let's find out which file requested
|
||||
String fNamePath = nspMap.get(fileName.substring(6)).getAbsolutePath(); // NOTE: 6 = "VIRT:/".length
|
||||
|
@ -776,8 +797,10 @@ class GoldLeaf extends TransferModule {
|
|||
int bytesRead = splitReader.read(chunk);
|
||||
// Let's check that we read expected size
|
||||
if (bytesRead != (int)size)
|
||||
return writeGL_FAIL("GL Handle 'ReadFile' command [CMD]\n" +
|
||||
" At offset: "+offset+"\n Requested: "+size+"\n Received: "+bytesRead);
|
||||
return writeGL_FAIL("GL Handle 'ReadFile' command [CMD]" +
|
||||
"\n At offset: " + offset +
|
||||
"\n Requested: " + size +
|
||||
"\n Received: " + bytesRead);
|
||||
// Let's tell as a command about our result.
|
||||
if (writeGL_PASS(longToArrLE(size))) {
|
||||
logPrinter.print("GL Handle 'ReadFile' command [CMD]", EMsgType.FAIL);
|
||||
|
@ -792,7 +815,7 @@ class GoldLeaf extends TransferModule {
|
|||
}
|
||||
else {
|
||||
randAccessFile.seek(offset);
|
||||
byte[] chunk = new byte[(int)size]; // WTF MAN?
|
||||
byte[] chunk = new byte[(int)size]; // yes, I know, but nothing to do here.
|
||||
// Let's find out how much bytes we got
|
||||
int bytesRead = randAccessFile.read(chunk);
|
||||
// Let's check that we read expected size
|
||||
|
@ -984,8 +1007,9 @@ class GoldLeaf extends TransferModule {
|
|||
closeOpenedReadFilesGl(); // Could be a problem if GL glitches and slow down process. Or if user has extra-slow SD card. TODO: refactor
|
||||
continue;
|
||||
default:
|
||||
logPrinter.print("GL Data transfer issue [read]\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
|
||||
logPrinter.print("GL Execution stopped", EMsgType.FAIL);
|
||||
logPrinter.print("GL Data transfer issue [read]\n Returned: " +
|
||||
UsbErrorCodes.getErrCode(result) +
|
||||
"\n GL Execution stopped", EMsgType.FAIL);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1012,8 +1036,9 @@ class GoldLeaf extends TransferModule {
|
|||
case LibUsb.ERROR_TIMEOUT:
|
||||
continue;
|
||||
default:
|
||||
logPrinter.print("GL Data transfer issue [read]\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
|
||||
logPrinter.print("GL Execution stopped", EMsgType.FAIL);
|
||||
logPrinter.print("GL Data transfer issue [read]\n Returned: " +
|
||||
UsbErrorCodes.getErrCode(result) +
|
||||
"\n GL Execution stopped", EMsgType.FAIL);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1067,110 +1092,21 @@ class GoldLeaf extends TransferModule {
|
|||
if (writeBufTransferred.get() == message.length)
|
||||
return false;
|
||||
else {
|
||||
logPrinter.print("GL Data transfer issue [write]\n Requested: "+message.length+"\n Transferred: "+writeBufTransferred.get(), EMsgType.FAIL);
|
||||
logPrinter.print("GL Data transfer issue [write]\n Requested: " +
|
||||
message.length +
|
||||
"\n Transferred: "+writeBufTransferred.get(), EMsgType.FAIL);
|
||||
return true;
|
||||
}
|
||||
case LibUsb.ERROR_TIMEOUT:
|
||||
continue;
|
||||
default:
|
||||
logPrinter.print("GL Data transfer issue [write]\n Returned: "+ UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
|
||||
logPrinter.print("GL Execution stopped", EMsgType.FAIL);
|
||||
logPrinter.print("GL Data transfer issue [write]\n Returned: " +
|
||||
UsbErrorCodes.getErrCode(result) +
|
||||
"\n GL Execution stopped", EMsgType.FAIL);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
logPrinter.print("GL Execution interrupted", EMsgType.INFO);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------*/
|
||||
/* GL EXPERIMENTAL PART */
|
||||
/* (left for better times) */
|
||||
/*----------------------------------------------------*/
|
||||
/*
|
||||
private boolean proxyStatPath(String path) {
|
||||
ByteBuffer writeBuffer = ByteBuffer.allocate(4096);
|
||||
List<byte[]> fileBytesSize = new LinkedList<>();
|
||||
if ((recentDirs.length == 0) && (recentFiles.length == 0)) {
|
||||
return writeGL_FAIL("proxyStatPath");
|
||||
}
|
||||
if (recentDirs.length > 0){
|
||||
writeBuffer.put(CMD_GLCO_SUCCESS);
|
||||
writeBuffer.put(GL_OBJ_TYPE_DIR);
|
||||
byte[] resultingDir = writeBuffer.array();
|
||||
writeToUsb(resultingDir);
|
||||
for (int i = 1; i < recentDirs.length; i++) {
|
||||
readGL();
|
||||
writeToUsb(resultingDir);
|
||||
}
|
||||
}
|
||||
if (recentFiles.length > 0){
|
||||
path = path.replaceAll(recentDirs[0]+"$", ""); // Remove the name from path
|
||||
for (String fileName : recentFiles){
|
||||
File f = new File(path+fileName);
|
||||
fileBytesSize.add(longToArrLE(f.length()));
|
||||
}
|
||||
writeBuffer.clear();
|
||||
for (int i = 0; i < recentFiles.length; i++){
|
||||
readGL();
|
||||
writeBuffer.clear();
|
||||
writeBuffer.put(CMD_GLCO_SUCCESS);
|
||||
writeBuffer.put(GL_OBJ_TYPE_FILE);
|
||||
writeBuffer.put(fileBytesSize.get(i));
|
||||
writeToUsb(writeBuffer.array());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean proxyGetDirFile(boolean forDirs){
|
||||
ByteBuffer writeBuffer = ByteBuffer.allocate(4096);
|
||||
List<byte[]> dirBytesNameSize = new LinkedList<>();
|
||||
List<byte[]> dirBytesName = new LinkedList<>();
|
||||
if (forDirs) {
|
||||
if (recentDirs.length <= 0)
|
||||
return writeGL_FAIL("proxyGetDirFile");
|
||||
for (String dirName : recentDirs) {
|
||||
byte[] name = dirName.getBytes(StandardCharsets.UTF_16LE);
|
||||
dirBytesNameSize.add(intToArrLE(name.length));
|
||||
dirBytesName.add(name);
|
||||
}
|
||||
writeBuffer.put(CMD_GLCO_SUCCESS);
|
||||
writeBuffer.put(dirBytesNameSize.get(0));
|
||||
writeBuffer.put(dirBytesName.get(0));
|
||||
writeToUsb(writeBuffer.array());
|
||||
writeBuffer.clear();
|
||||
for (int i = 1; i < recentDirs.length; i++){
|
||||
readGL();
|
||||
writeBuffer.put(CMD_GLCO_SUCCESS);
|
||||
writeBuffer.put(dirBytesNameSize.get(i));
|
||||
writeBuffer.put(dirBytesName.get(i));
|
||||
writeToUsb(writeBuffer.array());
|
||||
writeBuffer.clear();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (recentDirs.length <= 0)
|
||||
return writeGL_FAIL("proxyGetDirFile");
|
||||
for (String dirName : recentFiles){
|
||||
byte[] name = dirName.getBytes(StandardCharsets.UTF_16LE);
|
||||
dirBytesNameSize.add(intToArrLE(name.length));
|
||||
dirBytesName.add(name);
|
||||
}
|
||||
writeBuffer.put(CMD_GLCO_SUCCESS);
|
||||
writeBuffer.put(dirBytesNameSize.get(0));
|
||||
writeBuffer.put(dirBytesName.get(0));
|
||||
writeToUsb(writeBuffer.array());
|
||||
writeBuffer.clear();
|
||||
for (int i = 1; i < recentFiles.length; i++){
|
||||
readGL();
|
||||
writeBuffer.put(CMD_GLCO_SUCCESS);
|
||||
writeBuffer.put(dirBytesNameSize.get(i));
|
||||
writeBuffer.put(dirBytesName.get(i));
|
||||
writeToUsb(writeBuffer.array());
|
||||
writeBuffer.clear();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
1186
src/main/java/nsusbloader/COM/USB/GoldLeaf_07.java
Normal file
1186
src/main/java/nsusbloader/COM/USB/GoldLeaf_07.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -52,12 +52,20 @@ public class UsbCommunications extends Task<Void> {
|
|||
|
||||
TransferModule module;
|
||||
|
||||
if (protocol.equals("TinFoil"))
|
||||
module = new TinFoil(handler, nspMap, this, logPrinter);
|
||||
else if (protocol.equals("GoldLeaf"))
|
||||
module = new GoldLeaf(handler, nspMap, this, logPrinter, nspFilterForGl);
|
||||
else
|
||||
module = new GoldLeaf_05(handler, nspMap, this, logPrinter);
|
||||
switch (protocol) {
|
||||
case "TinFoil":
|
||||
module = new TinFoil(handler, nspMap, this, logPrinter);
|
||||
break;
|
||||
case "GoldLeaf":
|
||||
module = new GoldLeaf(handler, nspMap, this, logPrinter, nspFilterForGl);
|
||||
break;
|
||||
case "GoldLeafv0.7.x":
|
||||
module = new GoldLeaf_07(handler, nspMap, this, logPrinter, nspFilterForGl);
|
||||
break;
|
||||
default:
|
||||
module = new GoldLeaf_05(handler, nspMap, this, logPrinter);
|
||||
break;
|
||||
}
|
||||
|
||||
usbConnect.close();
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ public class SettingsController implements Initializable {
|
|||
|
||||
private HostServices hs;
|
||||
|
||||
private static final String[] oldGlSupportedVersions = {"v0.5"};
|
||||
private static final String[] oldGlSupportedVersions = {"v0.5", "v0.7.x"};
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
|
|
|
@ -12,7 +12,7 @@ import java.util.Locale;
|
|||
import java.util.ResourceBundle;
|
||||
|
||||
public class NSLMain extends Application {
|
||||
public static final String appVersion = "v0.9.1";
|
||||
public static final String appVersion = "v1.0";
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception{
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/NSLMain.fxml"));
|
||||
|
@ -59,9 +59,8 @@ public class NSLMain extends Application {
|
|||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
if ((args.length == 1) && (args[0].equals("-v") || args[0].equals("--version"))){
|
||||
if ((args.length == 1) && (args[0].equals("-v") || args[0].equals("--version")))
|
||||
System.out.println("NS-USBloader "+NSLMain.appVersion);
|
||||
}
|
||||
else
|
||||
launch(args);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue