Errno GetFileEntry(string path, out PascalFileEntry entry) { entry = new PascalFileEntry(); foreach (PascalFileEntry ent in fileEntries.Where(ent => string.Compare(path, StringHandlers .PascalToString(ent.Filename, Encoding), StringComparison .InvariantCultureIgnoreCase) == 0)) { entry = ent; return(Errno.NoError); } return(Errno.NoSuchFile); }
public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding, Dictionary <string, string> options, string @namespace) { device = imagePlugin; Encoding = encoding ?? new Apple2(); if (options == null) { options = GetDefaultOptions(); } if (options.TryGetValue("debug", out string debugString)) { bool.TryParse(debugString, out debug); } if (device.Info.Sectors < 3) { return(Errno.InvalidArgument); } multiplier = (uint)(imagePlugin.Info.SectorSize == 256 ? 2 : 1); // Blocks 0 and 1 are boot code catalogBlocks = device.ReadSectors(multiplier * 2, multiplier); // On Apple //, it's little endian // TODO: Fix //BigEndianBitConverter.IsLittleEndian = // multiplier == 2 ? !BitConverter.IsLittleEndian : BitConverter.IsLittleEndian; mountedVolEntry.FirstBlock = BigEndianBitConverter.ToInt16(catalogBlocks, 0x00); mountedVolEntry.LastBlock = BigEndianBitConverter.ToInt16(catalogBlocks, 0x02); mountedVolEntry.EntryType = (PascalFileKind)BigEndianBitConverter.ToInt16(catalogBlocks, 0x04); mountedVolEntry.VolumeName = new byte[8]; Array.Copy(catalogBlocks, 0x06, mountedVolEntry.VolumeName, 0, 8); mountedVolEntry.Blocks = BigEndianBitConverter.ToInt16(catalogBlocks, 0x0E); mountedVolEntry.Files = BigEndianBitConverter.ToInt16(catalogBlocks, 0x10); mountedVolEntry.Dummy = BigEndianBitConverter.ToInt16(catalogBlocks, 0x12); mountedVolEntry.LastBoot = BigEndianBitConverter.ToInt16(catalogBlocks, 0x14); mountedVolEntry.Tail = BigEndianBitConverter.ToInt32(catalogBlocks, 0x16); if (mountedVolEntry.FirstBlock != 0 || mountedVolEntry.LastBlock <= mountedVolEntry.FirstBlock || (ulong)mountedVolEntry.LastBlock > (device.Info.Sectors / multiplier) - 2 || (mountedVolEntry.EntryType != PascalFileKind.Volume && mountedVolEntry.EntryType != PascalFileKind.Secure) || mountedVolEntry.VolumeName[0] > 7 || mountedVolEntry.Blocks < 0 || (ulong)mountedVolEntry.Blocks != device.Info.Sectors / multiplier || mountedVolEntry.Files < 0) { return(Errno.InvalidArgument); } catalogBlocks = device.ReadSectors(multiplier * 2, (uint)(mountedVolEntry.LastBlock - mountedVolEntry.FirstBlock - 2) * multiplier); int offset = 26; fileEntries = new List <PascalFileEntry>(); while (offset + 26 < catalogBlocks.Length) { var entry = new PascalFileEntry { Filename = new byte[16], FirstBlock = BigEndianBitConverter.ToInt16(catalogBlocks, offset + 0x00), LastBlock = BigEndianBitConverter.ToInt16(catalogBlocks, offset + 0x02), EntryType = (PascalFileKind)BigEndianBitConverter.ToInt16(catalogBlocks, offset + 0x04), LastBytes = BigEndianBitConverter.ToInt16(catalogBlocks, offset + 0x16), ModificationTime = BigEndianBitConverter.ToInt16(catalogBlocks, offset + 0x18) }; Array.Copy(catalogBlocks, offset + 0x06, entry.Filename, 0, 16); if (entry.Filename[0] <= 15 && entry.Filename[0] > 0) { fileEntries.Add(entry); } offset += 26; } bootBlocks = device.ReadSectors(0, 2 * multiplier); XmlFsType = new FileSystemType { Bootable = !ArrayHelpers.ArrayIsNullOrEmpty(bootBlocks), Clusters = (ulong)mountedVolEntry.Blocks, ClusterSize = device.Info.SectorSize, Files = (ulong)mountedVolEntry.Files, FilesSpecified = true, Type = "UCSD Pascal", VolumeName = StringHandlers.PascalToString(mountedVolEntry.VolumeName, Encoding) }; mounted = true; return(Errno.NoError); }