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; Dictionary<string, Dictionary<string, byte>> dir_files = new Dictionary<string, Dictionary<string, byte>>(); 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); string LocalRootDump = root + "\\" + "dump" + "\\" + ids[0].ToString("X8") + "-" + ids[1].ToString("X8") + "\\"; string LocalRootInject = root + "\\" + "inject" + "\\" + ids[0].ToString("X8") + "-" + ids[1].ToString("X8") + "\\"; if (!ids[0].ToString("X8").Equals("00050000")) { writer.Write(BYTE_NORMAL); throw new Exception("Not interested."); } else { if (!Directory.Exists(LocalRootDump)) { Directory.CreateDirectory(LocalRootDump); } if (!Directory.Exists(LocalRootInject)) { Directory.CreateDirectory(LocalRootInject); } } // 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")); // 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", true, Encoding.ASCII, 1024*64); log.WriteLine(name + " Accepted connection from client " + client.Client.RemoteEndPoint.ToString()); string title_id = ids[0].ToString("X8") + "-" + ids[1].ToString("X8"); log.WriteLine(name + " TitleID: " + title_id); writer.Write(BYTE_SPECIAL); while (true) { //Log(log, "cmd_byte"); byte cmd_byte = reader.ReadByte(); switch (cmd_byte) { case BYTE_OPEN: { //Log(log, "BYTE_OPEN"); Boolean failed = 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, "old path" + path); //Log(log, "currentID: " + currentPersistentID); if (op_mode == BYTE_MODE_I) path = getRealPathCurrentInject(path, title_id); //Log(log, "new path" + path); if (path.Length == 0) failed = true; if (File.Exists(path) && !failed) { //Log(log, "path exits"); int handle = -1; for (int i = 1; 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(path, FileMode.Open, FileAccess.Read, FileShare.Read); writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write(handle); break; } //Log(log, "error fopen"); //else on error: writer.Write(BYTE_NORMAL); break; } case BYTE_SETPOS: { //Log(log, "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]; Log(log, "Postion was set to " + pos + "for handle " + handle); f.Position = pos; writer.Write(BYTE_SPECIAL); writer.Write(0); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_INJECTSTART: { long wiiUpersistentID = (long)reader.ReadUInt32(); int dumpCommon = 0; Boolean injectioncanceled = false; SaveSelectorDialog ofd = new SaveSelectorDialog(title_id, wiiUpersistentID); try { DialogResult result = ofd.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK) { currentPersistentID = ofd.NewPersistentID; dumpCommon = ofd.DumpCommon; //Console.WriteLine("Injecting " + currentPersistentID.ToString() + " into " + wiiUpersistentID.ToString() + " for title id " + title_id); if (dumpCommon == 1) Console.WriteLine("clean and inject common folder"); if (dumpCommon == 2) Console.WriteLine("inject common folder"); if (dumpCommon > 0 && currentPersistentID == 0) currentPersistentID = COMMON_PERSISTENTID; } else { Console.WriteLine("Injection canceled"); injectioncanceled = true; } } catch (Exception e) { Console.WriteLine("Injection canceled"); injectioncanceled = true; } if (injectioncanceled) { writer.Write(BYTE_NORMAL); } else { writer.Write(BYTE_SPECIAL); } int dumpmask = MASK_NORMAL; if (currentPersistentID != 0 && currentPersistentID != COMMON_PERSISTENTID) dumpmask |= MASK_USER; if (dumpCommon >= 1) { dumpmask |= MASK_COMMON; if(dumpCommon == 2) dumpmask |= MASK_COMMON_CLEAN; } writer.Write(dumpmask); writer.Write(BYTE_SPECIAL); break; } case BYTE_INJECTEND: { currentPersistentID = 0; //close all opened files for (int i = 1; i < files.Length; i++) { if (files[i] != null) { files[i].Close(); files[i] = null; } } writer.Write(BYTE_OK); //Console.WriteLine("InjectionEND"); break; } case BYTE_DUMPSTART: { long wiiUpersistentID = (long)reader.ReadUInt32(); Boolean dumpCommon = false; Boolean dumpUser = false; currentPersistentID = wiiUpersistentID; Boolean dumpcanceled = false; DumpDialog ofd = new DumpDialog(title_id, wiiUpersistentID); try { DialogResult result = ofd.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK) { dumpUser = ofd.DumpUser; dumpCommon = ofd.DumpCommon; //Console.WriteLine("Injecting " + currentPersistentID.ToString() + " into " + wiiUpersistentID.ToString() + " for title id " + title_id); if (dumpCommon) Console.WriteLine("dumping common data"); if (dumpUser) Console.WriteLine("dumping user data"); } else { Console.WriteLine("dump canceled"); dumpcanceled = true; } } catch (Exception e) { Console.WriteLine("dump canceled"); dumpcanceled = true; } if (dumpcanceled) { writer.Write(BYTE_NORMAL); } else { writer.Write(BYTE_SPECIAL); } int dumpmask = MASK_NORMAL; if (dumpUser) dumpmask |= MASK_USER; if (dumpCommon) { dumpmask |= MASK_COMMON; } writer.Write(dumpmask); writer.Write(BYTE_SPECIAL); break; } case BYTE_DUMPEND: { currentPersistentID = 0; //close all opened files for (int i = 1; i < files.Length; i++) { if (files[i] != null) { files[i].Close(); files[i] = null; } } writer.Write(BYTE_OK); //Console.WriteLine("dumpEND"); break; } case BYTE_READ_DIR: { Boolean failed = false; int len_path = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path-1); if (reader.ReadByte() != 0) throw new InvalidDataException(); int x = 0; //Console.WriteLine("old" + path); if(op_mode == BYTE_MODE_I) path = getRealPathCurrentInject(path, title_id); //Console.WriteLine("new" + path); if(path.Length == 0)failed = true; if (Directory.Exists(path) && !failed) { x = countDirectory(path); if (x > 0) { Dictionary<string, byte> value; if (!dir_files.TryGetValue(path, out value)) { //Console.Write("found no \"" + path + "\" in dic \n"); value = new Dictionary<string, byte>(); string[] fileEntries = Directory.GetFiles(path); foreach (string fn in fileEntries) { string fileName = Path.GetFileName(fn); value.Add(fileName, BYTE_FILE); } string[] subdirectoryEntries = Directory.GetDirectories(path); foreach (string sd in subdirectoryEntries) { string subdirectory = Path.GetFileName(sd); value.Add(subdirectory, BYTE_FOLDER); } dir_files.Add(path, value); //Console.Write("added \"" + path + "\" to dic \n"); } else { //Console.Write("dic for \"" + path + "\" ready \n"); } if (value.Count > 0) { writer.Write(BYTE_OK); //Console.Write("sent ok byte \n"); foreach (var item in value) { //Write writer.Write(item.Value); //Console.Write("type : " + item.Value); writer.Write(item.Key.Length); //Console.Write("length : " + item.Key.Length); writer.Write(item.Key, Encoding.ASCII, true); //Console.Write("filename : " + item.Key); int length = 0; if (item.Value == BYTE_FILE) length = (int)new System.IO.FileInfo(path + "/" + item.Key).Length; writer.Write(length); //Console.Write("filesize : " + length + " \n"); value.Remove(item.Key); //Console.Write("removed from list! " + value.Count + " remaining\n"); break; } writer.Write(BYTE_SPECIAL); // //Console.Write("file sent, wrote special byte \n"); break; } else { dir_files.Remove(path); //Console.Write("removed \"" + path + "\" from dic \n"); } } } writer.Write(BYTE_END); // //Console.Write("list was empty return BYTE_END \n"); //Console.Write("in break \n"); break; } case BYTE_READ: { //Log(log,"BYTE_READ"); int size = reader.ReadInt32(); int fd = reader.ReadInt32(); FileStream f = files[fd]; byte[] buffer = new byte[size]; int sz = (int)f.Length; int rd = 0; //Log(log, "want size:" + size + " for handle: " + fd); writer.Write(BYTE_SPECIAL); rd = f.Read(buffer, 0, buffer.Length); //Log(log,"rd:" + rd); writer.Write(rd); writer.Write(buffer, 0, rd); int offset = (int)f.Position; int progress = (int)(((float)offset / (float)sz) * 100); string strProgress = progress.ToString().PadLeft(3, ' '); string strSize = (sz / 1024).ToString(); string strCurrent = (offset / 1024).ToString().PadLeft(strSize.Length, ' '); Console.Write("\r\t--> {0}% ({1} kB / {2} kB)", strProgress, strCurrent, strSize); //Console.Write("send " + rd ); if (offset == sz) { Console.Write("\n"); log.Write("\r\t--> {0}% ({1} kB / {2} kB)\n", strProgress, strCurrent, strSize); } int ret = -5; if ((ret =reader.ReadByte()) != BYTE_OK) { Console.Write("error, got " + ret + " instead of " + BYTE_OK); //throw new InvalidDataException(); } //Log(log, "break READ"); break; } case BYTE_HANDLE: { //Log(log,"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(); //Console.WriteLine("old " + path); if (op_mode == BYTE_MODE_D) path = getRealPathCurrentDump(path, title_id); //Console.WriteLine("new " + path); if (path.Length == 0) { writer.Write(BYTE_SPECIAL); break; } if (!Directory.Exists(path)) { Directory.CreateDirectory(Path.GetDirectoryName(path)); } // Add new file for incoming data files_request.Add(fd, new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write)); // Send response if (fastmode) { writer.Write(BYTE_REQUEST); } else { writer.Write(BYTE_REQUEST_SLOW); } LogNoLine(log, "-> ["); // Send response writer.Write(BYTE_SPECIAL); break; } case BYTE_DUMP: { //Log(log,"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; LogNoLine(log, "."); // Write to file dump_file.Write(buffer, 0, sz); break; } } // Send response writer.Write(BYTE_SPECIAL); break; } case BYTE_CLOSE: { //Log(log, "BYTE_CLOSE"); int fd = reader.ReadInt32(); if (files[fd] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } //Log(log, name + " close(" + fd.ToString() + ")"); FileStream f = files[fd]; writer.Write(BYTE_SPECIAL); writer.Write(0); f.Close(); files[fd] = null; break; } case BYTE_CLOSE_DUMP: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) != 0x0fff00ff) { // 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; LogNoLine(log,"]"); Log(log, ""); // Close file and remove from request list dump_file.Close(); files_request.Remove(fd); break; } } // Send response writer.Write(BYTE_NORMAL); } break; } case BYTE_PING: { //Log(log, "BYTE_PING"); int val1 = reader.ReadInt32(); int val2 = reader.ReadInt32(); Log(log, name + " PING RECEIVED with values : " + val1.ToString() + " - " + val2.ToString()); break; } case BYTE_G_MODE: { if (op_mode == BYTE_MODE_D) { writer.Write(BYTE_MODE_D); } else if (op_mode == BYTE_MODE_I) { writer.Write(BYTE_MODE_I); } break; } case BYTE_LOG_STR: { //Log(log, "BYTE_LOG_STR"); int len_str = reader.ReadInt32(); string str = reader.ReadString(Encoding.ASCII, len_str - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); Log(log,"-> " + str); break; } default: Log(log, "xx" + cmd_byte); 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; Dictionary <string, Dictionary <string, byte> > dir_files = new Dictionary <string, Dictionary <string, byte> >(); 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); string LocalRootDump = root + "\\" + "dump" + "\\" + ids[0].ToString("X8") + "-" + ids[1].ToString("X8") + "\\"; string LocalRootInject = root + "\\" + "inject" + "\\" + ids[0].ToString("X8") + "-" + ids[1].ToString("X8") + "\\"; if (!ids[0].ToString("X8").Equals("00050000")) { writer.Write(BYTE_NORMAL); throw new Exception("Not interested."); } else { if (!Directory.Exists(LocalRootDump)) { Directory.CreateDirectory(LocalRootDump); } if (!Directory.Exists(LocalRootInject)) { Directory.CreateDirectory(LocalRootInject); } } // 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")); // 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", true, Encoding.ASCII, 1024 * 64); log.WriteLine(name + " Accepted connection from client " + client.Client.RemoteEndPoint.ToString()); string title_id = ids[0].ToString("X8") + "-" + ids[1].ToString("X8"); log.WriteLine(name + " TitleID: " + title_id); writer.Write(BYTE_SPECIAL); while (true) { //Log(log, "cmd_byte"); byte cmd_byte = reader.ReadByte(); switch (cmd_byte) { case BYTE_OPEN: { //Log(log, "BYTE_OPEN"); Boolean failed = 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, "old path" + path); //Log(log, "currentID: " + currentPersistentID); if (op_mode == BYTE_MODE_I) { path = getRealPathCurrentInject(path, title_id); } //Log(log, "new path" + path); if (path.Length == 0) { failed = true; } if (File.Exists(path) && !failed) { //Log(log, "path exits"); int handle = -1; for (int i = 1; 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(path, FileMode.Open, FileAccess.Read, FileShare.Read); writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write(handle); break; } //Log(log, "error fopen"); //else on error: writer.Write(BYTE_NORMAL); break; } case BYTE_SETPOS: { //Log(log, "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]; Log(log, "Postion was set to " + pos + "for handle " + handle); f.Position = pos; writer.Write(BYTE_SPECIAL); writer.Write(0); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_INJECTSTART: { long wiiUpersistentID = (long)reader.ReadUInt32(); int dumpCommon = 0; Boolean injectioncanceled = false; SaveSelectorDialog ofd = new SaveSelectorDialog(title_id, wiiUpersistentID); try { DialogResult result = ofd.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK) { currentPersistentID = ofd.NewPersistentID; dumpCommon = ofd.DumpCommon; //Console.WriteLine("Injecting " + currentPersistentID.ToString() + " into " + wiiUpersistentID.ToString() + " for title id " + title_id); if (dumpCommon == 1) { Console.WriteLine("clean and inject common folder"); } if (dumpCommon == 2) { Console.WriteLine("inject common folder"); } if (dumpCommon > 0 && currentPersistentID == 0) { currentPersistentID = COMMON_PERSISTENTID; } } else { Console.WriteLine("Injection canceled"); injectioncanceled = true; } } catch (Exception e) { Console.WriteLine("Injection canceled"); injectioncanceled = true; } if (injectioncanceled) { writer.Write(BYTE_NORMAL); } else { writer.Write(BYTE_SPECIAL); } int dumpmask = MASK_NORMAL; if (currentPersistentID != 0 && currentPersistentID != COMMON_PERSISTENTID) { dumpmask |= MASK_USER; } if (dumpCommon >= 1) { dumpmask |= MASK_COMMON; if (dumpCommon == 2) { dumpmask |= MASK_COMMON_CLEAN; } } writer.Write(dumpmask); writer.Write(BYTE_SPECIAL); break; } case BYTE_INJECTEND: { currentPersistentID = 0; //close all opened files for (int i = 1; i < files.Length; i++) { if (files[i] != null) { files[i].Close(); files[i] = null; } } writer.Write(BYTE_OK); //Console.WriteLine("InjectionEND"); break; } case BYTE_DUMPSTART: { long wiiUpersistentID = (long)reader.ReadUInt32(); Boolean dumpCommon = false; Boolean dumpUser = false; currentPersistentID = wiiUpersistentID; Boolean dumpcanceled = false; DumpDialog ofd = new DumpDialog(title_id, wiiUpersistentID); try { DialogResult result = ofd.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK) { dumpUser = ofd.DumpUser; dumpCommon = ofd.DumpCommon; //Console.WriteLine("Injecting " + currentPersistentID.ToString() + " into " + wiiUpersistentID.ToString() + " for title id " + title_id); if (dumpCommon) { Console.WriteLine("dumping common data"); } if (dumpUser) { Console.WriteLine("dumping user data"); } } else { Console.WriteLine("dump canceled"); dumpcanceled = true; } } catch (Exception e) { Console.WriteLine("dump canceled"); dumpcanceled = true; } if (dumpcanceled) { writer.Write(BYTE_NORMAL); } else { writer.Write(BYTE_SPECIAL); } int dumpmask = MASK_NORMAL; if (dumpUser) { dumpmask |= MASK_USER; } if (dumpCommon) { dumpmask |= MASK_COMMON; } writer.Write(dumpmask); writer.Write(BYTE_SPECIAL); break; } case BYTE_DUMPEND: { currentPersistentID = 0; //close all opened files for (int i = 1; i < files.Length; i++) { if (files[i] != null) { files[i].Close(); files[i] = null; } } writer.Write(BYTE_OK); //Console.WriteLine("dumpEND"); break; } case BYTE_READ_DIR: { Boolean failed = false; int len_path = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) { throw new InvalidDataException(); } int x = 0; //Console.WriteLine("old" + path); if (op_mode == BYTE_MODE_I) { path = getRealPathCurrentInject(path, title_id); } //Console.WriteLine("new" + path); if (path.Length == 0) { failed = true; } if (Directory.Exists(path) && !failed) { x = countDirectory(path); if (x > 0) { Dictionary <string, byte> value; if (!dir_files.TryGetValue(path, out value)) { //Console.Write("found no \"" + path + "\" in dic \n"); value = new Dictionary <string, byte>(); string[] fileEntries = Directory.GetFiles(path); foreach (string fn in fileEntries) { string fileName = Path.GetFileName(fn); value.Add(fileName, BYTE_FILE); } string[] subdirectoryEntries = Directory.GetDirectories(path); foreach (string sd in subdirectoryEntries) { string subdirectory = Path.GetFileName(sd); value.Add(subdirectory, BYTE_FOLDER); } dir_files.Add(path, value); //Console.Write("added \"" + path + "\" to dic \n"); } else { //Console.Write("dic for \"" + path + "\" ready \n"); } if (value.Count > 0) { writer.Write(BYTE_OK); //Console.Write("sent ok byte \n"); foreach (var item in value) { //Write writer.Write(item.Value); //Console.Write("type : " + item.Value); writer.Write(item.Key.Length); //Console.Write("length : " + item.Key.Length); writer.Write(item.Key, Encoding.ASCII, true); //Console.Write("filename : " + item.Key); int length = 0; if (item.Value == BYTE_FILE) { length = (int)new System.IO.FileInfo(path + "/" + item.Key).Length; } writer.Write(length); //Console.Write("filesize : " + length + " \n"); value.Remove(item.Key); //Console.Write("removed from list! " + value.Count + " remaining\n"); break; } writer.Write(BYTE_SPECIAL); // //Console.Write("file sent, wrote special byte \n"); break; } else { dir_files.Remove(path); //Console.Write("removed \"" + path + "\" from dic \n"); } } } writer.Write(BYTE_END); // //Console.Write("list was empty return BYTE_END \n"); //Console.Write("in break \n"); break; } case BYTE_READ: { //Log(log,"BYTE_READ"); int size = reader.ReadInt32(); int fd = reader.ReadInt32(); FileStream f = files[fd]; byte[] buffer = new byte[size]; int sz = (int)f.Length; int rd = 0; //Log(log, "want size:" + size + " for handle: " + fd); writer.Write(BYTE_SPECIAL); rd = f.Read(buffer, 0, buffer.Length); //Log(log,"rd:" + rd); writer.Write(rd); writer.Write(buffer, 0, rd); int offset = (int)f.Position; int progress = (int)(((float)offset / (float)sz) * 100); string strProgress = progress.ToString().PadLeft(3, ' '); string strSize = (sz / 1024).ToString(); string strCurrent = (offset / 1024).ToString().PadLeft(strSize.Length, ' '); Console.Write("\r\t--> {0}% ({1} kB / {2} kB)", strProgress, strCurrent, strSize); //Console.Write("send " + rd ); if (offset == sz) { Console.Write("\n"); log.Write("\r\t--> {0}% ({1} kB / {2} kB)\n", strProgress, strCurrent, strSize); } int ret = -5; if ((ret = reader.ReadByte()) != BYTE_OK) { Console.Write("error, got " + ret + " instead of " + BYTE_OK); //throw new InvalidDataException(); } //Log(log, "break READ"); break; } case BYTE_HANDLE: { //Log(log,"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(); } //Console.WriteLine("old " + path); if (op_mode == BYTE_MODE_D) { path = getRealPathCurrentDump(path, title_id); } //Console.WriteLine("new " + path); if (path.Length == 0) { writer.Write(BYTE_SPECIAL); break; } if (!Directory.Exists(path)) { Directory.CreateDirectory(Path.GetDirectoryName(path)); } // Add new file for incoming data files_request.Add(fd, new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write)); // Send response if (fastmode) { writer.Write(BYTE_REQUEST); } else { writer.Write(BYTE_REQUEST_SLOW); } LogNoLine(log, "-> ["); // Send response writer.Write(BYTE_SPECIAL); break; } case BYTE_DUMP: { //Log(log,"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; } LogNoLine(log, "."); // Write to file dump_file.Write(buffer, 0, sz); break; } } // Send response writer.Write(BYTE_SPECIAL); break; } case BYTE_CLOSE: { //Log(log, "BYTE_CLOSE"); int fd = reader.ReadInt32(); if (files[fd] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } //Log(log, name + " close(" + fd.ToString() + ")"); FileStream f = files[fd]; writer.Write(BYTE_SPECIAL); writer.Write(0); f.Close(); files[fd] = null; break; } case BYTE_CLOSE_DUMP: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) != 0x0fff00ff) { // 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; } LogNoLine(log, "]"); Log(log, ""); // Close file and remove from request list dump_file.Close(); files_request.Remove(fd); break; } } // Send response writer.Write(BYTE_NORMAL); } break; } case BYTE_PING: { //Log(log, "BYTE_PING"); int val1 = reader.ReadInt32(); int val2 = reader.ReadInt32(); Log(log, name + " PING RECEIVED with values : " + val1.ToString() + " - " + val2.ToString()); break; } case BYTE_G_MODE: { if (op_mode == BYTE_MODE_D) { writer.Write(BYTE_MODE_D); } else if (op_mode == BYTE_MODE_I) { writer.Write(BYTE_MODE_I); } break; } case BYTE_LOG_STR: { //Log(log, "BYTE_LOG_STR"); int len_str = reader.ReadInt32(); string str = reader.ReadString(Encoding.ASCII, len_str - 1); if (reader.ReadByte() != 0) { throw new InvalidDataException(); } Log(log, "-> " + str); break; } default: Log(log, "xx" + cmd_byte); 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"); }