/// <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); }
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); } } }
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); } }
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); }
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); }
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); }
// 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)); }
private static IntPtr OutputFileOpen(FdiNotification fdin) { // Console.WriteLine("OutputFileOpen:" + fdin.psz1); var stream = new MemoryStream(); return (IntPtr)GCHandle.Alloc(stream); }
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; }
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; } }
/// <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; }
// 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); }