This commit is contained in:
parent
02a2200d04
commit
0a9883ad2b
6 changed files with 271 additions and 254 deletions
6
pom.xml
6
pom.xml
|
@ -50,7 +50,7 @@
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<maven.build.timestamp.format>yyyyMMdd.HHmmss</maven.build.timestamp.format>
|
<maven.build.timestamp.format>yyyyMMdd.HHmmss</maven.build.timestamp.format>
|
||||||
<javafx.version>19.0.2.1</javafx.version>
|
<javafx.version>19.0.2.1</javafx.version>
|
||||||
<maven.compiler.release>11</maven.compiler.release>
|
<maven.compiler.release>17</maven.compiler.release>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<issueManagement>
|
<issueManagement>
|
||||||
|
@ -205,7 +205,7 @@
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.10.1</version>
|
<version>3.10.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<release>11</release>
|
<release>17</release>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- Don't generate default JAR without dependencies -->
|
<!-- Don't generate default JAR without dependencies -->
|
||||||
|
@ -274,7 +274,7 @@
|
||||||
<!-- <dontWrapJar>true</dontWrapJar> -->
|
<!-- <dontWrapJar>true</dontWrapJar> -->
|
||||||
<jre>
|
<jre>
|
||||||
<path>%PWD%/jdk</path>
|
<path>%PWD%/jdk</path>
|
||||||
<minVersion>11.0.0</minVersion>
|
<minVersion>17.0.0</minVersion>
|
||||||
</jre>
|
</jre>
|
||||||
<versionInfo>
|
<versionInfo>
|
||||||
<fileVersion>${project.version}.0.0</fileVersion>
|
<fileVersion>${project.version}.0.0</fileVersion>
|
||||||
|
|
|
@ -31,14 +31,17 @@ public abstract class TransferModule {
|
||||||
protected static final byte IN_EP = (byte) 0x81;
|
protected static final byte IN_EP = (byte) 0x81;
|
||||||
protected static final byte OUT_EP = (byte) 0x01;
|
protected static final byte OUT_EP = (byte) 0x01;
|
||||||
|
|
||||||
EFileStatus status = EFileStatus.UNKNOWN;
|
protected EFileStatus status = EFileStatus.UNKNOWN;
|
||||||
|
|
||||||
LinkedHashMap<String, File> nspMap;
|
protected LinkedHashMap<String, File> nspMap;
|
||||||
ILogPrinter logPrinter;
|
protected ILogPrinter logPrinter;
|
||||||
DeviceHandle handlerNS;
|
protected DeviceHandle handlerNS;
|
||||||
CancellableRunnable task;
|
protected CancellableRunnable task;
|
||||||
|
|
||||||
TransferModule(DeviceHandle handler, LinkedHashMap<String, File> nspMap, CancellableRunnable task, ILogPrinter printer){
|
protected TransferModule(DeviceHandle handler,
|
||||||
|
LinkedHashMap<String, File> nspMap,
|
||||||
|
CancellableRunnable task,
|
||||||
|
ILogPrinter printer){
|
||||||
this.handlerNS = handler;
|
this.handlerNS = handler;
|
||||||
this.nspMap = nspMap;
|
this.nspMap = nspMap;
|
||||||
this.task = task;
|
this.task = task;
|
||||||
|
@ -81,7 +84,7 @@ public abstract class TransferModule {
|
||||||
}
|
}
|
||||||
public EFileStatus getStatus(){ return status; }
|
public EFileStatus getStatus(){ return status; }
|
||||||
|
|
||||||
void print(String message, EMsgType type){
|
protected void print(String message, EMsgType type){
|
||||||
try {
|
try {
|
||||||
logPrinter.print(message, type);
|
logPrinter.print(message, type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import nsusbloader.ModelControllers.Log;
|
||||||
import nsusbloader.NSLDataTypes.EFileStatus;
|
import nsusbloader.NSLDataTypes.EFileStatus;
|
||||||
import nsusbloader.NSLDataTypes.EModule;
|
import nsusbloader.NSLDataTypes.EModule;
|
||||||
import nsusbloader.NSLDataTypes.EMsgType;
|
import nsusbloader.NSLDataTypes.EMsgType;
|
||||||
|
import nsusbloader.com.usb.gl.GoldLeaf_111;
|
||||||
import org.usb4java.*;
|
import org.usb4java.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
53
src/main/java/nsusbloader/com/usb/gl/Converters.java
Normal file
53
src/main/java/nsusbloader/com/usb/gl/Converters.java
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019-2025 Dmitry Isaenko
|
||||||
|
|
||||||
|
This file is part of NS-USBloader.
|
||||||
|
|
||||||
|
NS-USBloader 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.
|
||||||
|
|
||||||
|
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package nsusbloader.com.usb.gl;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
|
public class Converters {
|
||||||
|
/**
|
||||||
|
* Convert INT (Little endian) value to bytes-array representation
|
||||||
|
* */
|
||||||
|
public static byte[] intToArrLE(int value){
|
||||||
|
return ByteBuffer.allocate(Integer.BYTES).order(ByteOrder.LITTLE_ENDIAN)
|
||||||
|
.putInt(value)
|
||||||
|
.array();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convert LONG (Little endian) value to bytes-array representation
|
||||||
|
* */
|
||||||
|
public static byte[] longToArrLE(long value){
|
||||||
|
return ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN)
|
||||||
|
.putLong(value)
|
||||||
|
.array();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convert bytes-array to INT value (Little endian)
|
||||||
|
* */
|
||||||
|
public static int arrToIntLE(byte[] byteArrayWithInt, int intStartPosition){
|
||||||
|
return ByteBuffer.wrap(byteArrayWithInt).order(ByteOrder.LITTLE_ENDIAN).getInt(intStartPosition);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convert bytes-array to LONG value (Little endian)
|
||||||
|
* */
|
||||||
|
public static long arrToLongLE(byte[] byteArrayWithLong, int intStartPosition){
|
||||||
|
return ByteBuffer.wrap(byteArrayWithLong).order(ByteOrder.LITTLE_ENDIAN).getLong(intStartPosition);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,31 +16,33 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
along with NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package nsusbloader.com.usb;
|
package nsusbloader.com.usb.gl;
|
||||||
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import libKonogonka.RainbowDump;
|
|
||||||
import nsusbloader.MediatorControl;
|
import nsusbloader.MediatorControl;
|
||||||
import nsusbloader.ModelControllers.CancellableRunnable;
|
import nsusbloader.ModelControllers.CancellableRunnable;
|
||||||
import nsusbloader.ModelControllers.ILogPrinter;
|
import nsusbloader.ModelControllers.ILogPrinter;
|
||||||
import nsusbloader.NSLDataTypes.EMsgType;
|
import nsusbloader.NSLDataTypes.EMsgType;
|
||||||
import nsusbloader.com.helpers.NSSplitReader;
|
import nsusbloader.com.helpers.NSSplitReader;
|
||||||
|
import nsusbloader.com.usb.TransferModule;
|
||||||
|
import nsusbloader.com.usb.UsbErrorCodes;
|
||||||
import org.usb4java.DeviceHandle;
|
import org.usb4java.DeviceHandle;
|
||||||
import org.usb4java.LibUsb;
|
import org.usb4java.LibUsb;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import static nsusbloader.com.usb.gl.Converters.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GoldLeaf 1.1.1 processing
|
* GoldLeaf 1.1.1 processing
|
||||||
*/
|
*/
|
||||||
class GoldLeaf_111 extends TransferModule {
|
public class GoldLeaf_111 extends TransferModule {
|
||||||
// CMD
|
// CMD
|
||||||
private final static byte[] CMD_GLCO_FAILURE =
|
private final static byte[] CMD_GLCO_FAILURE =
|
||||||
Arrays.copyOf(new byte[]{0x47, 0x4c, 0x43, 0x4F, 0x00, 0x00, (byte) 0xAD, (byte) 0xDE}, 4096); // used @ writeToUsb_GLCMD
|
Arrays.copyOf(new byte[]{0x47, 0x4c, 0x43, 0x4F, 0x00, 0x00, (byte) 0xAD, (byte) 0xDE}, 4096); // used @ writeToUsb_GLCMD
|
||||||
|
@ -48,8 +50,8 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
new byte[]{0x47, 0x4c, 0x43, 0x4F, 0x00, 0x00, 0x00, 0x00}; // used @ writeToUsb_GLCMD
|
new byte[]{0x47, 0x4c, 0x43, 0x4F, 0x00, 0x00, 0x00, 0x00}; // used @ writeToUsb_GLCMD
|
||||||
|
|
||||||
// System.out.println((356 & 0x1FF) | ((1 + 100) & 0x1FFF) << 9); // 52068 // 0x00 0x00 0xCB 0x64
|
// 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};
|
private final byte[] GL_OBJECT_TYPE_FILE = new byte[]{0x01, 0x00, 0x00, 0x00};
|
||||||
private final byte[] GL_OBJ_TYPE_DIR = new byte[]{0x02, 0x00, 0x00, 0x00};
|
private final byte[] GL_OBJECT_TYPE_DIR = new byte[]{0x02, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
private final boolean nspFilter;
|
private final boolean nspFilter;
|
||||||
|
|
||||||
|
@ -72,59 +74,20 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
// For using in CMD_SelectFile with SPEC:/ prefix
|
// For using in CMD_SelectFile with SPEC:/ prefix
|
||||||
private File selectedFile;
|
private File selectedFile;
|
||||||
|
|
||||||
private final CancellableRunnable task;
|
public GoldLeaf_111(DeviceHandle handler,
|
||||||
|
|
||||||
private enum GL_CMD {
|
|
||||||
CMD_GetDriveCount((byte) 1),
|
|
||||||
CMD_GetDriveInfo((byte) 2),
|
|
||||||
CMD_StatPath((byte) 3),
|
|
||||||
CMD_GetFileCount((byte) 4),
|
|
||||||
CMD_GetFile((byte) 5),
|
|
||||||
CMD_GetDirectoryCount((byte) 6),
|
|
||||||
CMD_GetDirectory((byte) 7),
|
|
||||||
CMD_StartFile((byte) 8),
|
|
||||||
CMD_ReadFile((byte) 9),
|
|
||||||
CMD_WriteFile((byte) 10),
|
|
||||||
CMD_EndFile((byte) 11),
|
|
||||||
CMD_Create((byte) 12),
|
|
||||||
CMD_Delete((byte) 13),
|
|
||||||
CMD_Rename((byte) 14),
|
|
||||||
CMD_GetSpecialPathCount((byte) 15),
|
|
||||||
CMD_GetSpecialPath((byte) 16),
|
|
||||||
CMD_SelectFile((byte) 17),
|
|
||||||
CMD_UNKNOWN((byte) 255);
|
|
||||||
|
|
||||||
private final byte id;
|
|
||||||
|
|
||||||
GL_CMD(byte id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GL_CMD get(byte id) {
|
|
||||||
for(GL_CMD cmd : values()) {
|
|
||||||
if(cmd.id == id)
|
|
||||||
return cmd;
|
|
||||||
}
|
|
||||||
return CMD_UNKNOWN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GoldLeaf_111(DeviceHandle handler,
|
|
||||||
LinkedHashMap<String, File> nspMap,
|
LinkedHashMap<String, File> nspMap,
|
||||||
CancellableRunnable task,
|
CancellableRunnable task,
|
||||||
ILogPrinter logPrinter,
|
ILogPrinter logPrinter,
|
||||||
boolean nspFilter) {
|
boolean nspFilter) {
|
||||||
super(handler, nspMap, task, logPrinter);
|
super(handler, nspMap, task, logPrinter);
|
||||||
|
|
||||||
this.task = task;
|
|
||||||
this.nspFilter = nspFilter;
|
this.nspFilter = nspFilter;
|
||||||
|
|
||||||
print("=========== GoldLeaf v1.1.1 ===========\n\t" +
|
print("=========== GoldLeaf v1.1.1 ===========\n\t" +
|
||||||
"VIRT:/ equals files added into the application\n\t" +
|
"VIRT:/ equals files added into the application\n\t" +
|
||||||
"HOME:/ equals "
|
"HOME:/ equals " +homePath, EMsgType.INFO);
|
||||||
+System.getProperty("user.home"), EMsgType.INFO);
|
|
||||||
|
|
||||||
// Let's collect file names to the array to simplify our life
|
// Let's collect file names to the array (simplifies flow)
|
||||||
nspMapKeySetIndexes = nspMap.keySet().toArray(new String[0]);
|
nspMapKeySetIndexes = nspMap.keySet().toArray(new String[0]);
|
||||||
|
|
||||||
// Calculate size of VIRT:/ drive
|
// Calculate size of VIRT:/ drive
|
||||||
|
@ -152,90 +115,88 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//RainbowDump.hexDumpUTF8(readByte); // DEBUG
|
//RainbowDump.hexDumpUTF8(readByte); // DEBUG
|
||||||
System.out.println("\t→: "+GL_CMD.get(readByte[4])); // FIXME: DEBUG
|
//System.out.println("\t→ "+ GoldleafCmd.get(readByte[4]));
|
||||||
|
|
||||||
if (notGLCI(readByte))
|
if (notGLCI(readByte))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (GL_CMD.get(readByte[4])) {
|
switch (GoldleafCmd.get(readByte[4])) {
|
||||||
case CMD_GetDriveCount:
|
case GetDriveCount:
|
||||||
if (getDriveCount())
|
if (getDriveCount())
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
case CMD_GetDriveInfo:
|
case GetDriveInfo:
|
||||||
if (getDriveInfo(arrToIntLE(readByte,8)))
|
if (getDriveInfo(arrToIntLE(readByte,8)))
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
case CMD_GetSpecialPathCount:
|
case GetSpecialPathCount:
|
||||||
if (getSpecialPathCount())
|
if (getSpecialPathCount())
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
case CMD_GetSpecialPath:
|
case GetSpecialPath:
|
||||||
if (getSpecialPath(arrToIntLE(readByte,8)))
|
if (getSpecialPath(arrToIntLE(readByte,8)))
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
case CMD_GetDirectoryCount:
|
case GetDirectoryCount:
|
||||||
someLength1 = arrToIntLE(readByte, 8);
|
someLength1 = arrToIntLE(readByte, 8);
|
||||||
if (getDirectoryOrFileCount(new String(readByte, 12, someLength1, StandardCharsets.UTF_8), true))
|
if (getDirectoryOrFileCount(new String(readByte, 12, someLength1, StandardCharsets.UTF_8), true))
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
case CMD_GetFileCount:
|
case GetFileCount:
|
||||||
someLength1 = arrToIntLE(readByte, 8);
|
someLength1 = arrToIntLE(readByte, 8);
|
||||||
if (getDirectoryOrFileCount(new String(readByte, 12, someLength1, StandardCharsets.UTF_8), false))
|
if (getDirectoryOrFileCount(new String(readByte, 12, someLength1, StandardCharsets.UTF_8), false))
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
case CMD_GetDirectory:
|
case GetDirectory:
|
||||||
someLength1 = arrToIntLE(readByte, 8);
|
someLength1 = arrToIntLE(readByte, 8);
|
||||||
if (getDirectory(new String(readByte, 12, someLength1, StandardCharsets.UTF_8), arrToIntLE(readByte, someLength1+12)))
|
if (getDirectory(new String(readByte, 12, someLength1, StandardCharsets.UTF_8), arrToIntLE(readByte, someLength1+12)))
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
case CMD_GetFile:
|
case GetFile:
|
||||||
someLength1 = arrToIntLE(readByte, 8);
|
someLength1 = arrToIntLE(readByte, 8);
|
||||||
if (getFile(new String(readByte, 12, someLength1, StandardCharsets.UTF_8), arrToIntLE(readByte, someLength1+12)))
|
if (getFile(new String(readByte, 12, someLength1, StandardCharsets.UTF_8), arrToIntLE(readByte, someLength1+12)))
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
case CMD_StatPath:
|
case StatPath:
|
||||||
someLength1 = arrToIntLE(readByte, 8);
|
someLength1 = arrToIntLE(readByte, 8);
|
||||||
if (statPath(new String(readByte, 12, someLength1, StandardCharsets.UTF_8)))
|
if (statPath(new String(readByte, 12, someLength1, StandardCharsets.UTF_8)))
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
case CMD_Rename:
|
case Rename:
|
||||||
someLength1 = arrToIntLE(readByte, 8);
|
someLength1 = arrToIntLE(readByte, 8);
|
||||||
someLength2 = arrToIntLE(readByte, 12+someLength1);
|
someLength2 = arrToIntLE(readByte, 12+someLength1);
|
||||||
if (rename(new String(readByte, 12, someLength1, StandardCharsets.UTF_8), // 8+4=12
|
if (rename(new String(readByte, 12, someLength1, StandardCharsets.UTF_8), // 8+4=12
|
||||||
new String(readByte, 12+someLength1+4, someLength2, StandardCharsets.UTF_8)))
|
new String(readByte, 12+someLength1+4, someLength2, StandardCharsets.UTF_8)))
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
case CMD_Delete:
|
case Delete:
|
||||||
RainbowDump.hexDumpUTF8(readByte); // TODO: DEBUG
|
someLength1 = arrToIntLE(readByte, 8);
|
||||||
someLength1 = arrToIntLE(readByte, 12); // FIXME TEST ME!
|
if (delete(new String(readByte, 12, someLength1, StandardCharsets.UTF_8)))
|
||||||
if (delete(new String(readByte, 16, someLength1, StandardCharsets.UTF_8)))
|
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
case CMD_Create:
|
case Create:
|
||||||
someLength1 = arrToIntLE(readByte, 12); // FIXME TEST ME!
|
someLength1 = arrToIntLE(readByte, 8);
|
||||||
if (create(new String(readByte, 16, someLength1, StandardCharsets.UTF_8), readByte[8]))
|
if (create(new String(readByte, 12, someLength1, StandardCharsets.UTF_8), readByte[8]))
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
case CMD_ReadFile:
|
case ReadFile:
|
||||||
someLength1 = arrToIntLE(readByte, 8);
|
someLength1 = arrToIntLE(readByte, 8);
|
||||||
if (readFile(new String(readByte, 12, someLength1, StandardCharsets.UTF_8),
|
if (readFile(new String(readByte, 12, someLength1, StandardCharsets.UTF_8),
|
||||||
arrToLongLE(readByte, 12+someLength1),
|
arrToLongLE(readByte, 12+someLength1),
|
||||||
arrToLongLE(readByte, 12+someLength1+8)))
|
arrToLongLE(readByte, 12+someLength1+8)))
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
case CMD_WriteFile:
|
case WriteFile:
|
||||||
someLength1 = arrToIntLE(readByte, 8);
|
someLength1 = arrToIntLE(readByte, 8);
|
||||||
//if (writeFile(new String(readByte, 12, someLength1, StandardCharsets.UTF_8), arrToLongLE(readByte, 12+someLength1)))
|
|
||||||
if (writeFile(new String(readByte, 12, someLength1, StandardCharsets.UTF_8)))
|
if (writeFile(new String(readByte, 12, someLength1, StandardCharsets.UTF_8)))
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
case CMD_SelectFile:
|
case SelectFile:
|
||||||
if (selectFile())
|
if (selectFile())
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
case CMD_StartFile:
|
case StartFile:
|
||||||
case CMD_EndFile:
|
case EndFile:
|
||||||
if (startOrEndFile())
|
if (startOrEndFile())
|
||||||
break main_loop;
|
break main_loop;
|
||||||
break;
|
break;
|
||||||
|
@ -256,37 +217,6 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
return ! "GLCI".equals(new String(inputBytes, 0, 4, StandardCharsets.US_ASCII));
|
return ! "GLCI".equals(new String(inputBytes, 0, 4, StandardCharsets.US_ASCII));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Close files opened for read/write
|
|
||||||
*/
|
|
||||||
private void closeOpenedReadFilesGl(){
|
|
||||||
if (openReadFileNameAndPath != null){
|
|
||||||
closeRAFandSplitReader();
|
|
||||||
openReadFileNameAndPath = null;
|
|
||||||
randAccessFile = null;
|
|
||||||
splitReader = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void closeRAFandSplitReader(){
|
|
||||||
closeRAF();
|
|
||||||
try{
|
|
||||||
splitReader.close();
|
|
||||||
}
|
|
||||||
catch (IOException ioe_){
|
|
||||||
print("Unable to close: "+openReadFileNameAndPath+"\n\t"+ioe_.getMessage(), EMsgType.WARNING);
|
|
||||||
}
|
|
||||||
catch (Exception ignored){}
|
|
||||||
}
|
|
||||||
private void closeRAF(){
|
|
||||||
try{
|
|
||||||
randAccessFile.close();
|
|
||||||
}
|
|
||||||
catch (IOException ioe_){
|
|
||||||
print("Unable to close: "+openReadFileNameAndPath+"\n\t"+ioe_.getMessage(), EMsgType.WARNING);
|
|
||||||
}
|
|
||||||
catch (Exception ignored){}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle StartFile & EndFile
|
* 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.
|
* NOTE: It's something internal for GL and used somehow by GL-PC-app, so just ignore this, at least for v0.8.
|
||||||
|
@ -315,8 +245,7 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
driveLabelLen,
|
driveLabelLen,
|
||||||
driveLetter,
|
driveLetter,
|
||||||
driveLetterLen,
|
driveLetterLen,
|
||||||
totalFreeSpace,
|
totalFreeSpace;
|
||||||
totalSize;
|
|
||||||
long totalSizeLong;
|
long totalSizeLong;
|
||||||
|
|
||||||
if (driveNo == 0){ // 0 == VIRTUAL DRIVE
|
if (driveNo == 0){ // 0 == VIRTUAL DRIVE
|
||||||
|
@ -336,7 +265,7 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
totalFreeSpace = Arrays.copyOfRange(longToArrLE(userHomeDir.getFreeSpace()), 0, 4);;
|
totalFreeSpace = Arrays.copyOfRange(longToArrLE(userHomeDir.getFreeSpace()), 0, 4);;
|
||||||
totalSizeLong = userHomeDir.getTotalSpace();
|
totalSizeLong = userHomeDir.getTotalSpace();
|
||||||
}
|
}
|
||||||
totalSize = Arrays.copyOfRange(longToArrLE(totalSizeLong), 0, 4);
|
var totalSize = Arrays.copyOfRange(longToArrLE(totalSizeLong), 0, 4);
|
||||||
|
|
||||||
var command = Arrays.asList(
|
var command = Arrays.asList(
|
||||||
driveLabelLen,
|
driveLabelLen,
|
||||||
|
@ -367,24 +296,25 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
* Handle GetDirectoryCount & GetFileCount
|
* Handle GetDirectoryCount & GetFileCount
|
||||||
* @return true - failed, false - passed
|
* @return true - failed, false - passed
|
||||||
* */
|
* */
|
||||||
private boolean getDirectoryOrFileCount(String path, boolean isGetDirectoryCount) {
|
private boolean getDirectoryOrFileCount(String glFileName, boolean isGetDirectoryCount) {
|
||||||
if (path.equals("VIRT:/")) {
|
if (glFileName.equals("VIRT:/")) {
|
||||||
return isGetDirectoryCount ?
|
return isGetDirectoryCount ?
|
||||||
writeGL_PASS("GL Handle 'GetDirectoryCount' command") :
|
writeGL_PASS("GL Handle 'GetDirectoryCount' command") :
|
||||||
writeGL_PASS(intToArrLE(nspMap.size()), "GL Handle 'GetFileCount' command Count = " + nspMap.size());
|
writeGL_PASS(intToArrLE(nspMap.size()), "GL Handle 'GetFileCount' command Count = " + nspMap.size());
|
||||||
}
|
}
|
||||||
else if (path.startsWith("HOME:/")){
|
else if (glFileName.startsWith("HOME:/")){
|
||||||
// Let's make it normal path
|
var path = updateHomePath(glFileName);
|
||||||
path = updateHomePath(path);
|
|
||||||
var pathDir = new File(path);
|
var pathDir = new File(path);
|
||||||
|
|
||||||
// Make sure it's exists and it's path
|
if (notExistsOrDirectory(pathDir))
|
||||||
if ((! pathDir.exists() ) || (! pathDir.isDirectory()) )
|
return writeGL_FAIL("GL Handle 'GetDirectoryOrFileCount' command [doesn't exist or not a folder] "+ pathDir);
|
||||||
return writeGL_FAIL("GL Handle 'GetDirectoryOrFileCount' command [doesn't exist or not a folder]");
|
|
||||||
// Save recent dir path
|
this.recentPath = path; // Save recent dir path
|
||||||
this.recentPath = path;
|
var filesOrDirs = isGetDirectoryCount ?
|
||||||
var filesOrDirs = getFilesOrDirs(isGetDirectoryCount, pathDir);
|
pathDir.list(this::isDirectoryAndNotHidden) :
|
||||||
// If somehow there are no folders, let's say 0;
|
pathDir.list(this::isFileAndNotHidden);
|
||||||
|
|
||||||
|
// If no folders, let's say 0;
|
||||||
if (filesOrDirs == null)
|
if (filesOrDirs == null)
|
||||||
return writeGL_PASS("GL Handle 'GetDirectoryOrFileCount' command");
|
return writeGL_PASS("GL Handle 'GetDirectoryOrFileCount' command");
|
||||||
// Sorting is mandatory NOTE: Proxy tail
|
// Sorting is mandatory NOTE: Proxy tail
|
||||||
|
@ -397,34 +327,15 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
// Otherwise, let's tell how may folders are in there
|
// Otherwise, let's tell how may folders are in there
|
||||||
return writeGL_PASS(intToArrLE(filesOrDirs.length), "GL Handle 'GetDirectoryOrFileCount' command");
|
return writeGL_PASS(intToArrLE(filesOrDirs.length), "GL Handle 'GetDirectoryOrFileCount' command");
|
||||||
}
|
}
|
||||||
else if (path.startsWith("SPEC:/")){
|
else if (glFileName.startsWith("SPEC:/")){
|
||||||
if (isGetDirectoryCount) // If dir request then 0 dirs
|
if (isGetDirectoryCount) // If dir request then 0 dirs
|
||||||
return writeGL_PASS("GL Handle 'GetDirectoryCount' command");
|
return writeGL_PASS("GL Handle 'GetDirectoryCount' command");
|
||||||
else if (selectedFile != null) // Else it's file request, if we have selected then we will report 1.
|
else if (selectedFile != null) // Else it's file request, if we have selected then we will report 1.
|
||||||
return writeGL_PASS(intToArrLE(1), "GL Handle 'GetFileCount' command Count = 1");
|
return writeGL_PASS(intToArrLE(1), "GL Handle 'GetFileCount' command Count = 1");
|
||||||
return writeGL_FAIL("GL Handle 'GetDirectoryOrFileCount' command [unknown drive request] (file) - "+path);
|
return writeGL_FAIL("GL Handle 'GetDirectoryOrFileCount' command [unknown drive request] (file) - "+glFileName);
|
||||||
}
|
}
|
||||||
// If requested drive is not VIRT and not HOME then reply error
|
// If requested drive is not VIRT and not HOME then reply error
|
||||||
return writeGL_FAIL("GL Handle 'GetDirectoryOrFileCount' command [unknown drive request] "+(isGetDirectoryCount?"(dir) - ":"(file) - ")+path);
|
return writeGL_FAIL("GL Handle 'GetDirectoryOrFileCount' command [unknown drive request] "+(isGetDirectoryCount?"(dir) - ":"(file) - ")+glFileName);
|
||||||
}
|
|
||||||
private String[] getFilesOrDirs(boolean isGetDirectoryCount, File pathDir) {
|
|
||||||
String[] filesOrDirs;
|
|
||||||
// Now collecting every folder or file inside
|
|
||||||
if (isGetDirectoryCount){
|
|
||||||
filesOrDirs = pathDir.list((current, name) -> {
|
|
||||||
var dir = new File(current, name);
|
|
||||||
return (dir.isDirectory() && ! dir.isHidden());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
filesOrDirs = pathDir.list((current, name) -> {
|
|
||||||
var dir = new File(current, name);
|
|
||||||
return (! dir.isDirectory() && nspFilter ?
|
|
||||||
name.toLowerCase().endsWith(".nsp") :
|
|
||||||
! dir.isHidden());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return filesOrDirs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -445,14 +356,11 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
else {
|
else {
|
||||||
var pathDir = new File(dirName);
|
var pathDir = new File(dirName);
|
||||||
// Make sure it's exists and it's path
|
// Make sure it's exists and it's path
|
||||||
if ((! pathDir.exists() ) || (! pathDir.isDirectory()) )
|
if (notExistsOrDirectory(pathDir))
|
||||||
return writeGL_FAIL("GL Handle 'GetDirectory' command [doesn't exist or not a folder]");
|
return writeGL_FAIL("GL Handle 'GetDirectory' command [doesn't exist or not a folder]");
|
||||||
this.recentPath = dirName;
|
this.recentPath = dirName;
|
||||||
// Now collecting every folder or file inside
|
// Now collecting every folder or file inside
|
||||||
this.recentDirs = pathDir.list((current, name) -> {
|
this.recentDirs = pathDir.list(this::isDirectoryAndNotHidden);
|
||||||
var dir = new File(current, name);
|
|
||||||
return (dir.isDirectory() && ! dir.isHidden()); // TODO: FIX FOR WIN ?
|
|
||||||
});
|
|
||||||
// Check that we still don't have any fuckups
|
// Check that we still don't have any fuckups
|
||||||
if (this.recentDirs != null && this.recentDirs.length > subDirNo){
|
if (this.recentDirs != null && this.recentDirs.length > subDirNo){
|
||||||
Arrays.sort(recentFiles, String.CASE_INSENSITIVE_ORDER);
|
Arrays.sort(recentFiles, String.CASE_INSENSITIVE_ORDER);
|
||||||
|
@ -472,11 +380,11 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
* Handle GetFile
|
* Handle GetFile
|
||||||
* @return true - failed, false - passed
|
* @return true - failed, false - passed
|
||||||
* */
|
* */
|
||||||
private boolean getFile(String dirName, int subDirNo){
|
private boolean getFile(String glDirName, int subDirNo){
|
||||||
var command = new LinkedList<byte[]>();
|
var command = new LinkedList<byte[]>();
|
||||||
|
|
||||||
if (dirName.startsWith("HOME:/")) {
|
if (glDirName.startsWith("HOME:/")) {
|
||||||
dirName = updateHomePath(dirName);
|
var dirName = updateHomePath(glDirName);
|
||||||
|
|
||||||
if (dirName.equals(recentPath) && recentFiles != null && recentFiles.length != 0){
|
if (dirName.equals(recentPath) && recentFiles != null && recentFiles.length != 0){
|
||||||
var fileNameBytes = recentFiles[subDirNo].getBytes(StandardCharsets.UTF_8);
|
var fileNameBytes = recentFiles[subDirNo].getBytes(StandardCharsets.UTF_8);
|
||||||
|
@ -485,23 +393,10 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var pathDir = new File(dirName);
|
var pathDir = new File(dirName);
|
||||||
// Make sure it's exists and it's path
|
if (notExistsOrDirectory(pathDir))
|
||||||
if ((! pathDir.exists() ) || (! pathDir.isDirectory()) ) // TODO: CHECK AND REMOVE .exists() IF REDUNDANT
|
|
||||||
writeGL_FAIL("GL Handle 'GetFile' command [doesn't exist or not a folder]");
|
writeGL_FAIL("GL Handle 'GetFile' command [doesn't exist or not a folder]");
|
||||||
this.recentPath = dirName;
|
this.recentPath = dirName;
|
||||||
// Now collecting every folder or file inside
|
this.recentFiles = pathDir.list(this::isFileAndNotHidden);
|
||||||
if (nspFilter){
|
|
||||||
this.recentFiles = pathDir.list((current, name) -> {
|
|
||||||
var dir = new File(current, name);
|
|
||||||
return (! dir.isDirectory() && name.toLowerCase().endsWith(".nsp"));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.recentFiles = pathDir.list((current, name) -> {
|
|
||||||
var dir = new File(current, name);
|
|
||||||
return (! dir.isDirectory() && (! dir.isHidden()));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Check that we still don't have any fuckups
|
// Check that we still don't have any fuckups
|
||||||
if (this.recentFiles != null && this.recentFiles.length > subDirNo){
|
if (this.recentFiles != null && this.recentFiles.length > subDirNo){
|
||||||
Arrays.sort(recentFiles, String.CASE_INSENSITIVE_ORDER);
|
Arrays.sort(recentFiles, String.CASE_INSENSITIVE_ORDER);
|
||||||
|
@ -514,14 +409,14 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
}
|
}
|
||||||
return writeGL_PASS(command, "GL Handle 'GetFile' command.");
|
return writeGL_PASS(command, "GL Handle 'GetFile' command.");
|
||||||
}
|
}
|
||||||
else if (dirName.equals("VIRT:/") && (! nspMap.isEmpty())){ // thus nspMapKeySetIndexes also != 0
|
else if (glDirName.equals("VIRT:/") && (! nspMap.isEmpty())){ // thus nspMapKeySetIndexes also != 0
|
||||||
var fileNameBytes = nspMapKeySetIndexes[subDirNo].getBytes(StandardCharsets.UTF_8);
|
var fileNameBytes = nspMapKeySetIndexes[subDirNo].getBytes(StandardCharsets.UTF_8);
|
||||||
command.add(intToArrLE(fileNameBytes.length));
|
command.add(intToArrLE(fileNameBytes.length));
|
||||||
command.add(fileNameBytes);
|
command.add(fileNameBytes);
|
||||||
return writeGL_PASS(command, "GL Handle 'GetFile' command.");
|
return writeGL_PASS(command, "GL Handle 'GetFile' command.");
|
||||||
}
|
}
|
||||||
else if (dirName.equals("SPEC:/") && (selectedFile != null)){
|
else if (glDirName.equals("SPEC:/") && (selectedFile != null)){
|
||||||
byte[] fileNameBytes = selectedFile.getName().getBytes(StandardCharsets.UTF_8);
|
var fileNameBytes = selectedFile.getName().getBytes(StandardCharsets.UTF_8);
|
||||||
command.add(intToArrLE(fileNameBytes.length));
|
command.add(intToArrLE(fileNameBytes.length));
|
||||||
command.add(fileNameBytes);
|
command.add(fileNameBytes);
|
||||||
return writeGL_PASS(command, "GL Handle 'GetFile' command.");
|
return writeGL_PASS(command, "GL Handle 'GetFile' command.");
|
||||||
|
@ -541,9 +436,9 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
|
|
||||||
if (fileDirElement.exists()){
|
if (fileDirElement.exists()){
|
||||||
if (fileDirElement.isDirectory())
|
if (fileDirElement.isDirectory())
|
||||||
command.add(GL_OBJ_TYPE_DIR);
|
command.add(GL_OBJECT_TYPE_DIR);
|
||||||
else {
|
else {
|
||||||
command.add(GL_OBJ_TYPE_FILE);
|
command.add(GL_OBJECT_TYPE_FILE);
|
||||||
command.add(longToArrLE(fileDirElement.length()));
|
command.add(longToArrLE(fileDirElement.length()));
|
||||||
}
|
}
|
||||||
return writeGL_PASS(command, "GL Handle 'StatPath' command for "+glFileName);
|
return writeGL_PASS(command, "GL Handle 'StatPath' command for "+glFileName);
|
||||||
|
@ -552,7 +447,7 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
else if (glFileName.startsWith("VIRT:/")) {
|
else if (glFileName.startsWith("VIRT:/")) {
|
||||||
var fileName = glFileName.replaceFirst("^.*?:/", "");
|
var fileName = glFileName.replaceFirst("^.*?:/", "");
|
||||||
if (nspMap.containsKey(fileName)){
|
if (nspMap.containsKey(fileName)){
|
||||||
command.add(GL_OBJ_TYPE_FILE); // THIS IS INT
|
command.add(GL_OBJECT_TYPE_FILE); // THIS IS INT
|
||||||
if (nspMap.get(fileName).isDirectory())
|
if (nspMap.get(fileName).isDirectory())
|
||||||
command.add(longToArrLE(splitFileSize.get(fileName))); // YES, THIS IS LONG!;
|
command.add(longToArrLE(splitFileSize.get(fileName))); // YES, THIS IS LONG!;
|
||||||
else
|
else
|
||||||
|
@ -564,7 +459,7 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
else if (glFileName.startsWith("SPEC:/")){
|
else if (glFileName.startsWith("SPEC:/")){
|
||||||
var fileName = glFileName.replaceFirst("^.*?:/", "");
|
var fileName = glFileName.replaceFirst("^.*?:/", "");
|
||||||
if (selectedFile.getName().equals(fileName)){
|
if (selectedFile.getName().equals(fileName)){
|
||||||
command.add(GL_OBJ_TYPE_FILE);
|
command.add(GL_OBJECT_TYPE_FILE);
|
||||||
command.add(longToArrLE(selectedFile.length()));
|
command.add(longToArrLE(selectedFile.length()));
|
||||||
return writeGL_PASS(command, "GL Handle 'StatPath' command for "+glFileName);
|
return writeGL_PASS(command, "GL Handle 'StatPath' command for "+glFileName);
|
||||||
}
|
}
|
||||||
|
@ -577,7 +472,7 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
* */
|
* */
|
||||||
private boolean rename(String glFileName, String glNewFileName){
|
private boolean rename(String glFileName, String glNewFileName){
|
||||||
if (glFileName.startsWith("HOME:/")){
|
if (glFileName.startsWith("HOME:/")){
|
||||||
// This shit takes too much time to explain, but such behaviour won't let GL to fail
|
// Prevent GL failures
|
||||||
this.recentPath = null;
|
this.recentPath = null;
|
||||||
this.recentFiles = null;
|
this.recentFiles = null;
|
||||||
this.recentDirs = null;
|
this.recentDirs = null;
|
||||||
|
@ -590,7 +485,9 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
return writeGL_PASS("GL Handle 'Rename' command.");
|
return writeGL_PASS("GL Handle 'Rename' command.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SecurityException ignored){}
|
catch (SecurityException se){
|
||||||
|
return writeGL_FAIL("GL Handle 'Rename' command failed:\n\t" +se.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// For VIRT:/ and others we don't serve requests
|
// For VIRT:/ and others we don't serve requests
|
||||||
return writeGL_FAIL("GL Handle 'Rename' command is not supported for virtual drive, selected files," +
|
return writeGL_FAIL("GL Handle 'Rename' command is not supported for virtual drive, selected files," +
|
||||||
|
@ -600,48 +497,43 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
* Handle 'Delete'
|
* Handle 'Delete'
|
||||||
* @return true - failed, false - passed
|
* @return true - failed, false - passed
|
||||||
* */
|
* */
|
||||||
private boolean delete(String fileName) {
|
private boolean delete(String glFileName) {
|
||||||
if (fileName.startsWith("HOME:/")) {
|
if (! glFileName.startsWith("HOME:/"))
|
||||||
fileName = updateHomePath(fileName);
|
return writeGL_FAIL("GL Handle 'Delete' command [not supported for virtual drive/wrong drive/read-only directory] "+glFileName);
|
||||||
|
|
||||||
File fileToDel = new File(fileName);
|
var file = new File(updateHomePath(glFileName));
|
||||||
try {
|
try {
|
||||||
if (fileToDel.delete()){
|
if (file.delete())
|
||||||
return writeGL_PASS("GL Handle 'Rename' command.");
|
return writeGL_PASS("GL Handle 'Rename' command.");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (SecurityException ignored){} // Ah, leave it
|
catch (SecurityException ignored){} // Ah, leave it
|
||||||
}
|
|
||||||
// For VIRT:/ and others we don't serve requests
|
return writeGL_FAIL("GL Handle 'Create' command [unknown drive/read-only directory]");
|
||||||
return writeGL_FAIL("GL Handle 'Delete' command [not supported for virtual drive/wrong drive/read-only directory]");
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Handle 'Create'
|
* Handle 'Create'
|
||||||
* @param type 1 for file
|
* @param type 1 → file, 2 → folder
|
||||||
* 2 for folder
|
* @param glFileName full path including new file name in the end
|
||||||
* @param fileName full path including new file name in the end
|
|
||||||
* @return true - failed, false - passed
|
* @return true - failed, false - passed
|
||||||
* */
|
* */
|
||||||
private boolean create(String fileName, byte type) {
|
private boolean create(String glFileName, byte type) {
|
||||||
if (! fileName.startsWith("HOME:/")) // For VIRT:/ and others we don't serve requests
|
if (! glFileName.startsWith("HOME:/")) // For VIRT:/ and others we don't serve requests
|
||||||
return writeGL_FAIL("GL Handle 'Delete' command [not supported for virtual drive/wrong drive/read-only directory]");
|
return writeGL_FAIL("GL Handle 'Create' command [not supported for virtual drive/wrong drive/read-only directory]"+glFileName);
|
||||||
|
|
||||||
fileName = updateHomePath(fileName);
|
var file = new File(updateHomePath(glFileName));
|
||||||
|
|
||||||
boolean result = false;
|
|
||||||
try {
|
try {
|
||||||
if (type == 1)
|
boolean result = switch (type) {
|
||||||
result = new File(fileName).createNewFile();
|
case 1 -> file.createNewFile();
|
||||||
else if (type == 2)
|
case 2 -> file.mkdir();
|
||||||
result = new File(fileName).mkdir();
|
default -> false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
return writeGL_PASS("GL Handle 'Create' command.");
|
||||||
}
|
}
|
||||||
catch (SecurityException | IOException ignored){}
|
catch (SecurityException | IOException ignored){}
|
||||||
|
|
||||||
if (result) {
|
return writeGL_FAIL("GL Handle 'Create' command [unknown drive/read-only directory]");
|
||||||
return writeGL_PASS("GL Handle 'Create' command.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return writeGL_FAIL("GL Handle 'Delete' command [not supported for virtual drive/wrong drive/read-only directory]");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -660,11 +552,9 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
var fNamePath = nspMap.get(fileName).getAbsolutePath(); // NOTE: 6 = "VIRT:/".length
|
var fNamePath = nspMap.get(fileName).getAbsolutePath(); // NOTE: 6 = "VIRT:/".length
|
||||||
// If we don't have this file opened, let's open it
|
// If we don't have this file opened, let's open it
|
||||||
if (openReadFileNameAndPath == null || (! openReadFileNameAndPath.equals(fNamePath))) {
|
if (openReadFileNameAndPath == null || (! openReadFileNameAndPath.equals(fNamePath))) {
|
||||||
// Try close what opened
|
if (openReadFileNameAndPath != null) // (Try to) close what opened
|
||||||
if (openReadFileNameAndPath != null)
|
|
||||||
closeRAFandSplitReader();
|
closeRAFandSplitReader();
|
||||||
// Open what has to be opened
|
try{ // And open the rest
|
||||||
try{
|
|
||||||
var tempFile = nspMap.get(fileName);
|
var tempFile = nspMap.get(fileName);
|
||||||
if (tempFile.isDirectory()) {
|
if (tempFile.isDirectory()) {
|
||||||
randAccessFile = null;
|
randAccessFile = null;
|
||||||
|
@ -713,11 +603,11 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
|
|
||||||
if (randAccessFile == null){
|
if (randAccessFile == null){
|
||||||
splitReader.seek(offset);
|
splitReader.seek(offset);
|
||||||
bytesRead = splitReader.read(chunk); // Let's find out how many bytes we got
|
bytesRead = splitReader.read(chunk); // How many bytes we got?
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
randAccessFile.seek(offset);
|
randAccessFile.seek(offset);
|
||||||
bytesRead = randAccessFile.read(chunk); // Let's find out how many bytes we got
|
bytesRead = randAccessFile.read(chunk); // How many bytes we got?
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytesRead != (int) size) // Let's check that we read expected size
|
if (bytesRead != (int) size) // Let's check that we read expected size
|
||||||
|
@ -741,7 +631,6 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
/**
|
/**
|
||||||
* Handle 'WriteFile'
|
* Handle 'WriteFile'
|
||||||
* @param fileName full path including new file name in the end
|
* @param fileName full path including new file name in the end
|
||||||
*
|
|
||||||
* @return true - failed, false - passed
|
* @return true - failed, false - passed
|
||||||
* */
|
* */
|
||||||
private boolean writeFile(String fileName) {
|
private boolean writeFile(String fileName) {
|
||||||
|
@ -814,39 +703,56 @@ class GoldLeaf_111 extends TransferModule {
|
||||||
private String updateHomePath(String glPath){
|
private String updateHomePath(String glPath){
|
||||||
if (isWindows)
|
if (isWindows)
|
||||||
glPath = glPath.replaceAll("/", "\\\\");
|
glPath = glPath.replaceAll("/", "\\\\");
|
||||||
glPath = homePath + glPath.substring(6); // Do not use replaceAll since it will consider \ as special directive
|
glPath = homePath + glPath.substring(6); // Better not using .replaceAll() since it will consider \ as special directive
|
||||||
return glPath;
|
return glPath;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Convert INT (Little endian) value to bytes-array representation
|
private boolean isFileAndNotHidden(File parent, String child){
|
||||||
* */
|
var entry = new File(parent, child);
|
||||||
private byte[] intToArrLE(int value){
|
return (! entry.isDirectory()) && (nspFilter ?
|
||||||
return ByteBuffer.allocate(Integer.BYTES).order(ByteOrder.LITTLE_ENDIAN)
|
child.toLowerCase().endsWith(".nsp") :
|
||||||
.putInt(value)
|
! entry.isHidden());
|
||||||
.array();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Convert LONG (Little endian) value to bytes-array representation
|
|
||||||
* */
|
|
||||||
private byte[] longToArrLE(long value){
|
|
||||||
return ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN)
|
|
||||||
.putLong(value)
|
|
||||||
.array();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Convert bytes-array to INT value (Little endian)
|
|
||||||
* */
|
|
||||||
private int arrToIntLE(byte[] byteArrayWithInt, int intStartPosition){
|
|
||||||
return ByteBuffer.wrap(byteArrayWithInt).order(ByteOrder.LITTLE_ENDIAN).getInt(intStartPosition);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Convert bytes-array to LONG value (Little endian)
|
|
||||||
* */
|
|
||||||
private long arrToLongLE(byte[] byteArrayWithLong, int intStartPosition){
|
|
||||||
return ByteBuffer.wrap(byteArrayWithLong).order(ByteOrder.LITTLE_ENDIAN).getLong(intStartPosition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------------------------
|
private boolean isDirectoryAndNotHidden(File parent, String child){
|
||||||
|
var dir = new File(parent, child);
|
||||||
|
return (dir.isDirectory() && ! dir.isHidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean notExistsOrDirectory(File pathDir){
|
||||||
|
return (! pathDir.exists() ) || (! pathDir.isDirectory());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close files opened for read/write
|
||||||
|
*/
|
||||||
|
private void closeOpenedReadFilesGl(){
|
||||||
|
if (openReadFileNameAndPath != null){
|
||||||
|
closeRAFandSplitReader();
|
||||||
|
openReadFileNameAndPath = null;
|
||||||
|
randAccessFile = null;
|
||||||
|
splitReader = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void closeRAFandSplitReader(){
|
||||||
|
closeRAF();
|
||||||
|
try{
|
||||||
|
splitReader.close();
|
||||||
|
}
|
||||||
|
catch (IOException ioe_){
|
||||||
|
print("Unable to close: "+openReadFileNameAndPath+"\n\t"+ioe_.getMessage(), EMsgType.WARNING);
|
||||||
|
}
|
||||||
|
catch (Exception ignored){}
|
||||||
|
}
|
||||||
|
private void closeRAF(){
|
||||||
|
try{
|
||||||
|
randAccessFile.close();
|
||||||
|
}
|
||||||
|
catch (IOException ioe_){
|
||||||
|
print("Unable to close: "+openReadFileNameAndPath+"\n\t"+ioe_.getMessage(), EMsgType.WARNING);
|
||||||
|
}
|
||||||
|
catch (Exception ignored){}
|
||||||
|
}
|
||||||
/*----------------------------------------------------*/
|
/*----------------------------------------------------*/
|
||||||
/* GL READ/WRITE USB SPECIFIC */
|
/* GL READ/WRITE USB SPECIFIC */
|
||||||
/*----------------------------------------------------*/
|
/*----------------------------------------------------*/
|
54
src/main/java/nsusbloader/com/usb/gl/GoldleafCmd.java
Normal file
54
src/main/java/nsusbloader/com/usb/gl/GoldleafCmd.java
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019-2025 Dmitry Isaenko
|
||||||
|
|
||||||
|
This file is part of NS-USBloader.
|
||||||
|
|
||||||
|
NS-USBloader 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.
|
||||||
|
|
||||||
|
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package nsusbloader.com.usb.gl;
|
||||||
|
|
||||||
|
public enum GoldleafCmd {
|
||||||
|
GetDriveCount((byte) 1),
|
||||||
|
GetDriveInfo((byte) 2),
|
||||||
|
StatPath((byte) 3),
|
||||||
|
GetFileCount((byte) 4),
|
||||||
|
GetFile((byte) 5),
|
||||||
|
GetDirectoryCount((byte) 6),
|
||||||
|
GetDirectory((byte) 7),
|
||||||
|
StartFile((byte) 8),
|
||||||
|
ReadFile((byte) 9),
|
||||||
|
WriteFile((byte) 10),
|
||||||
|
EndFile((byte) 11),
|
||||||
|
Create((byte) 12),
|
||||||
|
Delete((byte) 13),
|
||||||
|
Rename((byte) 14),
|
||||||
|
GetSpecialPathCount((byte) 15),
|
||||||
|
GetSpecialPath((byte) 16),
|
||||||
|
SelectFile((byte) 17),
|
||||||
|
CMD_UNKNOWN((byte) 255);
|
||||||
|
|
||||||
|
private final byte id;
|
||||||
|
|
||||||
|
GoldleafCmd(byte id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GoldleafCmd get(byte id) {
|
||||||
|
for(GoldleafCmd cmd : values()) {
|
||||||
|
if(cmd.id == id)
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
return CMD_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue