static void Handle(object client_obj) { string name = Thread.CurrentThread.Name; FileStream[] files = new FileStream[256]; Dictionary <int, FileStream> files_request = new Dictionary <int, FileStream>(); StreamWriter log = null; try { TcpClient client = (TcpClient)client_obj; using (NetworkStream stream = client.GetStream()) { EndianBinaryReader reader = new EndianBinaryReader(stream); EndianBinaryWriter writer = new EndianBinaryWriter(stream); uint[] ids = reader.ReadUInt32s(4); // Log connection Console.WriteLine(name + " Accepted connection from client " + client.Client.RemoteEndPoint.ToString()); Console.WriteLine(name + " TitleID: " + ids[0].ToString("X8") + "-" + ids[1].ToString("X8")); if (!Directory.Exists(root + "\\" + ids[0].ToString("X8") + "-" + ids[1].ToString("X8"))) { writer.Write(BYTE_NORMAL); throw new Exception("Not interested."); } // Create log file for current thread log = new StreamWriter(logs_root + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + "-" + name + "-" + ids[0].ToString("X8") + "-" + ids[1].ToString("X8") + ".txt"); log.WriteLine(name + " Accepted connection from client " + client.Client.RemoteEndPoint.ToString()); log.WriteLine(name + " TitleID: " + ids[0].ToString("X8") + "-" + ids[1].ToString("X8")); string LocalRoot = root + "\\" + ids[0].ToString("X8") + "-" + ids[1].ToString("X8"); writer.Write(BYTE_SPECIAL); while (true) { byte cmd_byte = reader.ReadByte(); switch (cmd_byte) { case BYTE_OPEN: { bool request_slow = false; int len_path = reader.ReadInt32(); int len_mode = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) { throw new InvalidDataException(); } string mode = reader.ReadString(Encoding.ASCII, len_mode - 1); if (reader.ReadByte() != 0) { throw new InvalidDataException(); } Log(log, name + " " + path); if (File.Exists(LocalRoot + path)) { int handle = -1; for (int i = 0; i < files.Length; i++) { if (files[i] == null) { handle = i; break; } } if (handle == -1) { Log(log, name + " Out of file handles!"); writer.Write(BYTE_SPECIAL); writer.Write(-19); writer.Write(0); break; } Log(log, name + " -> fopen(\"" + path + "\", \"" + mode + "\") = " + handle.ToString()); files[handle] = new FileStream(LocalRoot + path, FileMode.Open, FileAccess.Read, FileShare.Read); writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write(0x0fff00ff | (handle << 8)); } // Check for file request : filename + "-request" or + "-request_slow" else if (File.Exists(LocalRoot + path + "-request") || (request_slow = File.Exists(LocalRoot + path + "-request_slow"))) { // Check if dump has already been done if (!File.Exists(LocalRoot + path + "-dump")) { // Inform cafiine that we request file to be sent writer.Write(!request_slow ? BYTE_REQUEST : BYTE_REQUEST_SLOW); } else { // Nothing to do writer.Write(BYTE_NORMAL); } } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_HANDLE: { // Read buffer params : fd, path length, path string int fd = reader.ReadInt32(); int len_path = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) { throw new InvalidDataException(); } // Add new file for incoming data files_request.Add(fd, new FileStream(LocalRoot + path + "-dump", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write)); // Send response writer.Write(BYTE_SPECIAL); break; } case BYTE_DUMP: { // Read buffer params : fd, size, file data int fd = reader.ReadInt32(); int sz = reader.ReadInt32(); byte[] buffer = new byte[sz]; buffer = reader.ReadBytes(sz); // Look for file descriptor foreach (var item in files_request) { if (item.Key == fd) { FileStream dump_file = item.Value; if (dump_file == null) { break; } Log(log, name + " -> dump(\"" + Path.GetFileName(dump_file.Name) + "\") " + (sz / 1024).ToString() + "kB"); // Write to file dump_file.Write(buffer, 0, sz); break; } } // Send response writer.Write(BYTE_SPECIAL); break; } case BYTE_READ: { int size = reader.ReadInt32(); int count = reader.ReadInt32(); int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-19); writer.Write(0); break; } FileStream f = files[handle]; byte[] buffer = new byte[size * count]; int sz = f.Read(buffer, 0, buffer.Length); writer.Write(BYTE_SPECIAL); writer.Write(sz / size); writer.Write(sz); writer.Write(buffer, 0, sz); if (reader.ReadByte() != BYTE_OK) { throw new InvalidDataException(); } } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_CLOSE: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } Log(log, name + " close(" + handle.ToString() + ")"); FileStream f = files[handle]; writer.Write(BYTE_SPECIAL); writer.Write(0); f.Close(); files[handle] = null; } else { // Check if it is a file to dump foreach (var item in files_request) { if (item.Key == fd) { FileStream dump_file = item.Value; if (dump_file == null) { break; } Log(log, name + " -> dump complete(\"" + Path.GetFileName(dump_file.Name) + "\")"); // Close file and remove from request list dump_file.Close(); files_request.Remove(fd); break; } } // Send response writer.Write(BYTE_NORMAL); } break; } case BYTE_SETPOS: { int fd = reader.ReadInt32(); int pos = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } FileStream f = files[handle]; f.Position = pos; writer.Write(BYTE_SPECIAL); writer.Write(0); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_STATFILE: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); writer.Write(0); break; } FileStream f = files[handle]; FSStat stat = new FSStat(); stat.flags = FSStatFlag.None; stat.permission = 0x400; stat.owner = ids[1]; stat.group = 0x101e; stat.file_size = (uint)f.Length; writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write(Marshal.SizeOf(stat)); writer.Write(stat); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_EOF: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } FileStream f = files[handle]; writer.Write(BYTE_SPECIAL); writer.Write(f.Position == f.Length ? -5 : 0); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_GETPOS: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); writer.Write(0); break; } FileStream f = files[handle]; writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write((int)f.Position); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_PING: { int val1 = reader.ReadInt32(); int val2 = reader.ReadInt32(); Log(log, name + " PING RECEIVED with values : " + val1.ToString() + " - " + val2.ToString()); break; } default: throw new InvalidDataException(); } } } } catch (Exception e) { if (log != null) { Log(log, name + " " + e.Message); } else { Console.WriteLine(name + " " + e.Message); } } finally { foreach (var item in files) { if (item != null) { item.Close(); } } foreach (var item in files_request) { if (item.Value != null) { item.Value.Close(); } } if (log != null) { log.Close(); } } Console.WriteLine(name + " Exit"); }
static void Handle(object client_obj) { string name = Thread.CurrentThread.Name; FileStream[] files = new FileStream[256]; Dictionary<int, FileStream> files_request = new Dictionary<int, FileStream>(); StreamWriter log = null; try { TcpClient client = (TcpClient)client_obj; using (NetworkStream stream = client.GetStream()) { EndianBinaryReader reader = new EndianBinaryReader(stream); EndianBinaryWriter writer = new EndianBinaryWriter(stream); uint[] ids = reader.ReadUInt32s(4); // Log connection Console.WriteLine(name + " Accepted connection from client " + client.Client.RemoteEndPoint.ToString()); Console.WriteLine(name + " TitleID: " + ids[0].ToString("X8") + "-" + ids[1].ToString("X8")); if (!Directory.Exists(root + "\\" + ids[0].ToString("X8") + "-" + ids[1].ToString("X8"))) { writer.Write(BYTE_NORMAL); throw new Exception("Not interested."); } // Create log file for current thread log = new StreamWriter(logs_root + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + "-" + name + "-" + ids[0].ToString("X8") + "-" + ids[1].ToString("X8") + ".txt"); log.WriteLine(name + " Accepted connection from client " + client.Client.RemoteEndPoint.ToString()); log.WriteLine(name + " TitleID: " + ids[0].ToString("X8") + "-" + ids[1].ToString("X8")); string LocalRoot = root + "\\" + ids[0].ToString("X8") + "-" + ids[1].ToString("X8"); writer.Write(BYTE_SPECIAL); while (true) { byte cmd_byte = reader.ReadByte(); switch (cmd_byte) { case BYTE_OPEN: { bool request_slow = false; int len_path = reader.ReadInt32(); int len_mode = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); string mode = reader.ReadString(Encoding.ASCII, len_mode - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); Log(log, name + " " + path); if (File.Exists(LocalRoot + path)) { int handle = -1; for (int i = 0; i < files.Length; i++) { if (files[i] == null) { handle = i; break; } } if (handle == -1) { Log(log, name + " Out of file handles!"); writer.Write(BYTE_SPECIAL); writer.Write(-19); writer.Write(0); break; } Log(log, name + " -> fopen(\"" + path + "\", \"" + mode + "\") = " + handle.ToString()); files[handle] = new FileStream(LocalRoot + path, FileMode.Open, FileAccess.Read, FileShare.Read); writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write(0x0fff00ff | (handle << 8)); } // Check for file request : filename + "-request" or + "-request_slow" else if (File.Exists(LocalRoot + path + "-request") || (request_slow = File.Exists(LocalRoot + path + "-request_slow"))) { // Check if dump has already been done if (!File.Exists(LocalRoot + path + "-dump")) { // Inform cafiine that we request file to be sent writer.Write(!request_slow ? BYTE_REQUEST : BYTE_REQUEST_SLOW); } else { // Nothing to do writer.Write(BYTE_NORMAL); } } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_HANDLE: { // Read buffer params : fd, path length, path string int fd = reader.ReadInt32(); int len_path = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); // Add new file for incoming data files_request.Add(fd, new FileStream(LocalRoot + path + "-dump", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write)); // Send response writer.Write(BYTE_SPECIAL); break; } case BYTE_DUMP: { // Read buffer params : fd, size, file data int fd = reader.ReadInt32(); int sz = reader.ReadInt32(); byte[] buffer = new byte[sz]; buffer = reader.ReadBytes(sz); // Look for file descriptor foreach (var item in files_request) { if (item.Key == fd) { FileStream dump_file = item.Value; if (dump_file == null) break; Log(log, name + " -> dump(\"" + Path.GetFileName(dump_file.Name) + "\") " + (sz / 1024).ToString() + "kB"); // Write to file dump_file.Write(buffer, 0, sz); break; } } // Send response writer.Write(BYTE_SPECIAL); break; } case BYTE_READ: { int size = reader.ReadInt32(); int count = reader.ReadInt32(); int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-19); writer.Write(0); break; } FileStream f = files[handle]; byte[] buffer = new byte[size * count]; int sz = f.Read(buffer, 0, buffer.Length); writer.Write(BYTE_SPECIAL); writer.Write(sz / size); writer.Write(sz); writer.Write(buffer, 0, sz); if (reader.ReadByte() != BYTE_OK) throw new InvalidDataException(); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_CLOSE: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } Log(log, name + " close(" + handle.ToString() + ")"); FileStream f = files[handle]; writer.Write(BYTE_SPECIAL); writer.Write(0); f.Close(); files[handle] = null; } else { // Check if it is a file to dump foreach (var item in files_request) { if (item.Key == fd) { FileStream dump_file = item.Value; if (dump_file == null) break; Log(log, name + " -> dump complete(\"" + Path.GetFileName(dump_file.Name) + "\")"); // Close file and remove from request list dump_file.Close(); files_request.Remove(fd); break; } } // Send response writer.Write(BYTE_NORMAL); } break; } case BYTE_SETPOS: { int fd = reader.ReadInt32(); int pos = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } FileStream f = files[handle]; f.Position = pos; writer.Write(BYTE_SPECIAL); writer.Write(0); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_STATFILE: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); writer.Write(0); break; } FileStream f = files[handle]; FSStat stat = new FSStat(); stat.flags = FSStatFlag.None; stat.permission = 0x400; stat.owner = ids[1]; stat.group = 0x101e; stat.file_size = (uint)f.Length; writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write(Marshal.SizeOf(stat)); writer.Write(stat); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_EOF: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } FileStream f = files[handle]; writer.Write(BYTE_SPECIAL); writer.Write(f.Position == f.Length ? -5 : 0); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_GETPOS: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); writer.Write(0); break; } FileStream f = files[handle]; writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write((int)f.Position); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_PING: { int val1 = reader.ReadInt32(); int val2 = reader.ReadInt32(); Log(log, name + " PING RECEIVED with values : " + val1.ToString() + " - " + val2.ToString()); break; } default: throw new InvalidDataException(); } } } } catch (Exception e) { if (log != null) Log(log, name + " " + e.Message); else Console.WriteLine(name + " " + e.Message); } finally { foreach (var item in files) { if (item != null) item.Close(); } foreach (var item in files_request) { if (item.Value != null) item.Value.Close(); } if (log != null) log.Close(); } Console.WriteLine(name + " Exit"); }
static void Handle(object client_obj) { string name = Thread.CurrentThread.Name; FileStream[] files = new FileStream[256]; try { TcpClient client = (TcpClient)client_obj; using (NetworkStream stream = client.GetStream()) { EndianBinaryReader reader = new EndianBinaryReader(stream); EndianBinaryWriter writer = new EndianBinaryWriter(stream); uint[] ids = reader.ReadUInt32s(4); Console.WriteLine(name + " Accepted connection from client " + client.Client.RemoteEndPoint.ToString()); Console.WriteLine(name + " TitleID: " + ids[0].ToString("X8") + "-" + ids[1].ToString("X8")); //Console.WriteLine(name + " OSID: " + ids[2].ToString("X8") + "-" + ids[3].ToString("X8")); if (!Directory.Exists(root + "\\" + ids[0].ToString("X8") + "-" + ids[1].ToString("X8"))) { writer.Write(BYTE_NORMAL); throw new Exception("Not interested."); } string LocalRoot = root + "\\" + ids[0].ToString("X8") + "-" + ids[1].ToString("X8"); writer.Write(BYTE_SPECIAL); while (true) { switch (reader.ReadByte()) { case BYTE_OPEN: { int len_path = reader.ReadInt32(); int len_mode = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); string mode = reader.ReadString(Encoding.ASCII, len_mode - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); Console.WriteLine(name + " " + path); if (File.Exists(LocalRoot + path)) { int handle = -1; for (int i = 0; i < files.Length; i++) { if (files[i] == null) { handle = i; break; } } if (handle == -1) { Console.WriteLine(name + " Out of file handles!"); writer.Write(BYTE_SPECIAL); writer.Write(-19); writer.Write(0); break; } Console.WriteLine(name + " fopen(\"" + path + "\", \"" + mode + "\") = " + handle.ToString()); files[handle] = new FileStream(LocalRoot + path, FileMode.Open, FileAccess.Read, FileShare.Read); writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write(0x0fff00ff | (handle << 8)); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_READ: { int size = reader.ReadInt32(); int count = reader.ReadInt32(); int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-19); writer.Write(0); break; } FileStream f = files[handle]; byte[] buffer = new byte[size * count]; int sz = f.Read(buffer, 0, buffer.Length); writer.Write(BYTE_SPECIAL); writer.Write(sz / size); writer.Write(sz); writer.Write(buffer, 0, sz); if (reader.ReadByte() != BYTE_OK) throw new InvalidDataException(); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_CLOSE: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } Console.WriteLine(name + " close(" + handle.ToString() + ")"); FileStream f = files[handle]; writer.Write(BYTE_SPECIAL); writer.Write(0); f.Close(); files[handle] = null; } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_SETPOS: { int fd = reader.ReadInt32(); int pos = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } FileStream f = files[handle]; f.Position = pos; writer.Write(BYTE_SPECIAL); writer.Write(0); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_STATFILE: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); writer.Write(0); break; } FileStream f = files[handle]; FSStat stat = new FSStat(); stat.flags = FSStatFlag.None; stat.permission = 0x400; stat.owner = ids[1]; stat.group = 0x101e; stat.file_size = (uint)f.Length; writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write(Marshal.SizeOf(stat)); writer.Write(stat); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_EOF: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } FileStream f = files[handle]; writer.Write(BYTE_SPECIAL); writer.Write(f.Position == f.Length ? -5 : 0); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_GETPOS: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); writer.Write(0); break; } FileStream f = files[handle]; writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write((int)f.Position); } else { writer.Write(BYTE_NORMAL); } break; } default: throw new InvalidDataException(); } } } } catch (Exception e) { Console.WriteLine(name + " " + e.Message); } finally { foreach (var item in files) { if (item != null) item.Close(); } } Console.WriteLine(name + " Exit"); }
private void _handle(object clientObj) { var name = Thread.CurrentThread.Name; var files = new FileStream[256]; var filesRequest = new Dictionary <int, FileStream>(); try { var client = (TcpClient)clientObj; using (var stream = client.GetStream()) { var reader = new EndianBinaryReader(stream); var writer = new EndianBinaryWriter(stream); var ids = reader.ReadUInt32s(4); if (!new File(_root, ids[0].ToString("X8") + "-" + ids[1].ToString("X8")).Exists()) { writer.Write(BYTE_NORMAL); throw new Exception("Not interested."); } var localRoot = new File(_root, ids[0].ToString("X8") + "-" + ids[1].ToString("X8")); writer.Write(BYTE_SPECIAL); while (true) { var cmdByte = reader.ReadByte(); switch (cmdByte) { case BYTE_OPEN: { var requestSlow = false; var lenPath = reader.ReadInt32(); var lenMode = reader.ReadInt32(); var path = reader.ReadString(Encoding.ASCII, lenPath - 1); if (reader.ReadByte() != 0) { throw new InvalidDataException(); } var mode = reader.ReadString(Encoding.ASCII, lenMode - 1); if (reader.ReadByte() != 0) { throw new InvalidDataException(); } if (new File(localRoot, path).Exists()) { var handle = -1; for (var i = 0; i < files.Length; i++) { if (files[i] == null) { handle = i; break; } } if (handle == -1) { writer.Write(BYTE_SPECIAL); writer.Write(-19); writer.Write(0); break; } files[handle] = new FileStream(localRoot + path, FileMode.Open, FileAccess.Read, FileShare.Read); writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write(0x0fff00ff | (handle << 8)); } else if (new File(localRoot, path + "-request").Exists() || (requestSlow = new File(localRoot, path + "-request_slow").Exists())) { if (new File(localRoot, path + "-dump").Exists()) { writer.Write(!requestSlow ? BYTE_REQUEST : BYTE_REQUEST_SLOW); } else { writer.Write(BYTE_NORMAL); } } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_HANDLE: { var fd = reader.ReadInt32(); var lenPath = reader.ReadInt32(); var path = reader.ReadString(Encoding.ASCII, lenPath - 1); if (reader.ReadByte() != 0) { throw new InvalidDataException(); } filesRequest.Add(fd, new FileStream(localRoot + path + "-dump", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write)); writer.Write(BYTE_SPECIAL); break; } case BYTE_DUMP: { // Read buffer params : fd, size, file data int fd = reader.ReadInt32(); int sz = reader.ReadInt32(); byte[] buffer = new byte[sz]; buffer = reader.ReadBytes(sz); // Look for file descriptor foreach (var item in filesRequest) { if (item.Key == fd) { FileStream dump_file = item.Value; if (dump_file == null) { break; } // Write to file dump_file.Write(buffer, 0, sz); break; } } // Send response writer.Write(BYTE_SPECIAL); break; } case BYTE_READ: { int size = reader.ReadInt32(); int count = reader.ReadInt32(); int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-19); writer.Write(0); break; } FileStream f = files[handle]; byte[] buffer = new byte[size * count]; int sz = f.Read(buffer, 0, buffer.Length); writer.Write(BYTE_SPECIAL); writer.Write(sz / size); writer.Write(sz); writer.Write(buffer, 0, sz); if (reader.ReadByte() != BYTE_OK) { throw new InvalidDataException(); } } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_CLOSE: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } FileStream f = files[handle]; writer.Write(BYTE_SPECIAL); writer.Write(0); f.Close(); files[handle] = null; } else { // Check if it is a file to dump foreach (var item in filesRequest) { if (item.Key == fd) { FileStream dump_file = item.Value; if (dump_file == null) { break; } // Close file and remove from request list dump_file.Close(); filesRequest.Remove(fd); break; } } // Send response writer.Write(BYTE_NORMAL); } break; } case BYTE_SETPOS: { int fd = reader.ReadInt32(); int pos = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } FileStream f = files[handle]; f.Position = pos; writer.Write(BYTE_SPECIAL); writer.Write(0); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_STATFILE: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); writer.Write(0); break; } FileStream f = files[handle]; FSStat stat = new FSStat(); stat.flags = FSStatFlag.None; stat.permission = 0x400; stat.owner = ids[1]; stat.group = 0x101e; stat.file_size = (uint)f.Length; writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write(Marshal.SizeOf(stat)); writer.Write(stat); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_EOF: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } FileStream f = files[handle]; writer.Write(BYTE_SPECIAL); writer.Write(f.Position == f.Length ? -5 : 0); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_GETPOS: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); writer.Write(0); break; } FileStream f = files[handle]; writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write((int)f.Position); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_PING: { int val1 = reader.ReadInt32(); int val2 = reader.ReadInt32(); break; } default: throw new InvalidDataException(); } } } } catch (Exception e) { Console.WriteLine(name + " " + e.Message); } finally { foreach (var item in files) { if (item != null) { item.Close(); } } foreach (var item in filesRequest) { if (item.Value != null) { item.Value.Close(); } } } Console.WriteLine(name + " Exit"); }
public void HandleClient(object client_obj) { string name = Thread.CurrentThread.Name; FileStream[] files = new FileStream[256]; try { TcpClient client = (TcpClient)client_obj; using (NetworkStream stream = client.GetStream()) { EndianBinaryReader reader = new EndianBinaryReader(stream); EndianBinaryWriter writer = new EndianBinaryWriter(stream); uint[] ids = reader.ReadUInt32s(4); bool isSplatoon = false; var titleId = ids[0].ToString("X8") + "-" + ids[1].ToString("X8"); // North America, Europe, Japan, Testfire Europe, Testfire Japan, Testfire North America if (titleId.Equals("00050000-10176900") || titleId.Equals("00050000-10176A00") || titleId.Equals("00050000-10162B00") || titleId.Equals("00050000-101D6A00") || titleId.Equals("00050000-101D6B00") || titleId.Equals("00050000-101D6C00")) { isSplatoon = true; } else if (!Directory.Exists("cafiine_root\\" + titleId)) { // close the connection if there is no directory for this title Log(LogType.Info, name + " Refusing connection from " + titleId); writer.Write(BYTE_NORMAL); throw new Exception("Not interested."); } Log(LogType.Info, name + " Accepted connection (" + ((isSplatoon) ? "Splatoon" : titleId) + ")"); writer.Write(BYTE_SPECIAL); while (true) { byte cmd_byte = reader.ReadByte(); switch (cmd_byte) { case BYTE_OPEN: { int len_path = reader.ReadInt32(); int len_mode = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) { throw new InvalidDataException(); } string mode = reader.ReadString(Encoding.ASCII, len_mode - 1); if (reader.ReadByte() != 0) { throw new InvalidDataException(); } //Log(LogType.Info, name + " " + path); String localPath = "cafiine_root\\" + titleId + path; if (isSplatoon && path.Contains(".bfstm")) { String strippedPath = Path.GetFileName(path); strippedPath = strippedPath.Substring(0, strippedPath.Length - 6); // get rid of ".bfstm" MusicFile musicFile = mainForm.GetFile(strippedPath); if (musicFile == null) { writer.Write(BYTE_NORMAL); break; } Log(LogType.Info, name + " Replacing " + strippedPath + " with " + musicFile.fileName); Log(LogType.NowPlaying, musicFile.fileName); localPath = musicFile.path; } else if (File.Exists(localPath)) { Log(LogType.Info, name + " Replacing " + path); } else { // not a music file from Splatoon and the file doesn't exist in our cafiine_root directory writer.Write(BYTE_NORMAL); break; } int handle = -1; for (int i = 0; i < files.Length; i++) { if (files[i] == null) { handle = i; break; } } if (handle == -1) { Log(LogType.Error, name + " Out of file handles!"); writer.Write(BYTE_SPECIAL); writer.Write(-19); writer.Write(0); break; } files[handle] = new FileStream(localPath, FileMode.Open, FileAccess.Read, FileShare.Read); writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write(0x0fff00ff | (handle << 8)); break; } case BYTE_HANDLE: { // Read buffer params : fd, path length, path string int fd = reader.ReadInt32(); int len_path = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) { throw new InvalidDataException(); } // Send response writer.Write(BYTE_SPECIAL); break; } case BYTE_DUMP: { // Read buffer params : fd, size, file data int fd = reader.ReadInt32(); int sz = reader.ReadInt32(); byte[] buffer = new byte[sz]; buffer = reader.ReadBytes(sz); // Send response writer.Write(BYTE_SPECIAL); break; } case BYTE_READ: { int size = reader.ReadInt32(); int count = reader.ReadInt32(); int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-19); writer.Write(0); break; } FileStream f = files[handle]; byte[] buffer = new byte[size * count]; int sz = f.Read(buffer, 0, buffer.Length); writer.Write(BYTE_SPECIAL); writer.Write(sz / size); writer.Write(sz); writer.Write(buffer, 0, sz); if (reader.ReadByte() != BYTE_OK) { throw new InvalidDataException(); } } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_CLOSE: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } Log(LogType.Info, name + " close(" + handle.ToString() + ")"); FileStream f = files[handle]; writer.Write(BYTE_SPECIAL); writer.Write(0); f.Close(); files[handle] = null; } else { // Send response writer.Write(BYTE_NORMAL); } break; } case BYTE_SETPOS: { int fd = reader.ReadInt32(); int pos = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } FileStream f = files[handle]; f.Position = pos; writer.Write(BYTE_SPECIAL); writer.Write(0); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_STATFILE: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); writer.Write(0); break; } FileStream f = files[handle]; FSStat stat = new FSStat(); stat.flags = FSStatFlag.None; stat.permission = 0x400; stat.owner = ids[1]; stat.group = 0x101e; stat.file_size = (uint)f.Length; writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write(Marshal.SizeOf(stat)); writer.Write(stat); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_EOF: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } FileStream f = files[handle]; writer.Write(BYTE_SPECIAL); writer.Write(f.Position == f.Length ? -5 : 0); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_GETPOS: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); writer.Write(0); break; } FileStream f = files[handle]; writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write((int)f.Position); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_PING: { int val1 = reader.ReadInt32(); int val2 = reader.ReadInt32(); Log(LogType.Info, name + " Ping received: " + val1.ToString() + ", " + val2.ToString()); break; } default: throw new InvalidDataException(); } } } } catch (Exception ex) { Log(LogType.Error, name + " " + ex.Message); } finally { foreach (var item in files) { if (item != null) { item.Close(); } } } Log(LogType.Info, name + " Connection closed."); }