Example #1
0
        public static void Extract(CabinetOpenCabHandler openCabHandler, CabinetCloseCabHandler closeCabHandler,
                                   object openCabContext, bool autoChain, CabinetExtractOpenFileHandler openFileHandler,
                                   CabinetExtractCloseFileHandler closeFileHandler, object openFileContext,
                                   CabinetFilterFileHandler filterFileHandler, object filterContext,
                                   CabinetStatusCallback statusCallback, object statusContext)
        #endif // !CABMINIMAL
        {
            using (CabExtractor cabInstance = new CabExtractor())
            {
                cabInstance.openCabHandler    = openCabHandler;
                cabInstance.closeCabHandler   = closeCabHandler;
                cabInstance.openCabContext    = openCabContext;
                cabInstance.openFileHandler   = openFileHandler;
                cabInstance.closeFileHandler  = closeFileHandler;
                cabInstance.openFileContext   = openFileContext;
                cabInstance.filterFileHandler = filterFileHandler;
                cabInstance.filterFileContext = filterContext;
                cabInstance.fdiNotifyHandler  = new FDI.PFNNOTIFY(cabInstance.CabExtractNotify);
                cabInstance.nextCabinetName   = "";

                        #if !CABMINIMAL
                cabInstance.statusCallback = statusCallback;
                cabInstance.statusContext  = statusContext;

                if (statusCallback != null)
                {
                    CabinetFileInfo[] files = Cabinet.GetFiles(openCabHandler, closeCabHandler, openCabContext,
                                                               autoChain, filterFileHandler, filterContext);

                    cabInstance.status.totalFiles     = files.Length;
                    cabInstance.status.totalFileBytes = 0;

                    int prevFolder = -1, prevCabinet = -1;
                    for (int i = 0; i < files.Length; i++)
                    {
                        cabInstance.status.totalFileBytes += files[i].Length;
                        if (files[i].CabinetFolderNumber != prevFolder)                 // Assumes the results of GetFiles are grouped by folders
                        {
                            prevFolder = files[i].CabinetFolderNumber;
                            cabInstance.status.totalFolders++;
                        }
                        if (files[i].CabinetNumber != prevCabinet)
                        {
                            prevCabinet = files[i].CabinetNumber;
                            cabInstance.status.totalCabinets++;
                        }
                    }
                }
                        #endif // !CABMINIMAL

                for (short iCab = 0; (autoChain || iCab == 0) && cabInstance.nextCabinetName != null; iCab++)
                {
                    cabInstance.cabNumbers[""] = iCab;
                    cabInstance.Process();
                }
            }
        }
Example #2
0
 /// <summary>
 /// Extracts all files from a cabinet to a destination directory, optionally extracting only newer files.
 /// </summary>
 /// <param name="destDirectory">Directory where the files are to be extracted.</param>
 /// <param name="update">Specify true to only extract files when the timestamp in the cabinet is newer than
 /// the timestamp of the file on disk, when the file already exists.</param>
 /// <param name="callback">Handler for receiving progress information; this may be null if progress is not desired.</param>
 /// <param name="context">User context object passed to the <paramref name="callback"/>, may be null.</param>
 internal virtual void ExtractAll(string destDirectory, bool update, CabinetStatusCallback callback, object context)
 {
     using (Stream stream = this.GetCabinetReadStream())
     {
         object[] fileContext = new Object[] { destDirectory, null, update };
         Cabinet.Extract(stream,
                         new CabinetExtractOpenFileHandler(CabinetInfo.ExtractOpenFileHandler),
                         new CabinetExtractCloseFileHandler(CabinetInfo.ExtractCloseFileHandler), fileContext, null, null, callback, context);
     }
 }
