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); }
internal override void Dispose(bool disposing) { try { if (disposing) { if (this.fciHandle != null) { this.fciHandle.Dispose(); this.fciHandle = null; } } } finally { base.Dispose(disposing); } }
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; } } } }
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); }
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; } } } }