mirror of
https://github.com/aaru-dps/Aaru.git
synced 2026-07-08 18:16:24 +00:00
[merge] Move decryption to own pipelines
This commit is contained in:
57
Aaru.Core/Image/Merge/MergeAacsBd.cs
Normal file
57
Aaru.Core/Image/Merge/MergeAacsBd.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Aaru.CommonTypes;
|
||||
using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.Localization;
|
||||
|
||||
namespace Aaru.Core.Image;
|
||||
|
||||
public sealed partial class Merger
|
||||
{
|
||||
/// <summary>Merges Blu-ray AACS optical sectors.</summary>
|
||||
/// <param name="inputOptical">Input optical media image.</param>
|
||||
/// <param name="outputOptical">Output optical media image.</param>
|
||||
/// <returns>Error number.</returns>
|
||||
ErrorNumber CopyAacsBdOpticalSectorsPrimary(IOpticalMediaImage inputOptical, IWritableOpticalImage outputOptical)
|
||||
{
|
||||
ErrorNumber errno = AacsBdExtentResolver.ResolveStreamFileExtents(inputOptical,
|
||||
_plugins,
|
||||
out List<AacsBdExtentResolver.LbaRange> ranges,
|
||||
out string err);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke(err);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
Func<ulong, bool> allowDecryptLba = lba => AacsBdExtentResolver.IsLbaAllowed(ranges, lba);
|
||||
|
||||
return AacsBdOpticalPipeline.Run(inputOptical,
|
||||
outputOptical,
|
||||
(uint)count,
|
||||
false,
|
||||
ref _aborted,
|
||||
_aacsDecryptedCpsUnitKeys,
|
||||
allowDecryptLba,
|
||||
new AacsBdOpticalPipeline.Ui
|
||||
{
|
||||
OnInitProgress = () => InitProgress?.Invoke(),
|
||||
OnInitProgress2 = () => InitProgress2?.Invoke(),
|
||||
OnEndProgress = () => EndProgress?.Invoke(),
|
||||
OnEndProgress2 = () => EndProgress2?.Invoke(),
|
||||
OnTrackProgress = (i, n) => UpdateProgress?.Invoke(string.Format(UI.Copying_sectors_in_track_0_of_1, i + 1, n), i, n),
|
||||
OnSectorRangeProgress = (start, end, seq, done, tot) =>
|
||||
UpdateProgress2?.Invoke(string.Format(UI.Copying_sectors_0_to_1_in_track_2,
|
||||
start,
|
||||
end,
|
||||
seq),
|
||||
done,
|
||||
tot),
|
||||
ErrorMessage = s => ErrorMessage?.Invoke(s),
|
||||
StoppingErrorMessage = s => StoppingErrorMessage?.Invoke(s)
|
||||
});
|
||||
}
|
||||
}
|
||||
313
Aaru.Core/Image/Merge/MergeCssDvd.cs
Normal file
313
Aaru.Core/Image/Merge/MergeCssDvd.cs
Normal file
@@ -0,0 +1,313 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// DVD CSS optical sector merge pipeline.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Aaru.CommonTypes;
|
||||
using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.CommonTypes.Structs;
|
||||
using Aaru.Localization;
|
||||
|
||||
namespace Aaru.Core.Image;
|
||||
|
||||
public sealed partial class Merger
|
||||
{
|
||||
/// <summary>Merges CSS-encrypted DVD optical sectors.</summary>
|
||||
/// <param name="inputOptical">Input optical media image.</param>
|
||||
/// <param name="outputOptical">Output optical media image.</param>
|
||||
/// <param name="useLong">True to use long sector reads.</param>
|
||||
/// <returns>Error number.</returns>
|
||||
ErrorNumber CopyCssDvdOpticalSectorsPrimary(IOpticalMediaImage inputOptical, IWritableOpticalImage outputOptical,
|
||||
bool useLong)
|
||||
{
|
||||
if(_aborted) return ErrorNumber.NoError;
|
||||
|
||||
InitProgress?.Invoke();
|
||||
InitProgress2?.Invoke();
|
||||
byte[] generatedTitleKeys = null;
|
||||
int currentTrack = 0;
|
||||
|
||||
foreach(Track track in inputOptical.Tracks)
|
||||
{
|
||||
if(_aborted) break;
|
||||
|
||||
UpdateProgress?.Invoke(string.Format(UI.Copying_sectors_in_track_0_of_1,
|
||||
currentTrack + 1,
|
||||
inputOptical.Tracks.Count),
|
||||
currentTrack,
|
||||
inputOptical.Tracks.Count);
|
||||
|
||||
ulong doneSectors = 0;
|
||||
ulong trackSectors = track.EndSector - track.StartSector + 1;
|
||||
|
||||
while(doneSectors < trackSectors)
|
||||
{
|
||||
if(_aborted) break;
|
||||
|
||||
byte[] sector;
|
||||
|
||||
uint sectorsToDo;
|
||||
|
||||
if(trackSectors - doneSectors >= (ulong)count)
|
||||
sectorsToDo = (uint)count;
|
||||
else
|
||||
sectorsToDo = (uint)(trackSectors - doneSectors);
|
||||
|
||||
UpdateProgress2?.Invoke(string.Format(UI.Copying_sectors_0_to_1_in_track_2,
|
||||
doneSectors + track.StartSector,
|
||||
doneSectors + sectorsToDo + track.StartSector,
|
||||
track.Sequence),
|
||||
(long)doneSectors,
|
||||
(long)trackSectors);
|
||||
|
||||
bool result;
|
||||
SectorStatus sectorStatus = SectorStatus.NotDumped;
|
||||
SectorStatus[] sectorStatusArray = new SectorStatus[1];
|
||||
ErrorNumber errno;
|
||||
|
||||
if(useLong)
|
||||
{
|
||||
errno = sectorsToDo == 1
|
||||
? inputOptical.ReadSectorLong(doneSectors + track.StartSector,
|
||||
false,
|
||||
out sector,
|
||||
out sectorStatus)
|
||||
: inputOptical.ReadSectorsLong(doneSectors + track.StartSector,
|
||||
false,
|
||||
sectorsToDo,
|
||||
out sector,
|
||||
out sectorStatusArray);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
CssDvdSectorDecrypt.ApplyCssAfterReadLong(ref sector,
|
||||
ref sectorStatus,
|
||||
sectorStatusArray,
|
||||
sectorsToDo,
|
||||
sectorsToDo == 1,
|
||||
inputOptical,
|
||||
doneSectors + track.StartSector,
|
||||
_plugins,
|
||||
ref generatedTitleKeys,
|
||||
() => _aborted,
|
||||
MODULE_NAME);
|
||||
|
||||
result = sectorsToDo == 1
|
||||
? outputOptical.WriteSectorLong(sector,
|
||||
doneSectors + track.StartSector,
|
||||
false,
|
||||
sectorStatus)
|
||||
: outputOptical.WriteSectorsLong(sector,
|
||||
doneSectors + track.StartSector,
|
||||
false,
|
||||
sectorsToDo,
|
||||
sectorStatusArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
StoppingErrorMessage?.Invoke(string.Format(UI.Error_0_reading_sector_1_not_continuing,
|
||||
errno,
|
||||
doneSectors + track.StartSector));
|
||||
|
||||
return ErrorNumber.WriteError;
|
||||
}
|
||||
|
||||
if(!result && sector.Length % 2352 != 0)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke(UI.Input_image_is_not_returning_long_sectors_not_continuing);
|
||||
|
||||
return ErrorNumber.InOutError;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = sectorsToDo == 1
|
||||
? inputOptical.ReadSector(doneSectors + track.StartSector,
|
||||
false,
|
||||
out sector,
|
||||
out sectorStatus)
|
||||
: inputOptical.ReadSectors(doneSectors + track.StartSector,
|
||||
false,
|
||||
sectorsToDo,
|
||||
out sector,
|
||||
out sectorStatusArray);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
CssDvdSectorDecrypt.ApplyCssAfterRead(ref sector,
|
||||
ref sectorStatus,
|
||||
sectorStatusArray,
|
||||
sectorsToDo,
|
||||
sectorsToDo == 1,
|
||||
inputOptical,
|
||||
doneSectors + track.StartSector,
|
||||
_plugins,
|
||||
ref generatedTitleKeys,
|
||||
() => _aborted,
|
||||
MODULE_NAME);
|
||||
|
||||
result = sectorsToDo == 1
|
||||
? outputOptical.WriteSector(sector,
|
||||
doneSectors + track.StartSector,
|
||||
false,
|
||||
sectorStatus)
|
||||
: outputOptical.WriteSectors(sector,
|
||||
doneSectors + track.StartSector,
|
||||
false,
|
||||
sectorsToDo,
|
||||
sectorStatusArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
StoppingErrorMessage?.Invoke(string.Format(UI.Error_0_reading_sector_1_not_continuing,
|
||||
errno,
|
||||
doneSectors + track.StartSector));
|
||||
|
||||
return ErrorNumber.WriteError;
|
||||
}
|
||||
}
|
||||
|
||||
if(!result)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke(string.Format(UI.Error_0_writing_sector_1_not_continuing,
|
||||
outputOptical.ErrorMessage,
|
||||
doneSectors + track.StartSector));
|
||||
|
||||
return ErrorNumber.WriteError;
|
||||
}
|
||||
|
||||
doneSectors += sectorsToDo;
|
||||
}
|
||||
|
||||
currentTrack++;
|
||||
}
|
||||
|
||||
EndProgress2?.Invoke();
|
||||
EndProgress?.Invoke();
|
||||
|
||||
return ErrorNumber.NoError;
|
||||
}
|
||||
|
||||
/// <summary>Merges CSS-encrypted DVD optical sectors from a secondary image.</summary>
|
||||
/// <param name="inputOptical">Input optical media image.</param>
|
||||
/// <param name="outputOptical">Output optical media image.</param>
|
||||
/// <param name="useLong">True to use long sector reads.</param>
|
||||
/// <param name="sectorsToCopy">Sectors to copy.</param>
|
||||
/// <returns>Error number.</returns>
|
||||
ErrorNumber CopyCssDvdOpticalSectorsSecondary(IOpticalMediaImage inputOptical, IWritableOpticalImage outputOptical,
|
||||
bool useLong, List<ulong> sectorsToCopy)
|
||||
{
|
||||
if(_aborted) return ErrorNumber.NoError;
|
||||
|
||||
InitProgress?.Invoke();
|
||||
byte[] generatedTitleKeys = null;
|
||||
int howManySectorsToCopy = sectorsToCopy.Count(t => t < inputOptical.Info.Sectors);
|
||||
int howManySectorsCopied = 0;
|
||||
|
||||
foreach(ulong sectorAddress in sectorsToCopy.Where(t => t < inputOptical.Info.Sectors)
|
||||
.TakeWhile(_ => !_aborted))
|
||||
{
|
||||
UpdateProgress?.Invoke(string.Format(UI.Copying_sector_0, sectorAddress),
|
||||
howManySectorsCopied,
|
||||
howManySectorsToCopy);
|
||||
|
||||
if(_aborted) break;
|
||||
|
||||
byte[] sector;
|
||||
bool result;
|
||||
SectorStatus sectorStatus;
|
||||
ErrorNumber errno;
|
||||
|
||||
if(useLong)
|
||||
{
|
||||
errno = inputOptical.ReadSectorLong(sectorAddress, false, out sector, out sectorStatus);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
SectorStatus[] sectorStatusArray = new SectorStatus[1];
|
||||
CssDvdSectorDecrypt.ApplyCssAfterReadLong(ref sector,
|
||||
ref sectorStatus,
|
||||
sectorStatusArray,
|
||||
1,
|
||||
true,
|
||||
inputOptical,
|
||||
sectorAddress,
|
||||
_plugins,
|
||||
ref generatedTitleKeys,
|
||||
() => _aborted,
|
||||
MODULE_NAME);
|
||||
|
||||
result = outputOptical.WriteSectorLong(sector, sectorAddress, false, sectorStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
StoppingErrorMessage?.Invoke(string.Format(UI.Error_0_reading_sector_1_not_continuing,
|
||||
errno,
|
||||
sectorAddress));
|
||||
|
||||
return ErrorNumber.WriteError;
|
||||
}
|
||||
|
||||
if(!result && sector.Length % 2352 != 0)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke(UI.Input_image_is_not_returning_long_sectors_not_continuing);
|
||||
|
||||
return ErrorNumber.InOutError;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = inputOptical.ReadSector(sectorAddress, false, out sector, out sectorStatus);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
SectorStatus[] sectorStatusArray = new SectorStatus[1];
|
||||
CssDvdSectorDecrypt.ApplyCssAfterRead(ref sector,
|
||||
ref sectorStatus,
|
||||
sectorStatusArray,
|
||||
1,
|
||||
true,
|
||||
inputOptical,
|
||||
sectorAddress,
|
||||
_plugins,
|
||||
ref generatedTitleKeys,
|
||||
() => _aborted,
|
||||
MODULE_NAME);
|
||||
|
||||
result = outputOptical.WriteSector(sector, sectorAddress, false, sectorStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
StoppingErrorMessage?.Invoke(string.Format(UI.Error_0_reading_sector_1_not_continuing,
|
||||
errno,
|
||||
sectorAddress));
|
||||
|
||||
return ErrorNumber.WriteError;
|
||||
}
|
||||
}
|
||||
|
||||
if(!result)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke(string.Format(UI.Error_0_writing_sector_1_not_continuing,
|
||||
outputOptical.ErrorMessage,
|
||||
sectorAddress));
|
||||
|
||||
return ErrorNumber.WriteError;
|
||||
}
|
||||
|
||||
howManySectorsCopied++;
|
||||
}
|
||||
|
||||
EndProgress?.Invoke();
|
||||
|
||||
return ErrorNumber.NoError;
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,7 @@ public sealed partial class Merger
|
||||
const string MODULE_NAME = "Image merger";
|
||||
bool _aborted;
|
||||
readonly PluginRegister _plugins = PluginRegister.Singleton;
|
||||
byte[][]? _aacsDecryptedCpsUnitKeys;
|
||||
|
||||
public ErrorNumber Start()
|
||||
{
|
||||
|
||||
@@ -6,10 +6,9 @@ using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.CommonTypes.Structs;
|
||||
using Aaru.Core.Media;
|
||||
using Aaru.Decryption.DVD;
|
||||
using Aaru.Devices;
|
||||
using Aaru.Localization;
|
||||
using Aaru.Logging;
|
||||
using MediaType = Aaru.CommonTypes.MediaType;
|
||||
|
||||
namespace Aaru.Core.Image;
|
||||
|
||||
@@ -173,8 +172,39 @@ public sealed partial class Merger
|
||||
|
||||
InitProgress?.Invoke();
|
||||
InitProgress2?.Invoke();
|
||||
byte[] generatedTitleKeys = null;
|
||||
var currentTrack = 0;
|
||||
var currentTrack = 0;
|
||||
|
||||
_aacsDecryptedCpsUnitKeys = null;
|
||||
|
||||
if(decrypt)
|
||||
{
|
||||
if(IsHdDvdAacsMedia(inputOptical.Info.MediaType))
|
||||
{
|
||||
StoppingErrorMessage?.Invoke(Aaru.Localization.Core.Aacs_hddvd_not_supported);
|
||||
|
||||
return ErrorNumber.UnsupportedMedia;
|
||||
}
|
||||
|
||||
if(IsBluRayAacsMedia(inputOptical.Info.MediaType))
|
||||
{
|
||||
_aacsDecryptedCpsUnitKeys = AacsKeyResolver.TryGetDecryptedCpsUnitKeys(inputOptical,
|
||||
_plugins,
|
||||
Encoding.UTF8,
|
||||
out string aacsErr);
|
||||
|
||||
if(_aacsDecryptedCpsUnitKeys == null)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke(aacsErr ?? Aaru.Localization.Core.Aacs_missing_unit_keys);
|
||||
|
||||
return ErrorNumber.NoData;
|
||||
}
|
||||
|
||||
return CopyAacsBdOpticalSectorsPrimary(inputOptical, outputOptical);
|
||||
}
|
||||
|
||||
if(CssDvdSectorDecrypt.IsDvdMedia(inputOptical.Info.MediaType))
|
||||
return CopyCssDvdOpticalSectorsPrimary(inputOptical, outputOptical, useLong);
|
||||
}
|
||||
|
||||
foreach(Track track in inputOptical.Tracks)
|
||||
{
|
||||
@@ -269,17 +299,6 @@ public sealed partial class Merger
|
||||
out sector,
|
||||
out sectorStatusArray);
|
||||
|
||||
// TODO: Move to generic place when anything but CSS DVDs can be decrypted
|
||||
if(IsDvdMedia(inputOptical.Info.MediaType) && decrypt)
|
||||
{
|
||||
DecryptDvdSector(ref sector,
|
||||
inputOptical,
|
||||
doneSectors + track.StartSector,
|
||||
sectorsToDo,
|
||||
_plugins,
|
||||
ref generatedTitleKeys);
|
||||
}
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
result = sectorsToDo == 1
|
||||
@@ -329,9 +348,11 @@ public sealed partial class Merger
|
||||
{
|
||||
if(_aborted) return ErrorNumber.NoError;
|
||||
|
||||
if(decrypt && CssDvdSectorDecrypt.IsDvdMedia(inputOptical.Info.MediaType))
|
||||
return CopyCssDvdOpticalSectorsSecondary(inputOptical, outputOptical, useLong, sectorsToCopy);
|
||||
|
||||
InitProgress?.Invoke();
|
||||
byte[] generatedTitleKeys = null;
|
||||
int howManySectorsToCopy = sectorsToCopy.Count(t => t < inputOptical.Info.Sectors);
|
||||
int howManySectorsToCopy = sectorsToCopy.Count(t => t < inputOptical.Info.Sectors);
|
||||
var howManySectorsCopied = 0;
|
||||
|
||||
foreach(ulong sectorAddress in sectorsToCopy.Where(t => t < inputOptical.Info.Sectors)
|
||||
@@ -375,10 +396,6 @@ public sealed partial class Merger
|
||||
{
|
||||
errno = inputOptical.ReadSector(sectorAddress, false, out sector, out sectorStatus);
|
||||
|
||||
// TODO: Move to generic place when anything but CSS DVDs can be decrypted
|
||||
if(IsDvdMedia(inputOptical.Info.MediaType) && decrypt)
|
||||
DecryptDvdSector(ref sector, inputOptical, sectorAddress, 1, _plugins, ref generatedTitleKeys);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
result = outputOptical.WriteSector(sector, sectorAddress, false, sectorStatus);
|
||||
else
|
||||
@@ -753,98 +770,21 @@ public sealed partial class Merger
|
||||
return ErrorNumber.NoError;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrypts DVD sectors using CSS (Content Scramble System) decryption
|
||||
/// Retrieves decryption keys from sector tags or generates them from ISO9660 filesystem
|
||||
/// Only MPEG packets within sectors can be encrypted
|
||||
/// </summary>
|
||||
void DecryptDvdSector(ref byte[] sector, IOpticalMediaImage inputOptical, ulong sectorAddress, uint sectorsToDo,
|
||||
PluginRegister plugins, ref byte[] generatedTitleKeys)
|
||||
{
|
||||
if(_aborted) return;
|
||||
static bool IsBluRayAacsMedia(MediaType mediaType) =>
|
||||
mediaType is MediaType.BDROM
|
||||
or MediaType.BDR
|
||||
or MediaType.BDRE
|
||||
or MediaType.BDRXL
|
||||
or MediaType.BDREXL
|
||||
or MediaType.UHDBD;
|
||||
|
||||
// Only sectors which are MPEG packets can be encrypted.
|
||||
if(!Mpeg.ContainsMpegPackets(sector, sectorsToDo)) return;
|
||||
|
||||
byte[] cmi, titleKey;
|
||||
|
||||
if(sectorsToDo == 1)
|
||||
{
|
||||
if(inputOptical.ReadSectorTag(sectorAddress, false, SectorTagType.DvdSectorCmi, out cmi) ==
|
||||
ErrorNumber.NoError &&
|
||||
inputOptical.ReadSectorTag(sectorAddress, false, SectorTagType.DvdTitleKeyDecrypted, out titleKey) ==
|
||||
ErrorNumber.NoError)
|
||||
sector = CSS.DecryptSector(sector, titleKey, cmi);
|
||||
else
|
||||
{
|
||||
if(generatedTitleKeys == null) GenerateDvdTitleKeys(inputOptical, plugins, ref generatedTitleKeys);
|
||||
|
||||
if(generatedTitleKeys != null)
|
||||
{
|
||||
sector = CSS.DecryptSector(sector,
|
||||
generatedTitleKeys.Skip((int)(5 * sectorAddress)).Take(5).ToArray(),
|
||||
null);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(inputOptical.ReadSectorsTag(sectorAddress, false, sectorsToDo, SectorTagType.DvdSectorCmi, out cmi) ==
|
||||
ErrorNumber.NoError &&
|
||||
inputOptical.ReadSectorsTag(sectorAddress,
|
||||
false,
|
||||
sectorsToDo,
|
||||
SectorTagType.DvdTitleKeyDecrypted,
|
||||
out titleKey) ==
|
||||
ErrorNumber.NoError)
|
||||
sector = CSS.DecryptSector(sector, titleKey, cmi, sectorsToDo);
|
||||
else
|
||||
{
|
||||
if(generatedTitleKeys == null) GenerateDvdTitleKeys(inputOptical, plugins, ref generatedTitleKeys);
|
||||
|
||||
if(generatedTitleKeys != null)
|
||||
{
|
||||
sector = CSS.DecryptSector(sector,
|
||||
generatedTitleKeys.Skip((int)(5 * sectorAddress))
|
||||
.Take((int)(5 * sectorsToDo))
|
||||
.ToArray(),
|
||||
null,
|
||||
sectorsToDo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates DVD CSS title keys from ISO9660 filesystem
|
||||
/// Used when explicit title keys are not available in sector tags
|
||||
/// Searches for ISO9660 partitions to derive decryption keys
|
||||
/// </summary>
|
||||
void GenerateDvdTitleKeys(IOpticalMediaImage inputOptical, PluginRegister plugins, ref byte[] generatedTitleKeys)
|
||||
{
|
||||
if(_aborted) return;
|
||||
|
||||
List<Partition> partitions = Partitions.GetAll(inputOptical);
|
||||
|
||||
partitions = partitions.FindAll(p =>
|
||||
{
|
||||
Filesystems.Identify(inputOptical, out List<string> idPlugins, p);
|
||||
|
||||
return idPlugins.Contains("iso9660 filesystem");
|
||||
});
|
||||
|
||||
if(!plugins.ReadOnlyFilesystems.TryGetValue("iso9660 filesystem", out IReadOnlyFilesystem rofs)) return;
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, UI.Generating_decryption_keys);
|
||||
|
||||
generatedTitleKeys = CSS.GenerateTitleKeys(inputOptical, partitions, inputOptical.Info.Sectors, rofs);
|
||||
}
|
||||
|
||||
static bool IsDvdMedia(MediaType mediaType) =>
|
||||
|
||||
// Checks if media type is any variant of DVD (ROM, R, RDL, PR, PRDL)
|
||||
// Consolidates media type checking logic used throughout conversion process
|
||||
mediaType is MediaType.DVDROM or MediaType.DVDR or MediaType.DVDRDL or MediaType.DVDPR or MediaType.DVDPRDL;
|
||||
static bool IsHdDvdAacsMedia(MediaType mediaType) =>
|
||||
mediaType is MediaType.HDDVDROM
|
||||
or MediaType.HDDVDRAM
|
||||
or MediaType.HDDVDR
|
||||
or MediaType.HDDVDRW
|
||||
or MediaType.HDDVDRDL
|
||||
or MediaType.HDDVDRWDL;
|
||||
|
||||
private static bool IsCompactDiscMedia(MediaType mediaType) =>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user