예제 #1
0
 public wnd1(EndianBinaryReader er)
     : base(er)
 {
     long basepos = er.BaseStream.Position - 0x4C;
     InflationLeft = er.ReadUInt16() / 16f;
     InflationRight = er.ReadUInt16() / 16f;
     InflationTop = er.ReadUInt16() / 16f;
     InflationBottom = er.ReadUInt16() / 16f;
     FrameSizeLeft = er.ReadUInt16();
     FrameSizeRight = er.ReadUInt16();
     FrameSizeTop = er.ReadUInt16();
     FrameSizeBottom = er.ReadUInt16();
     NrFrames = er.ReadByte();
     byte tmp = er.ReadByte();
     UseLTMaterial = (tmp & 1) == 1;
     UseVtxColorForAllWindow = (tmp & 2) == 2;
     Kind = (WindowKind)((tmp >> 2) & 3);
     DontDrawContent = (tmp & 8) == 16;
     Padding = er.ReadUInt16();
     ContentOffset = er.ReadUInt32();
     FrameOffsetTableOffset = er.ReadUInt32();
     er.BaseStream.Position = basepos + ContentOffset;
     Content = new WindowContent(er);
     er.BaseStream.Position = basepos + FrameOffsetTableOffset;
     WindowFrameOffsets = er.ReadUInt32s(NrFrames);
     WindowFrames = new WindowFrame[NrFrames];
     for (int i = 0; i < NrFrames; i++)
     {
         er.BaseStream.Position = basepos + WindowFrameOffsets[i];
         WindowFrames[i] = new WindowFrame(er);
     }
     er.BaseStream.Position = basepos + SectionSize;
 }
예제 #2
0
 public mat1(EndianBinaryReader er)
 {
     long startpos = er.BaseStream.Position;
     Signature = er.ReadString(Encoding.ASCII, 4);
     if (Signature != "mat1") throw new SignatureNotCorrectException(Signature, "mat1", er.BaseStream.Position - 4);
     SectionSize = er.ReadUInt32();
     NrMaterials = er.ReadUInt32();
     MaterialEntryOffsets = er.ReadUInt32s((int)NrMaterials);
     Materials = new MaterialEntry[NrMaterials];
     for (int i = 0; i < NrMaterials; i++)
     {
         er.BaseStream.Position = startpos + MaterialEntryOffsets[i];
         Materials[i] = new MaterialEntry(er);
     }
     er.BaseStream.Position = startpos + SectionSize;
 }
예제 #3
0
파일: Program.cs 프로젝트: Maschell/saviine
        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");
        }
예제 #4
0
파일: Program.cs 프로젝트: zhuowei/yamlconv
        private static void ConvertFromByaml(EndianBinaryReader reader, string outpath)
        {
            if (reader.ReadUInt32() != 0x42590001)
                throw new InvalidDataException();

            uint[] offsets = reader.ReadUInt32s(4);

            if (offsets[0] > reader.BaseStream.Length)
                throw new InvalidDataException();
            if (offsets[1] > reader.BaseStream.Length)
                throw new InvalidDataException();
            if (offsets[2] > reader.BaseStream.Length)
                throw new InvalidDataException();
            if (offsets[3] > reader.BaseStream.Length) {
                if (offsets[0] == 0x10) {
                    offsets[3] = offsets[2]; // Splatoon byamls are missing offsets[2]
                    offsets[2] = 0;
                } else {
                    throw new InvalidDataException();
                }
            }

            List<string> nodes = new List<string>();
            List<string> values = new List<string>();
            List<byte[]> data = new List<byte[]>();

            if (offsets[0] != 0)
            {
                reader.BaseStream.Seek(offsets[0], SeekOrigin.Begin);
                nodes.AddRange(new ByamlNode.StringList(reader).Strings);
            }
            if (offsets[1] != 0)
            {
                reader.BaseStream.Seek(offsets[1], SeekOrigin.Begin);
                values.AddRange(new ByamlNode.StringList(reader).Strings);
            }
            if (offsets[2] != 0)
            {
                reader.BaseStream.Seek(offsets[2], SeekOrigin.Begin);
                data.AddRange(new ByamlNode.BinaryDataList(reader).DataList);
            }

            ByamlNode tree;
            ByamlNodeType rootType;
            reader.BaseStream.Seek(offsets[3], SeekOrigin.Begin);
            rootType = (ByamlNodeType)reader.ReadByte();
            reader.BaseStream.Seek(-1, SeekOrigin.Current);
            if (rootType == ByamlNodeType.UnamedNode)
                tree = new ByamlNode.UnamedNode(reader);
            else
                tree = new ByamlNode.NamedNode(reader);

            XmlDocument yaml = new XmlDocument();
            yaml.AppendChild(yaml.CreateXmlDeclaration("1.0", "UTF-8", null));
            XmlElement root = yaml.CreateElement("yaml");
            yaml.AppendChild(root);

            tree.ToXml(yaml, root, nodes, values, data);

            using (StreamWriter writer = new StreamWriter(new FileStream(outpath, FileMode.Create), Encoding.UTF8))
            {
                yaml.Save(writer);
            }
        }
예제 #5
0
        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");
        }
