Small NXDT-code refactoring

This commit is contained in:
Dmitry Isaenko 2020-10-29 16:54:41 +03:00
parent 050982f8ea
commit fbd5ec970b
3 changed files with 112 additions and 74 deletions

View file

@ -0,0 +1,28 @@
/*
Copyright 2019-2020 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.Utilities.nxdumptool;
class NxdtHostIOException extends Exception {
NxdtHostIOException(){
super();
}
NxdtHostIOException(String message){
super(message);
}
}

View file

@ -0,0 +1,28 @@
/*
Copyright 2019-2020 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.Utilities.nxdumptool;
class NxdtMalformedException extends Exception {
NxdtMalformedException(){
super();
}
NxdtMalformedException(String message){
super(message);
}
}

View file

@ -201,26 +201,18 @@ class NxdtUsbAbi1 {
} }
private void handleSendFileProperties(byte[] message) throws Exception{ private void handleSendFileProperties(byte[] message) throws Exception{
try {
final long fullSize = getLElong(message, 0x10); final long fullSize = getLElong(message, 0x10);
final int fileNameLen = getLEint(message, 0x18); final int fileNameLen = getLEint(message, 0x18);
final int headerSize = getLEint(message, 0x1C); final int headerSize = getLEint(message, 0x1C);
checkFileNameLen(fileNameLen); // In case of negative value we should better handle it before String constructor throws error
if (checkFileNameLen(fileNameLen)) // In case of negative value we should better handle it before String constructor throws error
return;
String filename = new String(message, 0x20, fileNameLen, StandardCharsets.UTF_8); String filename = new String(message, 0x20, fileNameLen, StandardCharsets.UTF_8);
String absoluteFilePath = getAbsoluteFilePath(filename); String absoluteFilePath = getAbsoluteFilePath(filename);
File fileToDump = new File(absoluteFilePath); File fileToDump = new File(absoluteFilePath);
if (checkSizes(fullSize, headerSize)) checkSizes(fullSize, headerSize);
return; createPath(absoluteFilePath);
checkFileSystem(fileToDump, fullSize);
if (createPath(absoluteFilePath))
return;
if (checkFileSystem(fileToDump, fullSize))
return;
if (headerSize > 0){ // if NSP if (headerSize > 0){ // if NSP
logPrinter.print("Receiving NSP file: '"+filename+"' ("+formatByteSize(fullSize)+")", EMsgType.PASS); logPrinter.print("Receiving NSP file: '"+filename+"' ("+formatByteSize(fullSize)+")", EMsgType.PASS);
@ -238,63 +230,56 @@ class NxdtUsbAbi1 {
return; return;
if (isNspTransfer()) if (isNspTransfer())
dumpNspFile(nspFile, fullSize); dumpNspFile(fullSize);
else else
dumpFile(fileToDump, fullSize); dumpFile(fileToDump, fullSize);
writeUsb(USBSTATUS_SUCCESS); writeUsb(USBSTATUS_SUCCESS);
} }
private boolean checkFileNameLen(int fileNameLen) throws Exception{ catch (NxdtMalformedException malformed){
logPrinter.print(malformed.getMessage(), EMsgType.FAIL);
writeUsb(USBSTATUS_MALFORMED_REQUEST);
}
catch (NxdtHostIOException ioException){
logPrinter.print(ioException.getMessage(), EMsgType.FAIL);
writeUsb(USBSTATUS_HOSTIOERROR);
}
}
private void checkFileNameLen(int fileNameLen) throws NxdtMalformedException{
if (fileNameLen <= 0 || fileNameLen > NXDT_FILE_PROPERTIES_MAX_NAME_LENGTH){ if (fileNameLen <= 0 || fileNameLen > NXDT_FILE_PROPERTIES_MAX_NAME_LENGTH){
logPrinter.print("Invalid filename length!", EMsgType.FAIL); throw new NxdtMalformedException("Invalid filename length!");
writeUsb(USBSTATUS_MALFORMED_REQUEST);
return true;
} }
return false;
} }
private boolean checkSizes(long fileSize, int headerSize) throws Exception{ private void checkSizes(long fileSize, int headerSize) throws Exception{
if (headerSize >= fileSize){ if (headerSize >= fileSize){
logPrinter.print(String.format("File size (%d) should not be less or equal to header size (%d)!", fileSize, headerSize), EMsgType.FAIL);
resetNsp(); resetNsp();
writeUsb(USBSTATUS_MALFORMED_REQUEST); throw new NxdtMalformedException(String.format("File size (%d) should not be less or equal to header size (%d)!", fileSize, headerSize));
return true;
} }
if (fileSize < 0){ // It's possible to have files of zero-length, so only less is the problem if (fileSize < 0){ // It's possible to have files of zero-length, so only less is the problem
logPrinter.print("File size should not be less then zero!", EMsgType.FAIL);
resetNsp(); resetNsp();
writeUsb(USBSTATUS_MALFORMED_REQUEST); throw new NxdtMalformedException("File size should not be less then zero!");
return true;
} }
return false;
} }
private boolean checkFileSystem(File fileToDump, long fileSize) throws Exception{ private void checkFileSystem(File fileToDump, long fileSize) throws Exception{
// Check if enough space // Check if enough space
if (fileToDump.getParentFile().getFreeSpace() <= fileSize){ if (fileToDump.getParentFile().getFreeSpace() <= fileSize){
writeUsb(USBSTATUS_HOSTIOERROR); throw new NxdtHostIOException("Not enough space on selected volume. Need: "+fileSize+
logPrinter.print("Not enough space on selected volume. Need: "+fileSize+ " while available: "+fileToDump.getParentFile().getFreeSpace());
" while available: "+fileToDump.getParentFile().getFreeSpace(), EMsgType.FAIL);
return true;
} }
// Check if FS is NOT read-only // Check if FS is NOT read-only
if (! (fileToDump.canWrite() || fileToDump.createNewFile()) ){ if (! (fileToDump.canWrite() || fileToDump.createNewFile()) ){
writeUsb(USBSTATUS_HOSTIOERROR); throw new NxdtHostIOException("Unable to write into selected volume: "+fileToDump.getAbsolutePath());
logPrinter.print("Unable to write into selected volume: "+fileToDump.getAbsolutePath(), EMsgType.FAIL);
return true;
} }
return false;
} }
private void createNewNsp(String filename, int headerSize, long fileSize, File fileToDump) throws Exception{ private void createNewNsp(String filename, int headerSize, long fileSize, File fileToDump) throws NxdtHostIOException{
try { try {
nspFile = new NxdtNspFile(filename, headerSize, fileSize, fileToDump); nspFile = new NxdtNspFile(filename, headerSize, fileSize, fileToDump);
writeUsb(USBSTATUS_SUCCESS);
} }
catch (Exception e){ catch (Exception e){
logPrinter.print("Unable to create new file for: "+filename+" :"+e.getMessage(), EMsgType.FAIL);
e.printStackTrace(); e.printStackTrace();
writeUsb(USBSTATUS_HOSTIOERROR); throw new NxdtHostIOException("Unable to create new file for: "+filename+" :"+e.getMessage());
return;
} }
writeUsb(USBSTATUS_SUCCESS);
} }
private int getLEint(byte[] bytes, int fromOffset){ private int getLEint(byte[] bytes, int fromOffset){
return ByteBuffer.wrap(bytes, fromOffset, 0x4).order(ByteOrder.LITTLE_ENDIAN).getInt(); return ByteBuffer.wrap(bytes, fromOffset, 0x4).order(ByteOrder.LITTLE_ENDIAN).getInt();
@ -316,16 +301,13 @@ class NxdtUsbAbi1 {
return filename.startsWith("/"); return filename.startsWith("/");
} }
private boolean createPath(String path) throws Exception{ private void createPath(String path) throws Exception{
try { try {
Path folderForTheFile = Paths.get(path).getParent(); Path folderForTheFile = Paths.get(path).getParent();
Files.createDirectories(folderForTheFile); Files.createDirectories(folderForTheFile);
return false;
} }
catch (Exception e){ catch (Exception e){
logPrinter.print("Unable to create dir(s) for file "+path, EMsgType.FAIL); throw new NxdtHostIOException("Unable to create dir(s) for file '"+path+"':"+e.getMessage());
writeUsb(USBSTATUS_HOSTIOERROR);
return true;
} }
} }
@ -360,12 +342,12 @@ class NxdtUsbAbi1 {
} }
} }
private void dumpNspFile(NxdtNspFile nsp, long size) throws Exception{ private void dumpNspFile(long size) throws Exception{
FileOutputStream fos = new FileOutputStream(nsp.getFile(), true); FileOutputStream fos = new FileOutputStream(nspFile.getFile(), true);
long nspSize = nsp.getFullSize(); long nspSize = nspFile.getFullSize();
try (BufferedOutputStream bos = new BufferedOutputStream(fos)) { try (BufferedOutputStream bos = new BufferedOutputStream(fos)) {
long nspRemainingSize = nsp.getNspRemainingSize(); long nspRemainingSize = nspFile.getNspRemainingSize();
FileDescriptor fd = fos.getFD(); FileDescriptor fd = fos.getFD();
byte[] readBuffer; byte[] readBuffer;
@ -390,7 +372,7 @@ class NxdtUsbAbi1 {
if (isWindows10) if (isWindows10)
fd.sync(); fd.sync();
nspRemainingSize -= (lastChunkSize - 1); nspRemainingSize -= (lastChunkSize - 1);
nsp.setNspRemainingSize(nspRemainingSize); nspFile.setNspRemainingSize(nspRemainingSize);
} }
} }
@ -398,6 +380,7 @@ class NxdtUsbAbi1 {
final int headerSize = getLEint(message, 0x8); final int headerSize = getLEint(message, 0x8);
NxdtNspFile nsp = nspFile; NxdtNspFile nsp = nspFile;
resetNsp(); resetNsp();
logPrinter.updateProgress(1.0);
if (nsp == null) { if (nsp == null) {
writeUsb(USBSTATUS_MALFORMED_REQUEST); writeUsb(USBSTATUS_MALFORMED_REQUEST);
@ -423,7 +406,6 @@ class NxdtUsbAbi1 {
raf.write(headerData); raf.write(headerData);
} }
logPrinter.print("NSP file: '"+nsp.getName()+"' successfully received!", EMsgType.PASS); logPrinter.print("NSP file: '"+nsp.getName()+"' successfully received!", EMsgType.PASS);
logPrinter.updateProgress(1.0);
writeUsb(USBSTATUS_SUCCESS); writeUsb(USBSTATUS_SUCCESS);
} }
private void resetNsp(){ private void resetNsp(){