예제 #1
0
        ////////////////////////////////////////////////////////////////////
        // Save directory path in the ZIP directory
        ////////////////////////////////////////////////////////////////////

        public Boolean SaveDirectoryPath
        (
            String FullFileName,
            String ArchiveFileName
        )
        {
            try
            {
                // write zip file header for directory path
                WriteFileHeader(FullFileName, ArchiveFileName);

                // save file header
                ZipDir.Insert(~ZipDir.BinarySearch(FileHeaderInfo), FileHeaderInfo);

                // successful exit
                return(false);
            }

            // catch exceptions and save the exception error message and stack
            catch (Exception Ex)
            {
                // remove any information written to the file
                WriteStream.SetLength(WriteStartPosition);

                // error exit
                ExceptionStack = ExceptionReport.GetMessageAndStack(this, Ex);
                return(true);
            }
        }
예제 #2
0
        ////////////////////////////////////////////////////////////////////
        // Delete central directory entry
        ////////////////////////////////////////////////////////////////////

        public Boolean Delete
        (
            Int32 ZipDirIndex
        )
        {
            try
            {
                // delete the entry
                ZipDir.RemoveAt(ZipDirIndex);
            }

            // catch exceptions and save the exception error message and stack
            catch (Exception Ex)
            {
                // error exit
                ExceptionStack = ExceptionReport.GetMessageAndStack(this, Ex);
                return(true);
            }

            // set delete mode flag for save archive
            DeleteMode = true;

            // successful exit
            return(false);
        }
예제 #3
0
        ////////////////////////////////////////////////////////////////////
        // Decompress one file
        ////////////////////////////////////////////////////////////////////

        public Boolean Compress
        (
            String FullFileName,
            String ArchiveFileName
        )
        {
            try
            {
                // write zip file header
                WriteFileHeader(FullFileName, ArchiveFileName);

                // open source file for reading
                ReadStream = new FileStream(ReadFileName, FileMode.Open, FileAccess.Read, FileShare.Read);

                // convert stream to binary reader
                ReadFile = new BinaryReader(ReadStream, Encoding.UTF8);

                // uncompressed file length
                ReadRemain = (UInt32)ReadStream.Length;

                // reset CRC32 checksum
                ReadCRC32 = 0;

                // compress the file
                Compress();

                // close read file
                ReadFile.Close();
                ReadFile = null;

                // update zip file header with input file crc and compressed file length
                UpdateZipFileHeader();

                // successful exit
                return(false);
            }

            // catch exceptions and save the exception error message and stack
            catch (Exception Ex)
            {
                // close the read file if it is open
                if (ReadFile != null)
                {
                    ReadFile.Close();
                    ReadFile = null;
                }

                // remove any information written to the file
                WriteStream.SetLength(WriteStartPosition);

                // error exit
                ExceptionStack = ExceptionReport.GetMessageAndStack(this, Ex);
                return(true);
            }
        }
예제 #4
0
        ////////////////////////////////////////////////////////////////////
        // Save ZIP Archive
        ////////////////////////////////////////////////////////////////////

        public Boolean SaveArchive()
        {
            try
            {
                // zip directory is empty
                if (ZipDir.Count == 0)
                {
                    // close and delete the file
                    WriteFile.Close();
                    WriteFile = null;
                    File.Delete(WriteFileName);
                }
                else
                {
                    // one or more files were deleted
                    if (DeleteMode)
                    {
                        DeleteFiles();
                    }

                    // write zip file directory
                    ZipFileDirectory();

                    // close file
                    WriteFile.Close();
                    WriteFile = null;

                    // clear directory
                    ZipDir.Clear();
                }

                // successful exit
                return(false);
            }

            // catch exceptions and save the exception error message and stack
            catch (Exception Ex)
            {
                // close the write file if it is open
                CloseZipFile();

                // error exit
                ExceptionStack = ExceptionReport.GetMessageAndStack(this, Ex);
                return(true);
            }
        }
