diff --git a/.idea/.idea.Aaru/.idea/contentModel.xml b/.idea/.idea.Aaru/.idea/contentModel.xml
index 712090b5f..7fefc7113 100644
--- a/.idea/.idea.Aaru/.idea/contentModel.xml
+++ b/.idea/.idea.Aaru/.idea/contentModel.xml
@@ -279,7 +279,11 @@
-
+
+
+
+
+
diff --git a/Aaru.Core/Aaru.Core.csproj b/Aaru.Core/Aaru.Core.csproj
index 705984182..fd0b8088f 100644
--- a/Aaru.Core/Aaru.Core.csproj
+++ b/Aaru.Core/Aaru.Core.csproj
@@ -60,7 +60,9 @@
-
+
+
+
diff --git a/Aaru.Core/Devices/Dumping/PlayStationPortable.cs b/Aaru.Core/Devices/Dumping/PlayStationPortable.cs
deleted file mode 100644
index a919865ef..000000000
--- a/Aaru.Core/Devices/Dumping/PlayStationPortable.cs
+++ /dev/null
@@ -1,1234 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Xml.Serialization;
-using Aaru.CommonTypes;
-using Aaru.CommonTypes.Enums;
-using Aaru.CommonTypes.Extents;
-using Aaru.CommonTypes.Interfaces;
-using Aaru.CommonTypes.Metadata;
-using Aaru.CommonTypes.Structs;
-using Aaru.CommonTypes.Structs.Devices.SCSI;
-using Aaru.Console;
-using Aaru.Core.Logging;
-using Aaru.Decoders.SCSI;
-using Aaru.Devices;
-using Schemas;
-using MediaType = Aaru.CommonTypes.MediaType;
-using TrackType = Aaru.CommonTypes.Enums.TrackType;
-using Version = Aaru.CommonTypes.Interop.Version;
-
-namespace Aaru.Core.Devices.Dumping
-{
- public partial class Dump
- {
- static readonly byte[] FatSignature =
- {
- 0x46, 0x41, 0x54, 0x31, 0x36, 0x20, 0x20, 0x20
- };
- static readonly byte[] IsoExtension =
- {
- 0x49, 0x53, 0x4F
- };
-
- /// Dumps a CFW PlayStation Portable UMD
- void PlayStationPortable()
- {
- if(!_outputPlugin.SupportedMediaTypes.Contains(MediaType.MemoryStickDuo) &&
- !_outputPlugin.SupportedMediaTypes.Contains(MediaType.MemoryStickProDuo) &&
- !_outputPlugin.SupportedMediaTypes.Contains(MediaType.UMD))
- {
- _dumpLog.WriteLine("Selected output plugin does not support MemoryStick Duo or UMD, cannot dump...");
-
- StoppingErrorMessage?.
- Invoke("Selected output plugin does not support MemoryStick Duo or UMD, cannot dump...");
-
- return;
- }
-
- UpdateStatus?.Invoke("Checking if media is UMD or MemoryStick...");
- _dumpLog.WriteLine("Checking if media is UMD or MemoryStick...");
-
- bool sense = _dev.ModeSense6(out byte[] buffer, out _, false, ScsiModeSensePageControl.Current, 0,
- _dev.Timeout, out _);
-
- if(sense)
- {
- _dumpLog.WriteLine("Could not get MODE SENSE...");
- StoppingErrorMessage?.Invoke("Could not get MODE SENSE...");
-
- return;
- }
-
- Modes.DecodedMode? decoded = Modes.DecodeMode6(buffer, PeripheralDeviceTypes.DirectAccess);
-
- if(!decoded.HasValue)
- {
- _dumpLog.WriteLine("Could not decode MODE SENSE...");
- StoppingErrorMessage?.Invoke("Could not decode MODE SENSE...");
-
- return;
- }
-
- // UMDs are always write protected
- if(!decoded.Value.Header.WriteProtected)
- {
- DumpMs();
-
- return;
- }
-
- sense = _dev.Read12(out buffer, out _, 0, false, true, false, false, 0, 512, 0, 1, false, _dev.Timeout,
- out _);
-
- if(sense)
- {
- _dumpLog.WriteLine("Could not read...");
- StoppingErrorMessage?.Invoke("Could not read...");
-
- return;
- }
-
- byte[] tmp = new byte[8];
-
- Array.Copy(buffer, 0x36, tmp, 0, 8);
-
- // UMDs are stored inside a FAT16 volume
- if(!tmp.SequenceEqual(FatSignature))
- {
- DumpMs();
-
- return;
- }
-
- ushort fatStart = (ushort)((buffer[0x0F] << 8) + buffer[0x0E]);
- ushort sectorsPerFat = (ushort)((buffer[0x17] << 8) + buffer[0x16]);
- ushort rootStart = (ushort)((sectorsPerFat * 2) + fatStart);
-
- UpdateStatus?.Invoke($"Reading root directory in sector {rootStart}...");
- _dumpLog.WriteLine("Reading root directory in sector {0}...", rootStart);
-
- sense = _dev.Read12(out buffer, out _, 0, false, true, false, false, rootStart, 512, 0, 1, false,
- _dev.Timeout, out _);
-
- if(sense)
- {
- StoppingErrorMessage?.Invoke("Could not read...");
- _dumpLog.WriteLine("Could not read...");
-
- return;
- }
-
- tmp = new byte[3];
- Array.Copy(buffer, 0x28, tmp, 0, 3);
-
- if(!tmp.SequenceEqual(IsoExtension))
- {
- DumpMs();
-
- return;
- }
-
- UpdateStatus?.Invoke($"FAT starts at sector {fatStart} and runs for {sectorsPerFat} sectors...");
- _dumpLog.WriteLine("FAT starts at sector {0} and runs for {1} sectors...", fatStart, sectorsPerFat);
-
- UpdateStatus?.Invoke("Reading FAT...");
- _dumpLog.WriteLine("Reading FAT...");
-
- byte[] fat = new byte[sectorsPerFat * 512];
-
- uint position = 0;
-
- while(position < sectorsPerFat)
- {
- uint transfer = 64;
-
- if(transfer + position > sectorsPerFat)
- transfer = sectorsPerFat - position;
-
- sense = _dev.Read12(out buffer, out _, 0, false, true, false, false, position + fatStart, 512, 0,
- transfer, false, _dev.Timeout, out _);
-
- if(sense)
- {
- StoppingErrorMessage?.Invoke("Could not read...");
- _dumpLog.WriteLine("Could not read...");
-
- return;
- }
-
- Array.Copy(buffer, 0, fat, position * 512, transfer * 512);
-
- position += transfer;
- }
-
- UpdateStatus?.Invoke("Traversing FAT...");
- _dumpLog.WriteLine("Traversing FAT...");
-
- ushort previousCluster = BitConverter.ToUInt16(fat, 4);
-
- for(int i = 3; i < fat.Length / 2; i++)
- {
- ushort nextCluster = BitConverter.ToUInt16(fat, i * 2);
-
- if(nextCluster == previousCluster + 1)
- {
- previousCluster = nextCluster;
-
- continue;
- }
-
- if(nextCluster == 0xFFFF)
- break;
-
- DumpMs();
-
- return;
- }
-
- if(_outputPlugin is IWritableOpticalImage)
- DumpUmd();
- else
- StoppingErrorMessage?.Invoke("The specified plugin does not support storing optical disc images.");
- }
-
- void DumpUmd()
- {
- const uint BLOCK_SIZE = 2048;
- const MediaType DSK_TYPE = MediaType.UMD;
- uint blocksToRead = 16;
- double totalDuration = 0;
- double currentSpeed = 0;
- double maxSpeed = double.MinValue;
- double minSpeed = double.MaxValue;
- DateTime start;
- DateTime end;
-
- bool sense = _dev.Read12(out byte[] readBuffer, out _, 0, false, true, false, false, 0, 512, 0, 1, false,
- _dev.Timeout, out _);
-
- if(sense)
- {
- _dumpLog.WriteLine("Could not read...");
- StoppingErrorMessage?.Invoke("Could not read...");
-
- return;
- }
-
- ushort fatStart = (ushort)((readBuffer[0x0F] << 8) + readBuffer[0x0E]);
- ushort sectorsPerFat = (ushort)((readBuffer[0x17] << 8) + readBuffer[0x16]);
- ushort rootStart = (ushort)((sectorsPerFat * 2) + fatStart);
- ushort rootSize = (ushort)((((readBuffer[0x12] << 8) + readBuffer[0x11]) * 32) / 512);
- ushort umdStart = (ushort)(rootStart + rootSize);
-
- UpdateStatus?.Invoke($"Reading root directory in sector {rootStart}...");
- _dumpLog.WriteLine("Reading root directory in sector {0}...", rootStart);
-
- sense = _dev.Read12(out readBuffer, out _, 0, false, true, false, false, rootStart, 512, 0, 1, false,
- _dev.Timeout, out _);
-
- if(sense)
- {
- _dumpLog.WriteLine("Could not read...");
- StoppingErrorMessage?.Invoke("Could not read...");
-
- return;
- }
-
- uint umdSizeInBytes = BitConverter.ToUInt32(readBuffer, 0x3C);
- ulong blocks = umdSizeInBytes / BLOCK_SIZE;
- string mediaPartNumber = Encoding.ASCII.GetString(readBuffer, 0, 11).Trim();
-
- UpdateStatus?.
- Invoke($"Media has {blocks} blocks of {BLOCK_SIZE} bytes/each. (for a total of {blocks * (ulong)BLOCK_SIZE} bytes)");
-
- UpdateStatus?.Invoke($"Device reports {blocks} blocks ({blocks * BLOCK_SIZE} bytes).");
- UpdateStatus?.Invoke($"Device can read {blocksToRead} blocks at a time.");
- UpdateStatus?.Invoke($"Device reports {BLOCK_SIZE} bytes per logical block.");
- UpdateStatus?.Invoke($"Device reports {2048} bytes per physical block.");
- UpdateStatus?.Invoke($"SCSI device type: {_dev.ScsiType}.");
- UpdateStatus?.Invoke($"Media identified as {DSK_TYPE}.");
- UpdateStatus?.Invoke($"Media part number is {mediaPartNumber}.");
- _dumpLog.WriteLine("Device reports {0} blocks ({1} bytes).", blocks, blocks * BLOCK_SIZE);
- _dumpLog.WriteLine("Device can read {0} blocks at a time.", blocksToRead);
- _dumpLog.WriteLine("Device reports {0} bytes per logical block.", BLOCK_SIZE);
- _dumpLog.WriteLine("Device reports {0} bytes per physical block.", 2048);
- _dumpLog.WriteLine("SCSI device type: {0}.", _dev.ScsiType);
- _dumpLog.WriteLine("Media identified as {0}.", DSK_TYPE);
- _dumpLog.WriteLine("Media part number is {0}.", mediaPartNumber);
-
- bool ret;
-
- var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, BLOCK_SIZE, blocksToRead, _private);
- var ibgLog = new IbgLog(_outputPrefix + ".ibg", 0x0010);
- ret = _outputPlugin.Create(_outputPath, DSK_TYPE, _formatOptions, blocks, BLOCK_SIZE);
-
- // Cannot create image
- if(!ret)
- {
- _dumpLog.WriteLine("Error creating output image, not continuing.");
- _dumpLog.WriteLine(_outputPlugin.ErrorMessage);
-
- StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine +
- _outputPlugin.ErrorMessage);
-
- return;
- }
-
- start = DateTime.UtcNow;
- double imageWriteDuration = 0;
-
- (_outputPlugin as IWritableOpticalImage).SetTracks(new List