General refactor and cleanup.

This commit is contained in:
2024-05-01 04:05:22 +01:00
parent 185a8c3fd5
commit e46d21bde6
922 changed files with 36437 additions and 29485 deletions

View File

@@ -49,12 +49,13 @@ public sealed partial class CPM
try
{
_definitions =
JsonSerializer.
Deserialize(Assembly.GetExecutingAssembly().GetManifestResourceStream("Aaru.Filesystems.CPM.cpmdefs.json") ?? new MemoryStream(),
typeof(CpmDefinitions), CpmDefinitionsContext.Default) as CpmDefinitions;
JsonSerializer.Deserialize(Assembly.GetExecutingAssembly()
.GetManifestResourceStream("Aaru.Filesystems.CPM.cpmdefs.json") ??
new MemoryStream(),
typeof(CpmDefinitions),
CpmDefinitionsContext.Default) as CpmDefinitions;
if(_definitions is null)
return false;
if(_definitions is null) return false;
// Patch definitions
foreach(CpmDefinition def in _definitions.definitions)
@@ -67,12 +68,10 @@ public sealed partial class CPM
sectorIds = new int[def.sectorsPerTrack]
};
for(var i = 0; i < def.sectorsPerTrack; i++)
def.side1.sectorIds[i] = i + 1;
for(var i = 0; i < def.sectorsPerTrack; i++) def.side1.sectorIds[i] = i + 1;
}
if(def.sides != 2 || def.side2 != null)
continue;
if(def.sides != 2 || def.side2 != null) continue;
{
def.side2 = new Side
@@ -81,8 +80,7 @@ public sealed partial class CPM
sectorIds = new int[def.sectorsPerTrack]
};
for(var i = 0; i < def.sectorsPerTrack; i++)
def.side2.sectorIds[i] = i + 1;
for(var i = 0; i < def.sectorsPerTrack; i++) def.side2.sectorIds[i] = i + 1;
}
}
@@ -95,9 +93,11 @@ public sealed partial class CPM
}
}
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
[JsonSourceGenerationOptions(WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
IncludeFields = true)]
[JsonSerializable(typeof(CpmDefinitions))]
// ReSharper disable once PartialTypeWithSinglePart
public partial class CpmDefinitionsContext : JsonSerializerContext;

View File

