mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-11-26 12:12:02 +00:00
Update nsul_nxdt_patch.diff
This commit is contained in:
parent
ae6defb0e6
commit
d777183d9f
1 changed files with 22 additions and 282 deletions
|
@ -1,296 +1,36 @@
|
|||
diff --git a/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtUsbAbi1.java b/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtUsbAbi1.java
|
||||
index 9e5fd9b..fcd33a3 100644
|
||||
index dd2a1bc..4a3d7fd 100644
|
||||
--- a/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtUsbAbi1.java
|
||||
+++ b/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtUsbAbi1.java
|
||||
@@ -22,6 +22,7 @@ import nsusbloader.COM.USB.UsbErrorCodes;
|
||||
import nsusbloader.ModelControllers.ILogPrinter;
|
||||
import nsusbloader.NSLDataTypes.EMsgType;
|
||||
import org.usb4java.DeviceHandle;
|
||||
+import org.usb4java.DeviceDescriptor;
|
||||
import org.usb4java.LibUsb;
|
||||
|
||||
import java.io.*;
|
||||
@@ -40,9 +41,21 @@ class NxdtUsbAbi1 {
|
||||
private final boolean isWindows;
|
||||
private boolean isWindows10;
|
||||
|
||||
+ private short endpointMaxPacketSize = 0;
|
||||
@@ -111,6 +111,9 @@ class NxdtUsbAbi1 {
|
||||
DeviceInformation deviceInformation = DeviceInformation.build(handlerNS);
|
||||
NsUsbEndpointDescriptor endpointInDescriptor = deviceInformation.getSimplifiedDefaultEndpointDescriptorIn();
|
||||
this.endpointMaxPacketSize = endpointInDescriptor.getwMaxPacketSize();
|
||||
+
|
||||
private static final int NXDT_MAX_DIRECTIVE_SIZE = 0x1000;
|
||||
private static final int NXDT_FILE_CHUNK_SIZE = 0x800000;
|
||||
private static final int NXDT_FILE_PROPERTIES_MAX_NAME_LENGTH = 0x300;
|
||||
+ private static final int NXDT_USB_TIMEOUT = 5000;
|
||||
+
|
||||
+ private static final short NXDT_USB_FS_BCD_REVISION = 0x0110;
|
||||
+ private static final short NXDT_USB_FS_EP_MAX_PACKET_SIZE = 0x40;
|
||||
+
|
||||
+ private static final short NXDT_USB_HS_BCD_REVISION = 0x0200;
|
||||
+ private static final short NXDT_USB_HS_EP_MAX_PACKET_SIZE = 0x200;
|
||||
+
|
||||
+ private static final short NXDT_USB_SS_BCD_REVISION = 0x0300;
|
||||
+ private static final short NXDT_USB_SS_EP_MAX_PACKET_SIZE = 0x400;
|
||||
+ USBSTATUS_SUCCESS[8] = (byte)(endpointMaxPacketSize & 0xFF);
|
||||
+ USBSTATUS_SUCCESS[9] = (byte)((endpointMaxPacketSize >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
private static final byte ABI_VERSION = 1;
|
||||
private static final byte[] MAGIC_NXDT = { 0x4e, 0x58, 0x44, 0x54 };
|
||||
@@ -77,8 +90,6 @@ class NxdtUsbAbi1 {
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
- private static final long W_MAX_PACKET_SIZE = 0x200;
|
||||
-
|
||||
public NxdtUsbAbi1(DeviceHandle handler,
|
||||
ILogPrinter logPrinter,
|
||||
String saveToPath,
|
||||
@@ -174,7 +185,58 @@ class NxdtUsbAbi1 {
|
||||
private void readLoop(){
|
||||
@@ -187,16 +190,8 @@ class NxdtUsbAbi1 {
|
||||
writeUsb(USBSTATUS_UNSUPPORTED_ABI);
|
||||
throw new Exception("ABI v"+versionABI+" is not supported in current version.");
|
||||
}
|
||||
- writeUsb(USBSTATUS_SUCCESS);
|
||||
- replyToHandshake();
|
||||
- }
|
||||
- private void replyToHandshake() throws Exception{
|
||||
- // Send status response + endpoint max packet size
|
||||
- ByteBuffer buffer = ByteBuffer.allocate(USBSTATUS_SUCCESS.length + 2).order(ByteOrder.LITTLE_ENDIAN);
|
||||
- buffer.put(USBSTATUS_SUCCESS);
|
||||
- buffer.putShort(endpointMaxPacketSize);
|
||||
- byte[] response = buffer.array();
|
||||
-
|
||||
- writeUsb(response);
|
||||
+
|
||||
+ // Get endpoint max packet size
|
||||
+ getEndpointMaxPacketSize();
|
||||
+
|
||||
+ // Send status response + endpoint max packet size
|
||||
+ byte[] response = new byte[USBSTATUS_SUCCESS.length + 2];
|
||||
+ System.arraycopy(USBSTATUS_SUCCESS, 0, response, 0, USBSTATUS_SUCCESS.length);
|
||||
+ response[USBSTATUS_SUCCESS.length] = (byte)(endpointMaxPacketSize & 0xFF);
|
||||
+ response[USBSTATUS_SUCCESS.length + 1] = (byte)((endpointMaxPacketSize >> 8) & 0xFF);
|
||||
+
|
||||
+ writeUsb(response);
|
||||
+ }
|
||||
+
|
||||
+ private void getEndpointMaxPacketSize() throws Exception{
|
||||
+ // Get device descriptor to determine the max packet size in use. We'll send it to the console.
|
||||
+ // We'll get the device descriptor instead of an endpoint descriptor because it's a non-blocking call (the device descriptor is cached in memory by usb4java).
|
||||
+ DeviceDescriptor deviceDescriptor = getDeviceDescriptor();
|
||||
+
|
||||
+ short bcdUsbRevision = deviceDescriptor.bcdUSB();
|
||||
+ byte usbRevisionUpper = (byte)((bcdUsbRevision >> 8) & 0xFF);
|
||||
+ byte usbRevisionLower = (byte)(bcdUsbRevision & 0xFF);
|
||||
+
|
||||
+ switch(bcdUsbRevision){
|
||||
+ case NXDT_USB_FS_BCD_REVISION: // USB 1.1 (Full Speed).
|
||||
+ endpointMaxPacketSize = NXDT_USB_FS_EP_MAX_PACKET_SIZE;
|
||||
+ break;
|
||||
+ case NXDT_USB_HS_BCD_REVISION: // USB 2.0 (High Speed).
|
||||
+ endpointMaxPacketSize = NXDT_USB_HS_EP_MAX_PACKET_SIZE;
|
||||
+ break;
|
||||
+ case NXDT_USB_SS_BCD_REVISION: // USB 3.0 (Super Speed).
|
||||
+ endpointMaxPacketSize = NXDT_USB_SS_EP_MAX_PACKET_SIZE;
|
||||
+ break;
|
||||
+ default:
|
||||
+ writeUsb(USBSTATUS_HOSTIOERROR);
|
||||
+ throw new Exception("Invalid BCD USB release number \""+usbRevisionUpper+"."+usbRevisionLower+"\" in device descriptor!");
|
||||
+ }
|
||||
+
|
||||
+ //logPrinter.print("USB revision: "+usbRevisionUpper+"."+usbRevisionLower+".", EMsgType.INFO);
|
||||
+ //logPrinter.print("Max packet size: "+endpointMaxPacketSize+" b.", EMsgType.INFO);
|
||||
+ }
|
||||
+
|
||||
+ private DeviceDescriptor getDeviceDescriptor() throws Exception{
|
||||
+ int result;
|
||||
+ DeviceDescriptor descriptor = new DeviceDescriptor();
|
||||
+
|
||||
+ result = LibUsb.getDeviceDescriptor(LibUsb.getDevice(handlerNS), descriptor);
|
||||
+ if (result != LibUsb.SUCCESS){
|
||||
+ writeUsb(USBSTATUS_HOSTIOERROR);
|
||||
+ throw new Exception("Failed to get device descriptor! Returned "+result+" ("+UsbErrorCodes.getErrCode(result)+").");
|
||||
+ }
|
||||
+
|
||||
+ return descriptor;
|
||||
+ writeUsb(USBSTATUS_SUCCESS);
|
||||
}
|
||||
|
||||
private void handleSendFileProperties(byte[] message) throws Exception{
|
||||
@@ -188,6 +250,8 @@ class NxdtUsbAbi1 {
|
||||
return;
|
||||
}
|
||||
|
||||
+ logPrinter.print("Receiving: '"+filename+"' ("+fileSize+" b)", EMsgType.INFO);
|
||||
+
|
||||
// If RomFs related
|
||||
if (isRomFs(filename)) {
|
||||
if (isWindows)
|
||||
@@ -198,7 +262,6 @@ class NxdtUsbAbi1 {
|
||||
createPath(filename);
|
||||
}
|
||||
else {
|
||||
- logPrinter.print("Receiving: '"+filename+"' ("+fileSize+" b)", EMsgType.INFO);
|
||||
filename = saveToPath + filename;
|
||||
}
|
||||
|
||||
@@ -222,13 +285,11 @@ class NxdtUsbAbi1 {
|
||||
if (fileSize == 0)
|
||||
return;
|
||||
|
||||
- if (isWindows10)
|
||||
- dumpFileOnWindowsTen(fileToDump, fileSize);
|
||||
- else
|
||||
- dumpFile(fileToDump, fileSize);
|
||||
+ dumpFile(fileToDump, fileSize);
|
||||
|
||||
writeUsb(USBSTATUS_SUCCESS);
|
||||
|
||||
+ //logPrinter.print("File transfer successfully finished!", EMsgType.INFO);
|
||||
}
|
||||
|
||||
private int getLEint(byte[] bytes, int fromOffset){
|
||||
@@ -258,63 +319,46 @@ class NxdtUsbAbi1 {
|
||||
}
|
||||
|
||||
private void dumpFile(File file, long size) throws Exception{
|
||||
- try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file, false))) {
|
||||
- byte[] readBuffer;
|
||||
- long received = 0;
|
||||
- int bufferSize;
|
||||
-
|
||||
- boolean zlt_expected = isAligned(size);
|
||||
-
|
||||
- while (received < size) {
|
||||
- readBuffer = readUsbFile();
|
||||
- bos.write(readBuffer);
|
||||
- bufferSize = readBuffer.length;
|
||||
- received += bufferSize;
|
||||
- logPrinter.updateProgress((received + bufferSize) / (size / 100.0) / 100.0);
|
||||
- }
|
||||
+ byte[] readBuffer;
|
||||
+ long received = 0;
|
||||
+ int chunkSize = NXDT_FILE_CHUNK_SIZE;
|
||||
|
||||
- if (zlt_expected) {
|
||||
- logPrinter.print("Finishing with ZLT packet request", EMsgType.INFO);
|
||||
- readUsbFile();
|
||||
- }
|
||||
- } finally {
|
||||
- logPrinter.updateProgress(1.0);
|
||||
- }
|
||||
- }
|
||||
+ boolean zltExpected = isAligned(size, endpointMaxPacketSize);
|
||||
+ //logPrinter.print("ZLT packet expected: "+zlt_expected, EMsgType.INFO);
|
||||
|
||||
- // @see https://bugs.openjdk.java.net/browse/JDK-8146538
|
||||
- private void dumpFileOnWindowsTen(File file, long size) throws Exception{
|
||||
- FileOutputStream fos = new FileOutputStream(file, true);
|
||||
+ FileOutputStream fos = new FileOutputStream(file, false);
|
||||
+ FileDescriptor fd = fos.getFD();
|
||||
|
||||
try (BufferedOutputStream bos = new BufferedOutputStream(fos)) {
|
||||
- FileDescriptor fd = fos.getFD();
|
||||
- byte[] readBuffer;
|
||||
- long received = 0;
|
||||
- int bufferSize;
|
||||
-
|
||||
- boolean zlt_expected = isAligned(size);
|
||||
+ while(true){
|
||||
+ // Check if we aren't expecting a ZLT packet and the whole file has already been received.
|
||||
+ if (!zltExpected && received >= size) break;
|
||||
+
|
||||
+ // Update chunk size if needed.
|
||||
+ if (received < size && (long)chunkSize > (size - received)) chunkSize = (int)(size - received);
|
||||
+
|
||||
+ // Read current chunk. Don't attempt to read more than we're supposed to by allocating a buffer with a size equal to the current chunk size.
|
||||
+ // Immediately check if we're dealing with a ZLT packet afterwards.
|
||||
+ readBuffer = readUsbFile(chunkSize);
|
||||
+ if (readBuffer == null || readBuffer.length == 0)
|
||||
+ {
|
||||
+ //logPrinter.print("ZLT packet received.", EMsgType.INFO);
|
||||
+ if (zltExpected && received >= size) break;
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- while (received < size) {
|
||||
- readBuffer = readUsbFile();
|
||||
bos.write(readBuffer);
|
||||
- fd.sync(); // Fixes flushing under Windows (unharmful for other OS)
|
||||
- bufferSize = readBuffer.length;
|
||||
- received += bufferSize;
|
||||
+ if (isWindows10) fd.sync(); // Fixes flushing under Windows 10. See https://bugs.openjdk.java.net/browse/JDK-8146538
|
||||
+ received += readBuffer.length;
|
||||
|
||||
- logPrinter.updateProgress((received + bufferSize) / (size / 100.0) / 100.0);
|
||||
+ //logPrinter.print("Received "+readBuffer.length+" b. Got thus far: "+received+" b.", EMsgType.INFO);
|
||||
+ logPrinter.updateProgress((double)received / (double)size);
|
||||
}
|
||||
-
|
||||
- if (zlt_expected) {
|
||||
- logPrinter.print("Finishing with ZLT packet request", EMsgType.INFO);
|
||||
- readUsbFile();
|
||||
- }
|
||||
- } finally {
|
||||
- logPrinter.updateProgress(1.0);
|
||||
}
|
||||
}
|
||||
/** Handle Zero-length terminator **/
|
||||
- private boolean isAligned(long size){
|
||||
- return ((size & (W_MAX_PACKET_SIZE - 1)) == 0);
|
||||
+ private boolean isAligned(long size, long alignment){
|
||||
+ return ((size & (alignment - 1)) == 0);
|
||||
}
|
||||
|
||||
/** Sending any byte array to USB device **/
|
||||
@@ -326,7 +370,7 @@ class NxdtUsbAbi1 {
|
||||
if ( parent.isCancelled() )
|
||||
throw new InterruptedException("Execution interrupted");
|
||||
|
||||
- int result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, 5050);
|
||||
+ int result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, NXDT_USB_TIMEOUT);
|
||||
|
||||
if (result == LibUsb.SUCCESS) {
|
||||
if (writeBufTransferred.get() == message.length)
|
||||
@@ -338,7 +382,6 @@ class NxdtUsbAbi1 {
|
||||
throw new Exception("Data transfer issue [write]" +
|
||||
"\n Returned: " + UsbErrorCodes.getErrCode(result) +
|
||||
"\n (execution stopped)");
|
||||
-
|
||||
}
|
||||
/**
|
||||
* Reading what USB device responded (command).
|
||||
@@ -374,29 +417,25 @@ class NxdtUsbAbi1 {
|
||||
* @return byte array if data read successful
|
||||
* 'null' if read failed
|
||||
* */
|
||||
- private byte[] readUsbFile() throws Exception{
|
||||
- ByteBuffer readBuffer = ByteBuffer.allocateDirect(NXDT_FILE_CHUNK_SIZE);
|
||||
+ private byte[] readUsbFile(int chunkSize) throws Exception{
|
||||
+ ByteBuffer readBuffer = ByteBuffer.allocateDirect(chunkSize);
|
||||
IntBuffer readBufTransferred = IntBuffer.allocate(1);
|
||||
- int result;
|
||||
- int countDown = 0;
|
||||
- while (! parent.isCancelled() && countDown < 5) {
|
||||
- result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000);
|
||||
|
||||
- switch (result) {
|
||||
- case LibUsb.SUCCESS:
|
||||
- int trans = readBufTransferred.get();
|
||||
- byte[] receivedBytes = new byte[trans];
|
||||
- readBuffer.get(receivedBytes);
|
||||
- return receivedBytes;
|
||||
- case LibUsb.ERROR_TIMEOUT:
|
||||
- countDown++;
|
||||
- break;
|
||||
- default:
|
||||
- throw new Exception("Data transfer issue [read file]" +
|
||||
- "\n Returned: " + UsbErrorCodes.getErrCode(result)+
|
||||
- "\n (execution stopped)");
|
||||
- }
|
||||
+ if ( parent.isCancelled() )
|
||||
+ throw new InterruptedException();
|
||||
+
|
||||
+ int result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, NXDT_USB_TIMEOUT);
|
||||
+
|
||||
+ switch (result) {
|
||||
+ case LibUsb.SUCCESS:
|
||||
+ int trans = readBufTransferred.get();
|
||||
+ byte[] receivedBytes = new byte[trans];
|
||||
+ readBuffer.get(receivedBytes);
|
||||
+ return receivedBytes;
|
||||
+ default:
|
||||
+ throw new Exception("Data transfer issue [read file]" +
|
||||
+ "\n Returned: " + UsbErrorCodes.getErrCode(result)+
|
||||
+ "\n (execution stopped)");
|
||||
}
|
||||
- throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/resources/NSLMain.fxml b/src/main/resources/NSLMain.fxml
|
||||
index a2d42d6..9114c3d 100644
|
||||
--- a/src/main/resources/NSLMain.fxml
|
||||
|
|
Loading…
Reference in a new issue