diff --git a/src/de/mas/wupclient/Starter.java b/src/de/mas/wupclient/Starter.java index 87c2120..38b3651 100644 --- a/src/de/mas/wupclient/Starter.java +++ b/src/de/mas/wupclient/Starter.java @@ -6,13 +6,15 @@ import de.mas.wupclient.client.WUPClient; import de.mas.wupclient.client.operations.FSAOperations; import de.mas.wupclient.client.operations.UtilOperations; import de.mas.wupclient.client.utils.FEntry; +import de.mas.wupclient.client.utils.Logger; public class Starter { public static void main(String args[]){ WUPClient w = new WUPClient("192.168.0.035"); try { UtilOperations util = UtilOperations.UtilOperationsFactory(w); - FSAOperations fsa = FSAOperations.FSAOperationsFactory(w); + FSAOperations fsa = FSAOperations.FSAOperationsFactory(w); + util.ls(); //List result = util.ls("/vol/storage_mlc01/",true); printLSRecursive("/vol/storage_mlc01/sys/title/00050010/1004c200/",util); w.FSA_Close(w.get_fsa_handle()); @@ -26,10 +28,10 @@ public class Starter { List result = util.ls(path,true); for(FEntry entry : result){ if(entry.isFile()){ - System.out.println(path + entry.getFilename()); + Logger.log(path + entry.getFilename()); }else{ String newPath = path + entry.getFilename() + "/"; - System.out.println(newPath); + Logger.log(newPath); printLSRecursive(newPath, util); } } diff --git a/src/de/mas/wupclient/Utils.java b/src/de/mas/wupclient/Utils.java deleted file mode 100644 index c4fdede..0000000 --- a/src/de/mas/wupclient/Utils.java +++ /dev/null @@ -1,30 +0,0 @@ -package de.mas.wupclient; - -import java.util.Arrays; - -public class Utils { - public static String ByteArrayToString(byte[] ba) - { - if(ba == null) return null; - StringBuilder hex = new StringBuilder(ba.length * 2); - for(byte b : ba){ - hex.append(String.format("%02X", b)); - } - return hex.toString(); - } - - public static T[] concatAll(T[] first, T[]... rest) { - int totalLength = first.length; - for (T[] array : rest) { - totalLength += array.length; - } - T[] result = Arrays.copyOf(first, totalLength); - int offset = first.length; - for (T[] array : rest) { - System.arraycopy(array, 0, result, offset, array.length); - offset += array.length; - } - return result; - } - -} diff --git a/src/de/mas/wupclient/client/WUPClient.java b/src/de/mas/wupclient/client/WUPClient.java index 3f18635..74cab4f 100644 --- a/src/de/mas/wupclient/client/WUPClient.java +++ b/src/de/mas/wupclient/client/WUPClient.java @@ -8,6 +8,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; +import de.mas.wupclient.client.utils.Logger; import de.mas.wupclient.client.utils.Result; public class WUPClient { @@ -30,9 +31,9 @@ public class WUPClient { destByteBuffer.putInt(command); destByteBuffer.put(data); try { - outToServer.write(destByteBuffer.array()); - + outToServer.write(destByteBuffer.array()); } catch (IOException e) { + Logger.logErr("send failed"); e.printStackTrace(); } destByteBuffer.clear(); @@ -53,7 +54,7 @@ public class WUPClient { if(result.getResultValue() == 0){ return result.getData(); }else{ - System.out.println("Read error: " + result.getResultValue()); + Logger.logErr("Read error: " + result.getResultValue()); return null; } } @@ -68,7 +69,7 @@ public class WUPClient { if(result.getResultValue() == 0){ return result.getResultValue(); }else{ - System.out.println("write error: " + result.getResultValue()); + Logger.logErr("write error: " + result.getResultValue()); return -1; } } @@ -83,14 +84,12 @@ public class WUPClient { Result result = send(2,destByteBuffer.array()); if(result.getResultValue() == 0){ - destByteBuffer.clear(); - destByteBuffer = ByteBuffer.allocate(result.getData().length); - destByteBuffer.rewind(); + destByteBuffer = ByteBuffer.allocate(0x04); destByteBuffer.order(ByteOrder.BIG_ENDIAN); - destByteBuffer.put(result.getData()); + destByteBuffer.put(Arrays.copyOfRange(result.getData(), 0, 0x04)); return destByteBuffer.getInt(0); }else{ - System.out.println("svc error: " + result.getResultValue()); + Logger.logErr("svc error: " + result.getResultValue()); return -1; } } @@ -110,7 +109,7 @@ public class WUPClient { if(result.getResultValue() == 0){ return result.getResultValue(); }else{ - System.out.println("memcpy error: " + result.getResultValue()); + Logger.logErr("memcpy error: " + result.getResultValue()); return -1; } } @@ -121,29 +120,19 @@ public class WUPClient { if(size == 0){ return 0; } - if(align == 0){ - int[] buffer = new int[2]; - buffer[0] = 0xCAFF; - buffer[1] = size; - int result = svc(0x27, buffer); + if(align == 0){ + int result = svc(0x27, new int[] {0xCAFF,size}); return result; }else{ - int[] buffer = new int[3]; - buffer[0] = 0xCAFF; - buffer[1] = size; - buffer[2] = align; - int result = svc(0x28, buffer); + int result = svc(0x28, new int[] {0xCAFF,size,align}); return result; } } public int free(int address) throws IOException{ if(address == 0){ return 0; - } - int[] buffer = new int[2]; - buffer[0] = 0xCAFF; - buffer[1] = address; - return svc(0x29, buffer); + } + return svc(0x29, new int[] {0xCAFF,address}); } public int load_buffer(byte[] data) throws IOException{ @@ -173,20 +162,13 @@ public class WUPClient { } public int open(String device, int mode) throws IOException{ - int address = load_string(device); - - int[] buffer = new int[2]; - buffer[0] = address; - buffer[1] = mode; - - int handle = svc(0x33, buffer); + int address = load_string(device); + int handle = svc(0x33, new int[] {address,mode}); free(address); return handle; } public int close(int handle) throws IOException{ - int[] buffer = new int[1]; - buffer[0] = handle; - return svc(0x34,buffer); + return svc(0x34,new int[]{handle}); } public int get_fsa_handle() throws IOException{ @@ -197,35 +179,28 @@ public class WUPClient { } public int FSA_Close(int handle) throws IOException{ - int[] buffer = new int[1]; - buffer[0] = handle; - int result = svc(0x34, buffer); + int result = svc(0x34, new int[]{handle}); if(result == 0){ setFsaHandle(-1); + }else{ + Logger.logErr("FSA_Close: failed"); } return result; } - - public byte[] intToByteArray(int number){ - ByteBuffer destByteBuffer = ByteBuffer.allocate(4); - destByteBuffer.order(ByteOrder.BIG_ENDIAN); - destByteBuffer.putInt(number); - return destByteBuffer.array(); - } private Socket createSocket(String ip) { Socket clientSocket = null; try { clientSocket = new Socket(ip, 1337); } catch (UnknownHostException e) { - System.err.println("Unkown Host"); + Logger.logErr("Unkown Host"); e.printStackTrace(); } catch (IOException e) { - System.err.println("IO Error Host"); + Logger.logErr("IO Error Host"); e.printStackTrace(); } setSocket(clientSocket); - System.out.println("Connected"); + Logger.log("Connected"); return clientSocket; } diff --git a/src/de/mas/wupclient/client/operations/FSAOperations.java b/src/de/mas/wupclient/client/operations/FSAOperations.java index 5b0732f..f041f61 100644 --- a/src/de/mas/wupclient/client/operations/FSAOperations.java +++ b/src/de/mas/wupclient/client/operations/FSAOperations.java @@ -3,12 +3,14 @@ package de.mas.wupclient.client.operations; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; import de.mas.wupclient.client.WUPClient; import de.mas.wupclient.client.utils.FEntry; import de.mas.wupclient.client.utils.Result; +import de.mas.wupclient.client.utils.Utils; public class FSAOperations extends Operations { private static Map instances = new HashMap<>(); @@ -34,58 +36,39 @@ public class FSAOperations extends Operations { this.ioctl = ioctl; } - public Result FSA_ReadDir(int fsa_handle, int dirhandle) throws IOException { - byte[] inbuffer = new byte[0x520]; - System.arraycopy(getClient().intToByteArray(dirhandle), 0, inbuffer, 4, 4); - Result res = ioctl.ioctl(fsa_handle, 0x0B, inbuffer, 0x293); - - byte[] rawdata = res.getData(); - byte[] data = new byte[rawdata.length-4]; - System.arraycopy(rawdata, 4, data, 0, rawdata.length-4); - byte[] unknowndata = new byte[0x64]; - System.arraycopy(data, 0, unknowndata, 0, 0x64); - - int i = 0; - while(data[0x64 + i] != 0 && (i +0x64) < data.length){ - i++; - } - byte[] stringData = new byte[i]; - boolean isFile = false; - if((unknowndata[0] & 0x01) == 1){ - isFile = true; - } - System.arraycopy(data, 0x64, stringData, 0, i); - //System.out.println(new String(stringData, "UTF-8") + ":" + Integer.toBinaryString(unknowndata[0] & 0x01)); - if(res.getResultValue() == 0){ - return new Result(res.getResultValue(),new FEntry(new String(stringData, "UTF-8"),isFile,unknowndata)); - }else{ - return new Result(res.getResultValue(),null); - } - } - public Result FSA_OpenDir(int handle, String path) throws IOException{ byte[] inbuffer = new byte[0x520]; - byte[] string = path.getBytes(); - - System.arraycopy(string , 0, inbuffer, 4, string.length); - inbuffer[string.length + 4] = 0; + Utils.writeNullTerminatedStringToByteArray(inbuffer, path, 0x04); Result res = ioctl.ioctl(handle, 0x0A, inbuffer, 0x293); - byte[] data = res.getData(); - ByteBuffer destByteBuffer = ByteBuffer.allocate(data.length); - destByteBuffer.order(ByteOrder.BIG_ENDIAN); - destByteBuffer.put(data); - return new Result(res.getResultValue(),destByteBuffer.getInt(4)); + ByteBuffer destByteBuffer = ByteBuffer.allocate(0x04); + destByteBuffer.order(ByteOrder.BIG_ENDIAN); + destByteBuffer.put(Arrays.copyOfRange(res.getData(), 0x04, 0x08)); + + return new Result(res.getResultValue(),destByteBuffer.getInt(0x00)); } public int FSA_CloseDir(int handle, int dirhandle) throws IOException{ - byte[] inbuffer = new byte[0x520]; - System.arraycopy(getClient().intToByteArray(dirhandle), 0, inbuffer, 4, 4); + byte[] inbuffer = new byte[0x520]; + Utils.writeIntToByteArray(inbuffer, dirhandle, 0x04); Result res = ioctl.ioctl(handle, 0x0D, inbuffer, 0x293); return res.getResultValue(); } - - + public Result FSA_ReadDir(int fsa_handle, int dirhandle) throws IOException { + byte[] inbuffer = new byte[0x520]; + Utils.writeIntToByteArray(inbuffer,dirhandle,4); + + Result res = ioctl.ioctl(fsa_handle, 0x0B, inbuffer, 0x293); + + byte[] unknowndata = Arrays.copyOfRange(res.getData(), 0x04, 0x68); + + String filename = Utils.getStringFromByteArray(Arrays.copyOfRange(res.getData(), 0x68, res.getData().length)); + if(res.getResultValue() == 0){ + return new Result(res.getResultValue(),new FEntry(filename,((unknowndata[0] & 0x01) == 0x01),unknowndata)); + }else{ + return new Result(res.getResultValue(),null); + } + } } diff --git a/src/de/mas/wupclient/client/operations/IoctlOperations.java b/src/de/mas/wupclient/client/operations/IoctlOperations.java index 0d8a779..4c5e758 100644 --- a/src/de/mas/wupclient/client/operations/IoctlOperations.java +++ b/src/de/mas/wupclient/client/operations/IoctlOperations.java @@ -6,9 +6,9 @@ import java.nio.ByteOrder; import java.util.HashMap; import java.util.Map; -import de.mas.wupclient.Utils; import de.mas.wupclient.client.WUPClient; import de.mas.wupclient.client.utils.Result; +import de.mas.wupclient.client.utils.Utils; public class IoctlOperations extends Operations { private static Map instances = new HashMap<>(); @@ -29,26 +29,12 @@ public class IoctlOperations extends Operations { int ret; if(outbuf_size > 0){ - int out_address = getClient().alloc(outbuf_size); - int[] buffer = new int[6]; - buffer[0] = handle; - buffer[1] = cmd; - buffer[2] = in_address; - buffer[3] = inbuf.length; - buffer[4] = out_address; - buffer[5] = outbuf_size; - ret = getClient().svc(0x38, buffer); + int out_address = getClient().alloc(outbuf_size); + ret = getClient().svc(0x38, new int[] {handle,cmd,in_address,inbuf.length,out_address,outbuf_size}); out_data = getClient().read(out_address, outbuf_size); getClient().free(out_address); }else{ - int[] buffer = new int[6]; - buffer[0] = handle; - buffer[1] = cmd; - buffer[2] = in_address; - buffer[3] = inbuf.length; - buffer[4] = 0; - buffer[5] = 0; - ret = getClient().svc(0x38, buffer); + ret = getClient().svc(0x38, new int[] {handle,cmd,in_address,inbuf.length,0,0}); } getClient().free(in_address); return new Result(ret,out_data); @@ -57,9 +43,9 @@ public class IoctlOperations extends Operations { public int iovec(int[][] inputData) throws IOException{ ByteBuffer destByteBuffer = ByteBuffer.allocate(inputData.length * (0x04*3)); destByteBuffer.order(ByteOrder.BIG_ENDIAN); - for (int[] foo : inputData){ - destByteBuffer.putInt(foo[0]); - destByteBuffer.putInt(foo[1]); + for (int[] data : inputData){ + destByteBuffer.putInt(data[0]); + destByteBuffer.putInt(data[1]); destByteBuffer.putInt(0); } return getClient().load_buffer(destByteBuffer.array()); @@ -84,16 +70,9 @@ public class IoctlOperations extends Operations { i++; } - int[][] iovecs_buffer = Utils.concatAll(new_inbufs,ínbufs_ptr,outbufs_ptr,new_outbufs); + int iovecs = iovec(Utils.concatAll(new_inbufs,ínbufs_ptr,outbufs_ptr,new_outbufs)); - int iovecs = iovec(iovecs_buffer); - int[] buffer = new int[5]; - buffer[0] = handle; - buffer[1] = cmd; - buffer[2] = new_inbufs.length + ínbufs_ptr.length; - buffer[3] = new_outbufs.length + outbufs_ptr.length; - buffer[4] = iovecs; - int ret = getClient().svc(0x39, buffer); + int ret = getClient().svc(0x39, new int[]{handle,cmd,new_inbufs.length + ínbufs_ptr.length,new_outbufs.length + outbufs_ptr.length,iovecs}); byte[][] out_data = new byte[new_outbufs.length][]; i=0; diff --git a/src/de/mas/wupclient/client/operations/UtilOperations.java b/src/de/mas/wupclient/client/operations/UtilOperations.java index b8f1c8c..ffa5567 100644 --- a/src/de/mas/wupclient/client/operations/UtilOperations.java +++ b/src/de/mas/wupclient/client/operations/UtilOperations.java @@ -8,6 +8,7 @@ import java.util.Map; import de.mas.wupclient.client.WUPClient; import de.mas.wupclient.client.utils.FEntry; +import de.mas.wupclient.client.utils.Logger; import de.mas.wupclient.client.utils.Result; public class UtilOperations extends Operations { @@ -35,6 +36,13 @@ public class UtilOperations extends Operations { return ls(targetPath,false); } public List ls(String targetPath,boolean return_data) throws IOException{ + if(!return_data){ + if(targetPath != null){ + Logger.logCmd("ls(" + targetPath + ")"); + }else{ + Logger.logCmd("ls()"); + } + } List results = new ArrayList<>(); int fsa_handle = getClient().get_fsa_handle(); String path = targetPath; @@ -44,7 +52,7 @@ public class UtilOperations extends Operations { Result res = fsa.FSA_OpenDir(fsa_handle, path); if(res.getResultValue() != 0x0){ - System.out.println("opendir error : " + String.format("%08X",res.getResultValue())); + Logger.logErr("opendir error : " + String.format("%08X",res.getResultValue())); } int dirhandle = res.getData(); @@ -59,9 +67,9 @@ public class UtilOperations extends Operations { } if(!return_data){ if(entry.isFile()){ - System.out.println(entry.getFilename()); + Logger.log(entry.getFilename()); }else{ - System.out.println(entry.getFilename() + "/"); + Logger.log(entry.getFilename() + "/"); } }else{ results.add(entry); @@ -69,7 +77,7 @@ public class UtilOperations extends Operations { } int result; if((result = fsa.FSA_CloseDir(fsa_handle, dirhandle)) != 0){ - System.err.println("CloseDirdone failed!" + result); + Logger.logErr("CloseDir failed!" + result); } return results; } diff --git a/src/de/mas/wupclient/client/utils/Logger.java b/src/de/mas/wupclient/client/utils/Logger.java new file mode 100644 index 0000000..d9add65 --- /dev/null +++ b/src/de/mas/wupclient/client/utils/Logger.java @@ -0,0 +1,13 @@ +package de.mas.wupclient.client.utils; + +public class Logger { + public static void log(String log){ + System.out.println("> " + log); + } + public static void logCmd(String log){ + log("Executing: " + log); + } + public static void logErr(String log){ + System.err.println("> Error: " + log); + } +} diff --git a/src/de/mas/wupclient/client/utils/Utils.java b/src/de/mas/wupclient/client/utils/Utils.java new file mode 100644 index 0000000..91daf86 --- /dev/null +++ b/src/de/mas/wupclient/client/utils/Utils.java @@ -0,0 +1,87 @@ +package de.mas.wupclient.client.utils; + +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; + +public class Utils { + public static String ByteArrayToString(byte[] ba) + { + if(ba == null) return null; + StringBuilder hex = new StringBuilder(ba.length * 2); + for(byte b : ba){ + hex.append(String.format("%02X", b)); + } + return hex.toString(); + } + + @SafeVarargs + public static T[] concatAll(T[] first, T[]... rest) { + int totalLength = first.length; + for (T[] array : rest) { + totalLength += array.length; + } + T[] result = Arrays.copyOf(first, totalLength); + int offset = first.length; + for (T[] array : rest) { + System.arraycopy(array, 0, result, offset, array.length); + offset += array.length; + } + return result; + } + + public static String getStringFromByteArray(byte[] data){ + int i = 0; + while(data[i] != 0 && (i) < data.length){ + i++; + } + String string = ""; + try { + string = new String(Arrays.copyOf(data, i),"UTF-8"); + } catch (UnsupportedEncodingException e) { + Logger.logErr("UnsupportedEncodingException - couldn't creat String from byte[]"); + } + return string; + } + + public static void writeIntToByteArray(byte[] target, int dirhandle, int offset) { + if(target != null && target.length >= (offset + 0x04)){ + System.arraycopy(intToBigEndianByteArray(dirhandle), 0, target, offset, 4); + }else{ + Logger.logErr("writeIntToByteArray failed. Not enough space in targetBuffer"); + } + } + + public static byte[] intToBigEndianByteArray(int value){ + ByteBuffer destByteBuffer = ByteBuffer.allocate(4); + destByteBuffer.order(ByteOrder.BIG_ENDIAN); + destByteBuffer.putInt(value); + return destByteBuffer.array(); + } + + public static boolean writeNullTerminatedStringToByteArray(byte[] target, String input, int offset) { + if(writeStringToByteArray(target, input, offset)){ + int nullTerminatorOffset = offset + input.getBytes().length; + if(target != null && target.length >= (nullTerminatorOffset + 1)){ + target[nullTerminatorOffset] = 0; + return true; + }else{ + Logger.logErr("writeNullTerminatedStringToByteArray failed. Not enough space in targetBuffer"); + } + } + return false; + } + + public static boolean writeStringToByteArray(byte[] target, String input, int offset) { + byte[] stringBytes = input.getBytes(); + if(target != null && target.length >= (offset + stringBytes.length)){ + System.arraycopy(stringBytes , 0, target, offset, stringBytes.length); + return true; + }else{ + Logger.logErr("writeStringToByteArray failed. Not enough space in targetBuffer"); + } + return false; + } + +}