1
0
Fork 0
mirror of https://github.com/DarkMatterCore/nxdumptool.git synced 2024-09-19 13:33:25 +01:00
nxdumptool/nsul_nxdt_patch.diff
2020-08-17 17:30:47 -04:00

313 lines
19 KiB
Diff

diff --git a/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtUsbAbi1.java b/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtUsbAbi1.java
index 9e5fd9b..fcd33a3 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;
+
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;
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 {
writeUsb(USBSTATUS_UNSUPPORTED_ABI);
throw new Exception("ABI v"+versionABI+" is not supported in current version.");
}
- writeUsb(USBSTATUS_SUCCESS);
+
+ // 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;
}
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
+++ b/src/main/resources/NSLMain.fxml
@@ -71,12 +71,12 @@ Steps to roll NXDT functionality back:
<SVGPath content="M9,22A1,1 0 0,1 8,21V18H4A2,2 0 0,1 2,16V4C2,2.89 2.9,2 4,2H20A2,2 0 0,1 22,4V16A2,2 0 0,1 20,18H13.9L10.2,21.71C10,21.9 9.75,22 9.5,22V22H9M10,16V19.08L13.08,16H20V4H4V16H10M17,11H15V9H17V11M13,11H11V9H13V11M9,11H7V9H9V11Z" />
</graphic>
</Tab>
- <Tab closable="false" disable="true">
+ <Tab closable="false" disable="false">
<content>
<fx:include fx:id="NXDTab" source="NXDTab.fxml" VBox.vgrow="ALWAYS" />
</content>
<graphic>
- <SVGPath content="M 7 0 L 0 4 C -0.02484618 7.6613523 4.6259293e-18 7.3229335 0 10.984375 C 0 10.993031 0.015625 7 0.015625 8 L 13 0 L 7 0 z M 17.966797 6.46875 L 17.966797 10.673828 C 17.715715 10.211268 17.396999 9.8685131 17.011719 9.6464844 C 16.630766 9.4198301 16.171566 9.3066406 15.634766 9.3066406 C 14.755976 9.3066406 14.040441 9.682293 13.486328 10.431641 C 12.936542 11.180987 12.660156 12.165561 12.660156 13.386719 C 12.660156 14.607877 12.936542 15.59245 13.486328 16.341797 C 14.040441 17.091144 14.755976 17.466797 15.634766 17.466797 C 16.171566 17.466797 16.630766 17.354841 17.011719 17.132812 C 17.396999 16.90616 17.715715 16.562169 17.966797 16.099609 L 17.966797 17.265625 L 19.160156 17.265625 L 19.160156 6.46875 L 17.966797 6.46875 z M 20.572266 7.3652344 L 20.572266 9.5546875 L 19.800781 9.5546875 L 19.800781 10.539062 L 20.572266 10.539062 L 20.572266 14.724609 C 20.572266 15.688531 20.728201 16.353495 21.037109 16.720703 C 21.346016 17.083321 21.906432 17.265625 22.71875 17.265625 L 23.800781 17.265625 L 23.800781 16.205078 L 22.71875 16.205078 C 22.280176 16.205078 21.98867 16.114559 21.84375 15.935547 C 21.702645 15.756534 21.630859 15.353453 21.630859 14.724609 L 21.630859 10.539062 L 23.800781 10.539062 L 23.800781 9.5546875 L 21.630859 9.5546875 L 21.630859 7.3652344 L 20.572266 7.3652344 z M 3.6386719 9.3066406 C 3.1397071 9.3066406 2.6982722 9.4230165 2.3144531 9.6542969 C 1.9348986 9.8855772 1.6037331 10.233986 1.3222656 10.701172 L 1.3222656 9.4941406 L 0.13867188 9.4941406 L 0.13867188 17.265625 L 1.3222656 17.265625 L 1.3222656 12.873047 C 1.3222656 12.114448 1.5062865 11.515605 1.8730469 11.076172 C 2.2398077 10.636739 2.7395664 10.417969 3.375 10.417969 C 3.9038175 10.417969 4.3000442 10.599421 4.5644531 10.964844 C 4.8288618 11.330266 4.9609375 11.881715 4.9609375 12.617188 L 4.9609375 17.265625 L 6.1386719 17.265625 L 6.1386719 12.576172 C 6.1386719 11.503031 5.9280604 10.691072 5.5058594 10.140625 C 5.0836585 9.5855522 4.4617505 9.3066406 3.6386719 9.3066406 z M 6.984375 9.4941406 L 9.2207031 13.199219 L 6.7773438 17.265625 L 7.9960938 17.265625 L 9.828125 14.212891 L 11.658203 17.265625 L 12.878906 17.265625 L 10.484375 13.275391 L 12.759766 9.4941406 L 11.541016 9.4941406 L 9.8730469 12.263672 L 8.2050781 9.4941406 L 6.984375 9.4941406 z M 15.927734 10.375 C 16.559769 10.375 17.056283 10.643118 17.419922 11.179688 C 17.783557 11.711631 17.966797 12.447722 17.966797 13.386719 C 17.966797 14.325715 17.783557 15.06304 17.419922 15.599609 C 17.056283 16.131553 16.559769 16.398437 15.927734 16.398438 C 15.295699 16.398438 14.797233 16.131553 14.433594 15.599609 C 14.074286 15.06304 13.894531 14.325715 13.894531 13.386719 C 13.894531 12.447722 14.074286 11.711631 14.433594 11.179688 C 14.797233 10.643118 15.295699 10.375 15.927734 10.375 z M 24 18.400391 C 24.0056 21.386719 23.984375 22 23.984375 19 L 15 23.982422 L 23.984375 23.996094 C 23.993075 23.996094 24 23.990492 24 23.982422 L 24 18.400391 z" visible="false" />
+ <SVGPath content="M 7 0 L 0 4 C -0.02484618 7.6613523 4.6259293e-18 7.3229335 0 10.984375 C 0 10.993031 0.015625 7 0.015625 8 L 13 0 L 7 0 z M 17.966797 6.46875 L 17.966797 10.673828 C 17.715715 10.211268 17.396999 9.8685131 17.011719 9.6464844 C 16.630766 9.4198301 16.171566 9.3066406 15.634766 9.3066406 C 14.755976 9.3066406 14.040441 9.682293 13.486328 10.431641 C 12.936542 11.180987 12.660156 12.165561 12.660156 13.386719 C 12.660156 14.607877 12.936542 15.59245 13.486328 16.341797 C 14.040441 17.091144 14.755976 17.466797 15.634766 17.466797 C 16.171566 17.466797 16.630766 17.354841 17.011719 17.132812 C 17.396999 16.90616 17.715715 16.562169 17.966797 16.099609 L 17.966797 17.265625 L 19.160156 17.265625 L 19.160156 6.46875 L 17.966797 6.46875 z M 20.572266 7.3652344 L 20.572266 9.5546875 L 19.800781 9.5546875 L 19.800781 10.539062 L 20.572266 10.539062 L 20.572266 14.724609 C 20.572266 15.688531 20.728201 16.353495 21.037109 16.720703 C 21.346016 17.083321 21.906432 17.265625 22.71875 17.265625 L 23.800781 17.265625 L 23.800781 16.205078 L 22.71875 16.205078 C 22.280176 16.205078 21.98867 16.114559 21.84375 15.935547 C 21.702645 15.756534 21.630859 15.353453 21.630859 14.724609 L 21.630859 10.539062 L 23.800781 10.539062 L 23.800781 9.5546875 L 21.630859 9.5546875 L 21.630859 7.3652344 L 20.572266 7.3652344 z M 3.6386719 9.3066406 C 3.1397071 9.3066406 2.6982722 9.4230165 2.3144531 9.6542969 C 1.9348986 9.8855772 1.6037331 10.233986 1.3222656 10.701172 L 1.3222656 9.4941406 L 0.13867188 9.4941406 L 0.13867188 17.265625 L 1.3222656 17.265625 L 1.3222656 12.873047 C 1.3222656 12.114448 1.5062865 11.515605 1.8730469 11.076172 C 2.2398077 10.636739 2.7395664 10.417969 3.375 10.417969 C 3.9038175 10.417969 4.3000442 10.599421 4.5644531 10.964844 C 4.8288618 11.330266 4.9609375 11.881715 4.9609375 12.617188 L 4.9609375 17.265625 L 6.1386719 17.265625 L 6.1386719 12.576172 C 6.1386719 11.503031 5.9280604 10.691072 5.5058594 10.140625 C 5.0836585 9.5855522 4.4617505 9.3066406 3.6386719 9.3066406 z M 6.984375 9.4941406 L 9.2207031 13.199219 L 6.7773438 17.265625 L 7.9960938 17.265625 L 9.828125 14.212891 L 11.658203 17.265625 L 12.878906 17.265625 L 10.484375 13.275391 L 12.759766 9.4941406 L 11.541016 9.4941406 L 9.8730469 12.263672 L 8.2050781 9.4941406 L 6.984375 9.4941406 z M 15.927734 10.375 C 16.559769 10.375 17.056283 10.643118 17.419922 11.179688 C 17.783557 11.711631 17.966797 12.447722 17.966797 13.386719 C 17.966797 14.325715 17.783557 15.06304 17.419922 15.599609 C 17.056283 16.131553 16.559769 16.398437 15.927734 16.398438 C 15.295699 16.398438 14.797233 16.131553 14.433594 15.599609 C 14.074286 15.06304 13.894531 14.325715 13.894531 13.386719 C 13.894531 12.447722 14.074286 11.711631 14.433594 11.179688 C 14.797233 10.643118 15.295699 10.375 15.927734 10.375 z M 24 18.400391 C 24.0056 21.386719 23.984375 22 23.984375 19 L 15 23.982422 L 23.984375 23.996094 C 23.993075 23.996094 24 23.990492 24 23.982422 L 24 18.400391 z" visible="true" />
</graphic>
</Tab>
</tabs>