예제 #5
0
        ////////////////////////////////////////////////////////////////////
        // Create ZIP Archive
        ////////////////////////////////////////////////////////////////////

        public Boolean CreateArchive
        (
            String WriteFileName
        )
        {
            try
            {
                // save name
                this.WriteFileName = WriteFileName;

                // create destination file
                WriteStream = new FileStream(WriteFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.None);

                // convert stream to binary writer
                WriteFile = new BinaryWriter(WriteStream, Encoding.UTF8);

                // convert stream to binary reader
                WriteFileReader = new BinaryReader(WriteStream, Encoding.UTF8);

                // create empty zip file directory
                ZipDir = new List <FileHeader>();

                // reset zip directory position
                ZipDirPosition = 0;

                // reset delete mode
                DeleteMode = false;

                // successful exit
                return(false);
            }

            // catch exceptions and save the exception error message and stack
            catch (Exception Ex)
            {
                // close the write file if it is open
                CloseZipFile();

                // error exit
                ExceptionStack = ExceptionReport.GetMessageAndStack(this, Ex);
                return(true);
            }
        }
예제 #6
0
        /////////////////////////////////////////////////////////////////////
        // Open ZIP file and read file directory
        /////////////////////////////////////////////////////////////////////

        public Boolean OpenZipFile
        (
            String ReadFileName
        )
        {
            // trap errors
            try
            {
                // save name
                this.ReadFileName = ReadFileName;

                // open source file for reading
                ReadStream = new FileStream(ReadFileName, FileMode.Open, FileAccess.Read, FileShare.Read);

                // convert stream to binary reader
                ReadFile = new BinaryReader(ReadStream, Encoding.UTF8);

                // file is too long
                if (ReadStream.Length > (Int64)0xffffffff)
                {
                    throw new ApplicationException("No support for files over 4GB");
                }

                // read zip directory
                ReadZipFileDirectory();

                // successful exit
                return(false);
            }

            // make sure read file is closed
            catch (Exception Ex)
            {
                // close the read file if it is open
                CloseZipFile();

                // error exit
                ExceptionStack = ExceptionReport.GetMessageAndStack(this, Ex);
                return(true);
            }
        }
예제 #7
0
        ////////////////////////////////////////////////////////////////////
        // Decompress one file
        ////////////////////////////////////////////////////////////////////

        public Boolean Decompress
        (
            String ReadFileName,
            String WriteFileName
        )
        {
            try
            {
                // save name
                this.ReadFileName = ReadFileName;

                // open source file for reading
                ReadStream = new FileStream(ReadFileName, FileMode.Open, FileAccess.Read, FileShare.Read);

                // convert stream to binary reader
                ReadFile = new BinaryReader(ReadStream, Encoding.UTF8);

                // file is too long
                if (ReadStream.Length > (Int64)0xffffffff)
                {
                    throw new ApplicationException("No support for files over 4GB");
                }

                // compressed part of the file
                // we subtract 2 bytes for header and 4 bytes for adler32 checksum
                ReadRemain = (UInt32)ReadStream.Length - 6;
                ReadTotal  = ReadRemain;

                // get ZLib header
                Int32 Header = (ReadFile.ReadByte() << 8) | ReadFile.ReadByte();

                // test header: chksum, compression method must be deflated, no support for external dictionary
                if (Header % 31 != 0 || (Header & 0xf00) != 0x800 && (Header & 0xf00) != 0 || (Header & 0x20) != 0)
                {
                    throw new ApplicationException("ZLIB file header is in error");
                }

                // save name
                this.WriteFileName = WriteFileName;

                // create destination file
                WriteStream = new FileStream(WriteFileName, FileMode.Create, FileAccess.Write, FileShare.None);

                // convert stream to binary writer
                WriteFile = new BinaryWriter(WriteStream, Encoding.UTF8);

                // reset adler32 checksum
                WriteAdler32 = 1;

                // decompress the file
                if ((Header & 0xf00) == 0x800)
                {
                    Decompress();
                }
                else
                {
                    NoCompression();
                }

                // ZLib checksum is Adler32
                if ((((UInt32)ReadFile.ReadByte() << 24) | ((UInt32)ReadFile.ReadByte() << 16) |
                     ((UInt32)ReadFile.ReadByte() << 8) | ((UInt32)ReadFile.ReadByte())) != WriteAdler32)
                {
                    throw new ApplicationException("ZLIB file Adler32 test failed");
                }

                // close read file
                ReadFile.Close();
                ReadFile = null;

                // save file length
                WriteTotal = (UInt32)WriteStream.Length;

                // close write file
                WriteFile.Close();
                WriteFile = null;

                // successful exit
                return(false);
            }

            // make sure read and write files are closed
            catch (Exception Ex)
            {
                // close the read file if it is open
                if (ReadFile != null)
                {
                    ReadFile.Close();
                    ReadFile = null;
                }

                // close the write file if it is open
                if (WriteFile != null)
                {
                    WriteFile.Close();
                    WriteFile = null;
                }

                // error exit
                ExceptionStack = ExceptionReport.GetMessageAndStack(this, Ex);
                return(true);
            }
        }