@@ -47,8 +47,7 @@ public sealed partial class CPM
{
node = null;
if(!_mounted)
return ErrorNumber.AccessDenied;
if(!_mounted) return ErrorNumber.AccessDenied;
if(!string.IsNullOrEmpty(path) && string.Compare(path, "/", StringComparison.OrdinalIgnoreCase) != 0)
return ErrorNumber.NotSupported;
@@ -68,17 +67,13 @@ public sealed partial class CPM
{
filename = null;
if(!_mounted)
return ErrorNumber.AccessDenied;
if(!_mounted) return ErrorNumber.AccessDenied;
if(node is not CpmDirNode mynode)
return ErrorNumber.InvalidArgument;
if(node is not CpmDirNode mynode) return ErrorNumber.InvalidArgument;
if(mynode.Position < 0)
return ErrorNumber.InvalidArgument;
if(mynode.Position < 0) return ErrorNumber.InvalidArgument;
if(mynode.Position >= mynode.Contents.Length)
return ErrorNumber.NoError;
if(mynode.Position >= mynode.Contents.Length) return ErrorNumber.NoError;
filename = mynode.Contents[mynode.Position++];
@@ -88,8 +83,7 @@ public sealed partial class CPM
/// <inheritdoc />
public ErrorNumber CloseDir(IDirNode node)
{
if(node is not CpmDirNode mynode)
return ErrorNumber.InvalidArgument;
if(node is not CpmDirNode mynode) return ErrorNumber.InvalidArgument;
mynode.Position = -1;
mynode.Contents = null;
@@ -110,8 +104,7 @@ public sealed partial class CPM
{
try
{
if(directory == null)
return false;
if(directory == null) return false;
var fileCount = 0;
@@ -123,18 +116,15 @@ public sealed partial class CPM
{
for(var f = 0; f < 8; f++)
{
if(entry.filename[f] < 0x20 && entry.filename[f] != 0x00)
return false;
if(entry.filename[f] < 0x20 && entry.filename[f] != 0x00) return false;
}
for(var e = 0; e < 3; e++)
{
if(entry.extension[e] < 0x20 && entry.extension[e] != 0x00)
return false;
if(entry.extension[e] < 0x20 && entry.extension[e] != 0x00) return false;
}
if(!ArrayHelpers.ArrayIsNullOrWhiteSpace(entry.filename))
fileCount++;
if(!ArrayHelpers.ArrayIsNullOrWhiteSpace(entry.filename)) fileCount++;
}
else
{
@@ -144,14 +134,12 @@ public sealed partial class CPM
{
for(var f = 0; f < 8; f++)
{
if(entry.filename[f] < 0x20 && entry.filename[f] != 0x00)
return false;
if(entry.filename[f] < 0x20 && entry.filename[f] != 0x00) return false;
}
for(var e = 0; e < 3; e++)
{
if(entry.extension[e] < 0x20 && entry.extension[e] != 0x00)
return false;
if(entry.extension[e] < 0x20 && entry.extension[e] != 0x00) return false;
}
_label = Encoding.ASCII.GetString(directory, off + 1, 11).Trim();

View File

@@ -43,16 +43,15 @@ public sealed partial class CPM
{
attributes = new FileAttributes();
if(!_mounted)
return ErrorNumber.AccessDenied;
if(!_mounted) return ErrorNumber.AccessDenied;
string[] pathElements = path.Split(new[]
{
'/'
}, StringSplitOptions.RemoveEmptyEntries);
{
'/'
},
StringSplitOptions.RemoveEmptyEntries);
if(pathElements.Length != 1)
return ErrorNumber.NotSupported;
if(pathElements.Length != 1) return ErrorNumber.NotSupported;
if(string.IsNullOrEmpty(pathElements[0]) ||
string.Compare(pathElements[0], "/", StringComparison.OrdinalIgnoreCase) == 0)
@@ -76,19 +75,17 @@ public sealed partial class CPM
{
node = null;
if(!_mounted)
return ErrorNumber.AccessDenied;
if(!_mounted) return ErrorNumber.AccessDenied;
string[] pathElements = path.Split(new[]
{
'/'
}, StringSplitOptions.RemoveEmptyEntries);
{
'/'
},
StringSplitOptions.RemoveEmptyEntries);
if(pathElements.Length != 1)
return ErrorNumber.NotSupported;
if(pathElements.Length != 1) return ErrorNumber.NotSupported;
if(!_fileCache.TryGetValue(pathElements[0].ToUpperInvariant(), out byte[] file))
return ErrorNumber.NoSuchFile;
if(!_fileCache.TryGetValue(pathElements[0].ToUpperInvariant(), out byte[] file)) return ErrorNumber.NoSuchFile;
node = new CpmFileNode
{
@@ -104,11 +101,9 @@ public sealed partial class CPM
/// <inheritdoc />
public ErrorNumber CloseFile(IFileNode node)
{
if(!_mounted)
return ErrorNumber.AccessDenied;
if(!_mounted) return ErrorNumber.AccessDenied;
if(node is not CpmFileNode mynode)
return ErrorNumber.InvalidArgument;
if(node is not CpmFileNode mynode) return ErrorNumber.InvalidArgument;
mynode.Cache = null;
@@ -120,19 +115,15 @@ public sealed partial class CPM
{
read = 0;
if(!_mounted)
return ErrorNumber.AccessDenied;
if(!_mounted) return ErrorNumber.AccessDenied;
if(buffer is null || buffer.Length < length)
return ErrorNumber.InvalidArgument;
if(buffer is null || buffer.Length < length) return ErrorNumber.InvalidArgument;
if(node is not CpmFileNode mynode)
return ErrorNumber.InvalidArgument;
if(node is not CpmFileNode mynode) return ErrorNumber.InvalidArgument;
read = length;
if(length + mynode.Offset >= mynode.Length)
read = mynode.Length - mynode.Offset;
if(length + mynode.Offset >= mynode.Length) read = mynode.Length - mynode.Offset;
Array.Copy(mynode.Cache, mynode.Offset, buffer, 0, read);
@@ -154,16 +145,15 @@ public sealed partial class CPM
{
stat = null;
if(!_mounted)
return ErrorNumber.AccessDenied;
if(!_mounted) return ErrorNumber.AccessDenied;
string[] pathElements = path.Split(new[]
{
'/'
}, StringSplitOptions.RemoveEmptyEntries);
{
'/'
},
StringSplitOptions.RemoveEmptyEntries);
if(pathElements.Length != 1)
return ErrorNumber.NotSupported;
if(pathElements.Length != 1) return ErrorNumber.NotSupported;
if(!string.IsNullOrEmpty(path) && string.Compare(path, "/", StringComparison.OrdinalIgnoreCase) != 0)
{
@@ -178,11 +168,9 @@ public sealed partial class CPM
BlockSize = Metadata.ClusterSize
};
if(_labelCreationDate != null)
stat.CreationTime = DateHandlers.CpmToDateTime(_labelCreationDate);
if(_labelCreationDate != null) stat.CreationTime = DateHandlers.CpmToDateTime(_labelCreationDate);
if(_labelUpdateDate != null)
stat.StatusChangeTime = DateHandlers.CpmToDateTime(_labelUpdateDate);
if(_labelUpdateDate != null) stat.StatusChangeTime = DateHandlers.CpmToDateTime(_labelUpdateDate);
return ErrorNumber.NoError;
}

View File

@@ -191,8 +191,7 @@ public sealed partial class CPM
var sig3 = BitConverter.ToUInt32(sector, 0x7C);
// PCW16 extended boot record
if(sig1 == 0x4D2F5043 && sig2 == 0x004B5344 && sig3 == sig1)
amsSbOffset = 0x80;
if(sig1 == 0x4D2F5043 && sig2 == 0x004B5344 && sig3 == sig1) amsSbOffset = 0x80;
// Read the superblock
AmstradSuperBlock amsSb =
@@ -222,8 +221,7 @@ public sealed partial class CPM
bsh = amsSb.bsh
};
for(var i = 0; i < _dpb.bsh; i++)
_dpb.blm += (byte)Math.Pow(2, i);
for(var i = 0; i < _dpb.bsh; i++) _dpb.blm += (byte)Math.Pow(2, i);
if(sectorCount >= 1440)
{
@@ -241,13 +239,13 @@ public sealed partial class CPM
_dpb.off = amsSb.off;
_dpb.psh = amsSb.psh;
for(var i = 0; i < _dpb.psh; i++)
_dpb.phm += (byte)Math.Pow(2, i);
for(var i = 0; i < _dpb.psh; i++) _dpb.phm += (byte)Math.Pow(2, i);
_dpb.spt = (ushort)(amsSb.spt * (sectorSize / 128));
var directoryLength = (uint)(((ulong)_dpb.drm + 1) * 32 / sectorSize);
imagePlugin.ReadSectors(firstDirectorySector + partition.Start, directoryLength,
imagePlugin.ReadSectors(firstDirectorySector + partition.Start,
directoryLength,
out directory);
// Build a CP/M disk definition
@@ -276,8 +274,7 @@ public sealed partial class CPM
}
};
for(var si = 0; si < amsSb.spt; si++)
_workingDefinition.side1.sectorIds[si] = si + 1;
for(var si = 0; si < amsSb.spt; si++) _workingDefinition.side1.sectorIds[si] = si + 1;
if(amsSb.format == 2)
{
@@ -294,8 +291,7 @@ public sealed partial class CPM
sectorIds = new int[amsSb.spt]
};
for(var si = 0; si < amsSb.spt; si++)
_workingDefinition.side2.sectorIds[si] = si + 1;
for(var si = 0; si < amsSb.spt; si++) _workingDefinition.side2.sectorIds[si] = si + 1;
}
else
_workingDefinition.order = null;
@@ -320,8 +316,7 @@ public sealed partial class CPM
ushort sum = 0;
// Sum of all 16-bit words that make this sector must be 0
for(var i = 0; i < sector.Length; i += 2)
sum += BitConverter.ToUInt16(sector, i);
for(var i = 0; i < sector.Length; i += 2) sum += BitConverter.ToUInt16(sector, i);
// It may happen that there is a corrupted superblock
// Better to ignore corrupted than to false positive the rest
@@ -368,7 +363,8 @@ public sealed partial class CPM
var directoryLength = (uint)(((ulong)_dpb.drm + 1) * 32 / sectorSize);
imagePlugin.ReadSectors(firstDirectorySector + partition.Start, directoryLength,
imagePlugin.ReadSectors(firstDirectorySector + partition.Start,
directoryLength,
out directory);
AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Found_CPM_86_hard_disk_superblock);
@@ -410,8 +406,7 @@ public sealed partial class CPM
for(var si = 0; si < hddSb.sectorsPerTrack; si++)
_workingDefinition.side1.sectorIds[si] = si + 1;
for(var si = 0; si < hddSb.spt; si++)
_workingDefinition.side2.sectorIds[si] = si + 1;
for(var si = 0; si < hddSb.spt; si++) _workingDefinition.side2.sectorIds[si] = si + 1;
}
}
}
@@ -496,8 +491,7 @@ public sealed partial class CPM
sofs = 0
};
for(var si = 0; si < 8; si++)
_workingDefinition.side1.sectorIds[si] = si + 1;
for(var si = 0; si < 8; si++) _workingDefinition.side1.sectorIds[si] = si + 1;
}
break;
@@ -556,11 +550,9 @@ public sealed partial class CPM
sofs = 0
};
for(var si = 0; si < 8; si++)
_workingDefinition.side1.sectorIds[si] = si + 1;
for(var si = 0; si < 8; si++) _workingDefinition.side1.sectorIds[si] = si + 1;
for(var si = 0; si < 8; si++)
_workingDefinition.side2.sectorIds[si] = si + 1;
for(var si = 0; si < 8; si++) _workingDefinition.side2.sectorIds[si] = si + 1;
}
break;
@@ -621,11 +613,9 @@ public sealed partial class CPM
sofs = 0
};
for(var si = 0; si < 9; si++)
_workingDefinition.side1.sectorIds[si] = si + 1;
for(var si = 0; si < 9; si++) _workingDefinition.side1.sectorIds[si] = si + 1;
for(var si = 0; si < 9; si++)
_workingDefinition.side2.sectorIds[si] = si + 1;
for(var si = 0; si < 9; si++) _workingDefinition.side2.sectorIds[si] = si + 1;
}
break;
@@ -685,11 +675,9 @@ public sealed partial class CPM
sofs = 0
};
for(var si = 0; si < 9; si++)
_workingDefinition.side1.sectorIds[si] = si + 1;
for(var si = 0; si < 9; si++) _workingDefinition.side1.sectorIds[si] = si + 1;
for(var si = 0; si < 9; si++)
_workingDefinition.side2.sectorIds[si] = si + 1;
for(var si = 0; si < 9; si++) _workingDefinition.side2.sectorIds[si] = si + 1;
}
break;
@@ -748,11 +736,9 @@ public sealed partial class CPM
sofs = 0
};
for(var si = 0; si < 9; si++)
_workingDefinition.side1.sectorIds[si] = si + 1;
for(var si = 0; si < 9; si++) _workingDefinition.side1.sectorIds[si] = si + 1;
for(var si = 0; si < 9; si++)
_workingDefinition.side2.sectorIds[si] = si + 1;
for(var si = 0; si < 9; si++) _workingDefinition.side2.sectorIds[si] = si + 1;
}
break;
@@ -811,11 +797,9 @@ public sealed partial class CPM
sofs = 0
};
for(var si = 0; si < 15; si++)
_workingDefinition.side1.sectorIds[si] = si + 1;
for(var si = 0; si < 15; si++) _workingDefinition.side1.sectorIds[si] = si + 1;
for(var si = 0; si < 15; si++)
_workingDefinition.side2.sectorIds[si] = si + 1;
for(var si = 0; si < 15; si++) _workingDefinition.side2.sectorIds[si] = si + 1;
}
break;
@@ -874,11 +858,9 @@ public sealed partial class CPM
sofs = 0
};
for(var si = 0; si < 18; si++)
_workingDefinition.side1.sectorIds[si] = si + 1;
for(var si = 0; si < 18; si++) _workingDefinition.side1.sectorIds[si] = si + 1;
for(var si = 0; si < 18; si++)
_workingDefinition.side2.sectorIds[si] = si + 1;
for(var si = 0; si < 18; si++) _workingDefinition.side2.sectorIds[si] = si + 1;
}
break;
@@ -888,7 +870,8 @@ public sealed partial class CPM
{
var directoryLength = (uint)(((ulong)_dpb.drm + 1) * 32 / imagePlugin.Info.SectorSize);
imagePlugin.ReadSectors(firstDirectorySector86 + partition.Start, directoryLength,
imagePlugin.ReadSectors(firstDirectorySector86 + partition.Start,
directoryLength,
out directory);
AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Found_CPM_86_floppy_identifier);
@@ -962,7 +945,8 @@ public sealed partial class CPM
}
// Head changes after whole side
else if(string.Compare(def.order, "CYLINDERS",
else if(string.Compare(def.order,
"CYLINDERS",
StringComparison.InvariantCultureIgnoreCase) ==
0)
{
@@ -981,13 +965,14 @@ public sealed partial class CPM
}
// TODO: Implement COLUMBIA ordering
else if(string.Compare(def.order, "COLUMBIA",
else if(string.Compare(def.order,
"COLUMBIA",
StringComparison.InvariantCultureIgnoreCase) ==
0)
{
AaruConsole.DebugWriteLine(MODULE_NAME,
Localization.
Dont_know_how_to_handle_COLUMBIA_ordering_not_proceeding_with_this_definition);
Localization
.Dont_know_how_to_handle_COLUMBIA_ordering_not_proceeding_with_this_definition);
continue;
}
@@ -997,16 +982,16 @@ public sealed partial class CPM
0)
{
AaruConsole.DebugWriteLine(MODULE_NAME,
Localization.
Don_know_how_to_handle_EAGLE_ordering_not_proceeding_with_this_definition);
Localization
.Don_know_how_to_handle_EAGLE_ordering_not_proceeding_with_this_definition);
continue;
}
else
{
AaruConsole.DebugWriteLine(MODULE_NAME,
Localization.
Unknown_order_type_0_not_proceeding_with_this_definition,
Localization
.Unknown_order_type_0_not_proceeding_with_this_definition,
def.order);
continue;
@@ -1018,13 +1003,13 @@ public sealed partial class CPM
for(var p = 0; p < dirLen; p++)
{
errno =
imagePlugin.
ReadSector((ulong)((int)offset + (int)partition.Start + p / _sectorMask.Length * _sectorMask.Length + _sectorMask[p % _sectorMask.Length]),
out byte[] dirSector);
errno = imagePlugin.ReadSector((ulong)((int)offset +
(int)partition.Start +
p / _sectorMask.Length * _sectorMask.Length +
_sectorMask[p % _sectorMask.Length]),
out byte[] dirSector);
if(errno != ErrorNumber.NoError)
break;
if(errno != ErrorNumber.NoError) break;
ms.Write(dirSector, 0, dirSector.Length);
}
@@ -1034,21 +1019,21 @@ public sealed partial class CPM
if(def.evenOdd)
{
AaruConsole.DebugWriteLine(MODULE_NAME,
Localization.
Definition_contains_EVEN_ODD_field_with_unknown_meaning_detection_may_be_wrong);
Localization
.Definition_contains_EVEN_ODD_field_with_unknown_meaning_detection_may_be_wrong);
}
// Complement of the directory bytes if needed
if(def.complement)
{
for(var b = 0; b < directory.Length; b++)
directory[b] = (byte)(~directory[b] & 0xFF);
for(var b = 0; b < directory.Length; b++) directory[b] = (byte)(~directory[b] & 0xFF);
}
// Check the directory
if(CheckDir(directory))
{
AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Definition_0_has_a_correct_directory,
AaruConsole.DebugWriteLine(MODULE_NAME,
Localization.Definition_0_has_a_correct_directory,
def.comment);
// Build a Disc Parameter Block
@@ -1157,8 +1142,7 @@ public sealed partial class CPM
metadata = new FileSystem();
// As the identification is so complex, just call Identify() and relay on its findings
if(!Identify(imagePlugin, partition) || !_cpmFound || _workingDefinition == null || _dpb == null)
return;
if(!Identify(imagePlugin, partition) || !_cpmFound || _workingDefinition == null || _dpb == null) return;
var sb = new StringBuilder();
sb.AppendLine(Localization.CPM_filesystem);
@@ -1170,8 +1154,8 @@ public sealed partial class CPM
if(_dpb.dsm > 0)
{
sb.AppendFormat(Localization.Volume_contains_0_blocks_1_bytes, _dpb.dsm, _dpb.dsm * (128 << _dpb.bsh)).
AppendLine();
sb.AppendFormat(Localization.Volume_contains_0_blocks_1_bytes, _dpb.dsm, _dpb.dsm * (128 << _dpb.bsh))
.AppendLine();
}
sb.AppendFormat(Localization.Volume_contains_0_directory_entries, _dpb.drm + 1).AppendLine();
@@ -1181,8 +1165,9 @@ public sealed partial class CPM
else
{
sb.AppendFormat(Localization.Volume_reserves_1_tracks_0_sectors_for_system,
_workingDefinition.ofs * _workingDefinition.sectorsPerTrack, _workingDefinition.ofs).
AppendLine();
_workingDefinition.ofs * _workingDefinition.sectorsPerTrack,
_workingDefinition.ofs)
.AppendLine();
}
if(_workingDefinition.side1.sectorIds.Length >= 2)
@@ -1201,8 +1186,8 @@ public sealed partial class CPM
if(interleaveSide2 > 1)
{
sb.AppendFormat(Localization.Side_one_uses_0_one_software_interleaving, interleaveSide2).
AppendLine();
sb.AppendFormat(Localization.Side_one_uses_0_one_software_interleaving, interleaveSide2)
.AppendLine();
}
}
@@ -1217,8 +1202,8 @@ public sealed partial class CPM
break;
default:
sb.AppendFormat(Localization.Unknown_how_0_side_ordering_works, _workingDefinition.order).
AppendLine();
sb.AppendFormat(Localization.Unknown_how_0_side_ordering_works, _workingDefinition.order)
.AppendLine();
break;
}
@@ -1238,25 +1223,22 @@ public sealed partial class CPM
:X2}H AL1 {_dpb.al1:X2}H OFS {_workingDefinition.ofs}");
}
if(_label != null)
sb.AppendFormat(Localization.Volume_label_0, _label).AppendLine();
if(_label != null) sb.AppendFormat(Localization.Volume_label_0, _label).AppendLine();
if(_standardTimestamps)
sb.AppendLine(Localization.Volume_uses_standard_CPM_timestamps);
if(_standardTimestamps) sb.AppendLine(Localization.Volume_uses_standard_CPM_timestamps);
if(_thirdPartyTimestamps)
sb.AppendLine(Localization.Volume_uses_third_party_timestamps);
if(_thirdPartyTimestamps) sb.AppendLine(Localization.Volume_uses_third_party_timestamps);
if(_labelCreationDate != null)
{
sb.AppendFormat(Localization.Volume_created_on_0, DateHandlers.CpmToDateTime(_labelCreationDate)).
AppendLine();
sb.AppendFormat(Localization.Volume_created_on_0, DateHandlers.CpmToDateTime(_labelCreationDate))
.AppendLine();
}
if(_labelUpdateDate != null)
{
sb.AppendFormat(Localization.Volume_updated_on_0, DateHandlers.CpmToDateTime(_labelUpdateDate)).
AppendLine();
sb.AppendFormat(Localization.Volume_updated_on_0, DateHandlers.CpmToDateTime(_labelUpdateDate))
.AppendLine();
}
metadata = new FileSystem();
@@ -1268,11 +1250,9 @@ public sealed partial class CPM
else
metadata.Clusters = partition.End - partition.Start;
if(_labelCreationDate != null)
metadata.CreationDate = DateHandlers.CpmToDateTime(_labelCreationDate);
if(_labelCreationDate != null) metadata.CreationDate = DateHandlers.CpmToDateTime(_labelCreationDate);
if(_labelUpdateDate != null)
metadata.ModificationDate = DateHandlers.CpmToDateTime(_labelUpdateDate);
if(_labelUpdateDate != null) metadata.ModificationDate = DateHandlers.CpmToDateTime(_labelUpdateDate);
metadata.Type = FS_TYPE;
metadata.VolumeName = _label;