Example #3
0
 /// <summary>
 /// Creates a cabinet and writes it to a stream.
 /// </summary>
 /// <param name="stream">The stream for writing the cabinet.</param>
 /// <param name="files">The names of the files in the cabinet (not external file paths).</param>
 /// <param name="compLevel">The cabinet compression level.</param>
 /// <param name="openFileHandler">Callback for opening streams for reading included files.</param>
 /// <param name="closeFileHandler">Callback for closing included file streams. This may be null, in which
 /// case the stream's <see cref="Stream.Close"/> method will be called.</param>
 /// <param name="openFileContext">User context object that will be passed to the
 /// <paramref name="openFileHandler"/> and <paramref name="closeFileHandler"/>.</param>
 /// <param name="statusCallback">Callback for reporting creation progress.  This may be null
 /// if status is not desired.</param>
 /// <param name="statusContext">User context object passed to the <paramref name="statusCallback"/>.</param>
 /// <exception cref="CabinetCreateException">The cabinet could not be created.</exception>
 public static void Create(Stream stream, string[] files, CabinetCompressionLevel compLevel,
                           CabinetCreateOpenFileHandler openFileHandler, CabinetCreateCloseFileHandler closeFileHandler,
                           object openFileContext, CabinetStatusCallback statusCallback, object statusContext)
 #endif // !CABMINIMAL
 {
     if (stream == null)
     {
         throw new ArgumentNullException("stream");
     }
     Cabinet.Create(null, null, 0, 0, new CabinetOpenCabHandler(Cabinet.DefaultOpenCabHandler),
                    new CabinetCloseCabHandler(Cabinet.DefaultCloseCabHandler), stream, new string[][] { files }, compLevel,
                    openFileHandler, closeFileHandler, openFileContext
                 #if !CABMINIMAL
                    , statusCallback, statusContext
                 #endif // !CABMINIMAL
                    );
 }
Example #4
0
 /// <summary>
 /// Extracts files from a cabinet stream.
 /// </summary>
 /// <param name="stream">Stream for reading the cabinet file.</param>
 /// <param name="openFileHandler">Callback for opening streams for writing extracted files.</param>
 /// <param name="closeFileHandler">Callback for closing extracted file streams. This may be null, in which
 /// case the stream's <see cref="Stream.Close"/> method will be called.</param>
 /// <param name="openFileContext">User context object that will be passed to the
 /// <paramref name="openFileHandler"/> and <paramref name="closeFileHandler"/>.</param>
 /// <param name="filterFileHandler">Callback for filtering the list of extracted files.  If null,
 /// all files will be extracted.</param>
 /// <param name="filterContext">User context object that will be passed to the
 /// <paramref name="filterFileHandler"/>.</param>
 /// <param name="statusCallback">Callback for reporting extraction status.  This may be null
 /// if status is not desired.</param>
 /// <param name="statusContext">User context object passed to the <paramref name="statusCallback"/>.</param>
 /// <exception cref="CabinetExtractException">The stream is not a cabinet file or the cabinet file is corrupt.</exception>
 public static void Extract(Stream stream, CabinetExtractOpenFileHandler openFileHandler,
                            CabinetExtractCloseFileHandler closeFileHandler, object openFileContext,
                            CabinetFilterFileHandler filterFileHandler, object filterContext,
                            CabinetStatusCallback statusCallback, object statusContext)
 #endif
 {
     if (stream == null)
     {
         throw new ArgumentNullException("stream");
     }
     Cabinet.Extract(new CabinetOpenCabHandler(Cabinet.DefaultOpenCabHandler),
                     new CabinetCloseCabHandler(Cabinet.DefaultCloseCabHandler), stream, false, openFileHandler,
                     closeFileHandler, openFileContext, filterFileHandler, filterContext
                 #if !CABMINIMAL
                     , statusCallback, statusContext
                 #endif // !CABMINIMAL
                     );
 }
Example #5
0
        /// <summary>
        /// Compresses files into the cabinet file, specifying the names used to store the files in the cabinet.
        /// </summary>
        /// <param name="sourceDirectory">This parameter may be null, but if specified it is the root directory
        /// for any relative paths in <paramref name="filenameMap"/>.</param>
        /// <param name="filenameMap">A mapping from internal file paths to external file paths.</param>
        /// <param name="compLevel">The compression level used when creating the cabinet.</param>
        /// <param name="callback">Handler for receiving progress information; this may be null if progress is not desired.</param>
        /// <param name="context">User context object passed to the <paramref name="callback"/>, may be null.</param>
        internal virtual void CompressFileSet(string sourceDirectory, IDictionary filenameMap, CabinetCompressionLevel compLevel, CabinetStatusCallback callback, object context)
        {
            if (filenameMap == null)
            {
                throw new ArgumentNullException("filenameMap");
            }

            string[] fileNames = new string[filenameMap.Count];
            filenameMap.Keys.CopyTo(fileNames, 0);

            using (Stream stream = this.GetCabinetWriteStream())
            {
                Cabinet.Create(stream, fileNames, compLevel,
                               new CabinetCreateOpenFileHandler(CabinetInfo.CreateOpenFileHandler),
                               new CabinetCreateCloseFileHandler(CabinetInfo.CreateCloseFileHandler),
                               new object[] { sourceDirectory, filenameMap }, callback, context);
            }
        }
Example #6
0
        /// <summary>
        /// Compresses files into the cabinet file, specifying the names used to store the files in the cabinet.
        /// </summary>
        /// <param name="sourceDirectory">This parameter may be null, but if specified it is the root directory
        /// for any relative paths in <paramref name="sourceFileNames"/>.</param>
        /// <param name="sourceFileNames">The list of files to be included in the cabinet.</param>
        /// <param name="fileNames">The names of the files as they are stored in the cabinet. Each name
        /// includes the internal path of the file, if any. This parameter may be null, in which case the
        /// files are stored in the cabinet with their source file names and no path information.</param>
        /// <param name="compLevel">The compression level used when creating the cabinet.</param>
        /// <param name="callback">Handler for receiving progress information; this may be null if progress is not desired.</param>
        /// <param name="context">User context object passed to the <paramref name="callback"/>, may be null.</param>
        /// <remarks>
        /// Duplicate items in the <paramref name="fileNames"/> array will cause a <see cref="CabinetCreateException"/>.
        /// </remarks>
        internal virtual void CompressFiles(string sourceDirectory, string[] sourceFileNames, string[] fileNames, CabinetCompressionLevel compLevel, CabinetStatusCallback callback, object context)
        {
            if (sourceFileNames == null)
            {
                if (sourceDirectory == null)
                {
                    throw new ArgumentNullException("sourceDirectory", "Either sourceDirectory or sourceFileNames must be non-null.");
                }
                sourceFileNames = System.IO.Directory.GetFiles(sourceDirectory);
            }
            if (fileNames == null)
            {
                fileNames = new string[sourceFileNames.Length];
                for (int i = 0; i < sourceFileNames.Length; i++)
                {
                    fileNames[i] = Path.GetFileName(sourceFileNames[i]);
                }
            }

            using (Stream stream = this.GetCabinetWriteStream())
            {
                Cabinet.Create(stream, fileNames, compLevel,
                               new CabinetCreateOpenFileHandler(CabinetInfo.CreateOpenFileHandler),
                               new CabinetCreateCloseFileHandler(CabinetInfo.CreateCloseFileHandler),
                               new object[] { sourceDirectory, CreateStringDictionary(fileNames, sourceFileNames) }, callback, context);
            }
        }
Example #7
0
 /// <summary>
 /// Compresses all files in a directory into the cabinet file, optionally including subdirectories.
 /// The files are stored in the cabinet using their relative file paths in the directory tree.
 /// Note, while this library fully supports an internal directory structure in cabinets,
 /// some extraction tools do not.
 /// </summary>
 /// <param name="sourceDirectory">This parameter may be null, but if specified it is the root directory
 /// for any relative paths in source file.</param>
 /// <param name="includeSubdirectories">If true, recursively include files in subdirectories.</param>
 /// <param name="compLevel">The compression level used when creating the cabinet.</param>
 /// <param name="callback">Handler for receiving progress information; this may be null if progress is not desired.</param>
 /// <param name="context">User context object passed to the callback, may be null.</param>
 internal void CompressDirectory(string sourceDirectory, bool includeSubdirectories, CabinetCompressionLevel compLevel, CabinetStatusCallback callback, object context)
 {
     string[] files = GetRelativeFilePathsInDirectoryTree(sourceDirectory, includeSubdirectories);
     this.CompressFiles(sourceDirectory, files, files, compLevel, callback, context);
 }
Example #8
0
 /// <summary>
 /// Extracts multiple files from the cabinet. If any extracted files already exist on disk, they will be overwritten.
 /// </summary>
 /// <param name="filenameMap">A mapping from internal file paths to external file paths.
 /// Case-senstivity when matching internal paths depends on the IDictionary implementation.</param>
 /// <param name="destDirectory">This parameter may be null, but if specified it is the root directory
 /// for any relative external paths in <paramref name="filenameMap"/>.</param>
 /// <param name="update">Specify true to only extract files when the timestamp in the cabinet is newer than
 /// the timestamp of the file on disk, when the file already exists.</param>
 /// <param name="callback">Handler for receiving progress information; this may be null if progress is not desired.</param>
 /// <param name="context">User context object passed to the <paramref name="callback"/>, may be null.</param>
 internal virtual void ExtractFileSet(IDictionary filenameMap, string destDirectory, bool update, CabinetStatusCallback callback, Object context)
 {
     if (filenameMap == null)
     {
         throw new ArgumentNullException("filenameMap");
     }
     using (Stream stream = this.GetCabinetReadStream())
     {
         object[] fileContext = new Object[] { destDirectory, filenameMap, update };
         Cabinet.Extract(stream, new CabinetExtractOpenFileHandler(CabinetInfo.ExtractOpenFileHandler),
                         new CabinetExtractCloseFileHandler(CabinetInfo.ExtractCloseFileHandler), fileContext,
                         new CabinetFilterFileHandler(this.FilterFileHandler), filenameMap, callback, context);
     }
 }
Example #9
0
 /// <summary>
 /// Extracts multiple files from the cabinet, optionally extracting only newer files.
 /// </summary>
 /// <param name="fileNames">The names of the files in the cabinet. Each name includes the internal
 /// path of the file, if any. File name matching is case-insensitive.</param>
 /// <param name="destDirectory">This parameter may be null, but if specified it is the root directory
 /// for any relative paths in <paramref name="destFileNames"/>.</param>
 /// <param name="destFileNames">The paths where the files are to be extracted on disk. If this parameter is null,
 /// the files will be extracted with the names from the cabinet.</param>
 /// <param name="update">Specify true to only extract files when the timestamp in the cabinet is newer than
 /// the timestamp of the file on disk, when the file already exists.</param>
 /// <param name="callback">Handler for receiving progress information; this may be null if progress is not desired.</param>
 /// <param name="context">User context object passed to the <paramref name="callback"/>, may be null.</param>
 /// <remarks>
 /// If any extracted files already exist on disk, they will be overwritten.
 /// <p>The <paramref name="destDirectory"/> and <paramref name="destFileNames"/> parameters cannot both be null.</p>
 /// </remarks>
 internal void ExtractFiles(string[] fileNames, string destDirectory, string[] destFileNames, bool update, CabinetStatusCallback callback, object context)
 {
     if (fileNames == null)
     {
         throw new ArgumentNullException("fileNames");
     }
     if (destFileNames == null)
     {
         if (destDirectory == null)
         {
             throw new ArgumentNullException("destFileNames");
         }
         destFileNames = fileNames;
     }
     this.ExtractFileSet(CreateStringDictionary(fileNames, destFileNames), destDirectory, update, callback, context);
 }
