Example #1
0
        private void CreateFci(long maxArchiveSize)
        {
            NativeMethods.FCI.CCAB ccab = new NativeMethods.FCI.CCAB();
            if (maxArchiveSize > 0 && maxArchiveSize < ccab.cb)
            {
                ccab.cb = Math.Max(
                    NativeMethods.FCI.MIN_DISK, (int)maxArchiveSize);
            }

            object maxFolderSizeOption = this.context.GetOption(
                "maxFolderSize", null);

            if (maxFolderSizeOption != null)
            {
                long maxFolderSize = Convert.ToInt64(
                    maxFolderSizeOption, CultureInfo.InvariantCulture);
                if (maxFolderSize > 0 && maxFolderSize < ccab.cbFolderThresh)
                {
                    ccab.cbFolderThresh = (int)maxFolderSize;
                }
            }

            this.maxCabBytes = ccab.cb;
            ccab.szCab       = this.context.GetArchiveName(0);
            if (ccab.szCab == null)
            {
                throw new FileNotFoundException(
                          "Cabinet name not provided by stream context.");
            }
            ccab.setID = (short)new Random().Next(
                Int16.MinValue, Int16.MaxValue + 1);
            this.CabNumbers[ccab.szCab] = 0;
            this.currentArchiveName     = ccab.szCab;
            this.totalArchives          = 1;
            this.CabStream = null;

            this.Erf.Clear();
            this.fciHandle = NativeMethods.FCI.Create(
                this.ErfHandle.AddrOfPinnedObject(),
                this.fciFilePlacedHandler,
                this.fciAllocMemHandler,
                this.fciFreeMemHandler,
                this.fciOpenStreamHandler,
                this.fciReadStreamHandler,
                this.fciWriteStreamHandler,
                this.fciCloseStreamHandler,
                this.fciSeekStreamHandler,
                this.fciDeleteFileHandler,
                this.fciGetTempFileHandler,
                ccab,
                IntPtr.Zero);
            this.CheckError(false);
        }
Example #2
0
 internal override void Dispose(bool disposing)
 {
     try
     {
         if (disposing)
         {
             if (this.fciHandle != null)
             {
                 this.fciHandle.Dispose();
                 this.fciHandle = null;
             }
         }
     }
     finally
     {
         base.Dispose(disposing);
     }
 }