View File

@@ -89,12 +89,12 @@ public sealed partial class CPM
internal string[] Contents;
internal int Position;
#region IDirNode Members
#region IDirNode Members
/// <inheritdoc />
public string Path { get; init; }
#endregion
#endregion
}
#endregion
@@ -105,7 +105,7 @@ public sealed partial class CPM
{
internal byte[] Cache;
#region IFileNode Members
#region IFileNode Members
/// <inheritdoc />
public string Path { get; init; }
@@ -116,7 +116,7 @@ public sealed partial class CPM
/// <inheritdoc />
public long Offset { get; set; }
#endregion
#endregion
}
#endregion

View File

@@ -94,7 +94,8 @@ public sealed partial class CPM
}
// Head changes after whole side
else if(string.Compare(_workingDefinition.order, "CYLINDERS",
else if(string.Compare(_workingDefinition.order,
"CYLINDERS",
StringComparison.InvariantCultureIgnoreCase) ==
0)
{
@@ -122,8 +123,8 @@ public sealed partial class CPM
0)
{
AaruConsole.DebugWriteLine(MODULE_NAME,
Localization.
Dont_know_how_to_handle_COLUMBIA_ordering_not_proceeding_with_this_definition);
Localization
.Dont_know_how_to_handle_COLUMBIA_ordering_not_proceeding_with_this_definition);
return ErrorNumber.NotImplemented;
}
@@ -132,8 +133,8 @@ public sealed partial class CPM
else if(string.Compare(_workingDefinition.order, "EAGLE", StringComparison.InvariantCultureIgnoreCase) == 0)
{
AaruConsole.DebugWriteLine(MODULE_NAME,
Localization.
Don_know_how_to_handle_EAGLE_ordering_not_proceeding_with_this_definition);
Localization
.Don_know_how_to_handle_EAGLE_ordering_not_proceeding_with_this_definition);
return ErrorNumber.NotImplemented;
}
@@ -158,16 +159,16 @@ public sealed partial class CPM
for(var p = 0; p <= (int)(partition.End - partition.Start); p++)
{
ErrorNumber errno =
_device.ReadSector((ulong)((int)partition.Start + p / _sectorMask.Length * _sectorMask.Length + _sectorMask[p % _sectorMask.Length]),
_device.ReadSector((ulong)((int)partition.Start +
p / _sectorMask.Length * _sectorMask.Length +
_sectorMask[p % _sectorMask.Length]),
out byte[] readSector);
if(errno != ErrorNumber.NoError)
return errno;
if(errno != ErrorNumber.NoError) return errno;
if(_workingDefinition.complement)
{
for(var b = 0; b < readSector.Length; b++)
readSector[b] = (byte)(~readSector[b] & 0xFF);
for(var b = 0; b < readSector.Length; b++) readSector[b] = (byte)(~readSector[b] & 0xFF);
}
deinterleavedSectors.Add((ulong)p, readSector);
@@ -204,8 +205,7 @@ public sealed partial class CPM
blockMs.Write(sector, 0, sector.Length);
sectorsPerBlock++;
if(sectorsPerBlock != blockSize / sector.Length)
continue;
if(sectorsPerBlock != blockSize / sector.Length) continue;
allocationBlocks.Add(blockNo++, blockMs.ToArray());
sectorsPerBlock = 0;
@@ -238,8 +238,7 @@ public sealed partial class CPM
byte[] directory = dirMs.ToArray();
if(directory == null)
return ErrorNumber.InvalidArgument;
if(directory == null) return ErrorNumber.InvalidArgument;
var dirCnt = 0;
string file1 = null;
@@ -291,18 +290,15 @@ public sealed partial class CPM
validEntry &= entry.extension[i] >= 0x20;
}
if(!validEntry)
continue;
if(!validEntry) continue;
string filename = Encoding.ASCII.GetString(entry.filename).Trim();
string extension = Encoding.ASCII.GetString(entry.extension).Trim();
// If user is != 0, append user to name to have identical filenames
if(user > 0)
filename = $"{user:X1}:{filename}";
if(user > 0) filename = $"{user:X1}:{filename}";
if(!string.IsNullOrEmpty(extension))
filename = filename + "." + extension;
if(!string.IsNullOrEmpty(extension)) filename = filename + "." + extension;
filename = filename.Replace('/', '\u2215');
@@ -332,14 +328,11 @@ public sealed partial class CPM
blocks = new List<ushort>();
// Attributes
if(hidden)
fInfo.Attributes |= FileAttributes.Hidden;
if(hidden) fInfo.Attributes |= FileAttributes.Hidden;
if(rdOnly)
fInfo.Attributes |= FileAttributes.ReadOnly;
if(rdOnly) fInfo.Attributes |= FileAttributes.ReadOnly;
if(system)
fInfo.Attributes |= FileAttributes.System;
if(system) fInfo.Attributes |= FileAttributes.System;
// Supposedly there is a value in the directory entry telling how many blocks are designated in
// this entry. However some implementations tend to do whatever they wish, but none will ever
@@ -356,8 +349,7 @@ public sealed partial class CPM
_statCache.Add(filename, fInfo);
// Add the file to the directory listing
if(!_dirList.Contains(filename))
_dirList.Add(filename);
if(!_dirList.Contains(filename)) _dirList.Add(filename);
// Count entries 3 by 3 for timestamps
switch(dirCnt % 3)
@@ -406,18 +398,15 @@ public sealed partial class CPM
validEntry &= entry.extension[i] >= 0x20;
}
if(!validEntry)
continue;
if(!validEntry) continue;
string filename = Encoding.ASCII.GetString(entry.filename).Trim();
string extension = Encoding.ASCII.GetString(entry.extension).Trim();
// If user is != 0, append user to name to have identical filenames
if(user > 0)
filename = $"{user:X1}:{filename}";
if(user > 0) filename = $"{user:X1}:{filename}";
if(!string.IsNullOrEmpty(extension))
filename = filename + "." + extension;
if(!string.IsNullOrEmpty(extension)) filename = filename + "." + extension;
filename = filename.Replace('/', '\u2215');
@@ -447,14 +436,11 @@ public sealed partial class CPM
blocks = new List<ushort>();
// Attributes
if(hidden)
fInfo.Attributes |= FileAttributes.Hidden;
if(hidden) fInfo.Attributes |= FileAttributes.Hidden;
if(rdOnly)
fInfo.Attributes |= FileAttributes.ReadOnly;
if(rdOnly) fInfo.Attributes |= FileAttributes.ReadOnly;
if(system)
fInfo.Attributes |= FileAttributes.System;
if(system) fInfo.Attributes |= FileAttributes.System;
// Supposedly there is a value in the directory entry telling how many blocks are designated in
// this entry. However some implementations tend to do whatever they wish, but none will ever
@@ -471,8 +457,7 @@ public sealed partial class CPM
_statCache.Add(filename, fInfo);
// Add the file to the directory listing
if(!_dirList.Contains(filename))
_dirList.Add(filename);
if(!_dirList.Contains(filename)) _dirList.Add(filename);
// Count entries 3 by 3 for timestamps
switch(dirCnt % 3)
@@ -503,27 +488,22 @@ public sealed partial class CPM
int user = entry.userNumber & 0x0F;
for(var i = 0; i < 8; i++)
entry.filename[i] &= 0x7F;
for(var i = 0; i < 8; i++) entry.filename[i] &= 0x7F;
for(var i = 0; i < 3; i++)
entry.extension[i] &= 0x7F;
for(var i = 0; i < 3; i++) entry.extension[i] &= 0x7F;
string filename = Encoding.ASCII.GetString(entry.filename).Trim();
string extension = Encoding.ASCII.GetString(entry.extension).Trim();
// If user is != 0, append user to name to have identical filenames
if(user > 0)
filename = $"{user:X1}:{filename}";
if(user > 0) filename = $"{user:X1}:{filename}";
if(!string.IsNullOrEmpty(extension))
filename = filename + "." + extension;
if(!string.IsNullOrEmpty(extension)) filename = filename + "." + extension;
filename = filename.Replace('/', '\u2215');
// Do not repeat passwords
if(_passwordCache.ContainsKey(filename))
_passwordCache.Remove(filename);
if(_passwordCache.ContainsKey(filename)) _passwordCache.Remove(filename);
// Copy whole password entry
var tmp = new byte[32];
@@ -745,8 +725,7 @@ public sealed partial class CPM
{
var fileMs = new MemoryStream();
if(_statCache.TryGetValue(filename, out FileEntryInfo fInfo))
_statCache.Remove(filename);
if(_statCache.TryGetValue(filename, out FileEntryInfo fInfo)) _statCache.Remove(filename);
fInfo.Blocks = 0;
@@ -754,8 +733,7 @@ public sealed partial class CPM
{
for(var ex = 0; ex < extents.Count; ex++)
{
if(!extents.TryGetValue(ex, out List<ushort> alBlks))
continue;
if(!extents.TryGetValue(ex, out List<ushort> alBlks)) continue;
foreach(ushort alBlk in alBlks)
{
@@ -787,8 +765,7 @@ public sealed partial class CPM
var tmp = new byte[8];
Array.Copy(kvp.Value, 16, tmp, 0, 8);
for(var t = 0; t < 8; t++)
tmp[t] ^= kvp.Value[13];
for(var t = 0; t < 8; t++) tmp[t] ^= kvp.Value[13];
_decodedPasswordCache.Add(kvp.Key, tmp);
}
@@ -812,14 +789,11 @@ public sealed partial class CPM
Type = FS_TYPE
};
if(_labelCreationDate != null)
Metadata.CreationDate = DateHandlers.CpmToDateTime(_labelCreationDate);
if(_labelCreationDate != null) Metadata.CreationDate = DateHandlers.CpmToDateTime(_labelCreationDate);
if(_labelUpdateDate != null)
Metadata.ModificationDate = DateHandlers.CpmToDateTime(_labelUpdateDate);
if(_labelUpdateDate != null) Metadata.ModificationDate = DateHandlers.CpmToDateTime(_labelUpdateDate);
if(!string.IsNullOrEmpty(_label))
Metadata.VolumeName = _label;
if(!string.IsNullOrEmpty(_label)) Metadata.VolumeName = _label;
_mounted = true;
@@ -831,8 +805,7 @@ public sealed partial class CPM
{
stat = null;
if(!_mounted)
return ErrorNumber.AccessDenied;
if(!_mounted) return ErrorNumber.AccessDenied;
stat = _cpmStat;

View File

@@ -43,24 +43,21 @@ public sealed partial class CPM
/// <inheritdoc />
public ErrorNumber GetXattr(string path, string xattr, ref byte[] buf)
{
if(!_mounted)
return ErrorNumber.AccessDenied;
if(!_mounted) return ErrorNumber.AccessDenied;
string[] pathElements = path.Split(new[]
{
'/'
}, StringSplitOptions.RemoveEmptyEntries);
{
'/'
},
StringSplitOptions.RemoveEmptyEntries);
if(pathElements.Length != 1)
return ErrorNumber.NotSupported;
if(pathElements.Length != 1) return ErrorNumber.NotSupported;
if(!_fileCache.ContainsKey(pathElements[0].ToUpperInvariant()))
return ErrorNumber.NoSuchFile;
if(!_fileCache.ContainsKey(pathElements[0].ToUpperInvariant())) return ErrorNumber.NoSuchFile;
if(string.Compare(xattr, "com.caldera.cpm.password", StringComparison.InvariantCulture) == 0)
{
if(!_passwordCache.TryGetValue(pathElements[0].ToUpperInvariant(), out buf))
return ErrorNumber.NoError;
if(!_passwordCache.TryGetValue(pathElements[0].ToUpperInvariant(), out buf)) return ErrorNumber.NoError;
}
if(string.Compare(xattr, "com.caldera.cpm.password.text", StringComparison.InvariantCulture) != 0)
@@ -76,24 +73,21 @@ public sealed partial class CPM
{
xattrs = null;
if(!_mounted)
return ErrorNumber.AccessDenied;
if(!_mounted) return ErrorNumber.AccessDenied;
string[] pathElements = path.Split(new[]
{
'/'
}, StringSplitOptions.RemoveEmptyEntries);
{
'/'
},
StringSplitOptions.RemoveEmptyEntries);
if(pathElements.Length != 1)
return ErrorNumber.NotSupported;
if(pathElements.Length != 1) return ErrorNumber.NotSupported;
if(!_fileCache.ContainsKey(pathElements[0].ToUpperInvariant()))
return ErrorNumber.NoSuchFile;
if(!_fileCache.ContainsKey(pathElements[0].ToUpperInvariant())) return ErrorNumber.NoSuchFile;
xattrs = new List<string>();
if(_passwordCache.ContainsKey(pathElements[0].ToUpperInvariant()))
xattrs.Add("com.caldera.cpm.password");
if(_passwordCache.ContainsKey(pathElements[0].ToUpperInvariant())) xattrs.Add("com.caldera.cpm.password");
if(_decodedPasswordCache.ContainsKey(pathElements[0].ToUpperInvariant()))
xattrs.Add("com.caldera.cpm.password.text");