mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
REFACTOR: Final cleanup of DiscImageChef.Filters.
This commit is contained in:
@@ -38,117 +38,35 @@ using System.Runtime.InteropServices;
|
|||||||
namespace DiscImageChef.Filters
|
namespace DiscImageChef.Filters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decodes AppleDouble files
|
/// Decodes AppleDouble files
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AppleDouble : Filter
|
public class AppleDouble : Filter
|
||||||
{
|
{
|
||||||
enum AppleDoubleEntryID : uint
|
|
||||||
{
|
|
||||||
Invalid = 0,
|
|
||||||
DataFork = 1,
|
|
||||||
ResourceFork = 2,
|
|
||||||
RealName = 3,
|
|
||||||
Comment = 4,
|
|
||||||
Icon = 5,
|
|
||||||
ColorIcon = 6,
|
|
||||||
FileInfo = 7,
|
|
||||||
FileDates = 8,
|
|
||||||
FinderInfo = 9,
|
|
||||||
MacFileInfo = 10,
|
|
||||||
ProDOSFileInfo = 11,
|
|
||||||
DOSFileInfo = 12,
|
|
||||||
ShortName = 13,
|
|
||||||
AFPFileInfo = 14,
|
|
||||||
DirectoryID = 15
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct AppleDoubleHeader
|
|
||||||
{
|
|
||||||
public uint magic;
|
|
||||||
public uint version;
|
|
||||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] homeFilesystem;
|
|
||||||
public ushort entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct AppleDoubleEntry
|
|
||||||
{
|
|
||||||
public uint id;
|
|
||||||
public uint offset;
|
|
||||||
public uint length;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct AppleDoubleFileDates
|
|
||||||
{
|
|
||||||
public uint creationDate;
|
|
||||||
public uint modificationDate;
|
|
||||||
public uint backupDate;
|
|
||||||
public uint accessDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct AppleDoubleMacFileInfo
|
|
||||||
{
|
|
||||||
public uint creationDate;
|
|
||||||
public uint modificationDate;
|
|
||||||
public uint backupDate;
|
|
||||||
public uint accessDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct AppleDoubleUNIXFileInfo
|
|
||||||
{
|
|
||||||
public uint creationDate;
|
|
||||||
public uint accessDate;
|
|
||||||
public uint modificationDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct AppleDoubleDOSFileInfo
|
|
||||||
{
|
|
||||||
public ushort modificationDate;
|
|
||||||
public ushort modificationTime;
|
|
||||||
public ushort attributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct AppleDoubleProDOSFileInfo
|
|
||||||
{
|
|
||||||
public uint creationDate;
|
|
||||||
public uint modificationDate;
|
|
||||||
public uint backupDate;
|
|
||||||
public ushort access;
|
|
||||||
public ushort fileType;
|
|
||||||
public uint auxType;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint AppleDoubleMagic = 0x00051607;
|
const uint AppleDoubleMagic = 0x00051607;
|
||||||
const uint AppleDoubleVersion = 0x00010000;
|
const uint AppleDoubleVersion = 0x00010000;
|
||||||
const uint AppleDoubleVersion2 = 0x00020000;
|
const uint AppleDoubleVersion2 = 0x00020000;
|
||||||
|
readonly byte[] DOSHome =
|
||||||
|
{0x4D, 0x53, 0x2D, 0x44, 0x4F, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
||||||
|
|
||||||
readonly byte[] MacintoshHome =
|
readonly byte[] MacintoshHome =
|
||||||
{0x4D, 0x61, 0x63, 0x69, 0x6E, 0x74, 0x6F, 0x73, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
{0x4D, 0x61, 0x63, 0x69, 0x6E, 0x74, 0x6F, 0x73, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
||||||
|
readonly byte[] OSXHome =
|
||||||
|
{0x4D, 0x61, 0x63, 0x20, 0x4F, 0x53, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
||||||
readonly byte[] ProDOSHome =
|
readonly byte[] ProDOSHome =
|
||||||
{0x50, 0x72, 0x6F, 0x44, 0x4F, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
{0x50, 0x72, 0x6F, 0x44, 0x4F, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
||||||
readonly byte[] DOSHome =
|
|
||||||
{0x4D, 0x53, 0x2D, 0x44, 0x4F, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
|
||||||
readonly byte[] UNIXHome =
|
readonly byte[] UNIXHome =
|
||||||
{0x55, 0x6E, 0x69, 0x78, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
{0x55, 0x6E, 0x69, 0x78, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
||||||
readonly byte[] VMXHome =
|
readonly byte[] VMXHome =
|
||||||
{0x56, 0x41, 0x58, 0x20, 0x56, 0x4D, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
{0x56, 0x41, 0x58, 0x20, 0x56, 0x4D, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
||||||
readonly byte[] OSXHome =
|
string basePath;
|
||||||
{0x4D, 0x61, 0x63, 0x20, 0x4F, 0x53, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
DateTime creationTime;
|
||||||
|
|
||||||
AppleDoubleEntry dataFork;
|
AppleDoubleEntry dataFork;
|
||||||
AppleDoubleEntry rsrcFork;
|
AppleDoubleHeader header;
|
||||||
bool opened;
|
|
||||||
string basePath;
|
|
||||||
string headerPath;
|
string headerPath;
|
||||||
DateTime lastWriteTime;
|
DateTime lastWriteTime;
|
||||||
DateTime creationTime;
|
bool opened;
|
||||||
AppleDoubleHeader header;
|
AppleDoubleEntry rsrcFork;
|
||||||
|
|
||||||
public AppleDouble()
|
public AppleDouble()
|
||||||
{
|
{
|
||||||
@@ -263,7 +181,8 @@ namespace DiscImageChef.Filters
|
|||||||
UNIXAppleDouble = Path.Combine(parentFolder, "%" + filename);
|
UNIXAppleDouble = Path.Combine(parentFolder, "%" + filename);
|
||||||
DOSAppleDouble = Path.Combine(parentFolder, filenameNoExt + ".ADF");
|
DOSAppleDouble = Path.Combine(parentFolder, filenameNoExt + ".ADF");
|
||||||
DOSAppleDoubleLower = Path.Combine(parentFolder, filenameNoExt + ".adf");
|
DOSAppleDoubleLower = Path.Combine(parentFolder, filenameNoExt + ".adf");
|
||||||
NetatalkAppleDouble = Path.Combine(parentFolder, ".AppleDouble", filename ?? throw new InvalidOperationException());
|
NetatalkAppleDouble = Path.Combine(parentFolder, ".AppleDouble",
|
||||||
|
filename ?? throw new InvalidOperationException());
|
||||||
DAVEAppleDouble = Path.Combine(parentFolder, "resource.frk", filename);
|
DAVEAppleDouble = Path.Combine(parentFolder, "resource.frk", filename);
|
||||||
OSXAppleDouble = Path.Combine(parentFolder, "._" + filename);
|
OSXAppleDouble = Path.Combine(parentFolder, "._" + filename);
|
||||||
UnArAppleDouble = Path.Combine(parentFolder, filename + ".rsrc");
|
UnArAppleDouble = Path.Combine(parentFolder, filename + ".rsrc");
|
||||||
@@ -431,7 +350,8 @@ namespace DiscImageChef.Filters
|
|||||||
UNIXAppleDouble = Path.Combine(parentFolder, "%" + filename);
|
UNIXAppleDouble = Path.Combine(parentFolder, "%" + filename);
|
||||||
DOSAppleDouble = Path.Combine(parentFolder, filenameNoExt + ".ADF");
|
DOSAppleDouble = Path.Combine(parentFolder, filenameNoExt + ".ADF");
|
||||||
DOSAppleDoubleLower = Path.Combine(parentFolder, filenameNoExt + ".adf");
|
DOSAppleDoubleLower = Path.Combine(parentFolder, filenameNoExt + ".adf");
|
||||||
NetatalkAppleDouble = Path.Combine(parentFolder, ".AppleDouble", filename ?? throw new InvalidOperationException());
|
NetatalkAppleDouble = Path.Combine(parentFolder, ".AppleDouble",
|
||||||
|
filename ?? throw new InvalidOperationException());
|
||||||
DAVEAppleDouble = Path.Combine(parentFolder, "resource.frk", filename);
|
DAVEAppleDouble = Path.Combine(parentFolder, "resource.frk", filename);
|
||||||
OSXAppleDouble = Path.Combine(parentFolder, "._" + filename);
|
OSXAppleDouble = Path.Combine(parentFolder, "._" + filename);
|
||||||
UnArAppleDouble = Path.Combine(parentFolder, filename + ".rsrc");
|
UnArAppleDouble = Path.Combine(parentFolder, filename + ".rsrc");
|
||||||
@@ -646,5 +566,87 @@ namespace DiscImageChef.Filters
|
|||||||
opened = true;
|
opened = true;
|
||||||
basePath = path;
|
basePath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum AppleDoubleEntryID : uint
|
||||||
|
{
|
||||||
|
Invalid = 0,
|
||||||
|
DataFork = 1,
|
||||||
|
ResourceFork = 2,
|
||||||
|
RealName = 3,
|
||||||
|
Comment = 4,
|
||||||
|
Icon = 5,
|
||||||
|
ColorIcon = 6,
|
||||||
|
FileInfo = 7,
|
||||||
|
FileDates = 8,
|
||||||
|
FinderInfo = 9,
|
||||||
|
MacFileInfo = 10,
|
||||||
|
ProDOSFileInfo = 11,
|
||||||
|
DOSFileInfo = 12,
|
||||||
|
ShortName = 13,
|
||||||
|
AFPFileInfo = 14,
|
||||||
|
DirectoryID = 15
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct AppleDoubleHeader
|
||||||
|
{
|
||||||
|
public uint magic;
|
||||||
|
public uint version;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] homeFilesystem;
|
||||||
|
public ushort entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct AppleDoubleEntry
|
||||||
|
{
|
||||||
|
public uint id;
|
||||||
|
public uint offset;
|
||||||
|
public uint length;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct AppleDoubleFileDates
|
||||||
|
{
|
||||||
|
public uint creationDate;
|
||||||
|
public uint modificationDate;
|
||||||
|
public uint backupDate;
|
||||||
|
public uint accessDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct AppleDoubleMacFileInfo
|
||||||
|
{
|
||||||
|
public uint creationDate;
|
||||||
|
public uint modificationDate;
|
||||||
|
public uint backupDate;
|
||||||
|
public uint accessDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct AppleDoubleUNIXFileInfo
|
||||||
|
{
|
||||||
|
public uint creationDate;
|
||||||
|
public uint accessDate;
|
||||||
|
public uint modificationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct AppleDoubleDOSFileInfo
|
||||||
|
{
|
||||||
|
public ushort modificationDate;
|
||||||
|
public ushort modificationTime;
|
||||||
|
public ushort attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct AppleDoubleProDOSFileInfo
|
||||||
|
{
|
||||||
|
public uint creationDate;
|
||||||
|
public uint modificationDate;
|
||||||
|
public uint backupDate;
|
||||||
|
public ushort access;
|
||||||
|
public ushort fileType;
|
||||||
|
public uint auxType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,118 +38,36 @@ using System.Runtime.InteropServices;
|
|||||||
namespace DiscImageChef.Filters
|
namespace DiscImageChef.Filters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decodes AppleSingle files
|
/// Decodes AppleSingle files
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AppleSingle : Filter
|
public class AppleSingle : Filter
|
||||||
{
|
{
|
||||||
enum AppleSingleEntryID : uint
|
|
||||||
{
|
|
||||||
Invalid = 0,
|
|
||||||
DataFork = 1,
|
|
||||||
ResourceFork = 2,
|
|
||||||
RealName = 3,
|
|
||||||
Comment = 4,
|
|
||||||
Icon = 5,
|
|
||||||
ColorIcon = 6,
|
|
||||||
FileInfo = 7,
|
|
||||||
FileDates = 8,
|
|
||||||
FinderInfo = 9,
|
|
||||||
MacFileInfo = 10,
|
|
||||||
ProDOSFileInfo = 11,
|
|
||||||
DOSFileInfo = 12,
|
|
||||||
ShortName = 13,
|
|
||||||
AFPFileInfo = 14,
|
|
||||||
DirectoryID = 15
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct AppleSingleHeader
|
|
||||||
{
|
|
||||||
public uint magic;
|
|
||||||
public uint version;
|
|
||||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] homeFilesystem;
|
|
||||||
public ushort entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct AppleSingleEntry
|
|
||||||
{
|
|
||||||
public uint id;
|
|
||||||
public uint offset;
|
|
||||||
public uint length;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct AppleSingleFileDates
|
|
||||||
{
|
|
||||||
public uint creationDate;
|
|
||||||
public uint modificationDate;
|
|
||||||
public uint backupDate;
|
|
||||||
public uint accessDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct AppleSingleMacFileInfo
|
|
||||||
{
|
|
||||||
public uint creationDate;
|
|
||||||
public uint modificationDate;
|
|
||||||
public uint backupDate;
|
|
||||||
public uint accessDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct AppleSingleUNIXFileInfo
|
|
||||||
{
|
|
||||||
public uint creationDate;
|
|
||||||
public uint accessDate;
|
|
||||||
public uint modificationDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct AppleSingleDOSFileInfo
|
|
||||||
{
|
|
||||||
public ushort modificationDate;
|
|
||||||
public ushort modificationTime;
|
|
||||||
public ushort attributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct AppleSingleProDOSFileInfo
|
|
||||||
{
|
|
||||||
public uint creationDate;
|
|
||||||
public uint modificationDate;
|
|
||||||
public uint backupDate;
|
|
||||||
public ushort access;
|
|
||||||
public ushort fileType;
|
|
||||||
public uint auxType;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint AppleSingleMagic = 0x00051600;
|
const uint AppleSingleMagic = 0x00051600;
|
||||||
const uint AppleSingleVersion = 0x00010000;
|
const uint AppleSingleVersion = 0x00010000;
|
||||||
const uint AppleSingleVersion2 = 0x00020000;
|
const uint AppleSingleVersion2 = 0x00020000;
|
||||||
|
readonly byte[] DOSHome =
|
||||||
|
{0x4D, 0x53, 0x2D, 0x44, 0x4F, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
||||||
|
|
||||||
readonly byte[] MacintoshHome =
|
readonly byte[] MacintoshHome =
|
||||||
{0x4D, 0x61, 0x63, 0x69, 0x6E, 0x74, 0x6F, 0x73, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
{0x4D, 0x61, 0x63, 0x69, 0x6E, 0x74, 0x6F, 0x73, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
||||||
|
readonly byte[] OSXHome =
|
||||||
|
{0x4D, 0x61, 0x63, 0x20, 0x4F, 0x53, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
||||||
readonly byte[] ProDOSHome =
|
readonly byte[] ProDOSHome =
|
||||||
{0x50, 0x72, 0x6F, 0x44, 0x4F, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
{0x50, 0x72, 0x6F, 0x44, 0x4F, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
||||||
readonly byte[] DOSHome =
|
|
||||||
{0x4D, 0x53, 0x2D, 0x44, 0x4F, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
|
||||||
readonly byte[] UNIXHome =
|
readonly byte[] UNIXHome =
|
||||||
{0x55, 0x6E, 0x69, 0x78, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
{0x55, 0x6E, 0x69, 0x78, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
||||||
readonly byte[] VMSHome =
|
readonly byte[] VMSHome =
|
||||||
{0x56, 0x41, 0x58, 0x20, 0x56, 0x4D, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
{0x56, 0x41, 0x58, 0x20, 0x56, 0x4D, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
||||||
readonly byte[] OSXHome =
|
string basePath;
|
||||||
{0x4D, 0x61, 0x63, 0x20, 0x4F, 0x53, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
|
byte[] bytes;
|
||||||
|
DateTime creationTime;
|
||||||
|
|
||||||
AppleSingleEntry dataFork;
|
AppleSingleEntry dataFork;
|
||||||
AppleSingleEntry rsrcFork;
|
|
||||||
byte[] bytes;
|
|
||||||
Stream stream;
|
|
||||||
bool isBytes, isStream, isPath, opened;
|
|
||||||
string basePath;
|
|
||||||
DateTime lastWriteTime;
|
|
||||||
DateTime creationTime;
|
|
||||||
AppleSingleHeader header;
|
AppleSingleHeader header;
|
||||||
|
bool isBytes, isStream, isPath, opened;
|
||||||
|
DateTime lastWriteTime;
|
||||||
|
AppleSingleEntry rsrcFork;
|
||||||
|
Stream stream;
|
||||||
|
|
||||||
public AppleSingle()
|
public AppleSingle()
|
||||||
{
|
{
|
||||||
@@ -519,5 +437,87 @@ namespace DiscImageChef.Filters
|
|||||||
isPath = true;
|
isPath = true;
|
||||||
basePath = path;
|
basePath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum AppleSingleEntryID : uint
|
||||||
|
{
|
||||||
|
Invalid = 0,
|
||||||
|
DataFork = 1,
|
||||||
|
ResourceFork = 2,
|
||||||
|
RealName = 3,
|
||||||
|
Comment = 4,
|
||||||
|
Icon = 5,
|
||||||
|
ColorIcon = 6,
|
||||||
|
FileInfo = 7,
|
||||||
|
FileDates = 8,
|
||||||
|
FinderInfo = 9,
|
||||||
|
MacFileInfo = 10,
|
||||||
|
ProDOSFileInfo = 11,
|
||||||
|
DOSFileInfo = 12,
|
||||||
|
ShortName = 13,
|
||||||
|
AFPFileInfo = 14,
|
||||||
|
DirectoryID = 15
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct AppleSingleHeader
|
||||||
|
{
|
||||||
|
public uint magic;
|
||||||
|
public uint version;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] homeFilesystem;
|
||||||
|
public ushort entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct AppleSingleEntry
|
||||||
|
{
|
||||||
|
public uint id;
|
||||||
|
public uint offset;
|
||||||
|
public uint length;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct AppleSingleFileDates
|
||||||
|
{
|
||||||
|
public uint creationDate;
|
||||||
|
public uint modificationDate;
|
||||||
|
public uint backupDate;
|
||||||
|
public uint accessDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct AppleSingleMacFileInfo
|
||||||
|
{
|
||||||
|
public uint creationDate;
|
||||||
|
public uint modificationDate;
|
||||||
|
public uint backupDate;
|
||||||
|
public uint accessDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct AppleSingleUNIXFileInfo
|
||||||
|
{
|
||||||
|
public uint creationDate;
|
||||||
|
public uint accessDate;
|
||||||
|
public uint modificationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct AppleSingleDOSFileInfo
|
||||||
|
{
|
||||||
|
public ushort modificationDate;
|
||||||
|
public ushort modificationTime;
|
||||||
|
public ushort attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct AppleSingleProDOSFileInfo
|
||||||
|
{
|
||||||
|
public uint creationDate;
|
||||||
|
public uint modificationDate;
|
||||||
|
public uint backupDate;
|
||||||
|
public ushort access;
|
||||||
|
public ushort fileType;
|
||||||
|
public uint auxType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,17 +38,17 @@ using SharpCompress.Compressors.BZip2;
|
|||||||
namespace DiscImageChef.Filters
|
namespace DiscImageChef.Filters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decompress bz2 files while reading
|
/// Decompress bz2 files while reading
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BZip2 : Filter
|
public class BZip2 : Filter
|
||||||
{
|
{
|
||||||
Stream dataStream;
|
|
||||||
string basePath;
|
string basePath;
|
||||||
DateTime lastWriteTime;
|
|
||||||
DateTime creationTime;
|
DateTime creationTime;
|
||||||
bool opened;
|
Stream dataStream;
|
||||||
long decompressedSize;
|
long decompressedSize;
|
||||||
Stream innerStream;
|
Stream innerStream;
|
||||||
|
DateTime lastWriteTime;
|
||||||
|
bool opened;
|
||||||
|
|
||||||
public BZip2()
|
public BZip2()
|
||||||
{
|
{
|
||||||
@@ -96,7 +96,8 @@ namespace DiscImageChef.Filters
|
|||||||
|
|
||||||
if(buffer.Length <= 512) return true;
|
if(buffer.Length <= 512) return true;
|
||||||
|
|
||||||
return buffer[buffer.Length - 512] != 0x6B || buffer[buffer.Length - 511] != 0x6F || buffer[buffer.Length - 510] != 0x6C || buffer[buffer.Length - 509] != 0x79;
|
return buffer[buffer.Length - 512] != 0x6B || buffer[buffer.Length - 511] != 0x6F ||
|
||||||
|
buffer[buffer.Length - 510] != 0x6C || buffer[buffer.Length - 509] != 0x79;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Identify(Stream stream)
|
public override bool Identify(Stream stream)
|
||||||
@@ -139,8 +140,7 @@ namespace DiscImageChef.Filters
|
|||||||
stream.Read(buffer, 0, 4);
|
stream.Read(buffer, 0, 4);
|
||||||
stream.Seek(0, SeekOrigin.Begin);
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
// Check it is not an UDIF
|
// Check it is not an UDIF
|
||||||
if(buffer[0] == 0x6B && buffer[1] == 0x6F && buffer[2] == 0x6C && buffer[3] == 0x79)
|
if(buffer[0] == 0x6B && buffer[1] == 0x6F && buffer[2] == 0x6C && buffer[3] == 0x79) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,126 +41,127 @@ namespace DiscImageChef.Filters
|
|||||||
public Guid UUID;
|
public Guid UUID;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Closes all opened streams.
|
/// Closes all opened streams.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract void Close();
|
public abstract void Close();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the path used to open this filter.<br/>
|
/// Gets the path used to open this filter.<br />
|
||||||
/// UNIX: /path/to/archive.zip/path/to/file.bin => /path/to/archive.zip/path/to/file.bin <br/>
|
/// UNIX: /path/to/archive.zip/path/to/file.bin => /path/to/archive.zip/path/to/file.bin <br />
|
||||||
/// Windows: C:\path\to\archive.zip\path\to\file.bin => C:\path\to\archive.zip\path\to\file.bin
|
/// Windows: C:\path\to\archive.zip\path\to\file.bin => C:\path\to\archive.zip\path\to\file.bin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Path used to open this filter.</returns>
|
/// <returns>Path used to open this filter.</returns>
|
||||||
public abstract string GetBasePath();
|
public abstract string GetBasePath();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets creation time of file referenced by this filter.
|
/// Gets creation time of file referenced by this filter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The creation time.</returns>
|
/// <returns>The creation time.</returns>
|
||||||
public abstract DateTime GetCreationTime();
|
public abstract DateTime GetCreationTime();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets length of this filter's data fork.
|
/// Gets length of this filter's data fork.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The data fork length.</returns>
|
/// <returns>The data fork length.</returns>
|
||||||
public abstract long GetDataForkLength();
|
public abstract long GetDataForkLength();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a stream to access the data fork contents.
|
/// Gets a stream to access the data fork contents.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The data fork stream.</returns>
|
/// <returns>The data fork stream.</returns>
|
||||||
public abstract Stream GetDataForkStream();
|
public abstract Stream GetDataForkStream();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the filename for the file referenced by this filter.<br/>
|
/// Gets the filename for the file referenced by this filter.<br />
|
||||||
/// UNIX: /path/to/archive.zip/path/to/file.bin => file.bin <br/>
|
/// UNIX: /path/to/archive.zip/path/to/file.bin => file.bin <br />
|
||||||
/// Windows: C:\path\to\archive.zip\path\to\file.bin => file.bin
|
/// Windows: C:\path\to\archive.zip\path\to\file.bin => file.bin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The filename.</returns>
|
/// <returns>The filename.</returns>
|
||||||
public abstract string GetFilename();
|
public abstract string GetFilename();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets last write time of file referenced by this filter.
|
/// Gets last write time of file referenced by this filter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The last write time.</returns>
|
/// <returns>The last write time.</returns>
|
||||||
public abstract DateTime GetLastWriteTime();
|
public abstract DateTime GetLastWriteTime();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets length of file referenced by ths filter.
|
/// Gets length of file referenced by ths filter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The length.</returns>
|
/// <returns>The length.</returns>
|
||||||
public abstract long GetLength();
|
public abstract long GetLength();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets full path to file referenced by this filter. If it's an archive, it's the path inside the archive.<br/>
|
/// Gets full path to file referenced by this filter. If it's an archive, it's the path inside the archive.<br />
|
||||||
/// UNIX: /path/to/archive.zip/path/to/file.bin => /path/to/file.bin <br/>
|
/// UNIX: /path/to/archive.zip/path/to/file.bin => /path/to/file.bin <br />
|
||||||
/// Windows: C:\path\to\archive.zip\path\to\file.bin => \path\to\file.bin
|
/// Windows: C:\path\to\archive.zip\path\to\file.bin => \path\to\file.bin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The path.</returns>
|
/// <returns>The path.</returns>
|
||||||
public abstract string GetPath();
|
public abstract string GetPath();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets path to parent folder to the file referenced by this filter. If it's an archive, it's the full path to the archive itself.<br/>
|
/// Gets path to parent folder to the file referenced by this filter. If it's an archive, it's the full path to the
|
||||||
/// UNIX: /path/to/archive.zip/path/to/file.bin => /path/to/archive.zip <br/>
|
/// archive itself.<br />
|
||||||
/// Windows: C:\path\to\archive.zip\path\to\file.bin => C:\path\to\archive.zip
|
/// UNIX: /path/to/archive.zip/path/to/file.bin => /path/to/archive.zip <br />
|
||||||
|
/// Windows: C:\path\to\archive.zip\path\to\file.bin => C:\path\to\archive.zip
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The parent folder.</returns>
|
/// <returns>The parent folder.</returns>
|
||||||
public abstract string GetParentFolder();
|
public abstract string GetParentFolder();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets length of this filter's resource fork.
|
/// Gets length of this filter's resource fork.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The resource fork length.</returns>
|
/// <returns>The resource fork length.</returns>
|
||||||
public abstract long GetResourceForkLength();
|
public abstract long GetResourceForkLength();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a stream to access the resource fork contents.
|
/// Gets a stream to access the resource fork contents.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The resource fork stream.</returns>
|
/// <returns>The resource fork stream.</returns>
|
||||||
public abstract Stream GetResourceForkStream();
|
public abstract Stream GetResourceForkStream();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if the file referenced by this filter has a resource fork
|
/// Returns true if the file referenced by this filter has a resource fork
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract bool HasResourceFork();
|
public abstract bool HasResourceFork();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Identifies if the specified path contains data recognizable by this filter instance
|
/// Identifies if the specified path contains data recognizable by this filter instance
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">Path.</param>
|
/// <param name="path">Path.</param>
|
||||||
public abstract bool Identify(string path);
|
public abstract bool Identify(string path);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Identifies if the specified stream contains data recognizable by this filter instance
|
/// Identifies if the specified stream contains data recognizable by this filter instance
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stream">Stream.</param>
|
/// <param name="stream">Stream.</param>
|
||||||
public abstract bool Identify(Stream stream);
|
public abstract bool Identify(Stream stream);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Identifies if the specified buffer contains data recognizable by this filter instance
|
/// Identifies if the specified buffer contains data recognizable by this filter instance
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="buffer">Buffer.</param>
|
/// <param name="buffer">Buffer.</param>
|
||||||
public abstract bool Identify(byte[] buffer);
|
public abstract bool Identify(byte[] buffer);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if the filter has a file/stream/buffer currently opened and no <see cref="Close"/> has been issued.
|
/// Returns true if the filter has a file/stream/buffer currently opened and no <see cref="Close" /> has been issued.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract bool IsOpened();
|
public abstract bool IsOpened();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens the specified path with this filter instance
|
/// Opens the specified path with this filter instance
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">Path.</param>
|
/// <param name="path">Path.</param>
|
||||||
public abstract void Open(string path);
|
public abstract void Open(string path);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens the specified stream with this filter instance
|
/// Opens the specified stream with this filter instance
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stream">Stream.</param>
|
/// <param name="stream">Stream.</param>
|
||||||
public abstract void Open(Stream stream);
|
public abstract void Open(Stream stream);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens the specified buffer with this filter instance
|
/// Opens the specified buffer with this filter instance
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="buffer">Buffer.</param>
|
/// <param name="buffer">Buffer.</param>
|
||||||
public abstract void Open(byte[] buffer);
|
public abstract void Open(byte[] buffer);
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace DiscImageChef.Filters
|
|||||||
public SortedDictionary<string, Filter> Filters;
|
public SortedDictionary<string, Filter> Filters;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fills the list of all known filters
|
/// Fills the list of all known filters
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public FiltersList()
|
public FiltersList()
|
||||||
{
|
{
|
||||||
@@ -55,13 +55,14 @@ namespace DiscImageChef.Filters
|
|||||||
if(!type.IsSubclassOf(typeof(Filter))) continue;
|
if(!type.IsSubclassOf(typeof(Filter))) continue;
|
||||||
|
|
||||||
Filter filter = (Filter)type.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { });
|
Filter filter = (Filter)type.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { });
|
||||||
if(filter != null && !Filters.ContainsKey(filter.Name.ToLower())) Filters.Add(filter.Name.ToLower(), filter);
|
if(filter != null && !Filters.ContainsKey(filter.Name.ToLower()))
|
||||||
|
Filters.Add(filter.Name.ToLower(), filter);
|
||||||
}
|
}
|
||||||
catch(Exception exception) { DicConsole.ErrorWriteLine("Exception {0}", exception); }
|
catch(Exception exception) { DicConsole.ErrorWriteLine("Exception {0}", exception); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the filter that allows to read the specified path
|
/// Gets the filter that allows to read the specified path
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">Path</param>
|
/// <param name="path">Path</param>
|
||||||
/// <returns>The filter that allows reading the specified path</returns>
|
/// <returns>The filter that allows reading the specified path</returns>
|
||||||
@@ -91,7 +92,7 @@ namespace DiscImageChef.Filters
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets all known filters
|
/// Gets all known filters
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Known filters</returns>
|
/// <returns>Known filters</returns>
|
||||||
public SortedDictionary<string, Filter> GetFiltersList()
|
public SortedDictionary<string, Filter> GetFiltersList()
|
||||||
|
|||||||
@@ -36,19 +36,19 @@ using System.IO;
|
|||||||
namespace DiscImageChef.Filters
|
namespace DiscImageChef.Filters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ForcedSeekStream allows to seek a forward-readable stream (like System.IO.Compression streams)
|
/// ForcedSeekStream allows to seek a forward-readable stream (like System.IO.Compression streams)
|
||||||
/// by doing the slow and known trick of rewinding and forward reading until arriving the desired position.
|
/// by doing the slow and known trick of rewinding and forward reading until arriving the desired position.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ForcedSeekStream<T> : Stream where T : Stream
|
public class ForcedSeekStream<T> : Stream where T : Stream
|
||||||
{
|
{
|
||||||
|
const int BUFFER_LEN = 1048576;
|
||||||
|
string backFile;
|
||||||
|
FileStream backStream;
|
||||||
T baseStream;
|
T baseStream;
|
||||||
long streamLength;
|
long streamLength;
|
||||||
const int BUFFER_LEN = 1048576;
|
|
||||||
FileStream backStream;
|
|
||||||
string backFile;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="T:DiscImageChef.Filters.ForcedSeekStream`1"/> class.
|
/// Initializes a new instance of the <see cref="T:DiscImageChef.Filters.ForcedSeekStream`1" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="length">The real (uncompressed) length of the stream.</param>
|
/// <param name="length">The real (uncompressed) length of the stream.</param>
|
||||||
/// <param name="args">Parameters that are used to create the base stream.</param>
|
/// <param name="args">Parameters that are used to create the base stream.</param>
|
||||||
@@ -62,7 +62,7 @@ namespace DiscImageChef.Filters
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="T:DiscImageChef.Filters.ForcedSeekStream`1"/> class.
|
/// Initializes a new instance of the <see cref="T:DiscImageChef.Filters.ForcedSeekStream`1" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="args">Parameters that are used to create the base stream.</param>
|
/// <param name="args">Parameters that are used to create the base stream.</param>
|
||||||
public ForcedSeekStream(params object[] args)
|
public ForcedSeekStream(params object[] args)
|
||||||
@@ -73,27 +73,6 @@ namespace DiscImageChef.Filters
|
|||||||
CalculateLength();
|
CalculateLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Calculates the real (uncompressed) length of the stream.
|
|
||||||
/// It basically reads (uncompresses) the whole stream to memory discarding its contents,
|
|
||||||
/// so it should be used as a last resort.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The length.</returns>
|
|
||||||
public void CalculateLength()
|
|
||||||
{
|
|
||||||
int read;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
byte[] buffer = new byte[BUFFER_LEN];
|
|
||||||
read = baseStream.Read(buffer, 0, BUFFER_LEN);
|
|
||||||
backStream.Write(buffer, 0, read);
|
|
||||||
}
|
|
||||||
while(read == BUFFER_LEN);
|
|
||||||
|
|
||||||
streamLength = backStream.Length;
|
|
||||||
backStream.Position = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool CanRead => baseStream.CanRead;
|
public override bool CanRead => baseStream.CanRead;
|
||||||
|
|
||||||
public override bool CanSeek => true;
|
public override bool CanSeek => true;
|
||||||
@@ -109,6 +88,27 @@ namespace DiscImageChef.Filters
|
|||||||
set => SetPosition(value);
|
set => SetPosition(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the real (uncompressed) length of the stream.
|
||||||
|
/// It basically reads (uncompresses) the whole stream to memory discarding its contents,
|
||||||
|
/// so it should be used as a last resort.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The length.</returns>
|
||||||
|
public void CalculateLength()
|
||||||
|
{
|
||||||
|
int read;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[BUFFER_LEN];
|
||||||
|
read = baseStream.Read(buffer, 0, BUFFER_LEN);
|
||||||
|
backStream.Write(buffer, 0, read);
|
||||||
|
}
|
||||||
|
while(read == BUFFER_LEN);
|
||||||
|
|
||||||
|
streamLength = backStream.Length;
|
||||||
|
backStream.Position = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void SetPosition(long position)
|
void SetPosition(long position)
|
||||||
{
|
{
|
||||||
if(position == backStream.Position) return;
|
if(position == backStream.Position) return;
|
||||||
|
|||||||
@@ -37,16 +37,16 @@ using System.IO.Compression;
|
|||||||
namespace DiscImageChef.Filters
|
namespace DiscImageChef.Filters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decompress gzip files while reading
|
/// Decompress gzip files while reading
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GZip : Filter
|
public class GZip : Filter
|
||||||
{
|
{
|
||||||
Stream dataStream;
|
|
||||||
string basePath;
|
string basePath;
|
||||||
DateTime lastWriteTime;
|
|
||||||
DateTime creationTime;
|
DateTime creationTime;
|
||||||
bool opened;
|
Stream dataStream;
|
||||||
uint decompressedSize;
|
uint decompressedSize;
|
||||||
|
DateTime lastWriteTime;
|
||||||
|
bool opened;
|
||||||
Stream zStream;
|
Stream zStream;
|
||||||
|
|
||||||
public GZip()
|
public GZip()
|
||||||
|
|||||||
@@ -38,17 +38,17 @@ using SharpCompress.Compressors.LZMA;
|
|||||||
namespace DiscImageChef.Filters
|
namespace DiscImageChef.Filters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decompress lzip files while reading
|
/// Decompress lzip files while reading
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class LZip : Filter
|
public class LZip : Filter
|
||||||
{
|
{
|
||||||
Stream dataStream;
|
|
||||||
string basePath;
|
string basePath;
|
||||||
DateTime lastWriteTime;
|
|
||||||
DateTime creationTime;
|
DateTime creationTime;
|
||||||
bool opened;
|
Stream dataStream;
|
||||||
long decompressedSize;
|
long decompressedSize;
|
||||||
Stream innerStream;
|
Stream innerStream;
|
||||||
|
DateTime lastWriteTime;
|
||||||
|
bool opened;
|
||||||
|
|
||||||
public LZip()
|
public LZip()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,143 +39,22 @@ namespace DiscImageChef.Filters
|
|||||||
{
|
{
|
||||||
// TODO: Interpret fdScript
|
// TODO: Interpret fdScript
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decodes MacBinary files
|
/// Decodes MacBinary files
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MacBinary : Filter
|
public class MacBinary : Filter
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct MacBinaryHeader
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 0x00, MacBinary version, 0
|
|
||||||
/// </summary>
|
|
||||||
public byte version;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x01, Str63 Pascal filename
|
|
||||||
/// </summary>
|
|
||||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] filename;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x41, File type
|
|
||||||
/// </summary>
|
|
||||||
public uint type;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x45, File creator
|
|
||||||
/// </summary>
|
|
||||||
public uint creator;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x49, High byte of Finder flags
|
|
||||||
/// </summary>
|
|
||||||
public byte finderFlags;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x4A, Must be 0
|
|
||||||
/// </summary>
|
|
||||||
public byte zero1;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x4B, File's icon vertical position within its window
|
|
||||||
/// </summary>
|
|
||||||
public ushort verticalPosition;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x4D, File's icon horizontal position within its window
|
|
||||||
/// </summary>
|
|
||||||
public ushort horizontalPosition;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x4F, File's window or folder ID
|
|
||||||
/// </summary>
|
|
||||||
public short windowID;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x51, Protected flag
|
|
||||||
/// </summary>
|
|
||||||
public byte protect;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x52, Must be 0
|
|
||||||
/// </summary>
|
|
||||||
public byte zero2;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x53, Size of data fork
|
|
||||||
/// </summary>
|
|
||||||
public uint dataLength;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x57, Size of resource fork
|
|
||||||
/// </summary>
|
|
||||||
public uint resourceLength;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x5B, File's creation time
|
|
||||||
/// </summary>
|
|
||||||
public uint creationTime;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x5F, File's last modified time
|
|
||||||
/// </summary>
|
|
||||||
public uint modificationTime;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x63, Length of Get Info comment
|
|
||||||
/// </summary>
|
|
||||||
public ushort commentLength;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x65, Low byte of Finder flags
|
|
||||||
/// </summary>
|
|
||||||
public byte finderFlags2;
|
|
||||||
|
|
||||||
#region MacBinary III
|
|
||||||
/// <summary>
|
|
||||||
/// 0x66, magic identifier, "mBIN"
|
|
||||||
/// </summary>
|
|
||||||
public uint magic;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x6A, fdScript from fxInfo, identifies codepage of filename
|
|
||||||
/// </summary>
|
|
||||||
public byte fdScript;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x6B, fdXFlags from fxInfo, extended Mac OS 8 finder flags
|
|
||||||
/// </summary>
|
|
||||||
public byte fdXFlags;
|
|
||||||
#endregion MacBinary III
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 0x6C, unused
|
|
||||||
/// </summary>
|
|
||||||
public ulong reserved;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x74, Total unpacked files
|
|
||||||
/// </summary>
|
|
||||||
public uint totalPackedFiles;
|
|
||||||
|
|
||||||
#region MacBinary II
|
|
||||||
/// <summary>
|
|
||||||
/// 0x78, Length of secondary header
|
|
||||||
/// </summary>
|
|
||||||
public ushort secondaryHeaderLength;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x7A, version number of MacBinary that wrote this file, starts at 129
|
|
||||||
/// </summary>
|
|
||||||
public byte version2;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x7B, version number of MacBinary required to open this file, starts at 129
|
|
||||||
/// </summary>
|
|
||||||
public byte minVersion;
|
|
||||||
/// <summary>
|
|
||||||
/// 0x7C, CRC of previous bytes
|
|
||||||
/// </summary>
|
|
||||||
public short crc;
|
|
||||||
#endregion MacBinary II
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 0x7E, Reserved for computer type and OS ID
|
|
||||||
/// </summary>
|
|
||||||
public short computerID;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint MACBINARY_MAGIC = 0x6D42494E;
|
const uint MACBINARY_MAGIC = 0x6D42494E;
|
||||||
|
string basePath;
|
||||||
|
byte[] bytes;
|
||||||
|
DateTime creationTime;
|
||||||
|
|
||||||
long dataForkOff;
|
long dataForkOff;
|
||||||
long rsrcForkOff;
|
|
||||||
byte[] bytes;
|
|
||||||
Stream stream;
|
|
||||||
bool isBytes, isStream, isPath, opened;
|
|
||||||
string basePath;
|
|
||||||
DateTime lastWriteTime;
|
|
||||||
DateTime creationTime;
|
|
||||||
MacBinaryHeader header;
|
|
||||||
string filename;
|
string filename;
|
||||||
|
MacBinaryHeader header;
|
||||||
|
bool isBytes, isStream, isPath, opened;
|
||||||
|
DateTime lastWriteTime;
|
||||||
|
long rsrcForkOff;
|
||||||
|
Stream stream;
|
||||||
|
|
||||||
public MacBinary()
|
public MacBinary()
|
||||||
{
|
{
|
||||||
@@ -278,8 +157,7 @@ namespace DiscImageChef.Filters
|
|||||||
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
||||||
|
|
||||||
return header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 &&
|
return header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 &&
|
||||||
header.filename[0] < 64 && header.zero1 == 0 &&
|
header.filename[0] < 64 && header.zero1 == 0 && header.zero2 == 0 && header.reserved == 0 &&
|
||||||
header.zero2 == 0 && header.reserved == 0 &&
|
|
||||||
(header.dataLength > 0 || header.resourceLength > 0);
|
(header.dataLength > 0 || header.resourceLength > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,8 +171,7 @@ namespace DiscImageChef.Filters
|
|||||||
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
||||||
|
|
||||||
return header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 &&
|
return header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 &&
|
||||||
header.filename[0] < 64 && header.zero1 == 0 &&
|
header.filename[0] < 64 && header.zero1 == 0 && header.zero2 == 0 && header.reserved == 0 &&
|
||||||
header.zero2 == 0 && header.reserved == 0 &&
|
|
||||||
(header.dataLength > 0 || header.resourceLength > 0);
|
(header.dataLength > 0 || header.resourceLength > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,8 +186,7 @@ namespace DiscImageChef.Filters
|
|||||||
|
|
||||||
fstream.Close();
|
fstream.Close();
|
||||||
return header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 &&
|
return header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 &&
|
||||||
header.filename[0] < 64 && header.zero1 == 0 &&
|
header.filename[0] < 64 && header.zero1 == 0 && header.zero2 == 0 && header.reserved == 0 &&
|
||||||
header.zero2 == 0 && header.reserved == 0 &&
|
|
||||||
(header.dataLength > 0 || header.resourceLength > 0);
|
(header.dataLength > 0 || header.resourceLength > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,5 +274,126 @@ namespace DiscImageChef.Filters
|
|||||||
isPath = true;
|
isPath = true;
|
||||||
basePath = path;
|
basePath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct MacBinaryHeader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 0x00, MacBinary version, 0
|
||||||
|
/// </summary>
|
||||||
|
public byte version;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x01, Str63 Pascal filename
|
||||||
|
/// </summary>
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] filename;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x41, File type
|
||||||
|
/// </summary>
|
||||||
|
public uint type;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x45, File creator
|
||||||
|
/// </summary>
|
||||||
|
public uint creator;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x49, High byte of Finder flags
|
||||||
|
/// </summary>
|
||||||
|
public byte finderFlags;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x4A, Must be 0
|
||||||
|
/// </summary>
|
||||||
|
public byte zero1;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x4B, File's icon vertical position within its window
|
||||||
|
/// </summary>
|
||||||
|
public ushort verticalPosition;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x4D, File's icon horizontal position within its window
|
||||||
|
/// </summary>
|
||||||
|
public ushort horizontalPosition;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x4F, File's window or folder ID
|
||||||
|
/// </summary>
|
||||||
|
public short windowID;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x51, Protected flag
|
||||||
|
/// </summary>
|
||||||
|
public byte protect;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x52, Must be 0
|
||||||
|
/// </summary>
|
||||||
|
public byte zero2;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x53, Size of data fork
|
||||||
|
/// </summary>
|
||||||
|
public uint dataLength;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x57, Size of resource fork
|
||||||
|
/// </summary>
|
||||||
|
public uint resourceLength;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x5B, File's creation time
|
||||||
|
/// </summary>
|
||||||
|
public uint creationTime;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x5F, File's last modified time
|
||||||
|
/// </summary>
|
||||||
|
public uint modificationTime;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x63, Length of Get Info comment
|
||||||
|
/// </summary>
|
||||||
|
public ushort commentLength;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x65, Low byte of Finder flags
|
||||||
|
/// </summary>
|
||||||
|
public byte finderFlags2;
|
||||||
|
|
||||||
|
#region MacBinary III
|
||||||
|
/// <summary>
|
||||||
|
/// 0x66, magic identifier, "mBIN"
|
||||||
|
/// </summary>
|
||||||
|
public uint magic;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x6A, fdScript from fxInfo, identifies codepage of filename
|
||||||
|
/// </summary>
|
||||||
|
public byte fdScript;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x6B, fdXFlags from fxInfo, extended Mac OS 8 finder flags
|
||||||
|
/// </summary>
|
||||||
|
public byte fdXFlags;
|
||||||
|
#endregion MacBinary III
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 0x6C, unused
|
||||||
|
/// </summary>
|
||||||
|
public ulong reserved;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x74, Total unpacked files
|
||||||
|
/// </summary>
|
||||||
|
public uint totalPackedFiles;
|
||||||
|
|
||||||
|
#region MacBinary II
|
||||||
|
/// <summary>
|
||||||
|
/// 0x78, Length of secondary header
|
||||||
|
/// </summary>
|
||||||
|
public ushort secondaryHeaderLength;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x7A, version number of MacBinary that wrote this file, starts at 129
|
||||||
|
/// </summary>
|
||||||
|
public byte version2;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x7B, version number of MacBinary required to open this file, starts at 129
|
||||||
|
/// </summary>
|
||||||
|
public byte minVersion;
|
||||||
|
/// <summary>
|
||||||
|
/// 0x7C, CRC of previous bytes
|
||||||
|
/// </summary>
|
||||||
|
public short crc;
|
||||||
|
#endregion MacBinary II
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 0x7E, Reserved for computer type and OS ID
|
||||||
|
/// </summary>
|
||||||
|
public short computerID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,13 +38,13 @@ using Microsoft.Win32.SafeHandles;
|
|||||||
namespace DiscImageChef.Filters
|
namespace DiscImageChef.Filters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a stream that is a subset of another stream.
|
/// Creates a stream that is a subset of another stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class OffsetStream : Stream
|
public class OffsetStream : Stream
|
||||||
{
|
{
|
||||||
readonly Stream baseStream;
|
readonly Stream baseStream;
|
||||||
readonly long streamStart;
|
|
||||||
readonly long streamEnd;
|
readonly long streamEnd;
|
||||||
|
readonly long streamStart;
|
||||||
|
|
||||||
public OffsetStream(Stream stream, long start, long end)
|
public OffsetStream(Stream stream, long start, long end)
|
||||||
{
|
{
|
||||||
@@ -291,12 +291,6 @@ namespace DiscImageChef.Filters
|
|||||||
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
||||||
}
|
}
|
||||||
|
|
||||||
~OffsetStream()
|
|
||||||
{
|
|
||||||
baseStream.Close();
|
|
||||||
baseStream.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool CanRead => baseStream.CanRead;
|
public override bool CanRead => baseStream.CanRead;
|
||||||
|
|
||||||
public override bool CanSeek => baseStream.CanSeek;
|
public override bool CanSeek => baseStream.CanSeek;
|
||||||
@@ -317,6 +311,12 @@ namespace DiscImageChef.Filters
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~OffsetStream()
|
||||||
|
{
|
||||||
|
baseStream.Close();
|
||||||
|
baseStream.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback,
|
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback,
|
||||||
object state)
|
object state)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,82 +40,22 @@ using System.Text;
|
|||||||
namespace DiscImageChef.Filters
|
namespace DiscImageChef.Filters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decodes PCExchange files
|
/// Decodes PCExchange files
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PCExchange : Filter
|
public class PCExchange : Filter
|
||||||
{
|
{
|
||||||
const string FILE_ID = "FILEID.DAT";
|
const string FILE_ID = "FILEID.DAT";
|
||||||
const string FINDER_INFO = "FINDER.DAT";
|
const string FINDER_INFO = "FINDER.DAT";
|
||||||
const string RESOURCES = "RESOURCE.FRK";
|
const string RESOURCES = "RESOURCE.FRK";
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
||||||
struct PCExchangeEntry
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Name in Macintosh. If PCExchange version supports FAT's LFN they are the same.
|
|
||||||
/// Illegal characters for FAT get substituted with '_' both here and in FAT's LFN entry.
|
|
||||||
/// </summary>
|
|
||||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] macName;
|
|
||||||
/// <summary>
|
|
||||||
/// File type
|
|
||||||
/// </summary>
|
|
||||||
public uint type;
|
|
||||||
/// <summary>
|
|
||||||
/// File creator
|
|
||||||
/// </summary>
|
|
||||||
public uint creator;
|
|
||||||
/// <summary>
|
|
||||||
/// Finder flags
|
|
||||||
/// </summary>
|
|
||||||
public ushort fdFlags;
|
|
||||||
/// <summary>
|
|
||||||
/// File's icon vertical position within its window
|
|
||||||
/// </summary>
|
|
||||||
public ushort verticalPosition;
|
|
||||||
/// <summary>
|
|
||||||
/// File's icon horizontal position within its window
|
|
||||||
/// </summary>
|
|
||||||
public ushort horizontalPosition;
|
|
||||||
/// <summary>
|
|
||||||
/// Unknown, all bytes are empty but last, except in volume's label entry
|
|
||||||
/// </summary>
|
|
||||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 18)] public byte[] unknown1;
|
|
||||||
/// <summary>
|
|
||||||
/// File's creation date
|
|
||||||
/// </summary>
|
|
||||||
public uint creationDate;
|
|
||||||
/// <summary>
|
|
||||||
/// File's modification date
|
|
||||||
/// </summary>
|
|
||||||
public uint modificationDate;
|
|
||||||
/// <summary>
|
|
||||||
/// File's last backup date
|
|
||||||
/// </summary>
|
|
||||||
public uint backupDate;
|
|
||||||
/// <summary>
|
|
||||||
/// Unknown, but is unique, starts 0x7FFFFFFF and counts in reverse.
|
|
||||||
/// Probably file ID for alias look up?
|
|
||||||
/// </summary>
|
|
||||||
public uint unknown2;
|
|
||||||
/// <summary>
|
|
||||||
/// Name as in FAT entry (not LFN).
|
|
||||||
/// Resource fork file is always using this name, never LFN.
|
|
||||||
/// </summary>
|
|
||||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public byte[] dosName;
|
|
||||||
/// <summary>
|
|
||||||
/// Unknown, flags?
|
|
||||||
/// </summary>
|
|
||||||
public byte unknown3;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool opened;
|
|
||||||
string basePath;
|
string basePath;
|
||||||
string dataPath;
|
|
||||||
string rsrcPath;
|
|
||||||
DateTime lastWriteTime;
|
|
||||||
DateTime creationTime;
|
DateTime creationTime;
|
||||||
long dataLen;
|
long dataLen;
|
||||||
|
string dataPath;
|
||||||
|
DateTime lastWriteTime;
|
||||||
|
|
||||||
|
bool opened;
|
||||||
long rsrcLen;
|
long rsrcLen;
|
||||||
|
string rsrcPath;
|
||||||
|
|
||||||
public PCExchange()
|
public PCExchange()
|
||||||
{
|
{
|
||||||
@@ -203,7 +143,8 @@ namespace DiscImageChef.Filters
|
|||||||
{
|
{
|
||||||
string parentFolder = Path.GetDirectoryName(path);
|
string parentFolder = Path.GetDirectoryName(path);
|
||||||
|
|
||||||
if(!File.Exists(Path.Combine(parentFolder ?? throw new InvalidOperationException(), FINDER_INFO))) return false;
|
if(!File.Exists(Path.Combine(parentFolder ?? throw new InvalidOperationException(), FINDER_INFO)))
|
||||||
|
return false;
|
||||||
|
|
||||||
if(!Directory.Exists(Path.Combine(parentFolder, RESOURCES))) return false;
|
if(!Directory.Exists(Path.Combine(parentFolder, RESOURCES))) return false;
|
||||||
|
|
||||||
@@ -233,9 +174,10 @@ namespace DiscImageChef.Filters
|
|||||||
|
|
||||||
if(baseFilename != macName && baseFilename != dosName && baseFilename != dosNameLow) continue;
|
if(baseFilename != macName && baseFilename != dosName && baseFilename != dosNameLow) continue;
|
||||||
|
|
||||||
dataFound |= File.Exists(Path.Combine(parentFolder, macName ?? throw new InvalidOperationException())) ||
|
dataFound |=
|
||||||
File.Exists(Path.Combine(parentFolder, dosName)) ||
|
File.Exists(Path.Combine(parentFolder, macName ?? throw new InvalidOperationException())) ||
|
||||||
File.Exists(Path.Combine(parentFolder, dosNameLow));
|
File.Exists(Path.Combine(parentFolder, dosName)) ||
|
||||||
|
File.Exists(Path.Combine(parentFolder, dosNameLow));
|
||||||
|
|
||||||
rsrcFound |= File.Exists(Path.Combine(parentFolder, RESOURCES, dosName)) ||
|
rsrcFound |= File.Exists(Path.Combine(parentFolder, RESOURCES, dosName)) ||
|
||||||
File.Exists(Path.Combine(parentFolder, RESOURCES, dosNameLow));
|
File.Exists(Path.Combine(parentFolder, RESOURCES, dosNameLow));
|
||||||
@@ -269,7 +211,8 @@ namespace DiscImageChef.Filters
|
|||||||
string baseFilename = Path.GetFileName(path);
|
string baseFilename = Path.GetFileName(path);
|
||||||
|
|
||||||
FileStream finderDatStream =
|
FileStream finderDatStream =
|
||||||
new FileStream(Path.Combine(parentFolder ?? throw new InvalidOperationException(), FINDER_INFO), FileMode.Open, FileAccess.Read);
|
new FileStream(Path.Combine(parentFolder ?? throw new InvalidOperationException(), FINDER_INFO),
|
||||||
|
FileMode.Open, FileAccess.Read);
|
||||||
|
|
||||||
while(finderDatStream.Position + 0x5C <= finderDatStream.Length)
|
while(finderDatStream.Position + 0x5C <= finderDatStream.Length)
|
||||||
{
|
{
|
||||||
@@ -288,7 +231,8 @@ namespace DiscImageChef.Filters
|
|||||||
|
|
||||||
if(baseFilename != macName && baseFilename != dosName && baseFilename != dosNameLow) continue;
|
if(baseFilename != macName && baseFilename != dosName && baseFilename != dosNameLow) continue;
|
||||||
|
|
||||||
if(File.Exists(Path.Combine(parentFolder, macName ?? throw new InvalidOperationException()))) dataPath = Path.Combine(parentFolder, macName);
|
if(File.Exists(Path.Combine(parentFolder, macName ?? throw new InvalidOperationException())))
|
||||||
|
dataPath = Path.Combine(parentFolder, macName);
|
||||||
else if(File.Exists(Path.Combine(parentFolder, dosName)))
|
else if(File.Exists(Path.Combine(parentFolder, dosName)))
|
||||||
dataPath = Path.Combine(parentFolder, dosName);
|
dataPath = Path.Combine(parentFolder, dosName);
|
||||||
else if(File.Exists(Path.Combine(parentFolder, dosNameLow)))
|
else if(File.Exists(Path.Combine(parentFolder, dosNameLow)))
|
||||||
@@ -315,5 +259,65 @@ namespace DiscImageChef.Filters
|
|||||||
|
|
||||||
finderDatStream.Close();
|
finderDatStream.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct PCExchangeEntry
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Name in Macintosh. If PCExchange version supports FAT's LFN they are the same.
|
||||||
|
/// Illegal characters for FAT get substituted with '_' both here and in FAT's LFN entry.
|
||||||
|
/// </summary>
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] macName;
|
||||||
|
/// <summary>
|
||||||
|
/// File type
|
||||||
|
/// </summary>
|
||||||
|
public uint type;
|
||||||
|
/// <summary>
|
||||||
|
/// File creator
|
||||||
|
/// </summary>
|
||||||
|
public uint creator;
|
||||||
|
/// <summary>
|
||||||
|
/// Finder flags
|
||||||
|
/// </summary>
|
||||||
|
public ushort fdFlags;
|
||||||
|
/// <summary>
|
||||||
|
/// File's icon vertical position within its window
|
||||||
|
/// </summary>
|
||||||
|
public ushort verticalPosition;
|
||||||
|
/// <summary>
|
||||||
|
/// File's icon horizontal position within its window
|
||||||
|
/// </summary>
|
||||||
|
public ushort horizontalPosition;
|
||||||
|
/// <summary>
|
||||||
|
/// Unknown, all bytes are empty but last, except in volume's label entry
|
||||||
|
/// </summary>
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 18)] public byte[] unknown1;
|
||||||
|
/// <summary>
|
||||||
|
/// File's creation date
|
||||||
|
/// </summary>
|
||||||
|
public uint creationDate;
|
||||||
|
/// <summary>
|
||||||
|
/// File's modification date
|
||||||
|
/// </summary>
|
||||||
|
public uint modificationDate;
|
||||||
|
/// <summary>
|
||||||
|
/// File's last backup date
|
||||||
|
/// </summary>
|
||||||
|
public uint backupDate;
|
||||||
|
/// <summary>
|
||||||
|
/// Unknown, but is unique, starts 0x7FFFFFFF and counts in reverse.
|
||||||
|
/// Probably file ID for alias look up?
|
||||||
|
/// </summary>
|
||||||
|
public uint unknown2;
|
||||||
|
/// <summary>
|
||||||
|
/// Name as in FAT entry (not LFN).
|
||||||
|
/// Resource fork file is always using this name, never LFN.
|
||||||
|
/// </summary>
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public byte[] dosName;
|
||||||
|
/// <summary>
|
||||||
|
/// Unknown, flags?
|
||||||
|
/// </summary>
|
||||||
|
public byte unknown3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,17 +37,17 @@ using SharpCompress.Compressors.Xz;
|
|||||||
namespace DiscImageChef.Filters
|
namespace DiscImageChef.Filters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decompress xz files while reading
|
/// Decompress xz files while reading
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class XZ : Filter
|
public class XZ : Filter
|
||||||
{
|
{
|
||||||
Stream dataStream;
|
|
||||||
string basePath;
|
string basePath;
|
||||||
DateTime lastWriteTime;
|
|
||||||
DateTime creationTime;
|
DateTime creationTime;
|
||||||
bool opened;
|
Stream dataStream;
|
||||||
long decompressedSize;
|
long decompressedSize;
|
||||||
Stream innerStream;
|
Stream innerStream;
|
||||||
|
DateTime lastWriteTime;
|
||||||
|
bool opened;
|
||||||
|
|
||||||
public XZ()
|
public XZ()
|
||||||
{
|
{
|
||||||
@@ -242,7 +242,10 @@ namespace DiscImageChef.Filters
|
|||||||
{
|
{
|
||||||
if(basePath?.EndsWith(".xz", StringComparison.InvariantCultureIgnoreCase) == true)
|
if(basePath?.EndsWith(".xz", StringComparison.InvariantCultureIgnoreCase) == true)
|
||||||
return basePath.Substring(0, basePath.Length - 3);
|
return basePath.Substring(0, basePath.Length - 3);
|
||||||
return basePath?.EndsWith(".xzip", StringComparison.InvariantCultureIgnoreCase) == true ? basePath.Substring(0, basePath.Length - 5) : basePath;
|
|
||||||
|
return basePath?.EndsWith(".xzip", StringComparison.InvariantCultureIgnoreCase) == true
|
||||||
|
? basePath.Substring(0, basePath.Length - 5)
|
||||||
|
: basePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetParentFolder()
|
public override string GetParentFolder()
|
||||||
|
|||||||
@@ -36,14 +36,14 @@ using System.IO;
|
|||||||
namespace DiscImageChef.Filters
|
namespace DiscImageChef.Filters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// No filter for reading files not recognized by any filter
|
/// No filter for reading files not recognized by any filter
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ZZZNoFilter : Filter
|
public class ZZZNoFilter : Filter
|
||||||
{
|
{
|
||||||
Stream dataStream;
|
|
||||||
string basePath;
|
string basePath;
|
||||||
DateTime lastWriteTime;
|
|
||||||
DateTime creationTime;
|
DateTime creationTime;
|
||||||
|
Stream dataStream;
|
||||||
|
DateTime lastWriteTime;
|
||||||
bool opened;
|
bool opened;
|
||||||
|
|
||||||
public ZZZNoFilter()
|
public ZZZNoFilter()
|
||||||
|
|||||||
Reference in New Issue
Block a user