예제 #8
0
        ////////////////////////////////////////////////////////////////////
        // Compress one file
        ////////////////////////////////////////////////////////////////////

        public Boolean Compress
        (
            String ReadFileName,
            String WriteFileName
        )
        {
            try
            {
                // save name
                this.ReadFileName = ReadFileName;

                // open source file for reading
                ReadStream = new FileStream(ReadFileName, FileMode.Open, FileAccess.Read, FileShare.Read);

                // convert stream to binary reader
                ReadFile = new BinaryReader(ReadStream, Encoding.UTF8);

                // file is too long
                if (ReadStream.Length > (Int64)0xffffffff)
                {
                    throw new ApplicationException("No support for files over 4GB");
                }

                // uncompressed file length
                ReadRemain = (UInt32)ReadStream.Length;

                // save name
                this.WriteFileName = WriteFileName;

                // create destination file
                WriteStream = new FileStream(WriteFileName, FileMode.Create, FileAccess.Write, FileShare.None);

                // convert stream to binary writer
                WriteFile = new BinaryWriter(WriteStream, Encoding.UTF8);

                // compress the file (function defind in DeflateMethod the base class)
                Compress();

                // close read file
                ReadFile.Close();
                ReadFile = null;

                // close write file
                WriteFile.Close();
                WriteFile = null;

                // successful exit
                return(false);
            }

            // make sure read and write files are closed
            catch (Exception Ex)
            {
                // close the read file if it is open
                if (ReadFile != null)
                {
                    ReadFile.Close();
                    ReadFile = null;
                }

                // close the write file if it is open
                if (WriteFile != null)
                {
                    WriteFile.Close();
                    WriteFile = null;
                }

                // error exit
                ExceptionStack = ExceptionReport.GetMessageAndStack(this, Ex);
                return(true);
            }
        }
