示例#1
0
        public Errno Stat(string path, out FileEntryInfo stat)
        {
            stat = null;

            string[] pathElements = path.Split(new[]
            {
                '/'
            }, StringSplitOptions.RemoveEmptyEntries);

            if (pathElements.Length != 1)
            {
                return(Errno.NotSupported);
            }

            if (debug)
            {
                if (string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
                    string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0)
                {
                    stat = new FileEntryInfo
                    {
                        Attributes = FileAttributes.System, BlockSize = device.Info.SectorSize * multiplier, Links = 1
                    };

                    if (string.Compare(path, "$", StringComparison.InvariantCulture) == 0)
                    {
                        stat.Blocks = (catalogBlocks.Length / stat.BlockSize) + (catalogBlocks.Length % stat.BlockSize);
                        stat.Length = catalogBlocks.Length;
                    }
                    else
                    {
                        stat.Blocks = (bootBlocks.Length / stat.BlockSize) + (catalogBlocks.Length % stat.BlockSize);
                        stat.Length = bootBlocks.Length;
                    }

                    return(Errno.NoError);
                }
            }

            Errno error = GetFileEntry(path, out PascalFileEntry entry);

            if (error != Errno.NoError)
            {
                return(error);
            }

            stat = new FileEntryInfo
            {
                Attributes       = FileAttributes.File, Blocks = entry.LastBlock - entry.FirstBlock,
                BlockSize        = device.Info.SectorSize * multiplier,
                LastWriteTimeUtc = DateHandlers.UcsdPascalToDateTime(entry.ModificationTime),
                Length           = ((entry.LastBlock - entry.FirstBlock) * device.Info.SectorSize * multiplier) +
                                   entry.LastBytes,
                Links = 1
            };

            return(Errno.NoError);
        }
示例#2
0
文件: Info.cs 项目: paulyc/Aaru
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding = encoding ?? new Apple2();
            var sbInformation = new StringBuilder();

            information = "";
            _multiplier = (uint)(imagePlugin.Info.SectorSize == 256 ? 2 : 1);

            if (imagePlugin.Info.Sectors < 3)
            {
                return;
            }

            // Blocks 0 and 1 are boot code
            byte[] volBlock = imagePlugin.ReadSectors((_multiplier * 2) + partition.Start, _multiplier);

            // On Apple //, it's little endian
            // TODO: Fix
            //BigEndianBitConverter.IsLittleEndian =
            //    multiplier == 2 ? !BitConverter.IsLittleEndian : BitConverter.IsLittleEndian;

            var volEntry = new PascalVolumeEntry
            {
                FirstBlock = BigEndianBitConverter.ToInt16(volBlock, 0x00),
                LastBlock  = BigEndianBitConverter.ToInt16(volBlock, 0x02),
                EntryType  = (PascalFileKind)BigEndianBitConverter.ToInt16(volBlock, 0x04),
                VolumeName = new byte[8],
                Blocks     = BigEndianBitConverter.ToInt16(volBlock, 0x0E),
                Files      = BigEndianBitConverter.ToInt16(volBlock, 0x10),
                Dummy      = BigEndianBitConverter.ToInt16(volBlock, 0x12),
                LastBoot   = BigEndianBitConverter.ToInt16(volBlock, 0x14),
                Tail       = BigEndianBitConverter.ToInt32(volBlock, 0x16)
            };

            Array.Copy(volBlock, 0x06, volEntry.VolumeName, 0, 8);

            // First block is always 0 (even is it's sector 2)
            if (volEntry.FirstBlock != 0)
            {
                return;
            }

            // Last volume record block must be after first block, and before end of device
            if (volEntry.LastBlock <= volEntry.FirstBlock ||
                (ulong)volEntry.LastBlock > (imagePlugin.Info.Sectors / _multiplier) - 2)
            {
                return;
            }

            // Volume record entry type must be volume or secure
            if (volEntry.EntryType != PascalFileKind.Volume &&
                volEntry.EntryType != PascalFileKind.Secure)
            {
                return;
            }

            // Volume name is max 7 characters
            if (volEntry.VolumeName[0] > 7)
            {
                return;
            }

            // Volume blocks is equal to volume sectors
            if (volEntry.Blocks < 0 ||
                (ulong)volEntry.Blocks != imagePlugin.Info.Sectors / _multiplier)
            {
                return;
            }

            // There can be not less than zero files
            if (volEntry.Files < 0)
            {
                return;
            }

            sbInformation.AppendFormat("Volume record spans from block {0} to block {1}", volEntry.FirstBlock,
                                       volEntry.LastBlock).AppendLine();

            sbInformation.
            AppendFormat("Volume name: {0}", StringHandlers.PascalToString(volEntry.VolumeName, Encoding)).
            AppendLine();

            sbInformation.AppendFormat("Volume has {0} blocks", volEntry.Blocks).AppendLine();
            sbInformation.AppendFormat("Volume has {0} files", volEntry.Files).AppendLine();

            sbInformation.
            AppendFormat("Volume last booted at {0}", DateHandlers.UcsdPascalToDateTime(volEntry.LastBoot)).
            AppendLine();

            information = sbInformation.ToString();

            XmlFsType = new FileSystemType
            {
                Bootable       = !ArrayHelpers.ArrayIsNullOrEmpty(imagePlugin.ReadSectors(partition.Start, _multiplier * 2)),
                Clusters       = (ulong)volEntry.Blocks,
                ClusterSize    = imagePlugin.Info.SectorSize,
                Files          = (ulong)volEntry.Files,
                FilesSpecified = true,
                Type           = "UCSD Pascal",
                VolumeName     = StringHandlers.PascalToString(volEntry.VolumeName, Encoding)
            };
        }