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; }