mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Refactor sector writing methods to include SectorStatus parameter and update related logic
This commit is contained in:
@@ -65,28 +65,32 @@ public interface IWritableImage : IMediaImage, IBaseWritableImage
|
||||
/// <summary>Writes a sector to the image</summary>
|
||||
/// <param name="data">Sector data</param>
|
||||
/// <param name="sectorAddress">Sector address</param>
|
||||
/// <param name="sectorStatus"></param>
|
||||
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
|
||||
bool WriteSector(byte[] data, ulong sectorAddress);
|
||||
bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus);
|
||||
|
||||
/// <summary>Writes a sector to the image with main channel tags attached</summary>
|
||||
/// <param name="data">Sector data with its main channel tags attached</param>
|
||||
/// <param name="sectorAddress">Sector address</param>
|
||||
/// <param name="sectorStatus"></param>
|
||||
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
|
||||
bool WriteSectorLong(byte[] data, ulong sectorAddress);
|
||||
bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus);
|
||||
|
||||
/// <summary>Writes several sectors to the image</summary>
|
||||
/// <param name="data">Sectors data</param>
|
||||
/// <param name="sectorAddress">Sector starting address</param>
|
||||
/// <param name="length">How many sectors to write</param>
|
||||
/// <param name="sectorStatus"></param>
|
||||
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
|
||||
bool WriteSectors(byte[] data, ulong sectorAddress, uint length);
|
||||
bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus);
|
||||
|
||||
/// <summary>Writes several sectors to the image</summary>
|
||||
/// <param name="data">Sector data with their main channel tags attached</param>
|
||||
/// <param name="sectorAddress">Sector starting address</param>
|
||||
/// <param name="length">How many sectors to write</param>
|
||||
/// <param name="sectorStatus"></param>
|
||||
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
|
||||
bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length);
|
||||
bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus);
|
||||
|
||||
/// <summary>Writes parallel or subchannel sector tag for several sector</summary>
|
||||
/// <param name="data">Tag data to write</param>
|
||||
|
||||
@@ -197,7 +197,7 @@ public partial class Dump
|
||||
IbgLog ibgLog;
|
||||
double duration;
|
||||
|
||||
bool ret = true;
|
||||
var ret = true;
|
||||
|
||||
if(_dev.IsUsb &&
|
||||
_dev.UsbDescriptors != null &&
|
||||
@@ -294,7 +294,7 @@ public partial class Dump
|
||||
_mediaGraph?.PaintSectorsBad(_resume.BadBlocks);
|
||||
}
|
||||
|
||||
bool newTrim = false;
|
||||
var newTrim = false;
|
||||
|
||||
_dumpStopwatch.Restart();
|
||||
_speedStopwatch.Reset();
|
||||
@@ -336,7 +336,13 @@ public partial class Dump
|
||||
{
|
||||
mhddLog.Write(i, duration, blocksToRead);
|
||||
ibgLog.Write(i, currentSpeed * 1024);
|
||||
outputFormat.WriteSectors(cmdBuf, i, blocksToRead);
|
||||
|
||||
outputFormat.WriteSectors(cmdBuf,
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
extents.Add(i, blocksToRead, true);
|
||||
_mediaGraph?.PaintSectorsGood(i, blocksToRead);
|
||||
@@ -350,7 +356,13 @@ public partial class Dump
|
||||
mhddLog.Write(i, duration < 500 ? 65535 : duration, _skip);
|
||||
|
||||
ibgLog.Write(i, 0);
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip], i, _skip);
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
UpdateProgress?.Invoke(Localization.Core.Skipping_0_blocks_from_errored_block_1,
|
||||
@@ -436,7 +448,7 @@ public partial class Dump
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(cmdBuf, badSector);
|
||||
outputFormat.WriteSector(cmdBuf, badSector, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
}
|
||||
|
||||
@@ -453,8 +465,8 @@ public partial class Dump
|
||||
|
||||
if(_resume.BadBlocks.Count > 0 && !_aborted && _retryPasses > 0)
|
||||
{
|
||||
int pass = 1;
|
||||
bool forward = true;
|
||||
var pass = 1;
|
||||
var forward = true;
|
||||
|
||||
InitProgress?.Invoke();
|
||||
repeatRetryLba:
|
||||
@@ -504,7 +516,7 @@ public partial class Dump
|
||||
{
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(cmdBuf, badSector);
|
||||
outputFormat.WriteSector(cmdBuf, badSector, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core
|
||||
@@ -512,7 +524,7 @@ public partial class Dump
|
||||
badSector,
|
||||
pass));
|
||||
}
|
||||
else if(_persistent) outputFormat.WriteSector(cmdBuf, badSector);
|
||||
else if(_persistent) outputFormat.WriteSector(cmdBuf, badSector, SectorStatus.Errored);
|
||||
}
|
||||
|
||||
if(pass < _retryPasses && !_aborted && _resume.BadBlocks.Count > 0)
|
||||
@@ -613,7 +625,9 @@ public partial class Dump
|
||||
mhddLog.Write(currentBlock, duration);
|
||||
ibgLog.Write(currentBlock, currentSpeed * 1024);
|
||||
|
||||
outputFormat.WriteSector(cmdBuf, (ulong)((cy * heads + hd) * sectors + (sc - 1)));
|
||||
outputFormat.WriteSector(cmdBuf,
|
||||
(ulong)((cy * heads + hd) * sectors + (sc - 1)),
|
||||
SectorStatus.Dumped);
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
extents.Add(currentBlock);
|
||||
@@ -627,7 +641,8 @@ public partial class Dump
|
||||
ibgLog.Write(currentBlock, 0);
|
||||
|
||||
outputFormat.WriteSector(new byte[blockSize],
|
||||
(ulong)((cy * heads + hd) * sectors + (sc - 1)));
|
||||
(ulong)((cy * heads + hd) * sectors + (sc - 1)),
|
||||
SectorStatus.Errored);
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Aaru.CommonTypes.AaruMetadata;
|
||||
using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Extents;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.Core.Logging;
|
||||
@@ -60,7 +61,7 @@ partial class Dump
|
||||
|
||||
byte[] syncMark = [0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00];
|
||||
|
||||
byte[] testMark = new byte[12];
|
||||
var testMark = new byte[12];
|
||||
Array.Copy(sector, 0, testMark, 0, 12);
|
||||
|
||||
return syncMark.SequenceEqual(testMark) && (sector[0xF] == 0 || sector[0xF] == 1 || sector[0xF] == 2);
|
||||
@@ -79,9 +80,9 @@ partial class Dump
|
||||
|
||||
byte[] syncMark = [0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00];
|
||||
|
||||
byte[] testMark = new byte[12];
|
||||
var testMark = new byte[12];
|
||||
|
||||
for(int i = 0; i <= 2336; i++)
|
||||
for(var i = 0; i <= 2336; i++)
|
||||
{
|
||||
Array.Copy(sector, i, testMark, 0, 12);
|
||||
|
||||
@@ -179,7 +180,7 @@ partial class Dump
|
||||
break;
|
||||
}
|
||||
|
||||
uint firstSectorToRead = (uint)i;
|
||||
var firstSectorToRead = (uint)i;
|
||||
|
||||
blocksToRead = _maximumReadable;
|
||||
|
||||
@@ -288,8 +289,8 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
byte[] data = new byte[sectorSize];
|
||||
byte[] sub = new byte[subSize];
|
||||
var data = new byte[sectorSize];
|
||||
var sub = new byte[subSize];
|
||||
|
||||
Array.Copy(cmdBuf, 0, data, 0, sectorSize);
|
||||
|
||||
@@ -297,7 +298,10 @@ partial class Dump
|
||||
|
||||
if(cdiReadyReadAsAudio) data = Sector.Scramble(data);
|
||||
|
||||
outputOptical.WriteSectorsLong(data, i + r, 1);
|
||||
outputOptical.WriteSectorsLong(data,
|
||||
i + r,
|
||||
1,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, 1).ToArray());
|
||||
|
||||
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
|
||||
desiredSubchannel,
|
||||
@@ -329,7 +333,7 @@ partial class Dump
|
||||
}
|
||||
}
|
||||
else
|
||||
outputOptical.WriteSectorsLong(cmdBuf, i + r, 1);
|
||||
outputOptical.WriteSectorsLong(cmdBuf, i + r, 1, [SectorStatus.Dumped]);
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
@@ -386,11 +390,11 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
byte[] data = new byte[sectorSize * blocksToRead];
|
||||
byte[] sub = new byte[subSize * blocksToRead];
|
||||
byte[] tmpData = new byte[sectorSize];
|
||||
var data = new byte[sectorSize * blocksToRead];
|
||||
var sub = new byte[subSize * blocksToRead];
|
||||
var tmpData = new byte[sectorSize];
|
||||
|
||||
for(int b = 0; b < blocksToRead; b++)
|
||||
for(var b = 0; b < blocksToRead; b++)
|
||||
{
|
||||
if(cdiReadyReadAsAudio)
|
||||
{
|
||||
@@ -404,7 +408,10 @@ partial class Dump
|
||||
Array.Copy(cmdBuf, (int)(sectorSize + b * blockSize), sub, subSize * b, subSize);
|
||||
}
|
||||
|
||||
outputOptical.WriteSectorsLong(data, i, blocksToRead);
|
||||
outputOptical.WriteSectorsLong(data,
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
|
||||
desiredSubchannel,
|
||||
@@ -447,20 +454,28 @@ partial class Dump
|
||||
{
|
||||
if(cdiReadyReadAsAudio)
|
||||
{
|
||||
byte[] tmpData = new byte[sectorSize];
|
||||
byte[] data = new byte[sectorSize * blocksToRead];
|
||||
var tmpData = new byte[sectorSize];
|
||||
var data = new byte[sectorSize * blocksToRead];
|
||||
|
||||
for(int b = 0; b < blocksToRead; b++)
|
||||
for(var b = 0; b < blocksToRead; b++)
|
||||
{
|
||||
Array.Copy(cmdBuf, (int)(b * sectorSize), tmpData, 0, sectorSize);
|
||||
tmpData = Sector.Scramble(tmpData);
|
||||
Array.Copy(tmpData, 0, data, sectorSize * b, sectorSize);
|
||||
}
|
||||
|
||||
outputOptical.WriteSectorsLong(data, i, blocksToRead);
|
||||
outputOptical.WriteSectorsLong(data,
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
}
|
||||
else
|
||||
outputOptical.WriteSectorsLong(cmdBuf, i, blocksToRead);
|
||||
outputOptical.WriteSectorsLong(cmdBuf,
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
}
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
@@ -103,7 +103,7 @@ partial class Dump
|
||||
{
|
||||
ulong sectorSpeedStart = 0; // Used to calculate correct speed
|
||||
uint blocksToRead; // How many sectors to read at once
|
||||
bool sense = true; // Sense indicator
|
||||
var sense = true; // Sense indicator
|
||||
byte[] cmdBuf = null; // Data buffer
|
||||
ReadOnlySpan<byte> senseBuf = null; // Sense buffer
|
||||
double cmdDuration = 0; // Command execution time
|
||||
@@ -123,9 +123,9 @@ partial class Dump
|
||||
InitProgress?.Invoke();
|
||||
|
||||
int currentReadSpeed = _speed;
|
||||
bool crossingLeadOut = false;
|
||||
bool failedCrossingLeadOut = false;
|
||||
bool skippingLead = false;
|
||||
var crossingLeadOut = false;
|
||||
var failedCrossingLeadOut = false;
|
||||
var skippingLead = false;
|
||||
|
||||
for(ulong i = _resume.NextBlock; (long)i <= lastSector; i += blocksToRead)
|
||||
{
|
||||
@@ -145,7 +145,7 @@ partial class Dump
|
||||
|
||||
if((long)i > lastSector) break;
|
||||
|
||||
uint firstSectorToRead = (uint)i;
|
||||
var firstSectorToRead = (uint)i;
|
||||
|
||||
Track track = tracks.OrderBy(t => t.StartSector).LastOrDefault(t => i >= t.StartSector);
|
||||
|
||||
@@ -310,10 +310,10 @@ partial class Dump
|
||||
// Try to workaround firmware
|
||||
if(decSense?.ASC == 0x64)
|
||||
{
|
||||
bool goBackTrackTypeChange = false;
|
||||
var goBackTrackTypeChange = false;
|
||||
|
||||
// Go one for one as the drive does not tell us which one failed
|
||||
for(int bi = 0; bi < blocksToRead; bi++)
|
||||
for(var bi = 0; bi < blocksToRead; bi++)
|
||||
{
|
||||
_speedStopwatch.Start();
|
||||
|
||||
@@ -584,7 +584,7 @@ partial class Dump
|
||||
|
||||
if(_supportsPlextorD8)
|
||||
{
|
||||
int adjustment = 0;
|
||||
var adjustment = 0;
|
||||
|
||||
if(offsetBytes < 0) adjustment = -sectorsForOffset;
|
||||
|
||||
@@ -604,7 +604,7 @@ partial class Dump
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
uint sectorsForFix = (uint)(1 + sectorsForOffset);
|
||||
var sectorsForFix = (uint)(1 + sectorsForOffset);
|
||||
|
||||
FixOffsetData(offsetBytes,
|
||||
sectorSize,
|
||||
@@ -630,7 +630,7 @@ partial class Dump
|
||||
{
|
||||
case 0:
|
||||
|
||||
for(int c = 16; c < 2352; c++)
|
||||
for(var c = 16; c < 2352; c++)
|
||||
{
|
||||
if(cmdBuf[c] == 0x00) continue;
|
||||
|
||||
@@ -768,28 +768,36 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
byte[] data = new byte[sectorSize];
|
||||
byte[] sub = new byte[subSize];
|
||||
var data = new byte[sectorSize];
|
||||
var sub = new byte[subSize];
|
||||
|
||||
Array.Copy(cmdBuf, 0, data, 0, sectorSize);
|
||||
|
||||
Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);
|
||||
|
||||
if(supportsLongSectors)
|
||||
outputFormat.WriteSectorsLong(data, i + r, 1);
|
||||
outputFormat.WriteSectorsLong(data,
|
||||
i + r,
|
||||
1,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
else
|
||||
{
|
||||
var cooked = new MemoryStream();
|
||||
byte[] sector = new byte[sectorSize];
|
||||
var sector = new byte[sectorSize];
|
||||
|
||||
for(int b = 0; b < blocksToRead; b++)
|
||||
for(var b = 0; b < blocksToRead; b++)
|
||||
{
|
||||
Array.Copy(cmdBuf, (int)(0 + b * blockSize), sector, 0, sectorSize);
|
||||
byte[] cookedSector = Sector.GetUserData(sector);
|
||||
cooked.Write(cookedSector, 0, cookedSector.Length);
|
||||
}
|
||||
|
||||
outputFormat.WriteSectors(cooked.ToArray(), i, blocksToRead);
|
||||
outputFormat.WriteSectors(cooked.ToArray(),
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
}
|
||||
|
||||
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
|
||||
@@ -836,20 +844,24 @@ partial class Dump
|
||||
else
|
||||
{
|
||||
if(supportsLongSectors)
|
||||
outputFormat.WriteSectorsLong(cmdBuf, i + r, 1);
|
||||
outputFormat.WriteSectorsLong(cmdBuf, i + r, 1, [SectorStatus.Dumped]);
|
||||
else
|
||||
{
|
||||
var cooked = new MemoryStream();
|
||||
byte[] sector = new byte[sectorSize];
|
||||
var sector = new byte[sectorSize];
|
||||
|
||||
for(int b = 0; b < blocksToRead; b++)
|
||||
for(var b = 0; b < blocksToRead; b++)
|
||||
{
|
||||
Array.Copy(cmdBuf, (int)(b * sectorSize), sector, 0, sectorSize);
|
||||
byte[] cookedSector = Sector.GetUserData(sector);
|
||||
cooked.Write(cookedSector, 0, cookedSector.Length);
|
||||
}
|
||||
|
||||
outputFormat.WriteSectors(cooked.ToArray(), i, blocksToRead);
|
||||
outputFormat.WriteSectors(cooked.ToArray(),
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -866,7 +878,7 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
outputFormat.WriteSectorsLong(new byte[sectorSize], i + r, 1);
|
||||
outputFormat.WriteSectorsLong(new byte[sectorSize], i + r, 1, [SectorStatus.Errored]);
|
||||
|
||||
if(desiredSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
@@ -879,13 +891,16 @@ partial class Dump
|
||||
else
|
||||
{
|
||||
if(supportsLongSectors)
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize], i + r, 1);
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize], i + r, 1, [SectorStatus.Errored]);
|
||||
else
|
||||
{
|
||||
if(cmdBuf.Length % sectorSize == 0)
|
||||
outputFormat.WriteSectors(new byte[2048], i + r, 1);
|
||||
outputFormat.WriteSectors(new byte[2048], i + r, 1, [SectorStatus.Errored]);
|
||||
else
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize], i + r, 1);
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize],
|
||||
i + r,
|
||||
1,
|
||||
[SectorStatus.Errored]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -926,7 +941,7 @@ partial class Dump
|
||||
{
|
||||
if(crossingLeadOut && failedCrossingLeadOut)
|
||||
{
|
||||
byte[] tmp = new byte[cmdBuf.Length + blockSize];
|
||||
var tmp = new byte[cmdBuf.Length + blockSize];
|
||||
Array.Copy(cmdBuf, 0, tmp, 0, cmdBuf.Length);
|
||||
}
|
||||
|
||||
@@ -951,10 +966,10 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
byte[] data = new byte[sectorSize * blocksToRead];
|
||||
byte[] sub = new byte[subSize * blocksToRead];
|
||||
var data = new byte[sectorSize * blocksToRead];
|
||||
var sub = new byte[subSize * blocksToRead];
|
||||
|
||||
for(int b = 0; b < blocksToRead; b++)
|
||||
for(var b = 0; b < blocksToRead; b++)
|
||||
{
|
||||
Array.Copy(cmdBuf, (int)(0 + b * blockSize), data, sectorSize * b, sectorSize);
|
||||
|
||||
@@ -962,20 +977,27 @@ partial class Dump
|
||||
}
|
||||
|
||||
if(supportsLongSectors)
|
||||
outputFormat.WriteSectorsLong(data, i, blocksToRead);
|
||||
outputFormat.WriteSectorsLong(data,
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
else
|
||||
{
|
||||
var cooked = new MemoryStream();
|
||||
byte[] sector = new byte[sectorSize];
|
||||
var sector = new byte[sectorSize];
|
||||
|
||||
for(int b = 0; b < blocksToRead; b++)
|
||||
for(var b = 0; b < blocksToRead; b++)
|
||||
{
|
||||
Array.Copy(cmdBuf, (int)(0 + b * blockSize), sector, 0, sectorSize);
|
||||
byte[] cookedSector = Sector.GetUserData(sector);
|
||||
cooked.Write(cookedSector, 0, cookedSector.Length);
|
||||
}
|
||||
|
||||
outputFormat.WriteSectors(cooked.ToArray(), i, blocksToRead);
|
||||
outputFormat.WriteSectors(cooked.ToArray(),
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
}
|
||||
|
||||
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
|
||||
@@ -1021,20 +1043,27 @@ partial class Dump
|
||||
else
|
||||
{
|
||||
if(supportsLongSectors)
|
||||
outputFormat.WriteSectorsLong(cmdBuf, i, blocksToRead);
|
||||
outputFormat.WriteSectorsLong(cmdBuf,
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
|
||||
.ToArray());
|
||||
else
|
||||
{
|
||||
var cooked = new MemoryStream();
|
||||
byte[] sector = new byte[sectorSize];
|
||||
var sector = new byte[sectorSize];
|
||||
|
||||
for(int b = 0; b < blocksToRead; b++)
|
||||
for(var b = 0; b < blocksToRead; b++)
|
||||
{
|
||||
Array.Copy(cmdBuf, (int)(b * sectorSize), sector, 0, sectorSize);
|
||||
byte[] cookedSector = Sector.GetUserData(sector);
|
||||
cooked.Write(cookedSector, 0, cookedSector.Length);
|
||||
}
|
||||
|
||||
outputFormat.WriteSectors(cooked.ToArray(), i, blocksToRead);
|
||||
outputFormat.WriteSectors(cooked.ToArray(),
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1066,7 +1095,10 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
outputFormat.WriteSectorsLong(new byte[sectorSize * _skip], i, _skip);
|
||||
outputFormat.WriteSectorsLong(new byte[sectorSize * _skip],
|
||||
i,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
if(desiredSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
@@ -1079,13 +1111,23 @@ partial class Dump
|
||||
else
|
||||
{
|
||||
if(supportsLongSectors)
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize * _skip], i, _skip);
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize * _skip],
|
||||
i,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
else
|
||||
{
|
||||
if(cmdBuf.Length % sectorSize == 0)
|
||||
outputFormat.WriteSectors(new byte[2048 * _skip], i, _skip);
|
||||
outputFormat.WriteSectors(new byte[2048 * _skip],
|
||||
i,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
else
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize * _skip], i, _skip);
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize * _skip],
|
||||
i,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip)
|
||||
.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Aaru.Checksums;
|
||||
using Aaru.CommonTypes.AaruMetadata;
|
||||
using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Extents;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.CommonTypes.Structs.Devices.SCSI;
|
||||
@@ -80,7 +81,7 @@ partial class Dump
|
||||
ref string mcn, HashSet<int> subchannelExtents,
|
||||
Dictionary<byte, int> smallestPregapLbaPerTrack, bool supportsLongSectors)
|
||||
{
|
||||
bool sense = true; // Sense indicator
|
||||
var sense = true; // Sense indicator
|
||||
byte[] cmdBuf = null; // Data buffer
|
||||
double cmdDuration; // Command execution time
|
||||
const uint sectorSize = 2352; // Full sector size
|
||||
@@ -98,9 +99,9 @@ partial class Dump
|
||||
|
||||
if(_resume.BadBlocks.Count <= 0 || _aborted || _retryPasses <= 0) return;
|
||||
|
||||
int pass = 1;
|
||||
bool forward = true;
|
||||
bool runningPersistent = false;
|
||||
var pass = 1;
|
||||
var forward = true;
|
||||
var runningPersistent = false;
|
||||
|
||||
Modes.ModePage? currentModePage = null;
|
||||
byte[] md6;
|
||||
@@ -217,7 +218,7 @@ partial class Dump
|
||||
ulong[] tmpArray = _resume.BadBlocks.ToArray();
|
||||
List<ulong> sectorsNotEvenPartial = [];
|
||||
|
||||
for(int i = 0; i < tmpArray.Length; i++)
|
||||
for(var i = 0; i < tmpArray.Length; i++)
|
||||
{
|
||||
ulong badSector = tmpArray[i];
|
||||
|
||||
@@ -255,7 +256,7 @@ partial class Dump
|
||||
Track track = tracks.OrderBy(t => t.StartSector).LastOrDefault(t => badSector >= t.StartSector);
|
||||
|
||||
byte sectorsToReRead = 1;
|
||||
uint badSectorToReRead = (uint)badSector;
|
||||
var badSectorToReRead = (uint)badSector;
|
||||
|
||||
if(_fixOffset && audioExtents.Contains(badSector) && offsetBytes != 0)
|
||||
{
|
||||
@@ -421,7 +422,7 @@ partial class Dump
|
||||
{
|
||||
case 0:
|
||||
|
||||
for(int c = 16; c < 2352; c++)
|
||||
for(var c = 16; c < 2352; c++)
|
||||
{
|
||||
if(cmdBuf[c] == 0x00) continue;
|
||||
|
||||
@@ -465,8 +466,9 @@ partial class Dump
|
||||
|
||||
// MEDIUM ERROR, retry with ignore error below
|
||||
if(decSense is { ASC: 0x11 })
|
||||
if(!sectorsNotEvenPartial.Contains(badSector))
|
||||
sectorsNotEvenPartial.Add(badSector);
|
||||
{
|
||||
if(!sectorsNotEvenPartial.Contains(badSector)) sectorsNotEvenPartial.Add(badSector);
|
||||
}
|
||||
}
|
||||
|
||||
// Because one block has been partially used to fix the offset
|
||||
@@ -502,15 +504,15 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
byte[] data = new byte[sectorSize];
|
||||
byte[] sub = new byte[subSize];
|
||||
var data = new byte[sectorSize];
|
||||
var sub = new byte[subSize];
|
||||
Array.Copy(cmdBuf, 0, data, 0, sectorSize);
|
||||
Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);
|
||||
|
||||
if(supportsLongSectors)
|
||||
outputOptical.WriteSectorLong(data, badSector);
|
||||
outputOptical.WriteSectorLong(data, badSector, SectorStatus.Dumped);
|
||||
else
|
||||
outputOptical.WriteSector(Sector.GetUserData(data), badSector);
|
||||
outputOptical.WriteSector(Sector.GetUserData(data), badSector, SectorStatus.Dumped);
|
||||
|
||||
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
|
||||
desiredSubchannel,
|
||||
@@ -541,9 +543,9 @@ partial class Dump
|
||||
else
|
||||
{
|
||||
if(supportsLongSectors)
|
||||
outputOptical.WriteSectorLong(cmdBuf, badSector);
|
||||
outputOptical.WriteSectorLong(cmdBuf, badSector, SectorStatus.Dumped);
|
||||
else
|
||||
outputOptical.WriteSector(Sector.GetUserData(cmdBuf), badSector);
|
||||
outputOptical.WriteSector(Sector.GetUserData(cmdBuf), badSector, SectorStatus.Dumped);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -605,7 +607,7 @@ partial class Dump
|
||||
|
||||
InitProgress?.Invoke();
|
||||
|
||||
for(int i = 0; i < sectorsNotEvenPartial.Count; i++)
|
||||
for(var i = 0; i < sectorsNotEvenPartial.Count; i++)
|
||||
{
|
||||
ulong badSector = sectorsNotEvenPartial[i];
|
||||
|
||||
@@ -655,15 +657,15 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
byte[] data = new byte[sectorSize];
|
||||
byte[] sub = new byte[subSize];
|
||||
var data = new byte[sectorSize];
|
||||
var sub = new byte[subSize];
|
||||
Array.Copy(cmdBuf, 0, data, 0, sectorSize);
|
||||
Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);
|
||||
|
||||
if(supportsLongSectors)
|
||||
outputOptical.WriteSectorLong(data, badSector);
|
||||
outputOptical.WriteSectorLong(data, badSector, SectorStatus.Errored);
|
||||
else
|
||||
outputOptical.WriteSector(Sector.GetUserData(data), badSector);
|
||||
outputOptical.WriteSector(Sector.GetUserData(data), badSector, SectorStatus.Errored);
|
||||
|
||||
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
|
||||
desiredSubchannel,
|
||||
@@ -694,9 +696,9 @@ partial class Dump
|
||||
else
|
||||
{
|
||||
if(supportsLongSectors)
|
||||
outputOptical.WriteSectorLong(cmdBuf, badSector);
|
||||
outputOptical.WriteSectorLong(cmdBuf, badSector, SectorStatus.Errored);
|
||||
else
|
||||
outputOptical.WriteSector(Sector.GetUserData(cmdBuf), badSector);
|
||||
outputOptical.WriteSector(Sector.GetUserData(cmdBuf), badSector, SectorStatus.Errored);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,7 +743,7 @@ partial class Dump
|
||||
Dictionary<byte, string> isrcs, ref string mcn, HashSet<int> subchannelExtents,
|
||||
Dictionary<byte, int> smallestPregapLbaPerTrack)
|
||||
{
|
||||
bool sense = true; // Sense indicator
|
||||
var sense = true; // Sense indicator
|
||||
byte[] cmdBuf = null; // Data buffer
|
||||
double cmdDuration; // Command execution time
|
||||
ReadOnlySpan<byte> senseBuf = null; // Sense buffer
|
||||
@@ -760,8 +762,8 @@ partial class Dump
|
||||
|
||||
if(_aborted) return;
|
||||
|
||||
int pass = 1;
|
||||
bool forward = true;
|
||||
var pass = 1;
|
||||
var forward = true;
|
||||
|
||||
InitProgress?.Invoke();
|
||||
|
||||
@@ -777,7 +779,7 @@ partial class Dump
|
||||
|
||||
foreach(int bs in tmpArray)
|
||||
{
|
||||
uint badSector = (uint)bs;
|
||||
var badSector = (uint)bs;
|
||||
|
||||
Track track = tracks.OrderBy(t => t.StartSector).LastOrDefault(t => badSector >= t.StartSector);
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ partial class Dump
|
||||
{
|
||||
byte[] cmdBuf = null; // Data buffer
|
||||
const uint sectorSize = 2352; // Full sector size
|
||||
bool sense = true; // Sense indicator
|
||||
var sense = true; // Sense indicator
|
||||
ReadOnlySpan<byte> senseBuf = null;
|
||||
var outputOptical = _outputPlugin as IWritableOpticalImage;
|
||||
|
||||
@@ -205,17 +205,21 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
byte[] data = new byte[sectorSize * _maximumReadable];
|
||||
byte[] sub = new byte[subSize * _maximumReadable];
|
||||
var data = new byte[sectorSize * _maximumReadable];
|
||||
var sub = new byte[subSize * _maximumReadable];
|
||||
|
||||
for(int b = 0; b < _maximumReadable; b++)
|
||||
for(var b = 0; b < _maximumReadable; b++)
|
||||
{
|
||||
Array.Copy(cmdBuf, (int)(0 + b * blockSize), data, sectorSize * b, sectorSize);
|
||||
|
||||
Array.Copy(cmdBuf, (int)(sectorSize + b * blockSize), sub, subSize * b, subSize);
|
||||
}
|
||||
|
||||
outputOptical.WriteSectorsLong(data, i, _maximumReadable);
|
||||
outputOptical.WriteSectorsLong(data,
|
||||
i,
|
||||
_maximumReadable,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)_maximumReadable)
|
||||
.ToArray());
|
||||
|
||||
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
|
||||
desiredSubchannel,
|
||||
@@ -247,7 +251,11 @@ partial class Dump
|
||||
}
|
||||
}
|
||||
else
|
||||
outputOptical.WriteSectors(cmdBuf, i, _maximumReadable);
|
||||
outputOptical.WriteSectors(cmdBuf,
|
||||
i,
|
||||
_maximumReadable,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)_maximumReadable)
|
||||
.ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
}
|
||||
@@ -263,7 +271,7 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
outputOptical.WriteSectorsLong(new byte[sectorSize * _skip], i, 1);
|
||||
outputOptical.WriteSectorsLong(new byte[sectorSize * _skip], i, 1, new SectorStatus[1]);
|
||||
|
||||
outputOptical.WriteSectorsTag(new byte[subSize * _skip],
|
||||
i,
|
||||
@@ -271,7 +279,7 @@ partial class Dump
|
||||
SectorTagType.CdSectorSubchannel);
|
||||
}
|
||||
else
|
||||
outputOptical.WriteSectors(new byte[blockSize * _skip], i, 1);
|
||||
outputOptical.WriteSectors(new byte[blockSize * _skip], i, 1, new SectorStatus[1]);
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
@@ -331,7 +339,7 @@ partial class Dump
|
||||
{
|
||||
byte[] cmdBuf = null; // Data buffer
|
||||
const uint sectorSize = 2352; // Full sector size
|
||||
bool sense = true; // Sense indicator
|
||||
var sense = true; // Sense indicator
|
||||
ReadOnlySpan<byte> senseBuf = null;
|
||||
var outputOptical = _outputPlugin as IWritableOpticalImage;
|
||||
|
||||
@@ -444,17 +452,21 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
byte[] data = new byte[sectorSize * _maximumReadable];
|
||||
byte[] sub = new byte[subSize * _maximumReadable];
|
||||
var data = new byte[sectorSize * _maximumReadable];
|
||||
var sub = new byte[subSize * _maximumReadable];
|
||||
|
||||
for(int b = 0; b < _maximumReadable; b++)
|
||||
for(var b = 0; b < _maximumReadable; b++)
|
||||
{
|
||||
Array.Copy(cmdBuf, (int)(0 + b * blockSize), data, sectorSize * b, sectorSize);
|
||||
|
||||
Array.Copy(cmdBuf, (int)(sectorSize + b * blockSize), sub, subSize * b, subSize);
|
||||
}
|
||||
|
||||
outputOptical.WriteSectorsLong(data, i, _maximumReadable);
|
||||
outputOptical.WriteSectorsLong(data,
|
||||
i,
|
||||
_maximumReadable,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)_maximumReadable)
|
||||
.ToArray());
|
||||
|
||||
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
|
||||
desiredSubchannel,
|
||||
@@ -486,7 +498,11 @@ partial class Dump
|
||||
}
|
||||
}
|
||||
else
|
||||
outputOptical.WriteSectors(cmdBuf, i, _maximumReadable);
|
||||
outputOptical.WriteSectors(cmdBuf,
|
||||
i,
|
||||
_maximumReadable,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)_maximumReadable)
|
||||
.ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
}
|
||||
@@ -502,7 +518,7 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
outputOptical.WriteSectorsLong(new byte[sectorSize * _skip], i, 1);
|
||||
outputOptical.WriteSectorsLong(new byte[sectorSize * _skip], i, 1, new SectorStatus[1]);
|
||||
|
||||
if(desiredSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
@@ -513,7 +529,7 @@ partial class Dump
|
||||
}
|
||||
}
|
||||
else
|
||||
outputOptical.WriteSectors(new byte[blockSize * _skip], i, 1);
|
||||
outputOptical.WriteSectors(new byte[blockSize * _skip], i, 1, new SectorStatus[1]);
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ partial class Dump
|
||||
|
||||
if(track is null) continue;
|
||||
|
||||
byte[] sector = new byte[2352];
|
||||
var sector = new byte[2352];
|
||||
|
||||
switch(track.Type)
|
||||
{
|
||||
@@ -102,9 +102,9 @@ partial class Dump
|
||||
}
|
||||
|
||||
if(supportsLongSectors)
|
||||
outputOptical.WriteSectorLong(sector, s);
|
||||
outputOptical.WriteSectorLong(sector, s, SectorStatus.Dumped);
|
||||
else
|
||||
outputOptical.WriteSector(Sector.GetUserData(sector), s);
|
||||
outputOptical.WriteSector(Sector.GetUserData(sector), s, SectorStatus.Dumped);
|
||||
|
||||
_resume.BadBlocks.Remove(s);
|
||||
extents.Add(s);
|
||||
|
||||
@@ -39,6 +39,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Aaru.Checksums;
|
||||
using Aaru.CommonTypes.AaruMetadata;
|
||||
using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Extents;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.Core.Logging;
|
||||
@@ -84,7 +85,7 @@ partial class Dump
|
||||
Dictionary<byte, string> isrcs, ref string mcn, HashSet<int> subchannelExtents,
|
||||
Dictionary<byte, int> smallestPregapLbaPerTrack)
|
||||
{
|
||||
bool sense = true; // Sense indicator
|
||||
var sense = true; // Sense indicator
|
||||
byte[] cmdBuf = null; // Data buffer
|
||||
double cmdDuration = 0; // Command execution time
|
||||
const uint sectorSize = 2352; // Full sector size
|
||||
@@ -109,7 +110,7 @@ partial class Dump
|
||||
trimStart:
|
||||
ulong[] tmpArray = _resume.BadBlocks.ToArray();
|
||||
|
||||
for(int b = 0; b < tmpArray.Length; b++)
|
||||
for(var b = 0; b < tmpArray.Length; b++)
|
||||
{
|
||||
ulong badSector = tmpArray[b];
|
||||
|
||||
@@ -126,7 +127,7 @@ partial class Dump
|
||||
Track track = tracks.OrderBy(t => t.StartSector).LastOrDefault(t => badSector >= t.StartSector);
|
||||
|
||||
byte sectorsToTrim = 1;
|
||||
uint badSectorToRead = (uint)badSector;
|
||||
var badSectorToRead = (uint)badSector;
|
||||
|
||||
if(_fixOffset && audioExtents.Contains(badSector) && offsetBytes != 0)
|
||||
{
|
||||
@@ -290,7 +291,7 @@ partial class Dump
|
||||
{
|
||||
case 0:
|
||||
|
||||
for(int c = 16; c < 2352; c++)
|
||||
for(var c = 16; c < 2352; c++)
|
||||
{
|
||||
if(cmdBuf[c] == 0x00) continue;
|
||||
|
||||
@@ -417,15 +418,15 @@ partial class Dump
|
||||
|
||||
if(supportedSubchannel != MmcSubchannel.None)
|
||||
{
|
||||
byte[] data = new byte[sectorSize];
|
||||
byte[] sub = new byte[subSize];
|
||||
var data = new byte[sectorSize];
|
||||
var sub = new byte[subSize];
|
||||
Array.Copy(cmdBuf, 0, data, 0, sectorSize);
|
||||
Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);
|
||||
|
||||
if(supportsLongSectors)
|
||||
outputOptical.WriteSectorLong(data, badSector);
|
||||
outputOptical.WriteSectorLong(data, badSector, SectorStatus.Dumped);
|
||||
else
|
||||
outputOptical.WriteSector(Sector.GetUserData(data), badSector);
|
||||
outputOptical.WriteSector(Sector.GetUserData(data), badSector, SectorStatus.Dumped);
|
||||
|
||||
ulong trkStartBefore = track.StartSector;
|
||||
|
||||
@@ -467,9 +468,9 @@ partial class Dump
|
||||
}
|
||||
|
||||
if(supportsLongSectors)
|
||||
outputOptical.WriteSectorLong(cmdBuf, badSector);
|
||||
outputOptical.WriteSectorLong(cmdBuf, badSector, SectorStatus.Dumped);
|
||||
else
|
||||
outputOptical.WriteSector(Sector.GetUserData(cmdBuf), badSector);
|
||||
outputOptical.WriteSector(Sector.GetUserData(cmdBuf), badSector, SectorStatus.Dumped);
|
||||
}
|
||||
|
||||
_trimStopwatch.Stop();
|
||||
|
||||
@@ -230,7 +230,7 @@ partial class Dump
|
||||
|
||||
if(decMode?.Pages != null)
|
||||
{
|
||||
bool setGeometry = false;
|
||||
var setGeometry = false;
|
||||
|
||||
foreach(Modes.ModePage page in decMode.Value.Pages)
|
||||
{
|
||||
@@ -327,7 +327,7 @@ partial class Dump
|
||||
_mediaGraph?.PaintSectorsBad(_resume.BadBlocks);
|
||||
}
|
||||
|
||||
bool newTrim = false;
|
||||
var newTrim = false;
|
||||
_speedStopwatch.Reset();
|
||||
ulong sectorSpeedStart = 0;
|
||||
InitProgress?.Invoke();
|
||||
@@ -374,7 +374,12 @@ partial class Dump
|
||||
mhddLog.Write(i, cmdDuration, blocksToRead);
|
||||
ibgLog.Write(i, currentSpeed * 1024);
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(readBuffer, i, blocksToRead);
|
||||
|
||||
outputFormat.WriteSectors(readBuffer,
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
extents.Add(i, blocksToRead, true);
|
||||
_mediaGraph?.PaintSectorsGood(i, blocksToRead);
|
||||
@@ -388,7 +393,12 @@ partial class Dump
|
||||
|
||||
// Write empty data
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip], i, _skip);
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
for(ulong b = i; b < i + _skip; b++) _resume.BadBlocks.Add(b);
|
||||
@@ -470,7 +480,7 @@ partial class Dump
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
}
|
||||
|
||||
@@ -487,9 +497,9 @@ partial class Dump
|
||||
|
||||
if(_resume.BadBlocks.Count > 0 && !_aborted && _retryPasses > 0)
|
||||
{
|
||||
int pass = 1;
|
||||
bool forward = true;
|
||||
bool runningPersistent = false;
|
||||
var pass = 1;
|
||||
var forward = true;
|
||||
var runningPersistent = false;
|
||||
|
||||
Modes.ModePage? currentModePage = null;
|
||||
byte[] md6;
|
||||
@@ -637,14 +647,14 @@ partial class Dump
|
||||
{
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Correctly_retried_block_0_in_pass_1,
|
||||
badSector,
|
||||
pass));
|
||||
}
|
||||
else if(runningPersistent) outputFormat.WriteSector(readBuffer, badSector);
|
||||
else if(runningPersistent) outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Errored);
|
||||
}
|
||||
|
||||
if(pass < _retryPasses && !_aborted && _resume.BadBlocks.Count > 0)
|
||||
|
||||
@@ -86,7 +86,7 @@ public partial class Dump
|
||||
return;
|
||||
}
|
||||
|
||||
uint blocks = (uint)((readBuffer[0] << 24) + (readBuffer[1] << 16) + (readBuffer[2] << 8) + readBuffer[3]);
|
||||
var blocks = (uint)((readBuffer[0] << 24) + (readBuffer[1] << 16) + (readBuffer[2] << 8) + readBuffer[3]);
|
||||
|
||||
blocks++;
|
||||
|
||||
@@ -191,7 +191,7 @@ public partial class Dump
|
||||
_mediaGraph?.PaintSectorsBad(_resume.BadBlocks);
|
||||
}
|
||||
|
||||
bool newTrim = false;
|
||||
var newTrim = false;
|
||||
|
||||
_speedStopwatch.Restart();
|
||||
ulong sectorSpeedStart = 0;
|
||||
@@ -246,7 +246,12 @@ public partial class Dump
|
||||
mhddLog.Write(i, cmdDuration, blocksToRead);
|
||||
ibgLog.Write(i, currentSpeed * 1024);
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(readBuffer, i, blocksToRead);
|
||||
|
||||
outputFormat.WriteSectors(readBuffer,
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
extents.Add(i, blocksToRead, true);
|
||||
_mediaGraph?.PaintSectorsGood(i, blocksToRead);
|
||||
@@ -262,7 +267,12 @@ public partial class Dump
|
||||
|
||||
// Write empty data
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip], i, _skip);
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
for(ulong b = i; b < i + _skip; b++) _resume.BadBlocks.Add(b);
|
||||
@@ -363,7 +373,7 @@ public partial class Dump
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
}
|
||||
|
||||
@@ -380,9 +390,9 @@ public partial class Dump
|
||||
|
||||
if(_resume.BadBlocks.Count > 0 && !_aborted && _retryPasses > 0)
|
||||
{
|
||||
int pass = 1;
|
||||
bool forward = true;
|
||||
bool runningPersistent = false;
|
||||
var pass = 1;
|
||||
var forward = true;
|
||||
var runningPersistent = false;
|
||||
|
||||
Modes.ModePage? currentModePage = null;
|
||||
byte[] md6;
|
||||
@@ -562,14 +572,14 @@ public partial class Dump
|
||||
{
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Correctly_retried_block_0_in_pass_1,
|
||||
badSector,
|
||||
pass));
|
||||
}
|
||||
else if(runningPersistent) outputFormat.WriteSector(readBuffer, badSector);
|
||||
else if(runningPersistent) outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Errored);
|
||||
}
|
||||
|
||||
if(pass < _retryPasses && !_aborted && _resume.BadBlocks.Count > 0)
|
||||
|
||||
@@ -96,11 +96,11 @@ public partial class Dump
|
||||
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);
|
||||
var fatStart = (ushort)((readBuffer[0x0F] << 8) + readBuffer[0x0E]);
|
||||
var sectorsPerFat = (ushort)((readBuffer[0x17] << 8) + readBuffer[0x16]);
|
||||
var rootStart = (ushort)(sectorsPerFat * 2 + fatStart);
|
||||
var rootSize = (ushort)(((readBuffer[0x12] << 8) + readBuffer[0x11]) * 32 / 512);
|
||||
var umdStart = (ushort)(rootStart + rootSize);
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Reading_root_directory_in_sector_0, rootStart));
|
||||
|
||||
@@ -126,7 +126,7 @@ public partial class Dump
|
||||
return;
|
||||
}
|
||||
|
||||
uint umdSizeInBytes = BitConverter.ToUInt32(readBuffer, 0x3C);
|
||||
var umdSizeInBytes = BitConverter.ToUInt32(readBuffer, 0x3C);
|
||||
ulong blocks = umdSizeInBytes / blockSize;
|
||||
string mediaPartNumber = Encoding.ASCII.GetString(readBuffer, 0, 11).Trim();
|
||||
|
||||
@@ -229,7 +229,7 @@ public partial class Dump
|
||||
_mediaGraph?.PaintSectorsBad(_resume.BadBlocks);
|
||||
}
|
||||
|
||||
bool newTrim = false;
|
||||
var newTrim = false;
|
||||
|
||||
_speedStopwatch.Reset();
|
||||
ulong sectorSpeedStart = 0;
|
||||
@@ -285,7 +285,12 @@ public partial class Dump
|
||||
{
|
||||
mhddLog.Write(i, cmdDuration, blocksToRead);
|
||||
ibgLog.Write(i, currentSpeed * 1024);
|
||||
outputOptical.WriteSectors(readBuffer, i, blocksToRead);
|
||||
|
||||
outputOptical.WriteSectors(readBuffer,
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
extents.Add(i, blocksToRead, true);
|
||||
_mediaGraph?.PaintSectorsGood(i, blocksToRead);
|
||||
@@ -300,7 +305,11 @@ public partial class Dump
|
||||
if(i + _skip > blocks) _skip = (uint)(blocks - i);
|
||||
|
||||
// Write empty data
|
||||
outputOptical.WriteSectors(new byte[blockSize * _skip], i, _skip);
|
||||
outputOptical.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
for(ulong b = i; b < i + _skip; b++) _resume.BadBlocks.Add(b);
|
||||
@@ -400,7 +409,7 @@ public partial class Dump
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputOptical.WriteSector(readBuffer, badSector);
|
||||
outputOptical.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
}
|
||||
|
||||
@@ -417,9 +426,9 @@ public partial class Dump
|
||||
|
||||
if(_resume.BadBlocks.Count > 0 && !_aborted && _retryPasses > 0)
|
||||
{
|
||||
int pass = 1;
|
||||
bool forward = true;
|
||||
bool runningPersistent = false;
|
||||
var pass = 1;
|
||||
var forward = true;
|
||||
var runningPersistent = false;
|
||||
|
||||
Modes.ModePage? currentModePage = null;
|
||||
byte[] md6;
|
||||
@@ -576,14 +585,14 @@ public partial class Dump
|
||||
{
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputOptical.WriteSector(readBuffer, badSector);
|
||||
outputOptical.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Correctly_retried_block_0_in_pass_1,
|
||||
badSector,
|
||||
pass));
|
||||
}
|
||||
else if(runningPersistent) outputOptical.WriteSector(readBuffer, badSector);
|
||||
else if(runningPersistent) outputOptical.WriteSector(readBuffer, badSector, SectorStatus.Errored);
|
||||
}
|
||||
|
||||
if(pass < _retryPasses && !_aborted && _resume.BadBlocks.Count > 0)
|
||||
|
||||
@@ -285,9 +285,8 @@ partial class Dump
|
||||
Modes.DecodedMode? decMode = null;
|
||||
|
||||
if(!sense && !_dev.Error)
|
||||
{
|
||||
if(Modes.DecodeMode10(cmdBuf, _dev.ScsiType).HasValue) decMode = Modes.DecodeMode10(cmdBuf, _dev.ScsiType);
|
||||
}
|
||||
if(Modes.DecodeMode10(cmdBuf, _dev.ScsiType).HasValue)
|
||||
decMode = Modes.DecodeMode10(cmdBuf, _dev.ScsiType);
|
||||
|
||||
UpdateStatus?.Invoke(Localization.Core.Requesting_MODE_SENSE_6);
|
||||
|
||||
@@ -315,9 +314,8 @@ partial class Dump
|
||||
if(sense || _dev.Error) sense = _dev.ModeSense(out cmdBuf, out senseBuf, 5, out duration);
|
||||
|
||||
if(!sense && !_dev.Error)
|
||||
{
|
||||
if(Modes.DecodeMode6(cmdBuf, _dev.ScsiType).HasValue) decMode = Modes.DecodeMode6(cmdBuf, _dev.ScsiType);
|
||||
}
|
||||
if(Modes.DecodeMode6(cmdBuf, _dev.ScsiType).HasValue)
|
||||
decMode = Modes.DecodeMode6(cmdBuf, _dev.ScsiType);
|
||||
|
||||
// TODO: Check partitions page
|
||||
if(decMode.HasValue)
|
||||
@@ -361,12 +359,12 @@ partial class Dump
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Media_identified_as_0, dskType.Humanize()));
|
||||
|
||||
|
||||
bool endOfMedia = false;
|
||||
var endOfMedia = false;
|
||||
ulong currentBlock = 0;
|
||||
uint currentFile = 0;
|
||||
byte currentPartition = 0;
|
||||
byte totalPartitions = 1; // TODO: Handle partitions.
|
||||
bool fixedLen = false;
|
||||
var fixedLen = false;
|
||||
uint transferLen = blockSize;
|
||||
|
||||
firstRead:
|
||||
@@ -601,8 +599,8 @@ partial class Dump
|
||||
return;
|
||||
}
|
||||
|
||||
bool canLocateLong = false;
|
||||
bool canLocate = false;
|
||||
var canLocateLong = false;
|
||||
var canLocate = false;
|
||||
|
||||
UpdateStatus?.Invoke(Localization.Core.Positioning_tape_to_block_1);
|
||||
|
||||
@@ -1092,7 +1090,7 @@ partial class Dump
|
||||
|
||||
// Write empty data
|
||||
_writeStopwatch.Restart();
|
||||
outputTape.WriteSector(new byte[blockSize], currentBlock);
|
||||
outputTape.WriteSector(new byte[blockSize], currentBlock, SectorStatus.NotDumped);
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
mhddLog.Write(currentBlock, duration < 500 ? 65535 : duration);
|
||||
@@ -1104,7 +1102,7 @@ partial class Dump
|
||||
mhddLog.Write(currentBlock, duration);
|
||||
ibgLog.Write(currentBlock, currentSpeed * 1024);
|
||||
_writeStopwatch.Restart();
|
||||
outputTape.WriteSector(cmdBuf, currentBlock);
|
||||
outputTape.WriteSector(cmdBuf, currentBlock, SectorStatus.Dumped);
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
extents.Add(currentBlock, 1, true);
|
||||
}
|
||||
@@ -1167,8 +1165,8 @@ partial class Dump
|
||||
|
||||
if(_resume.BadBlocks.Count > 0 && !_aborted && _retryPasses > 0 && (canLocate || canLocateLong))
|
||||
{
|
||||
int pass = 1;
|
||||
bool forward = false;
|
||||
var pass = 1;
|
||||
var forward = false;
|
||||
const bool runningPersistent = false;
|
||||
|
||||
Modes.ModePage? currentModePage;
|
||||
@@ -1299,13 +1297,13 @@ partial class Dump
|
||||
{
|
||||
_resume.BadBlocks.Remove(badBlock);
|
||||
extents.Add(badBlock);
|
||||
outputTape.WriteSector(cmdBuf, badBlock);
|
||||
outputTape.WriteSector(cmdBuf, badBlock, SectorStatus.Dumped);
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Correctly_retried_block_0_in_pass_1,
|
||||
badBlock,
|
||||
pass));
|
||||
}
|
||||
else if(runningPersistent) outputTape.WriteSector(cmdBuf, badBlock);
|
||||
else if(runningPersistent) outputTape.WriteSector(cmdBuf, badBlock, SectorStatus.Errored);
|
||||
}
|
||||
|
||||
if(pass < _retryPasses && !_aborted && _resume.BadBlocks.Count > 0)
|
||||
|
||||
@@ -118,7 +118,7 @@ partial class Dump
|
||||
_writeStopwatch.Restart();
|
||||
|
||||
byte[] tmpBuf;
|
||||
byte[] cmi = new byte[blocksToRead];
|
||||
var cmi = new byte[blocksToRead];
|
||||
|
||||
for(uint j = 0; j < blocksToRead; j++)
|
||||
{
|
||||
@@ -160,7 +160,10 @@ partial class Dump
|
||||
buffer = CSS.DecryptSectorLong(buffer, titleKey, cmi, blocksToRead);
|
||||
}
|
||||
|
||||
outputFormat.WriteSectorsLong(buffer, i, blocksToRead);
|
||||
outputFormat.WriteSectorsLong(buffer,
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
extents.Add(i, blocksToRead, true);
|
||||
@@ -175,7 +178,12 @@ partial class Dump
|
||||
|
||||
// Write empty data
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize * _skip], i, _skip);
|
||||
|
||||
outputFormat.WriteSectorsLong(new byte[blockSize * _skip],
|
||||
i,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
for(ulong b = i; b < i + _skip; b++) _resume.BadBlocks.Add(b);
|
||||
|
||||
@@ -189,7 +189,12 @@ partial class Dump
|
||||
mhddLog.Write(i, cmdDuration, blocksToRead);
|
||||
ibgLog.Write(i, currentSpeed * 1024);
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(buffer, i, blocksToRead);
|
||||
|
||||
outputFormat.WriteSectors(buffer,
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
extents.Add(i, blocksToRead, true);
|
||||
_mediaGraph?.PaintSectorsGood(i, blocksToRead);
|
||||
@@ -217,7 +222,12 @@ partial class Dump
|
||||
|
||||
// Write empty data
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip], i, _skip);
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
for(ulong b = i; b < i + _skip; b++) _resume.BadBlocks.Add(b);
|
||||
|
||||
@@ -57,9 +57,9 @@ partial class Dump
|
||||
void RetrySbcData(Reader scsiReader, DumpHardware currentTry, ExtentsULong extents, ref double totalDuration,
|
||||
ExtentsULong blankExtents, byte[] discKey)
|
||||
{
|
||||
int pass = 1;
|
||||
bool forward = true;
|
||||
bool runningPersistent = false;
|
||||
var pass = 1;
|
||||
var forward = true;
|
||||
var runningPersistent = false;
|
||||
bool sense;
|
||||
byte[] buffer;
|
||||
bool recoveredError;
|
||||
@@ -67,7 +67,7 @@ partial class Dump
|
||||
byte[] md6;
|
||||
byte[] md10;
|
||||
bool blankCheck;
|
||||
bool newBlank = false;
|
||||
var newBlank = false;
|
||||
var outputFormat = _outputPlugin as IWritableImage;
|
||||
|
||||
if(_persistent)
|
||||
@@ -310,7 +310,7 @@ partial class Dump
|
||||
|
||||
if(scsiReader.LiteOnReadRaw || scsiReader.HldtstReadRaw)
|
||||
{
|
||||
byte[] cmi = new byte[1];
|
||||
var cmi = new byte[1];
|
||||
|
||||
byte[] key = buffer.Skip(7).Take(5).ToArray();
|
||||
|
||||
@@ -348,10 +348,10 @@ partial class Dump
|
||||
}
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
outputFormat.WriteSectorLong(buffer, badSector);
|
||||
outputFormat.WriteSectorLong(buffer, badSector, SectorStatus.Dumped);
|
||||
}
|
||||
else
|
||||
outputFormat.WriteSector(buffer, badSector);
|
||||
outputFormat.WriteSector(buffer, badSector, SectorStatus.Dumped);
|
||||
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
|
||||
@@ -359,7 +359,7 @@ partial class Dump
|
||||
badSector,
|
||||
pass));
|
||||
}
|
||||
else if(runningPersistent) outputFormat.WriteSector(buffer, badSector);
|
||||
else if(runningPersistent) outputFormat.WriteSector(buffer, badSector, SectorStatus.Errored);
|
||||
}
|
||||
|
||||
if(pass < _retryPasses && !_aborted && _resume.BadBlocks.Count > 0)
|
||||
@@ -397,8 +397,8 @@ partial class Dump
|
||||
|
||||
void RetryTitleKeys(DVDDecryption dvdDecrypt, byte[] discKey, ref double totalDuration)
|
||||
{
|
||||
int pass = 1;
|
||||
bool forward = true;
|
||||
var pass = 1;
|
||||
var forward = true;
|
||||
bool sense;
|
||||
byte[] buffer;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Aaru.CommonTypes.AaruMetadata;
|
||||
using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Extents;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.Core.Logging;
|
||||
@@ -52,7 +53,7 @@ partial class Dump
|
||||
bool sense;
|
||||
byte[] buffer;
|
||||
ulong sectorSpeedStart = 0;
|
||||
bool canMediumScan = true;
|
||||
var canMediumScan = true;
|
||||
var outputFormat = _outputPlugin as IWritableImage;
|
||||
|
||||
InitProgress?.Invoke();
|
||||
@@ -179,9 +180,8 @@ partial class Dump
|
||||
writtenExtents.Add(0, blocks - 1);
|
||||
|
||||
foreach(Tuple<ulong, ulong> blank in blankExtents.ToArray())
|
||||
{
|
||||
for(ulong b = blank.Item1; b <= blank.Item2; b++) writtenExtents.Remove(b);
|
||||
}
|
||||
for(ulong b = blank.Item1; b <= blank.Item2; b++)
|
||||
writtenExtents.Remove(b);
|
||||
}
|
||||
|
||||
if(writtenExtents.Count == 0)
|
||||
@@ -236,7 +236,12 @@ partial class Dump
|
||||
mhddLog.Write(i, cmdDuration, blocksToRead);
|
||||
ibgLog.Write(i, currentSpeed * 1024);
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(buffer, i, blocksToRead);
|
||||
|
||||
outputFormat.WriteSectors(buffer,
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
extents.Add(i, blocksToRead, true);
|
||||
}
|
||||
@@ -249,7 +254,12 @@ partial class Dump
|
||||
|
||||
// Write empty data
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip], i, _skip);
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
for(ulong b = i; b < i + _skip; b++) _resume.BadBlocks.Add(b);
|
||||
|
||||
@@ -52,7 +52,7 @@ partial class Dump
|
||||
bool recoveredError;
|
||||
bool blankCheck;
|
||||
byte[] buffer;
|
||||
bool newBlank = false;
|
||||
var newBlank = false;
|
||||
|
||||
if(_outputPlugin is not IWritableImage outputFormat)
|
||||
{
|
||||
@@ -101,7 +101,7 @@ partial class Dump
|
||||
|
||||
if(scsiReader.LiteOnReadRaw || scsiReader.HldtstReadRaw)
|
||||
{
|
||||
byte[] cmi = new byte[1];
|
||||
var cmi = new byte[1];
|
||||
|
||||
byte[] key = buffer.Skip(7).Take(5).ToArray();
|
||||
|
||||
@@ -138,10 +138,10 @@ partial class Dump
|
||||
}
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
outputFormat.WriteSectorLong(buffer, badSector);
|
||||
outputFormat.WriteSectorLong(buffer, badSector, SectorStatus.Dumped);
|
||||
}
|
||||
else
|
||||
outputFormat.WriteSector(buffer, badSector);
|
||||
outputFormat.WriteSector(buffer, badSector, SectorStatus.Dumped);
|
||||
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
}
|
||||
|
||||
@@ -87,9 +87,9 @@ public partial class Dump
|
||||
byte[] ecsd = null;
|
||||
byte[] scr = null;
|
||||
uint physicalBlockSize = 0;
|
||||
bool byteAddressed = true;
|
||||
var byteAddressed = true;
|
||||
uint[] response;
|
||||
bool supportsCmd23 = false;
|
||||
var supportsCmd23 = false;
|
||||
var outputFormat = _outputPlugin as IWritableImage;
|
||||
|
||||
Dictionary<MediaTagType, byte[]> mediaTags = new();
|
||||
@@ -412,7 +412,7 @@ public partial class Dump
|
||||
return;
|
||||
}
|
||||
|
||||
bool ret = true;
|
||||
var ret = true;
|
||||
|
||||
foreach(MediaTagType tag in mediaTags.Keys.Where(tag => !outputFormat.SupportedMediaTags.Contains(tag)))
|
||||
{
|
||||
@@ -592,7 +592,7 @@ public partial class Dump
|
||||
_dumpStopwatch.Restart();
|
||||
_speedStopwatch.Reset();
|
||||
double imageWriteDuration = 0;
|
||||
bool newTrim = false;
|
||||
var newTrim = false;
|
||||
ulong sectorSpeedStart = 0;
|
||||
|
||||
InitProgress?.Invoke();
|
||||
@@ -664,7 +664,12 @@ public partial class Dump
|
||||
mhddLog.Write(i, duration, blocksToRead);
|
||||
ibgLog.Write(i, currentSpeed * 1024);
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(cmdBuf, i, blocksToRead);
|
||||
|
||||
outputFormat.WriteSectors(cmdBuf,
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, blocksToRead).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
extents.Add(i, blocksToRead, true);
|
||||
_mediaGraph?.PaintSectorsGood(i, blocksToRead);
|
||||
@@ -681,7 +686,12 @@ public partial class Dump
|
||||
|
||||
ibgLog.Write(i, 0);
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip], i, _skip);
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
AaruLogging.WriteLine(Localization.Core.Skipping_0_blocks_from_errored_block_1, _skip, i);
|
||||
i += _skip - blocksToRead;
|
||||
@@ -771,7 +781,7 @@ public partial class Dump
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(cmdBuf, badSector);
|
||||
outputFormat.WriteSector(cmdBuf, badSector, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
}
|
||||
|
||||
@@ -788,8 +798,8 @@ public partial class Dump
|
||||
|
||||
if(_resume.BadBlocks.Count > 0 && !_aborted && _retryPasses > 0)
|
||||
{
|
||||
int pass = 1;
|
||||
bool forward = true;
|
||||
var pass = 1;
|
||||
var forward = true;
|
||||
|
||||
InitProgress?.Invoke();
|
||||
repeatRetryLba:
|
||||
@@ -832,7 +842,7 @@ public partial class Dump
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(cmdBuf, badSector);
|
||||
outputFormat.WriteSector(cmdBuf, badSector, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Correctly_retried_block_0_in_pass_1,
|
||||
|
||||
@@ -150,7 +150,7 @@ partial class Dump
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] tmpBuf = new byte[ssBuf.Length - 4];
|
||||
var tmpBuf = new byte[ssBuf.Length - 4];
|
||||
Array.Copy(ssBuf, 4, tmpBuf, 0, ssBuf.Length - 4);
|
||||
mediaTags.Add(MediaTagType.Xbox_SecuritySector, tmpBuf);
|
||||
|
||||
@@ -475,7 +475,7 @@ partial class Dump
|
||||
|
||||
if(_skip < blocksToRead) _skip = blocksToRead;
|
||||
|
||||
bool ret = true;
|
||||
var ret = true;
|
||||
|
||||
foreach(MediaTagType tag in mediaTags.Keys.Where(tag => !outputFormat.SupportedMediaTags.Contains(tag)))
|
||||
{
|
||||
@@ -579,14 +579,14 @@ partial class Dump
|
||||
if(_resume.NextBlock > 0)
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Resuming_from_block_0, _resume.NextBlock));
|
||||
|
||||
bool newTrim = false;
|
||||
var newTrim = false;
|
||||
|
||||
UpdateStatus?.Invoke(Localization.Core.Reading_game_partition);
|
||||
_speedStopwatch.Reset();
|
||||
ulong sectorSpeedStart = 0;
|
||||
InitProgress?.Invoke();
|
||||
|
||||
for(int e = 0; e <= 16; e++)
|
||||
for(var e = 0; e <= 16; e++)
|
||||
{
|
||||
if(_aborted)
|
||||
{
|
||||
@@ -683,7 +683,12 @@ partial class Dump
|
||||
mhddLog.Write(i, cmdDuration, blocksToRead);
|
||||
ibgLog.Write(i, currentSpeed * 1024);
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(readBuffer, i, blocksToRead);
|
||||
|
||||
outputFormat.WriteSectors(readBuffer,
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
extents.Add(i, blocksToRead, true);
|
||||
_mediaGraph?.PaintSectorsGood(i, blocksToRead);
|
||||
@@ -699,7 +704,12 @@ partial class Dump
|
||||
|
||||
// Write empty data
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip], i, _skip);
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
i,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
for(ulong b = i; b < i + _skip; b++) _resume.BadBlocks.Add(b);
|
||||
@@ -757,7 +767,12 @@ partial class Dump
|
||||
|
||||
// Write empty data
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(new byte[blockSize * blocksToRead], i, blocksToRead);
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * blocksToRead],
|
||||
i,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
blocksToRead = saveBlocksToRead;
|
||||
extents.Add(i, blocksToRead, true);
|
||||
@@ -802,7 +817,12 @@ partial class Dump
|
||||
|
||||
// Write empty data
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(new byte[blockSize * blocksToRead], middle + currentSector, blocksToRead);
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * blocksToRead],
|
||||
middle + currentSector,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)blocksToRead).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
extents.Add(currentSector, blocksToRead, true);
|
||||
_writeStopwatch.Stop();
|
||||
@@ -887,7 +907,12 @@ partial class Dump
|
||||
mhddLog.Write(currentSector, cmdDuration, blocksToRead);
|
||||
ibgLog.Write(currentSector, currentSpeed * 1024);
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(readBuffer, currentSector, blocksToRead);
|
||||
|
||||
outputFormat.WriteSectors(readBuffer,
|
||||
currentSector,
|
||||
blocksToRead,
|
||||
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
extents.Add(currentSector, blocksToRead, true);
|
||||
_mediaGraph?.PaintSectorsGood(currentSector, blocksToRead);
|
||||
@@ -901,7 +926,12 @@ partial class Dump
|
||||
|
||||
// Write empty data
|
||||
_writeStopwatch.Restart();
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip], currentSector, _skip);
|
||||
|
||||
outputFormat.WriteSectors(new byte[blockSize * _skip],
|
||||
currentSector,
|
||||
_skip,
|
||||
Enumerable.Repeat(SectorStatus.NotDumped, (int)_skip).ToArray());
|
||||
|
||||
imageWriteDuration += _writeStopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
// TODO: Handle errors in video partition
|
||||
@@ -1030,7 +1060,7 @@ partial class Dump
|
||||
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
}
|
||||
|
||||
@@ -1050,14 +1080,15 @@ partial class Dump
|
||||
List<ulong> tmpList = [];
|
||||
|
||||
foreach(ulong ur in _resume.BadBlocks)
|
||||
for(ulong i = ur; i < ur + blocksToRead; i++)
|
||||
tmpList.Add(i);
|
||||
{
|
||||
for(ulong i = ur; i < ur + blocksToRead; i++) tmpList.Add(i);
|
||||
}
|
||||
|
||||
tmpList.Sort();
|
||||
|
||||
int pass = 1;
|
||||
bool forward = true;
|
||||
bool runningPersistent = false;
|
||||
var pass = 1;
|
||||
var forward = true;
|
||||
var runningPersistent = false;
|
||||
|
||||
_resume.BadBlocks = tmpList;
|
||||
Modes.ModePage? currentModePage = null;
|
||||
@@ -1230,14 +1261,14 @@ partial class Dump
|
||||
{
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector);
|
||||
outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Dumped);
|
||||
_mediaGraph?.PaintSectorGood(badSector);
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Correctly_retried_block_0_in_pass_1,
|
||||
badSector,
|
||||
pass));
|
||||
}
|
||||
else if(runningPersistent) outputFormat.WriteSector(readBuffer, badSector);
|
||||
else if(runningPersistent) outputFormat.WriteSector(readBuffer, badSector, SectorStatus.Errored);
|
||||
}
|
||||
|
||||
if(pass < _retryPasses && !_aborted && _resume.BadBlocks.Count > 0)
|
||||
|
||||
@@ -742,18 +742,26 @@ public sealed partial class ImageConvertViewModel : ViewModelBase
|
||||
});
|
||||
|
||||
bool result;
|
||||
SectorStatus sectorStatus = SectorStatus.NotDumped;
|
||||
var sectorStatusArray = new SectorStatus[1];
|
||||
|
||||
if(useLong)
|
||||
{
|
||||
errno = sectorsToDo == 1
|
||||
? _inputFormat.ReadSectorLong(doneSectors, out sector, out _)
|
||||
: _inputFormat.ReadSectorsLong(doneSectors, sectorsToDo, out sector, out _);
|
||||
? _inputFormat.ReadSectorLong(doneSectors, out sector, out sectorStatus)
|
||||
: _inputFormat.ReadSectorsLong(doneSectors,
|
||||
sectorsToDo,
|
||||
out sector,
|
||||
out sectorStatusArray);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
result = sectorsToDo == 1
|
||||
? outputFormat.WriteSectorLong(sector, doneSectors)
|
||||
: outputFormat.WriteSectorsLong(sector, doneSectors, sectorsToDo);
|
||||
? outputFormat.WriteSectorLong(sector, doneSectors, sectorStatus)
|
||||
: outputFormat.WriteSectorsLong(sector,
|
||||
doneSectors,
|
||||
sectorsToDo,
|
||||
sectorStatusArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -786,14 +794,14 @@ public sealed partial class ImageConvertViewModel : ViewModelBase
|
||||
else
|
||||
{
|
||||
errno = sectorsToDo == 1
|
||||
? _inputFormat.ReadSector(doneSectors, out sector, out _)
|
||||
: _inputFormat.ReadSectors(doneSectors, sectorsToDo, out sector, out _);
|
||||
? _inputFormat.ReadSector(doneSectors, out sector, out sectorStatus)
|
||||
: _inputFormat.ReadSectors(doneSectors, sectorsToDo, out sector, out sectorStatusArray);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
result = sectorsToDo == 1
|
||||
? outputFormat.WriteSector(sector, doneSectors)
|
||||
: outputFormat.WriteSectors(sector, doneSectors, sectorsToDo);
|
||||
? outputFormat.WriteSector(sector, doneSectors, sectorStatus)
|
||||
: outputFormat.WriteSectors(sector, doneSectors, sectorsToDo, sectorStatusArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1201,23 +1209,30 @@ public sealed partial class ImageConvertViewModel : ViewModelBase
|
||||
});
|
||||
|
||||
bool result;
|
||||
SectorStatus sectorStatus = SectorStatus.NotDumped;
|
||||
var sectorStatusArray = new SectorStatus[1];
|
||||
|
||||
if(useLong)
|
||||
{
|
||||
errno = sectorsToDo == 1
|
||||
? _inputFormat.ReadSectorLong(doneSectors + track.StartSector, out sector, out _)
|
||||
? _inputFormat.ReadSectorLong(doneSectors + track.StartSector,
|
||||
out sector,
|
||||
out sectorStatus)
|
||||
: _inputFormat.ReadSectorsLong(doneSectors + track.StartSector,
|
||||
sectorsToDo,
|
||||
out sector,
|
||||
out _);
|
||||
out sectorStatusArray);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
result = sectorsToDo == 1
|
||||
? outputFormat.WriteSectorLong(sector, doneSectors + track.StartSector)
|
||||
? outputFormat.WriteSectorLong(sector,
|
||||
doneSectors + track.StartSector,
|
||||
sectorStatus)
|
||||
: outputFormat.WriteSectorsLong(sector,
|
||||
doneSectors + track.StartSector,
|
||||
sectorsToDo);
|
||||
sectorsToDo,
|
||||
sectorStatusArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1248,19 +1263,24 @@ public sealed partial class ImageConvertViewModel : ViewModelBase
|
||||
else
|
||||
{
|
||||
errno = sectorsToDo == 1
|
||||
? _inputFormat.ReadSector(doneSectors + track.StartSector, out sector, out _)
|
||||
? _inputFormat.ReadSector(doneSectors + track.StartSector,
|
||||
out sector,
|
||||
out sectorStatus)
|
||||
: _inputFormat.ReadSectors(doneSectors + track.StartSector,
|
||||
sectorsToDo,
|
||||
out sector,
|
||||
out _);
|
||||
out sectorStatusArray);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
result = sectorsToDo == 1
|
||||
? outputFormat.WriteSector(sector, doneSectors + track.StartSector)
|
||||
? outputFormat.WriteSector(sector,
|
||||
doneSectors + track.StartSector,
|
||||
sectorStatus)
|
||||
: outputFormat.WriteSectors(sector,
|
||||
doneSectors + track.StartSector,
|
||||
sectorsToDo);
|
||||
sectorsToDo,
|
||||
sectorStatusArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -241,16 +241,20 @@ public sealed partial class A2R
|
||||
public bool WriteMediaTag(byte[] data, MediaTagType tag) => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress) => throw new NotImplementedException();
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus) =>
|
||||
throw new NotImplementedException();
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress) => throw new NotImplementedException();
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus) =>
|
||||
throw new NotImplementedException();
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length) => throw new NotImplementedException();
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus) =>
|
||||
throw new NotImplementedException();
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length) => throw new NotImplementedException();
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus) =>
|
||||
throw new NotImplementedException();
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -66,9 +66,9 @@ public sealed partial class AaruFormat
|
||||
#region IWritableOpticalImage Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
Status res = aaruf_write_sector(_context, sectorAddress, false, data, SectorStatus.Dumped, (uint)data.Length);
|
||||
Status res = aaruf_write_sector(_context, sectorAddress, false, data, sectorStatus, (uint)data.Length);
|
||||
|
||||
if(res == Status.Ok) return true;
|
||||
|
||||
@@ -78,10 +78,9 @@ public sealed partial class AaruFormat
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
Status res =
|
||||
aaruf_write_sector_long(_context, sectorAddress, false, data, SectorStatus.Dumped, (uint)data.Length);
|
||||
Status res = aaruf_write_sector_long(_context, sectorAddress, false, data, sectorStatus, (uint)data.Length);
|
||||
|
||||
if(res == Status.Ok) return true;
|
||||
|
||||
@@ -137,7 +136,7 @@ public sealed partial class AaruFormat
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
var sectorSize = (uint)(data.Length / length);
|
||||
|
||||
@@ -146,14 +145,14 @@ public sealed partial class AaruFormat
|
||||
var sectorData = new byte[sectorSize];
|
||||
Array.Copy(data, i * sectorSize, sectorData, 0, sectorSize);
|
||||
|
||||
if(!WriteSector(sectorData, sectorAddress + i)) return false;
|
||||
if(!WriteSector(sectorData, sectorAddress + i, sectorStatus[i])) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
var sectorSize = (uint)(data.Length / length);
|
||||
|
||||
@@ -162,7 +161,7 @@ public sealed partial class AaruFormat
|
||||
var sectorData = new byte[sectorSize];
|
||||
Array.Copy(data, i * sectorSize, sectorData, 0, sectorSize);
|
||||
|
||||
if(!WriteSectorLong(sectorData, sectorAddress + i)) return false;
|
||||
if(!WriteSectorLong(sectorData, sectorAddress + i, sectorStatus[i])) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -288,9 +287,8 @@ public sealed partial class AaruFormat
|
||||
|
||||
// Convert array of booleans to List of enums
|
||||
for(nuint i = 0; i < sizet_length; i++)
|
||||
{
|
||||
if(sectorTagsBuffer[i] != 0) _imageInfo.ReadableSectorTags.Add((SectorTagType)i);
|
||||
}
|
||||
if(sectorTagsBuffer[i] != 0)
|
||||
_imageInfo.ReadableSectorTags.Add((SectorTagType)i);
|
||||
|
||||
sizet_length = 0;
|
||||
ret = aaruf_get_readable_media_tags(_context, null, ref sizet_length);
|
||||
@@ -314,9 +312,8 @@ public sealed partial class AaruFormat
|
||||
|
||||
// Convert array of booleans to List of enums
|
||||
for(nuint i = 0; i < sizet_length; i++)
|
||||
{
|
||||
if(mediaTagsBuffer[i] != 0) _imageInfo.ReadableMediaTags.Add((MediaTagType)i);
|
||||
}
|
||||
if(mediaTagsBuffer[i] != 0)
|
||||
_imageInfo.ReadableMediaTags.Add((MediaTagType)i);
|
||||
|
||||
ret = aaruf_get_media_sequence(_context, out int sequence, out int lastSequence);
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@ public sealed partial class Alcohol120
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -261,7 +261,7 @@ public sealed partial class Alcohol120
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -343,7 +343,7 @@ public sealed partial class Alcohol120
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -369,7 +369,7 @@ public sealed partial class Alcohol120
|
||||
return false;
|
||||
}
|
||||
|
||||
uint subchannelSize = (uint)(track.SubchannelType != TrackSubchannelType.None ? 96 : 0);
|
||||
var subchannelSize = (uint)(track.SubchannelType != TrackSubchannelType.None ? 96 : 0);
|
||||
|
||||
_imageStream.Seek((long)(track.FileOffset +
|
||||
(sectorAddress - track.StartSector) *
|
||||
@@ -382,7 +382,7 @@ public sealed partial class Alcohol120
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -415,7 +415,7 @@ public sealed partial class Alcohol120
|
||||
return false;
|
||||
}
|
||||
|
||||
uint subchannelSize = (uint)(track.SubchannelType != TrackSubchannelType.None ? 96 : 0);
|
||||
var subchannelSize = (uint)(track.SubchannelType != TrackSubchannelType.None ? 96 : 0);
|
||||
|
||||
for(uint i = 0; i < length; i++)
|
||||
{
|
||||
@@ -441,7 +441,7 @@ public sealed partial class Alcohol120
|
||||
{
|
||||
CommonTypes.Structs.Track[] tmpTracks = tracks.OrderBy(t => t.Sequence).ToArray();
|
||||
|
||||
for(int i = 1; i < tmpTracks.Length; i++)
|
||||
for(var i = 1; i < tmpTracks.Length; i++)
|
||||
{
|
||||
CommonTypes.Structs.Track firstTrackInSession =
|
||||
tracks.FirstOrDefault(t => t.Session == tmpTracks[i].Session);
|
||||
@@ -548,9 +548,9 @@ public sealed partial class Alcohol120
|
||||
FullTOC.CDFullTOC? decodedToc = FullTOC.Decode(tmpToc);
|
||||
|
||||
long currentExtraOffset = currentTrackOffset;
|
||||
int extraCount = 0;
|
||||
var extraCount = 0;
|
||||
|
||||
for(int i = 1; i <= sessions; i++)
|
||||
for(var i = 1; i <= sessions; i++)
|
||||
{
|
||||
if(decodedToc.HasValue)
|
||||
{
|
||||
@@ -619,7 +619,7 @@ public sealed partial class Alcohol120
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = 1; i <= sessions; i++)
|
||||
for(var i = 1; i <= sessions; i++)
|
||||
{
|
||||
CommonTypes.Structs.Track firstTrack = _writingTracks.First(t => t.Session == i);
|
||||
CommonTypes.Structs.Track lastTrack = _writingTracks.Last(t => t.Session == i);
|
||||
@@ -915,7 +915,7 @@ public sealed partial class Alcohol120
|
||||
|
||||
// Write header
|
||||
_descriptorStream.Seek(0, SeekOrigin.Begin);
|
||||
byte[] block = new byte[Marshal.SizeOf<Header>()];
|
||||
var block = new byte[Marshal.SizeOf<Header>()];
|
||||
nint blockPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.SizeOf<Header>());
|
||||
System.Runtime.InteropServices.Marshal.StructureToPtr(header, blockPtr, true);
|
||||
System.Runtime.InteropServices.Marshal.Copy(blockPtr, block, 0, block.Length);
|
||||
|
||||
@@ -113,7 +113,7 @@ public sealed partial class Anex86
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -145,7 +145,7 @@ public sealed partial class Anex86
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -177,7 +177,7 @@ public sealed partial class Anex86
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -185,7 +185,7 @@ public sealed partial class Anex86
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -233,7 +233,7 @@ public sealed partial class Anex86
|
||||
}
|
||||
}
|
||||
|
||||
byte[] hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
var hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
MemoryMarshal.Write(hdr, in _header);
|
||||
|
||||
_writingStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
@@ -109,7 +109,7 @@ public sealed partial class Apple2Mg
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -141,7 +141,7 @@ public sealed partial class Apple2Mg
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -173,7 +173,7 @@ public sealed partial class Apple2Mg
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -181,7 +181,7 @@ public sealed partial class Apple2Mg
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -199,7 +199,7 @@ public sealed partial class Apple2Mg
|
||||
}
|
||||
|
||||
_writingStream.Seek(0x40 + 17 * 16 * 256, SeekOrigin.Begin);
|
||||
byte[] tmp = new byte[256];
|
||||
var tmp = new byte[256];
|
||||
_writingStream.EnsureRead(tmp, 0, tmp.Length);
|
||||
|
||||
bool isDos = tmp[0x01] == 17 &&
|
||||
@@ -235,7 +235,7 @@ public sealed partial class Apple2Mg
|
||||
_writingStream.WriteByte(0);
|
||||
}
|
||||
|
||||
byte[] hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
var hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
nint hdrPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.SizeOf<Header>());
|
||||
System.Runtime.InteropServices.Marshal.StructureToPtr(_imageHeader, hdrPtr, true);
|
||||
System.Runtime.InteropServices.Marshal.Copy(hdrPtr, hdr, 0, hdr.Length);
|
||||
|
||||
@@ -114,10 +114,11 @@ public sealed partial class AppleDos
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress) => WriteSectors(data, sectorAddress, 1);
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus) =>
|
||||
WriteSectors(data, sectorAddress, 1, [SectorStatus.Dumped]);
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -148,7 +149,7 @@ public sealed partial class AppleDos
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -156,7 +157,7 @@ public sealed partial class AppleDos
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -195,9 +196,9 @@ public sealed partial class AppleDos
|
||||
? _interleave
|
||||
: _deinterleave;
|
||||
|
||||
for(int t = 0; t < 35; t++)
|
||||
for(var t = 0; t < 35; t++)
|
||||
{
|
||||
for(int s = 0; s < 16; s++)
|
||||
for(var s = 0; s < 16; s++)
|
||||
Array.Copy(_deinterleaved, t * 16 * 256 + offsets[s] * 256, tmp, t * 16 * 256 + s * 256, 256);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public sealed partial class Apridisk
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
(ushort cylinder, byte head, byte sector) = LbaToChs(sectorAddress);
|
||||
|
||||
@@ -124,7 +124,7 @@ public sealed partial class Apridisk
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
for(uint i = 0; i < length; i++)
|
||||
{
|
||||
@@ -158,7 +158,7 @@ public sealed partial class Apridisk
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -166,7 +166,7 @@ public sealed partial class Apridisk
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -180,7 +180,7 @@ public sealed partial class Apridisk
|
||||
_writingStream.Seek(0, SeekOrigin.Begin);
|
||||
_writingStream.Write(_signature, 0, _signature.Length);
|
||||
|
||||
byte[] hdr = new byte[Marshal.SizeOf<Record>()];
|
||||
var hdr = new byte[Marshal.SizeOf<Record>()];
|
||||
|
||||
for(ushort c = 0; c < _imageInfo.Cylinders; c++)
|
||||
{
|
||||
|
||||
@@ -111,7 +111,7 @@ public sealed partial class Blu
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
int longSectorSize = _imageInfo.MediaType == MediaType.PriamDataTower ? 536 : 532;
|
||||
|
||||
@@ -145,7 +145,7 @@ public sealed partial class Blu
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
int longSectorSize = _imageInfo.MediaType == MediaType.PriamDataTower ? 536 : 532;
|
||||
|
||||
@@ -179,7 +179,7 @@ public sealed partial class Blu
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -269,7 +269,7 @@ public sealed partial class Blu
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -387,7 +387,7 @@ public sealed partial class Blu
|
||||
|
||||
byte[] markerTag = Encoding.UTF8.GetBytes("Aaru " + Version.GetVersion());
|
||||
byte[] driveName;
|
||||
byte[] driveType = new byte[3];
|
||||
var driveType = new byte[3];
|
||||
byte[] driveBlocks = BigEndianBitConverter.GetBytes((uint)_imageInfo.Sectors);
|
||||
int longSectorSize = _imageInfo.MediaType == MediaType.PriamDataTower ? 536 : 532;
|
||||
byte[] blockSize = BigEndianBitConverter.GetBytes((ushort)longSectorSize);
|
||||
|
||||
@@ -143,7 +143,7 @@ public sealed partial class Cdrdao
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -188,7 +188,7 @@ public sealed partial class Cdrdao
|
||||
// cdrdao audio tracks are endian swapped corresponding to Aaru
|
||||
if(track.Type == TrackType.Audio)
|
||||
{
|
||||
byte[] swapped = new byte[data.Length];
|
||||
var swapped = new byte[data.Length];
|
||||
|
||||
for(long i = 0; i < swapped.Length; i += 2)
|
||||
{
|
||||
@@ -209,7 +209,7 @@ public sealed partial class Cdrdao
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -261,7 +261,7 @@ public sealed partial class Cdrdao
|
||||
// cdrdao audio tracks are endian swapped corresponding to Aaru
|
||||
if(track.Type == TrackType.Audio)
|
||||
{
|
||||
byte[] swapped = new byte[data.Length];
|
||||
var swapped = new byte[data.Length];
|
||||
|
||||
for(long i = 0; i < swapped.Length; i += 2)
|
||||
{
|
||||
@@ -307,7 +307,7 @@ public sealed partial class Cdrdao
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -345,7 +345,7 @@ public sealed partial class Cdrdao
|
||||
// cdrdao audio tracks are endian swapped corresponding to Aaru
|
||||
if(track.Type == TrackType.Audio)
|
||||
{
|
||||
byte[] swapped = new byte[data.Length];
|
||||
var swapped = new byte[data.Length];
|
||||
|
||||
for(long i = 0; i < swapped.Length; i += 2)
|
||||
{
|
||||
@@ -356,7 +356,7 @@ public sealed partial class Cdrdao
|
||||
data = swapped;
|
||||
}
|
||||
|
||||
uint subchannelSize = (uint)(track.SubchannelType != TrackSubchannelType.None ? 96 : 0);
|
||||
var subchannelSize = (uint)(track.SubchannelType != TrackSubchannelType.None ? 96 : 0);
|
||||
|
||||
trackStream.Seek((long)(track.FileOffset +
|
||||
(sectorAddress - track.StartSector) *
|
||||
@@ -369,7 +369,7 @@ public sealed partial class Cdrdao
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -414,7 +414,7 @@ public sealed partial class Cdrdao
|
||||
// cdrdao audio tracks are endian swapped corresponding to Aaru
|
||||
if(track.Type == TrackType.Audio)
|
||||
{
|
||||
byte[] swapped = new byte[data.Length];
|
||||
var swapped = new byte[data.Length];
|
||||
|
||||
for(long i = 0; i < swapped.Length; i += 2)
|
||||
{
|
||||
@@ -425,7 +425,7 @@ public sealed partial class Cdrdao
|
||||
data = swapped;
|
||||
}
|
||||
|
||||
uint subchannelSize = (uint)(track.SubchannelType != TrackSubchannelType.None ? 96 : 0);
|
||||
var subchannelSize = (uint)(track.SubchannelType != TrackSubchannelType.None ? 96 : 0);
|
||||
|
||||
for(uint i = 0; i < length; i++)
|
||||
{
|
||||
@@ -458,9 +458,8 @@ public sealed partial class Cdrdao
|
||||
}
|
||||
|
||||
if(_writingTracks != null && _writingStreams != null)
|
||||
{
|
||||
foreach(FileStream oldTrack in _writingStreams.Select(t => t.Value).Distinct()) oldTrack.Close();
|
||||
}
|
||||
foreach(FileStream oldTrack in _writingStreams.Select(t => t.Value).Distinct())
|
||||
oldTrack.Close();
|
||||
|
||||
ulong currentOffset = 0;
|
||||
_writingTracks = [];
|
||||
|
||||
@@ -110,7 +110,7 @@ public sealed partial class CdrWin
|
||||
Tracks = []
|
||||
};
|
||||
|
||||
int mediaTypeAsInt = (int)_discImage.MediaType;
|
||||
var mediaTypeAsInt = (int)_discImage.MediaType;
|
||||
|
||||
_isCd = mediaTypeAsInt is >= 10 and <= 39
|
||||
or 112
|
||||
@@ -168,7 +168,7 @@ public sealed partial class CdrWin
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -220,7 +220,7 @@ public sealed partial class CdrWin
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -279,7 +279,7 @@ public sealed partial class CdrWin
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -324,7 +324,7 @@ public sealed partial class CdrWin
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -393,9 +393,8 @@ public sealed partial class CdrWin
|
||||
}
|
||||
|
||||
if(_writingTracks != null && _writingStreams != null)
|
||||
{
|
||||
foreach(FileStream oldTrack in _writingStreams.Select(t => t.Value).Distinct()) oldTrack.Close();
|
||||
}
|
||||
foreach(FileStream oldTrack in _writingStreams.Select(t => t.Value).Distinct())
|
||||
oldTrack.Close();
|
||||
|
||||
_writingTracks = [];
|
||||
|
||||
@@ -459,7 +458,7 @@ public sealed partial class CdrWin
|
||||
_writingStreams.First().Value.Close();
|
||||
}
|
||||
|
||||
int currentSession = 0;
|
||||
var currentSession = 0;
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(_discImage.Comment))
|
||||
{
|
||||
|
||||
@@ -128,11 +128,11 @@ public sealed partial class CisCopy
|
||||
DiskType.MF2DD or DiskType.MD2HD or DiskType.MF2HD => 160
|
||||
};
|
||||
|
||||
int headStep = 1;
|
||||
var headStep = 1;
|
||||
|
||||
if(diskType is DiskType.MD1DD or DiskType.MD1DD8) headStep = 2;
|
||||
|
||||
for(int i = 0; i < tracks; i += headStep)
|
||||
for(var i = 0; i < tracks; i += headStep)
|
||||
{
|
||||
_writingStream.WriteByte((byte)TrackType.Copied);
|
||||
|
||||
@@ -157,7 +157,7 @@ public sealed partial class CisCopy
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -189,7 +189,7 @@ public sealed partial class CisCopy
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -221,7 +221,7 @@ public sealed partial class CisCopy
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -229,7 +229,7 @@ public sealed partial class CisCopy
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ public sealed partial class CloneCd
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -142,7 +142,7 @@ public sealed partial class CloneCd
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -158,7 +158,7 @@ public sealed partial class CloneCd
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -193,7 +193,7 @@ public sealed partial class CloneCd
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -310,7 +310,7 @@ public sealed partial class CloneCd
|
||||
// Easy, just decode the real toc
|
||||
if(_fullToc != null)
|
||||
{
|
||||
byte[] tmp = new byte[_fullToc.Length + 2];
|
||||
var tmp = new byte[_fullToc.Length + 2];
|
||||
Array.Copy(BigEndianBitConverter.GetBytes((ushort)_fullToc.Length), 0, tmp, 0, 2);
|
||||
Array.Copy(_fullToc, 0, tmp, 2, _fullToc.Length);
|
||||
nullableToc = FullTOC.Decode(tmp);
|
||||
@@ -329,7 +329,7 @@ public sealed partial class CloneCd
|
||||
|
||||
if(!string.IsNullOrEmpty(_catalog)) _descriptorStream.WriteLine("CATALOG={0}", _catalog);
|
||||
|
||||
for(int i = 1; i <= toc.LastCompleteSession; i++)
|
||||
for(var i = 1; i <= toc.LastCompleteSession; i++)
|
||||
{
|
||||
_descriptorStream.WriteLine("[Session {0}]", i);
|
||||
|
||||
@@ -365,7 +365,7 @@ public sealed partial class CloneCd
|
||||
_descriptorStream.WriteLine("PreGapSubC=0");
|
||||
}
|
||||
|
||||
for(int i = 0; i < toc.TrackDescriptors.Length; i++)
|
||||
for(var i = 0; i < toc.TrackDescriptors.Length; i++)
|
||||
{
|
||||
long alba = MsfToLba((toc.TrackDescriptors[i].Min, toc.TrackDescriptors[i].Sec,
|
||||
toc.TrackDescriptors[i].Frame));
|
||||
@@ -484,7 +484,8 @@ public sealed partial class CloneCd
|
||||
ErrorMessage = string.Format(Localization.Could_not_create_subchannel_file_exception_0,
|
||||
ex.Message);
|
||||
|
||||
AaruLogging.Exception(ex,Localization.Could_not_create_subchannel_file_exception_0,
|
||||
AaruLogging.Exception(ex,
|
||||
Localization.Could_not_create_subchannel_file_exception_0,
|
||||
ex.Message);
|
||||
|
||||
return false;
|
||||
@@ -561,7 +562,8 @@ public sealed partial class CloneCd
|
||||
ErrorMessage = string.Format(Localization.Could_not_create_subchannel_file_exception_0,
|
||||
ex.Message);
|
||||
|
||||
AaruLogging.Exception(ex,Localization.Could_not_create_subchannel_file_exception_0,
|
||||
AaruLogging.Exception(ex,
|
||||
Localization.Could_not_create_subchannel_file_exception_0,
|
||||
ex.Message);
|
||||
|
||||
return false;
|
||||
|
||||
@@ -102,7 +102,7 @@ public sealed partial class CopyTape
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!_writtenBlockPositions.TryGetValue(sectorAddress, out ulong position))
|
||||
{
|
||||
@@ -138,11 +138,11 @@ public sealed partial class CopyTape
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
for(uint i = 0; i < length; i++)
|
||||
{
|
||||
bool ret = WriteSector(data, sectorAddress + i);
|
||||
bool ret = WriteSector(data, sectorAddress + i, sectorStatus[i]);
|
||||
|
||||
if(!ret) return false;
|
||||
}
|
||||
@@ -151,7 +151,7 @@ public sealed partial class CopyTape
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Unsupported_feature;
|
||||
|
||||
@@ -159,7 +159,7 @@ public sealed partial class CopyTape
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Unsupported_feature;
|
||||
|
||||
|
||||
@@ -51,8 +51,8 @@ public sealed partial class DiskCopy42
|
||||
uint sectorSize)
|
||||
{
|
||||
header = new Header();
|
||||
bool tags = false;
|
||||
bool macosx = false;
|
||||
var tags = false;
|
||||
var macosx = false;
|
||||
|
||||
if(options != null && options.TryGetValue("macosx", out string tmpOption)) bool.TryParse(tmpOption, out macosx);
|
||||
|
||||
@@ -223,7 +223,7 @@ public sealed partial class DiskCopy42
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -255,7 +255,7 @@ public sealed partial class DiskCopy42
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -287,7 +287,7 @@ public sealed partial class DiskCopy42
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -328,7 +328,7 @@ public sealed partial class DiskCopy42
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -387,7 +387,7 @@ public sealed partial class DiskCopy42
|
||||
if(writingStream.Length == 0x54 + header.DataSize) header.TagSize = 0;
|
||||
|
||||
writingStream.Seek(0x54, SeekOrigin.Begin);
|
||||
byte[] data = new byte[header.DataSize];
|
||||
var data = new byte[header.DataSize];
|
||||
writingStream.EnsureRead(data, 0, (int)header.DataSize);
|
||||
header.DataChecksum = CheckSum(data);
|
||||
writingStream.Seek(0x54 + header.DataSize, SeekOrigin.Begin);
|
||||
|
||||
@@ -131,7 +131,7 @@ public sealed partial class DriDiskCopy
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -163,7 +163,7 @@ public sealed partial class DriDiskCopy
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -195,7 +195,7 @@ public sealed partial class DriDiskCopy
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -203,7 +203,7 @@ public sealed partial class DriDiskCopy
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -220,7 +220,7 @@ public sealed partial class DriDiskCopy
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] hdr = new byte[Marshal.SizeOf<Footer>()];
|
||||
var hdr = new byte[Marshal.SizeOf<Footer>()];
|
||||
nint hdrPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.SizeOf<Footer>());
|
||||
System.Runtime.InteropServices.Marshal.StructureToPtr(_footer, hdrPtr, true);
|
||||
System.Runtime.InteropServices.Marshal.Copy(hdrPtr, hdr, 0, hdr.Length);
|
||||
|
||||
@@ -125,7 +125,7 @@ public sealed partial class MaxiDisk
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -159,7 +159,7 @@ public sealed partial class MaxiDisk
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -193,7 +193,7 @@ public sealed partial class MaxiDisk
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -201,7 +201,7 @@ public sealed partial class MaxiDisk
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -232,7 +232,7 @@ public sealed partial class MaxiDisk
|
||||
i >>= 1;
|
||||
}
|
||||
|
||||
byte[] hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
var hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
nint hdrPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.SizeOf<Header>());
|
||||
System.Runtime.InteropServices.Marshal.StructureToPtr(header, hdrPtr, true);
|
||||
System.Runtime.InteropServices.Marshal.Copy(hdrPtr, hdr, 0, hdr.Length);
|
||||
|
||||
@@ -100,7 +100,7 @@ public sealed partial class Nhdr0
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -134,7 +134,7 @@ public sealed partial class Nhdr0
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -168,7 +168,7 @@ public sealed partial class Nhdr0
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -176,7 +176,7 @@ public sealed partial class Nhdr0
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -239,7 +239,7 @@ public sealed partial class Nhdr0
|
||||
commentBytes.Length >= 0x100 ? 0x100 : commentBytes.Length);
|
||||
}
|
||||
|
||||
byte[] hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
var hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
nint hdrPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.SizeOf<Header>());
|
||||
System.Runtime.InteropServices.Marshal.StructureToPtr(header, hdrPtr, true);
|
||||
System.Runtime.InteropServices.Marshal.Copy(hdrPtr, hdr, 0, hdr.Length);
|
||||
|
||||
@@ -92,7 +92,7 @@ public sealed partial class Parallels
|
||||
return false;
|
||||
}
|
||||
|
||||
uint batEntries = (uint)(sectors * sectorSize / DEFAULT_CLUSTER_SIZE);
|
||||
var batEntries = (uint)(sectors * sectorSize / DEFAULT_CLUSTER_SIZE);
|
||||
|
||||
if(sectors * sectorSize % DEFAULT_CLUSTER_SIZE > 0) batEntries++;
|
||||
|
||||
@@ -129,7 +129,7 @@ public sealed partial class Parallels
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -180,7 +180,7 @@ public sealed partial class Parallels
|
||||
|
||||
// TODO: This can be optimized
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -208,10 +208,10 @@ public sealed partial class Parallels
|
||||
|
||||
for(uint i = 0; i < length; i++)
|
||||
{
|
||||
byte[] tmp = new byte[512];
|
||||
var tmp = new byte[512];
|
||||
Array.Copy(data, i * 512, tmp, 0, 512);
|
||||
|
||||
if(!WriteSector(tmp, sectorAddress + i)) return false;
|
||||
if(!WriteSector(tmp, sectorAddress + i, sectorStatus[i])) return false;
|
||||
}
|
||||
|
||||
ErrorMessage = "";
|
||||
@@ -220,7 +220,7 @@ public sealed partial class Parallels
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -228,7 +228,7 @@ public sealed partial class Parallels
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -267,7 +267,7 @@ public sealed partial class Parallels
|
||||
}
|
||||
}
|
||||
|
||||
byte[] hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
var hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
nint hdrPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.SizeOf<Header>());
|
||||
System.Runtime.InteropServices.Marshal.StructureToPtr(_pHdr, hdrPtr, true);
|
||||
System.Runtime.InteropServices.Marshal.Copy(hdrPtr, hdr, 0, hdr.Length);
|
||||
|
||||
@@ -113,10 +113,10 @@ public sealed partial class Qcow
|
||||
_l1Table = new ulong[_l1Size];
|
||||
|
||||
_l1Mask = 0;
|
||||
int c = 0;
|
||||
var c = 0;
|
||||
_l1Shift = _qHdr.l2_bits + _qHdr.cluster_bits;
|
||||
|
||||
for(int i = 0; i < 64; i++)
|
||||
for(var i = 0; i < 64; i++)
|
||||
{
|
||||
_l1Mask <<= 1;
|
||||
|
||||
@@ -128,15 +128,15 @@ public sealed partial class Qcow
|
||||
|
||||
_l2Mask = 0;
|
||||
|
||||
for(int i = 0; i < _qHdr.l2_bits; i++) _l2Mask = (_l2Mask << 1) + 1;
|
||||
for(var i = 0; i < _qHdr.l2_bits; i++) _l2Mask = (_l2Mask << 1) + 1;
|
||||
|
||||
_l2Mask <<= _qHdr.cluster_bits;
|
||||
|
||||
_sectorMask = 0;
|
||||
|
||||
for(int i = 0; i < _qHdr.cluster_bits; i++) _sectorMask = (_sectorMask << 1) + 1;
|
||||
for(var i = 0; i < _qHdr.cluster_bits; i++) _sectorMask = (_sectorMask << 1) + 1;
|
||||
|
||||
byte[] empty = new byte[_qHdr.l1_table_offset + _l1Size * 8];
|
||||
var empty = new byte[_qHdr.l1_table_offset + _l1Size * 8];
|
||||
_writingStream.Write(empty, 0, empty.Length);
|
||||
|
||||
IsWriting = true;
|
||||
@@ -154,7 +154,7 @@ public sealed partial class Qcow
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -197,7 +197,7 @@ public sealed partial class Qcow
|
||||
{
|
||||
_writingStream.Seek(0, SeekOrigin.End);
|
||||
_l1Table[l1Off] = (ulong)((_writingStream.Length + _clusterSize - 1) / _clusterSize * _clusterSize);
|
||||
byte[] l2TableB = new byte[_l2Size * 8];
|
||||
var l2TableB = new byte[_l2Size * 8];
|
||||
_writingStream.Position = (long)_l1Table[l1Off];
|
||||
_writingStream.Write(l2TableB, 0, l2TableB.Length);
|
||||
}
|
||||
@@ -208,14 +208,14 @@ public sealed partial class Qcow
|
||||
|
||||
_writingStream.Seek((long)(_l1Table[l1Off] + l2Off * 8), SeekOrigin.Begin);
|
||||
|
||||
byte[] entry = new byte[8];
|
||||
var entry = new byte[8];
|
||||
_writingStream.EnsureRead(entry, 0, 8);
|
||||
ulong offset = BigEndianBitConverter.ToUInt64(entry, 0);
|
||||
var offset = BigEndianBitConverter.ToUInt64(entry, 0);
|
||||
|
||||
if(offset == 0)
|
||||
{
|
||||
offset = (ulong)_writingStream.Length;
|
||||
byte[] cluster = new byte[_clusterSize];
|
||||
var cluster = new byte[_clusterSize];
|
||||
entry = BigEndianBitConverter.GetBytes(offset);
|
||||
_writingStream.Seek((long)(_l1Table[l1Off] + l2Off * 8), SeekOrigin.Begin);
|
||||
_writingStream.Write(entry, 0, 8);
|
||||
@@ -233,7 +233,7 @@ public sealed partial class Qcow
|
||||
|
||||
// TODO: This can be optimized
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -261,10 +261,10 @@ public sealed partial class Qcow
|
||||
|
||||
for(uint i = 0; i < length; i++)
|
||||
{
|
||||
byte[] tmp = new byte[_imageInfo.SectorSize];
|
||||
var tmp = new byte[_imageInfo.SectorSize];
|
||||
Array.Copy(data, i * _imageInfo.SectorSize, tmp, 0, _imageInfo.SectorSize);
|
||||
|
||||
if(!WriteSector(tmp, sectorAddress + i)) return false;
|
||||
if(!WriteSector(tmp, sectorAddress + i, sectorStatus[i])) return false;
|
||||
}
|
||||
|
||||
ErrorMessage = "";
|
||||
@@ -273,7 +273,7 @@ public sealed partial class Qcow
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -281,7 +281,7 @@ public sealed partial class Qcow
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
|
||||
@@ -112,10 +112,10 @@ public sealed partial class Qcow2
|
||||
_l2Size = 1 << _l2Bits;
|
||||
|
||||
_l1Mask = 0;
|
||||
int c = 0;
|
||||
var c = 0;
|
||||
_l1Shift = (int)(_l2Bits + _qHdr.cluster_bits);
|
||||
|
||||
for(int i = 0; i < 64; i++)
|
||||
for(var i = 0; i < 64; i++)
|
||||
{
|
||||
_l1Mask <<= 1;
|
||||
|
||||
@@ -127,13 +127,13 @@ public sealed partial class Qcow2
|
||||
|
||||
_l2Mask = 0;
|
||||
|
||||
for(int i = 0; i < _l2Bits; i++) _l2Mask = (_l2Mask << 1) + 1;
|
||||
for(var i = 0; i < _l2Bits; i++) _l2Mask = (_l2Mask << 1) + 1;
|
||||
|
||||
_l2Mask <<= (int)_qHdr.cluster_bits;
|
||||
|
||||
_sectorMask = 0;
|
||||
|
||||
for(int i = 0; i < _qHdr.cluster_bits; i++) _sectorMask = (_sectorMask << 1) + 1;
|
||||
for(var i = 0; i < _qHdr.cluster_bits; i++) _sectorMask = (_sectorMask << 1) + 1;
|
||||
|
||||
_qHdr.l1_size = (uint)((long)_qHdr.size + (1 << _l1Shift) - 1 >> _l1Shift);
|
||||
|
||||
@@ -159,7 +159,7 @@ public sealed partial class Qcow2
|
||||
|
||||
if(l1TableClusters == 0) l1TableClusters = 1;
|
||||
|
||||
byte[] empty = new byte[_qHdr.l1_table_offset + l1TableClusters * (ulong)_clusterSize];
|
||||
var empty = new byte[_qHdr.l1_table_offset + l1TableClusters * (ulong)_clusterSize];
|
||||
_writingStream.Write(empty, 0, empty.Length);
|
||||
|
||||
IsWriting = true;
|
||||
@@ -177,7 +177,7 @@ public sealed partial class Qcow2
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -220,7 +220,7 @@ public sealed partial class Qcow2
|
||||
{
|
||||
_writingStream.Seek(0, SeekOrigin.End);
|
||||
_l1Table[l1Off] = (ulong)_writingStream.Position;
|
||||
byte[] l2TableB = new byte[_l2Size * 8];
|
||||
var l2TableB = new byte[_l2Size * 8];
|
||||
_writingStream.Seek(0, SeekOrigin.End);
|
||||
_writingStream.Write(l2TableB, 0, l2TableB.Length);
|
||||
}
|
||||
@@ -231,14 +231,14 @@ public sealed partial class Qcow2
|
||||
|
||||
_writingStream.Seek((long)(_l1Table[l1Off] + l2Off * 8), SeekOrigin.Begin);
|
||||
|
||||
byte[] entry = new byte[8];
|
||||
var entry = new byte[8];
|
||||
_writingStream.EnsureRead(entry, 0, 8);
|
||||
ulong offset = BigEndianBitConverter.ToUInt64(entry, 0);
|
||||
var offset = BigEndianBitConverter.ToUInt64(entry, 0);
|
||||
|
||||
if(offset == 0)
|
||||
{
|
||||
offset = (ulong)_writingStream.Length;
|
||||
byte[] cluster = new byte[_clusterSize];
|
||||
var cluster = new byte[_clusterSize];
|
||||
entry = BigEndianBitConverter.GetBytes(offset);
|
||||
_writingStream.Seek((long)(_l1Table[l1Off] + l2Off * 8), SeekOrigin.Begin);
|
||||
_writingStream.Write(entry, 0, 8);
|
||||
@@ -259,7 +259,7 @@ public sealed partial class Qcow2
|
||||
{
|
||||
refBlockOffset = (ulong)_writingStream.Length;
|
||||
_refCountTable[refCountTableIndex] = refBlockOffset;
|
||||
byte[] cluster = new byte[_clusterSize];
|
||||
var cluster = new byte[_clusterSize];
|
||||
_writingStream.Seek(0, SeekOrigin.End);
|
||||
_writingStream.Write(cluster, 0, cluster.Length);
|
||||
}
|
||||
@@ -275,7 +275,7 @@ public sealed partial class Qcow2
|
||||
|
||||
// TODO: This can be optimized
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -303,10 +303,10 @@ public sealed partial class Qcow2
|
||||
|
||||
for(uint i = 0; i < length; i++)
|
||||
{
|
||||
byte[] tmp = new byte[_imageInfo.SectorSize];
|
||||
var tmp = new byte[_imageInfo.SectorSize];
|
||||
Array.Copy(data, i * _imageInfo.SectorSize, tmp, 0, _imageInfo.SectorSize);
|
||||
|
||||
if(!WriteSector(tmp, sectorAddress + i)) return false;
|
||||
if(!WriteSector(tmp, sectorAddress + i, sectorStatus[i])) return false;
|
||||
}
|
||||
|
||||
ErrorMessage = "";
|
||||
@@ -315,7 +315,7 @@ public sealed partial class Qcow2
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -323,7 +323,7 @@ public sealed partial class Qcow2
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
|
||||
@@ -109,12 +109,12 @@ public sealed partial class Qed
|
||||
|
||||
_l1Table = new ulong[_tableSize];
|
||||
_l1Mask = 0;
|
||||
int c = 0;
|
||||
var c = 0;
|
||||
_clusterBits = Ctz32(_qHdr.cluster_size);
|
||||
_l2Mask = _tableSize - 1 << _clusterBits;
|
||||
_l1Shift = _clusterBits + Ctz32(_tableSize);
|
||||
|
||||
for(int i = 0; i < 64; i++)
|
||||
for(var i = 0; i < 64; i++)
|
||||
{
|
||||
_l1Mask <<= 1;
|
||||
|
||||
@@ -126,9 +126,9 @@ public sealed partial class Qed
|
||||
|
||||
_sectorMask = 0;
|
||||
|
||||
for(int i = 0; i < _clusterBits; i++) _sectorMask = (_sectorMask << 1) + 1;
|
||||
for(var i = 0; i < _clusterBits; i++) _sectorMask = (_sectorMask << 1) + 1;
|
||||
|
||||
byte[] empty = new byte[_qHdr.l1_table_offset + _tableSize * 8];
|
||||
var empty = new byte[_qHdr.l1_table_offset + _tableSize * 8];
|
||||
_writingStream.Write(empty, 0, empty.Length);
|
||||
|
||||
IsWriting = true;
|
||||
@@ -146,7 +146,7 @@ public sealed partial class Qed
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -189,7 +189,7 @@ public sealed partial class Qed
|
||||
{
|
||||
_writingStream.Seek(0, SeekOrigin.End);
|
||||
_l1Table[l1Off] = (ulong)_writingStream.Position;
|
||||
byte[] l2TableB = new byte[_tableSize * 8];
|
||||
var l2TableB = new byte[_tableSize * 8];
|
||||
_writingStream.Seek(0, SeekOrigin.End);
|
||||
_writingStream.Write(l2TableB, 0, l2TableB.Length);
|
||||
}
|
||||
@@ -200,14 +200,14 @@ public sealed partial class Qed
|
||||
|
||||
_writingStream.Seek((long)(_l1Table[l1Off] + l2Off * 8), SeekOrigin.Begin);
|
||||
|
||||
byte[] entry = new byte[8];
|
||||
var entry = new byte[8];
|
||||
_writingStream.EnsureRead(entry, 0, 8);
|
||||
ulong offset = BitConverter.ToUInt64(entry, 0);
|
||||
var offset = BitConverter.ToUInt64(entry, 0);
|
||||
|
||||
if(offset == 0)
|
||||
{
|
||||
offset = (ulong)_writingStream.Length;
|
||||
byte[] cluster = new byte[_qHdr.cluster_size];
|
||||
var cluster = new byte[_qHdr.cluster_size];
|
||||
entry = BitConverter.GetBytes(offset);
|
||||
_writingStream.Seek((long)(_l1Table[l1Off] + l2Off * 8), SeekOrigin.Begin);
|
||||
_writingStream.Write(entry, 0, 8);
|
||||
@@ -225,7 +225,7 @@ public sealed partial class Qed
|
||||
|
||||
// TODO: This can be optimized
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -253,10 +253,10 @@ public sealed partial class Qed
|
||||
|
||||
for(uint i = 0; i < length; i++)
|
||||
{
|
||||
byte[] tmp = new byte[_imageInfo.SectorSize];
|
||||
var tmp = new byte[_imageInfo.SectorSize];
|
||||
Array.Copy(data, i * _imageInfo.SectorSize, tmp, 0, _imageInfo.SectorSize);
|
||||
|
||||
if(!WriteSector(tmp, sectorAddress + i)) return false;
|
||||
if(!WriteSector(tmp, sectorAddress + i, sectorStatus[i])) return false;
|
||||
}
|
||||
|
||||
ErrorMessage = "";
|
||||
@@ -265,7 +265,7 @@ public sealed partial class Qed
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -273,7 +273,7 @@ public sealed partial class Qed
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -290,7 +290,7 @@ public sealed partial class Qed
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] hdr = new byte[Marshal.SizeOf<QedHeader>()];
|
||||
var hdr = new byte[Marshal.SizeOf<QedHeader>()];
|
||||
MemoryMarshal.Write(hdr, in _qHdr);
|
||||
|
||||
_writingStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
@@ -113,7 +113,7 @@ public sealed partial class RayDim
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -147,7 +147,7 @@ public sealed partial class RayDim
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -181,7 +181,7 @@ public sealed partial class RayDim
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -189,7 +189,7 @@ public sealed partial class RayDim
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -231,7 +231,7 @@ public sealed partial class RayDim
|
||||
return false;
|
||||
}
|
||||
|
||||
string headerSignature = $"Disk IMage VER 1.0 Copyright (C) {DateTime.Now.Year
|
||||
var headerSignature = $"Disk IMage VER 1.0 Copyright (C) {DateTime.Now.Year
|
||||
:D4} Ray Arachelian, All Rights Reserved. Aaru ";
|
||||
|
||||
var header = new Header
|
||||
@@ -245,7 +245,7 @@ public sealed partial class RayDim
|
||||
|
||||
header.signature[0x4A] = 0x00;
|
||||
|
||||
byte[] hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
var hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
nint hdrPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.SizeOf<Header>());
|
||||
System.Runtime.InteropServices.Marshal.StructureToPtr(header, hdrPtr, true);
|
||||
System.Runtime.InteropServices.Marshal.Copy(hdrPtr, hdr, 0, hdr.Length);
|
||||
|
||||
@@ -123,7 +123,7 @@ public sealed partial class RsIde
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -157,7 +157,7 @@ public sealed partial class RsIde
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -191,7 +191,7 @@ public sealed partial class RsIde
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -199,7 +199,7 @@ public sealed partial class RsIde
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -285,7 +285,7 @@ public sealed partial class RsIde
|
||||
if(string.IsNullOrEmpty(_imageInfo.DriveSerialNumber))
|
||||
_imageInfo.DriveSerialNumber = $"{new Random().NextDouble():16X}";
|
||||
|
||||
byte[] ataIdBytes = new byte[Marshal.SizeOf<Identify.IdentifyDevice>()];
|
||||
var ataIdBytes = new byte[Marshal.SizeOf<Identify.IdentifyDevice>()];
|
||||
nint ptr = System.Runtime.InteropServices.Marshal.AllocHGlobal(512);
|
||||
System.Runtime.InteropServices.Marshal.StructureToPtr(ataId, ptr, true);
|
||||
|
||||
@@ -306,7 +306,7 @@ public sealed partial class RsIde
|
||||
else
|
||||
Array.Copy(_identify, 0, header.identify, 0, 106);
|
||||
|
||||
byte[] hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
var hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
nint hdrPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.SizeOf<Header>());
|
||||
System.Runtime.InteropServices.Marshal.StructureToPtr(header, hdrPtr, true);
|
||||
System.Runtime.InteropServices.Marshal.Copy(hdrPtr, hdr, 0, hdr.Length);
|
||||
|
||||
@@ -56,7 +56,7 @@ public sealed partial class SaveDskF
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -88,7 +88,7 @@ public sealed partial class SaveDskF
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -120,7 +120,7 @@ public sealed partial class SaveDskF
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -128,7 +128,7 @@ public sealed partial class SaveDskF
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -158,7 +158,7 @@ public sealed partial class SaveDskF
|
||||
: commentsBytes.Length);
|
||||
}
|
||||
|
||||
byte[] hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
var hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
nint hdrPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.SizeOf<Header>());
|
||||
System.Runtime.InteropServices.Marshal.StructureToPtr(_header, hdrPtr, true);
|
||||
System.Runtime.InteropServices.Marshal.Copy(hdrPtr, hdr, 0, hdr.Length);
|
||||
|
||||
@@ -101,9 +101,9 @@ public sealed partial class SuperCardPro
|
||||
|
||||
List<byte> scpData = FluxRepresentationsToUInt16List(dataBuffer, scpIndices, out uint[] trackLengths);
|
||||
|
||||
uint offset = (uint)(4 + 12 * Header.revolutions);
|
||||
var offset = (uint)(4 + 12 * Header.revolutions);
|
||||
|
||||
for(int i = 0; i < Header.revolutions; i++)
|
||||
for(var i = 0; i < Header.revolutions; i++)
|
||||
{
|
||||
_writingStream.Write(BitConverter.GetBytes(scpIndices[i]), 0, 4);
|
||||
_writingStream.Write(BitConverter.GetBytes(trackLengths[i]), 0, 4);
|
||||
@@ -179,7 +179,7 @@ public sealed partial class SuperCardPro
|
||||
_writingStream.WriteByte(Header.resolution);
|
||||
|
||||
_writingStream.Seek(0, SeekOrigin.End);
|
||||
string date = DateTime.Now.ToString("G");
|
||||
var date = DateTime.Now.ToString("G");
|
||||
_writingStream.Write(Encoding.ASCII.GetBytes(date), 0, date.Length);
|
||||
|
||||
Header.checksum = CalculateChecksum(_writingStream);
|
||||
@@ -207,14 +207,14 @@ public sealed partial class SuperCardPro
|
||||
|
||||
public bool WriteMediaTag(byte[] data, MediaTagType tag) => false;
|
||||
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Flux_decoding_is_not_yet_implemented;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Flux_decoding_is_not_yet_implemented;
|
||||
|
||||
@@ -222,7 +222,7 @@ public sealed partial class SuperCardPro
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Flux_decoding_is_not_yet_implemented;
|
||||
|
||||
@@ -230,7 +230,7 @@ public sealed partial class SuperCardPro
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Flux_decoding_is_not_yet_implemented;
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ public sealed partial class T98
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -132,7 +132,7 @@ public sealed partial class T98
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -164,7 +164,7 @@ public sealed partial class T98
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -172,7 +172,7 @@ public sealed partial class T98
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -189,7 +189,7 @@ public sealed partial class T98
|
||||
return false;
|
||||
}
|
||||
|
||||
int cylinders = (int)(_imageInfo.Sectors / 33 / 8);
|
||||
var cylinders = (int)(_imageInfo.Sectors / 33 / 8);
|
||||
_writingStream.Seek(0, SeekOrigin.Begin);
|
||||
_writingStream.Write(BitConverter.GetBytes(cylinders), 0, 4);
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ public sealed partial class Udif
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -179,7 +179,7 @@ public sealed partial class Udif
|
||||
|
||||
// TODO: This can be optimized
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -227,10 +227,10 @@ public sealed partial class Udif
|
||||
|
||||
for(uint i = 0; i < length; i++)
|
||||
{
|
||||
byte[] tmp = new byte[_imageInfo.SectorSize];
|
||||
var tmp = new byte[_imageInfo.SectorSize];
|
||||
Array.Copy(data, i * _imageInfo.SectorSize, tmp, 0, _imageInfo.SectorSize);
|
||||
|
||||
if(!WriteSector(tmp, sectorAddress + i)) return false;
|
||||
if(!WriteSector(tmp, sectorAddress + i, sectorStatus[i])) return false;
|
||||
}
|
||||
|
||||
ErrorMessage = "";
|
||||
@@ -239,7 +239,7 @@ public sealed partial class Udif
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -247,7 +247,7 @@ public sealed partial class Udif
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ public sealed partial class Vdi
|
||||
return false;
|
||||
}
|
||||
|
||||
uint ibmEntries = (uint)(sectors * sectorSize / DEFAULT_BLOCK_SIZE);
|
||||
var ibmEntries = (uint)(sectors * sectorSize / DEFAULT_BLOCK_SIZE);
|
||||
|
||||
if(sectors * sectorSize % DEFAULT_BLOCK_SIZE > 0) ibmEntries++;
|
||||
|
||||
@@ -139,7 +139,7 @@ public sealed partial class Vdi
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -191,7 +191,7 @@ public sealed partial class Vdi
|
||||
|
||||
// TODO: This can be optimized
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -219,10 +219,10 @@ public sealed partial class Vdi
|
||||
|
||||
for(uint i = 0; i < length; i++)
|
||||
{
|
||||
byte[] tmp = new byte[_imageInfo.SectorSize];
|
||||
var tmp = new byte[_imageInfo.SectorSize];
|
||||
Array.Copy(data, i * _imageInfo.SectorSize, tmp, 0, _imageInfo.SectorSize);
|
||||
|
||||
if(!WriteSector(tmp, sectorAddress + i)) return false;
|
||||
if(!WriteSector(tmp, sectorAddress + i, sectorStatus[i])) return false;
|
||||
}
|
||||
|
||||
ErrorMessage = "";
|
||||
@@ -231,7 +231,7 @@ public sealed partial class Vdi
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -239,7 +239,7 @@ public sealed partial class Vdi
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -281,7 +281,7 @@ public sealed partial class Vdi
|
||||
}
|
||||
}
|
||||
|
||||
byte[] hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
var hdr = new byte[Marshal.SizeOf<Header>()];
|
||||
nint hdrPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.SizeOf<Header>());
|
||||
System.Runtime.InteropServices.Marshal.StructureToPtr(_vHdr, hdrPtr, true);
|
||||
System.Runtime.InteropServices.Marshal.Copy(hdrPtr, hdr, 0, hdr.Length);
|
||||
|
||||
@@ -49,6 +49,126 @@ namespace Aaru.Images;
|
||||
|
||||
public sealed partial class Vhd
|
||||
{
|
||||
void SetChsInFooter()
|
||||
{
|
||||
if(_imageInfo.Cylinders == 0)
|
||||
{
|
||||
ulong cylinderTimesHeads;
|
||||
|
||||
if(_imageInfo.Sectors > 65535 * 16 * 255)
|
||||
{
|
||||
_imageInfo.Cylinders = 65535;
|
||||
_imageInfo.Heads = 16;
|
||||
_imageInfo.SectorsPerTrack = 255;
|
||||
}
|
||||
|
||||
if(_imageInfo.Sectors >= 65535 * 16 * 63)
|
||||
{
|
||||
_imageInfo.Heads = 16;
|
||||
_imageInfo.SectorsPerTrack = 255;
|
||||
cylinderTimesHeads = _imageInfo.Sectors / _imageInfo.SectorsPerTrack;
|
||||
}
|
||||
else
|
||||
{
|
||||
_imageInfo.SectorsPerTrack = 17;
|
||||
cylinderTimesHeads = _imageInfo.Sectors / _imageInfo.SectorsPerTrack;
|
||||
|
||||
_imageInfo.Heads = (uint)((cylinderTimesHeads + 1023) / 1024);
|
||||
|
||||
if(_imageInfo.Heads < 4) _imageInfo.Heads = 4;
|
||||
|
||||
if(cylinderTimesHeads >= _imageInfo.Heads * 1024 || _imageInfo.Heads > 16)
|
||||
{
|
||||
_imageInfo.SectorsPerTrack = 31;
|
||||
_imageInfo.Heads = 16;
|
||||
cylinderTimesHeads = _imageInfo.Sectors / _imageInfo.SectorsPerTrack;
|
||||
}
|
||||
|
||||
if(cylinderTimesHeads >= _imageInfo.Heads * 1024)
|
||||
{
|
||||
_imageInfo.SectorsPerTrack = 63;
|
||||
_imageInfo.Heads = 16;
|
||||
cylinderTimesHeads = _imageInfo.Sectors / _imageInfo.SectorsPerTrack;
|
||||
}
|
||||
}
|
||||
|
||||
_imageInfo.Cylinders = (uint)(cylinderTimesHeads / _imageInfo.Heads);
|
||||
}
|
||||
|
||||
_thisFooter.DiskGeometry = ((_imageInfo.Cylinders & 0xFFFF) << 16) +
|
||||
((_imageInfo.Heads & 0xFF) << 8) +
|
||||
(_imageInfo.SectorsPerTrack & 0xFF);
|
||||
}
|
||||
|
||||
void Flush()
|
||||
{
|
||||
_thisFooter.Offset = _thisFooter.DiskType == TYPE_FIXED ? ulong.MaxValue : 512;
|
||||
|
||||
var footerBytes = new byte[512];
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.Cookie), 0, footerBytes, 0x00, 8);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.Features), 0, footerBytes, 0x08, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.Version), 0, footerBytes, 0x0C, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.Offset), 0, footerBytes, 0x10, 8);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.Timestamp), 0, footerBytes, 0x18, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.CreatorApplication), 0, footerBytes, 0x1C, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.CreatorVersion), 0, footerBytes, 0x20, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.CreatorHostOs), 0, footerBytes, 0x24, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.OriginalSize), 0, footerBytes, 0x28, 8);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.CurrentSize), 0, footerBytes, 0x30, 8);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.DiskGeometry), 0, footerBytes, 0x38, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.DiskType), 0, footerBytes, 0x3C, 4);
|
||||
Array.Copy(_thisFooter.UniqueId.ToByteArray(), 0, footerBytes, 0x44, 4);
|
||||
|
||||
_thisFooter.Checksum = VhdChecksum(footerBytes);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.Checksum), 0, footerBytes, 0x40, 4);
|
||||
|
||||
if(!_dynamic)
|
||||
{
|
||||
_writingStream.Seek((long)_thisFooter.OriginalSize, SeekOrigin.Begin);
|
||||
_writingStream.Write(footerBytes, 0, 512);
|
||||
|
||||
_writingStream.Flush();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(_blockInCache)
|
||||
{
|
||||
_writingStream.Position = _cachedBlockPosition;
|
||||
_writingStream.Write(_cachedBlock, 0, _cachedBlock.Length);
|
||||
_cachedBlock = null;
|
||||
_blockInCache = false;
|
||||
}
|
||||
|
||||
_writingStream.Position = (long)_thisDynamic.TableOffset;
|
||||
ReadOnlySpan<uint> span = _blockAllocationTable;
|
||||
|
||||
byte[] bat = MemoryMarshal.Cast<uint, byte>(span)[..(int)(_thisDynamic.MaxTableEntries * sizeof(uint))]
|
||||
.ToArray();
|
||||
|
||||
_writingStream.Write(bat, 0, bat.Length);
|
||||
|
||||
var dynamicBytes = new byte[1024];
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisDynamic.Cookie), 0, dynamicBytes, 0x00, 8);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisDynamic.DataOffset), 0, dynamicBytes, 0x08, 8);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisDynamic.TableOffset), 0, dynamicBytes, 0x10, 8);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisDynamic.HeaderVersion), 0, dynamicBytes, 0x18, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisDynamic.MaxTableEntries), 0, dynamicBytes, 0x1C, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisDynamic.BlockSize), 0, dynamicBytes, 0x20, 4);
|
||||
|
||||
_thisDynamic.Checksum = VhdChecksum(dynamicBytes);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisDynamic.Checksum), 0, dynamicBytes, 0x24, 4);
|
||||
|
||||
_writingStream.Position = 0;
|
||||
_writingStream.Write(footerBytes, 0, 512);
|
||||
_writingStream.Position = 512;
|
||||
_writingStream.Write(dynamicBytes, 0, 1024);
|
||||
_writingStream.Position = _currentFooterPosition;
|
||||
_writingStream.Write(footerBytes, 0, 512);
|
||||
|
||||
_writingStream.Flush();
|
||||
}
|
||||
|
||||
#region IWritableImage Members
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -202,7 +322,7 @@ public sealed partial class Vhd
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -236,7 +356,7 @@ public sealed partial class Vhd
|
||||
}
|
||||
|
||||
// Block number for BAT searching
|
||||
uint blockNumber = (uint)Math.Floor(sectorAddress / (_thisDynamic.BlockSize / 512.0));
|
||||
var blockNumber = (uint)Math.Floor(sectorAddress / (_thisDynamic.BlockSize / 512.0));
|
||||
|
||||
// If there's a cached block and it's the one we're looking for, flush cached data (clears cache)
|
||||
if(_blockInCache && _cachedBlockNumber != blockNumber) Flush();
|
||||
@@ -269,10 +389,10 @@ public sealed partial class Vhd
|
||||
}
|
||||
|
||||
// Sector number inside of block
|
||||
uint sectorInBlock = (uint)(sectorAddress % (_thisDynamic.BlockSize / 512));
|
||||
int bitmapByte = (int)Math.Floor((double)sectorInBlock / 8);
|
||||
int bitmapBit = (int)(sectorInBlock % 8);
|
||||
byte mask = (byte)(1 << 7 - bitmapBit);
|
||||
var sectorInBlock = (uint)(sectorAddress % (_thisDynamic.BlockSize / 512));
|
||||
var bitmapByte = (int)Math.Floor((double)sectorInBlock / 8);
|
||||
var bitmapBit = (int)(sectorInBlock % 8);
|
||||
var mask = (byte)(1 << 7 - bitmapBit);
|
||||
bool dirty = (_cachedBlock[bitmapByte] & mask) == mask;
|
||||
|
||||
// If there's no data in sector...
|
||||
@@ -304,16 +424,16 @@ public sealed partial class Vhd
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(_dynamic)
|
||||
{
|
||||
if(ArrayHelpers.ArrayIsNullOrEmpty(data))
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
for(var i = 0; i < length; i++)
|
||||
{
|
||||
// Block number for BAT searching
|
||||
uint blockNumber = (uint)Math.Floor(sectorAddress / (_thisDynamic.BlockSize / 512.0));
|
||||
var blockNumber = (uint)Math.Floor(sectorAddress / (_thisDynamic.BlockSize / 512.0));
|
||||
|
||||
// Block not allocated, bail out
|
||||
if(_blockAllocationTable[blockNumber] == 0xFFFFFFFF) continue;
|
||||
@@ -330,10 +450,10 @@ public sealed partial class Vhd
|
||||
}
|
||||
|
||||
// Sector number inside of block
|
||||
uint sectorInBlock = (uint)(sectorAddress % (_thisDynamic.BlockSize / 512));
|
||||
int bitmapByte = (int)Math.Floor((double)sectorInBlock / 8);
|
||||
int bitmapBit = (int)(sectorInBlock % 8);
|
||||
byte mask = (byte)(1 << 7 - bitmapBit);
|
||||
var sectorInBlock = (uint)(sectorAddress % (_thisDynamic.BlockSize / 512));
|
||||
var bitmapByte = (int)Math.Floor((double)sectorInBlock / 8);
|
||||
var bitmapBit = (int)(sectorInBlock % 8);
|
||||
var mask = (byte)(1 << 7 - bitmapBit);
|
||||
bool dirty = (_cachedBlock[bitmapByte] & mask) == mask;
|
||||
|
||||
if(!dirty) continue;
|
||||
@@ -351,10 +471,9 @@ public sealed partial class Vhd
|
||||
return true;
|
||||
}
|
||||
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
if(!WriteSector(data[(i * 512)..(i * 512 + 512)], sectorAddress + (ulong)i)) return false;
|
||||
}
|
||||
for(var i = 0; i < length; i++)
|
||||
if(!WriteSector(data[(i * 512)..(i * 512 + 512)], sectorAddress + (ulong)i, sectorStatus[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -389,7 +508,7 @@ public sealed partial class Vhd
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -397,7 +516,7 @@ public sealed partial class Vhd
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -484,124 +603,4 @@ public sealed partial class Vhd
|
||||
public bool SetMetadata(Metadata metadata) => false;
|
||||
|
||||
#endregion
|
||||
|
||||
void SetChsInFooter()
|
||||
{
|
||||
if(_imageInfo.Cylinders == 0)
|
||||
{
|
||||
ulong cylinderTimesHeads;
|
||||
|
||||
if(_imageInfo.Sectors > 65535 * 16 * 255)
|
||||
{
|
||||
_imageInfo.Cylinders = 65535;
|
||||
_imageInfo.Heads = 16;
|
||||
_imageInfo.SectorsPerTrack = 255;
|
||||
}
|
||||
|
||||
if(_imageInfo.Sectors >= 65535 * 16 * 63)
|
||||
{
|
||||
_imageInfo.Heads = 16;
|
||||
_imageInfo.SectorsPerTrack = 255;
|
||||
cylinderTimesHeads = _imageInfo.Sectors / _imageInfo.SectorsPerTrack;
|
||||
}
|
||||
else
|
||||
{
|
||||
_imageInfo.SectorsPerTrack = 17;
|
||||
cylinderTimesHeads = _imageInfo.Sectors / _imageInfo.SectorsPerTrack;
|
||||
|
||||
_imageInfo.Heads = (uint)((cylinderTimesHeads + 1023) / 1024);
|
||||
|
||||
if(_imageInfo.Heads < 4) _imageInfo.Heads = 4;
|
||||
|
||||
if(cylinderTimesHeads >= _imageInfo.Heads * 1024 || _imageInfo.Heads > 16)
|
||||
{
|
||||
_imageInfo.SectorsPerTrack = 31;
|
||||
_imageInfo.Heads = 16;
|
||||
cylinderTimesHeads = _imageInfo.Sectors / _imageInfo.SectorsPerTrack;
|
||||
}
|
||||
|
||||
if(cylinderTimesHeads >= _imageInfo.Heads * 1024)
|
||||
{
|
||||
_imageInfo.SectorsPerTrack = 63;
|
||||
_imageInfo.Heads = 16;
|
||||
cylinderTimesHeads = _imageInfo.Sectors / _imageInfo.SectorsPerTrack;
|
||||
}
|
||||
}
|
||||
|
||||
_imageInfo.Cylinders = (uint)(cylinderTimesHeads / _imageInfo.Heads);
|
||||
}
|
||||
|
||||
_thisFooter.DiskGeometry = ((_imageInfo.Cylinders & 0xFFFF) << 16) +
|
||||
((_imageInfo.Heads & 0xFF) << 8) +
|
||||
(_imageInfo.SectorsPerTrack & 0xFF);
|
||||
}
|
||||
|
||||
void Flush()
|
||||
{
|
||||
_thisFooter.Offset = _thisFooter.DiskType == TYPE_FIXED ? ulong.MaxValue : 512;
|
||||
|
||||
byte[] footerBytes = new byte[512];
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.Cookie), 0, footerBytes, 0x00, 8);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.Features), 0, footerBytes, 0x08, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.Version), 0, footerBytes, 0x0C, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.Offset), 0, footerBytes, 0x10, 8);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.Timestamp), 0, footerBytes, 0x18, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.CreatorApplication), 0, footerBytes, 0x1C, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.CreatorVersion), 0, footerBytes, 0x20, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.CreatorHostOs), 0, footerBytes, 0x24, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.OriginalSize), 0, footerBytes, 0x28, 8);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.CurrentSize), 0, footerBytes, 0x30, 8);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.DiskGeometry), 0, footerBytes, 0x38, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.DiskType), 0, footerBytes, 0x3C, 4);
|
||||
Array.Copy(_thisFooter.UniqueId.ToByteArray(), 0, footerBytes, 0x44, 4);
|
||||
|
||||
_thisFooter.Checksum = VhdChecksum(footerBytes);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisFooter.Checksum), 0, footerBytes, 0x40, 4);
|
||||
|
||||
if(!_dynamic)
|
||||
{
|
||||
_writingStream.Seek((long)_thisFooter.OriginalSize, SeekOrigin.Begin);
|
||||
_writingStream.Write(footerBytes, 0, 512);
|
||||
|
||||
_writingStream.Flush();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(_blockInCache)
|
||||
{
|
||||
_writingStream.Position = _cachedBlockPosition;
|
||||
_writingStream.Write(_cachedBlock, 0, _cachedBlock.Length);
|
||||
_cachedBlock = null;
|
||||
_blockInCache = false;
|
||||
}
|
||||
|
||||
_writingStream.Position = (long)_thisDynamic.TableOffset;
|
||||
ReadOnlySpan<uint> span = _blockAllocationTable;
|
||||
|
||||
byte[] bat = MemoryMarshal.Cast<uint, byte>(span)[..(int)(_thisDynamic.MaxTableEntries * sizeof(uint))]
|
||||
.ToArray();
|
||||
|
||||
_writingStream.Write(bat, 0, bat.Length);
|
||||
|
||||
byte[] dynamicBytes = new byte[1024];
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisDynamic.Cookie), 0, dynamicBytes, 0x00, 8);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisDynamic.DataOffset), 0, dynamicBytes, 0x08, 8);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisDynamic.TableOffset), 0, dynamicBytes, 0x10, 8);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisDynamic.HeaderVersion), 0, dynamicBytes, 0x18, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisDynamic.MaxTableEntries), 0, dynamicBytes, 0x1C, 4);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisDynamic.BlockSize), 0, dynamicBytes, 0x20, 4);
|
||||
|
||||
_thisDynamic.Checksum = VhdChecksum(dynamicBytes);
|
||||
Array.Copy(BigEndianBitConverter.GetBytes(_thisDynamic.Checksum), 0, dynamicBytes, 0x24, 4);
|
||||
|
||||
_writingStream.Position = 0;
|
||||
_writingStream.Write(footerBytes, 0, 512);
|
||||
_writingStream.Position = 512;
|
||||
_writingStream.Write(dynamicBytes, 0, 1024);
|
||||
_writingStream.Position = _currentFooterPosition;
|
||||
_writingStream.Write(footerBytes, 0, 512);
|
||||
|
||||
_writingStream.Flush();
|
||||
}
|
||||
}
|
||||
@@ -184,7 +184,7 @@ public sealed partial class VMware
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -217,7 +217,7 @@ public sealed partial class VMware
|
||||
|
||||
// TODO: Implement sparse and split
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -249,7 +249,7 @@ public sealed partial class VMware
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -257,7 +257,7 @@ public sealed partial class VMware
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ public sealed partial class Virtual98
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -139,7 +139,7 @@ public sealed partial class Virtual98
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -171,7 +171,7 @@ public sealed partial class Virtual98
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -179,7 +179,7 @@ public sealed partial class Virtual98
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -238,7 +238,7 @@ public sealed partial class Virtual98
|
||||
if(commentsBytes != null)
|
||||
Array.Copy(commentsBytes, 0, _v98Hdr.comment, 0, commentsBytes.Length >= 128 ? 128 : commentsBytes.Length);
|
||||
|
||||
byte[] hdr = new byte[Marshal.SizeOf<Virtual98Header>()];
|
||||
var hdr = new byte[Marshal.SizeOf<Virtual98Header>()];
|
||||
nint hdrPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.SizeOf<Virtual98Header>());
|
||||
System.Runtime.InteropServices.Marshal.StructureToPtr(_v98Hdr, hdrPtr, true);
|
||||
System.Runtime.InteropServices.Marshal.Copy(hdrPtr, hdr, 0, hdr.Length);
|
||||
|
||||
@@ -157,7 +157,7 @@ public sealed partial class ZZZRawImage
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSector(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -189,7 +189,7 @@ public sealed partial class ZZZRawImage
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectors(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
if(!IsWriting)
|
||||
{
|
||||
@@ -221,7 +221,7 @@ public sealed partial class ZZZRawImage
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress, SectorStatus sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
@@ -229,7 +229,7 @@ public sealed partial class ZZZRawImage
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length, SectorStatus[] sectorStatus)
|
||||
{
|
||||
ErrorMessage = Localization.Writing_sectors_with_tags_is_not_supported;
|
||||
|
||||
|
||||
@@ -150,23 +150,30 @@ public abstract class OpticalImageConvertIssueTest
|
||||
|
||||
var useNotLong = false;
|
||||
var result = false;
|
||||
SectorStatus sectorStatus = SectorStatus.NotDumped;
|
||||
var sectorStatuses = new SectorStatus[1];
|
||||
|
||||
if(UseLong)
|
||||
{
|
||||
errno = sectorsToDo == 1
|
||||
? inputFormat.ReadSectorLong(doneSectors + track.StartSector, out sector, out _)
|
||||
? inputFormat.ReadSectorLong(doneSectors + track.StartSector,
|
||||
out sector,
|
||||
out sectorStatus)
|
||||
: inputFormat.ReadSectorsLong(doneSectors + track.StartSector,
|
||||
sectorsToDo,
|
||||
out sector,
|
||||
out _);
|
||||
out sectorStatuses);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
result = sectorsToDo == 1
|
||||
? outputOptical.WriteSectorLong(sector, doneSectors + track.StartSector)
|
||||
? outputOptical.WriteSectorLong(sector,
|
||||
doneSectors + track.StartSector,
|
||||
sectorStatus)
|
||||
: outputOptical.WriteSectorsLong(sector,
|
||||
doneSectors + track.StartSector,
|
||||
sectorsToDo);
|
||||
sectorsToDo,
|
||||
sectorStatuses);
|
||||
}
|
||||
else
|
||||
result = true;
|
||||
@@ -177,17 +184,20 @@ public abstract class OpticalImageConvertIssueTest
|
||||
if(!UseLong || useNotLong)
|
||||
{
|
||||
errno = sectorsToDo == 1
|
||||
? inputFormat.ReadSector(doneSectors + track.StartSector, out sector, out _)
|
||||
? inputFormat.ReadSector(doneSectors + track.StartSector, out sector, out sectorStatus)
|
||||
: inputFormat.ReadSectors(doneSectors + track.StartSector,
|
||||
sectorsToDo,
|
||||
out sector,
|
||||
out _);
|
||||
out sectorStatuses);
|
||||
|
||||
Assert.That(errno, Is.EqualTo(ErrorNumber.NoError));
|
||||
|
||||
result = sectorsToDo == 1
|
||||
? outputOptical.WriteSector(sector, doneSectors + track.StartSector)
|
||||
: outputOptical.WriteSectors(sector, doneSectors + track.StartSector, sectorsToDo);
|
||||
? outputOptical.WriteSector(sector, doneSectors + track.StartSector, sectorStatus)
|
||||
: outputOptical.WriteSectors(sector,
|
||||
doneSectors + track.StartSector,
|
||||
sectorsToDo,
|
||||
sectorStatuses);
|
||||
}
|
||||
|
||||
Assert.That(result,
|
||||
|
||||
@@ -242,23 +242,30 @@ public abstract class WritableOpticalMediaImageTest : BaseWritableMediaImageTest
|
||||
|
||||
var useNotLong = false;
|
||||
var result = false;
|
||||
SectorStatus sectorStatus = SectorStatus.NotDumped;
|
||||
var sectorStatusArray = new SectorStatus[1];
|
||||
|
||||
if(useLong)
|
||||
{
|
||||
errno = sectorsToDo == 1
|
||||
? inputFormat.ReadSectorLong(doneSectors + track.StartSector, out sector, out _)
|
||||
? inputFormat.ReadSectorLong(doneSectors + track.StartSector,
|
||||
out sector,
|
||||
out sectorStatus)
|
||||
: inputFormat.ReadSectorsLong(doneSectors + track.StartSector,
|
||||
sectorsToDo,
|
||||
out sector,
|
||||
out _);
|
||||
out sectorStatusArray);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
result = sectorsToDo == 1
|
||||
? outputFormat.WriteSectorLong(sector, doneSectors + track.StartSector)
|
||||
? outputFormat.WriteSectorLong(sector,
|
||||
doneSectors + track.StartSector,
|
||||
sectorStatus)
|
||||
: outputFormat.WriteSectorsLong(sector,
|
||||
doneSectors + track.StartSector,
|
||||
sectorsToDo);
|
||||
sectorsToDo,
|
||||
sectorStatusArray);
|
||||
}
|
||||
else
|
||||
result = false;
|
||||
@@ -269,19 +276,24 @@ public abstract class WritableOpticalMediaImageTest : BaseWritableMediaImageTest
|
||||
if(!useLong || useNotLong)
|
||||
{
|
||||
errno = sectorsToDo == 1
|
||||
? inputFormat.ReadSector(doneSectors + track.StartSector, out sector, out _)
|
||||
? inputFormat.ReadSector(doneSectors + track.StartSector,
|
||||
out sector,
|
||||
out sectorStatus)
|
||||
: inputFormat.ReadSectors(doneSectors + track.StartSector,
|
||||
sectorsToDo,
|
||||
out sector,
|
||||
out _);
|
||||
out sectorStatusArray);
|
||||
|
||||
Assert.That(errno, Is.EqualTo(ErrorNumber.NoError));
|
||||
|
||||
result = sectorsToDo == 1
|
||||
? outputFormat.WriteSector(sector, doneSectors + track.StartSector)
|
||||
? outputFormat.WriteSector(sector,
|
||||
doneSectors + track.StartSector,
|
||||
sectorStatus)
|
||||
: outputFormat.WriteSectors(sector,
|
||||
doneSectors + track.StartSector,
|
||||
sectorsToDo);
|
||||
sectorsToDo,
|
||||
sectorStatusArray);
|
||||
}
|
||||
|
||||
Assert.That(result,
|
||||
|
||||
@@ -702,26 +702,30 @@ sealed class ConvertImageCommand : Command<ConvertImageCommand.Settings>
|
||||
|
||||
var useNotLong = false;
|
||||
var result = false;
|
||||
SectorStatus sectorStatus = SectorStatus.NotDumped;
|
||||
var sectorStatusArray = new SectorStatus[1];
|
||||
|
||||
if(useLong)
|
||||
{
|
||||
errno = sectorsToDo == 1
|
||||
? inputOptical.ReadSectorLong(doneSectors + track.StartSector,
|
||||
out sector,
|
||||
out _)
|
||||
out sectorStatus)
|
||||
: inputOptical.ReadSectorsLong(doneSectors + track.StartSector,
|
||||
sectorsToDo,
|
||||
out sector,
|
||||
out _);
|
||||
out sectorStatusArray);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
result = sectorsToDo == 1
|
||||
? outputOptical.WriteSectorLong(sector,
|
||||
doneSectors + track.StartSector)
|
||||
doneSectors + track.StartSector,
|
||||
sectorStatus)
|
||||
: outputOptical.WriteSectorsLong(sector,
|
||||
doneSectors + track.StartSector,
|
||||
sectorsToDo);
|
||||
sectorsToDo,
|
||||
sectorStatusArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -766,11 +770,11 @@ sealed class ConvertImageCommand : Command<ConvertImageCommand.Settings>
|
||||
errno = sectorsToDo == 1
|
||||
? inputOptical.ReadSector(doneSectors + track.StartSector,
|
||||
out sector,
|
||||
out _)
|
||||
out sectorStatus)
|
||||
: inputOptical.ReadSectors(doneSectors + track.StartSector,
|
||||
sectorsToDo,
|
||||
out sector,
|
||||
out _);
|
||||
out sectorStatusArray);
|
||||
|
||||
// TODO: Move to generic place when anything but CSS DVDs can be decrypted
|
||||
if(inputOptical.Info.MediaType is MediaType.DVDROM
|
||||
@@ -907,10 +911,12 @@ sealed class ConvertImageCommand : Command<ConvertImageCommand.Settings>
|
||||
{
|
||||
result = sectorsToDo == 1
|
||||
? outputOptical.WriteSector(sector,
|
||||
doneSectors + track.StartSector)
|
||||
doneSectors + track.StartSector,
|
||||
sectorStatus)
|
||||
: outputOptical.WriteSectors(sector,
|
||||
doneSectors + track.StartSector,
|
||||
sectorsToDo);
|
||||
sectorsToDo,
|
||||
sectorStatusArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1434,21 +1440,26 @@ sealed class ConvertImageCommand : Command<ConvertImageCommand.Settings>
|
||||
string.Format(UI.Converting_sectors_0_to_1, doneSectors, doneSectors + sectorsToDo);
|
||||
|
||||
bool result;
|
||||
SectorStatus sectorStatus = SectorStatus.NotDumped;
|
||||
var sectorStatusArray = new SectorStatus[1];
|
||||
|
||||
if(useLong)
|
||||
{
|
||||
errno = sectorsToDo == 1
|
||||
? inputFormat.ReadSectorLong(doneSectors, out sector, out _)
|
||||
? inputFormat.ReadSectorLong(doneSectors, out sector, out sectorStatus)
|
||||
: inputFormat.ReadSectorsLong(doneSectors,
|
||||
sectorsToDo,
|
||||
out sector,
|
||||
out _);
|
||||
out sectorStatusArray);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
result = sectorsToDo == 1
|
||||
? outputMedia.WriteSectorLong(sector, doneSectors)
|
||||
: outputMedia.WriteSectorsLong(sector, doneSectors, sectorsToDo);
|
||||
? outputMedia.WriteSectorLong(sector, doneSectors, sectorStatus)
|
||||
: outputMedia.WriteSectorsLong(sector,
|
||||
doneSectors,
|
||||
sectorsToDo,
|
||||
sectorStatusArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1473,14 +1484,20 @@ sealed class ConvertImageCommand : Command<ConvertImageCommand.Settings>
|
||||
else
|
||||
{
|
||||
errno = sectorsToDo == 1
|
||||
? inputFormat.ReadSector(doneSectors, out sector, out _)
|
||||
: inputFormat.ReadSectors(doneSectors, sectorsToDo, out sector, out _);
|
||||
? inputFormat.ReadSector(doneSectors, out sector, out sectorStatus)
|
||||
: inputFormat.ReadSectors(doneSectors,
|
||||
sectorsToDo,
|
||||
out sector,
|
||||
out sectorStatusArray);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
result = sectorsToDo == 1
|
||||
? outputMedia.WriteSector(sector, doneSectors)
|
||||
: outputMedia.WriteSectors(sector, doneSectors, sectorsToDo);
|
||||
? outputMedia.WriteSector(sector, doneSectors, sectorStatus)
|
||||
: outputMedia.WriteSectors(sector,
|
||||
doneSectors,
|
||||
sectorsToDo,
|
||||
sectorStatusArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user