|
|
|
|
@@ -30,6 +30,8 @@
|
|
|
|
|
// Copyright © 2011-2022 Natalia Portillo
|
|
|
|
|
// ****************************************************************************/
|
|
|
|
|
|
|
|
|
|
namespace Aaru.DiscImages;
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Globalization;
|
|
|
|
|
@@ -51,8 +53,6 @@ using Aaru.Helpers;
|
|
|
|
|
using DMI = Aaru.Decoders.Xbox.DMI;
|
|
|
|
|
using Session = Aaru.CommonTypes.Structs.Session;
|
|
|
|
|
|
|
|
|
|
namespace Aaru.DiscImages;
|
|
|
|
|
|
|
|
|
|
public sealed partial class BlindWrite5
|
|
|
|
|
{
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
@@ -64,31 +64,28 @@ public sealed partial class BlindWrite5
|
|
|
|
|
if(stream.Length < 276)
|
|
|
|
|
return ErrorNumber.InvalidArgument;
|
|
|
|
|
|
|
|
|
|
byte[] hdr = new byte[260];
|
|
|
|
|
var hdr = new byte[260];
|
|
|
|
|
stream.Read(hdr, 0, 260);
|
|
|
|
|
_header = Marshal.ByteArrayToStructureLittleEndian<Header>(hdr);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.signature = {0}",
|
|
|
|
|
StringHandlers.CToString(_header.signature));
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < _header.unknown1.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown1[{1}] = 0x{0:X8}", _header.unknown1[i],
|
|
|
|
|
i);
|
|
|
|
|
for(var i = 0; i < _header.unknown1.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown1[{1}] = 0x{0:X8}", _header.unknown1[i], i);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.profile = {0}", _header.profile);
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.sessions = {0}", _header.sessions);
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < _header.unknown2.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown2[{1}] = 0x{0:X8}", _header.unknown2[i],
|
|
|
|
|
i);
|
|
|
|
|
for(var i = 0; i < _header.unknown2.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown2[{1}] = 0x{0:X8}", _header.unknown2[i], i);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.mcnIsValid = {0}", _header.mcnIsValid);
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.mcn = {0}", StringHandlers.CToString(_header.mcn));
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown3 = 0x{0:X4}", _header.unknown3);
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < _header.unknown4.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown4[{1}] = 0x{0:X8}", _header.unknown4[i],
|
|
|
|
|
i);
|
|
|
|
|
for(var i = 0; i < _header.unknown4.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown4[{1}] = 0x{0:X8}", _header.unknown4[i], i);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.pmaLen = {0}", _header.pmaLen);
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.atipLen = {0}", _header.atipLen);
|
|
|
|
|
@@ -96,16 +93,14 @@ public sealed partial class BlindWrite5
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.cdInfoLen = {0}", _header.cdInfoLen);
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.bcaLen = {0}", _header.bcaLen);
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < _header.unknown5.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown5[{1}] = 0x{0:X8}", _header.unknown5[i],
|
|
|
|
|
i);
|
|
|
|
|
for(var i = 0; i < _header.unknown5.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown5[{1}] = 0x{0:X8}", _header.unknown5[i], i);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.dvdStrLen = {0}", _header.dvdStrLen);
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.dvdInfoLen = {0}", _header.dvdInfoLen);
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < _header.unknown6.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown6[{1}] = 0x{0:X2}", _header.unknown6[i],
|
|
|
|
|
i);
|
|
|
|
|
for(var i = 0; i < _header.unknown6.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown6[{1}] = 0x{0:X2}", _header.unknown6[i], i);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "header.manufacturer = {0}",
|
|
|
|
|
StringHandlers.CToString(_header.manufacturer));
|
|
|
|
|
@@ -148,7 +143,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
if(_unkBlock.Length > 0)
|
|
|
|
|
stream.Read(_unkBlock, 0, _unkBlock.Length);
|
|
|
|
|
|
|
|
|
|
byte[] temp = new byte[_header.pmaLen];
|
|
|
|
|
var temp = new byte[_header.pmaLen];
|
|
|
|
|
|
|
|
|
|
if(temp.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
@@ -247,20 +242,20 @@ public sealed partial class BlindWrite5
|
|
|
|
|
_discInformation = null;
|
|
|
|
|
|
|
|
|
|
// How many data blocks
|
|
|
|
|
byte[] tmpArray = new byte[4];
|
|
|
|
|
var tmpArray = new byte[4];
|
|
|
|
|
stream.Read(tmpArray, 0, tmpArray.Length);
|
|
|
|
|
uint dataBlockCount = BitConverter.ToUInt32(tmpArray, 0);
|
|
|
|
|
var dataBlockCount = BitConverter.ToUInt32(tmpArray, 0);
|
|
|
|
|
|
|
|
|
|
stream.Read(tmpArray, 0, tmpArray.Length);
|
|
|
|
|
uint dataPathLen = BitConverter.ToUInt32(tmpArray, 0);
|
|
|
|
|
byte[] dataPathBytes = new byte[dataPathLen];
|
|
|
|
|
var dataPathLen = BitConverter.ToUInt32(tmpArray, 0);
|
|
|
|
|
var dataPathBytes = new byte[dataPathLen];
|
|
|
|
|
stream.Read(dataPathBytes, 0, dataPathBytes.Length);
|
|
|
|
|
_dataPath = Encoding.Unicode.GetString(dataPathBytes);
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "Data path: {0}", _dataPath);
|
|
|
|
|
|
|
|
|
|
_dataFiles = new List<DataFile>();
|
|
|
|
|
|
|
|
|
|
for(int cD = 0; cD < dataBlockCount; cD++)
|
|
|
|
|
for(var cD = 0; cD < dataBlockCount; cD++)
|
|
|
|
|
{
|
|
|
|
|
tmpArray = new byte[52];
|
|
|
|
|
|
|
|
|
|
@@ -299,15 +294,15 @@ public sealed partial class BlindWrite5
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.type = 0x{0:X8}", dataFile.Type);
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.length = {0}", dataFile.Length);
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < dataFile.Unknown1.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.unknown1[{1}] = {0}",
|
|
|
|
|
dataFile.Unknown1[i], i);
|
|
|
|
|
for(var i = 0; i < dataFile.Unknown1.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.unknown1[{1}] = {0}", dataFile.Unknown1[i],
|
|
|
|
|
i);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.offset = {0}", dataFile.Offset);
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < dataFile.Unknown2.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.unknown2[{1}] = {0}",
|
|
|
|
|
dataFile.Unknown2[i], i);
|
|
|
|
|
for(var i = 0; i < dataFile.Unknown2.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.unknown2[{1}] = {0}", dataFile.Unknown2[i],
|
|
|
|
|
i);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.startLba = {0}", dataFile.StartLba);
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.sectors = {0}", dataFile.Sectors);
|
|
|
|
|
@@ -318,7 +313,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
|
|
|
|
|
_bwSessions = new List<SessionDescriptor>();
|
|
|
|
|
|
|
|
|
|
for(int ses = 0; ses < _header.sessions; ses++)
|
|
|
|
|
for(var ses = 0; ses < _header.sessions; ses++)
|
|
|
|
|
{
|
|
|
|
|
var session = new SessionDescriptor();
|
|
|
|
|
tmpArray = new byte[16];
|
|
|
|
|
@@ -338,15 +333,13 @@ public sealed partial class BlindWrite5
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].start = {1}", ses, session.Start);
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].end = {1}", ses, session.End);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].firstTrack = {1}", ses,
|
|
|
|
|
session.FirstTrack);
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].firstTrack = {1}", ses, session.FirstTrack);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].lastTrack = {1}", ses,
|
|
|
|
|
session.LastTrack);
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].lastTrack = {1}", ses, session.LastTrack);
|
|
|
|
|
|
|
|
|
|
for(int tSeq = 0; tSeq < session.Entries; tSeq++)
|
|
|
|
|
for(var tSeq = 0; tSeq < session.Entries; tSeq++)
|
|
|
|
|
{
|
|
|
|
|
byte[] trk = new byte[72];
|
|
|
|
|
var trk = new byte[72];
|
|
|
|
|
stream.Read(trk, 0, 72);
|
|
|
|
|
session.Tracks[tSeq] = Marshal.ByteArrayToStructureLittleEndian<TrackDescriptor>(trk);
|
|
|
|
|
|
|
|
|
|
@@ -361,16 +354,15 @@ public sealed partial class BlindWrite5
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].track[{1}].type = {2}", ses, tSeq,
|
|
|
|
|
session.Tracks[tSeq].type);
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < session.Tracks[tSeq].unknown1.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin",
|
|
|
|
|
"session[{0}].track[{1}].unknown1[{2}] = 0x{3:X2}", ses, tSeq, i,
|
|
|
|
|
session.Tracks[tSeq].unknown1[i]);
|
|
|
|
|
for(var i = 0; i < session.Tracks[tSeq].unknown1.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].track[{1}].unknown1[{2}] = 0x{3:X2}",
|
|
|
|
|
ses, tSeq, i, session.Tracks[tSeq].unknown1[i]);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].track[{1}].unknown2 = 0x{2:X8}", ses,
|
|
|
|
|
tSeq, session.Tracks[tSeq].unknown2);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].track[{1}].subchannel = {2}", ses,
|
|
|
|
|
tSeq, session.Tracks[tSeq].subchannel);
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].track[{1}].subchannel = {2}", ses, tSeq,
|
|
|
|
|
session.Tracks[tSeq].subchannel);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].track[{1}].unknown3 = 0x{2:X2}", ses,
|
|
|
|
|
tSeq, session.Tracks[tSeq].unknown3);
|
|
|
|
|
@@ -414,21 +406,19 @@ public sealed partial class BlindWrite5
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].track[{1}].pregap = {2}", ses, tSeq,
|
|
|
|
|
session.Tracks[tSeq].pregap);
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < session.Tracks[tSeq].unknown6.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin",
|
|
|
|
|
"session[{0}].track[{1}].unknown6[{2}] = 0x{3:X8}", ses, tSeq, i,
|
|
|
|
|
session.Tracks[tSeq].unknown6[i]);
|
|
|
|
|
for(var i = 0; i < session.Tracks[tSeq].unknown6.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].track[{1}].unknown6[{2}] = 0x{3:X8}",
|
|
|
|
|
ses, tSeq, i, session.Tracks[tSeq].unknown6[i]);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].track[{1}].startLba = {2}", ses,
|
|
|
|
|
tSeq, session.Tracks[tSeq].startLba);
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].track[{1}].startLba = {2}", ses, tSeq,
|
|
|
|
|
session.Tracks[tSeq].startLba);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].track[{1}].sectors = {2}", ses, tSeq,
|
|
|
|
|
session.Tracks[tSeq].sectors);
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < session.Tracks[tSeq].unknown7.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin",
|
|
|
|
|
"session[{0}].track[{1}].unknown7[{2}] = 0x{3:X8}", ses, tSeq, i,
|
|
|
|
|
session.Tracks[tSeq].unknown7[i]);
|
|
|
|
|
for(var i = 0; i < session.Tracks[tSeq].unknown7.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].track[{1}].unknown7[{2}] = 0x{3:X8}",
|
|
|
|
|
ses, tSeq, i, session.Tracks[tSeq].unknown7[i]);
|
|
|
|
|
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].track[{1}].session = {2}", ses, tSeq,
|
|
|
|
|
session.Tracks[tSeq].session);
|
|
|
|
|
@@ -441,7 +431,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
for(int i = 0; i < session.Tracks[tSeq].unknown9.Length; i++)
|
|
|
|
|
for(var i = 0; i < session.Tracks[tSeq].unknown9.Length; i++)
|
|
|
|
|
AaruConsole.DebugWriteLine("BlindWrite5 plugin",
|
|
|
|
|
"session[{0}].track[{1}].unknown9[{2}] = 0x{3:X8}", ses, tSeq, i,
|
|
|
|
|
session.Tracks[tSeq].unknown9[i]);
|
|
|
|
|
@@ -458,7 +448,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
tmpArray = new byte[4];
|
|
|
|
|
stream.Read(tmpArray, 0, tmpArray.Length);
|
|
|
|
|
|
|
|
|
|
byte[] footer = new byte[16];
|
|
|
|
|
var footer = new byte[16];
|
|
|
|
|
stream.Read(footer, 0, footer.Length);
|
|
|
|
|
|
|
|
|
|
if(_bw5Footer.SequenceEqual(footer))
|
|
|
|
|
@@ -514,8 +504,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
|
|
|
|
|
if(filtersList.GetFilter(Path.Combine(imageFilter.ParentFolder, path)) != null)
|
|
|
|
|
{
|
|
|
|
|
chars.FileFilter =
|
|
|
|
|
filtersList.GetFilter(Path.Combine(imageFilter.ParentFolder, path));
|
|
|
|
|
chars.FileFilter = filtersList.GetFilter(Path.Combine(imageFilter.ParentFolder, path));
|
|
|
|
|
|
|
|
|
|
chars.FilePath = path;
|
|
|
|
|
}
|
|
|
|
|
@@ -531,19 +520,17 @@ public sealed partial class BlindWrite5
|
|
|
|
|
|
|
|
|
|
chars.FileFilter =
|
|
|
|
|
filtersList.GetFilter(Path.Combine(imageFilter.ParentFolder,
|
|
|
|
|
path.ToLower(CultureInfo.
|
|
|
|
|
CurrentCulture)));
|
|
|
|
|
path.ToLower(CultureInfo.CurrentCulture)));
|
|
|
|
|
}
|
|
|
|
|
else if(filtersList.GetFilter(Path.Combine(imageFilter.ParentFolder,
|
|
|
|
|
path.ToUpper(CultureInfo.
|
|
|
|
|
CurrentCulture))) != null)
|
|
|
|
|
path.ToUpper(CultureInfo.CurrentCulture))) !=
|
|
|
|
|
null)
|
|
|
|
|
{
|
|
|
|
|
chars.FilePath = path.ToUpper(CultureInfo.CurrentCulture);
|
|
|
|
|
|
|
|
|
|
chars.FileFilter =
|
|
|
|
|
filtersList.GetFilter(Path.Combine(imageFilter.ParentFolder,
|
|
|
|
|
path.ToUpper(CultureInfo.
|
|
|
|
|
CurrentCulture)));
|
|
|
|
|
path.ToUpper(CultureInfo.CurrentCulture)));
|
|
|
|
|
}
|
|
|
|
|
else if(filtersList.GetFilter(Path.Combine(imageFilter.ParentFolder,
|
|
|
|
|
dataFile.Filename.ToLower(CultureInfo.
|
|
|
|
|
@@ -602,8 +589,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
AaruConsole.ErrorWriteLine("BlindWrite5 found unknown subchannel size: {0}",
|
|
|
|
|
sectorSize - 2352);
|
|
|
|
|
AaruConsole.ErrorWriteLine("BlindWrite5 found unknown subchannel size: {0}", sectorSize - 2352);
|
|
|
|
|
|
|
|
|
|
return ErrorNumber.NotSupported;
|
|
|
|
|
}
|
|
|
|
|
@@ -630,7 +616,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
|
|
|
|
|
ulong offsetBytes = 0;
|
|
|
|
|
_offsetMap = new Dictionary<uint, ulong>();
|
|
|
|
|
bool isDvd = false;
|
|
|
|
|
var isDvd = false;
|
|
|
|
|
byte firstSession = byte.MaxValue;
|
|
|
|
|
byte lastSession = 0;
|
|
|
|
|
_trackFlags = new Dictionary<uint, byte>();
|
|
|
|
|
@@ -657,7 +643,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
|
|
|
|
|
foreach(TrackDescriptor trk in ses.Tracks)
|
|
|
|
|
{
|
|
|
|
|
byte adrCtl = (byte)((trk.adr << 4) + trk.ctl);
|
|
|
|
|
var adrCtl = (byte)((trk.adr << 4) + trk.ctl);
|
|
|
|
|
fullTocStream.WriteByte((byte)trk.session);
|
|
|
|
|
fullTocStream.WriteByte(adrCtl);
|
|
|
|
|
fullTocStream.WriteByte(0x00);
|
|
|
|
|
@@ -768,13 +754,10 @@ public sealed partial class BlindWrite5
|
|
|
|
|
track.StartSector = (ulong)(trk.startLba + trk.pregap);
|
|
|
|
|
track.EndSector = (ulong)(trk.sectors + trk.startLba) - 1;
|
|
|
|
|
|
|
|
|
|
List<DataFileCharacteristics> fileCharsForThisTrack = _filePaths.
|
|
|
|
|
Where(chars =>
|
|
|
|
|
trk.startLba >=
|
|
|
|
|
chars.StartLba &&
|
|
|
|
|
trk.startLba + trk.sectors <=
|
|
|
|
|
chars.StartLba + chars.Sectors).
|
|
|
|
|
ToList();
|
|
|
|
|
var fileCharsForThisTrack = _filePaths.
|
|
|
|
|
Where(chars => trk.startLba >= chars.StartLba &&
|
|
|
|
|
trk.startLba + trk.sectors <=
|
|
|
|
|
chars.StartLba + chars.Sectors).ToList();
|
|
|
|
|
|
|
|
|
|
if(fileCharsForThisTrack.Count == 0 &&
|
|
|
|
|
_filePaths.Any(f => Path.GetExtension(f.FilePath).ToLowerInvariant() == ".b00"))
|
|
|
|
|
@@ -783,8 +766,8 @@ public sealed partial class BlindWrite5
|
|
|
|
|
_filePaths.FirstOrDefault(f => Path.GetExtension(f.FilePath).ToLowerInvariant() == ".b00");
|
|
|
|
|
|
|
|
|
|
string filename = Path.GetFileNameWithoutExtension(splitStartChars.FilePath);
|
|
|
|
|
bool lowerCaseExtension = false;
|
|
|
|
|
bool lowerCaseFileName = false;
|
|
|
|
|
var lowerCaseExtension = false;
|
|
|
|
|
var lowerCaseFileName = false;
|
|
|
|
|
string basePath;
|
|
|
|
|
|
|
|
|
|
bool version5 = string.Compare(Path.GetExtension(imageFilter.Filename), ".B5T",
|
|
|
|
|
@@ -794,11 +777,8 @@ public sealed partial class BlindWrite5
|
|
|
|
|
string firstExtensionLower = version5 ? "b5i" : "b6i";
|
|
|
|
|
|
|
|
|
|
if(File.Exists(Path.Combine(imageFilter.ParentFolder, $"{filename}.{firstExtension}")))
|
|
|
|
|
{
|
|
|
|
|
basePath = imageFilter.ParentFolder;
|
|
|
|
|
}
|
|
|
|
|
else if(File.Exists(Path.Combine(imageFilter.ParentFolder,
|
|
|
|
|
$"{filename}.{firstExtensionLower}")))
|
|
|
|
|
else if(File.Exists(Path.Combine(imageFilter.ParentFolder, $"{filename}.{firstExtensionLower}")))
|
|
|
|
|
{
|
|
|
|
|
basePath = imageFilter.ParentFolder;
|
|
|
|
|
lowerCaseExtension = true;
|
|
|
|
|
@@ -818,9 +798,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if(File.Exists(Path.Combine(_dataPath, $"{filename}.{firstExtension}")))
|
|
|
|
|
{
|
|
|
|
|
basePath = _dataPath;
|
|
|
|
|
}
|
|
|
|
|
else if(File.Exists(Path.Combine(_dataPath, $"{filename}.{firstExtensionLower}")))
|
|
|
|
|
{
|
|
|
|
|
basePath = _dataPath;
|
|
|
|
|
@@ -842,9 +820,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
|
|
|
|
|
else if(File.Exists(Path.Combine(_dataPath.ToLower(CultureInfo.CurrentCulture),
|
|
|
|
|
$"{filename}.{firstExtension}")))
|
|
|
|
|
{
|
|
|
|
|
basePath = _dataPath.ToLower(CultureInfo.CurrentCulture);
|
|
|
|
|
}
|
|
|
|
|
else if(File.Exists(Path.Combine(_dataPath.ToLower(CultureInfo.CurrentCulture),
|
|
|
|
|
$"{filename}.{firstExtensionLower}")))
|
|
|
|
|
{
|
|
|
|
|
@@ -867,9 +843,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
|
|
|
|
|
else if(File.Exists(Path.Combine(imageFilter.ParentFolder, _dataPath,
|
|
|
|
|
$"{filename}.{firstExtension}")))
|
|
|
|
|
{
|
|
|
|
|
basePath = Path.Combine(imageFilter.ParentFolder, _dataPath);
|
|
|
|
|
}
|
|
|
|
|
else if(File.Exists(Path.Combine(imageFilter.ParentFolder, _dataPath,
|
|
|
|
|
$"{filename}.{firstExtensionLower}")))
|
|
|
|
|
{
|
|
|
|
|
@@ -893,13 +867,10 @@ public sealed partial class BlindWrite5
|
|
|
|
|
else if(File.Exists(Path.Combine(imageFilter.ParentFolder,
|
|
|
|
|
_dataPath.ToLower(CultureInfo.CurrentCulture),
|
|
|
|
|
$"{filename}.{firstExtension}")))
|
|
|
|
|
{
|
|
|
|
|
basePath = Path.Combine(imageFilter.ParentFolder,
|
|
|
|
|
_dataPath.ToLower(CultureInfo.CurrentCulture));
|
|
|
|
|
}
|
|
|
|
|
else if(File.Exists(Path.Combine(imageFilter.ParentFolder,
|
|
|
|
|
_dataPath.ToLower(CultureInfo.CurrentCulture),
|
|
|
|
|
$"{filename}.b00")))
|
|
|
|
|
_dataPath.ToLower(CultureInfo.CurrentCulture), $"{filename}.b00")))
|
|
|
|
|
{
|
|
|
|
|
basePath = Path.Combine(imageFilter.ParentFolder,
|
|
|
|
|
_dataPath.ToLower(CultureInfo.CurrentCulture));
|
|
|
|
|
@@ -926,17 +897,14 @@ public sealed partial class BlindWrite5
|
|
|
|
|
lowerCaseExtension = true;
|
|
|
|
|
}
|
|
|
|
|
else if(File.Exists(Path.Combine("", $"{filename}.{firstExtension}")))
|
|
|
|
|
{
|
|
|
|
|
basePath = "";
|
|
|
|
|
}
|
|
|
|
|
else if(File.Exists(Path.Combine("", $"{filename}.{firstExtensionLower}")))
|
|
|
|
|
{
|
|
|
|
|
basePath = "";
|
|
|
|
|
lowerCaseExtension = true;
|
|
|
|
|
}
|
|
|
|
|
else if(
|
|
|
|
|
File.Exists(Path.Combine("",
|
|
|
|
|
$"{filename.ToLower(CultureInfo.CurrentCulture)}.{firstExtension}")))
|
|
|
|
|
else if(File.Exists(Path.Combine("",
|
|
|
|
|
$"{filename.ToLower(CultureInfo.CurrentCulture)}.{firstExtension}")))
|
|
|
|
|
{
|
|
|
|
|
basePath = "";
|
|
|
|
|
lowerCaseFileName = true;
|
|
|
|
|
@@ -981,8 +949,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
track.File = $"{filename}.{extension}";
|
|
|
|
|
|
|
|
|
|
if(trk.startLba >= 0)
|
|
|
|
|
track.FileOffset =
|
|
|
|
|
(ulong)((trk.startLba * splitStartChars.SectorSize) + splitStartChars.Offset);
|
|
|
|
|
track.FileOffset = (ulong)(trk.startLba * splitStartChars.SectorSize + splitStartChars.Offset);
|
|
|
|
|
else
|
|
|
|
|
track.FileOffset = (ulong)(trk.startLba * -1 * splitStartChars.SectorSize);
|
|
|
|
|
|
|
|
|
|
@@ -1191,8 +1158,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case DiskCategory.Nintendo:
|
|
|
|
|
_imageInfo.MediaType =
|
|
|
|
|
pfi0.Value.DiscSize == DVDSize.Eighty ? MediaType.GOD : MediaType.WOD;
|
|
|
|
|
_imageInfo.MediaType = pfi0.Value.DiscSize == DVDSize.Eighty ? MediaType.GOD : MediaType.WOD;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case DiskCategory.UMD:
|
|
|
|
|
@@ -1210,11 +1176,11 @@ public sealed partial class BlindWrite5
|
|
|
|
|
else if(_imageInfo.MediaType == MediaType.CD ||
|
|
|
|
|
_imageInfo.MediaType == MediaType.CDROM)
|
|
|
|
|
{
|
|
|
|
|
bool data = false;
|
|
|
|
|
bool mode2 = false;
|
|
|
|
|
bool firstAudio = false;
|
|
|
|
|
bool firstData = false;
|
|
|
|
|
bool audio = false;
|
|
|
|
|
var data = false;
|
|
|
|
|
var mode2 = false;
|
|
|
|
|
var firstAudio = false;
|
|
|
|
|
var firstData = false;
|
|
|
|
|
var audio = false;
|
|
|
|
|
|
|
|
|
|
foreach(Track bwTrack in Tracks)
|
|
|
|
|
{
|
|
|
|
|
@@ -1249,7 +1215,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
Sessions.Count > 1 &&
|
|
|
|
|
mode2)
|
|
|
|
|
_imageInfo.MediaType = MediaType.CDPLUS;
|
|
|
|
|
else if((firstData && audio) || mode2)
|
|
|
|
|
else if(firstData && audio || mode2)
|
|
|
|
|
_imageInfo.MediaType = MediaType.CDROMXA;
|
|
|
|
|
else if(!audio)
|
|
|
|
|
_imageInfo.MediaType = MediaType.CDROM;
|
|
|
|
|
@@ -1264,8 +1230,8 @@ public sealed partial class BlindWrite5
|
|
|
|
|
|
|
|
|
|
if(string.Compare(Path.GetExtension(imageFilter.Filename), ".B5T", StringComparison.OrdinalIgnoreCase) == 0)
|
|
|
|
|
_imageInfo.ApplicationVersion = "5";
|
|
|
|
|
else if(string.Compare(Path.GetExtension(imageFilter.Filename), ".B6T",
|
|
|
|
|
StringComparison.OrdinalIgnoreCase) == 0)
|
|
|
|
|
else if(string.Compare(Path.GetExtension(imageFilter.Filename), ".B6T", StringComparison.OrdinalIgnoreCase) ==
|
|
|
|
|
0)
|
|
|
|
|
_imageInfo.ApplicationVersion = "6";
|
|
|
|
|
|
|
|
|
|
_imageInfo.Version = "5";
|
|
|
|
|
@@ -1286,7 +1252,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
|
|
|
|
|
if(_atip != null)
|
|
|
|
|
{
|
|
|
|
|
byte[] atipTmp = new byte[_atip.Length + 4];
|
|
|
|
|
var atipTmp = new byte[_atip.Length + 4];
|
|
|
|
|
Array.Copy(_atip, 0, atipTmp, 4, _atip.Length);
|
|
|
|
|
atipTmp[0] = (byte)((_atip.Length & 0xFF00) >> 8);
|
|
|
|
|
atipTmp[1] = (byte)(_atip.Length & 0xFF);
|
|
|
|
|
@@ -1303,7 +1269,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isBd = false;
|
|
|
|
|
var isBd = false;
|
|
|
|
|
|
|
|
|
|
if(_imageInfo.MediaType == MediaType.BDR ||
|
|
|
|
|
_imageInfo.MediaType == MediaType.BDRE ||
|
|
|
|
|
@@ -1432,8 +1398,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) =>
|
|
|
|
|
ReadSectors(sectorAddress, 1, out buffer);
|
|
|
|
|
public ErrorNumber ReadSector(ulong sectorAddress, out byte[] buffer) => ReadSectors(sectorAddress, 1, out buffer);
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public ErrorNumber ReadSectorTag(ulong sectorAddress, SectorTagType tag, out byte[] buffer) =>
|
|
|
|
|
@@ -1489,9 +1454,8 @@ public sealed partial class BlindWrite5
|
|
|
|
|
if(length + sectorAddress > aaruTrack.EndSector - aaruTrack.StartSector + 1)
|
|
|
|
|
return ErrorNumber.OutOfRange;
|
|
|
|
|
|
|
|
|
|
DataFileCharacteristics chars = (from characteristics in _filePaths let firstSector =
|
|
|
|
|
characteristics.StartLba let lastSector =
|
|
|
|
|
firstSector + characteristics.Sectors - 1 let wantedSector =
|
|
|
|
|
DataFileCharacteristics chars = (from characteristics in _filePaths let firstSector = characteristics.StartLba
|
|
|
|
|
let lastSector = firstSector + characteristics.Sectors - 1 let wantedSector =
|
|
|
|
|
(int)(sectorAddress + aaruTrack.StartSector)
|
|
|
|
|
where wantedSector >= firstSector && wantedSector <= lastSector
|
|
|
|
|
select characteristics).FirstOrDefault();
|
|
|
|
|
@@ -1503,7 +1467,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
uint sectorOffset;
|
|
|
|
|
uint sectorSize;
|
|
|
|
|
uint sectorSkip;
|
|
|
|
|
bool mode2 = false;
|
|
|
|
|
var mode2 = false;
|
|
|
|
|
|
|
|
|
|
switch(aaruTrack.Type)
|
|
|
|
|
{
|
|
|
|
|
@@ -1577,9 +1541,9 @@ public sealed partial class BlindWrite5
|
|
|
|
|
|
|
|
|
|
buffer = br.ReadBytes((int)((sectorSize + sectorSkip) * length));
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < length; i++)
|
|
|
|
|
for(var i = 0; i < length; i++)
|
|
|
|
|
{
|
|
|
|
|
byte[] sector = new byte[sectorSize];
|
|
|
|
|
var sector = new byte[sectorSize];
|
|
|
|
|
Array.Copy(buffer, (sectorSize + sectorSkip) * i, sector, 0, sectorSize);
|
|
|
|
|
sector = Sector.GetUserDataFromMode2(sector);
|
|
|
|
|
mode2Ms.Write(sector, 0, sector.Length);
|
|
|
|
|
@@ -1591,7 +1555,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
sectorSkip == 0)
|
|
|
|
|
buffer = br.ReadBytes((int)(sectorSize * length));
|
|
|
|
|
else
|
|
|
|
|
for(int i = 0; i < length; i++)
|
|
|
|
|
for(var i = 0; i < length; i++)
|
|
|
|
|
{
|
|
|
|
|
br.BaseStream.Seek(sectorOffset, SeekOrigin.Current);
|
|
|
|
|
byte[] sector = br.ReadBytes((int)sectorSize);
|
|
|
|
|
@@ -1617,9 +1581,8 @@ public sealed partial class BlindWrite5
|
|
|
|
|
if(length + sectorAddress > aaruTrack.EndSector - aaruTrack.StartSector + 1)
|
|
|
|
|
return ErrorNumber.OutOfRange;
|
|
|
|
|
|
|
|
|
|
DataFileCharacteristics chars = (from characteristics in _filePaths let firstSector =
|
|
|
|
|
characteristics.StartLba let lastSector =
|
|
|
|
|
firstSector + characteristics.Sectors - 1 let wantedSector =
|
|
|
|
|
DataFileCharacteristics chars = (from characteristics in _filePaths let firstSector = characteristics.StartLba
|
|
|
|
|
let lastSector = firstSector + characteristics.Sectors - 1 let wantedSector =
|
|
|
|
|
(int)(sectorAddress + aaruTrack.StartSector)
|
|
|
|
|
where wantedSector >= firstSector && wantedSector <= lastSector
|
|
|
|
|
select characteristics).FirstOrDefault();
|
|
|
|
|
@@ -2070,7 +2033,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
sectorSkip == 0)
|
|
|
|
|
buffer = br.ReadBytes((int)(sectorSize * length));
|
|
|
|
|
else
|
|
|
|
|
for(int i = 0; i < length; i++)
|
|
|
|
|
for(var i = 0; i < length; i++)
|
|
|
|
|
{
|
|
|
|
|
br.BaseStream.Seek(sectorOffset, SeekOrigin.Current);
|
|
|
|
|
byte[] sector = br.ReadBytes((int)sectorSize);
|
|
|
|
|
@@ -2082,11 +2045,11 @@ public sealed partial class BlindWrite5
|
|
|
|
|
return ErrorNumber.NoError;
|
|
|
|
|
|
|
|
|
|
buffer = chars.Subchannel switch
|
|
|
|
|
{
|
|
|
|
|
TrackSubchannelType.Q16Interleaved => Subchannel.ConvertQToRaw(buffer),
|
|
|
|
|
TrackSubchannelType.PackedInterleaved => Subchannel.Interleave(buffer),
|
|
|
|
|
_ => buffer
|
|
|
|
|
};
|
|
|
|
|
{
|
|
|
|
|
TrackSubchannelType.Q16Interleaved => Subchannel.ConvertQToRaw(buffer),
|
|
|
|
|
TrackSubchannelType.PackedInterleaved => Subchannel.Interleave(buffer),
|
|
|
|
|
_ => buffer
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return ErrorNumber.NoError;
|
|
|
|
|
}
|
|
|
|
|
@@ -2127,9 +2090,8 @@ public sealed partial class BlindWrite5
|
|
|
|
|
if(length + sectorAddress > aaruTrack.EndSector - aaruTrack.StartSector + 1)
|
|
|
|
|
return ErrorNumber.OutOfRange;
|
|
|
|
|
|
|
|
|
|
DataFileCharacteristics chars = (from characteristics in _filePaths let firstSector =
|
|
|
|
|
characteristics.StartLba let lastSector =
|
|
|
|
|
firstSector + characteristics.Sectors - 1 let wantedSector =
|
|
|
|
|
DataFileCharacteristics chars = (from characteristics in _filePaths let firstSector = characteristics.StartLba
|
|
|
|
|
let lastSector = firstSector + characteristics.Sectors - 1 let wantedSector =
|
|
|
|
|
(int)(sectorAddress + aaruTrack.StartSector)
|
|
|
|
|
where wantedSector >= firstSector && wantedSector <= lastSector
|
|
|
|
|
select characteristics).FirstOrDefault();
|
|
|
|
|
@@ -2197,7 +2159,7 @@ public sealed partial class BlindWrite5
|
|
|
|
|
sectorSkip == 0)
|
|
|
|
|
buffer = br.ReadBytes((int)(sectorSize * length));
|
|
|
|
|
else
|
|
|
|
|
for(int i = 0; i < length; i++)
|
|
|
|
|
for(var i = 0; i < length; i++)
|
|
|
|
|
{
|
|
|
|
|
br.BaseStream.Seek(sectorOffset, SeekOrigin.Current);
|
|
|
|
|
byte[] sector = br.ReadBytes((int)sectorSize);
|
|
|
|
|
|