From c20e404aa161d4db8ce2fb0c854351a36bb59f50 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 5 Jul 2007 09:35:31 +0000 Subject: [PATCH] fixes alignment while reading from MIX git-svn-id: svn://svn.ijw.co.nz/svn/OpenRa@1098 993157c7-ee19-0410-b2c4-bb4e9862e678 --- OpenRa.FileFormats/Map.cs | 2 - OpenRa.FileFormats/OpenRa.FileFormats.csproj | 1 + OpenRa.FileFormats/Package.cs | 79 +++++++++----------- 3 files changed, 37 insertions(+), 45 deletions(-) diff --git a/OpenRa.FileFormats/Map.cs b/OpenRa.FileFormats/Map.cs index 44354dac31..ef1e935773 100644 --- a/OpenRa.FileFormats/Map.cs +++ b/OpenRa.FileFormats/Map.cs @@ -52,7 +52,6 @@ namespace OpenRa.FileFormats } byte[] data = Convert.FromBase64String( sb.ToString() ); - Console.WriteLine( "Format80 data: {0}", data.Length ); List chunks = new List(); @@ -69,7 +68,6 @@ namespace OpenRa.FileFormats int actualLength = Format80.DecodeInto( new MemoryStream( src ), dest ); chunks.Add( dest ); - Console.WriteLine( "Chunk length: {0}", actualLength ); } } catch( EndOfStreamException ) { } diff --git a/OpenRa.FileFormats/OpenRa.FileFormats.csproj b/OpenRa.FileFormats/OpenRa.FileFormats.csproj index 30dea7ef72..9ac47d6448 100644 --- a/OpenRa.FileFormats/OpenRa.FileFormats.csproj +++ b/OpenRa.FileFormats/OpenRa.FileFormats.csproj @@ -35,6 +35,7 @@ + diff --git a/OpenRa.FileFormats/Package.cs b/OpenRa.FileFormats/Package.cs index a3fb91a138..92f8367306 100644 --- a/OpenRa.FileFormats/Package.cs +++ b/OpenRa.FileFormats/Package.cs @@ -11,6 +11,7 @@ namespace OpenRa.FileFormats readonly string filename; readonly List index; readonly bool isRmix, isEncrypted; + readonly long dataStart; public ICollection Content { @@ -30,26 +31,23 @@ namespace OpenRa.FileFormats if (isRmix) { isEncrypted = 0 != (signature & (uint)MixFileFlags.Encrypted); - index = ParseRaHeader(s); - } - else - { - isEncrypted = false; - s.Seek(0, SeekOrigin.Begin); - index = ParseTdHeader(s); + if( isEncrypted ) + { + index = ParseRaHeader( s, out dataStart ); + return; + } } + + isEncrypted = false; + s.Seek(0, SeekOrigin.Begin); + index = ParseTdHeader(s, out dataStart); } } - List ParseRaHeader(Stream s) - { - if (!isEncrypted) - { - Console.WriteLine("RA, not encrypted"); - return ParseTdHeader(s); - } + const long headerStart = 84; - long headerStart = 84; + List ParseRaHeader(Stream s, out long dataStart) + { BinaryReader reader = new BinaryReader(s); byte[] keyblock = reader.ReadBytes(80); byte[] blowfishKey = MixDecrypt.MixDecrypt.BlowfishKey(keyblock); @@ -57,15 +55,7 @@ namespace OpenRa.FileFormats uint[] h = ReadUints(reader, 2); Blowfish fish = new Blowfish(blowfishKey); - uint[] decrypted = fish.Decrypt(h); - - MemoryStream ms = new MemoryStream(); - BinaryWriter writer = new BinaryWriter(ms); - foreach (uint t in decrypted) - writer.Write(t); - writer.Flush(); - - ms.Position = 0; + MemoryStream ms = Decrypt( h, fish ); BinaryReader reader2 = new BinaryReader(ms); ushort numFiles = reader2.ReadUInt16(); @@ -76,18 +66,29 @@ namespace OpenRa.FileFormats s.Position = headerStart; reader = new BinaryReader(s); - h = ReadUints(reader, 2 + numFiles * PackageEntry.Size / 4); - decrypted = fish.Decrypt(h); + int byteCount = 6 + numFiles * PackageEntry.Size; + h = ReadUints( reader, ( byteCount + 3 ) / 4 ); - ms = new MemoryStream(); - writer = new BinaryWriter(ms); - foreach (uint t in decrypted) - writer.Write(t); + ms = Decrypt( h, fish ); + + dataStart = headerStart + byteCount + ( ( ~byteCount + 1 ) & 7 ); + + long ds; + return ParseTdHeader( ms, out ds ); + } + + static MemoryStream Decrypt( uint[] h, Blowfish fish ) + { + uint[] decrypted = fish.Decrypt( h ); + + MemoryStream ms = new MemoryStream(); + BinaryWriter writer = new BinaryWriter( ms ); + foreach( uint t in decrypted ) + writer.Write( t ); writer.Flush(); ms.Position = 0; - - return ParseTdHeader(ms); + return ms; } uint[] ReadUints(BinaryReader r, int count) @@ -99,7 +100,7 @@ namespace OpenRa.FileFormats return ret; } - List ParseTdHeader(Stream s) + List ParseTdHeader(Stream s, out long dataStart) { List items = new List(); @@ -110,6 +111,7 @@ namespace OpenRa.FileFormats for (int i = 0; i < numFiles; i++) items.Add(new PackageEntry(reader)); + dataStart = s.Position; return items; } @@ -120,16 +122,7 @@ namespace OpenRa.FileFormats { using (Stream s = File.OpenRead(filename)) { - s.Seek(2 + 4 + (isRmix ? 4 : 0), SeekOrigin.Begin); - - s.Seek(2, SeekOrigin.Current); //dword align - s.Seek( 4, SeekOrigin.Current ); //wtf, i dont know why i need this either :( - - if( isEncrypted ) - s.Seek(80, SeekOrigin.Current); - - s.Seek( index.Count * PackageEntry.Size + e.Offset, SeekOrigin.Current ); - + s.Seek( dataStart + e.Offset, SeekOrigin.Begin ); byte[] data = new byte[ e.Length ]; s.Read( data, 0, (int)e.Length ); return new MemoryStream(data);