예제 #9
0
        ////////////////////////////////////////////////////////////////////
        // Decompress ZIP file
        ////////////////////////////////////////////////////////////////////

        public Boolean DecompressZipFile
        (
            FileHeader FH,
            String RootPathName,                                        // save the decompressed file in this directory
            String NewFileName,                                         // if this file name is given it overwrite the name in the FH structure
            Boolean CreatePath,
            Boolean OverWrite
        )
        {
            try
            {
                // save file header
                FileHeaderInfo = FH;

                // read file header for this file and compare it to the directory information
                ReadFileHeader(FileHeaderInfo.FilePos);

                // compressed length
                ReadRemain = FileHeaderInfo.CompSize;
                ReadTotal  = ReadRemain;

                // build write file name
                // Root name (optional) plus either original name or a new name
                WriteFileName = (String.IsNullOrEmpty(RootPathName) ? String.Empty :
                                 (RootPathName.EndsWith("\\") ? RootPathName : RootPathName + "\\")) +
                                (String.IsNullOrEmpty(NewFileName) ? FH.FileName : NewFileName);

                // test if write file name has a path component
                Int32 Ptr = WriteFileName.LastIndexOf('\\');
                if (Ptr >= 0)
                {
                    // make sure directory exists
                    if (!Directory.Exists(WriteFileName.Substring(0, Ptr)))
                    {
                        // make a new folder
                        if (CreatePath)
                        {
                            Directory.CreateDirectory(WriteFileName.Substring(0, Ptr));
                        }

                        // error
                        else
                        {
                            throw new ApplicationException("Extract file failed. Invalid directory path");
                        }
                    }
                }

                // create destination file
                WriteStream = new FileStream(WriteFileName, OverWrite ? FileMode.Create : FileMode.CreateNew, FileAccess.Write, FileShare.None);

                // convert stream to binary writer
                WriteFile = new BinaryWriter(WriteStream, Encoding.UTF8);

                // reset crc32 checksum
                WriteCRC32 = 0;

                // switch based on compression method
                switch (FileHeaderInfo.CompMethod)
                {
                // no compression
                case 0:
                    NoCompression();
                    break;

                // deflate compress method
                case 8:
                    // decompress file
                    Decompress();
                    break;

                // not supported
                default:
                    throw new ApplicationException("Unsupported compression method");
                }

                // Zip file checksum is CRC32
                if (FileHeaderInfo.FileCRC32 != WriteCRC32)
                {
                    throw new ApplicationException("ZIP file CRC test failed");
                }

                // save file length
                WriteTotal = (UInt32)WriteStream.Length;

                // close write file
                WriteFile.Close();
                WriteFile = null;

                // if file times are available set the file time
                if (FileTimeAvailable)
                {
                    File.SetCreationTime(WriteFileName, FileCreateTime);
                    File.SetLastWriteTime(WriteFileName, FileModifyTime);
                    File.SetLastAccessTime(WriteFileName, FileAccessTime);
                }
                else
                {
                    // convert dos file date and time to DateTime format
                    DateTime FileDosTime = new DateTime(1980 + ((FileHeaderInfo.FileDate >> 9) & 0x7f),
                                                        (FileHeaderInfo.FileDate >> 5) & 0xf, FileHeaderInfo.FileDate & 0x1f,
                                                        (FileHeaderInfo.FileTime >> 11) & 0x1f, (FileHeaderInfo.FileTime >> 5) & 0x3f, 2 * (FileHeaderInfo.FileTime & 0x1f));
                    File.SetCreationTime(WriteFileName, FileDosTime);
                    File.SetLastWriteTime(WriteFileName, FileDosTime);
                    File.SetLastAccessTime(WriteFileName, FileDosTime);
                }

                // set file attribute attributes
                if (FileHeaderInfo.FileAttr != 0)
                {
                    File.SetAttributes(WriteFileName, FileHeaderInfo.FileAttr);
                }

                // successful exit
                return(false);
            }

            // make sure write file is closed
            catch (Exception Ex)
            {
                // close the write file if it is open
                if (WriteFile != null)
                {
                    WriteFile.Close();
                    WriteFile = null;
                }

                // error exit
                ExceptionStack = ExceptionReport.GetMessageAndStack(this, Ex);
                return(true);
            }
        }
