Ejemplo n.º 1
0
        public void CreateAFS(string inputDirectory, string outputFile, string FilesList = "")
        {
            string[] inputFiles;

            if (FilesList == "")
            {
                inputFiles = Directory.GetFiles(inputDirectory);
            }
            else
            {
                inputFiles = File.ReadAllLines(FilesList);
            }

            FileStream   fs1 = new FileStream(outputFile, FileMode.Create);
            BinaryWriter bw  = new BinaryWriter(fs1);

            byte[] header = { 0x41, 0x46, 0x53, 0x00 }; //AFS

            fs1.Write(header, 0, header.Length);
            bw.Write((uint)inputFiles.Length);

            //Generate TOC and FileNameDirectory

            TableOfContents[]   TOC = new TableOfContents[inputFiles.Length];
            FileNameDirectory[] FND = new FileNameDirectory[inputFiles.Length];

            UInt32 CurrentOffset = Pad((uint)(8 + (8 * inputFiles.Length) + 8), 0x800);  //Header + TOC + FND Offset and size

            for (int n = 0; n < inputFiles.Length; n++)
            {
                FileInfo f = new FileInfo(inputFiles[n]);

                //TOC
                TOC[n].FileSize = (uint)f.Length;
                TOC[n].Offset   = CurrentOffset;

                CurrentOffset += TOC[n].FileSize;
                CurrentOffset  = Pad(CurrentOffset, 0x800);

                //FileNameDirectory
                FND[n].FileName = Path.GetFileName(inputFiles[n]);
                FND[n].Year     = (UInt16)f.LastWriteTime.Year;
                FND[n].Month    = (UInt16)f.LastWriteTime.Month;
                FND[n].Day      = (UInt16)f.LastWriteTime.Day;
                FND[n].Hour     = (UInt16)f.LastWriteTime.Hour;
                FND[n].Minute   = (UInt16)f.LastWriteTime.Minute;
                FND[n].Second   = (UInt16)f.LastWriteTime.Second;
                FND[n].FileSize = (uint)f.Length;
            }

            //Write TOC to file
            for (int n = 0; n < inputFiles.Length; n++)
            {
                bw.Write(TOC[n].Offset);
                bw.Write(TOC[n].FileSize);
            }

            //Write Filename Directory Offset and Size
            UInt32 FNDOffset = CurrentOffset;
            UInt32 FNDSize   = (uint)(inputFiles.Length * 0x30);

            fs1.Seek(TOC[0].Offset - 8, SeekOrigin.Begin);
            bw.Write(FNDOffset);
            bw.Write(FNDSize);

            //Write files data to file
            for (int n = 0; n < inputFiles.Length; n++)
            {
                byte[] data = File.ReadAllBytes(inputFiles[n]);
                fs1.Seek(TOC[n].Offset, SeekOrigin.Begin);
                fs1.Write(data, 0, data.Length);
            }

            //Write Filename Directory
            fs1.Seek(FNDOffset, SeekOrigin.Begin);
            for (int n = 0; n < inputFiles.Length; n++)
            {
                byte[] name = Encoding.Default.GetBytes(FND[n].FileName);
                fs1.Write(name, 0, name.Length);
                fs1.Seek(0x20 - name.Length, SeekOrigin.Current);

                bw.Write(FND[n].Year);
                bw.Write(FND[n].Month);
                bw.Write(FND[n].Day);
                bw.Write(FND[n].Hour);
                bw.Write(FND[n].Minute);
                bw.Write(FND[n].Second);
                bw.Write(FND[n].FileSize);
            }

            //Pad final 0s
            long currentPosition = fs1.Position;
            long EOF             = Pad((uint)fs1.Position, 0x800);

            for (long n = currentPosition; n < EOF; n++)
            {
                bw.Write((byte)0);
            }

            bw.Close();
            fs1.Close();
        }
Ejemplo n.º 2
0
        public bool ExtractAFS(string inputFile, string outputDirectory, string FilesList = "")
        {
            bool ThereIsFileNameTable = true;

            FileStream   fs1 = new FileStream(inputFile, FileMode.Open, FileAccess.Read);
            BinaryReader br  = new BinaryReader(fs1);

            if (br.ReadUInt32() != 0x00534641) //Header different than AFS
            {
                br.Close();
                fs1.Close();
                return(false);
            }

            UInt32 NumberOfFiles = br.ReadUInt32();

            TableOfContents[]   TOC = new TableOfContents[NumberOfFiles];
            FileNameDirectory[] FND = new FileNameDirectory[NumberOfFiles];

            //Read TOC
            for (int n = 0; n < NumberOfFiles; n++)
            {
                TOC[n].Offset   = br.ReadUInt32();
                TOC[n].FileSize = br.ReadUInt32();
            }

            //Read Filename Directory Offset and Size
            UInt32 FNDOffset = 0;
            UInt32 FNDSize   = 0;

            while (fs1.Position < TOC[0].Offset && FNDOffset == 0)
            {
                //fs1.Seek(TOC[0].Offset - 8, SeekOrigin.Begin);
                FNDOffset = br.ReadUInt32();
                FNDSize   = br.ReadUInt32();
            }
            if (FNDOffset == 0)
            {
                ThereIsFileNameTable = false;
            }

            string[] FileName = new string[NumberOfFiles];

            if (ThereIsFileNameTable)
            {
                //Read FND
                fs1.Seek(FNDOffset, SeekOrigin.Begin);

                for (int n = 0; n < NumberOfFiles; n++)
                {
                    byte[] name = new byte[32];
                    fs1.Read(name, 0, name.Length);
                    FileName[n] = Encoding.Default.GetString(name).Replace("\0", "");

                    FND[n].Year     = br.ReadUInt16();
                    FND[n].Month    = br.ReadUInt16();
                    FND[n].Day      = br.ReadUInt16();
                    FND[n].Hour     = br.ReadUInt16();
                    FND[n].Minute   = br.ReadUInt16();
                    FND[n].Second   = br.ReadUInt16();
                    FND[n].FileSize = br.ReadUInt32();
                }
            }
            else
            {
                string IDX = Path.Combine(Path.GetDirectoryName(inputFile), Path.GetFileNameWithoutExtension(inputFile)) + ".idx";

                if (File.Exists(IDX))
                {
                    FileName = ReadIDX(IDX);
                }
                else
                {
                    for (int n = 0; n < NumberOfFiles; n++)
                    {
                        FileName[n] = n.ToString("00000000");
                    }
                }
            }

            //Extract files
            if (outputDirectory.EndsWith(@"\") == false)
            {
                outputDirectory += @"\";
            }
            if (Directory.Exists(outputDirectory) == false)
            {
                Directory.CreateDirectory(outputDirectory);
            }

            String[] filelist = new String[NumberOfFiles];

            for (int n = 0; n < NumberOfFiles; n++)
            {
                byte[] filedata = new byte[TOC[n].FileSize];
                fs1.Seek(TOC[n].Offset, SeekOrigin.Begin);
                fs1.Read(filedata, 0, filedata.Length);

                string outputFile = outputDirectory + FileName[n];

                File.WriteAllBytes(outputFile, filedata);

                if (ThereIsFileNameTable)
                {
                    System.DateTime date = new System.DateTime(FND[n].Year, FND[n].Month, FND[n].Day, FND[n].Hour, FND[n].Minute, FND[n].Second);
                    File.SetLastWriteTime(outputFile, date);
                }

                filelist[n] = outputFile; //Save the list of files in order to have the original order
            }

            if (FilesList != "")
            {
                File.WriteAllLines(FilesList, filelist);
            }

            br.Close();
            fs1.Close();

            return(true);
        }