private bool IsCabinet(Stream cabStream, out short id, out int cabFolderCount, out int fileCount) { int streamHandle = StreamHandles.AllocHandle(cabStream); try { Erf.Clear(); NativeMethods.FDI.CABINFO fdici; bool isCabinet = 0 != NativeMethods.FDI.IsCabinet(fdiHandle, streamHandle, out fdici); if (Erf.Error) { if (((NativeMethods.FDI.ERROR)Erf.Oper) == NativeMethods.FDI.ERROR.UNKNOWN_CABINET_VERSION) { isCabinet = false; } else { throw new CabException( Erf.Oper, Erf.Type, CabException.GetErrorMessage(Erf.Oper, Erf.Type, true)); } } id = fdici.setID; cabFolderCount = fdici.cFolders; fileCount = fdici.cFiles; return(isCabinet); } finally { StreamHandles.FreeHandle(streamHandle); } }
public IList <ArchiveFileInfo> GetFileInfo( IUnpackStreamContext streamContext, Predicate <string> fileFilter) { if (streamContext == null) { throw new ArgumentNullException("streamContext"); } lock (this) { _context = streamContext; _filter = fileFilter; NextCabinetName = string.Empty; _fileList = new List <ArchiveFileInfo>(); var tmpSuppress = SuppressProgressEvents; SuppressProgressEvents = true; try { for (short cabNumber = 0; NextCabinetName != null; cabNumber++) { Erf.Clear(); CabNumbers[NextCabinetName] = cabNumber; NativeMethods.FDI.Copy( _fdiHandle, NextCabinetName, string.Empty, 0, CabListNotify, IntPtr.Zero, IntPtr.Zero); CheckError(true); } var tmpFileList = _fileList; _fileList = null; return(tmpFileList.AsReadOnly()); } finally { SuppressProgressEvents = tmpSuppress; if (CabStream != null) { _context.CloseArchiveReadStream( CurrentArchiveNumber, CurrentArchiveName, CabStream); CabStream = null; } _context = null; } } }
private void AddFile( string name, Stream stream, FileAttributes attributes, DateTime lastWriteTime, bool execute, CompressionLevel compLevel) { FileStream = stream; _fileAttributes = attributes & (FileAttributes.Archive | FileAttributes.Hidden | FileAttributes.ReadOnly | FileAttributes.System); _fileLastWriteTime = lastWriteTime; CurrentFileName = name; var tcomp = GetCompressionType(compLevel); var namePtr = IntPtr.Zero; try { var nameEncoding = Encoding.ASCII; if (Encoding.UTF8.GetByteCount(name) > name.Length) { nameEncoding = Encoding.UTF8; _fileAttributes |= FileAttributes.Normal; // _A_NAME_IS_UTF } var nameBytes = nameEncoding.GetBytes(name); namePtr = Marshal.AllocHGlobal(nameBytes.Length + 1); Marshal.Copy(nameBytes, 0, namePtr, nameBytes.Length); Marshal.WriteByte(namePtr, nameBytes.Length, 0); Erf.Clear(); NativeMethods.FCI.AddFile( _fciHandle, string.Empty, namePtr, execute, _fciGetNextCabinet, _fciCreateStatus, _fciGetOpenInfo, tcomp); } finally { if (namePtr != IntPtr.Zero) { Marshal.FreeHGlobal(namePtr); } } CheckError(false); FileStream = null; CurrentFileName = null; }
private void CreateFci(long maxArchiveSize) { var ccab = new NativeMethods.FCI.CCAB(); if (maxArchiveSize > 0 && maxArchiveSize < ccab.cb) { ccab.cb = Math.Max( NativeMethods.FCI.MIN_DISK, (int)maxArchiveSize); } var maxFolderSizeOption = _context.GetOption( "maxFolderSize", null); if (maxFolderSizeOption != null) { var maxFolderSize = Convert.ToInt64( maxFolderSizeOption, CultureInfo.InvariantCulture); if (maxFolderSize > 0 && maxFolderSize < ccab.cbFolderThresh) { ccab.cbFolderThresh = (int)maxFolderSize; } } _maxCabBytes = ccab.cb; ccab.szCab = _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); CabNumbers[ccab.szCab] = 0; CurrentArchiveName = ccab.szCab; TotalArchives = 1; CabStream = null; Erf.Clear(); _fciHandle = NativeMethods.FCI.Create( ErfHandle.AddrOfPinnedObject(), _fciFilePlacedHandler, _fciAllocMemHandler, _fciFreeMemHandler, _fciOpenStreamHandler, _fciReadStreamHandler, _fciWriteStreamHandler, _fciCloseStreamHandler, _fciSeekStreamHandler, _fciDeleteFileHandler, _fciGetTempFileHandler, ccab, IntPtr.Zero); CheckError(false); }
private void FlushCabinet() { Erf.Clear(); NativeMethods.FCI.FlushCabinet(_fciHandle, false, _fciGetNextCabinet, _fciCreateStatus); CheckError(false); }
public void Unpack( IUnpackStreamContext streamContext, Predicate <string> fileFilter) { lock (this) { IList <ArchiveFileInfo> files = GetFileInfo(streamContext, fileFilter); ResetProgressData(); if (files != null) { totalFiles = files.Count; for (int i = 0; i < files.Count; i++) { totalFileBytes += files[i].Length; if (files[i].ArchiveNumber >= this.totalArchives) { int totalArchives = files[i].ArchiveNumber + 1; this.totalArchives = (short)totalArchives; } } } context = streamContext; fileList = null; NextCabinetName = String.Empty; folderId = -1; currentFileNumber = -1; try { for (short cabNumber = 0; NextCabinetName != null; cabNumber++) { Erf.Clear(); CabNumbers[NextCabinetName] = cabNumber; NativeMethods.FDI.Copy( fdiHandle, NextCabinetName, String.Empty, 0, CabExtractNotify, IntPtr.Zero, IntPtr.Zero); CheckError(true); } } finally { if (CabStream != null) { context.CloseArchiveReadStream( currentArchiveNumber, currentArchiveName, CabStream); CabStream = null; } if (FileStream != null) { context.CloseFileWriteStream(currentFileName, FileStream, FileAttributes.Normal, DateTime.Now); FileStream = null; } context = null; } } }