public static string Decrypt(string encrPath, string decrPath, DerivedBytesProvider derivedBytesProvider, FileDecryptOptions options = null) { if (string.IsNullOrWhiteSpace(encrPath)) { throw new ArgumentNullException(nameof(encrPath)); } if (string.IsNullOrWhiteSpace(decrPath)) { throw new ArgumentNullException(nameof(decrPath)); } if (derivedBytesProvider == null) { throw new ArgumentNullException(nameof(derivedBytesProvider)); } options ??= new FileDecryptOptions(); using (FileStream inputStream = File.OpenRead(encrPath)) using (HelixFileDecryptor decryptor = new HelixFileDecryptor(inputStream)) { decryptor.Initialize(derivedBytesProvider); FileEntry header = decryptor.ReadHeader(); options?.AfterMetadataRead?.Invoke(header, options); if (!header.IsValid(out HeaderCorruptionException ex)) { throw ex; } string decrFullFileName = decrPath; string decrStagedFileName = decrPath + HelixConsts.StagedHxExtention; string decrBackupFileName = decrPath + HelixConsts.BackupExtention; if (header.EntryType == FileEntryType.File) { if (!string.IsNullOrEmpty(Path.GetDirectoryName(decrStagedFileName))) { Directory.CreateDirectory(Path.GetDirectoryName(decrStagedFileName)); } using (var contentStream = decryptor.GetContentStream()) using (var stagedFile = File.OpenWrite(decrStagedFileName)) { contentStream.CopyTo(stagedFile); } File.SetLastWriteTimeUtc(decrStagedFileName, header.LastWriteTimeUtc); if (File.Exists(decrFullFileName)) { File.Move(decrFullFileName, decrBackupFileName); } else if (Directory.Exists(decrFullFileName)) { if (Directory.GetFiles(decrFullFileName).Length > 0) { throw new IOException($"Unable to process entry, directory is not empty ({decrFullFileName})"); } Directory.Move(decrFullFileName, decrBackupFileName); } File.Move(decrStagedFileName, decrFullFileName); if (File.Exists(decrBackupFileName)) { File.SetAttributes(decrBackupFileName, FileAttributes.Normal); //incase it was read only File.Delete(decrBackupFileName); } else if (Directory.Exists(decrBackupFileName)) { Directory.Delete(decrBackupFileName); } } else if (header.EntryType == FileEntryType.Directory) { if (File.Exists(decrFullFileName)) { File.Move(decrFullFileName, decrBackupFileName); } if (Directory.Exists(decrFullFileName)) { //If there is a case difference need to delete the directory if (Path.GetFileName(decrFullFileName) != Path.GetFileName(new DirectoryInfo(decrFullFileName).Name)) { if (Directory.GetFiles(decrFullFileName).Length > 0) { throw new IOException($"Unable to process entry, directory is not empty ({decrFullFileName})"); } Directory.Move(decrFullFileName, decrBackupFileName); } } Directory.CreateDirectory(decrFullFileName); } else //purge or delete { if (File.Exists(decrFullFileName)) { File.Move(decrFullFileName, decrBackupFileName); } else if (Directory.Exists(decrFullFileName)) { if (Directory.GetFiles(decrFullFileName).Length > 0) { throw new IOException($"Unable to process entry, directory is not empty ({decrFullFileName})"); } Directory.Move(decrFullFileName, decrBackupFileName); } } if (File.Exists(decrBackupFileName)) { File.Delete(decrBackupFileName); } else if (Directory.Exists(decrBackupFileName)) { Directory.Delete(decrBackupFileName); } } return(decrPath); }
public static string Decrypt(string encrPath, string decrPath, string password, FileDecryptOptions options = null) { options = (options ?? new FileDecryptOptions()).Clone(); return(Decrypt(encrPath, decrPath, DerivedBytesProvider.FromPassword(password), options)); }