예제 #1
0
파일: Form1.cs 프로젝트: int0/Settlers7.BBA
        private bool SaveFile(BBA bba, string outDir)
        {
            FileStream   f        = null;
            MemoryStream fStream  = null;
            string       FileName = bba.FileName;
            FileStream   pakFile  = m_fs;

            pakFile.Position = bba.Offset;

            int BytesToWrite = bba.UnpackedSize;
            int BytesToRead  = (bba.PackedSize % 4);

            BytesToRead = (BytesToRead == 0) ? bba.PackedSize : (4 - BytesToRead) + bba.PackedSize;
            int BytesRead = 0;

            try
            {
                f = CreateFile(outDir, FileName);
                if (f == null)
                {
                    return(false);
                }

                if (bba.UnpackedSize == 0)
                {
                    f.Close(); return(true);
                }

                fStream = new MemoryStream(BytesToRead);


                if (fStream == null)
                {
                    f.Close(); return(false);
                }

                byte[] buff = fStream.GetBuffer();


                BBAFlags Flags = (BBAFlags)bba.Flags;

                bool IsFileWriten = false;
                bool Decrypted    = false;
                bool Decompressed = false;

                BytesRead = pakFile.Read(buff, 0, BytesToRead);

                if (BytesRead == 0)
                {
                    f.Close(); return(false);
                }

                if ((Flags & BBAFlags.EncryptedHeader) == BBAFlags.EncryptedHeader)
                {
                    int    count = bba.PackedSize / bba.Unknown2 + 1;
                    byte[] b     = new byte[0x10];
                    for (int i = 0; i < count; i++)
                    {
                        Array.Copy(buff, i * bba.Unknown2, b, 0, 0x10);

                        using (MemoryStream s = new MemoryStream())
                        {
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            byte[] TmpKey = s.GetBuffer();
                            BBACrypt.DecryptFileHeader(b, b.Length, TmpKey, 0x10, false);
                        }

                        Array.Copy(b, 0, buff, i * bba.Unknown2, 0x10);
                    }
                }

                if ((Flags & BBAFlags.EncryptedEntireContent) == BBAFlags.EncryptedEntireContent)
                {
                    IsFileWriten = true;
                    int    count = BytesToRead / bba.Unknown2 + 1;
                    byte[] b     = new byte[0x8000];

                    for (int i = 0; i < count; i++)
                    {
                        int ToDecrypt = ((BytesToRead - (i * bba.Unknown2 + b.Length)) >= 0) ? b.Length : BytesToRead - i * bba.Unknown2;

                        Array.Copy(buff, i * bba.Unknown2, b, 0, ToDecrypt);

                        using (MemoryStream s = new MemoryStream())
                        {
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            byte[] TmpKey = s.GetBuffer();
                            bool   bRes   = BBACrypt.DecryptIndexTable(b, ToDecrypt, TmpKey, 0x10);
                            if (!bRes)
                            {
                                this.listBox1.Items.Add("Failed to decrypt: " + bba.FileName);
                            }

                            int ToWrite = (ToDecrypt == 0x8000) ? 0x8000 : BytesToWrite - i * bba.Unknown2;
                            f.Write(b, 0, ToWrite);
                        }
                    }
                }


                if ((Flags & BBAFlags.Gziped) == BBAFlags.Gziped &&
                    !Decompressed)
                {
                    IsFileWriten = true;
                    using (MemoryStream m = new MemoryStream(buff))
                    {
                        using (GZipStream Decompress = new GZipStream(m, CompressionMode.Decompress))
                        {
                            MemoryStream DecompressionStream = new MemoryStream(0x10000);
                            byte[]       DecompressionBuffer = DecompressionStream.GetBuffer();
                            int          numRead;
                            while ((numRead = Decompress.Read(DecompressionBuffer, 0, DecompressionBuffer.Length)) != 0)
                            {
                                f.Write(DecompressionBuffer, 0, numRead);
                                BytesToWrite -= numRead;
                            }
                            DecompressionStream.Dispose();
                            DecompressionStream.Close();
                            Decompressed = true;
                        }
                    }
                }


                if (!IsFileWriten)
                {
                    f.Write(buff, 0, bba.PackedSize);
                }


                //                         MemoryStream s = new MemoryStream();
                //
                //                             s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                //                             s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                //                             s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                //                             s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                //
                //                             byte[] TmpKey = s.GetBuffer();
                //                             buff = new byte[bba.UnpackedSize];
                //                             pakFile.Read(buff, 0, buff.Length);
                //
                //                             bool bRes = BBACrypt.DecryptIndexTable(buff, buff.Length, TmpKey, 0x10);
                //
                //                             if (bRes == false)
                //                             {
                //                                 this.listBox1.SelectedItem = listBox1.Items.Add("Failed to decrypt: " + bba.FileName );
                //                             }
                //                             else
                //                             {
                //
                //                             }
                //                      }
            }
            catch (System.Exception ex)
            {
                if (FileName != null)
                {
                    this.listBox1.Items.Add(FileName);
                }

                this.listBox1.Items.Add(ex.Message);
            }

            f.Position = 0;

            int crc32 = Compression.GetStreamCRC32(f);

            if (bba.UnpackedCRC32 != crc32)
            {
                listBox1.Items.Add("CRC mismatch: " + bba.FileName);
            }

            if (f != null)
            {
                f.Close();
            }

            if (fStream != null)
            {
                fStream.Dispose();
                fStream.Close();
            }



            DateTime time = DateTime.FromFileTime(bba.Time);

            File.SetCreationTime(outDir + @"\" + FileName, time);
            File.SetLastWriteTime(outDir + @"\" + FileName, time);
            File.SetLastAccessTime(outDir + @"\" + FileName, time);

            return(true);
        }
예제 #2
0
파일: Form1.cs 프로젝트: int0/Settlers7.BBA
        private void ReadFAT(FileStream f)
        {
            //Prepare FAT reader.
            f.Position = m_header.IndexTableOffset;
            byte[] table = new byte[m_header.IndexTableSize];
            f.Read(table, 0, table.Length);
            BBACrypt.DecryptIndexTable(table, table.Length, null, 0);

            //MemoryStream input = new MemoryStream( table );
            m_IndexTable = new MemoryStream(table);
            //Compression.Decompress( input, 8, m_IndexTable, true );

            //input.Dispose();
            //input.Close();

            //table = m_IndexTable.GetBuffer();

            FileStream fs = File.OpenWrite(openFileDialog1.FileName + ".idx");

            fs.Write(table, 0, table.Length);
            fs.Close();

            m_tablehead.OffsetToBBAHeadInTable = BitConverter.ToInt32(table, 0);
            m_tablehead.IndexTableOffset       = BitConverter.ToInt32(table, 4);
            m_tablehead.HashTableOffset        = BitConverter.ToInt32(table, 8);

            m_IndexTable.Position = m_tablehead.IndexTableOffset + 4;
            BinaryReader reader = new BinaryReader(m_IndexTable, Encoding.Default);

            int  count      = BitConverter.ToInt32(table, m_tablehead.IndexTableOffset);
            long TableBegin = m_IndexTable.Position;

            for (int i = 0; i < count; i++)
            {
                BBA bba = new BBA();
                bba.BBAEntryPositionInTable = m_IndexTable.Position;
                bba.Time                 = reader.ReadInt64();
                bba.UnpackedSize         = reader.ReadInt32();
                bba.UnpackedCRC32        = reader.ReadInt32();
                bba.Flags                = reader.ReadInt32();
                bba.Unknown1             = reader.ReadInt32();
                bba.Offset               = reader.ReadInt64();
                bba.PackedSize           = reader.ReadInt32();
                bba.PackedCRC32          = reader.ReadInt32();
                bba.Unknown2             = reader.ReadInt32();
                bba.Unknown3             = reader.ReadInt32();
                bba.PathSize             = reader.ReadInt32();
                bba.SizeOfPathToRootDir  = reader.ReadInt32();
                bba.IsFile               = reader.ReadInt32();
                bba.OffsetToNextFileName = reader.ReadInt32();
                byte[] filename = reader.ReadBytes(bba.PathSize);
                bba.FileName = Encoding.Default.GetString(filename);

                //if( ( bba.Unknown1 + bba.Unknown2 + bba.Unknown3 ) != 0 )
                //{
                //    listBox1.Items.Add("u1: " + bba.Unknown1.ToString() + "u2: " + bba.Unknown2.ToString() + "u3: " + bba.Unknown3.ToString());
                //}

                if (bba.IsFile == -1)
                {
                    m_pakList.Add(bba);
                }
                //else
                //{
                //    m_dirList.Add(bba);
                //}

                int pos = (int)m_IndexTable.Position + 1;
                int x   = (pos % 4);
                pos = (x == 0) ? 0 : 4 - x;
                m_IndexTable.Position += pos + 1;

                //if (bba.OffsetToNextFileName == -1)
                //    break;

                //m_IndexTable.Position = pos;//TableBegin + bba.OffsetToNextFileName;
            }
            listBox1.Items.Add("Files found: " + m_pakList.Count.ToString());
            m_IndexTable.Position = 0;
        }