예제 #10
0
        ////////////////////////////////////////////////////////////////////
        // Compare Files
        ////////////////////////////////////////////////////////////////////

        private Boolean CompareFiles()
        {
            FileStream   Stream1, Stream2;
            BinaryReader File1 = null, File2 = null;

            Byte[] Buffer1, Buffer2;

            // trap errors
            try
            {
                // open file1 for reading
                Stream1 = new FileStream(InputFileName, FileMode.Open, FileAccess.Read, FileShare.Read);

                // convert stream to binary reader
                File1 = new BinaryReader(Stream1, Encoding.UTF8);

                // open file2 for reading
                Stream2 = new FileStream(DecompFileName, FileMode.Open, FileAccess.Read, FileShare.Read);

                // convert stream to binary reader
                File2 = new BinaryReader(Stream2, Encoding.UTF8);

                // length must be the same
                if (Stream1.Length != Stream2.Length)
                {
                    throw new ApplicationException("Compare files failed. Files lengths not the same");
                }

                // allocate buffer
                Buffer1 = new Byte[32 * 1024];
                Buffer2 = new Byte[32 * 1024];

                // compare
                Int64 Len = Stream1.Length;
                while (Len > 0)
                {
                    Int32 Count = Len < (Int64)Buffer1.Length ? (Int32)Len : Buffer1.Length;
                    Int32 Act1  = File1.Read(Buffer1, 0, Count);
                    if (Act1 != Count)
                    {
                        throw new ApplicationException("Compare files failed. Reading file1 failed");
                    }
                    Int32 Act2 = File2.Read(Buffer2, 0, Count);
                    if (Act2 != Count)
                    {
                        throw new ApplicationException("Compare files failed. Reading file2 failed");
                    }
                    Int32 Index;
                    for (Index = 0; Index < Count && Buffer1[Index] == Buffer2[Index]; Index++)
                    {
                        ;
                    }
                    if (Index != Count)
                    {
                        throw new ApplicationException("Compare files failed. The two files are not the same");
                    }
                    Len -= Count;
                }

                File1.Close();
                File2.Close();

                // successful exit
                return(false);
            }

            catch (Exception Ex)
            {
                // make sure read file is closed
                File1.Close();
                File2.Close();

                // error exit
                ExceptionStack = ExceptionReport.GetMessageAndStack(this, Ex);
                return(true);
            }
        }
