mirror of
https://github.com/aaru-dps/Aaru.git
synced 2026-04-05 21:44:17 +00:00
Add support for Nintendo Wii U compressed disc images (WUX format)
This commit is contained in:
@@ -61,4 +61,5 @@
|
|||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=vmware/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=vmware/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=wcdiskimage/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=wcdiskimage/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=winoncd/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=winoncd/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=wux/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=zzzrawimage/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=zzzrawimage/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||||
42
Aaru.Images/WUX/Constants.cs
Normal file
42
Aaru.Images/WUX/Constants.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// Aaru Data Preservation Suite
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : Constants.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Component : Disc image plugins.
|
||||||
|
//
|
||||||
|
// --[ Description ] ----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Contains constants for Nintendo Wii U compressed disc images (WUX format).
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2026 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
namespace Aaru.Images;
|
||||||
|
|
||||||
|
public sealed partial class Wux
|
||||||
|
{
|
||||||
|
const uint WUX_MAGIC = 0x30585557U;
|
||||||
|
const uint WUX_HEADER_SIZE = 0x20;
|
||||||
|
const uint WIIU_PHYSICAL_SECTOR = 0x8000;
|
||||||
|
const uint WIIU_LOGICAL_SECTOR = 2048;
|
||||||
|
const uint LOGICAL_PER_PHYSICAL = WIIU_PHYSICAL_SECTOR / WIIU_LOGICAL_SECTOR;
|
||||||
|
}
|
||||||
63
Aaru.Images/WUX/Identify.cs
Normal file
63
Aaru.Images/WUX/Identify.cs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// Aaru Data Preservation Suite
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : Identify.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Component : Disc image plugins.
|
||||||
|
//
|
||||||
|
// --[ Description ] ----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Identifies Nintendo Wii U compressed disc images (WUX format).
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2026 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
|
using Aaru.CommonTypes.Interfaces;
|
||||||
|
using Aaru.Helpers;
|
||||||
|
|
||||||
|
namespace Aaru.Images;
|
||||||
|
|
||||||
|
public sealed partial class Wux
|
||||||
|
{
|
||||||
|
#region IOpticalMediaImage Members
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool Identify(IFilter imageFilter)
|
||||||
|
{
|
||||||
|
Stream stream = imageFilter.GetDataForkStream();
|
||||||
|
|
||||||
|
if(stream.Length < WUX_HEADER_SIZE) return false;
|
||||||
|
|
||||||
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
var headerBytes = new byte[WUX_HEADER_SIZE];
|
||||||
|
stream.EnsureRead(headerBytes, 0, (int)WUX_HEADER_SIZE);
|
||||||
|
|
||||||
|
WuxHeader header = Marshal.SpanToStructureLittleEndian<WuxHeader>(headerBytes);
|
||||||
|
|
||||||
|
if(header.Magic != WUX_MAGIC) return false;
|
||||||
|
|
||||||
|
return header.SectorSize == WIIU_PHYSICAL_SECTOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
80
Aaru.Images/WUX/Properties.cs
Normal file
80
Aaru.Images/WUX/Properties.cs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// Aaru Data Preservation Suite
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : Properties.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Component : Disc image plugins.
|
||||||
|
//
|
||||||
|
// --[ Description ] ----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Contains properties for Nintendo Wii U compressed disc images (WUX format).
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2026 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Aaru.CommonTypes.AaruMetadata;
|
||||||
|
using Aaru.CommonTypes.Structs;
|
||||||
|
using Partition = Aaru.CommonTypes.Partition;
|
||||||
|
using Track = Aaru.CommonTypes.Structs.Track;
|
||||||
|
using Session = Aaru.CommonTypes.Structs.Session;
|
||||||
|
|
||||||
|
namespace Aaru.Images;
|
||||||
|
|
||||||
|
public sealed partial class Wux
|
||||||
|
{
|
||||||
|
#region IOpticalMediaImage Members
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
|
||||||
|
// ReSharper disable once ConvertToAutoProperty
|
||||||
|
public ImageInfo Info => _imageInfo;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string Name => "Nintendo Wii U WUX";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Guid Id => new("A8B84E3D-6F8C-4F82-B5E0-1C5A7F4A9D2E");
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string Author => Authors.NataliaPortillo;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string Format => "Nintendo Wii U WUX";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public List<Partition> Partitions { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public List<Track> Tracks { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public List<Session> Sessions { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public List<DumpHardware> DumpHardware => null;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Metadata AaruMetadata => null;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
310
Aaru.Images/WUX/Read.cs
Normal file
310
Aaru.Images/WUX/Read.cs
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// Aaru Data Preservation Suite
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : Read.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Component : Disc image plugins.
|
||||||
|
//
|
||||||
|
// --[ Description ] ----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Reads Nintendo Wii U compressed disc images (WUX format).
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2026 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using Aaru.CommonTypes;
|
||||||
|
using Aaru.CommonTypes.Enums;
|
||||||
|
using Aaru.CommonTypes.Interfaces;
|
||||||
|
using Aaru.Helpers;
|
||||||
|
using Aaru.Logging;
|
||||||
|
using Track = Aaru.CommonTypes.Structs.Track;
|
||||||
|
using TrackType = Aaru.CommonTypes.Enums.TrackType;
|
||||||
|
using Session = Aaru.CommonTypes.Structs.Session;
|
||||||
|
|
||||||
|
namespace Aaru.Images;
|
||||||
|
|
||||||
|
public sealed partial class Wux
|
||||||
|
{
|
||||||
|
#region IOpticalMediaImage Members
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ErrorNumber Open(IFilter imageFilter)
|
||||||
|
{
|
||||||
|
Stream stream = imageFilter.GetDataForkStream();
|
||||||
|
|
||||||
|
if(stream.Length < WUX_HEADER_SIZE) return ErrorNumber.InvalidArgument;
|
||||||
|
|
||||||
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
var headerBytes = new byte[WUX_HEADER_SIZE];
|
||||||
|
stream.EnsureRead(headerBytes, 0, (int)WUX_HEADER_SIZE);
|
||||||
|
|
||||||
|
WuxHeader header = Marshal.SpanToStructureLittleEndian<WuxHeader>(headerBytes);
|
||||||
|
|
||||||
|
if(header.Magic != WUX_MAGIC) return ErrorNumber.InvalidArgument;
|
||||||
|
|
||||||
|
if(header.SectorSize != WIIU_PHYSICAL_SECTOR) return ErrorNumber.InvalidArgument;
|
||||||
|
|
||||||
|
_sectorCount = (uint)(header.UncompressedSize / WIIU_PHYSICAL_SECTOR);
|
||||||
|
|
||||||
|
AaruLogging.Debug(MODULE_NAME, "WUX uncompressed size: {0} bytes", header.UncompressedSize);
|
||||||
|
AaruLogging.Debug(MODULE_NAME, "WUX physical sector count: {0}", _sectorCount);
|
||||||
|
|
||||||
|
// Read sector index table
|
||||||
|
var indexBytes = new byte[_sectorCount * 4];
|
||||||
|
stream.EnsureRead(indexBytes, 0, indexBytes.Length);
|
||||||
|
|
||||||
|
_sectorIndex = new uint[_sectorCount];
|
||||||
|
|
||||||
|
for(uint i = 0; i < _sectorCount; i++) _sectorIndex[i] = BitConverter.ToUInt32(indexBytes, (int)(i * 4));
|
||||||
|
|
||||||
|
// Data starts at next sector-aligned offset after header + index table
|
||||||
|
ulong rawDataOffset = WUX_HEADER_SIZE + (ulong)indexBytes.Length;
|
||||||
|
_dataOffset = rawDataOffset + WIIU_PHYSICAL_SECTOR - 1 & ~((ulong)WIIU_PHYSICAL_SECTOR - 1);
|
||||||
|
|
||||||
|
AaruLogging.Debug(MODULE_NAME, "WUX data offset: 0x{0:X}", _dataOffset);
|
||||||
|
|
||||||
|
_imageFilter = imageFilter;
|
||||||
|
|
||||||
|
_imageInfo.MediaType = MediaType.WUOD;
|
||||||
|
_imageInfo.SectorSize = WIIU_LOGICAL_SECTOR;
|
||||||
|
_imageInfo.Sectors = (ulong)_sectorCount * LOGICAL_PER_PHYSICAL;
|
||||||
|
_imageInfo.ImageSize = header.UncompressedSize;
|
||||||
|
_imageInfo.CreationTime = imageFilter.CreationTime;
|
||||||
|
_imageInfo.LastModificationTime = imageFilter.LastWriteTime;
|
||||||
|
_imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.Filename);
|
||||||
|
_imageInfo.MetadataMediaType = MetadataMediaType.OpticalDisc;
|
||||||
|
_imageInfo.HasPartitions = true;
|
||||||
|
_imageInfo.HasSessions = true;
|
||||||
|
|
||||||
|
// Load .key sidecar
|
||||||
|
_mediaTags = new Dictionary<MediaTagType, byte[]>();
|
||||||
|
string basename = imageFilter.BasePath;
|
||||||
|
string extension = Path.GetExtension(imageFilter.Filename)?.ToLower();
|
||||||
|
basename = basename[..^(extension?.Length ?? basename.Length)];
|
||||||
|
|
||||||
|
string keyPath = basename + ".key";
|
||||||
|
|
||||||
|
if(File.Exists(keyPath))
|
||||||
|
{
|
||||||
|
byte[] keyData = File.ReadAllBytes(keyPath);
|
||||||
|
|
||||||
|
if(keyData.Length == 16)
|
||||||
|
{
|
||||||
|
_mediaTags[MediaTagType.WiiUDiscKey] = keyData;
|
||||||
|
AaruLogging.Debug(MODULE_NAME, "Found Wii U disc key sidecar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_imageInfo.ReadableMediaTags = [.._mediaTags.Keys];
|
||||||
|
|
||||||
|
// Set up single track covering the entire disc
|
||||||
|
Tracks =
|
||||||
|
[
|
||||||
|
new Track
|
||||||
|
{
|
||||||
|
Sequence = 1,
|
||||||
|
Session = 1,
|
||||||
|
Type = TrackType.Data,
|
||||||
|
StartSector = 0,
|
||||||
|
EndSector = _imageInfo.Sectors - 1,
|
||||||
|
Pregap = 0,
|
||||||
|
FileType = "BINARY",
|
||||||
|
Filter = imageFilter,
|
||||||
|
File = imageFilter.Filename
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
Sessions =
|
||||||
|
[
|
||||||
|
new Session
|
||||||
|
{
|
||||||
|
Sequence = 1,
|
||||||
|
StartSector = 0,
|
||||||
|
EndSector = _imageInfo.Sectors - 1,
|
||||||
|
StartTrack = 1,
|
||||||
|
EndTrack = 1
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
Partitions =
|
||||||
|
[
|
||||||
|
new Partition
|
||||||
|
{
|
||||||
|
Sequence = 0,
|
||||||
|
Start = 0,
|
||||||
|
Length = _imageInfo.Sectors,
|
||||||
|
Size = _imageInfo.Sectors * _imageInfo.SectorSize,
|
||||||
|
Offset = 0,
|
||||||
|
Type = "Nintendo Wii U Optical Disc"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return ErrorNumber.NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ErrorNumber ReadMediaTag(MediaTagType tag, out byte[] buffer)
|
||||||
|
{
|
||||||
|
buffer = null;
|
||||||
|
|
||||||
|
if(!_mediaTags.TryGetValue(tag, out byte[] data)) return ErrorNumber.NoData;
|
||||||
|
|
||||||
|
buffer = new byte[data.Length];
|
||||||
|
Array.Copy(data, buffer, data.Length);
|
||||||
|
|
||||||
|
return ErrorNumber.NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ErrorNumber ReadSector(ulong sectorAddress, bool negative, out byte[] buffer, out SectorStatus sectorStatus)
|
||||||
|
{
|
||||||
|
buffer = null;
|
||||||
|
sectorStatus = SectorStatus.NotDumped;
|
||||||
|
|
||||||
|
if(negative) return ErrorNumber.InvalidArgument;
|
||||||
|
|
||||||
|
if(sectorAddress >= _imageInfo.Sectors) return ErrorNumber.OutOfRange;
|
||||||
|
|
||||||
|
// Map logical sector to position within WUX
|
||||||
|
var physicalSector = (uint)(sectorAddress / LOGICAL_PER_PHYSICAL);
|
||||||
|
var sectorOffset = (uint)(sectorAddress % LOGICAL_PER_PHYSICAL);
|
||||||
|
|
||||||
|
if(physicalSector >= _sectorCount) return ErrorNumber.OutOfRange;
|
||||||
|
|
||||||
|
uint mappedSector = _sectorIndex[physicalSector];
|
||||||
|
|
||||||
|
ulong fileOffset = _dataOffset +
|
||||||
|
(ulong)mappedSector * WIIU_PHYSICAL_SECTOR +
|
||||||
|
(ulong)sectorOffset * WIIU_LOGICAL_SECTOR;
|
||||||
|
|
||||||
|
buffer = new byte[WIIU_LOGICAL_SECTOR];
|
||||||
|
|
||||||
|
Stream stream = _imageFilter.GetDataForkStream();
|
||||||
|
stream.Seek((long)fileOffset, SeekOrigin.Begin);
|
||||||
|
stream.EnsureRead(buffer, 0, (int)WIIU_LOGICAL_SECTOR);
|
||||||
|
|
||||||
|
sectorStatus = SectorStatus.Dumped;
|
||||||
|
|
||||||
|
return ErrorNumber.NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ErrorNumber ReadSectorLong(ulong sectorAddress, bool negative, out byte[] buffer,
|
||||||
|
out SectorStatus sectorStatus) =>
|
||||||
|
ReadSector(sectorAddress, negative, out buffer, out sectorStatus);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ErrorNumber ReadSectors(ulong sectorAddress, bool negative, uint length, out byte[] buffer,
|
||||||
|
out SectorStatus[] sectorStatus)
|
||||||
|
{
|
||||||
|
buffer = null;
|
||||||
|
sectorStatus = null;
|
||||||
|
|
||||||
|
if(negative) return ErrorNumber.InvalidArgument;
|
||||||
|
|
||||||
|
if(sectorAddress + length > _imageInfo.Sectors) return ErrorNumber.OutOfRange;
|
||||||
|
|
||||||
|
buffer = new byte[length * WIIU_LOGICAL_SECTOR];
|
||||||
|
sectorStatus = new SectorStatus[length];
|
||||||
|
|
||||||
|
for(uint i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
ErrorNumber errno = ReadSector(sectorAddress + i, false, out byte[] sector, out SectorStatus status);
|
||||||
|
|
||||||
|
if(errno != ErrorNumber.NoError) return errno;
|
||||||
|
|
||||||
|
Array.Copy(sector, 0, buffer, i * WIIU_LOGICAL_SECTOR, WIIU_LOGICAL_SECTOR);
|
||||||
|
sectorStatus[i] = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ErrorNumber.NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ErrorNumber ReadSectorsLong(ulong sectorAddress, bool negative, uint length, out byte[] buffer,
|
||||||
|
out SectorStatus[] sectorStatus) =>
|
||||||
|
ReadSectors(sectorAddress, negative, length, out buffer, out sectorStatus);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ErrorNumber ReadSectorTag(ulong sectorAddress, bool negative, SectorTagType tag, out byte[] buffer)
|
||||||
|
{
|
||||||
|
buffer = null;
|
||||||
|
|
||||||
|
return ErrorNumber.NotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ErrorNumber ReadSectorsTag(ulong sectorAddress, bool negative, uint length, SectorTagType tag,
|
||||||
|
out byte[] buffer)
|
||||||
|
{
|
||||||
|
buffer = null;
|
||||||
|
|
||||||
|
return ErrorNumber.NotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ErrorNumber ReadSector(ulong sectorAddress, uint track, out byte[] buffer, out SectorStatus sectorStatus) =>
|
||||||
|
ReadSector(sectorAddress, false, out buffer, out sectorStatus);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ErrorNumber ReadSectorLong(ulong sectorAddress, uint track, out byte[] buffer,
|
||||||
|
out SectorStatus sectorStatus) =>
|
||||||
|
ReadSector(sectorAddress, false, out buffer, out sectorStatus);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ErrorNumber ReadSectors(ulong sectorAddress, uint length, uint track, out byte[] buffer,
|
||||||
|
out SectorStatus[] sectorStatus) =>
|
||||||
|
ReadSectors(sectorAddress, false, length, out buffer, out sectorStatus);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ErrorNumber ReadSectorsLong(ulong sectorAddress, uint length, uint track, out byte[] buffer,
|
||||||
|
out SectorStatus[] sectorStatus) =>
|
||||||
|
ReadSectors(sectorAddress, false, length, out buffer, out sectorStatus);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ErrorNumber ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag, out byte[] buffer)
|
||||||
|
{
|
||||||
|
buffer = null;
|
||||||
|
|
||||||
|
return ErrorNumber.NotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ErrorNumber ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag,
|
||||||
|
out byte[] buffer)
|
||||||
|
{
|
||||||
|
buffer = null;
|
||||||
|
|
||||||
|
return ErrorNumber.NotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public List<Track> GetSessionTracks(Session session) => Tracks;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public List<Track> GetSessionTracks(ushort session) => Tracks;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
60
Aaru.Images/WUX/Structs.cs
Normal file
60
Aaru.Images/WUX/Structs.cs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// Aaru Data Preservation Suite
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : Structs.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Component : Disc image plugins.
|
||||||
|
//
|
||||||
|
// --[ Description ] ----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Contains structures for Nintendo Wii U compressed disc images (WUX format).
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2026 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Aaru.Images;
|
||||||
|
|
||||||
|
public sealed partial class Wux
|
||||||
|
{
|
||||||
|
#region Nested type: WuxHeader
|
||||||
|
|
||||||
|
/// <summary>WUX file header, 32 bytes, all fields little-endian</summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct WuxHeader
|
||||||
|
{
|
||||||
|
/// <summary>Offset 0x00, "WUX0" magic (0x30585557 LE)</summary>
|
||||||
|
public uint Magic;
|
||||||
|
/// <summary>Offset 0x04, reserved / version</summary>
|
||||||
|
public uint Reserved;
|
||||||
|
/// <summary>Offset 0x08, sector size (must be 0x8000)</summary>
|
||||||
|
public uint SectorSize;
|
||||||
|
/// <summary>Offset 0x0C, must be 0</summary>
|
||||||
|
public uint Reserved2;
|
||||||
|
/// <summary>Offset 0x10, uncompressed disc size in bytes</summary>
|
||||||
|
public ulong UncompressedSize;
|
||||||
|
/// <summary>Offset 0x18, must be 0</summary>
|
||||||
|
public ulong Reserved3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
62
Aaru.Images/WUX/Verify.cs
Normal file
62
Aaru.Images/WUX/Verify.cs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// Aaru Data Preservation Suite
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : Verify.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Component : Disc image plugins.
|
||||||
|
//
|
||||||
|
// --[ Description ] ----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Verifies Nintendo Wii U compressed disc images (WUX format).
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2026 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Aaru.Images;
|
||||||
|
|
||||||
|
public sealed partial class Wux
|
||||||
|
{
|
||||||
|
#region IOpticalMediaImage Members
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool? VerifySector(ulong sectorAddress) => null;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
|
||||||
|
out List<ulong> unknownLbas)
|
||||||
|
{
|
||||||
|
failingLbas = [];
|
||||||
|
unknownLbas = [];
|
||||||
|
|
||||||
|
for(ulong i = 0; i < length; i++) unknownLbas.Add(sectorAddress + i);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
|
||||||
|
out List<ulong> unknownLbas) =>
|
||||||
|
VerifySectors(sectorAddress, length, out failingLbas, out unknownLbas);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
76
Aaru.Images/WUX/WUX.cs
Normal file
76
Aaru.Images/WUX/WUX.cs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// Aaru Data Preservation Suite
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : WUX.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Component : Disc image plugins.
|
||||||
|
//
|
||||||
|
// --[ Description ] ----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Manages Nintendo Wii U compressed disc images (WUX format).
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2026 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Aaru.CommonTypes.Enums;
|
||||||
|
using Aaru.CommonTypes.Interfaces;
|
||||||
|
using Aaru.CommonTypes.Structs;
|
||||||
|
|
||||||
|
namespace Aaru.Images;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
/// <summary>Implements reading Nintendo Wii U compressed disc images (WUX format)</summary>
|
||||||
|
public sealed partial class Wux : IOpticalMediaImage
|
||||||
|
{
|
||||||
|
const string MODULE_NAME = "WUX plugin";
|
||||||
|
ulong _dataOffset;
|
||||||
|
IFilter _imageFilter;
|
||||||
|
ImageInfo _imageInfo;
|
||||||
|
|
||||||
|
Dictionary<MediaTagType, byte[]> _mediaTags;
|
||||||
|
uint _sectorCount;
|
||||||
|
uint[] _sectorIndex;
|
||||||
|
|
||||||
|
public Wux() => _imageInfo = new ImageInfo
|
||||||
|
{
|
||||||
|
ReadableSectorTags = [],
|
||||||
|
ReadableMediaTags = [],
|
||||||
|
HasPartitions = true,
|
||||||
|
HasSessions = true,
|
||||||
|
Version = null,
|
||||||
|
Application = null,
|
||||||
|
ApplicationVersion = null,
|
||||||
|
Creator = null,
|
||||||
|
Comments = null,
|
||||||
|
MediaManufacturer = null,
|
||||||
|
MediaModel = null,
|
||||||
|
MediaSerialNumber = null,
|
||||||
|
MediaBarcode = null,
|
||||||
|
MediaPartNumber = null,
|
||||||
|
MediaSequence = 0,
|
||||||
|
LastMediaSequence = 0,
|
||||||
|
DriveManufacturer = null,
|
||||||
|
DriveModel = null,
|
||||||
|
DriveSerialNumber = null,
|
||||||
|
DriveFirmwareRevision = null
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -112,6 +112,7 @@ Media image formats we can read
|
|||||||
* TeleDisk
|
* TeleDisk
|
||||||
* UltraISO (.ISZ)
|
* UltraISO (.ISZ)
|
||||||
* WinOnCD (.C2D)
|
* WinOnCD (.C2D)
|
||||||
|
* WUX
|
||||||
* X68k DIM disk image files (.DIM)
|
* X68k DIM disk image files (.DIM)
|
||||||
|
|
||||||
Media image formats we can write to
|
Media image formats we can write to
|
||||||
|
|||||||
Reference in New Issue
Block a user