private FileStream OpenBBAFile(string path) { FileStream f = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); f.Position = 0; f.Read(b_head, 0, b_head.Length); //Read header. int h = BitConverter.ToInt32(b_head, 0); if (h == s7_bba_head_sig) { BinaryReader reader = new BinaryReader(f); //Add: header reading code. //Fill: PAKHead.... m_head.Header = Encoding.Default.GetString(b_head, 0, 4); m_head.Version = BitConverter.ToInt32(b_head, 4); m_head.HeaderSize = BitConverter.ToInt32(b_head, 8); m_head.Magic = BitConverter.ToInt32(b_head, 12); if (m_head.Magic == s7_bba_head_magic) { listBox1.Items.Add("BBA container opened."); f.Read(b_header, 0, b_header.Length); BBACrypt.DecryptHeader(b_header, b_header.Length, b_head, b_head.Length); m_header.IndexTableOffset = BitConverter.ToInt64(b_header, 0); m_header.IndexTableSize = BitConverter.ToInt32(b_header, 8); m_header.IndexTableCRC32 = BitConverter.ToInt32(b_header, 12); m_header.Magic = BitConverter.ToUInt32(b_header, 16); m_header.Magic2 = BitConverter.ToUInt32(b_header, 20); if (m_header.Magic == s7_bba_header_magic && m_header.Magic2 == s7_bba_header_magic2) { return(f); } else { listBox1.Items.Add(String.Format("BBA container contains bad magic value: {0:X} {1:X}", m_header.Magic, m_header.Magic2)); } } else { listBox1.Items.Add(String.Format("BBA container contains bad magic value: {0:X}", m_head.Magic)); } } else { listBox1.Items.Add("Not Settlers 7 .BBA file"); } f.Close(); f.Dispose(); return(null); }
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); }
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; }
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { BBACrypt.SetMode(comboBox1.SelectedIndex); }
private void BuildBBA(object obj) { DisableControls(); string saveTo = saveFileDialog1.FileName; string openDir = folderBrowserDialog1.SelectedPath; try { m_fs = new FileStream(saveTo, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); m_fs.Position = 0; m_fs.Write(new byte[0x50], 0, 0x50); int idx = listBox1.Items.Add("Getting Files Info..."); ClearMembers(); int aproxsize = 0; GetFilesInfo(new DirectoryInfo(openDir), ref aproxsize); listBox1.Items[idx] += "OK"; int count = m_pakList.Count; int refresh = 0; int counter = 0; this.progressBar1.Maximum = count; this.progressBar1.Value = 0; this.progressBar1.Step = 1; idx = listBox1.Items.Add("writing data..."); for (int i = 0; i < count; i++) { BBA bba = ( BBA )m_pakList[i]; if (bba.IsFile == -1) { string file = openDir + "\\" + bba.FileName; FileStream f1 = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); f1.Position = 0; bba.UnpackedCRC32 = Compression.GetStreamCRC32(f1); f1.Position = 0; bba.Offset = m_fs.Position; bba.PackedSize = WriteFile(m_fs, f1, new FileInfo(file)); if (bba.PackedSize != bba.UnpackedSize) { bba.Flags = 1; } m_fs.Flush(); f1.Close(); m_pakList[i] = bba; } this.progressBar1.PerformStep(); if (refresh == 100) { this.progressBar1.Refresh(); this.listBox1.Refresh(); refresh = 0; } refresh++; counter++; } listBox1.Items[idx] += "OK"; m_header.IndexTableOffset = m_fs.Position; refresh = 0; counter = 0; this.progressBar1.Maximum = count; this.progressBar1.Value = 0; this.progressBar1.Step = 1; idx = listBox1.Items.Add("Generating Index Table and Encrypting Headers..."); m_IndexTable = new MemoryStream(); m_IndexTable.Write(new byte[0x110], 0, 0x110); m_IndexTable.Write(BitConverter.GetBytes(count), 0, 4); int OffsetToNextEntry = 0; for (int i = 0; i < count; i++) { BBA bba = ( BBA )m_pakList[i]; byte[] entry = BuildEntry(bba); if (bba.Flags == 1) { byte[] dataheader = new byte[0x10]; m_fs.Position = bba.Offset; m_fs.Read(dataheader, 0, dataheader.Length); BBACrypt.EncryptFileHeader(dataheader, dataheader.Length, entry, entry.Length); m_fs.Position = bba.Offset; m_fs.Write(dataheader, 0, dataheader.Length); m_fs.Position = bba.Offset; bba.PackedCRC32 = Compression.GetStreamCRC32(m_fs, bba.PackedSize); } else { bba.PackedSize = bba.UnpackedSize; bba.PackedCRC32 = bba.UnpackedCRC32; } OffsetToNextEntry += entry.Length; OffsetToNextEntry += bba.PathSize + 1; int pos = ( int )m_IndexTable.Position; pos += bba.PathSize + 0x40 + 1; int x = (pos % 4); pos = (x == 0) ? 0 : 4 - x; OffsetToNextEntry += pos; bba.BBAEntryPositionInTable = m_IndexTable.Position; if (bba.IsFile == -1) { if (bba.OffsetToNextFileName != -1) { bba.OffsetToNextFileName = OffsetToNextEntry; } } m_pakList[i] = bba; entry = BuildEntry(bba); m_IndexTable.Write(entry, 0, entry.Length); m_IndexTable.Write(Encoding.Default.GetBytes(bba.FileName), 0, bba.PathSize); m_IndexTable.Write(new byte[pos + 1], 0, pos + 1); this.progressBar1.PerformStep(); if (refresh == 100) { this.progressBar1.Refresh(); this.listBox1.Refresh(); refresh = 0; } refresh++; counter++; } int HashTablePosition = ( int )m_IndexTable.Position; byte[] hashtable = BuildHashTable(); m_IndexTable.Write(hashtable, 0, hashtable.Length); BinaryWriter bw = new BinaryWriter(m_IndexTable); m_IndexTable.Position = 0; bw.Write(( int )0x40); bw.Write(( int )0x110); bw.Write(HashTablePosition); m_IndexTable.Position = 0x40; bw.Write(c_bbaHead, 0, c_bbaHead.Length); m_IndexTable.Position = 0x60; bw.Write(s7_bba_header_magic); bw.Write(s7_bba_header_magic2); m_IndexTable.Position = 0x94; bw.Write(s7_bba_magic1); bw.Write(s7_bba_header_magic); m_IndexTable.Position = 0; int IndexTableAlignedSize = (int)m_IndexTable.Length; int len = (int)m_IndexTable.Length; len = (len % 4); len = (len == 0) ? 0 : 4 - len; if (len != 0) { IndexTableAlignedSize += len; } // bw = new BinaryWriter( m_IndexTable ); // bw.Write( ( int )m_IndexTable.Length ); m_header.IndexTableSize = IndexTableAlignedSize; m_IndexTable.Capacity = IndexTableAlignedSize; byte[] idxtable = m_IndexTable.GetBuffer(); bool res = BBACrypt.EncryptIndexTable(idxtable, m_header.IndexTableSize, null, 0); m_header.IndexTableCRC32 = GetCRC32(idxtable); m_header.Magic = s7_bba_header_magic; m_header.Magic2 = s7_bba_header_magic2; m_fs.Position = m_header.IndexTableOffset; m_fs.Write(idxtable, 0, idxtable.Length); m_fs.Position = 0; m_fs.Write(c_bbaHead, 0, c_bbaHead.Length); byte[] header = BuildHeader(); BBACrypt.EncryptHeader(header, header.Length, c_bbaHead, c_bbaHead.Length); m_fs.Write(header, 0, header.Length); listBox1.Items[idx] += "OK"; listBox1.Items.Add("BBA file successfully created."); } catch (Exception e) { listBox1.Items.Add(e.Message); } m_fs.Close(); m_fs = null; EnableControls(); GC.Collect(); }