private Stream Decrypt(out ArchiveListingHeaderV2 header)
        {
            Stream result = _accessor.ExtractListing();
            try
            {
                header = result.ReadStruct<ArchiveListingHeaderV2>();
                if (header.IsValid(result.Length))
                    return result;

                using (TempFileProvider tmpProvider = new TempFileProvider("filelist", ".win32.bin"))
                {
                    using (Stream output = tmpProvider.Create())
                    {
                        output.WriteStruct(header);
                        result.CopyTo(output);
                        result.SafeDispose();
                    }

                    Process decrypter = new Process
                    {
                        StartInfo = new ProcessStartInfo()
                        {
                            FileName = @"Resources\Executable\ffxiiicrypt.exe",
                            Arguments = "-d \"" + tmpProvider.FilePath + "\" 2",
                            CreateNoWindow = true,
                            UseShellExecute = false,
                            RedirectStandardOutput = true,
                            RedirectStandardError = true
                        }
                    };
                    decrypter.Start();
                    Task<string> erroMessage = decrypter.StandardError.ReadToEndAsync();
                    Task<string> outputMessage = decrypter.StandardOutput.ReadToEndAsync();
                    decrypter.WaitForExit();
                    if (decrypter.ExitCode != 0)
                    {
                        StringBuilder sb = new StringBuilder("Decryption error! Code: ");
                        sb.AppendLine(decrypter.ExitCode.ToString());
                        sb.AppendLine("Error: ");
                        sb.AppendLine(erroMessage.Result);
                        sb.AppendLine("Output: ");
                        sb.AppendLine(outputMessage.Result);

                        throw new InvalidDataException(sb.ToString());
                    }

                    result = tmpProvider.OpenRead();
                    header = result.ReadStruct<ArchiveListingHeaderV2>();
                    if (!header.IsValid(result.Length))
                        throw new InvalidDataException();
                }

                return result;
            }
            catch
            {
                result.SafeDispose();
                throw;
            }
        }
        private void RecreateEncryptedListing(MemoryStream headerBuff, int hederSize, MemoryStream textBuff, int blocksSize, byte[] buff)
        {
            using (TempFileProvider tmpProvider = new TempFileProvider("filelist", ".win32.bin"))
            {
                using (Stream output = tmpProvider.Create())
                {
                    headerBuff.CopyToStream(output, hederSize, buff);
                    textBuff.CopyToStream(output, blocksSize, buff);
                }

                Process encrypter = new Process
                {
                    StartInfo = new ProcessStartInfo()
                    {
                        FileName = @"Resources\Executable\ffxiiicrypt.exe",
                        Arguments = "-e \"" + tmpProvider.FilePath + "\" 2",
                        CreateNoWindow = true,
                        UseShellExecute = false,
                        RedirectStandardOutput = true,
                        RedirectStandardError = true
                    }
                };
                encrypter.Start();
                Task<string> erroMessage = encrypter.StandardError.ReadToEndAsync();
                Task<string> outputMessage = encrypter.StandardOutput.ReadToEndAsync();
                encrypter.WaitForExit();
                if (encrypter.ExitCode != 0)
                {
                    StringBuilder sb = new StringBuilder("Decryption error! Code: ");
                    sb.AppendLine(encrypter.ExitCode.ToString());
                    sb.AppendLine("Error: ");
                    sb.AppendLine(erroMessage.Result);
                    sb.AppendLine("Output: ");
                    sb.AppendLine(outputMessage.Result);

                    throw new InvalidDataException(sb.ToString());
                }

                using (Stream input = tmpProvider.OpenRead())
                using (Stream output = _accessor.RecreateListing((Int32)input.Length))
                    input.CopyToStream(output, (Int32)input.Length, buff);
            }
        }