Esempio n. 1
0
        /// <summary>
        /// Returns the game header for the currently loaded game.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T ReadHeader <T>() where T : GameHeader
        {
            using (BinaryReader reader =
                       new BinaryReader(File.Open(filePath, FileMode.Open, FileAccess.Read,
                                                  FileShare.Read), Encoding.ASCII))
            {
                byte[] buffer = new byte[Marshal.SizeOf(typeof(T))];
                reader.BaseStream.Position = IsGameBoyAdvance(filePath) ? gbaHeaderOffset : gbHeaderOffset;
                buffer = reader.ReadBytes(buffer.Length);

                return((T)StructureHelper.BytesToClass <T>(ref buffer));
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Extract a .zip archive file content to the target path.
        /// </summary>
        /// <param name="zipBuffer">The input to extract.</param>
        /// <param name="targetDirectory">The destination of the extracted files.</param>
        /// <param name="overwrite">true to overwrite existing files; false otherwhise.</param>
        /// <returns>true if all the files were extracted successfully; false if some problems occurred.</returns>
        public static bool Extract(byte[] zipBuffer, string targetDirectory, bool overwrite)
        {
            byte[] buffer = new byte[Marshal.SizeOf(typeof(CentralDirectoryEnd))];

            if (zipBuffer.Length <= buffer.Length)
            {
                return(false);
            }

            uint signatureValue = (uint)Signature.CentralDirectoryEnd;

            byte[] signature = new byte[] {
                (byte)(signatureValue & 0xff),
                (byte)((signatureValue >> 0x8) & 0xff),
                (byte)((signatureValue >> 0x10) & 0xff),
                (byte)(signatureValue >> 0x18),
            };

            for (int i = zipBuffer.Length - signature.Length; i >= 0; i--)
            {
                if (zipBuffer[i] == signature[0] &&
                    zipBuffer[i + 1] == signature[1] &&
                    zipBuffer[i + 2] == signature[2] &&
                    zipBuffer[i + 3] == signature[3])
                {
                    Array.Copy(zipBuffer, i, buffer, 0, buffer.Length);
                    break;
                }
            }

            CentralDirectoryEnd cde = StructureHelper.BytesToClass <CentralDirectoryEnd>(ref buffer);

            if (cde.TotalEntries == 0 || cde.CentralDirectorySize == 0)
            {
                return(false);
            }

            CentralFileHeader cfh;

            buffer = new byte[Marshal.SizeOf(typeof(CentralFileHeader))];

            uint count  = cde.CentralDirectorySize;
            uint offset = cde.CentralDirectoryOffset;
            uint skip   = 0;

            List <uint> lfhOffsets = new List <uint>();

            do
            {
                Array.Copy(zipBuffer, offset, buffer, 0, buffer.Length);
                cfh = StructureHelper.BytesToClass <CentralFileHeader>(ref buffer);

                if (cfh.Signature == (uint)Signature.CentralFileHeader &&
                    (cfh.CompressionMethod == (ushort)CompressionMethod.Store ||
                     cfh.CompressionMethod == (ushort)CompressionMethod.Deflate) &&
                    cfh.FileNameLength > 0)
                {
                    lfhOffsets.Add(cfh.HeaderRelativeOffset);
                }

                skip = (uint)buffer.Length + cfh.FileNameLength +
                       cfh.ExtraFieldLength + cfh.FileCommentLength;

                count  -= skip;
                offset += skip;
            } while (count > 0);

            if (lfhOffsets.Count != cde.TotalEntries)
            {
                return(false);
            }

            LocalFileHeader lfh;

            buffer = new byte[Marshal.SizeOf(typeof(LocalFileHeader))];

            for (int i = 0; i < lfhOffsets.Count; i++)
            {
                Array.Copy(zipBuffer, lfhOffsets[i], buffer, 0, buffer.Length);
                lfh = StructureHelper.BytesToClass <LocalFileHeader>(ref buffer);

                if (lfh.Signature == (uint)Signature.LocalFileHeader &&
                    lfh.FileNameLength > 0)
                {
                    byte[] uncompressedData = new byte[0];

                    if (lfh.UncompressedSize > 0)
                    {
                        byte[] compressedData = new byte[lfh.CompressedSize];

                        Array.Copy(zipBuffer, lfhOffsets[i] + buffer.Length + lfh.FileNameLength + lfh.ExtraFieldLength,
                                   compressedData, 0, lfh.CompressedSize);

                        if (lfh.CompressionMethod == (ushort)CompressionMethod.Deflate)
                        {
                            uncompressedData = Inflate(compressedData);
                        }
                        else if (lfh.CompressionMethod == (ushort)CompressionMethod.Store)
                        {
                            uncompressedData = new byte[lfh.UncompressedSize];
                            compressedData.CopyTo(uncompressedData, 0);
                        }
                    }

                    if (uncompressedData.Length == lfh.UncompressedSize &&
                        Crc.ComputeCrc32(uncompressedData) == lfh.Crc32)
                    {
                        int codePage = 0;

                        if (((lfh.GeneralPurposeBitFlag >> 0xB) & 1) != 1)
                        {
                            codePage = (int)LanguageEncoding.IBM437;
                        }
                        else
                        {
                            codePage = (int)LanguageEncoding.UTF8;
                        }

                        string outputPath =
                            Path.Combine(targetDirectory, Encoding.GetEncoding(codePage).GetString(zipBuffer,
                                                                                                   (int)lfhOffsets[i] + buffer.Length, lfh.FileNameLength));

                        if (!File.Exists(outputPath) || overwrite)
                        {
                            File.WriteAllBytes(outputPath, uncompressedData);
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }