예제 #1
0
        /// <summary>
        /// Receives notification callbacks from the File Decompression Interface (FDI).
        /// </summary>
        /// <param name="fdint">A <see cref="FdiNotificationType"/> value that specifies which notification is being sent.</param>
        /// <param name="fdin">A <see cref="FdiNotification"/> that contains information about the notification</param>
        /// <returns>The return value is dependent on the notification type.</returns>
        /// <remarks>The File Decompression Interface (FDI)provides notifications for six different events.  Clients must respond to those
        /// notifications by handling the <see cref="NotifyCabinetInfo"/>, <see cref="NotifyCloseFile"/>, <see cref="NotifyCopyFile"/>,
        /// <see cref="NotifyEnumerate"/>, <see cref="NotifyNextCabinet"/>, and <see cref="NotifyPartialFile"/> events.</remarks>
        protected virtual int NotifyCallback(FdiNotificationType fdint, FdiNotification fdin)
        {
            Trace.WriteLine(string.Format("NotifyCallback: type {0}", fdint));

            NotifyEventArgs e = new NotifyEventArgs(fdin);

            // fire the proper event
            switch (fdint)
            {
            case FdiNotificationType.CabinetInfo:
                OnNotifyCabinetInfo(e);
                break;

            case FdiNotificationType.CloseFileInfo:
                OnNotifyCloseFile(e);
                break;

            case FdiNotificationType.CopyFile:
                OnNotifyCopyFile(e);
                break;

            case FdiNotificationType.Enumerate:
                OnNotifyEnumerate(e);
                break;

            case FdiNotificationType.NextCabinet:
                OnNotifyNextCabinet(e);
                break;

            case FdiNotificationType.PartialFile:
                OnNotifyPartialFile(e);
                break;
            }
            return(e.Result);
        }
예제 #2
0
        private IntPtr OutputFileOpen(FdiNotification fdin)
        {
            if (_decompressAll)
            { // Extract all files
                DecompressFile extractFile = new DecompressFile();
                _decompressFiles.Add(extractFile);

                MemoryStream stream = new MemoryStream();
                GCHandle     gch    = GCHandle.Alloc(stream);
                extractFile.Name   = fdin.psz1;
                extractFile.Handle = (IntPtr)gch;

                return(extractFile.Handle);
            }
            else
            { // Extract only some files
                DecompressFile extractFile = _decompressFiles.Where(ef => ef.Name == fdin.psz1).SingleOrDefault();
                if (extractFile == null)
                { // Do not extract, not in the decompress list
                    return(IntPtr.Zero);
                }
                else
                { // Do extract, found in the decompress List
                    MemoryStream stream = new MemoryStream();
                    GCHandle     gch    = GCHandle.Alloc(stream);
                    extractFile.Handle = (IntPtr)gch;

                    return(extractFile.Handle);
                }
            }
        }
예제 #3
0
        private IntPtr NotifyCallback(FdiNotificationType fdint, FdiNotification fdin)
        {
            switch (fdint)
            {
            case FdiNotificationType.CopyFile:
                return(OutputFileOpen(fdin));

            case FdiNotificationType.CloseFileInfo:
                return(OutputFileClose(fdin));

            default:
                return(IntPtr.Zero);
            }
        }
예제 #4
0
        private IntPtr OutputFileOpen(FdiNotification fdin)
        {
            CabDecompressFile extractFile = _decompressFiles.SingleOrDefault(ef => ef.Name == fdin.psz1);

            if (extractFile != null)
            {
                MemoryStream stream = new MemoryStream();
                GCHandle     gch    = GCHandle.Alloc(stream);
                extractFile.Handle = (IntPtr)gch;
                return(extractFile.Handle);
            }

            //Don't extract
            return(IntPtr.Zero);
        }
예제 #5
0
        private IntPtr OutputFileClose(FdiNotification fdin)
        {
            DecompressFile extractFile = _decompressFiles.Where(ef => ef.Handle == fdin.hf).Single();

            using (Stream stream = StreamFromHandle(fdin.hf))
            {
                extractFile.Found  = true;
                extractFile.Length = (int)stream.Length;

                if (0 < stream.Length)
                {
                    extractFile.Data = new byte[stream.Length];
                    stream.Position  = 0;
                    stream.Read(extractFile.Data, 0, (int)stream.Length);
                }
            }

            return((IntPtr)TRUE);
        }
예제 #6
0
        private IntPtr OutputFileClose(FdiNotification fdin)
        {
            CabDecompressFile extractFile = _decompressFiles.Single(ef => ef.Handle == fdin.hf);
            Stream            stream      = StreamFromHandle(fdin.hf);

            extractFile.Found  = true;
            extractFile.Length = (int)stream.Length;

            if (stream.Length > 0)
            {
                extractFile.Data = new byte[stream.Length];
                stream.Position  = 0;
                stream.Read(extractFile.Data,
                            0,
                            (int)stream.Length);
            }

            stream.Close();
            return(IntPtr.Zero);
        }
예제 #7
0
        // Handles FDI notification
        internal static IntPtr FdiNotify(FdiNotificationType fdint, FdiNotification fdin)
        {
            switch (fdint)
            {
            case FdiNotificationType.FdintCOPY_FILE:
            {
                // TODO: Should I catch exceptions for the new functions?

                // Copy target directory
                string destPath = Marshal.PtrToStringAnsi(fdin.pv);

                // Split the path to a filename and path
                string fileName          = Path.GetFileName(fdin.psz1);
                string remainingPsz1Path = Path.GetDirectoryName(fdin.psz1);
                destPath = Path.Combine(destPath, remainingPsz1Path);

                Directory.CreateDirectory(destPath);         // Creates all intermediate directories if necessary.

                // Create the file
                string absoluteFilePath = Path.Combine(destPath, fileName);
                return(CabinetNativeApi.FdiOpen(absoluteFilePath, (int)OpFlags.Create, (int)(PermissionMode.Read | PermissionMode.Write)));        // TODO: OK to ignore _O_SEQUENTIAL, WrOnly, and _O_BINARY?
            }

            case FdiNotificationType.FdintCLOSE_FILE_INFO:
            {
                // Close the file
                CabinetNativeApi.FdiClose(fdin.hf);

                // Set the file attributes
                string destPath         = Marshal.PtrToStringAnsi(fdin.pv);
                string absoluteFilePath = Path.Combine(destPath, fdin.psz1);

                IntPtr hFile = PlatformInvokes.CreateFile(
                    absoluteFilePath,
                    PlatformInvokes.FileDesiredAccess.GenericRead | PlatformInvokes.FileDesiredAccess.GenericWrite,
                    PlatformInvokes.FileShareMode.Read,
                    IntPtr.Zero,
                    PlatformInvokes.FileCreationDisposition.OpenExisting,
                    PlatformInvokes.FileAttributes.Normal,
                    IntPtr.Zero);

                if (hFile != IntPtr.Zero)
                {
                    PlatformInvokes.FILETIME ftFile = new PlatformInvokes.FILETIME();
                    if (PlatformInvokes.DosDateTimeToFileTime(fdin.date, fdin.time, ftFile))
                    {
                        PlatformInvokes.FILETIME ftLocal = new PlatformInvokes.FILETIME();
                        if (PlatformInvokes.LocalFileTimeToFileTime(ftFile, ftLocal))
                        {
                            PlatformInvokes.SetFileTime(hFile, ftLocal, null, ftLocal);
                        }
                    }

                    PlatformInvokes.CloseHandle(hFile);
                }

                PlatformInvokes.SetFileAttributesW(
                    absoluteFilePath,
                    (PlatformInvokes.FileAttributes)fdin.attribs & (PlatformInvokes.FileAttributes.ReadOnly | PlatformInvokes.FileAttributes.Hidden | PlatformInvokes.FileAttributes.System | PlatformInvokes.FileAttributes.Archive));

                // Call notification function
                return(new IntPtr(1));
            }
            }

            return(new IntPtr(0));
        }
예제 #8
0
 private static IntPtr OutputFileOpen(FdiNotification fdin)
 {
     // Console.WriteLine("OutputFileOpen:" + fdin.psz1);
       var stream = new MemoryStream();
       return (IntPtr)GCHandle.Alloc(stream);
 }
예제 #9
0
 private static IntPtr OutputFileClose(FdiNotification fdin)
 {
     var stream = StreamFromHandle(fdin.hf);
       var data = new Byte[stream.Length];
       stream.Position = 0;
       stream.Read(data, 0, (Int32)stream.Length);
       stream.Close();
       File.WriteAllBytes(fdin.psz1, data);
       return IntPtr.Zero;
 }
예제 #10
0
 private static IntPtr NotifyCallback(FdiNotificationType fdint, FdiNotification fdin)
 {
     switch (fdint)
       {
     case FdiNotificationType.CopyFile:
       return OutputFileOpen(fdin);
     case FdiNotificationType.CloseFileInfo:
       return OutputFileClose(fdin);
     default:
       return IntPtr.Zero;
       }
 }
예제 #11
0
 /// <summary>
 /// Initializes a new instance of the NotifyEventArgs class.
 /// </summary>
 /// <param name="f">An <see cref="FdiNotification"/> struction that contains notification information.</param>
 public NotifyEventArgs(FdiNotification f)
 {
     fdin   = f;
     result = 0;
 }
예제 #12
0
        // Handles FDI notification
        internal static IntPtr FdiNotify(FdiNotificationType fdint, FdiNotification fdin)
        {
            switch (fdint)
            {
                case FdiNotificationType.FdintCOPY_FILE:
                    {
                        // TODO: Should I catch exceptions for the new functions?

                        // Copy target directory
                        string destPath = Marshal.PtrToStringAnsi(fdin.pv);

                        // Split the path to a filename and path
                        string fileName = Path.GetFileName(fdin.psz1);
                        string remainingPsz1Path = Path.GetDirectoryName(fdin.psz1);
                        destPath = Path.Combine(destPath, remainingPsz1Path);

                        Directory.CreateDirectory(destPath); // Creates all intermediate directories if necessary.

                        // Create the file
                        string absoluteFilePath = Path.Combine(destPath, fileName);
                        return CabinetNativeApi.FdiOpen(absoluteFilePath, (int)OpFlags.Create, (int)(PermissionMode.Read | PermissionMode.Write)); // TODO: OK to ignore _O_SEQUENTIAL, WrOnly, and _O_BINARY?
                    }
                case FdiNotificationType.FdintCLOSE_FILE_INFO:
                    {
                        // Close the file
                        CabinetNativeApi.FdiClose(fdin.hf);

                        // Set the file attributes
                        string destPath = Marshal.PtrToStringAnsi(fdin.pv);
                        string absoluteFilePath = Path.Combine(destPath, fdin.psz1);

                        IntPtr hFile = PlatformInvokes.CreateFile(
                            absoluteFilePath,
                            PlatformInvokes.FileDesiredAccess.GenericRead | PlatformInvokes.FileDesiredAccess.GenericWrite,
                            PlatformInvokes.FileShareMode.Read,
                            IntPtr.Zero,
                            PlatformInvokes.FileCreationDisposition.OpenExisting,
                            PlatformInvokes.FileAttributes.Normal,
                            IntPtr.Zero);

                        if (hFile != IntPtr.Zero)
                        {
                            PlatformInvokes.FILETIME ftFile = new PlatformInvokes.FILETIME();
                            if (PlatformInvokes.DosDateTimeToFileTime(fdin.date, fdin.time, ftFile))
                            {
                                PlatformInvokes.FILETIME ftLocal = new PlatformInvokes.FILETIME();
                                if (PlatformInvokes.LocalFileTimeToFileTime(ftFile, ftLocal))
                                {
                                    PlatformInvokes.SetFileTime(hFile, ftLocal, null, ftLocal);
                                }
                            }

                            PlatformInvokes.CloseHandle(hFile);
                        }

                        PlatformInvokes.SetFileAttributesW(
                            absoluteFilePath,
                            (PlatformInvokes.FileAttributes)fdin.attribs & (PlatformInvokes.FileAttributes.ReadOnly | PlatformInvokes.FileAttributes.Hidden | PlatformInvokes.FileAttributes.System | PlatformInvokes.FileAttributes.Archive));

                        // Call notification function
                        return new IntPtr(1);
                    }
            }
            return new IntPtr(0);
        }