示例#1
0
        static WriterZipEntry BuildEntry(Stream ms, string file, Func <byte[]> dataGetter)
        {
            bool FileOnDisk = dataGetter == null;

            WriterZipEntry entry = new WriterZipEntry();

            entry.MainOffset = ms.Position;
            entry.Filename   = FileOnDisk ? Path.GetFileName(file) : file;

            //Header
            ms.Write(BitConverter.GetBytes(ZipReader.filemagic), 0, 4);
            ms.Write(BitConverter.GetBytes(MinVers), 0, 2);
            ms.Write(BitConverter.GetBytes(BitFlag), 0, 2);
            ms.Write(BitConverter.GetBytes(ComprMethod), 0, 2);

            //Date/time
            DateTime date  = FileOnDisk ? new FileInfo(file).LastWriteTime : DateTime.Now;
            ushort   secs  = 0;
            ushort   mins  = 0;
            ushort   hours = 0;

            ushort day   = 0;
            ushort month = 0;
            ushort year  = 0;

            secs  = (ushort)date.Second;
            mins  = (ushort)date.Minute;
            hours = (ushort)date.Hour;

            ushort datetime = (ushort)(secs / 2);

            datetime |= (ushort)(mins >> 5);
            datetime |= (ushort)(hours >> 11);
            ms.Write(BitConverter.GetBytes(datetime), 0, 2);
            entry.Time = datetime;

            day   = (ushort)date.Day;
            month = (ushort)date.Month;
            year  = (ushort)date.Year;

            datetime  = day;
            datetime &= (ushort)(month >> 5);
            datetime &= (ushort)(year >> 9);
            ms.Write(BitConverter.GetBytes(datetime), 0, 2);
            entry.Date = datetime;

            byte[] comprData;
            Stream dataStream = null;

            if (FileOnDisk)
            {
                dataStream = new FileStream(file, FileMode.Open, FileAccess.Read);
            }
            else
            {
                dataStream = new MemoryStream(dataGetter());
            }

            using (dataStream)
            {
                byte[] buff = new byte[dataStream.Length];
                dataStream.Read(buff, 0, buff.Length);

                // create and write local header
                entry.CRC32  = crc.BlockChecksum(buff);
                entry.UncLen = (UInt32)dataStream.Length;

                ms.Write(BitConverter.GetBytes(entry.CRC32), 0, 4);

                ms.Seek(4, SeekOrigin.Current); // Skip compressed size
                ms.Write(BitConverter.GetBytes(entry.UncLen), 0, 4);

                if (entry.Filename.ToLower().Contains("meresults"))
                {
                    entry.Filename = "texmod.def";
                }

                ms.Write(BitConverter.GetBytes((ushort)entry.Filename.Length), 0, 2);
                ms.Write(BitConverter.GetBytes((ushort)0), 0, 2);  // extra

                // Filename
                foreach (char c in entry.Filename)
                {
                    ms.WriteByte((byte)c);
                }

                dataStream.Seek(0, SeekOrigin.Begin); // Rewind to compress entry
                using (MemoryStream ms2 = new MemoryStream())
                {
                    using (DeflateStream deflator = new DeflateStream(ms2, CompressionMode.Compress))
                        dataStream.CopyTo(deflator);

                    comprData = ms2.ToArray();
                }
                entry.ComprLen = (uint)comprData.Length + 12;      // 12 is crypt header
                ZipCrypto.EncryptData(ms, comprData, entry.CRC32); // Encrypt and write data
            }

            // Footer
            ms.Write(BitConverter.GetBytes(ZipReader.datadescriptormagic), 0, 4);
            ms.Write(BitConverter.GetBytes(entry.CRC32), 0, 4);
            ms.Write(BitConverter.GetBytes(entry.ComprLen), 0, 4);
            ms.Write(BitConverter.GetBytes(entry.UncLen), 0, 4);

            // Go back and write compressed length
            ms.Seek(entry.MainOffset + 18, SeekOrigin.Begin);
            ms.Write(BitConverter.GetBytes(entry.ComprLen), 0, 4);

            // Go to end for next entry
            ms.Seek(0, SeekOrigin.End);
            return(entry);
        }
