示例#1
0
        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);
            }
        }
示例#2
0
        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;
                }
            }
        }
示例#3
0
        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;
        }
示例#4
0
        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);
        }
示例#5
0
 private void FlushCabinet()
 {
     Erf.Clear();
     NativeMethods.FCI.FlushCabinet(_fciHandle, false, _fciGetNextCabinet, _fciCreateStatus);
     CheckError(false);
 }
示例#6
0
        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;
                }
            }
        }