/// <summary> /// Class Constructor /// </summary> /// <param name="file">The full path to the TPF file for reading</param> /// <param name="treefolder">The path to the directory containing the hash tree files</param> /// <param name="FormView">Should the class generate a form to view this TPF</param> public TPFExtract(String file, String treefolder, bool FormView) { _zippy = new ZipReader(file); Files = new List<string>(); foreach (ZipReader.ZipEntryFull entry in _zippy.Entries) Files.Add(entry.Filename); _trees = new List<HashTree>(); try { _trees.Add(new HashTree(Path.Combine(treefolder, "ME1Tree.hash"))); } catch (FileNotFoundException) { } try { _trees.Add(new HashTree(Path.Combine(treefolder, "ME2Tree.hash"))); } catch (FileNotFoundException) { } try { _trees.Add(new HashTree(Path.Combine(treefolder, "ME3Tree.hash"))); } catch (FileNotFoundException) { } _formview = FormView; if (_formview) { if (_trees.Count < 3) MessageBox.Show("Some of the hash files weren't found, some of the auto-matching options won't be available", "Missing files", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); TPFView form = new TPFView(this); form.Show(); } }
/// <summary> /// Class Constructor /// </summary> /// <param name="file">The full path to the TPF file for reading</param> /// <param name="treefolder">The path to the directory containing the hash tree files</param> /// <param name="FormView">Should the class generate a form to view this TPF</param> public TPFExtract(String file, String treefolder, bool FormView) { _zippy = new ZipReader(file); Files = new List <string>(); foreach (ZipReader.ZipEntryFull entry in _zippy.Entries) { Files.Add(entry.Filename); } _trees = new List <HashTree>(); try { _trees.Add(new HashTree(Path.Combine(treefolder, "ME1Tree.hash"))); } catch (FileNotFoundException) { } try { _trees.Add(new HashTree(Path.Combine(treefolder, "ME2Tree.hash"))); } catch (FileNotFoundException) { } try { _trees.Add(new HashTree(Path.Combine(treefolder, "ME3Tree.hash"))); } catch (FileNotFoundException) { } _formview = FormView; if (_formview) { if (_trees.Count < 3) { MessageBox.Show("Some of the hash files weren't found, some of the auto-matching options won't be available", "Missing files", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); } TPFView form = new TPFView(this); form.Show(); } }
public static void DecryptData(ZipReader.ZipEntry entry, byte[] block, int start, int count) { if (block == null || block.Length < count || count < 12) throw new ArgumentException("Invalid arguments for decryption"); crcgen = new CRC32(); InitCipher(tpfkey); DecryptBlock(block, start, 12); if (block[11] != (byte)((entry.CRC >> 24) & 0xff) && (entry.BitFlag & 0x8) != 0x8) throw new FormatException("Incorrect password"); DecryptBlock(block, start + 12, count - 12); }
public static void DecryptData(ZipReader.ZipEntry entry, byte[] block, int start, int count) { if (block == null || block.Length < count || count < 12) throw new ArgumentException("Invalid arguments for decryption"); InitCipher(tpfkey); DecryptBlock(block, start, 12); // KFreon: Apparently not required. Causes some TPF's to fail loading, but when commented out, TPF loads fine, so... /*if (block[11] != (byte)((entry.CRC >> 24) & 0xff) && (entry.BitFlag & 0x8) != 0x8) throw new FormatException("Incorrect password");*/ DecryptBlock(block, start + 12, count - 12); }
/// <summary> /// Constructor for TPF texture objects. /// </summary> /// <param name="filename">Filename of texture.</param> /// <param name="tpfind">Index of texture inside TPF, if applicable.</param> /// <param name="path">Path of texture, if applicable.</param> /// <param name="zip">Zippy of TPF, if applicable.</param> public TPFTexInfo(string filename, int tpfind, string path, ZipReader zip, int WhichGame) { FileName = filename; TPFInd = tpfind; FilePath = path; Files = new List <string>(); ExpIDs = new List <int>(); Thumbnail = new MemoryStream(); OriginalExpIDs = new List <int>(); OriginalFiles = new List <string>(); FileDuplicates = new List <TPFTexInfo>(); TreeDuplicates = new List <int>(); zippy = zip; GameVersion = WhichGame; }
public ZipEntryFull(byte[] entry, ZipReader par) : base(par) { if (BitConverter.ToUInt32(entry, 0) != dirfileheadermagic) { throw new FormatException("Incorrect header"); } Buildvers = BitConverter.ToUInt16(entry, 4); Minvers = BitConverter.ToUInt16(entry, 6); BitFlag = BitConverter.ToUInt16(entry, 8); ComprMethod = BitConverter.ToUInt16(entry, 10); ModifyTime = BitConverter.ToUInt16(entry, 12); ModifyDate = BitConverter.ToUInt16(entry, 14); CRC = BitConverter.ToUInt32(entry, 16); ComprSize = BitConverter.ToUInt32(entry, 20); UncomprSize = BitConverter.ToUInt32(entry, 24); ushort namelen = BitConverter.ToUInt16(entry, 28); ushort extralen = BitConverter.ToUInt16(entry, 30); ushort commlen = BitConverter.ToUInt16(entry, 32); DiskStart = BitConverter.ToUInt16(entry, 34); InternalAttr = BitConverter.ToUInt16(entry, 36); ExternalAttr = BitConverter.ToUInt32(entry, 38); FileOffset = BitConverter.ToUInt32(entry, 42); char[] strbuild = new char[namelen]; for (int i = 0; i < namelen; i++) { strbuild[i] = (char)entry[46 + i]; } Filename = new string(strbuild); Extra = new byte[extralen]; for (int i = 0; i < extralen; i++) { Extra[i] = entry[46 + namelen + i]; } strbuild = new char[commlen]; for (int i = 0; i < commlen; i++) { strbuild[i] = (char)entry[46 + namelen + extralen + i]; } Comment = new string(strbuild); }
public static byte[] DecryptData(ZipReader.ZipEntry entry, byte[] block, int start, int count) { if (block == null || block.Length < count || count < 12) throw new ArgumentException("Invalid arguments for decryption"); UInt32[] Keys = InitCipher(tpfkey); // Decrypt crypt header DecryptBlock(block, start, 12, Keys); // 12 = crypt header size // KFreon: Testing header //Console.WriteLine($"crypt header crc: {block[start + 10]}, {block[start + 11]}"); // KFreon: Doesn't seem to require this /*if (block[11] != (byte)((entry.CRC >> 24) & 0xff) && (entry.BitFlag & 0x8) != 0x8) Console.WriteLine("Incorrect password");*/ DecryptBlock(block, start + 12, count - 12, Keys); // Decrypt main block after crypt header return block; }
public ZipEntryFull(byte[] entry, ZipReader par) : base(par) { if (BitConverter.ToUInt32(entry, 0) != dirfileheadermagic) throw new FormatException("Incorrect header"); Buildvers = BitConverter.ToUInt16(entry, 4); Minvers = BitConverter.ToUInt16(entry, 6); BitFlag = BitConverter.ToUInt16(entry, 8); ComprMethod = BitConverter.ToUInt16(entry, 10); ModifyTime = BitConverter.ToUInt16(entry, 12); ModifyDate = BitConverter.ToUInt16(entry, 14); CRC = BitConverter.ToUInt32(entry, 16); ComprSize = BitConverter.ToUInt32(entry, 20); UncomprSize = BitConverter.ToUInt32(entry, 24); ushort namelen = BitConverter.ToUInt16(entry, 28); ushort extralen = BitConverter.ToUInt16(entry, 30); ushort commlen = BitConverter.ToUInt16(entry, 32); DiskStart = BitConverter.ToUInt16(entry, 34); InternalAttr = BitConverter.ToUInt16(entry, 36); ExternalAttr = BitConverter.ToUInt32(entry, 38); FileOffset = BitConverter.ToUInt32(entry, 42); char[] strbuild = new char[namelen]; for (int i = 0; i < namelen; i++) strbuild[i] = (char)entry[46 + i]; Filename = new string(strbuild); Extra = new byte[extralen]; for (int i = 0; i < extralen; i++) Extra[i] = entry[46 + namelen + i]; strbuild = new char[commlen]; for (int i = 0; i < commlen; i++) strbuild[i] = (char)entry[46 + namelen + extralen + i]; Comment = new string(strbuild); }
public byte[] Extract(bool Preview, String outname = null) { byte[] databuff; int dataoff = 30; if (Filename != null) { dataoff += Filename.Length; } if (Extra != null) { dataoff += Extra.Length; } using (FileStream tpf = new FileStream(_par._filename, FileMode.Open, FileAccess.Read)) { tpf.Seek(FileOffset, SeekOrigin.Begin); databuff = ZipReader.BuffXOR(tpf, dataoff + (int)ComprSize + 16); // XOR the whole data block as well as the footer } // Check for correct header data and such ZipEntry fileentry = new ZipEntry(databuff); if (!fileentry.Compare(this)) { throw new InvalidDataException("File header not as expected"); } if (BitConverter.ToUInt32(databuff, (int)ComprSize + dataoff) != datadescriptormagic) { throw new InvalidDataException("Footer not as expected"); } //ZipCrypto.DecryptData(this, databuff, dataoff, (int)ComprSize); KFreonZipCrypto crypto = new KFreonZipCrypto(this, databuff, dataoff, (int)ComprSize); databuff = crypto.GetBlocks(); databuff = Deflate(databuff, 12 + dataoff, (int)ComprSize - 12); if (databuff.Length != UncomprSize) { throw new InvalidDataException("Deflation resulted in incorrect file size"); } CRC32 crcgen = new CRC32(); if (crcgen.BlockChecksum(databuff, 0, (int)UncomprSize) != CRC) { throw new InvalidDataException("Checksums don't match"); } if (!Preview) { outname = outname ?? Filename; using (FileStream fs = new FileStream(outname, FileMode.Create, FileAccess.Write)) { fs.Write(databuff, 0, (int)UncomprSize); } return(null); } else { return(databuff); } }
/// <summary> /// Constructor for TPF texture objects. /// </summary> /// <param name="filename">Filename of texture.</param> /// <param name="tpfind">Index of texture inside TPF, if applicable.</param> /// <param name="path">Path of texture, if applicable.</param> /// <param name="zip">Zippy of TPF, if applicable.</param> public TPFTexInfo(string filename, int tpfind, string path, ZipReader zip, int WhichGame) { FileName = filename; TPFInd = tpfind; FilePath = path; Files = new List<string>(); ExpIDs = new List<int>(); Thumbnail = new MemoryStream(); OriginalExpIDs = new List<int>(); OriginalFiles = new List<string>(); FileDuplicates = new List<TPFTexInfo>(); TreeDuplicates = new List<int>(); zippy = zip; GameVersion = WhichGame; }
public ZipEntryFull(byte[] entry, ZipReader par) : base(par) { if (BitConverter.ToUInt32(entry, 0) != dirfileheadermagic) throw new FormatException("Incorrect header"); Buildvers = BitConverter.ToUInt16(entry, 4); Minvers = BitConverter.ToUInt16(entry, 6); BitFlag = BitConverter.ToUInt16(entry, 8); ComprMethod = BitConverter.ToUInt16(entry, 10); ModifyTime = BitConverter.ToUInt16(entry, 12); ModifyDate = BitConverter.ToUInt16(entry, 14); CRC = BitConverter.ToUInt32(entry, 16); ComprSize = BitConverter.ToUInt32(entry, 20); UncomprSize = BitConverter.ToUInt32(entry, 24); ushort namelen = BitConverter.ToUInt16(entry, 28); ushort extralen = BitConverter.ToUInt16(entry, 30); ushort commlen = BitConverter.ToUInt16(entry, 32); DiskStart = BitConverter.ToUInt16(entry, 34); InternalAttr = BitConverter.ToUInt16(entry, 36); ExternalAttr = BitConverter.ToUInt32(entry, 38); FileOffset = BitConverter.ToUInt32(entry, 42); char[] strbuild = new char[namelen]; for (int i = 0; i < namelen; i++) strbuild[i] = (char)entry[46 + i]; Filename = new string(strbuild); Extra = new byte[extralen]; for (int i = 0; i < extralen; i++) Extra[i] = entry[46 + namelen + i]; strbuild = new char[commlen]; for (int i = 0; i < commlen; i++) strbuild[i] = (char)entry[46 + namelen + extralen + i]; Comment = new string(strbuild); // KFreon: Debugging /*Console.WriteLine(Filename); Console.WriteLine($"build = {Buildvers}"); Console.WriteLine($"minvers = {Minvers}"); Console.WriteLine($"bitflag = {BitFlag}"); Console.WriteLine($"compr = {ComprMethod}"); Console.WriteLine($"modifytime = {ModifyTime}"); Console.WriteLine($"modifydate = {ModifyDate}"); Console.WriteLine($"crc = {CRC}"); Console.WriteLine($"comprsize = {ComprSize}"); Console.WriteLine($"uncsize = {UncomprSize}"); Console.WriteLine($"namelen = {namelen}"); Console.WriteLine($"extralen = {extralen}"); Console.WriteLine($"commlen = {commlen}"); Console.WriteLine($"diskstart = {DiskStart}"); Console.WriteLine($"internal = {InternalAttr}"); Console.WriteLine($"external = {ExternalAttr}"); Console.WriteLine($"file offset = {FileOffset}"); Console.WriteLine($"extra = {Extra}"); Console.WriteLine($"comment = {Comment}"); Console.WriteLine();*/ }
public ZipEntry(ZipReader par) { _par = par; }
private void PreviewDef(ZipReader.ZipEntryFull ent) { try { byte[] data = ent.Extract(true); if (data == null) throw new NullReferenceException("Data returned was null"); pictureBox1.Visible = false; char[] chars = new char[data.Length]; for (int i = 0; i < data.Length; i++) chars[i] = (char)data[i]; rtb1.Text = "Texmod.def contents:\n\n" + new string(chars); } catch (Exception exc) { MessageBox.Show("An error occurred: " + exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
private void PreviewImg(ZipReader.ZipEntryFull ent) { }
public TPFTexInfo(string file, ZipReader.ZipEntryFull entry, MEDirectories.MEDirectories gameDirecs) : this(gameDirecs) { ZipEntry = entry; if (Path.IsPathRooted(file)) { FilePath = Path.GetDirectoryName(file); FileName = Path.GetFileName(file); } else FileName = file; }
private void PreviewTex(ZipReader.ZipEntryFull ent, bool dds) { try { Bitmap img; if (dds) { byte[] data = ent.Extract(true); if (data == null) throw new NullReferenceException("Data returned was null"); using (ImageEngineImage ddsimg = new ImageEngineImage(data)) img = ddsimg.GetGDIBitmap(true); } else { ent.Extract(false, "preview.tga"); img = new TargaImage("preview.tga").Image; File.Delete("preview.tga"); } if (pictureBox1.Image != null) pictureBox1.Image.Dispose(); if (_resize) pictureBox1.Image = resizeImage(img, new System.Drawing.Size(512, 512)); else pictureBox1.Image = img; pictureBox1.Visible = true; pictureBox1.Refresh(); } catch (Exception exc) { MessageBox.Show("An error occurred: " + exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public ZipEntryFull(byte[] entry, ZipReader par) : base(par) { if (BitConverter.ToUInt32(entry, 0) != dirfileheadermagic) { throw new FormatException("Incorrect header"); } Buildvers = BitConverter.ToUInt16(entry, 4); Minvers = BitConverter.ToUInt16(entry, 6); BitFlag = BitConverter.ToUInt16(entry, 8); ComprMethod = BitConverter.ToUInt16(entry, 10); ModifyTime = BitConverter.ToUInt16(entry, 12); ModifyDate = BitConverter.ToUInt16(entry, 14); CRC = BitConverter.ToUInt32(entry, 16); ComprSize = BitConverter.ToUInt32(entry, 20); UncomprSize = BitConverter.ToUInt32(entry, 24); ushort namelen = BitConverter.ToUInt16(entry, 28); ushort extralen = BitConverter.ToUInt16(entry, 30); ushort commlen = BitConverter.ToUInt16(entry, 32); DiskStart = BitConverter.ToUInt16(entry, 34); InternalAttr = BitConverter.ToUInt16(entry, 36); ExternalAttr = BitConverter.ToUInt32(entry, 38); FileOffset = BitConverter.ToUInt32(entry, 42); char[] strbuild = new char[namelen]; for (int i = 0; i < namelen; i++) { strbuild[i] = (char)entry[46 + i]; } Filename = new string(strbuild); Extra = new byte[extralen]; for (int i = 0; i < extralen; i++) { Extra[i] = entry[46 + namelen + i]; } strbuild = new char[commlen]; for (int i = 0; i < commlen; i++) { strbuild[i] = (char)entry[46 + namelen + extralen + i]; } Comment = new string(strbuild); // KFreon: Debugging /*Console.WriteLine(Filename); * Console.WriteLine($"build = {Buildvers}"); * Console.WriteLine($"minvers = {Minvers}"); * Console.WriteLine($"bitflag = {BitFlag}"); * Console.WriteLine($"compr = {ComprMethod}"); * Console.WriteLine($"modifytime = {ModifyTime}"); * Console.WriteLine($"modifydate = {ModifyDate}"); * Console.WriteLine($"crc = {CRC}"); * Console.WriteLine($"comprsize = {ComprSize}"); * Console.WriteLine($"uncsize = {UncomprSize}"); * Console.WriteLine($"namelen = {namelen}"); * Console.WriteLine($"extralen = {extralen}"); * Console.WriteLine($"commlen = {commlen}"); * Console.WriteLine($"diskstart = {DiskStart}"); * Console.WriteLine($"internal = {InternalAttr}"); * Console.WriteLine($"external = {ExternalAttr}"); * Console.WriteLine($"file offset = {FileOffset}"); * Console.WriteLine($"extra = {Extra}"); * Console.WriteLine($"comment = {Comment}"); * Console.WriteLine();*/ }
public byte[] Extract(bool Preview, String outname = null) { byte[] databuff; int dataoff = 30; // For ZipEntry header - not the above one if (Filename != null) { dataoff += Filename.Length; } if (Extra != null) { dataoff += Extra.Length; } // KFreon: Use stored MemoryStream if possible. Stream tpf = null; if (_par.FileData == null) { tpf = new FileStream(_par._filename, FileMode.Open, FileAccess.Read); } else { tpf = new MemoryStream(_par.FileData); } tpf.Seek(FileOffset, SeekOrigin.Begin); databuff = ZipReader.BuffXOR(tpf, dataoff + (int)ComprSize + 16); // XOR the whole data block as well as the footer // KFreon: Dispose of stream IF it was a FileStream if (_par.FileData == null) { tpf.Dispose(); } // Check for correct header data and such ZipEntry fileentry = new ZipEntry(databuff); if (!fileentry.Compare(this)) { throw new InvalidDataException("File header not as expected"); } // KFreon: Apparently not necessary. Some TPF's fail to load with this, but when commented out, they load fine, so... /*if (BitConverter.ToUInt32(databuff, (int)ComprSize + dataoff) != datadescriptormagic) * Console.WriteLine("Footer not as expected");*/ ZipDecrypto crypto = new ZipDecrypto(this, databuff, dataoff, (int)ComprSize); databuff = crypto.GetBlocks(); databuff = Deflate(databuff, 12 + dataoff, (int)ComprSize - 12); if (databuff.Length != UncomprSize) { throw new InvalidDataException("Deflation resulted in incorrect file size"); } CRC32 crcgen = new CRC32(); if (crcgen.BlockChecksum(databuff, 0, (int)UncomprSize) != CRC) { throw new InvalidDataException("Checksums don't match"); } if (!Preview) { outname = outname ?? Filename; using (FileStream fs = new FileStream(outname, FileMode.Create, FileAccess.Write)) { fs.Write(databuff, 0, (int)UncomprSize); } return(null); } else { return(databuff); } }
public KFreonZipCrypto(ZipReader.ZipEntry entry, byte[] block, int start, int count) { Blocks = DecryptData(entry, block, start, count); }