示例#2
0
        //public const UInt32 ExternalAttr = 0x81B40020;  // Texmod uses this one but ours won't work if we do...

        static WriterZipEntry BuildEntry(Stream ms, string file, Func<byte[]> dataGetter)
        {
            bool FileOnDisk = dataGetter == null;

            WriterZipEntry entry = new WriterZipEntry();
            entry.MainOffset = ms.Position;
            entry.Filename = FileOnDisk ? Path.GetFileName(file) : file;

            //Header
            ms.Write(BitConverter.GetBytes(ZipReader.filemagic), 0, 4);
            ms.Write(BitConverter.GetBytes(MinVers), 0, 2);
            ms.Write(BitConverter.GetBytes(BitFlag), 0, 2);
            ms.Write(BitConverter.GetBytes(ComprMethod), 0, 2);

            //Date/time
            DateTime date = FileOnDisk ? new FileInfo(file).LastWriteTime : DateTime.Now;
            ushort secs = 0;
            ushort mins = 0;
            ushort hours = 0;

            ushort day = 0;
            ushort month = 0;
            ushort year = 0;

            secs = (ushort)date.Second;
            mins = (ushort)date.Minute;
            hours = (ushort)date.Hour;
            
            ushort datetime = (ushort)(secs / 2);
            datetime |= (ushort)(mins >> 5);
            datetime |= (ushort)(hours >> 11);
            ms.Write(BitConverter.GetBytes(datetime), 0, 2);
            entry.Time = datetime;

            day = (ushort)date.Day;
            month = (ushort)date.Month;
            year = (ushort)date.Year;
            
            datetime = day;
            datetime &= (ushort)(month >> 5);
            datetime &= (ushort)(year >> 9);
            ms.Write(BitConverter.GetBytes(datetime), 0, 2);
            entry.Date = datetime;

            byte[] comprData;
            Stream dataStream = null;
            if (FileOnDisk)
                dataStream = new FileStream(file, FileMode.Open, FileAccess.Read);
            else
                dataStream = new MemoryStream(dataGetter());

            using (dataStream)
            {
                byte[] buff = new byte[dataStream.Length];
                dataStream.Read(buff, 0, buff.Length);

                // create and write local header
                entry.CRC32 = CRC32.BlockChecksum(buff);
                entry.UncLen = (UInt32)dataStream.Length;

                ms.Write(BitConverter.GetBytes(entry.CRC32), 0, 4);

                ms.Seek(4, SeekOrigin.Current); // Skip compressed size
                ms.Write(BitConverter.GetBytes(entry.UncLen), 0, 4);

                if (entry.Filename.ToLower().Contains("meresults"))
                    entry.Filename = "texmod.def";

                ms.Write(BitConverter.GetBytes((ushort)entry.Filename.Length), 0, 2);
                ms.Write(BitConverter.GetBytes((ushort)0), 0, 2);  // extra

                // Filename
                foreach (char c in entry.Filename)  
                    ms.WriteByte((byte)c);
                
                dataStream.Seek(0, SeekOrigin.Begin); // Rewind to compress entry
                using (MemoryStream ms2 = new MemoryStream())
                {
                    using (DeflateStream deflator = new DeflateStream(ms2, CompressionMode.Compress))
                        dataStream.CopyTo(deflator);

                    comprData = ms2.ToArray();
                }
                entry.ComprLen = (uint)comprData.Length + 12;  // 12 is crypt header
                ZipCrypto.EncryptData(ms, comprData, entry.CRC32); // Encrypt and write data
            }

            // Footer
            ms.Write(BitConverter.GetBytes(ZipReader.datadescriptormagic), 0, 4);
            ms.Write(BitConverter.GetBytes(entry.CRC32), 0, 4);
            ms.Write(BitConverter.GetBytes(entry.ComprLen), 0, 4);
            ms.Write(BitConverter.GetBytes(entry.UncLen), 0, 4);

            // Go back and write compressed length
            ms.Seek(entry.MainOffset + 18, SeekOrigin.Begin);
            ms.Write(BitConverter.GetBytes(entry.ComprLen), 0, 4);

            // Go to end for next entry
            ms.Seek(0, SeekOrigin.End);
            return entry;
        }