예제 #11
0
        ////////////////////////////////////////////////////////////////////
        //	On add button
        ////////////////////////////////////////////////////////////////////

        private void OnAddButton
        (
            object sender,
            EventArgs e
        )
        {
            // get selected list
            ListView.SelectedListViewItemCollection SelectedList = FileList.SelectedItems;

            // the list is empty
            if (SelectedList.Count == 0)
            {
                return;
            }

            // trap duplicate file errors
            try
            {
                // zip file root directory
                RootDir    = (String)DirectoryTree.SelectedNode.Tag;
                RootDirPtr = RootDir.Length + 1;

                // create empty file list
                AddDir = new List <FileHeader>();

                // get all selected directories
                foreach (ListViewItem Item in SelectedList)
                {
                    if (Item.Tag.GetType() == typeof(DirectoryInfo))
                    {
                        ProcessDirectory((DirectoryInfo)Item.Tag);
                    }
                }

                // get all selected files in the zip file root directory
                foreach (ListViewItem Item in SelectedList)
                {
                    if (Item.Tag.GetType() == typeof(FileInfo))
                    {
                        // shortcut for file information
                        FileInfo FI = (FileInfo)Item.Tag;

                        // create zip directory file header record with name date time and attributes
                        FileHeader FH = new FileHeader(FI.FullName.Substring(RootDirPtr), FI.LastWriteTime, FI.Attributes, 0, FI.Length);

                        // find item poition in the list
                        Int32 Index = AddDir.BinarySearch(FH);
                        if (Index >= 0)
                        {
                            throw new ApplicationException("Duplicate file name");
                        }

                        // add to the list
                        AddDir.Insert(~Index, FH);
                    }
                }

                // save compression level
                CompLevel = (Int32)CompLevelUpDown.Value;

                // close screen
                DialogResult = DialogResult.OK;
                return;
            }

            // error
            catch (Exception Ex)
            {
                // error exit
                String[] ExceptionStack = ExceptionReport.GetMessageAndStack(this, Ex);
                MessageBox.Show(this, "Add files and folders error\n" + ExceptionStack[0] + "\n" + ExceptionStack[1],
                                "Add Files Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
        }
예제 #12
0
        ////////////////////////////////////////////////////////////////////
        // Decompress one file
        ////////////////////////////////////////////////////////////////////

        public Boolean Compress
        (
            String ReadFileName,
            String WriteFileName
        )
        {
            try
            {
                // save read file name
                this.ReadFileName = ReadFileName;

                // open source file for reading
                ReadStream = new FileStream(ReadFileName, FileMode.Open, FileAccess.Read, FileShare.Read);

                // convert stream to binary reader
                ReadFile = new BinaryReader(ReadStream, Encoding.UTF8);

                // file is too long
                if (ReadStream.Length > (Int64)0xffffffff)
                {
                    throw new ApplicationException("No support for files over 4GB");
                }

                // uncompressed file length
                ReadRemain = (UInt32)ReadStream.Length;

                // reset adler32 checksum
                ReadAdler32 = 1;

                // save name
                this.WriteFileName = WriteFileName;

                // create destination file
                WriteStream = new FileStream(WriteFileName, FileMode.Create, FileAccess.Write, FileShare.None);

                // convert stream to binary writer
                WriteFile = new BinaryWriter(WriteStream, Encoding.UTF8);

                // Header is made out of 16 bits [iiiicccclldxxxxx]
                // iiii is compression information. It is WindowBit - 8 in this case 7. iiii = 0111
                // cccc is compression method. Deflate (8 dec) or Store (0 dec)
                // The first byte is 0x78 for deflate and 0x70 for store
                // ll is compression level 0 to 3 (CompLevelTable translates between user level of 0-9 to header level of 0-3)
                // d is preset dictionary. The preset dictionary is not supported by this program. d is always 0
                // xxx is 5 bit check sum
                Int32 Header = (0x78 << 8) | (CompLevelTable[CompressionLevel] << 6);
                Header += 31 - (Header % 31);

                // write two bytes in most significant byte first
                WriteFile.Write((Byte)(Header >> 8));
                WriteFile.Write((Byte)Header);

                // compress the file
                Compress();

                // compress function was stored
                if (CompFunction == CompFunc.Stored)
                {
                    // set file position to header
                    WriteStream.Position = 0;

                    // change compression method from Deflate(8) to Stored(0)
                    Header  = (0x70 << 8) | (CompLevelTable[CompressionLevel] << 6);
                    Header += 31 - (Header % 31);

                    // write two bytes in most significant byte first
                    WriteFile.Write((Byte)(Header >> 8));
                    WriteFile.Write((Byte)Header);

                    // restore file position
                    WriteStream.Position = WriteStream.Length;
                }

                // ZLib checksum is Adler32 write it big endian order, high byte first
                WriteFile.Write((Byte)(ReadAdler32 >> 24));
                WriteFile.Write((Byte)(ReadAdler32 >> 16));
                WriteFile.Write((Byte)(ReadAdler32 >> 8));
                WriteFile.Write((Byte)ReadAdler32);

                // close read file
                ReadFile.Close();
                ReadFile = null;

                // close write file
                WriteFile.Close();
                WriteFile = null;

                // successful exit
                return(false);
            }

            // make sure read and write files are closed
            catch (Exception Ex)
            {
                // close the read file if it is open
                if (ReadFile != null)
                {
                    ReadFile.Close();
                    ReadFile = null;
                }

                // close the write file if it is open
                if (WriteFile != null)
                {
                    WriteFile.Close();
                    WriteFile = null;
                }

                // error exit
                ExceptionStack = ExceptionReport.GetMessageAndStack(this, Ex);
                return(true);
            }
        }