예제 #1
0
        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);
        }
예제 #2
0
 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));
 }