private void Extract(NCSDPartition section, Stream outputStream) { using (outputStream) { Tools.ExtractFileStreamPart(this.NCSDMemoryMappedFile, outputStream, section.Offset, section.Size); } }
public void Decrypt(FileStream outputStream, bool trim = true) { if (this.Cryptor == null || this.SeedDatabase == null) { throw new ArgumentException("Cannot decrypt without seed database or crypto engine."); } long size; if (!trim) { outputStream.SetLength(this.Info.ImageSize); } else { size = this.Info.Partitions[0].Offset; foreach (NCSDPartition partition in this.Info.Partitions) { size += partition.Size; } outputStream.SetLength(size); } outputStream.Seek(0, SeekOrigin.Begin); MemoryMappedFile outputFile = Tools.LoadFileMapped(outputStream); using (MemoryMappedViewStream srcHeaderViewStream = this.NCSDMemoryMappedFile.CreateViewStream(0x0, this.Info.Partitions[0].Offset)) { using (MemoryMappedViewStream destHeaderViewStream = outputFile.CreateViewStream(0x0, this.Info.Partitions[0].Offset)) { srcHeaderViewStream.CopyTo(destHeaderViewStream); } } foreach (NCSDPartition partition in this.Info.Partitions) { using (MemoryMappedViewStream destPartitionViewStream = outputFile.CreateViewStream(partition.Offset, partition.Size)) { NCCH ncch = new NCCH(this.NCSDMemoryMappedFile, partition.Offset, this.Cryptor, this.SeedDatabase); ncch.Decrypt(outputFile); } } if (!trim) { NCSDPartition lastPartition = this.Info.Partitions.Last(); long lastPosition = lastPartition.Offset + lastPartition.Size; using (MemoryMappedViewStream viewStream = outputFile.CreateViewStream(lastPosition, this.Info.ImageSize - lastPosition)) { while (viewStream.Position / 64 < viewStream.Length / 64) { byte[] buffer = new byte[64]; for (int i = 0; i < buffer.Length; i++) { buffer[i] = 0xFF; } viewStream.Write(buffer, 0, buffer.Length); } } } }