Example #3
0
        internal void Pack(
            IPackStreamContext streamContext,
            IEnumerable <string> files,
            long maxArchiveSize)
        {
            if (streamContext == null)
            {
                throw new ArgumentNullException("streamContext");
            }

            if (files == null)
            {
                throw new ArgumentNullException("files");
            }

            lock (this)
            {
                try
                {
                    this.context = streamContext;

                    this.ResetProgressData();

                    this.CreateFci(maxArchiveSize);

                    foreach (string file in files)
                    {
                        FileAttributes attributes;
                        DateTime       lastWriteTime;
                        Stream         fileStream = this.context.OpenFileReadStream(
                            file,
                            out attributes,
                            out lastWriteTime);
                        if (fileStream != null)
                        {
                            this.totalFileBytes += fileStream.Length;
                            this.totalFiles++;
                            this.context.CloseFileReadStream(file, fileStream);
                        }
                    }

                    long uncompressedBytesInFolder = 0;
                    this.currentFileNumber = -1;

                    foreach (string file in files)
                    {
                        FileAttributes attributes;
                        DateTime       lastWriteTime;
                        Stream         fileStream = this.context.OpenFileReadStream(
                            file, out attributes, out lastWriteTime);
                        if (fileStream == null)
                        {
                            continue;
                        }

                        if (fileStream.Length >= (long)NativeMethods.FCI.MAX_FOLDER)
                        {
                            throw new NotSupportedException(String.Format(
                                                                CultureInfo.InvariantCulture,
                                                                "File {0} exceeds maximum file size " +
                                                                "for cabinet format.",
                                                                file));
                        }

                        if (uncompressedBytesInFolder > 0)
                        {
                            // Automatically create a new folder if this file
                            // won't fit in the current folder.
                            bool nextFolder = uncompressedBytesInFolder
                                              + fileStream.Length >= (long)NativeMethods.FCI.MAX_FOLDER;

                            // Otherwise ask the client if it wants to
                            // move to the next folder.
                            if (!nextFolder)
                            {
                                object nextFolderOption = streamContext.GetOption(
                                    "nextFolder",
                                    new object[] { file, this.currentFolderNumber });
                                nextFolder = Convert.ToBoolean(
                                    nextFolderOption, CultureInfo.InvariantCulture);
                            }

                            if (nextFolder)
                            {
                                this.FlushFolder();
                                uncompressedBytesInFolder = 0;
                            }
                        }

                        if (this.currentFolderTotalBytes > 0)
                        {
                            this.currentFolderTotalBytes = 0;
                            this.currentFolderNumber++;
                            uncompressedBytesInFolder = 0;
                        }

                        this.currentFileName = file;
                        this.currentFileNumber++;

                        this.currentFileTotalBytes     = fileStream.Length;
                        this.currentFileBytesProcessed = 0;
                        this.OnProgress(ArchiveProgressType.StartFile);

                        uncompressedBytesInFolder += fileStream.Length;

                        this.AddFile(
                            file,
                            fileStream,
                            attributes,
                            lastWriteTime,
                            false,
                            this.CompressionLevel);
                    }

                    this.FlushFolder();
                    this.FlushCabinet();
                }
                finally
                {
                    if (this.CabStream != null)
                    {
                        this.context.CloseArchiveWriteStream(
                            this.currentArchiveNumber,
                            this.currentArchiveName,
                            this.CabStream);
                        this.CabStream = null;
                    }

                    if (this.FileStream != null)
                    {
                        this.context.CloseFileReadStream(
                            this.currentFileName, this.FileStream);
                        this.FileStream = null;
                    }
                    this.context = null;

                    if (this.fciHandle != null)
                    {
                        this.fciHandle.Dispose();
                        this.fciHandle = null;
                    }
                }
            }
        }
Example #4
0
        private void CreateFci(long maxArchiveSize)
        {
            NativeMethods.FCI.CCAB ccab = new NativeMethods.FCI.CCAB();
            if (maxArchiveSize > 0 && maxArchiveSize < ccab.cb)
            {
                ccab.cb = Math.Max(
                    NativeMethods.FCI.MIN_DISK, (int) maxArchiveSize);
            }

            object maxFolderSizeOption = this.context.GetOption(
                "maxFolderSize", null);
            if (maxFolderSizeOption != null)
            {
                long maxFolderSize = Convert.ToInt64(
                    maxFolderSizeOption, CultureInfo.InvariantCulture);
                if (maxFolderSize > 0 && maxFolderSize < ccab.cbFolderThresh)
                {
                    ccab.cbFolderThresh = (int) maxFolderSize;
                }
            }

            this.maxCabBytes = ccab.cb;
            ccab.szCab = this.context.GetArchiveName(0);
            if (ccab.szCab == null)
            {
                throw new FileNotFoundException(
                    "Cabinet name not provided by stream context.");
            }
            ccab.setID = (short) new Random().Next(
                Int16.MinValue, Int16.MaxValue + 1);
            this.CabNumbers[ccab.szCab] = 0;
            this.currentArchiveName = ccab.szCab;
            this.totalArchives = 1;
            this.CabStream = null;

            this.Erf.Clear();
            this.fciHandle = NativeMethods.FCI.Create(
                this.ErfHandle.AddrOfPinnedObject(),
                this.fciFilePlacedHandler,
                this.fciAllocMemHandler,
                this.fciFreeMemHandler,
                this.fciOpenStreamHandler,
                this.fciReadStreamHandler,
                this.fciWriteStreamHandler,
                this.fciCloseStreamHandler,
                this.fciSeekStreamHandler,
                this.fciDeleteFileHandler,
                this.fciGetTempFileHandler,
                ccab,
                IntPtr.Zero);
            this.CheckError(false);
        }
