static void BuildTPF(Stream ms, string Author, string Comment, List <WriterZipEntry> Entries) { uint cdlen = 0; uint cdpos = (uint)ms.Position; for (int i = 0; i < Entries.Count; i++) { // Create and write Full entry header ms.Write(BitConverter.GetBytes(ZipReader.dirfileheadermagic), 0, 4); ms.Write(BitConverter.GetBytes(0), 0, 2); ms.Write(BitConverter.GetBytes(ZipWriter.MinVers), 0, 2); ms.Write(BitConverter.GetBytes(ZipWriter.BitFlag), 0, 2); ms.Write(BitConverter.GetBytes(ZipWriter.ComprMethod), 0, 2); ZipWriter.WriterZipEntry entry = Entries[i]; WriteGlobalEntryHeader(entry, ms); } cdlen = (uint)(ms.Position - cdpos); // EOF Record ms.Write(BitConverter.GetBytes(ZipReader.endofdirmagic), 0, 4); ms.Write(BitConverter.GetBytes(0), 0, 4); // Disk No = 0, // Start disk = 0 ms.Write(BitConverter.GetBytes((ushort)Entries.Count), 0, 2); ms.Write(BitConverter.GetBytes((ushort)Entries.Count), 0, 2); ms.Write(BitConverter.GetBytes(cdlen), 0, 4); ms.Write(BitConverter.GetBytes(cdpos), 0, 4); // KFreon: This is the created by/comment section. Seems to be required for Texmod. string createdByANDComment = Author + "\r\n" + Comment; // KFreon: Newline required by Texmod to seperate author and comment. byte[] bytes = Encoding.Default.GetBytes(createdByANDComment); ms.Write(BitConverter.GetBytes(createdByANDComment.Length), 0, 2); ms.Write(bytes, 0, bytes.Length); long streamlen = ms.Length; ms.Seek(0, SeekOrigin.Begin); // XOR the file // Why this way? Shouldn't be done like this while (ms.Position < ms.Length) { int count = (ms.Position + 10000 <= ms.Length) ? 10000 : (int)(ms.Length - ms.Position); byte[] buff2 = BuffXOR(ms, count); ms.Seek(-count, SeekOrigin.Current); ms.Write(buff2, 0, count); } }
static void WriteGlobalEntryHeader(ZipWriter.WriterZipEntry entry, Stream ms) { ms.Write(BitConverter.GetBytes(entry.Time), 0, 2); ms.Write(BitConverter.GetBytes(entry.Date), 0, 2); ms.Write(BitConverter.GetBytes(entry.CRC32), 0, 4); ms.Write(BitConverter.GetBytes(entry.ComprLen), 0, 4); ms.Write(BitConverter.GetBytes(entry.UncLen), 0, 4); ms.Write(BitConverter.GetBytes((ushort)entry.Filename.Length), 0, 2); ms.Write(BitConverter.GetBytes(0), 0, 4); // 0 for extra field, 0 for comment ms.Write(BitConverter.GetBytes(0), 0, 4); // 0 for disk no, 0 for internal attributes ms.Write(BitConverter.GetBytes(ExternalAttr), 0, 4); ms.Write(BitConverter.GetBytes((int)entry.MainOffset), 0, 4); foreach (char c in entry.Filename) { ms.WriteByte((byte)c); } }