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:
@@ -42,113 +42,31 @@ namespace DiscImageChef.Filters
|
|||||||
/// </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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,114 +42,32 @@ namespace DiscImageChef.Filters
|
|||||||
/// </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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,13 +42,13 @@ namespace DiscImageChef.Filters
|
|||||||
/// </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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,8 @@ namespace DiscImageChef.Filters
|
|||||||
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
|
||||||
|
/// archive itself.<br />
|
||||||
/// UNIX: /path/to/archive.zip/path/to/file.bin => /path/to/archive.zip <br />
|
/// 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
|
/// Windows: C:\path\to\archive.zip\path\to\file.bin => C:\path\to\archive.zip
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ 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); }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,11 +41,11 @@ namespace DiscImageChef.Filters
|
|||||||
/// </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.
|
||||||
@@ -73,6 +73,21 @@ namespace DiscImageChef.Filters
|
|||||||
CalculateLength();
|
CalculateLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool CanRead => baseStream.CanRead;
|
||||||
|
|
||||||
|
public override bool CanSeek => true;
|
||||||
|
|
||||||
|
public override bool CanWrite => false;
|
||||||
|
|
||||||
|
public override long Length => streamLength;
|
||||||
|
|
||||||
|
public override long Position
|
||||||
|
{
|
||||||
|
get => backStream.Position;
|
||||||
|
|
||||||
|
set => SetPosition(value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Calculates the real (uncompressed) length of the stream.
|
/// Calculates the real (uncompressed) length of the stream.
|
||||||
/// It basically reads (uncompresses) the whole stream to memory discarding its contents,
|
/// It basically reads (uncompresses) the whole stream to memory discarding its contents,
|
||||||
@@ -94,21 +109,6 @@ namespace DiscImageChef.Filters
|
|||||||
backStream.Position = 0;
|
backStream.Position = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanRead => baseStream.CanRead;
|
|
||||||
|
|
||||||
public override bool CanSeek => true;
|
|
||||||
|
|
||||||
public override bool CanWrite => false;
|
|
||||||
|
|
||||||
public override long Length => streamLength;
|
|
||||||
|
|
||||||
public override long Position
|
|
||||||
{
|
|
||||||
get => backStream.Position;
|
|
||||||
|
|
||||||
set => SetPosition(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPosition(long position)
|
void SetPosition(long position)
|
||||||
{
|
{
|
||||||
if(position == backStream.Position) return;
|
if(position == backStream.Position) return;
|
||||||
|
|||||||
@@ -41,12 +41,12 @@ namespace DiscImageChef.Filters
|
|||||||
/// </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()
|
||||||
|
|||||||
@@ -42,13 +42,13 @@ namespace DiscImageChef.Filters
|
|||||||
/// </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()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -43,6 +43,238 @@ namespace DiscImageChef.Filters
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MacBinary : Filter
|
public class MacBinary : Filter
|
||||||
{
|
{
|
||||||
|
const uint MACBINARY_MAGIC = 0x6D42494E;
|
||||||
|
string basePath;
|
||||||
|
byte[] bytes;
|
||||||
|
DateTime creationTime;
|
||||||
|
|
||||||
|
long dataForkOff;
|
||||||
|
string filename;
|
||||||
|
MacBinaryHeader header;
|
||||||
|
bool isBytes, isStream, isPath, opened;
|
||||||
|
DateTime lastWriteTime;
|
||||||
|
long rsrcForkOff;
|
||||||
|
Stream stream;
|
||||||
|
|
||||||
|
public MacBinary()
|
||||||
|
{
|
||||||
|
Name = "MacBinary";
|
||||||
|
UUID = new Guid("D7C321D3-E51F-45DF-A150-F6BFDF0D7704");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Close()
|
||||||
|
{
|
||||||
|
bytes = null;
|
||||||
|
stream?.Close();
|
||||||
|
isBytes = false;
|
||||||
|
isStream = false;
|
||||||
|
isPath = false;
|
||||||
|
opened = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string GetBasePath()
|
||||||
|
{
|
||||||
|
return basePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override DateTime GetCreationTime()
|
||||||
|
{
|
||||||
|
return creationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long GetDataForkLength()
|
||||||
|
{
|
||||||
|
return header.dataLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Stream GetDataForkStream()
|
||||||
|
{
|
||||||
|
if(header.dataLength == 0) return null;
|
||||||
|
|
||||||
|
if(isBytes) return new OffsetStream(bytes, dataForkOff, dataForkOff + header.dataLength - 1);
|
||||||
|
if(isStream) return new OffsetStream(stream, dataForkOff, dataForkOff + header.dataLength - 1);
|
||||||
|
if(isPath)
|
||||||
|
return new OffsetStream(basePath, FileMode.Open, FileAccess.Read, dataForkOff,
|
||||||
|
dataForkOff + header.dataLength - 1);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string GetFilename()
|
||||||
|
{
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override DateTime GetLastWriteTime()
|
||||||
|
{
|
||||||
|
return lastWriteTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long GetLength()
|
||||||
|
{
|
||||||
|
return header.dataLength + header.resourceLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string GetParentFolder()
|
||||||
|
{
|
||||||
|
return Path.GetDirectoryName(basePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string GetPath()
|
||||||
|
{
|
||||||
|
return basePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long GetResourceForkLength()
|
||||||
|
{
|
||||||
|
return header.resourceLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Stream GetResourceForkStream()
|
||||||
|
{
|
||||||
|
if(header.resourceLength == 0) return null;
|
||||||
|
|
||||||
|
if(isBytes) return new OffsetStream(bytes, rsrcForkOff, rsrcForkOff + header.resourceLength - 1);
|
||||||
|
if(isStream) return new OffsetStream(stream, rsrcForkOff, rsrcForkOff + header.resourceLength - 1);
|
||||||
|
if(isPath)
|
||||||
|
return new OffsetStream(basePath, FileMode.Open, FileAccess.Read, rsrcForkOff,
|
||||||
|
rsrcForkOff + header.resourceLength - 1);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool HasResourceFork()
|
||||||
|
{
|
||||||
|
return header.resourceLength > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Identify(byte[] buffer)
|
||||||
|
{
|
||||||
|
if(buffer == null || buffer.Length < 128) return false;
|
||||||
|
|
||||||
|
byte[] hdr_b = new byte[128];
|
||||||
|
Array.Copy(buffer, 0, hdr_b, 0, 128);
|
||||||
|
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
||||||
|
|
||||||
|
return header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 &&
|
||||||
|
header.filename[0] < 64 && header.zero1 == 0 && header.zero2 == 0 && header.reserved == 0 &&
|
||||||
|
(header.dataLength > 0 || header.resourceLength > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Identify(Stream stream)
|
||||||
|
{
|
||||||
|
if(stream == null || stream.Length < 128) return false;
|
||||||
|
|
||||||
|
byte[] hdr_b = new byte[128];
|
||||||
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
stream.Read(hdr_b, 0, 128);
|
||||||
|
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
||||||
|
|
||||||
|
return header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 &&
|
||||||
|
header.filename[0] < 64 && header.zero1 == 0 && header.zero2 == 0 && header.reserved == 0 &&
|
||||||
|
(header.dataLength > 0 || header.resourceLength > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Identify(string path)
|
||||||
|
{
|
||||||
|
FileStream fstream = new FileStream(path, FileMode.Open, FileAccess.Read);
|
||||||
|
if(fstream.Length < 128) return false;
|
||||||
|
|
||||||
|
byte[] hdr_b = new byte[128];
|
||||||
|
fstream.Read(hdr_b, 0, 128);
|
||||||
|
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
||||||
|
|
||||||
|
fstream.Close();
|
||||||
|
return header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 &&
|
||||||
|
header.filename[0] < 64 && header.zero1 == 0 && header.zero2 == 0 && header.reserved == 0 &&
|
||||||
|
(header.dataLength > 0 || header.resourceLength > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool IsOpened()
|
||||||
|
{
|
||||||
|
return opened;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Open(byte[] buffer)
|
||||||
|
{
|
||||||
|
MemoryStream ms = new MemoryStream(buffer);
|
||||||
|
ms.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
byte[] hdr_b = new byte[128];
|
||||||
|
ms.Read(hdr_b, 0, 128);
|
||||||
|
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
||||||
|
|
||||||
|
uint blocks = 1;
|
||||||
|
blocks += (uint)(header.secondaryHeaderLength / 128);
|
||||||
|
if(header.secondaryHeaderLength % 128 > 0) blocks++;
|
||||||
|
dataForkOff = blocks * 128;
|
||||||
|
blocks += header.dataLength / 128;
|
||||||
|
if(header.dataLength % 128 > 0) blocks++;
|
||||||
|
rsrcForkOff = blocks * 128;
|
||||||
|
|
||||||
|
filename = StringHandlers.PascalToString(header.filename, Encoding.GetEncoding("macintosh"));
|
||||||
|
creationTime = DateHandlers.MacToDateTime(header.creationTime);
|
||||||
|
lastWriteTime = DateHandlers.MacToDateTime(header.modificationTime);
|
||||||
|
|
||||||
|
ms.Close();
|
||||||
|
opened = true;
|
||||||
|
isBytes = true;
|
||||||
|
bytes = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Open(Stream stream)
|
||||||
|
{
|
||||||
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
byte[] hdr_b = new byte[128];
|
||||||
|
stream.Read(hdr_b, 0, 128);
|
||||||
|
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
||||||
|
|
||||||
|
uint blocks = 1;
|
||||||
|
blocks += (uint)(header.secondaryHeaderLength / 128);
|
||||||
|
if(header.secondaryHeaderLength % 128 > 0) blocks++;
|
||||||
|
dataForkOff = blocks * 128;
|
||||||
|
blocks += header.dataLength / 128;
|
||||||
|
if(header.dataLength % 128 > 0) blocks++;
|
||||||
|
rsrcForkOff = blocks * 128;
|
||||||
|
|
||||||
|
filename = StringHandlers.PascalToString(header.filename, Encoding.GetEncoding("macintosh"));
|
||||||
|
creationTime = DateHandlers.MacToDateTime(header.creationTime);
|
||||||
|
lastWriteTime = DateHandlers.MacToDateTime(header.modificationTime);
|
||||||
|
|
||||||
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
opened = true;
|
||||||
|
isStream = true;
|
||||||
|
this.stream = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Open(string path)
|
||||||
|
{
|
||||||
|
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
|
||||||
|
fs.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
byte[] hdr_b = new byte[128];
|
||||||
|
fs.Read(hdr_b, 0, 128);
|
||||||
|
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
||||||
|
|
||||||
|
uint blocks = 1;
|
||||||
|
blocks += (uint)(header.secondaryHeaderLength / 128);
|
||||||
|
if(header.secondaryHeaderLength % 128 > 0) blocks++;
|
||||||
|
dataForkOff = blocks * 128;
|
||||||
|
blocks += header.dataLength / 128;
|
||||||
|
if(header.dataLength % 128 > 0) blocks++;
|
||||||
|
rsrcForkOff = blocks * 128;
|
||||||
|
|
||||||
|
filename = StringHandlers.PascalToString(header.filename, Encoding.GetEncoding("macintosh"));
|
||||||
|
creationTime = DateHandlers.MacToDateTime(header.creationTime);
|
||||||
|
lastWriteTime = DateHandlers.MacToDateTime(header.modificationTime);
|
||||||
|
|
||||||
|
fs.Close();
|
||||||
|
opened = true;
|
||||||
|
isPath = true;
|
||||||
|
basePath = path;
|
||||||
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
struct MacBinaryHeader
|
struct MacBinaryHeader
|
||||||
{
|
{
|
||||||
@@ -163,240 +395,5 @@ namespace DiscImageChef.Filters
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public short computerID;
|
public short computerID;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint MACBINARY_MAGIC = 0x6D42494E;
|
|
||||||
|
|
||||||
long dataForkOff;
|
|
||||||
long rsrcForkOff;
|
|
||||||
byte[] bytes;
|
|
||||||
Stream stream;
|
|
||||||
bool isBytes, isStream, isPath, opened;
|
|
||||||
string basePath;
|
|
||||||
DateTime lastWriteTime;
|
|
||||||
DateTime creationTime;
|
|
||||||
MacBinaryHeader header;
|
|
||||||
string filename;
|
|
||||||
|
|
||||||
public MacBinary()
|
|
||||||
{
|
|
||||||
Name = "MacBinary";
|
|
||||||
UUID = new Guid("D7C321D3-E51F-45DF-A150-F6BFDF0D7704");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Close()
|
|
||||||
{
|
|
||||||
bytes = null;
|
|
||||||
stream?.Close();
|
|
||||||
isBytes = false;
|
|
||||||
isStream = false;
|
|
||||||
isPath = false;
|
|
||||||
opened = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string GetBasePath()
|
|
||||||
{
|
|
||||||
return basePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override DateTime GetCreationTime()
|
|
||||||
{
|
|
||||||
return creationTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override long GetDataForkLength()
|
|
||||||
{
|
|
||||||
return header.dataLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Stream GetDataForkStream()
|
|
||||||
{
|
|
||||||
if(header.dataLength == 0) return null;
|
|
||||||
|
|
||||||
if(isBytes) return new OffsetStream(bytes, dataForkOff, dataForkOff + header.dataLength - 1);
|
|
||||||
if(isStream) return new OffsetStream(stream, dataForkOff, dataForkOff + header.dataLength - 1);
|
|
||||||
if(isPath)
|
|
||||||
return new OffsetStream(basePath, FileMode.Open, FileAccess.Read, dataForkOff,
|
|
||||||
dataForkOff + header.dataLength - 1);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string GetFilename()
|
|
||||||
{
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override DateTime GetLastWriteTime()
|
|
||||||
{
|
|
||||||
return lastWriteTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override long GetLength()
|
|
||||||
{
|
|
||||||
return header.dataLength + header.resourceLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string GetParentFolder()
|
|
||||||
{
|
|
||||||
return Path.GetDirectoryName(basePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string GetPath()
|
|
||||||
{
|
|
||||||
return basePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override long GetResourceForkLength()
|
|
||||||
{
|
|
||||||
return header.resourceLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Stream GetResourceForkStream()
|
|
||||||
{
|
|
||||||
if(header.resourceLength == 0) return null;
|
|
||||||
|
|
||||||
if(isBytes) return new OffsetStream(bytes, rsrcForkOff, rsrcForkOff + header.resourceLength - 1);
|
|
||||||
if(isStream) return new OffsetStream(stream, rsrcForkOff, rsrcForkOff + header.resourceLength - 1);
|
|
||||||
if(isPath)
|
|
||||||
return new OffsetStream(basePath, FileMode.Open, FileAccess.Read, rsrcForkOff,
|
|
||||||
rsrcForkOff + header.resourceLength - 1);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool HasResourceFork()
|
|
||||||
{
|
|
||||||
return header.resourceLength > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Identify(byte[] buffer)
|
|
||||||
{
|
|
||||||
if(buffer == null || buffer.Length < 128) return false;
|
|
||||||
|
|
||||||
byte[] hdr_b = new byte[128];
|
|
||||||
Array.Copy(buffer, 0, hdr_b, 0, 128);
|
|
||||||
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
|
||||||
|
|
||||||
return header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 &&
|
|
||||||
header.filename[0] < 64 && header.zero1 == 0 &&
|
|
||||||
header.zero2 == 0 && header.reserved == 0 &&
|
|
||||||
(header.dataLength > 0 || header.resourceLength > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Identify(Stream stream)
|
|
||||||
{
|
|
||||||
if(stream == null || stream.Length < 128) return false;
|
|
||||||
|
|
||||||
byte[] hdr_b = new byte[128];
|
|
||||||
stream.Seek(0, SeekOrigin.Begin);
|
|
||||||
stream.Read(hdr_b, 0, 128);
|
|
||||||
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
|
||||||
|
|
||||||
return header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 &&
|
|
||||||
header.filename[0] < 64 && header.zero1 == 0 &&
|
|
||||||
header.zero2 == 0 && header.reserved == 0 &&
|
|
||||||
(header.dataLength > 0 || header.resourceLength > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Identify(string path)
|
|
||||||
{
|
|
||||||
FileStream fstream = new FileStream(path, FileMode.Open, FileAccess.Read);
|
|
||||||
if(fstream.Length < 128) return false;
|
|
||||||
|
|
||||||
byte[] hdr_b = new byte[128];
|
|
||||||
fstream.Read(hdr_b, 0, 128);
|
|
||||||
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
|
||||||
|
|
||||||
fstream.Close();
|
|
||||||
return header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 &&
|
|
||||||
header.filename[0] < 64 && header.zero1 == 0 &&
|
|
||||||
header.zero2 == 0 && header.reserved == 0 &&
|
|
||||||
(header.dataLength > 0 || header.resourceLength > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool IsOpened()
|
|
||||||
{
|
|
||||||
return opened;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Open(byte[] buffer)
|
|
||||||
{
|
|
||||||
MemoryStream ms = new MemoryStream(buffer);
|
|
||||||
ms.Seek(0, SeekOrigin.Begin);
|
|
||||||
|
|
||||||
byte[] hdr_b = new byte[128];
|
|
||||||
ms.Read(hdr_b, 0, 128);
|
|
||||||
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
|
||||||
|
|
||||||
uint blocks = 1;
|
|
||||||
blocks += (uint)(header.secondaryHeaderLength / 128);
|
|
||||||
if(header.secondaryHeaderLength % 128 > 0) blocks++;
|
|
||||||
dataForkOff = blocks * 128;
|
|
||||||
blocks += header.dataLength / 128;
|
|
||||||
if(header.dataLength % 128 > 0) blocks++;
|
|
||||||
rsrcForkOff = blocks * 128;
|
|
||||||
|
|
||||||
filename = StringHandlers.PascalToString(header.filename, Encoding.GetEncoding("macintosh"));
|
|
||||||
creationTime = DateHandlers.MacToDateTime(header.creationTime);
|
|
||||||
lastWriteTime = DateHandlers.MacToDateTime(header.modificationTime);
|
|
||||||
|
|
||||||
ms.Close();
|
|
||||||
opened = true;
|
|
||||||
isBytes = true;
|
|
||||||
bytes = buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Open(Stream stream)
|
|
||||||
{
|
|
||||||
stream.Seek(0, SeekOrigin.Begin);
|
|
||||||
|
|
||||||
byte[] hdr_b = new byte[128];
|
|
||||||
stream.Read(hdr_b, 0, 128);
|
|
||||||
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
|
||||||
|
|
||||||
uint blocks = 1;
|
|
||||||
blocks += (uint)(header.secondaryHeaderLength / 128);
|
|
||||||
if(header.secondaryHeaderLength % 128 > 0) blocks++;
|
|
||||||
dataForkOff = blocks * 128;
|
|
||||||
blocks += header.dataLength / 128;
|
|
||||||
if(header.dataLength % 128 > 0) blocks++;
|
|
||||||
rsrcForkOff = blocks * 128;
|
|
||||||
|
|
||||||
filename = StringHandlers.PascalToString(header.filename, Encoding.GetEncoding("macintosh"));
|
|
||||||
creationTime = DateHandlers.MacToDateTime(header.creationTime);
|
|
||||||
lastWriteTime = DateHandlers.MacToDateTime(header.modificationTime);
|
|
||||||
|
|
||||||
stream.Seek(0, SeekOrigin.Begin);
|
|
||||||
opened = true;
|
|
||||||
isStream = true;
|
|
||||||
this.stream = stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Open(string path)
|
|
||||||
{
|
|
||||||
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
|
|
||||||
fs.Seek(0, SeekOrigin.Begin);
|
|
||||||
|
|
||||||
byte[] hdr_b = new byte[128];
|
|
||||||
fs.Read(hdr_b, 0, 128);
|
|
||||||
header = BigEndianMarshal.ByteArrayToStructureBigEndian<MacBinaryHeader>(hdr_b);
|
|
||||||
|
|
||||||
uint blocks = 1;
|
|
||||||
blocks += (uint)(header.secondaryHeaderLength / 128);
|
|
||||||
if(header.secondaryHeaderLength % 128 > 0) blocks++;
|
|
||||||
dataForkOff = blocks * 128;
|
|
||||||
blocks += header.dataLength / 128;
|
|
||||||
if(header.dataLength % 128 > 0) blocks++;
|
|
||||||
rsrcForkOff = blocks * 128;
|
|
||||||
|
|
||||||
filename = StringHandlers.PascalToString(header.filename, Encoding.GetEncoding("macintosh"));
|
|
||||||
creationTime = DateHandlers.MacToDateTime(header.creationTime);
|
|
||||||
lastWriteTime = DateHandlers.MacToDateTime(header.modificationTime);
|
|
||||||
|
|
||||||
fs.Close();
|
|
||||||
opened = true;
|
|
||||||
isPath = true;
|
|
||||||
basePath = path;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,8 +43,8 @@ namespace DiscImageChef.Filters
|
|||||||
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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -47,75 +47,15 @@ namespace DiscImageChef.Filters
|
|||||||
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,7 +174,8 @@ 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, macName ?? throw new InvalidOperationException())) ||
|
||||||
File.Exists(Path.Combine(parentFolder, dosName)) ||
|
File.Exists(Path.Combine(parentFolder, dosName)) ||
|
||||||
File.Exists(Path.Combine(parentFolder, dosNameLow));
|
File.Exists(Path.Combine(parentFolder, 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -41,13 +41,13 @@ namespace DiscImageChef.Filters
|
|||||||
/// </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()
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ namespace DiscImageChef.Filters
|
|||||||
/// </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