Example #5
0
        internal void Pack(
            IPackStreamContext streamContext,
            IEnumerable<string> files,
            long maxArchiveSize)
        {
            if (streamContext == null)
            {
                throw new ArgumentNullException("streamContext");
            }

            if (files == null)
            {
                throw new ArgumentNullException("files");
            }

            lock (this)
            {
                try
                {
                    this.context = streamContext;

                    this.ResetProgressData();

                    this.CreateFci(maxArchiveSize);

                    foreach (string file in files)
                    {
                        FileAttributes attributes;
                        DateTime lastWriteTime;
                        Stream fileStream = this.context.OpenFileReadStream(
                            file,
                            out attributes,
                            out lastWriteTime);
                        if (fileStream != null)
                        {
                            this.totalFileBytes += fileStream.Length;
                            this.totalFiles++;
                            this.context.CloseFileReadStream(file, fileStream);
                        }
                    }

                    long uncompressedBytesInFolder = 0;
                    this.currentFileNumber = -1;

                    foreach (string file in files)
                    {
                        FileAttributes attributes;
                        DateTime lastWriteTime;
                        Stream fileStream = this.context.OpenFileReadStream(
                            file, out attributes, out lastWriteTime);
                        if (fileStream == null)
                        {
                            continue;
                        }

                        if (fileStream.Length >= (long) NativeMethods.FCI.MAX_FOLDER)
                        {
                            throw new NotSupportedException(String.Format(
                                CultureInfo.InvariantCulture,
                                "File {0} exceeds maximum file size " +
                                "for cabinet format.",
                                file));
                        }

                        if (uncompressedBytesInFolder > 0)
                        {
                            // Automatically create a new folder if this file
                            // won't fit in the current folder.
                            bool nextFolder = uncompressedBytesInFolder
                                + fileStream.Length >= (long) NativeMethods.FCI.MAX_FOLDER;

                            // Otherwise ask the client if it wants to
                            // move to the next folder.
                            if (!nextFolder)
                            {
                                object nextFolderOption = streamContext.GetOption(
                                    "nextFolder",
                                    new object[] { file, this.currentFolderNumber });
                                nextFolder = Convert.ToBoolean(
                                    nextFolderOption, CultureInfo.InvariantCulture);
                            }

                            if (nextFolder)
                            {
                                this.FlushFolder();
                                uncompressedBytesInFolder = 0;
                            }
                        }

                        if (this.currentFolderTotalBytes > 0)
                        {
                            this.currentFolderTotalBytes = 0;
                            this.currentFolderNumber++;
                            uncompressedBytesInFolder = 0;
                        }

                        this.currentFileName = file;
                        this.currentFileNumber++;

                        this.currentFileTotalBytes = fileStream.Length;
                        this.currentFileBytesProcessed = 0;
                        this.OnProgress(ArchiveProgressType.StartFile);

                        uncompressedBytesInFolder += fileStream.Length;

                        this.AddFile(
                            file,
                            fileStream,
                            attributes,
                            lastWriteTime,
                            false,
                            this.CompressionLevel);
                    }

                    this.FlushFolder();
                    this.FlushCabinet();
                }
                finally
                {
                    if (this.CabStream != null)
                    {
                        this.context.CloseArchiveWriteStream(
                            this.currentArchiveNumber,
                            this.currentArchiveName,
                            this.CabStream);
                        this.CabStream = null;
                    }

                    if (this.FileStream != null)
                    {
                        this.context.CloseFileReadStream(
                            this.currentFileName, this.FileStream);
                        this.FileStream = null;
                    }
                    this.context = null;

                    if (this.fciHandle != null)
                    {
                        this.fciHandle.Dispose();
                        this.fciHandle = null;
                    }
                }
            }
        }
Example #6
0
 internal override void Dispose(bool disposing)
 {
     try
     {
         if (disposing)
         {
             if (this.fciHandle != null)
             {
                 this.fciHandle.Dispose();
                 this.fciHandle = null;
             }
         }
     }
     finally
     {
         base.Dispose(disposing);
     }
 }