private static Task <MS2Archive> LoadMS2F(MS2CryptoMode cryptoMode, BinaryReader br, string name, MemoryMappedFile dataMemoryMappedFile) { return(Task.Run(async() => { uint unk = br.ReadUInt32(); // TODO: unknown/unused? uint dataCompressedSize = br.ReadUInt32() | br.ReadUInt32(); uint dataEncodedSize = br.ReadUInt32() | br.ReadUInt32(); uint size = br.ReadUInt32() | br.ReadUInt32(); uint compressedSize = br.ReadUInt32() | br.ReadUInt32(); uint encodedSize = br.ReadUInt32() | br.ReadUInt32(); uint fileCount = br.ReadUInt32() | br.ReadUInt32(); uint dataSize = br.ReadUInt32() | br.ReadUInt32(); if (unk != 0) { Logger.Debug($"Archive header unk is \"{unk}\"."); } var header = new MS2SizeHeader(encodedSize, compressedSize, size); var data = new MS2SizeHeader(dataEncodedSize, dataCompressedSize, dataSize); Logger.Verbose($"There are {fileCount} files in the archive."); List <MS2File> files = await LoadFiles(cryptoMode, header, data, fileCount, br, dataMemoryMappedFile).ConfigureAwait(false); var archive = new MS2Archive(cryptoMode, header, data, name, dataMemoryMappedFile, files); return archive; })); }
public async Task Save_OneFileToPath_ArchiveHeaderEqualsExpectedData() { const string FileName = nameof(Save_OneFileToPath_ArchiveHeaderEqualsExpectedData); string headerPath = FileName + HeaderFileExtension; string dataPath = FileName + DataFileExtension; string input = "inputdata123" + nameof(Save_OneFileToPath_ArchiveHeaderEqualsExpectedData); string encryptedInput = "encrypteddata654" + nameof(Save_OneFileToPath_ArchiveHeaderEqualsExpectedData); var sizeMock = CreateSizeMock(1, 20, 8); IMS2SizeHeader expectedFileInfoSize = sizeMock.Object; IMS2SizeHeader expectedFileDataSize = sizeMock.Object; long expectedFileCount = 1; MS2CryptoMode expectedCryptoMode = (MS2CryptoMode)12345; IMS2ArchiveCryptoRepository repo = new FakeCryptoRepository(expectedCryptoMode, EncodingTest, input, encryptedInput, sizeMock.Object); var archive = new MS2Archive(repo); AddDataStringToArchive(archive, input, encryptedInput, sizeMock, 1, "singlefile", CompressionType.Zlib); await archive.SaveAsync(headerPath, dataPath); using var fsHeader = File.OpenRead(headerPath); using var br = new BinaryReader(fsHeader, EncodingTest, true); MS2CryptoMode actualCryptoMode = (MS2CryptoMode)br.ReadUInt32(); var(actualFileInfoSize, actualFileDataSize, actualFileCount) = await repo.GetArchiveHeaderCrypto().ReadAsync(fsHeader); Assert.AreEqual(expectedCryptoMode, actualCryptoMode); Assert.AreEqual(expectedFileInfoSize.EncodedSize, actualFileInfoSize.EncodedSize); Assert.AreEqual(expectedFileInfoSize.CompressedSize, actualFileInfoSize.CompressedSize); Assert.AreEqual(expectedFileInfoSize.Size, actualFileInfoSize.Size); Assert.AreEqual(expectedFileDataSize.EncodedSize, actualFileDataSize.EncodedSize); Assert.AreEqual(expectedFileDataSize.CompressedSize, actualFileDataSize.CompressedSize); Assert.AreEqual(expectedFileDataSize.Size, actualFileDataSize.Size); Assert.AreEqual(expectedFileCount, actualFileCount); }
public async Task Save_ToFileOverwriteAndExpand_OutputEqualExpectedSize() { const string FileName = nameof(Save_ToFileOverwriteAndExpand_OutputEqualExpectedSize); string headerPath = FileName + HeaderFileExtension; string dataPath = FileName + DataFileExtension; string input = "inputdata123" + nameof(Save_ToFileOverwriteAndExpand_OutputEqualExpectedSize); string encryptedInput = "encrypteddata654" + nameof(Save_ToFileOverwriteAndExpand_OutputEqualExpectedSize); var sizeMock = CreateSizeMock(1, 20, 8); MS2CryptoMode expectedCryptoMode = (MS2CryptoMode)12345; IMS2ArchiveCryptoRepository repo = new FakeCryptoRepository(expectedCryptoMode, EncodingTest, input, encryptedInput, sizeMock.Object); int expectedHeaderLength = 60 + encryptedInput.Length * 2; int expectedDataLength = encryptedInput.Length; SetFileLength(headerPath, 1 << 10); SetFileLength(dataPath, 1 << 10); var archive = new MS2Archive(repo); AddDataStringToArchive(archive, input, encryptedInput, sizeMock, 1, "overwritefile", CompressionType.None); await archive.SaveAsync(headerPath, dataPath); int actualHeaderLength = File.ReadAllText(headerPath).Length; int actualDataLength = File.ReadAllText(dataPath).Length; Assert.AreEqual(expectedHeaderLength, actualHeaderLength); Assert.AreEqual(expectedDataLength, actualDataLength); }
private static byte[] DecryptNoDecompress(MS2CryptoMode cryptoMode, byte[] src, uint size) { IMultiArray key; IMultiArray iv; switch (cryptoMode) { case MS2CryptoMode.MS2F: key = Cryptography.MS2F.Key; iv = Cryptography.MS2F.IV; break; case MS2CryptoMode.NS2F: key = Cryptography.NS2F.Key; iv = Cryptography.NS2F.IV; break; default: case MS2CryptoMode.OS2F: case MS2CryptoMode.PS2F: throw new NotImplementedException(); } return(Decryption.DecryptNoDecompress(src, size, key[size], iv[size])); }
public async Task Save_ThreeFilesCompressedToFile_DataEqualsExpected() { const string FileName = nameof(Save_ThreeFilesToFile_DataEqualsExpected); string headerPath = FileName + HeaderFileExtension; string dataPath = FileName + DataFileExtension; string input = "inputdata123" + nameof(Save_ThreeFilesToFile_DataEqualsExpected); string encryptedInput = "encrypteddata654" + nameof(Save_ThreeFilesToFile_DataEqualsExpected); var sbExpected = new StringBuilder(); var sizeMock = CreateSizeMock(20, 30, 40); MS2CryptoMode cryptoMode = (MS2CryptoMode)12345; IMS2ArchiveCryptoRepository repo = new FakeCryptoRepository(cryptoMode, EncodingTest, input, encryptedInput, sizeMock.Object); const int fileCount = 3; var archive = MS2Archive.GetArchiveMS2F(); for (uint i = 1; i <= fileCount; i++) { sbExpected.Append(input); AddDataStringToArchive(archive, input, encryptedInput, sizeMock, i, "file" + i, CompressionType.Zlib); } await archive.SaveAsync(headerPath, dataPath); using var fsData = File.OpenRead(dataPath); StringBuilder sbActual = new StringBuilder(); for (uint i = 1; i <= fileCount; i++) { string actual = await StreamToString(await repo.GetDecryptionStreamAsync(fsData, sizeMock.Object, false)); sbActual.Append(actual); } Assert.AreEqual(sbExpected.ToString(), sbActual.ToString()); }
public async Task Save_OneFileToFile_FileInfoHeaderEqualsExpectedData() { const string FileName = nameof(Save_OneFileToFile_FileInfoHeaderEqualsExpectedData); string headerPath = FileName + HeaderFileExtension; string dataPath = FileName + DataFileExtension; string input = "inputdata123," + nameof(Save_OneFileToFile_FileInfoHeaderEqualsExpectedData); string encryptedInput = "encrypteddata654," + nameof(Save_OneFileToFile_FileInfoHeaderEqualsExpectedData); var sizeMock = CreateSizeMock(1, 20, 8); MS2CryptoMode expectedCryptoMode = (MS2CryptoMode)12345; IMS2FileInfo expectedFileInfo = CreateFileInfoMock(1.ToString(), "singlefile").Object; IMS2ArchiveCryptoRepository repo = new FakeCryptoRepository(expectedCryptoMode, EncodingTest, "1,singlefile", "1,singlefile", sizeMock.Object); var archive = new MS2Archive(repo); AddDataStringToArchive(archive, input, encryptedInput, sizeMock, 1, "singlefile", CompressionType.Zlib); await archive.SaveAsync(headerPath, dataPath); using var fsHeader = File.OpenRead(headerPath); using var br = new BinaryReader(fsHeader, EncodingTest, true); MS2CryptoMode actualCryptoMode = (MS2CryptoMode)br.ReadUInt32(); var(actualFileInfoSize, actualFileDataSize, actualFileCount) = await repo.GetArchiveHeaderCrypto().ReadAsync(fsHeader); var msFileInfo = await repo.GetDecryptionStreamAsync(fsHeader, actualFileInfoSize, true); using var srFileInfo = new StreamReader(msFileInfo, EncodingTest, true, -1, true); IMS2FileInfo actualFileInfo = await repo.GetFileInfoReaderCrypto().ReadAsync(srFileInfo); Assert.AreEqual(expectedFileInfo.Id, actualFileInfo.Id); Assert.AreEqual(expectedFileInfo.Path, actualFileInfo.Path); Assert.AreEqual(expectedFileInfo.RootFolderId, actualFileInfo.RootFolderId); }
public async Task TestConsistency() { string message = "very encrypted"; MS2CryptoMode cryptoMode = MS2CryptoMode.MS2F; Encoding encoding = Encoding.ASCII; byte[] bytesToEncrypt = encoding.GetBytes(message); { bool compress = true; (byte[] encryptedBytes, MS2SizeHeader header) = await CryptoHelper.EncryptDataToDataAsync(cryptoMode, compress, bytesToEncrypt).ConfigureAwait(false); byte[] decryptedBytes = await CryptoHelper.DecryptDataToDataAsync(cryptoMode, header, compress, encryptedBytes).ConfigureAwait(false); CollectionAssert.AreEqual(bytesToEncrypt, decryptedBytes); string decryptedMessage = encoding.GetString(decryptedBytes); Assert.AreEqual(message, decryptedMessage); } { bool compress = false; (byte[] encryptedBytes, MS2SizeHeader header) = await CryptoHelper.EncryptDataToDataAsync(cryptoMode, compress, bytesToEncrypt).ConfigureAwait(false); byte[] decryptedBytes = await CryptoHelper.DecryptDataToDataAsync(cryptoMode, header, compress, encryptedBytes).ConfigureAwait(false); CollectionAssert.AreEqual(bytesToEncrypt, decryptedBytes); string decryptedMessage = encoding.GetString(decryptedBytes); Assert.AreEqual(message, decryptedMessage); } }
public FakeCryptoRepository(MS2CryptoMode cryptoMode, Encoding encoding, string decrypted, string encrypted, IMS2SizeHeader encryptedSize) { this.CryptoMode = cryptoMode; this.Encoding = encoding; this.Decrypted = decrypted; this.Encrypted = encrypted; this.EncryptedSize = encryptedSize; }
private MS2File(MS2FileInfoHeader infoHeader, MS2FileHeader header, MS2CryptoMode archiveCryptoMode, MemoryMappedFile dataFile) { this.InfoHeader = infoHeader ?? throw new ArgumentNullException(nameof(infoHeader)); this.Header = header ?? throw new ArgumentNullException(nameof(header)); this.ArchiveCryptoMode = archiveCryptoMode; this.DataMemoryMappedFile = dataFile ?? throw new ArgumentNullException(nameof(dataFile)); this.CompressionType = this.Header.CompressionType; this.IsDataEncrypted = true; }
private static async Task SaveAsync(MS2CryptoMode cryptoMode, MS2File[] files, Stream headerStream, Stream dataStream) { MS2SizeHeader header; MS2SizeHeader dataHeader; Stream encryptedHeaderStream; Stream encryptedDataHeaderStream; using (var archiveInfoHeaderStream = new MemoryStream()) using (var archiveHeaderStream = new MemoryStream()) { var tasks = new Task <(MemoryStream ms, MS2SizeHeader header)> [files.Length];
private MS2Archive(MS2CryptoMode cryptoMode, MS2SizeHeader header, MS2SizeHeader data, string name, MemoryMappedFile dataFile, List <MS2File> files) { this.Name = name; this.DataFile = dataFile; this.CryptoMode = cryptoMode; this.Header = header; this.Data = data; this.Files = files; }
internal static async Task <MS2File> Load(MS2CryptoMode cryptoMode, Stream headerStream, Stream dataStream, MemoryMappedFile dataMemoryMappedFile) { MS2FileInfoHeader fileInfoHeader = await MS2FileInfoHeader.Load(headerStream).ConfigureAwait(false); MS2FileHeader fileHeader = await MS2FileHeader.Load(cryptoMode, dataStream).ConfigureAwait(false); DLogger.Write($"Id={fileInfoHeader.Id}-{fileHeader.Id}, CompressionId={fileHeader.CompressionType}, RootFolder={fileInfoHeader.RootFolderId}, Name={fileInfoHeader.Name}, Size={FileEx.FormatStorage(fileHeader.EncodedSize)}->{FileEx.FormatStorage(fileHeader.CompressedSize)}->{FileEx.FormatStorage(fileHeader.Size)}"); var file = new MS2File(fileInfoHeader, fileHeader, cryptoMode, dataMemoryMappedFile); return(file); }
private MS2File(MS2FileInfoHeader infoHeader, CompressionType compressionType, MS2CryptoMode archiveCryptoMode, Stream dataStream) { if (!dataStream.CanSeek) { throw new ArgumentException("Stream must be seekable.", nameof(dataStream)); } this.InfoHeader = infoHeader ?? throw new ArgumentNullException(nameof(infoHeader)); this.ArchiveCryptoMode = archiveCryptoMode; this.DataStream = dataStream ?? throw new ArgumentNullException(nameof(dataStream)); this.CompressionType = compressionType; this.IsDataEncrypted = false; }
/// <summary> /// Only supports <see cref="RunMode.Sync"/> and <see cref="RunMode.Async"/>. /// </summary> /// <param name="cryptoMode"></param> /// <param name="files"></param> /// <param name="headerStream"></param> /// <param name="dataStream"></param> /// <param name="runMode"></param> /// <returns></returns> public static Task Save(MS2CryptoMode cryptoMode, MS2File[] files, Stream headerStream, Stream dataStream, RunMode runMode) { switch (runMode) { case RunMode.Sync: return(SaveSync(cryptoMode, files, headerStream, dataStream)); case RunMode.Async: return(SaveAsync(cryptoMode, files, headerStream, dataStream)); default: throw new ArgumentException("Given RunMode is not supported for this method.", nameof(runMode)); } }
public static async Task <byte[]> DecryptDataToDataAsync(MS2CryptoMode cryptoMode, MS2SizeHeader header, bool isCompressed, byte[] bytes) { if (header.EncodedSize == 0 || header.CompressedSize == 0 || header.Size == 0) { return(new byte[0]); } if (isCompressed) { return(await Task.Run(() => Decrypt(cryptoMode, bytes, header.CompressedSize, header.Size)).ConfigureAwait(false)); } else { return(await Task.Run(() => DecryptNoDecompress(cryptoMode, bytes, header.Size)).ConfigureAwait(false)); } }
private static async Task <List <MS2File> > LoadFiles(MS2CryptoMode cryptoMode, MS2SizeHeader header, MS2SizeHeader data, uint fileCount, BinaryReader br, MemoryMappedFile dataMemoryMappedFile) { var files = new List <MS2File>((int)fileCount); // TODO: are those always compressed? using (Stream headerStream = await DecryptStreamToStreamAsync(cryptoMode, header, true, br.BaseStream).ConfigureAwait(false)) using (Stream dataStream = await DecryptStreamToStreamAsync(cryptoMode, data, true, br.BaseStream).ConfigureAwait(false)) { for (int i = 0; i < fileCount; i++) { files.Add(await MS2File.Load(cryptoMode, headerStream, dataStream, dataMemoryMappedFile).ConfigureAwait(false)); } return(files); } }
public static async Task <byte[]> DecryptStreamToDataAsync(MS2CryptoMode cryptoMode, MS2SizeHeader header, bool isCompressed, Stream stream) { if (header.EncodedSize == 0 || header.CompressedSize == 0 || header.Size == 0) { return(new byte[0]); } byte[] buffer = new byte[header.EncodedSize]; uint readBytes = (uint)await stream.ReadAsync(buffer, 0, (int)header.EncodedSize).ConfigureAwait(false); if (readBytes != header.EncodedSize) { throw new Exception("Data length mismatch when reading data."); } return(await DecryptDataToDataAsync(cryptoMode, header, isCompressed, buffer).ConfigureAwait(false)); }
internal static async Task <MS2FileHeader> Load(MS2CryptoMode cryptoMode, Stream stream) { using (var br = new BinaryReader(stream, Encoding.ASCII, true)) { switch (cryptoMode) { case MS2CryptoMode.MS2F: return(await CreateMS2F(br).ConfigureAwait(false)); case MS2CryptoMode.NS2F: return(await CreateNS2F(br).ConfigureAwait(false)); default: case MS2CryptoMode.OS2F: case MS2CryptoMode.PS2F: throw new NotImplementedException(); } } }
public async Task GetStreamAsync_StreamEncryptedTrueAndCompressionZlib_EqualsExpected() { string input = "testdatainputencryptedcompressed"; string expected = "testdataexpected"; MS2CryptoMode cryptoMode = (MS2CryptoMode)12345; var sizeMock = CreateSizeMock(10, 20, 30); IMS2ArchiveCryptoRepository repo = new FakeCryptoRepository(cryptoMode, EncodingTest, expected, input, sizeMock.Object); using MemoryStream inputStream = StringToStream(input); var archiveMock = CreateArchiveMock(repo); var infoMock = CreateFileInfoMock("1", "testfile"); var headerMock = CreateFileHeaderMock(sizeMock, 1, 0, CompressionType.Zlib); var file = new MS2File(archiveMock.Object, inputStream, infoMock.Object, headerMock.Object, true); var actualStream = await file.GetStreamAsync(); string actual = await StreamToString(actualStream); Assert.AreEqual(expected, actual); }
public async Task Save_OneFileToPath_DataEqualsInput() { const string FileName = nameof(Save_OneFileToPath_DataEqualsInput); string headerPath = FileName + HeaderFileExtension; string dataPath = FileName + DataFileExtension; string input = "inputdata123" + nameof(Save_OneFileToPath_DataEqualsInput); string encryptedInput = "encrypteddata654" + nameof(Save_OneFileToPath_DataEqualsInput); var sizeMock = CreateSizeMock(20, 30, 40); MS2CryptoMode cryptoMode = (MS2CryptoMode)12345; IMS2ArchiveCryptoRepository repo = new FakeCryptoRepository(cryptoMode, EncodingTest, input, encryptedInput, sizeMock.Object); var archive = new MS2Archive(repo); AddDataStringToArchive(archive, input, encryptedInput, sizeMock, 1, "singlefile", CompressionType.Zlib); await archive.SaveAsync(headerPath, dataPath); using var fsData = File.OpenRead(dataPath); string actual = await StreamToString(await repo.GetDecryptionStreamAsync(fsData, sizeMock.Object, false)); Assert.AreEqual(input, actual); }
private static Task <MS2Archive> LoadNS2F(MS2CryptoMode cryptoMode, BinaryReader br, string name, MemoryMappedFile dataMemoryMappedFile) { return(Task.Run(async() => { uint fileCount = br.ReadUInt32(); uint dataCompressedSize = br.ReadUInt32() | br.ReadUInt32(); uint dataEncodedSize = br.ReadUInt32() | br.ReadUInt32(); uint size = br.ReadUInt32() | br.ReadUInt32(); uint compressedSize = br.ReadUInt32() | br.ReadUInt32(); uint encodedSize = br.ReadUInt32() | br.ReadUInt32(); uint dataSize = br.ReadUInt32() | br.ReadUInt32(); var header = new MS2SizeHeader(encodedSize, compressedSize, size); var data = new MS2SizeHeader(dataEncodedSize, dataCompressedSize, dataSize); List <MS2File> files = await LoadFiles(cryptoMode, header, data, fileCount, br, dataMemoryMappedFile).ConfigureAwait(false); var archive = new MS2Archive(cryptoMode, header, data, name, dataMemoryMappedFile, files); return archive; })); }
internal async Task Save(MS2CryptoMode cryptoMode, Stream stream) { using (var bw = new BinaryWriter(stream, Encoding.ASCII, true)) { switch (cryptoMode) { case MS2CryptoMode.MS2F: await this.SaveMS2F(bw).ConfigureAwait(false); break; case MS2CryptoMode.NS2F: await this.SaveNS2F(bw).ConfigureAwait(false); break; default: case MS2CryptoMode.OS2F: case MS2CryptoMode.PS2F: throw new NotImplementedException(); } } }
public static async Task Save(MS2CryptoMode cryptoMode, MS2File[] files, string headerFilePath, string dataFilePath, RunMode runMode) { using (Stream headerStream = File.Open(headerFilePath, FileMode.Create, FileAccess.Write, FileShare.Read)) { switch (runMode) { case RunMode.Sync: case RunMode.Async: using (Stream dataStream = File.Open(dataFilePath, FileMode.Create, FileAccess.Write, FileShare.Read)) { await Save(cryptoMode, files, headerStream, dataStream, runMode).ConfigureAwait(false); } break; case RunMode.Async2: await SaveAsync2(cryptoMode, files, headerStream, dataFilePath).ConfigureAwait(false); break; default: throw new ArgumentException("Given RunMode is not supported for this method.", nameof(runMode)); } } }
public async Task GetStreamForArchivingAsync_StreamEncryptedTrueAndCompressionNone_EqualsInput() { string input = "testdatainput"; string expected = input; MS2CryptoMode cryptoMode = (MS2CryptoMode)12345; var sizeMock = CreateSizeMock(10, 10, 10); var expectedSize = sizeMock.Object; IMS2ArchiveCryptoRepository repo = new FakeCryptoRepository(cryptoMode, EncodingTest, input, expected, sizeMock.Object); using MemoryStream inputStream = StringToStream(input); var archiveMock = CreateArchiveMock(repo); var infoMock = CreateFileInfoMock("1", "testfile"); var headerMock = CreateFileHeaderMock(sizeMock, 1, 0, CompressionType.None); var file = new MS2File(archiveMock.Object, inputStream, infoMock.Object, headerMock.Object, true); var(actualStream, actualSize) = await file.GetStreamForArchivingAsync(); string actual = await StreamToString(actualStream); Assert.AreEqual(expected, actual); Assert.AreEqual(expectedSize.EncodedSize, actualSize.EncodedSize); Assert.AreEqual(expectedSize.CompressedSize, actualSize.CompressedSize); Assert.AreEqual(expectedSize.Size, actualSize.Size); }
public static Task <Stream> DecryptStreamToStreamAsync(MS2CryptoMode cryptoMode, MS2SizeHeader header, bool isCompressed, Stream stream) { return(DecryptStreamToDataAsync(cryptoMode, header, isCompressed, stream).ContinueWith <Stream>(t => new MemoryStream(t.Result))); }
public static MS2File Create(uint id, string pathInArchive, CompressionType compressionType, MS2CryptoMode archiveCryptoMode, Stream dataStream) => new MS2File(MS2FileInfoHeader.Create(id.ToString(), pathInArchive), compressionType, archiveCryptoMode, dataStream);
public async Task TestCreateConsistencyMS2F() { const string archiveName = "PrecomputedTerrain"; const string folderToArchive = @"C:\Users\Miyu\Desktop\ReleaseOutput\Resource\" + archiveName; string folderToArchiveFullPath = Path.GetFullPath(folderToArchive) + @"\"; string[] filesToArchive = Directory.GetFiles(folderToArchive, "*.*", SearchOption.AllDirectories).Select(p => Path.GetFullPath(p)).ToArray(); const string headerFilePath = @"..\TestData\PrecomputedTerrain.m2h"; const string dataFilePath = @"..\TestData\PrecomputedTerrain.m2d"; MS2CryptoMode archiveCryptoMode = MS2CryptoMode.MS2F; MS2File[] files = new MS2File[filesToArchive.Length]; for (int i = 0; i < filesToArchive.Length; i++) { string file = filesToArchive[i]; files[i] = MS2File.Create((uint)i + 1u, file.Remove(folderToArchiveFullPath), CompressionType.Zlib, archiveCryptoMode, file); } const string testArchiveName = "FromExtractedMS2F"; const string headerTestFileName = testArchiveName + ".m2h"; const string dataTestFileName = testArchiveName + ".m2d"; try { await MS2Archive.Save(archiveCryptoMode, files, headerTestFileName, dataTestFileName, RunMode.Async2).ConfigureAwait(false); Assert.IsTrue(File.Exists(headerTestFileName)); Assert.IsTrue(File.Exists(dataTestFileName)); using (MS2Archive archive = await MS2Archive.Load(headerFilePath, dataFilePath).ConfigureAwait(false)) { Dictionary <uint, MS2File> mappedFiles = archive.Files.Zip(files, (o, s) => (o, s)) .ToDictionary(f => f.o.Id, f => files.Where(sf => sf.Name == f.o.Name).First()); Assert.AreEqual(archive.CryptoMode, archiveCryptoMode); Assert.AreEqual(archive.Files.Count, filesToArchive.Length); //Assert.AreEqual(archive.Name, ArchiveName); Task[] tasks = new Task[filesToArchive.Length]; for (int i = 0; i < filesToArchive.Length; i++) { int ic = i; tasks[ic] = Task.Run(async() => { MS2File file = archive.Files[ic]; MS2File savedFile = mappedFiles[file.Id]; var(savedStream, savedShouldDispose) = await savedFile.GetDecryptedStreamAsync().ConfigureAwait(false); try { Assert.AreEqual(file.Id, (uint)ic + 1); Assert.AreEqual(file.CompressionType, CompressionType.Zlib); Assert.IsTrue(file.IsZlibCompressed); Assert.AreEqual(file.Name, savedFile.Name); Assert.AreEqual(file.Header.CompressionType, file.CompressionType); Assert.AreEqual(file.Header.Size, (uint)savedStream.Length); (Stream stream, bool shouldDispose) = await file.GetDecryptedStreamAsync().ConfigureAwait(false); try { byte[] savedBytes = new byte[savedStream.Length]; byte[] originalBytes = new byte[stream.Length]; int savedReadBytes = await savedStream.ReadAsync(savedBytes, 0, savedBytes.Length).ConfigureAwait(false); int originalReadBytes = await stream.ReadAsync(originalBytes, 0, originalBytes.Length).ConfigureAwait(false); Assert.AreEqual(originalReadBytes, savedReadBytes); CollectionAssert.AreEqual(originalBytes, savedBytes); } finally { if (shouldDispose) { stream.Dispose(); } } } finally { if (savedShouldDispose) { savedStream.Dispose(); } } }); } await Task.WhenAll(tasks).ConfigureAwait(false); } } finally { File.Delete(headerTestFileName); File.Delete(dataTestFileName); } }
public static Task <(Stream Stream, MS2SizeHeader Header)> EncryptStreamToStreamAsync(MS2CryptoMode cryptoMode, bool compress, Stream stream, uint count) { return(EncryptStreamToDataAsync(cryptoMode, compress, stream, count).ContinueWith <(Stream, MS2SizeHeader)>(t => (new MemoryStream(t.Result.Bytes), t.Result.Header))); }
public static async Task <(byte[] Bytes, MS2SizeHeader Header)> EncryptDataToDataAsync(MS2CryptoMode cryptoMode, bool compress, byte[] bytes) { if (compress) { byte[] compressedBytes = await Task.Run(() => Compress(bytes)).ConfigureAwait(false); byte[] encryptedBytes = await Task.Run(() => EncryptNoCompress(cryptoMode, compressedBytes, (uint)compressedBytes.Length)).ConfigureAwait(false); var header = new MS2SizeHeader((uint)encryptedBytes.Length, (uint)compressedBytes.Length, (uint)bytes.Length); return(encryptedBytes, header); } else { byte[] encryptedBytes = await Task.Run(() => EncryptNoCompress(cryptoMode, bytes, (uint)bytes.Length)).ConfigureAwait(false); var header = new MS2SizeHeader((uint)encryptedBytes.Length, (uint)bytes.Length, (uint)bytes.Length); return(encryptedBytes, header); } }
public static async Task <(byte[] Bytes, MS2SizeHeader Header)> EncryptStreamToDataAsync(MS2CryptoMode cryptoMode, bool compress, Stream stream, uint count) { if (count == 0) { return(new byte[0], new MS2SizeHeader(0u, 0u, 0u)); } byte[] buffer = new byte[count]; uint readBytes = (uint)await stream.ReadAsync(buffer, 0, (int)count).ConfigureAwait(false); if (readBytes != count) { throw new Exception("Data length mismatch when reading data."); } return(await EncryptDataToDataAsync(cryptoMode, compress, buffer).ConfigureAwait(false)); }