예제 #6
0
        static void Handle(object client_obj)
        {
            string name = Thread.CurrentThread.Name;
            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"));

                    // 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"));

                    writer.Write(BYTE_SPECIAL);

                    while (true)
                    {
                        byte cmd_byte = reader.ReadByte();
                        switch (cmd_byte)
                        {
                            case BYTE_OPEN_FILE:
                            case BYTE_OPEN_FILE_ASYNC:
                                {
                                    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();

                                    if (cmd_byte == BYTE_OPEN_FILE)
                                        Log(log, name + " FSOpenFile(\"" + path + "\", \"" + mode + "\")");
                                    else
                                        Log(log, name + " FSOpenFileAsync(\"" + path + "\", \"" + mode + "\")");

                                    break;
                                }
                            case BYTE_READ_FILE:
                            case BYTE_READ_FILE_ASYNC:
                                {
                                    int size = reader.ReadInt32();
                                    int count = reader.ReadInt32();
                                    int fd = reader.ReadInt32();

                                    if (cmd_byte == BYTE_READ_FILE)
                                        Log(log, name + " FSReadFile(size=" + size.ToString() + ", count=" + count.ToString() + ", fd=" + fd.ToString() + ")");
                                    else
                                        Log(log, name + " FSReadFileAsync(size=" + size.ToString() + ", count=" + count.ToString() + ", fd=" + fd.ToString() + ")");

                                    break;
                                }
                            case BYTE_CLOSE_FILE:
                            case BYTE_CLOSE_FILE_ASYNC:
                                {
                                    int fd = reader.ReadInt32();

                                    if (cmd_byte == BYTE_CLOSE_FILE)
                                        Log(log, name + " FSCloseFile(" + fd.ToString() + ")");
                                    else
                                        Log(log, name + " FSCloseFileAsync(" + fd.ToString() + ")");

                                    break;
                                }
                            case BYTE_SETPOS:
                                {
                                    int fd = reader.ReadInt32();
                                    int pos = reader.ReadInt32();

                                    Log(log, name + " FSSetPos(fd=" + fd.ToString() + ", pos=" + pos.ToString() + ")");

                                    break;
                                }
                            case BYTE_STATFILE:
                                {
                                    int fd = reader.ReadInt32();
                                    Log(log, name + " FSGetStatFile(" + fd.ToString() + ")");

                                    break;
                                }
                            case BYTE_OPEN_DIR:
                            case BYTE_OPEN_DIR_ASYNC:
                                {
                                    int len_path = reader.ReadInt32();
                                    string path = reader.ReadString(Encoding.ASCII, len_path - 1);
                                    if (reader.ReadByte() != 0) throw new InvalidDataException();

                                    if (cmd_byte == BYTE_OPEN_DIR)
                                        Log(log, name + " FSOpenDir(\"" + path + "\")");
                                    else
                                        Log(log, name + " FSOpenDirAsync(\"" + path + "\")");

                                    break;
                                }
                            case BYTE_READ_DIR:
                            case BYTE_READ_DIR_ASYNC:
                                {
                                    int fd = reader.ReadInt32();

                                    if (cmd_byte == BYTE_READ_DIR)
                                        Log(log, name + " FSReadDir(fd=" + fd.ToString() + ")");
                                    else
                                        Log(log, name + " FSReadDirAsync(fd=" + fd.ToString() + ")");

                                    break;
                                }
                            case BYTE_CLOSE_DIR:
                            case BYTE_CLOSE_DIR_ASYNC:
                                {
                                    int fd = reader.ReadInt32();

                                    if (cmd_byte == BYTE_CLOSE_DIR)
                                        Log(log, name + " FSCloseDir(" + fd.ToString() + ")");
                                    else
                                        Log(log, name + " FSCloseDirAsync(" + fd.ToString() + ")");

                                    break;
                                }
                            case BYTE_CHANGE_DIR:
                            case BYTE_CHANGE_DIR_ASYNC:
                                {
                                    int len_path = reader.ReadInt32();
                                    string path = reader.ReadString(Encoding.ASCII, len_path - 1);
                                    if (reader.ReadByte() != 0) throw new InvalidDataException();

                                    Log(log, name + " FSChangeDir(\"" + path + "\")");

                                    break;
                                }
                            case BYTE_GET_CWD:
                                {
                                    Log(log, name + " FSGetCwd()");

                                    break;
                                }
                            case BYTE_STAT:
                            case BYTE_STAT_ASYNC:
                                {
                                    int len_path = reader.ReadInt32();
                                    string path = reader.ReadString(Encoding.ASCII, len_path - 1);
                                    if (reader.ReadByte() != 0) throw new InvalidDataException();

                                    Log(log, name + " FSGetStat(\"" + path + "\")");
                                    break;
                                }
                            case BYTE_EOF:
                                {
                                    int fd = reader.ReadInt32();
                                    Log(log, name + " FSGetEof(" + fd.ToString() + ")");
                                    break;
                                }
                            case BYTE_GETPOS:
                                {
                                    int fd = reader.ReadInt32();
                                    Log(log, name + " FSGetPos(" + fd.ToString() + ")");
                                    break;
                                }
                            case BYTE_MOUNT_SD:
                                {
                                    Log(log, name + " Trying to mount SD card");
                                    break;
                                }
                            case BYTE_MOUNT_SD_OK:
                                {
                                    Log(log, name + " SD card mounted !");
                                    break;
                                }
                            case BYTE_MOUNT_SD_BAD:
                                {
                                    Log(log, name + " Can't mount SD card");
                                    break;
                                }
                            case BYTE_PING:
                                {
                                    int val1 = reader.ReadInt32();
                                    int val2 = reader.ReadInt32();

                                    Log(log, name + " PING RECEIVED with values : " + val1.ToString() + " - " + val2.ToString());
                                    break;
                                }
                            case 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, name + " LogString =>(\"" + str + "\")");
                                    break;
                                }
                            default:
                                throw new InvalidDataException();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                if (log != null)
                    Log(log, name + " " + e.Message);
                else
                    Console.WriteLine(name + " " + e.Message);
            }
            finally
            {
                if (log != null)
                    log.Close();
            }
            Console.WriteLine(name + " Exit");
        }
예제 #7
0
        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");
        }