// 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)); }
// 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); }