Example #10
0
        public static void Create(CabinetNameHandler nameHandler, object nameContext, long maxCabSize, long maxFolderSize,
                                  CabinetOpenCabHandler openCabHandler, CabinetCloseCabHandler closeCabHandler, object openCabContext,
                                  string[][] foldersAndFiles, CabinetCompressionLevel compLevel, CabinetCreateOpenFileHandler openFileHandler,
                                  CabinetCreateCloseFileHandler closeFileHandler, object openFileContext,
                                  CabinetStatusCallback statusCallback, object statusContext)
        #endif // !CABMINIMAL
        {
            using (CabCreator cabInstance = new CabCreator(maxCabSize, maxFolderSize))
            {
                cabInstance.nameHandler      = nameHandler;
                cabInstance.nameContext      = nameContext;
                cabInstance.openCabHandler   = openCabHandler;
                cabInstance.closeCabHandler  = closeCabHandler;
                cabInstance.openCabContext   = openCabContext;
                cabInstance.openFileHandler  = openFileHandler;
                cabInstance.closeFileHandler = closeFileHandler;
                cabInstance.openFileContext  = openFileContext;

                        #if !CABMINIMAL
                cabInstance.statusCallback = statusCallback;
                cabInstance.statusContext  = statusContext;

                if (cabInstance.statusCallback != null)
                {
                    cabInstance.status.totalFolders = (short)foldersAndFiles.Length;
                    for (int iFolder = 0; iFolder < foldersAndFiles.Length; iFolder++)
                    {
                        string[] files = foldersAndFiles[iFolder];
                        for (int iFile = 0; iFile < files.Length; iFile++)
                        {
                            FileAttributes attributes;
                            DateTime       lastWriteTime;
                            Stream         fileStream = openFileHandler(files[iFile], out attributes, out lastWriteTime, openFileContext);
                            if (fileStream != null)
                            {
                                cabInstance.status.totalFileBytes += fileStream.Length;
                                cabInstance.status.totalFiles++;
                            }
                            closeFileHandler(files[iFile], fileStream, openFileContext);
                        }
                    }
                }
                        #endif // !CABMINIMAL

                for (int iFolder = 0; iFolder < foldersAndFiles.Length; iFolder++)
                {
                    string[] files = foldersAndFiles[iFolder];
                    for (int iFile = 0; iFile < files.Length; iFile++)
                    {
                        FileAttributes attributes;
                        DateTime       lastWriteTime;
                        Stream         fileStream = openFileHandler(files[iFile], out attributes, out lastWriteTime, openFileContext);
                        if (fileStream != null)
                        {
                                                #if !CABMINIMAL
                            if (cabInstance.statusCallback != null)
                            {
                                if (cabInstance.status.currentFolderTotalBytes > 0)
                                {
                                    cabInstance.status.currentFolderBytesProcessed = cabInstance.status.currentFolderTotalBytes;
                                    cabInstance.status.statusType = CabinetStatusType.FinishFolder;
                                    cabInstance.statusCallback(cabInstance.status, cabInstance.statusContext);
                                    cabInstance.status.currentFolderBytesProcessed = cabInstance.status.currentFolderTotalBytes = 0;

                                    if (!(iFolder == 0 && iFile == 0))
                                    {
                                        cabInstance.status.currentFolderNumber++;
                                        if (cabInstance.status.totalFolders <= cabInstance.status.currentFolderNumber)
                                        {
                                            cabInstance.status.totalFolders = (short)(cabInstance.status.currentFolderNumber + 1);
                                        }
                                    }
                                }
                            }
                                                #endif // !CABMINIMAL
                            cabInstance.status.currentFileName = files[iFile];
                            if (!(iFolder == 0 && iFile == 0))
                            {
                                cabInstance.status.currentFileNumber++;
                            }
                                                #if !CABMINIMAL
                            if (cabInstance.statusCallback != null)
                            {
                                cabInstance.status.currentFileTotalBytes     = fileStream.Length;
                                cabInstance.status.currentFileBytesProcessed = 0;
                                cabInstance.status.statusType = CabinetStatusType.StartFile;
                                cabInstance.statusCallback(cabInstance.status, cabInstance.statusContext);
                            }
                                                #endif // !CABMINIMAL

                            cabInstance.AddFile(files[iFile], fileStream, attributes, lastWriteTime, false, compLevel);
                        }
                    }
                    cabInstance.FlushFolder();
                }
                cabInstance.FlushCabinet();
            }
        }