Beispiel #1
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            uint sbSize = (uint)(Marshal.SizeOf <RefsVolumeHeader>() / imagePlugin.Info.SectorSize);

            if (Marshal.SizeOf <RefsVolumeHeader>() % imagePlugin.Info.SectorSize != 0)
            {
                sbSize++;
            }

            if (partition.Start + sbSize >= partition.End)
            {
                return(false);
            }

            byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize);

            if (sector.Length < Marshal.SizeOf <RefsVolumeHeader>())
            {
                return(false);
            }

            RefsVolumeHeader refsVhdr = Marshal.ByteArrayToStructureLittleEndian <RefsVolumeHeader>(sector);

            return(refsVhdr.identifier == FSRS && ArrayHelpers.ArrayIsNullOrEmpty(refsVhdr.mustBeZero) &&
                   refsVhdr.signature.SequenceEqual(refsSignature));
        }
Beispiel #2
0
        // TODO: This can be optimized
        public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
        {
            if (!IsWriting)
            {
                ErrorMessage = "Tried to write on a non-writable image";

                return(false);
            }

            if (data.Length % imageInfo.SectorSize != 0)
            {
                ErrorMessage = "Incorrect data size";

                return(false);
            }

            if (sectorAddress + length > imageInfo.Sectors)
            {
                ErrorMessage = "Tried to write past image size";

                return(false);
            }

            // Ignore empty sectors
            if (ArrayHelpers.ArrayIsNullOrEmpty(data))
            {
                if (currentChunk.type == CHUNK_TYPE_COPY)
                {
                    chunks.Add(currentChunk.sector, currentChunk);

                    currentChunk = new BlockChunk
                    {
                        type = CHUNK_TYPE_NOCOPY, sector = currentSector
                    };
                }

                currentChunk.sectors += (ulong)(data.Length / imageInfo.SectorSize);
                currentSector        += (ulong)(data.Length / imageInfo.SectorSize);
                masterChecksum.Update(data);

                ErrorMessage = "";

                return(true);
            }

            for (uint i = 0; i < length; i++)
            {
                byte[] tmp = new byte[imageInfo.SectorSize];
                Array.Copy(data, i * imageInfo.SectorSize, tmp, 0, imageInfo.SectorSize);

                if (!WriteSector(tmp, sectorAddress + i))
                {
                    return(false);
                }
            }

            ErrorMessage = "";

            return(true);
        }
Beispiel #3
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            RefsVolumeHeader refsVhdr = new RefsVolumeHeader();

            uint sbSize = (uint)(Marshal.SizeOf(refsVhdr) / imagePlugin.Info.SectorSize);

            if (Marshal.SizeOf(refsVhdr) % imagePlugin.Info.SectorSize != 0)
            {
                sbSize++;
            }

            if (partition.Start + sbSize >= partition.End)
            {
                return(false);
            }

            byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize);
            if (sector.Length < Marshal.SizeOf(refsVhdr))
            {
                return(false);
            }

            IntPtr sbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(refsVhdr));

            Marshal.Copy(sector, 0, sbPtr, Marshal.SizeOf(refsVhdr));
            refsVhdr = (RefsVolumeHeader)Marshal.PtrToStructure(sbPtr, typeof(RefsVolumeHeader));
            Marshal.FreeHGlobal(sbPtr);

            return(refsVhdr.identifier == FSRS && ArrayHelpers.ArrayIsNullOrEmpty(refsVhdr.mustBeZero) &&
                   refsVhdr.signature.SequenceEqual(refsSignature));
        }
Beispiel #4
0
        public bool Open(IFilter imageFilter)
        {
            Stream stream = imageFilter.GetDataForkStream();

            stream.Seek(0, SeekOrigin.Begin);

            byte[] hdrB = new byte[Marshal.SizeOf <RsIdeHeader>()];
            stream.Read(hdrB, 0, hdrB.Length);

            RsIdeHeader hdr = Marshal.ByteArrayToStructureLittleEndian <RsIdeHeader>(hdrB);

            if (!hdr.magic.SequenceEqual(signature))
            {
                return(false);
            }

            dataOff = hdr.dataOff;

            imageInfo.MediaType            = MediaType.GENERIC_HDD;
            imageInfo.SectorSize           = (uint)(hdr.flags.HasFlag(RsIdeFlags.HalfSectors) ? 256 : 512);
            imageInfo.ImageSize            = (ulong)(stream.Length - dataOff);
            imageInfo.Sectors              = imageInfo.ImageSize / imageInfo.SectorSize;
            imageInfo.CreationTime         = imageFilter.GetCreationTime();
            imageInfo.LastModificationTime = imageFilter.GetLastWriteTime();
            imageInfo.MediaTitle           = Path.GetFileNameWithoutExtension(imageFilter.GetFilename());
            imageInfo.XmlMediaType         = XmlMediaType.BlockMedia;
            imageInfo.Version              = $"{hdr.revision >> 8}.{hdr.revision & 0x0F}";

            if (!ArrayHelpers.ArrayIsNullOrEmpty(hdr.identify))
            {
                identify = new byte[512];
                Array.Copy(hdr.identify, 0, identify, 0, hdr.identify.Length);
                Identify.IdentifyDevice?ataId = Decoders.ATA.Identify.Decode(identify);

                if (ataId.HasValue)
                {
                    imageInfo.ReadableMediaTags.Add(MediaTagType.ATA_IDENTIFY);
                    imageInfo.Cylinders             = ataId.Value.Cylinders;
                    imageInfo.Heads                 = ataId.Value.Heads;
                    imageInfo.SectorsPerTrack       = ataId.Value.SectorsPerCard;
                    imageInfo.DriveFirmwareRevision = ataId.Value.FirmwareRevision;
                    imageInfo.DriveModel            = ataId.Value.Model;
                    imageInfo.DriveSerialNumber     = ataId.Value.SerialNumber;
                    imageInfo.MediaSerialNumber     = ataId.Value.MediaSerial;
                    imageInfo.MediaManufacturer     = ataId.Value.MediaManufacturer;
                }
            }

            if (imageInfo.Cylinders == 0 || imageInfo.Heads == 0 || imageInfo.SectorsPerTrack == 0)
            {
                imageInfo.Cylinders       = (uint)(imageInfo.Sectors / 16 / 63);
                imageInfo.Heads           = 16;
                imageInfo.SectorsPerTrack = 63;
            }

            rsIdeImageFilter = imageFilter;

            return(true);
        }
Beispiel #5
0
        public bool Identify(IFilter imageFilter)
        {
            Stream stream = imageFilter.GetDataForkStream();

            if ((stream.Length - Marshal.SizeOf <DriFooter>()) % 512 != 0)
            {
                return(false);
            }

            byte[] buffer = new byte[Marshal.SizeOf <DriFooter>()];
            stream.Seek(-buffer.Length, SeekOrigin.End);
            stream.Read(buffer, 0, buffer.Length);

            DriFooter tmpFooter = Marshal.ByteArrayToStructureLittleEndian <DriFooter>(buffer);

            string sig = StringHandlers.CToString(tmpFooter.signature);

            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.signature = \"{0}\"", sig);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.five = {0}", tmpFooter.bpb.five);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.driveCode = {0}", tmpFooter.bpb.driveCode);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.unknown = {0}", tmpFooter.bpb.unknown);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.cylinders = {0}", tmpFooter.bpb.cylinders);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.unknown2 = {0}", tmpFooter.bpb.unknown2);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.bps = {0}", tmpFooter.bpb.bps);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.spc = {0}", tmpFooter.bpb.spc);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.rsectors = {0}", tmpFooter.bpb.rsectors);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.fats_no = {0}", tmpFooter.bpb.fats_no);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.sectors = {0}", tmpFooter.bpb.sectors);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.media_descriptor = {0}",
                                      tmpFooter.bpb.media_descriptor);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.spfat = {0}", tmpFooter.bpb.spfat);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.sptrack = {0}", tmpFooter.bpb.sptrack);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.heads = {0}", tmpFooter.bpb.heads);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.hsectors = {0}", tmpFooter.bpb.hsectors);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.drive_no = {0}", tmpFooter.bpb.drive_no);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.unknown3 = {0}", tmpFooter.bpb.unknown3);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.unknown4 = {0}", tmpFooter.bpb.unknown4);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.sptrack2 = {0}", tmpFooter.bpb.sptrack2);
            DicConsole.DebugWriteLine("DRI DiskCopy plugin",
                                      "ArrayHelpers.ArrayIsNullOrEmpty(tmp_footer.bpb.unknown5) = {0}",
                                      ArrayHelpers.ArrayIsNullOrEmpty(tmpFooter.bpb.unknown5));

            Regex regexSignature = new Regex(REGEX_DRI);
            Match matchSignature = regexSignature.Match(sig);

            DicConsole.DebugWriteLine("DRI DiskCopy plugin", "MatchSignature.Success? = {0}", matchSignature.Success);

            if (!matchSignature.Success)
            {
                return(false);
            }

            if (tmpFooter.bpb.sptrack * tmpFooter.bpb.cylinders * tmpFooter.bpb.heads != tmpFooter.bpb.sectors)
            {
                return(false);
            }

            return(tmpFooter.bpb.sectors * tmpFooter.bpb.bps + Marshal.SizeOf <DriFooter>() == stream.Length);
        }
Beispiel #6
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";

            var sb = new StringBuilder();

            int  sbSizeInBytes   = Marshal.SizeOf <SuperBlock>();
            uint sbSizeInSectors = (uint)(sbSizeInBytes / imagePlugin.Info.SectorSize);

            if (sbSizeInBytes % imagePlugin.Info.SectorSize > 0)
            {
                sbSizeInSectors++;
            }

            byte[]     sbSector = imagePlugin.ReadSectors(partition.Start, sbSizeInSectors);
            SuperBlock supblk   = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sbSector);

            sb.AppendFormat("{0} bytes per zone", supblk.s_zone_size).AppendLine();

            sb.AppendFormat("{0} zones in volume ({1} bytes)", supblk.s_nzones, supblk.s_nzones * supblk.s_zone_size).
            AppendLine();

            sb.AppendFormat("{0} inodes", supblk.s_ninodes).AppendLine();

            sb.AppendFormat("{0} data zones ({1} bytes)", supblk.s_ndatazones,
                            supblk.s_ndatazones * supblk.s_zone_size).AppendLine();

            sb.AppendFormat("{0} imap zones ({1} bytes)", supblk.s_imap_zones,
                            supblk.s_imap_zones * supblk.s_zone_size).AppendLine();

            sb.AppendFormat("{0} zmap zones ({1} bytes)", supblk.s_zmap_zones,
                            supblk.s_zmap_zones * supblk.s_zone_size).AppendLine();

            sb.AppendFormat("First data zone: {0}", supblk.s_firstdatazone).AppendLine();

            sb.AppendFormat("Maximum filesize is {0} bytes ({1} MiB)", supblk.s_max_size, supblk.s_max_size / 1048576).
            AppendLine();

            sb.AppendFormat("{0} zones reserved for kernel images ({1} bytes)", supblk.s_kernzones,
                            supblk.s_kernzones * supblk.s_zone_size).AppendLine();

            sb.AppendFormat("First kernel zone: {0}", supblk.s_firstkernzone).AppendLine();

            XmlFsType = new FileSystemType
            {
                Bootable    = !ArrayHelpers.ArrayIsNullOrEmpty(supblk.s_boot_segment),
                Clusters    = supblk.s_nzones,
                ClusterSize = supblk.s_zone_size,
                Type        = "Xia filesystem"
            };

            information = sb.ToString();
        }
Beispiel #7
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = new Radix50();
            information = "";

            StringBuilder sb = new StringBuilder();

            byte[] hbSector = imagePlugin.ReadSector(1 + partition.Start);

            GCHandle      handle    = GCHandle.Alloc(hbSector, GCHandleType.Pinned);
            RT11HomeBlock homeblock =
                (RT11HomeBlock)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(RT11HomeBlock));

            handle.Free();

            /* TODO: Is this correct?
             * Assembler:
             *      MOV address, R0
             *      CLR R1
             *      MOV #255., R2
             * 10$: ADD (R0)+, R1
             *      SOB R2, 10$
             *      MOV 1,@R0
             */
            ushort check = 0;

            for (int i = 0; i < 512; i += 2)
            {
                check += BitConverter.ToUInt16(hbSector, i);
            }

            sb.AppendFormat("Volume format is {0}",
                            StringHandlers.SpacePaddedToString(homeblock.format, Encoding.ASCII)).AppendLine();
            sb.AppendFormat("{0} sectors per cluster ({1} bytes)", homeblock.cluster, homeblock.cluster * 512)
            .AppendLine();
            sb.AppendFormat("First directory segment starts at block {0}", homeblock.rootBlock).AppendLine();
            sb.AppendFormat("Volume owner is \"{0}\"", Encoding.GetString(homeblock.ownername).TrimEnd()).AppendLine();
            sb.AppendFormat("Volume label: \"{0}\"", Encoding.GetString(homeblock.volname).TrimEnd()).AppendLine();
            sb.AppendFormat("Checksum: 0x{0:X4} (calculated 0x{1:X4})", homeblock.checksum, check).AppendLine();

            byte[] bootBlock = imagePlugin.ReadSector(0);

            XmlFsType = new FileSystemType
            {
                Type        = "RT-11",
                ClusterSize = homeblock.cluster * 512,
                Clusters    = homeblock.cluster,
                VolumeName  = StringHandlers.SpacePaddedToString(homeblock.volname, Encoding),
                Bootable    = !ArrayHelpers.ArrayIsNullOrEmpty(bootBlock)
            };

            information = sb.ToString();
        }
Beispiel #8
0
        public bool WriteSector(byte[] data, ulong sectorAddress)
        {
            if (!IsWriting)
            {
                ErrorMessage = "Tried to write on a non-writable image";

                return(false);
            }

            if (data.Length != _imageInfo.SectorSize)
            {
                ErrorMessage = "Incorrect data size";

                return(false);
            }

            if (sectorAddress >= _imageInfo.Sectors)
            {
                ErrorMessage = "Tried to write past image size";

                return(false);
            }

            // Ignore empty sectors
            if (ArrayHelpers.ArrayIsNullOrEmpty(data))
            {
                return(true);
            }

            ulong index  = sectorAddress * _vHdr.sectorSize / _vHdr.blockSize;
            ulong secOff = sectorAddress * _vHdr.sectorSize % _vHdr.blockSize;

            uint ibmOff = _ibm[index];

            if (ibmOff == VDI_EMPTY)
            {
                ibmOff                   = (_currentWritingPosition - _vHdr.offsetData) / _vHdr.blockSize;
                _ibm[index]              = ibmOff;
                _currentWritingPosition += _vHdr.blockSize;
                _vHdr.allocatedBlocks++;
            }

            ulong imageOff = _vHdr.offsetData + (ibmOff * _vHdr.blockSize);

            _writingStream.Seek((long)imageOff, SeekOrigin.Begin);
            _writingStream.Seek((long)secOff, SeekOrigin.Current);
            _writingStream.Write(data, 0, data.Length);

            ErrorMessage = "";

            return(true);
        }
Beispiel #9
0
        public bool WriteSector(byte[] data, ulong sectorAddress)
        {
            if (!IsWriting)
            {
                ErrorMessage = "Tried to write on a non-writable image";

                return(false);
            }

            if (data.Length != 512)
            {
                ErrorMessage = "Incorrect data size";

                return(false);
            }

            if (sectorAddress >= imageInfo.Sectors)
            {
                ErrorMessage = "Tried to write past image size";

                return(false);
            }

            // Ignore empty sectors
            if (ArrayHelpers.ArrayIsNullOrEmpty(data))
            {
                return(true);
            }

            ulong index  = sectorAddress / pHdr.cluster_size;
            ulong secOff = sectorAddress % pHdr.cluster_size;

            uint batOff = bat[index];

            if (batOff == 0)
            {
                batOff                  = (uint)(currentWritingPosition / 512);
                bat[index]              = batOff;
                currentWritingPosition += pHdr.cluster_size * 512;
            }

            ulong imageOff = batOff * 512;

            writingStream.Seek((long)imageOff, SeekOrigin.Begin);
            writingStream.Seek((long)secOff * 512, SeekOrigin.Current);
            writingStream.Write(data, 0, data.Length);

            ErrorMessage = "";

            return(true);
        }
Beispiel #10
0
        // TODO: This can be optimized
        public bool WriteSectors(byte[] data, ulong sectorAddress, uint length)
        {
            if (!IsWriting)
            {
                ErrorMessage = "Tried to write on a non-writable image";

                return(false);
            }

            if (data.Length % _imageInfo.SectorSize != 0)
            {
                ErrorMessage = "Incorrect data size";

                return(false);
            }

            if (sectorAddress + length > _imageInfo.Sectors)
            {
                ErrorMessage = "Tried to write past image size";

                return(false);
            }

            // Ignore empty sectors
            if (ArrayHelpers.ArrayIsNullOrEmpty(data))
            {
                return(true);
            }

            for (uint i = 0; i < length; i++)
            {
                byte[] tmp = new byte[_imageInfo.SectorSize];
                Array.Copy(data, i * _imageInfo.SectorSize, tmp, 0, _imageInfo.SectorSize);

                if (!WriteSector(tmp, sectorAddress + i))
                {
                    return(false);
                }
            }

            ErrorMessage = "";

            return(true);
        }
Beispiel #11
0
        // TODO: Find root directory on volumes with DiscRecord
        // TODO: Support big directories (ADFS-G?)
        // TODO: Find the real freemap on volumes with DiscRecord, as DiscRecord's discid may be empty but this one isn't
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1");
            StringBuilder sbInformation = new StringBuilder();

            XmlFsType   = new FileSystemType();
            information = "";

            ulong sbSector;

            byte[]   sector;
            uint     sectorsToRead;
            GCHandle ptr;
            ulong    bytes;

            // ADFS-S, ADFS-M, ADFS-L, ADFS-D without partitions
            if (partition.Start == 0)
            {
                sector = imagePlugin.ReadSector(0);
                byte oldChk0 = AcornMapChecksum(sector, 255);
                ptr = GCHandle.Alloc(sector, GCHandleType.Pinned);
                OldMapSector0 oldMap0 =
                    (OldMapSector0)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldMapSector0));

                sector = imagePlugin.ReadSector(1);
                byte oldChk1 = AcornMapChecksum(sector, 255);
                ptr = GCHandle.Alloc(sector, GCHandleType.Pinned);
                OldMapSector1 oldMap1 =
                    (OldMapSector1)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldMapSector1));

                // According to documentation map1 MUST start on sector 1. On ADFS-D it starts at 0x100, not on sector 1 (0x400)
                if (oldMap0.checksum == oldChk0 && oldMap1.checksum != oldChk1 && sector.Length >= 512)
                {
                    sector = imagePlugin.ReadSector(0);
                    byte[] tmp = new byte[256];
                    Array.Copy(sector, 256, tmp, 0, 256);
                    oldChk1 = AcornMapChecksum(tmp, 255);
                    ptr     = GCHandle.Alloc(tmp, GCHandleType.Pinned);
                    oldMap1 = (OldMapSector1)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldMapSector1));
                }

                if (oldMap0.checksum == oldChk0 && oldMap1.checksum == oldChk1 && oldMap0.checksum != 0 &&
                    oldMap1.checksum != 0)
                {
                    bytes = (ulong)((oldMap0.size[2] << 16) + (oldMap0.size[1] << 8) + oldMap0.size[0]) * 256;
                    byte[] namebytes = new byte[10];
                    for (int i = 0; i < 5; i++)
                    {
                        namebytes[i * 2]     = oldMap0.name[i];
                        namebytes[i * 2 + 1] = oldMap1.name[i];
                    }

                    XmlFsType = new FileSystemType
                    {
                        Bootable    = oldMap1.boot != 0, // Or not?
                        Clusters    = (long)(bytes / imagePlugin.Info.SectorSize),
                        ClusterSize = (int)imagePlugin.Info.SectorSize,
                        Type        = "Acorn Advanced Disc Filing System"
                    };

                    if (ArrayHelpers.ArrayIsNullOrEmpty(namebytes))
                    {
                        sbSector      = OLD_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize;
                        sectorsToRead = OLD_DIRECTORY_SIZE / imagePlugin.Info.SectorSize;
                        if (OLD_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0)
                        {
                            sectorsToRead++;
                        }

                        sector = imagePlugin.ReadSectors(sbSector, sectorsToRead);
                        if (sector.Length > OLD_DIRECTORY_SIZE)
                        {
                            byte[] tmp = new byte[OLD_DIRECTORY_SIZE];
                            Array.Copy(sector, 0, tmp, 0, OLD_DIRECTORY_SIZE - 53);
                            Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54, 53);
                            sector = tmp;
                        }
                        ptr = GCHandle.Alloc(sector, GCHandleType.Pinned);
                        OldDirectory oldRoot =
                            (OldDirectory)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldDirectory));

                        if (oldRoot.header.magic == OLD_DIR_MAGIC && oldRoot.tail.magic == OLD_DIR_MAGIC)
                        {
                            namebytes = oldRoot.tail.name;
                        }
                        else
                        {
                            // RISC OS says the old directory can't be in the new location, hard disks created by RISC OS 3.10 do that...
                            sbSector      = NEW_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize;
                            sectorsToRead = NEW_DIRECTORY_SIZE / imagePlugin.Info.SectorSize;
                            if (NEW_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0)
                            {
                                sectorsToRead++;
                            }

                            sector = imagePlugin.ReadSectors(sbSector, sectorsToRead);
                            if (sector.Length > OLD_DIRECTORY_SIZE)
                            {
                                byte[] tmp = new byte[OLD_DIRECTORY_SIZE];
                                Array.Copy(sector, 0, tmp, 0, OLD_DIRECTORY_SIZE - 53);
                                Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54, 53);
                                sector = tmp;
                            }
                            ptr     = GCHandle.Alloc(sector, GCHandleType.Pinned);
                            oldRoot = (OldDirectory)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(),
                                                                           typeof(OldDirectory));

                            if (oldRoot.header.magic == OLD_DIR_MAGIC && oldRoot.tail.magic == OLD_DIR_MAGIC)
                            {
                                namebytes = oldRoot.tail.name;
                            }
                            else
                            {
                                sector = imagePlugin.ReadSectors(sbSector, sectorsToRead);
                                if (sector.Length > NEW_DIRECTORY_SIZE)
                                {
                                    byte[] tmp = new byte[NEW_DIRECTORY_SIZE];
                                    Array.Copy(sector, 0, tmp, 0, NEW_DIRECTORY_SIZE - 41);
                                    Array.Copy(sector, sector.Length - 42, tmp, NEW_DIRECTORY_SIZE - 42, 41);
                                    sector = tmp;
                                }
                                ptr = GCHandle.Alloc(sector, GCHandleType.Pinned);
                                NewDirectory newRoot =
                                    (NewDirectory)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(),
                                                                         typeof(NewDirectory));
                                if (newRoot.header.magic == NEW_DIR_MAGIC && newRoot.tail.magic == NEW_DIR_MAGIC)
                                {
                                    namebytes = newRoot.tail.title;
                                }
                            }
                        }
                    }

                    sbInformation.AppendLine("Acorn Advanced Disc Filing System");
                    sbInformation.AppendLine();
                    sbInformation.AppendFormat("{0} bytes per sector", imagePlugin.Info.SectorSize).AppendLine();
                    sbInformation.AppendFormat("Volume has {0} bytes", bytes).AppendLine();
                    sbInformation.AppendFormat("Volume name: {0}", StringHandlers.CToString(namebytes, Encoding))
                    .AppendLine();
                    if (oldMap1.discId > 0)
                    {
                        XmlFsType.VolumeSerial = $"{oldMap1.discId:X4}";
                        sbInformation.AppendFormat("Volume ID: {0:X4}", oldMap1.discId).AppendLine();
                    }
                    if (!ArrayHelpers.ArrayIsNullOrEmpty(namebytes))
                    {
                        XmlFsType.VolumeName = StringHandlers.CToString(namebytes, Encoding);
                    }

                    information = sbInformation.ToString();

                    return;
                }
            }

            // Partitioning or not, new formats follow:
            DiscRecord drSb;

            sector = imagePlugin.ReadSector(partition.Start);
            byte newChk = NewMapChecksum(sector);

            DicConsole.DebugWriteLine("ADFS Plugin", "newChk = {0}", newChk);
            DicConsole.DebugWriteLine("ADFS Plugin", "map.zoneChecksum = {0}", sector[0]);

            sbSector      = BOOT_BLOCK_LOCATION / imagePlugin.Info.SectorSize;
            sectorsToRead = BOOT_BLOCK_SIZE / imagePlugin.Info.SectorSize;
            if (BOOT_BLOCK_SIZE % imagePlugin.Info.SectorSize > 0)
            {
                sectorsToRead++;
            }

            byte[] bootSector = imagePlugin.ReadSectors(sbSector + partition.Start, sectorsToRead);
            int    bootChk    = 0;

            for (int i = 0; i < 0x1FF; i++)
            {
                bootChk = (bootChk & 0xFF) + (bootChk >> 8) + bootSector[i];
            }

            DicConsole.DebugWriteLine("ADFS Plugin", "bootChk = {0}", bootChk);
            DicConsole.DebugWriteLine("ADFS Plugin", "bBlock.checksum = {0}", bootSector[0x1FF]);

            if (newChk == sector[0] && newChk != 0)
            {
                ptr = GCHandle.Alloc(sector, GCHandleType.Pinned);
                NewMap nmap = (NewMap)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(NewMap));
                ptr.Free();
                drSb = nmap.discRecord;
            }
            else if (bootChk == bootSector[0x1FF])
            {
                ptr = GCHandle.Alloc(bootSector, GCHandleType.Pinned);
                BootBlock bBlock = (BootBlock)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(BootBlock));
                ptr.Free();
                drSb = bBlock.discRecord;
            }
            else
            {
                return;
            }

            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.log2secsize = {0}", drSb.log2secsize);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.spt = {0}", drSb.spt);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.heads = {0}", drSb.heads);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.density = {0}", drSb.density);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.idlen = {0}", drSb.idlen);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.log2bpmb = {0}", drSb.log2bpmb);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.skew = {0}", drSb.skew);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.bootoption = {0}", drSb.bootoption);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.lowsector = {0}", drSb.lowsector);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.nzones = {0}", drSb.nzones);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.zone_spare = {0}", drSb.zone_spare);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.root = {0}", drSb.root);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_size = {0}", drSb.disc_size);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_id = {0}", drSb.disc_id);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_name = {0}",
                                      StringHandlers.CToString(drSb.disc_name, Encoding));
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_type = {0}", drSb.disc_type);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_size_high = {0}", drSb.disc_size_high);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.flags = {0}", drSb.flags);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.nzones_high = {0}", drSb.nzones_high);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.format_version = {0}", drSb.format_version);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.root_size = {0}", drSb.root_size);

            if (drSb.log2secsize < 8 || drSb.log2secsize > 10)
            {
                return;
            }

            if (drSb.idlen < drSb.log2secsize + 3 || drSb.idlen > 19)
            {
                return;
            }

            if (drSb.disc_size_high >> drSb.log2secsize != 0)
            {
                return;
            }

            if (!ArrayHelpers.ArrayIsNullOrEmpty(drSb.reserved))
            {
                return;
            }

            bytes  = drSb.disc_size_high;
            bytes *= 0x100000000;
            bytes += drSb.disc_size;

            ulong zones = drSb.nzones_high;

            zones *= 0x100000000;
            zones += drSb.nzones;

            if (bytes > imagePlugin.Info.Sectors * imagePlugin.Info.SectorSize)
            {
                return;
            }

            XmlFsType = new FileSystemType();

            sbInformation.AppendLine("Acorn Advanced Disc Filing System");
            sbInformation.AppendLine();
            sbInformation.AppendFormat("Version {0}", drSb.format_version).AppendLine();
            sbInformation.AppendFormat("{0} bytes per sector", 1 << drSb.log2secsize).AppendLine();
            sbInformation.AppendFormat("{0} sectors per track", drSb.spt).AppendLine();
            sbInformation.AppendFormat("{0} heads", drSb.heads).AppendLine();
            sbInformation.AppendFormat("Density code: {0}", drSb.density).AppendLine();
            sbInformation.AppendFormat("Skew: {0}", drSb.skew).AppendLine();
            sbInformation.AppendFormat("Boot option: {0}", drSb.bootoption).AppendLine();
            // TODO: What the hell is this field refering to?
            sbInformation.AppendFormat("Root starts at frag {0}", drSb.root).AppendLine();
            //sbInformation.AppendFormat("Root is {0} bytes long", drSb.root_size).AppendLine();
            sbInformation.AppendFormat("Volume has {0} bytes in {1} zones", bytes, zones).AppendLine();
            sbInformation.AppendFormat("Volume flags: 0x{0:X4}", drSb.flags).AppendLine();
            if (drSb.disc_id > 0)
            {
                XmlFsType.VolumeSerial = $"{drSb.disc_id:X4}";
                sbInformation.AppendFormat("Volume ID: {0:X4}", drSb.disc_id).AppendLine();
            }
            if (!ArrayHelpers.ArrayIsNullOrEmpty(drSb.disc_name))
            {
                string discname = StringHandlers.CToString(drSb.disc_name, Encoding);
                XmlFsType.VolumeName = discname;
                sbInformation.AppendFormat("Volume name: {0}", discname).AppendLine();
            }

            information = sbInformation.ToString();

            XmlFsType.Bootable   |= drSb.bootoption != 0; // Or not?
            XmlFsType.Clusters    = (long)(bytes / (ulong)(1 << drSb.log2secsize));
            XmlFsType.ClusterSize = 1 << drSb.log2secsize;
            XmlFsType.Type        = "Acorn Advanced Disc Filing System";
        }
Beispiel #12
0
        static void ReadBufferDma(string devPath, Device dev)
        {
start:
            System.Console.Clear();

            bool sense = dev.ReadBufferDma(out byte[] buffer, out AtaErrorRegistersLba28 errorRegisters, dev.Timeout,
                                           out double duration);

menu:
            AaruConsole.WriteLine("Device: {0}", devPath);
            AaruConsole.WriteLine("Sending READ BUFFER DMA to the device:");
            AaruConsole.WriteLine("Command took {0} ms.", duration);
            AaruConsole.WriteLine("Sense is {0}.", sense);
            AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null");
            AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer));
            AaruConsole.WriteLine();
            AaruConsole.WriteLine("Choose what to do:");
            AaruConsole.WriteLine("1.- Print buffer.");
            AaruConsole.WriteLine("2.- Decode error registers.");
            AaruConsole.WriteLine("3.- Send command again.");
            AaruConsole.WriteLine("0.- Return to 28-bit ATA commands menu.");
            AaruConsole.Write("Choose: ");

            string strDev = System.Console.ReadLine();

            if (!int.TryParse(strDev, out int item))
            {
                AaruConsole.WriteLine("Not a number. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }

            switch (item)
            {
            case 0:
                AaruConsole.WriteLine("Returning to 28-bit ATA commands menu...");

                return;

            case 1:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("READ BUFFER DMA response:");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(buffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 2:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("READ BUFFER DMA status registers:");
                AaruConsole.Write("{0}", MainClass.DecodeAtaRegisters(errorRegisters));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 3: goto start;

            default:
                AaruConsole.WriteLine("Incorrect option. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }
        }
Beispiel #13
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = Encoding.UTF8;
            information = "";

            uint sbSize = (uint)(Marshal.SizeOf <RefsVolumeHeader>() / imagePlugin.Info.SectorSize);

            if (Marshal.SizeOf <RefsVolumeHeader>() % imagePlugin.Info.SectorSize != 0)
            {
                sbSize++;
            }

            if (partition.Start + sbSize >= partition.End)
            {
                return;
            }

            byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize);

            if (sector.Length < Marshal.SizeOf <RefsVolumeHeader>())
            {
                return;
            }

            RefsVolumeHeader refsVhdr = Marshal.ByteArrayToStructureLittleEndian <RefsVolumeHeader>(sector);

            AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.jump empty? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(refsVhdr.jump));

            AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.signature = {0}",
                                       StringHandlers.CToString(refsVhdr.signature));

            AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.mustBeZero empty? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(refsVhdr.mustBeZero));

            AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.identifier = {0}",
                                       StringHandlers.CToString(BitConverter.GetBytes(refsVhdr.identifier)));

            AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.length = {0}", refsVhdr.length);
            AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.checksum = 0x{0:X4}", refsVhdr.checksum);
            AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.sectors = {0}", refsVhdr.sectors);
            AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.bytesPerSector = {0}", refsVhdr.bytesPerSector);

            AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.sectorsPerCluster = {0}",
                                       refsVhdr.sectorsPerCluster);

            AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.unknown1 zero? = {0}", refsVhdr.unknown1 == 0);
            AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.unknown2 zero? = {0}", refsVhdr.unknown2 == 0);
            AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.unknown3 zero? = {0}", refsVhdr.unknown3 == 0);
            AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.unknown4 zero? = {0}", refsVhdr.unknown4 == 0);

            AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.unknown5 empty? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(refsVhdr.unknown5));

            if (refsVhdr.identifier != FSRS ||
                !ArrayHelpers.ArrayIsNullOrEmpty(refsVhdr.mustBeZero) ||
                !refsVhdr.signature.SequenceEqual(refsSignature))
            {
                return;
            }

            var sb = new StringBuilder();

            sb.AppendLine("Microsoft Resilient File System");
            sb.AppendFormat("Volume uses {0} bytes per sector", refsVhdr.bytesPerSector).AppendLine();

            sb.AppendFormat("Volume uses {0} sectors per cluster ({1} bytes)", refsVhdr.sectorsPerCluster,
                            refsVhdr.sectorsPerCluster * refsVhdr.bytesPerSector).AppendLine();

            sb.AppendFormat("Volume has {0} sectors ({1} bytes)", refsVhdr.sectors,
                            refsVhdr.sectors * refsVhdr.bytesPerSector).AppendLine();

            information = sb.ToString();

            XmlFsType = new FileSystemType
            {
                Type     = "Resilient File System", ClusterSize = refsVhdr.bytesPerSector * refsVhdr.sectorsPerCluster,
                Clusters = refsVhdr.sectors / refsVhdr.sectorsPerCluster
            };
        }
Beispiel #14
0
        static void ReadCdDa(string devPath, Device dev)
        {
            uint   address = 0;
            uint   length  = 1;
            string strDev;
            int    item;

parameters:

            while (true)
            {
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("Parameters for READ CD-DA command:");
                AaruConsole.WriteLine("LBA: {0}", address);
                AaruConsole.WriteLine("Will transfer {0} sectors", length);
                AaruConsole.WriteLine();
                AaruConsole.WriteLine("Choose what to do:");
                AaruConsole.WriteLine("1.- Change parameters.");
                AaruConsole.WriteLine("2.- Send command with these parameters.");
                AaruConsole.WriteLine("0.- Return to NEC vendor commands menu.");

                strDev = System.Console.ReadLine();

                if (!int.TryParse(strDev, out item))
                {
                    AaruConsole.WriteLine("Not a number. Press any key to continue...");
                    System.Console.ReadKey();

                    continue;
                }

                switch (item)
                {
                case 0:
                    AaruConsole.WriteLine("Returning to NEC vendor commands menu...");

                    return;

                case 1:
                    AaruConsole.Write("Logical Block Address?: ");
                    strDev = System.Console.ReadLine();

                    if (!uint.TryParse(strDev, out address))
                    {
                        AaruConsole.WriteLine("Not a number. Press any key to continue...");
                        address = 0;
                        System.Console.ReadKey();

                        continue;
                    }

                    AaruConsole.Write("How many sectors to transfer?: ");
                    strDev = System.Console.ReadLine();

                    if (!uint.TryParse(strDev, out length))
                    {
                        AaruConsole.WriteLine("Not a number. Press any key to continue...");
                        length = 1;
                        System.Console.ReadKey();
                    }

                    break;

                case 2: goto start;
                }
            }

start:
            System.Console.Clear();

            bool sense = dev.NecReadCdDa(out byte[] buffer, out byte[] senseBuffer, address, length, dev.Timeout,
                                         out double duration);

menu:
            AaruConsole.WriteLine("Device: {0}", devPath);
            AaruConsole.WriteLine("Sending READ CD-DA to the device:");
            AaruConsole.WriteLine("Command took {0} ms.", duration);
            AaruConsole.WriteLine("Sense is {0}.", sense);
            AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null");
            AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer));
            AaruConsole.WriteLine("Sense buffer is {0} bytes.", senseBuffer?.Length.ToString() ?? "null");
            AaruConsole.WriteLine("Sense buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(senseBuffer));
            AaruConsole.WriteLine();
            AaruConsole.WriteLine("Choose what to do:");
            AaruConsole.WriteLine("1.- Print buffer.");
            AaruConsole.WriteLine("2.- Print sense buffer.");
            AaruConsole.WriteLine("3.- Decode sense buffer.");
            AaruConsole.WriteLine("4.- Send command again.");
            AaruConsole.WriteLine("5.- Change parameters.");
            AaruConsole.WriteLine("0.- Return to NEC vendor commands menu.");
            AaruConsole.Write("Choose: ");

            strDev = System.Console.ReadLine();

            if (!int.TryParse(strDev, out item))
            {
                AaruConsole.WriteLine("Not a number. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }

            switch (item)
            {
            case 0:
                AaruConsole.WriteLine("Returning to NEC vendor commands menu...");

                return;

            case 1:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("READ CD-DA response:");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(buffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 2:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("READ CD-DA sense:");

                if (senseBuffer != null)
                {
                    PrintHex.PrintHexArray(senseBuffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 3:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("READ CD-DA decoded sense:");
                AaruConsole.Write("{0}", Sense.PrettifySense(senseBuffer));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 4: goto start;

            case 5: goto parameters;

            default:
                AaruConsole.WriteLine("Incorrect option. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }
        }
Beispiel #15
0
        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);
        }
Beispiel #16
0
        static void Unlock(string devPath, Device dev)
        {
start:
            System.Console.Clear();
            bool sense = dev.KreonDeprecatedUnlock(out byte[] senseBuffer, dev.Timeout, out double duration);

menu:
            DicConsole.WriteLine("Device: {0}", devPath);
            DicConsole.WriteLine("Sending UNLOCK to the device:");
            DicConsole.WriteLine("Command took {0} ms.", duration);
            DicConsole.WriteLine("Sense is {0}.", sense);
            DicConsole.WriteLine("Sense buffer is {0} bytes.", senseBuffer?.Length.ToString() ?? "null");
            DicConsole.WriteLine("Sense buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(senseBuffer));
            DicConsole.WriteLine("UNLOCK decoded sense:");
            DicConsole.Write("{0}", Sense.PrettifySense(senseBuffer));
            DicConsole.WriteLine();
            DicConsole.WriteLine("Choose what to do:");
            DicConsole.WriteLine("1.- Print sense buffer.");
            DicConsole.WriteLine("2.- Send command again.");
            DicConsole.WriteLine("0.- Return to Kreon vendor commands menu.");
            DicConsole.Write("Choose: ");

            string strDev = System.Console.ReadLine();

            if (!int.TryParse(strDev, out int item))
            {
                DicConsole.WriteLine("Not a number. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                goto menu;
            }

            switch (item)
            {
            case 0:
                DicConsole.WriteLine("Returning to Kreon vendor commands menu...");
                return;

            case 1:
                System.Console.Clear();
                DicConsole.WriteLine("Device: {0}", devPath);
                DicConsole.WriteLine("UNLOCK sense:");
                if (senseBuffer != null)
                {
                    PrintHex.PrintHexArray(senseBuffer, 64);
                }
                DicConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                DicConsole.WriteLine("Device: {0}", devPath);
                goto menu;

            case 2: goto start;

            default:
                DicConsole.WriteLine("Incorrect option. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                goto menu;
            }
        }
Beispiel #17
0
        public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset)
        {
            partitions = new List <Partition>();

            // I think Apricot can't chain partitions so.
            if (sectorOffset != 0)
            {
                return(false);
            }

            byte[] sector = imagePlugin.ReadSector(0);

            if (sector.Length < 512)
            {
                return(false);
            }

            Label label = Marshal.ByteArrayToStructureLittleEndian <Label>(sector);

            // Not much to check but...
            ulong deviceSectors = imagePlugin.Info.Sectors;
            ulong deviceSizeAccordingToLabel = label.cylinders * label.heads * label.spt;

            if (label.operatingSystem > 4 ||
                label.bootType > 5 ||
                label.partitionCount > 8 ||
                deviceSizeAccordingToLabel > deviceSectors ||
                label.firstDataBlock > deviceSectors)
            {
                return(false);
            }

            AaruConsole.DebugWriteLine("Apricot partitions", "label.version = \"{0}\"",
                                       StringHandlers.CToString(label.version));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.operatingSystem = {0} ({1})", label.operatingSystem,
                                       label.operatingSystem < _operatingSystemCodes.Length
                                           ? _operatingSystemCodes[label.operatingSystem] : "Unknown");

            AaruConsole.DebugWriteLine("Apricot partitions", "label.writeProtected = {0}", label.writeProtected);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.copyProtected = {0}", label.copyProtected);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.bootType = {0} ({1})", label.bootType,
                                       label.bootType < _bootTypeCodes.Length ? _bootTypeCodes[label.bootType]
                                           : "Unknown");

            AaruConsole.DebugWriteLine("Apricot partitions", "label.partitionCount = {0}", label.partitionCount);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.winchester = {0}", label.winchester);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.sectorSize = {0}", label.sectorSize);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.spt = {0}", label.spt);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.cylinders = {0}", label.cylinders);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.heads = {0}", label.heads);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.interleave = {0}", label.interleave);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.skew = {0}", label.skew);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.bootLocation = {0}", label.bootLocation);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.bootSize = {0}", label.bootSize);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.bootAddress = 0x{0:X8}", label.bootAddress);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.bootOffset:label.bootSegment = {0:X4}:{1:X4}",
                                       label.bootOffset, label.bootSegment);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.firstDataBlock = {0}", label.firstDataBlock);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.generation = {0}", label.generation);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.copyCount = {0}", label.copyCount);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.maxCopies = {0}", label.maxCopies);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.serialNumber = \"{0}\"",
                                       StringHandlers.CToString(label.serialNumber));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.partNumber = \"{0}\"",
                                       StringHandlers.CToString(label.partNumber));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.copyright = \"{0}\"",
                                       StringHandlers.CToString(label.copyright));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.bps = {0}", label.mainBPB.bps);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.spc = {0}", label.mainBPB.spc);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.rsectors = {0}", label.mainBPB.rsectors);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.fats_no = {0}", label.mainBPB.fats_no);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.root_ent = {0}", label.mainBPB.root_ent);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.sectors = {0}", label.mainBPB.sectors);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.media = {0}", label.mainBPB.media);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.spfat = {0}", label.mainBPB.spfat);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.diskType = {0} ({1})",
                                       label.mainBPB.diskType,
                                       label.mainBPB.diskType < _diskTypeCodes.Length
                                           ? _diskTypeCodes[label.mainBPB.diskType] : "Unknown");

            AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.startSector = {0}",
                                       label.mainBPB.startSector);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.fontName = \"{0}\"",
                                       StringHandlers.CToString(label.fontName));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardName = \"{0}\"",
                                       StringHandlers.CToString(label.keyboardName));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.biosMajorVersion = {0}", label.biosMajorVersion);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.biosMinorVersion = {0}", label.biosMinorVersion);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.diagnosticsFlag = {0}", label.diagnosticsFlag);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.prnDevice = {0} ({1})", label.prnDevice,
                                       label.prnDevice < _printDevices.Length ? _printDevices[label.prnDevice]
                                           : "Unknown");

            AaruConsole.DebugWriteLine("Apricot partitions", "label.bellVolume = {0}", label.bellVolume);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.enableCache = {0}", label.enableCache);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.enableGraphics = {0}", label.enableGraphics);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.dosLength = {0}", label.dosLength);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.fontLength = {0}", label.fontLength);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardLength = {0}", label.keyboardLength);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.dosStart = {0}", label.dosStart);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.fontStart = {0}", label.fontStart);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardStart = {0}", label.keyboardStart);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardVolume = {0}", label.keyboardVolume);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.autorepeat = {0}", label.autorepeat);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.autorepeatLeadIn = {0}", label.autorepeatLeadIn);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.autorepeatInterval = {0}",
                                       label.autorepeatInterval);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.microscreenMode = {0}", label.microscreenMode);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.spareKeyboard is null? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(label.spareKeyboard));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.lineMode = {0} ({1} lines)", label.lineMode,
                                       label.lineMode < _lineModes.Length ? _lineModes[label.lineMode] : 0);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.lineWidth = {0} ({1} columns)", label.lineWidth,
                                       label.lineWidth < _lineWidths.Length ? _lineWidths[label.lineWidth] : 0);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.imageOff = {0}", label.imageOff);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.spareScreen is null? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(label.spareScreen));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.txBaudRate = {0} ({1} bps)", label.txBaudRate,
                                       label.txBaudRate < _baudRates.Length ? _baudRates[label.txBaudRate] : 0);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.rxBaudRate = {0} ({1} bps)", label.rxBaudRate,
                                       label.rxBaudRate < _baudRates.Length ? _baudRates[label.rxBaudRate] : 0);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.txBits = {0}", label.txBits);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.rxBits = {0}", label.rxBits);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.stopBits = {0} ({1} bits)", label.stopBits,
                                       label.stopBits < _stopBits.Length ? _stopBits[label.stopBits] : 0);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.parityCheck = {0}", label.parityCheck);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.parityType = {0} ({1})", label.parityType,
                                       label.parityType < _parityTypes.Length ? _parityTypes[label.parityType]
                                           : "Unknown");

            AaruConsole.DebugWriteLine("Apricot partitions", "label.txXonXoff = {0}", label.txXonXoff);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.rxXonXoff = {0}", label.rxXonXoff);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.xonCharacter = {0}", label.xonCharacter);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.xoffCharacter = {0}", label.xoffCharacter);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.rxXonXoffBuffer = {0}", label.rxXonXoffBuffer);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.dtrDsr = {0}", label.dtrDsr);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.ctsRts = {0}", label.ctsRts);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.nullsAfterCr = {0}", label.nullsAfterCr);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.nullsAfterFF = {0}", label.nullsAfterFF);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.lfAfterCRSerial = {0}", label.lfAfterCRSerial);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.biosErrorReportSerial = {0}",
                                       label.biosErrorReportSerial);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.spareSerial is null? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(label.spareSerial));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.lfAfterCrParallel = {0}", label.lfAfterCrParallel);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.selectLine = {0}", label.selectLine);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.paperEmpty = {0}", label.paperEmpty);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.faultLine = {0}", label.faultLine);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.biosErrorReportParallel = {0}",
                                       label.biosErrorReportParallel);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.spareParallel is null? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(label.spareParallel));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.spareWinchester is null? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(label.spareWinchester));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.parkingEnabled = {0}", label.parkingEnabled);
            AaruConsole.DebugWriteLine("Apricot partitions", "label.formatProtection = {0}", label.formatProtection);

            AaruConsole.DebugWriteLine("Apricot partitions", "label.spareRamDisk is null? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(label.spareRamDisk));

            for (int i = 0; i < 32; i++)
            {
                AaruConsole.DebugWriteLine("Apricot partitions", "label.badBlocks[{1}] = {0}", label.badBlocks[i], i);
            }

            for (int i = 0; i < 8; i++)
            {
                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].bps = {0}",
                                           label.partitions[i].bps, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].spc = {0}",
                                           label.partitions[i].spc, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].rsectors = {0}",
                                           label.partitions[i].rsectors, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].fats_no = {0}",
                                           label.partitions[i].fats_no, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].root_ent = {0}",
                                           label.partitions[i].root_ent, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].sectors = {0}",
                                           label.partitions[i].sectors, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].media = {0}",
                                           label.partitions[i].media, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].spfat = {0}",
                                           label.partitions[i].spfat, i);

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].diskType = {0} ({2})",
                                           label.partitions[i].diskType, i,
                                           label.partitions[i].diskType < _diskTypeCodes.Length
                                               ? _diskTypeCodes[label.partitions[i].diskType] : "Unknown");

                AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].startSector = {0}",
                                           label.partitions[i].startSector, i);
            }

            AaruConsole.DebugWriteLine("Apricot partitions", "label.spare is null? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(label.spare));

            AaruConsole.DebugWriteLine("Apricot partitions", "label.cpmDoubleSided = {0}", label.cpmDoubleSided);

            // Only hard disks can contain partitions
            if (!label.winchester)
            {
                return(false);
            }

            for (byte i = 0; i < label.partitionCount; i++)
            {
                var part = new Partition
                {
                    Start    = label.partitions[i].startSector,
                    Size     = (ulong)(label.partitions[i].sectors * label.sectorSize),
                    Length   = label.partitions[i].sectors,
                    Type     = "ACT Apricot partition",
                    Sequence = i,
                    Scheme   = Name,
                    Offset   = (ulong)(label.partitions[i].startSector * label.sectorSize)
                };

                if (part.Start < deviceSectors &&
                    part.End < deviceSectors)
                {
                    partitions.Add(part);
                }
            }

            return(partitions.Count > 0);
        }
Beispiel #18
0
        /// <summary>
        ///     Lists special Apple Lisa filesystem features as extended attributes
        /// </summary>
        /// <returns>Error number.</returns>
        /// <param name="fileId">File identifier.</param>
        /// <param name="xattrs">Extended attributes.</param>
        Errno ListXAttr(short fileId, out List <string> xattrs)
        {
            xattrs = null;

            if (!mounted)
            {
                return(Errno.AccessDenied);
            }

            // System files
            if (fileId < 4)
            {
                if (!debug || fileId == 0)
                {
                    return(Errno.InvalidArgument);
                }

                xattrs = new List <string>();

                // Only MDDF contains an extended attributes
                if (fileId == FILEID_MDDF)
                {
                    byte[] buf = Encoding.ASCII.GetBytes(mddf.password);

                    // If the MDDF contains a password, show it
                    if (buf.Length > 0)
                    {
                        xattrs.Add("com.apple.lisa.password");
                    }
                }
            }
            else
            {
                // Search for the file
                Errno error = ReadExtentsFile(fileId, out ExtentFile file);

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

                xattrs = new List <string>();

                // Password field is never emptied, check if valid
                if (file.password_valid > 0)
                {
                    xattrs.Add("com.apple.lisa.password");
                }

                // Check for a valid copy-protection serial number
                if (file.serial > 0)
                {
                    xattrs.Add("com.apple.lisa.serial");
                }

                // Check if the label contains something or is empty
                if (!ArrayHelpers.ArrayIsNullOrEmpty(file.LisaInfo))
                {
                    xattrs.Add("com.apple.lisa.label");
                }
            }

            // On debug mode allow sector tags to be accessed as an xattr
            if (debug)
            {
                xattrs.Add("com.apple.lisa.tags");
            }

            xattrs.Sort();

            return(Errno.NoError);
        }
Beispiel #19
0
        public Errno ListXAttr(string path, out List <string> xattrs)
        {
            xattrs = null;
            if (!mounted)
            {
                return(Errno.AccessDenied);
            }

            string[] pathElements = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            if (pathElements.Length != 1)
            {
                return(Errno.NotSupported);
            }

            path = pathElements[0];

            xattrs = new List <string>();

            if (debug)
            {
                if (string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
                    string.Compare(path, "$Bitmap", StringComparison.InvariantCulture) == 0 ||
                    string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 ||
                    string.Compare(path, "$MDB", StringComparison.InvariantCulture) == 0)
                {
                    if (device.Info.ReadableSectorTags.Contains(SectorTagType.AppleSectorTag))
                    {
                        xattrs.Add("com.apple.macintosh.tags");
                    }

                    return(Errno.NoError);
                }
            }

            if (!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId))
            {
                return(Errno.NoSuchFile);
            }

            if (!idToEntry.TryGetValue(fileId, out MFS_FileEntry entry))
            {
                return(Errno.NoSuchFile);
            }

            if (entry.flRLgLen > 0)
            {
                xattrs.Add("com.apple.ResourceFork");
                if (debug && device.Info.ReadableSectorTags.Contains(SectorTagType.AppleSectorTag))
                {
                    xattrs.Add("com.apple.ResourceFork.tags");
                }
            }

            if (!ArrayHelpers.ArrayIsNullOrEmpty(entry.flUsrWds))
            {
                xattrs.Add("com.apple.FinderInfo");
            }

            if (debug && device.Info.ReadableSectorTags.Contains(SectorTagType.AppleSectorTag) && entry.flLgLen > 0)
            {
                xattrs.Add("com.apple.macintosh.tags");
            }

            xattrs.Sort();

            return(Errno.NoError);
        }
Beispiel #20
0
        static void RequestBlockAddress(string devPath, Device dev)
        {
            uint   lba = 0;
            string strDev;
            int    item;

parameters:

            while (true)
            {
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("Parameters for REQUEST BLOCK ADDRESS command:");
                AaruConsole.WriteLine("LBA: {0}", lba);
                AaruConsole.WriteLine();
                AaruConsole.WriteLine("Choose what to do:");
                AaruConsole.WriteLine("1.- Change parameters.");
                AaruConsole.WriteLine("2.- Send command with these parameters.");
                AaruConsole.WriteLine("0.- Return to Archive vendor commands menu.");

                strDev = System.Console.ReadLine();

                if (!int.TryParse(strDev, out item))
                {
                    AaruConsole.WriteLine("Not a number. Press any key to continue...");
                    System.Console.ReadKey();

                    continue;
                }

                switch (item)
                {
                case 0:
                    AaruConsole.WriteLine("Returning to Archive vendor commands menu...");

                    return;

                case 1:
                    AaruConsole.Write("LBA?: ");
                    strDev = System.Console.ReadLine();

                    if (!uint.TryParse(strDev, out lba))
                    {
                        AaruConsole.WriteLine("Not a number. Press any key to continue...");
                        lba = 0;
                        System.Console.ReadKey();
                    }

                    break;

                case 2: goto start;
                }
            }

start:
            System.Console.Clear();

            bool sense = dev.ArchiveCorpRequestBlockAddress(out byte[] buffer, out byte[] senseBuffer, lba, dev.Timeout,
                                                            out double duration);

menu:
            AaruConsole.WriteLine("Device: {0}", devPath);
            AaruConsole.WriteLine("Sending REQUEST BLOCK ADDRESS to the device:");
            AaruConsole.WriteLine("Command took {0} ms.", duration);
            AaruConsole.WriteLine("Sense is {0}.", sense);
            AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null");
            AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer));
            AaruConsole.WriteLine("Sense buffer is {0} bytes.", senseBuffer?.Length.ToString() ?? "null");
            AaruConsole.WriteLine("Sense buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(senseBuffer));
            AaruConsole.WriteLine();
            AaruConsole.WriteLine("Choose what to do:");
            AaruConsole.WriteLine("1.- Print buffer.");
            AaruConsole.WriteLine("2.- Print sense buffer.");
            AaruConsole.WriteLine("3.- Decode sense buffer.");
            AaruConsole.WriteLine("4.- Send command again.");
            AaruConsole.WriteLine("5.- Change parameters.");
            AaruConsole.WriteLine("0.- Return to Archive vendor commands menu.");
            AaruConsole.Write("Choose: ");

            strDev = System.Console.ReadLine();

            if (!int.TryParse(strDev, out item))
            {
                AaruConsole.WriteLine("Not a number. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }

            switch (item)
            {
            case 0:
                AaruConsole.WriteLine("Returning to Archive vendor commands menu...");

                return;

            case 1:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("REQUEST BLOCK ADDRESS response:");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(buffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 2:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("REQUEST BLOCK ADDRESS sense:");

                if (senseBuffer != null)
                {
                    PrintHex.PrintHexArray(senseBuffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 3:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("REQUEST BLOCK ADDRESS decoded sense:");
                AaruConsole.Write("{0}", Sense.PrettifySense(senseBuffer));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 4: goto start;

            case 5: goto parameters;

            default:
                AaruConsole.WriteLine("Incorrect option. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }
        }
Beispiel #21
0
        static void Read(string devPath, Device dev, bool multiple)
        {
            uint   address   = 0;
            uint   blockSize = 512;
            uint   count     = 1;
            bool   byteAddr  = false;
            string strDev;
            int    item;

parameters:

            while (true)
            {
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("Parameters for READ_{0}_BLOCK command:", multiple ? "MULTIPLE" : "SINGLE");
                AaruConsole.WriteLine("Read from {1}: {0}", address, byteAddr ? "byte" : "block");
                AaruConsole.WriteLine("Expected block size: {0} bytes", blockSize);

                if (multiple)
                {
                    AaruConsole.WriteLine("Will read {0} blocks", count);
                }

                AaruConsole.WriteLine();
                AaruConsole.WriteLine("Choose what to do:");
                AaruConsole.WriteLine("1.- Change parameters.");
                AaruConsole.WriteLine("2.- Send command with these parameters.");
                AaruConsole.WriteLine("0.- Return to SecureDigital commands menu.");

                strDev = System.Console.ReadLine();

                if (!int.TryParse(strDev, out item))
                {
                    AaruConsole.WriteLine("Not a number. Press any key to continue...");
                    System.Console.ReadKey();

                    continue;
                }

                switch (item)
                {
                case 0:
                    AaruConsole.WriteLine("Returning to SecureDigital commands menu...");

                    return;

                case 1:
                    AaruConsole.Write("Use byte addressing?: ");
                    strDev = System.Console.ReadLine();

                    if (!bool.TryParse(strDev, out byteAddr))
                    {
                        AaruConsole.WriteLine("Not a boolean. Press any key to continue...");
                        byteAddr = false;
                        System.Console.ReadKey();

                        continue;
                    }

                    AaruConsole.Write("Read from {0}?: ", byteAddr ? "byte" : "block");
                    strDev = System.Console.ReadLine();

                    if (!uint.TryParse(strDev, out address))
                    {
                        AaruConsole.WriteLine("Not a number. Press any key to continue...");
                        address = 0;
                        System.Console.ReadKey();

                        continue;
                    }

                    if (multiple)
                    {
                        AaruConsole.Write("How many blocks to read?");
                        strDev = System.Console.ReadLine();

                        if (!uint.TryParse(strDev, out count))
                        {
                            AaruConsole.WriteLine("Not a number. Press any key to continue...");
                            count = 1;
                            System.Console.ReadKey();

                            continue;
                        }
                    }

                    AaruConsole.Write("How many bytes to expect in a block?");
                    strDev = System.Console.ReadLine();

                    if (!uint.TryParse(strDev, out blockSize))
                    {
                        AaruConsole.WriteLine("Not a number. Press any key to continue...");
                        blockSize = 512;
                        System.Console.ReadKey();
                    }

                    break;

                case 2: goto start;
                }
            }

start:
            System.Console.Clear();

            bool sense = dev.Read(out byte[] buffer, out uint[] response, address, blockSize, multiple ? count : 1,
                                  byteAddr, dev.Timeout, out double duration);

menu:
            AaruConsole.WriteLine("Device: {0}", devPath);
            AaruConsole.WriteLine("Sending READ_{0}_BLOCK to the device:", multiple ? "MULTIPLE" : "SINGLE");
            AaruConsole.WriteLine("Command took {0} ms.", duration);
            AaruConsole.WriteLine("Sense is {0}.", sense);
            AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null");
            AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer));
            AaruConsole.WriteLine("Response has {0} elements.", response?.Length.ToString() ?? "null");
            AaruConsole.WriteLine();
            AaruConsole.WriteLine("Choose what to do:");
            AaruConsole.WriteLine("1.- Print buffer.");
            AaruConsole.WriteLine("2.- Print response buffer.");
            AaruConsole.WriteLine("3.- Send command again.");
            AaruConsole.WriteLine("4.- Change parameters.");
            AaruConsole.WriteLine("0.- Return to SecureDigital commands menu.");
            AaruConsole.Write("Choose: ");

            strDev = System.Console.ReadLine();

            if (!int.TryParse(strDev, out item))
            {
                AaruConsole.WriteLine("Not a number. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }

            switch (item)
            {
            case 0:
                AaruConsole.WriteLine("Returning to SecureDigital commands menu...");

                return;

            case 1:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("READ_{0}_BLOCK buffer:", multiple ? "MULTIPLE" : "SINGLE");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(buffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 2:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("READ_{0}_BLOCK response:", multiple ? "MULTIPLE" : "SINGLE");

                if (response != null)
                {
                    foreach (uint res in response)
                    {
                        AaruConsole.Write("0x{0:x8} ", res);
                    }

                    AaruConsole.WriteLine();
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 3: goto start;

            case 4: goto parameters;

            default:
                AaruConsole.WriteLine("Incorrect option. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }
        }
Beispiel #22
0
        static void ExtractSecuritySectors(string devPath, Device dev)
        {
            byte   requestNumber = 0;
            string strDev;
            int    item;

parameters:
            while (true)
            {
                System.Console.Clear();
                DicConsole.WriteLine("Device: {0}", devPath);
                DicConsole.WriteLine("Parameters for EXTRACT SS command:");
                DicConsole.WriteLine("Request number: {0}", requestNumber);
                DicConsole.WriteLine();
                DicConsole.WriteLine("Choose what to do:");
                DicConsole.WriteLine("1.- Change parameters.");
                DicConsole.WriteLine("2.- Send command with these parameters.");
                DicConsole.WriteLine("0.- Return to Kreon vendor commands menu.");

                strDev = System.Console.ReadLine();
                if (!int.TryParse(strDev, out item))
                {
                    DicConsole.WriteLine("Not a number. Press any key to continue...");
                    System.Console.ReadKey();
                    continue;
                }

                switch (item)
                {
                case 0:
                    DicConsole.WriteLine("Returning to Kreon vendor commands menu...");
                    return;

                case 1:
                    DicConsole.Write("Request number?: ");
                    strDev = System.Console.ReadLine();
                    if (!byte.TryParse(strDev, out requestNumber))
                    {
                        DicConsole.WriteLine("Not a number. Press any key to continue...");
                        requestNumber = 0;
                        System.Console.ReadKey();
                    }

                    break;

                case 2: goto start;
                }
            }

start:
            System.Console.Clear();
            bool sense = dev.KreonExtractSs(out byte[] buffer, out byte[] senseBuffer, dev.Timeout, out double duration,
                                            requestNumber);

menu:
            DicConsole.WriteLine("Device: {0}", devPath);
            DicConsole.WriteLine("Sending EXTRACT SS to the device:");
            DicConsole.WriteLine("Command took {0} ms.", duration);
            DicConsole.WriteLine("Sense is {0}.", sense);
            DicConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null");
            DicConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer));
            DicConsole.WriteLine("Sense buffer is {0} bytes.", senseBuffer?.Length.ToString() ?? "null");
            DicConsole.WriteLine("Sense buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(senseBuffer));
            DicConsole.WriteLine();
            DicConsole.WriteLine("Choose what to do:");
            DicConsole.WriteLine("1.- Print buffer.");
            DicConsole.WriteLine("2.- Print sense buffer.");
            DicConsole.WriteLine("3.- Decode sense buffer.");
            DicConsole.WriteLine("4.- Send command again.");
            DicConsole.WriteLine("5.- Change parameters.");
            DicConsole.WriteLine("0.- Return to Kreon vendor commands menu.");
            DicConsole.Write("Choose: ");

            strDev = System.Console.ReadLine();
            if (!int.TryParse(strDev, out item))
            {
                DicConsole.WriteLine("Not a number. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                goto menu;
            }

            switch (item)
            {
            case 0:
                DicConsole.WriteLine("Returning to Kreon vendor commands menu...");
                return;

            case 1:
                System.Console.Clear();
                DicConsole.WriteLine("Device: {0}", devPath);
                DicConsole.WriteLine("EXTRACT SS response:");
                if (buffer != null)
                {
                    PrintHex.PrintHexArray(buffer, 64);
                }
                DicConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                DicConsole.WriteLine("Device: {0}", devPath);
                goto menu;

            case 2:
                System.Console.Clear();
                DicConsole.WriteLine("Device: {0}", devPath);
                DicConsole.WriteLine("EXTRACT SS sense:");
                if (senseBuffer != null)
                {
                    PrintHex.PrintHexArray(senseBuffer, 64);
                }
                DicConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                DicConsole.WriteLine("Device: {0}", devPath);
                goto menu;

            case 3:
                System.Console.Clear();
                DicConsole.WriteLine("Device: {0}", devPath);
                DicConsole.WriteLine("EXTRACT SS decoded sense:");
                DicConsole.Write("{0}", Sense.PrettifySense(senseBuffer));
                DicConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                DicConsole.WriteLine("Device: {0}", devPath);
                goto menu;

            case 4: goto start;

            case 5: goto parameters;

            default:
                DicConsole.WriteLine("Incorrect option. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                goto menu;
            }
        }
Beispiel #23
0
        static void SendScr(string devPath, Device dev)
        {
start:
            System.Console.Clear();
            bool sense = dev.ReadScr(out byte[] buffer, out uint[] response, dev.Timeout, out double duration);

menu:
            AaruConsole.WriteLine("Device: {0}", devPath);
            AaruConsole.WriteLine("Sending SEND_SCR to the device:");
            AaruConsole.WriteLine("Command took {0} ms.", duration);
            AaruConsole.WriteLine("Sense is {0}.", sense);
            AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null");
            AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer));
            AaruConsole.WriteLine("Response has {0} elements.", response?.Length.ToString() ?? "null");
            AaruConsole.WriteLine();
            AaruConsole.WriteLine("Choose what to do:");
            AaruConsole.WriteLine("1.- Print buffer.");
            AaruConsole.WriteLine("2.- Decode buffer.");
            AaruConsole.WriteLine("3.- Print response buffer.");
            AaruConsole.WriteLine("4.- Send command again.");
            AaruConsole.WriteLine("0.- Return to SecureDigital commands menu.");
            AaruConsole.Write("Choose: ");

            string strDev = System.Console.ReadLine();

            if (!int.TryParse(strDev, out int item))
            {
                AaruConsole.WriteLine("Not a number. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }

            switch (item)
            {
            case 0:
                AaruConsole.WriteLine("Returning to SecureDigital commands menu...");

                return;

            case 1:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("SEND_SCR buffer:");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(buffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 2:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("SEND_SCR decoded buffer:");

                if (buffer != null)
                {
                    AaruConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifySCR(buffer));
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 3:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("SEND_SCR response:");

                if (response != null)
                {
                    foreach (uint res in response)
                    {
                        AaruConsole.Write("0x{0:x8} ", res);
                    }

                    AaruConsole.WriteLine();
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 4: goto start;

            default:
                AaruConsole.WriteLine("Incorrect option. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }
        }
Beispiel #24
0
        // TODO: BBC Master hard disks are untested...
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (partition.Start >= partition.End)
            {
                return(false);
            }

            ulong sbSector;
            uint  sectorsToRead;

            if (imagePlugin.Info.SectorSize < 256)
            {
                return(false);
            }

            byte[]   sector;
            GCHandle ptr;

            // ADFS-S, ADFS-M, ADFS-L, ADFS-D without partitions
            if (partition.Start == 0)
            {
                sector = imagePlugin.ReadSector(0);
                byte oldChk0 = AcornMapChecksum(sector, 255);
                ptr = GCHandle.Alloc(sector, GCHandleType.Pinned);
                OldMapSector0 oldMap0 =
                    (OldMapSector0)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldMapSector0));

                sector = imagePlugin.ReadSector(1);
                byte oldChk1 = AcornMapChecksum(sector, 255);
                ptr = GCHandle.Alloc(sector, GCHandleType.Pinned);
                OldMapSector1 oldMap1 =
                    (OldMapSector1)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldMapSector1));

                DicConsole.DebugWriteLine("ADFS Plugin", "oldMap0.checksum = {0}", oldMap0.checksum);
                DicConsole.DebugWriteLine("ADFS Plugin", "oldChk0 = {0}", oldChk0);

                // According to documentation map1 MUST start on sector 1. On ADFS-D it starts at 0x100, not on sector 1 (0x400)
                if (oldMap0.checksum == oldChk0 && oldMap1.checksum != oldChk1 && sector.Length >= 512)
                {
                    sector = imagePlugin.ReadSector(0);
                    byte[] tmp = new byte[256];
                    Array.Copy(sector, 256, tmp, 0, 256);
                    oldChk1 = AcornMapChecksum(tmp, 255);
                    ptr     = GCHandle.Alloc(tmp, GCHandleType.Pinned);
                    oldMap1 = (OldMapSector1)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldMapSector1));
                }

                DicConsole.DebugWriteLine("ADFS Plugin", "oldMap1.checksum = {0}", oldMap1.checksum);
                DicConsole.DebugWriteLine("ADFS Plugin", "oldChk1 = {0}", oldChk1);

                if (oldMap0.checksum == oldChk0 && oldMap1.checksum == oldChk1 && oldMap0.checksum != 0 &&
                    oldMap1.checksum != 0)
                {
                    sbSector      = OLD_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize;
                    sectorsToRead = OLD_DIRECTORY_SIZE / imagePlugin.Info.SectorSize;
                    if (OLD_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0)
                    {
                        sectorsToRead++;
                    }

                    sector = imagePlugin.ReadSectors(sbSector, sectorsToRead);
                    if (sector.Length > OLD_DIRECTORY_SIZE)
                    {
                        byte[] tmp = new byte[OLD_DIRECTORY_SIZE];
                        Array.Copy(sector, 0, tmp, 0, OLD_DIRECTORY_SIZE - 53);
                        Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54, 53);
                        sector = tmp;
                    }
                    ptr = GCHandle.Alloc(sector, GCHandleType.Pinned);
                    OldDirectory oldRoot =
                        (OldDirectory)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldDirectory));
                    byte dirChk = AcornDirectoryChecksum(sector, (int)OLD_DIRECTORY_SIZE - 1);

                    DicConsole.DebugWriteLine("ADFS Plugin", "oldRoot.header.magic at 0x200 = {0}",
                                              oldRoot.header.magic);
                    DicConsole.DebugWriteLine("ADFS Plugin", "oldRoot.tail.magic at 0x200 = {0}", oldRoot.tail.magic);
                    DicConsole.DebugWriteLine("ADFS Plugin", "oldRoot.tail.checkByte at 0x200 = {0}",
                                              oldRoot.tail.checkByte);
                    DicConsole.DebugWriteLine("ADFS Plugin", "dirChk at 0x200 = {0}", dirChk);

                    if (oldRoot.header.magic == OLD_DIR_MAGIC && oldRoot.tail.magic == OLD_DIR_MAGIC ||
                        oldRoot.header.magic == NEW_DIR_MAGIC && oldRoot.tail.magic == NEW_DIR_MAGIC)
                    {
                        return(true);
                    }

                    // RISC OS says the old directory can't be in the new location, hard disks created by RISC OS 3.10 do that...
                    sbSector      = NEW_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize;
                    sectorsToRead = NEW_DIRECTORY_SIZE / imagePlugin.Info.SectorSize;
                    if (NEW_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0)
                    {
                        sectorsToRead++;
                    }

                    sector = imagePlugin.ReadSectors(sbSector, sectorsToRead);
                    if (sector.Length > OLD_DIRECTORY_SIZE)
                    {
                        byte[] tmp = new byte[OLD_DIRECTORY_SIZE];
                        Array.Copy(sector, 0, tmp, 0, OLD_DIRECTORY_SIZE - 53);
                        Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54, 53);
                        sector = tmp;
                    }
                    ptr     = GCHandle.Alloc(sector, GCHandleType.Pinned);
                    oldRoot = (OldDirectory)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldDirectory));
                    dirChk  = AcornDirectoryChecksum(sector, (int)OLD_DIRECTORY_SIZE - 1);

                    DicConsole.DebugWriteLine("ADFS Plugin", "oldRoot.header.magic at 0x400 = {0}",
                                              oldRoot.header.magic);
                    DicConsole.DebugWriteLine("ADFS Plugin", "oldRoot.tail.magic at 0x400 = {0}", oldRoot.tail.magic);
                    DicConsole.DebugWriteLine("ADFS Plugin", "oldRoot.tail.checkByte at 0x400 = {0}",
                                              oldRoot.tail.checkByte);
                    DicConsole.DebugWriteLine("ADFS Plugin", "dirChk at 0x400 = {0}", dirChk);

                    if (oldRoot.header.magic == OLD_DIR_MAGIC && oldRoot.tail.magic == OLD_DIR_MAGIC ||
                        oldRoot.header.magic == NEW_DIR_MAGIC && oldRoot.tail.magic == NEW_DIR_MAGIC)
                    {
                        return(true);
                    }
                }
            }

            // Partitioning or not, new formats follow:
            DiscRecord drSb;

            sector = imagePlugin.ReadSector(partition.Start);
            byte newChk = NewMapChecksum(sector);

            DicConsole.DebugWriteLine("ADFS Plugin", "newChk = {0}", newChk);
            DicConsole.DebugWriteLine("ADFS Plugin", "map.zoneChecksum = {0}", sector[0]);

            sbSector      = BOOT_BLOCK_LOCATION / imagePlugin.Info.SectorSize;
            sectorsToRead = BOOT_BLOCK_SIZE / imagePlugin.Info.SectorSize;
            if (BOOT_BLOCK_SIZE % imagePlugin.Info.SectorSize > 0)
            {
                sectorsToRead++;
            }

            if (sbSector + partition.Start + sectorsToRead >= partition.End)
            {
                return(false);
            }

            byte[] bootSector = imagePlugin.ReadSectors(sbSector + partition.Start, sectorsToRead);
            int    bootChk    = 0;

            for (int i = 0; i < 0x1FF; i++)
            {
                bootChk = (bootChk & 0xFF) + (bootChk >> 8) + bootSector[i];
            }

            DicConsole.DebugWriteLine("ADFS Plugin", "bootChk = {0}", bootChk);
            DicConsole.DebugWriteLine("ADFS Plugin", "bBlock.checksum = {0}", bootSector[0x1FF]);

            if (newChk == sector[0] && newChk != 0)
            {
                ptr = GCHandle.Alloc(sector, GCHandleType.Pinned);
                NewMap nmap = (NewMap)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(NewMap));
                ptr.Free();
                drSb = nmap.discRecord;
            }
            else if (bootChk == bootSector[0x1FF])
            {
                ptr = GCHandle.Alloc(bootSector, GCHandleType.Pinned);
                BootBlock bBlock = (BootBlock)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(BootBlock));
                ptr.Free();
                drSb = bBlock.discRecord;
            }
            else
            {
                return(false);
            }

            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.log2secsize = {0}", drSb.log2secsize);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.idlen = {0}", drSb.idlen);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_size_high = {0}", drSb.disc_size_high);
            DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_size = {0}", drSb.disc_size);
            DicConsole.DebugWriteLine("ADFS Plugin", "IsNullOrEmpty(drSb.reserved) = {0}",
                                      ArrayHelpers.ArrayIsNullOrEmpty(drSb.reserved));

            if (drSb.log2secsize < 8 || drSb.log2secsize > 10)
            {
                return(false);
            }

            if (drSb.idlen < drSb.log2secsize + 3 || drSb.idlen > 19)
            {
                return(false);
            }

            if (drSb.disc_size_high >> drSb.log2secsize != 0)
            {
                return(false);
            }

            if (!ArrayHelpers.ArrayIsNullOrEmpty(drSb.reserved))
            {
                return(false);
            }

            ulong bytes = drSb.disc_size_high;

            bytes *= 0x100000000;
            bytes += drSb.disc_size;

            return(bytes <= imagePlugin.Info.Sectors * imagePlugin.Info.SectorSize);
        }
Beispiel #25
0
        public Errno GetXattr(string path, string xattr, ref byte[] buf)
        {
            if (!mounted)
            {
                return(Errno.AccessDenied);
            }

            string[] pathElements = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            if (pathElements.Length != 1)
            {
                return(Errno.NotSupported);
            }

            path = pathElements[0];

            if (debug)
            {
                if (string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
                    string.Compare(path, "$Bitmap", StringComparison.InvariantCulture) == 0 ||
                    string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 ||
                    string.Compare(path, "$MDB", StringComparison.InvariantCulture) == 0)
                {
                    if (device.Info.ReadableSectorTags.Contains(SectorTagType.AppleSectorTag) &&
                        string.Compare(xattr, "com.apple.macintosh.tags", StringComparison.InvariantCulture) == 0)
                    {
                        if (string.Compare(path, "$", StringComparison.InvariantCulture) == 0)
                        {
                            buf = new byte[directoryTags.Length];
                            Array.Copy(directoryTags, 0, buf, 0, buf.Length);
                            return(Errno.NoError);
                        }

                        if (string.Compare(path, "$Bitmap", StringComparison.InvariantCulture) == 0)
                        {
                            buf = new byte[bitmapTags.Length];
                            Array.Copy(bitmapTags, 0, buf, 0, buf.Length);
                            return(Errno.NoError);
                        }

                        if (string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0)
                        {
                            buf = new byte[bootTags.Length];
                            Array.Copy(bootTags, 0, buf, 0, buf.Length);
                            return(Errno.NoError);
                        }

                        if (string.Compare(path, "$MDB", StringComparison.InvariantCulture) == 0)
                        {
                            buf = new byte[mdbTags.Length];
                            Array.Copy(mdbTags, 0, buf, 0, buf.Length);
                            return(Errno.NoError);
                        }
                    }
                    else
                    {
                        return(Errno.NoSuchExtendedAttribute);
                    }
                }
            }

            Errno error;

            if (!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId))
            {
                return(Errno.NoSuchFile);
            }

            if (!idToEntry.TryGetValue(fileId, out MFS_FileEntry entry))
            {
                return(Errno.NoSuchFile);
            }

            if (entry.flRLgLen > 0 &&
                string.Compare(xattr, "com.apple.ResourceFork", StringComparison.InvariantCulture) == 0)
            {
                error = ReadFile(path, out buf, true, false);
                return(error);
            }

            if (entry.flRLgLen > 0 &&
                string.Compare(xattr, "com.apple.ResourceFork.tags", StringComparison.InvariantCulture) == 0)
            {
                error = ReadFile(path, out buf, true, true);
                return(error);
            }

            if (!ArrayHelpers.ArrayIsNullOrEmpty(entry.flUsrWds) &&
                string.Compare(xattr, "com.apple.FinderInfo", StringComparison.InvariantCulture) == 0)
            {
                buf = new byte[16];
                Array.Copy(entry.flUsrWds, 0, buf, 0, 16);
                return(Errno.NoError);
            }

            if (!debug || !device.Info.ReadableSectorTags.Contains(SectorTagType.AppleSectorTag) ||
                string.Compare(xattr, "com.apple.macintosh.tags", StringComparison.InvariantCulture) != 0)
            {
                return(Errno.NoSuchExtendedAttribute);
            }

            error = ReadFile(path, out buf, false, true);
            return(error);
        }
Beispiel #26
0
        static void ReadLog(string devPath, Device dev)
        {
            byte   address = 0;
            string strDev;
            int    item;

parameters:
            while (true)
            {
                System.Console.Clear();
                DicConsole.WriteLine("Device: {0}", devPath);
                DicConsole.WriteLine("Parameters for READ LOG command:");
                DicConsole.WriteLine("Log address: {0}", address);
                DicConsole.WriteLine();
                DicConsole.WriteLine("Choose what to do:");
                DicConsole.WriteLine("1.- Change parameters.");
                DicConsole.WriteLine("2.- Send command with these parameters.");
                DicConsole.WriteLine("0.- Return to S.M.A.R.T. commands menu.");

                strDev = System.Console.ReadLine();
                if (!int.TryParse(strDev, out item))
                {
                    DicConsole.WriteLine("Not a number. Press any key to continue...");
                    System.Console.ReadKey();
                    continue;
                }

                switch (item)
                {
                case 0:
                    DicConsole.WriteLine("Returning to S.M.A.R.T. commands menu...");
                    return;

                case 1:
                    DicConsole.Write("Log address?: ");
                    strDev = System.Console.ReadLine();
                    if (!byte.TryParse(strDev, out address))
                    {
                        DicConsole.WriteLine("Not a number. Press any key to continue...");
                        address = 0;
                        System.Console.ReadKey();
                    }

                    break;

                case 2: goto start;
                }
            }

start:
            System.Console.Clear();
            bool sense = dev.SmartReadLog(out byte[] buffer, out AtaErrorRegistersLba28 errorRegisters, address,
                                          dev.Timeout, out double duration);

menu:
            DicConsole.WriteLine("Device: {0}", devPath);
            DicConsole.WriteLine("Sending READ LOG to the device:");
            DicConsole.WriteLine("Command took {0} ms.", duration);
            DicConsole.WriteLine("Sense is {0}.", sense);
            DicConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null");
            DicConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer));
            DicConsole.WriteLine();
            DicConsole.WriteLine("Choose what to do:");
            DicConsole.WriteLine("1.- Print buffer.");
            DicConsole.WriteLine("2.- Decode error registers.");
            DicConsole.WriteLine("3.- Send command again.");
            DicConsole.WriteLine("4.- Change parameters.");
            DicConsole.WriteLine("0.- Return to S.M.A.R.T. commands menu.");
            DicConsole.Write("Choose: ");

            strDev = System.Console.ReadLine();
            if (!int.TryParse(strDev, out item))
            {
                DicConsole.WriteLine("Not a number. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                goto menu;
            }

            switch (item)
            {
            case 0:
                DicConsole.WriteLine("Returning to S.M.A.R.T. commands menu...");
                return;

            case 1:
                System.Console.Clear();
                DicConsole.WriteLine("Device: {0}", devPath);
                DicConsole.WriteLine("READ LOG response:");
                if (buffer != null)
                {
                    PrintHex.PrintHexArray(buffer, 64);
                }
                DicConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                DicConsole.WriteLine("Device: {0}", devPath);
                goto menu;

            case 2:
                System.Console.Clear();
                DicConsole.WriteLine("Device: {0}", devPath);
                DicConsole.WriteLine("READ LOG status registers:");
                DicConsole.Write("{0}", MainClass.DecodeAtaRegisters(errorRegisters));
                DicConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                DicConsole.WriteLine("Device: {0}", devPath);
                goto menu;

            case 3: goto start;

            case 4: goto parameters;

            default:
                DicConsole.WriteLine("Incorrect option. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                goto menu;
            }
        }
Beispiel #27
0
        /// <summary>
        ///     Lists special Apple Lisa filesystem features as extended attributes
        /// </summary>
        /// <returns>Error number.</returns>
        /// <param name="fileId">File identifier.</param>
        /// <param name="xattr">Extended attribute name.</param>
        /// <param name="buf">Buffer where the extended attribute will be stored.</param>
        Errno GetXattr(short fileId, string xattr, out byte[] buf)
        {
            buf = null;

            if (!mounted)
            {
                return(Errno.AccessDenied);
            }

            // System files
            if (fileId < 4)
            {
                if (!debug || fileId == 0)
                {
                    return(Errno.InvalidArgument);
                }

                // Only MDDF contains an extended attributes
                if (fileId == FILEID_MDDF)
                {
                    if (xattr == "com.apple.lisa.password")
                    {
                        buf = Encoding.ASCII.GetBytes(mddf.password);
                        return(Errno.NoError);
                    }
                }

                // But on debug mode even system files contain tags
                if (debug && xattr == "com.apple.lisa.tags")
                {
                    return(ReadSystemFile(fileId, out buf, true));
                }

                return(Errno.NoSuchExtendedAttribute);
            }

            // Search for the file
            Errno error = ReadExtentsFile(fileId, out ExtentFile file);

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

            switch (xattr)
            {
            case "com.apple.lisa.password" when file.password_valid > 0:
                buf = new byte[8];
                Array.Copy(file.password, 0, buf, 0, 8);
                return(Errno.NoError);

            case "com.apple.lisa.serial" when file.serial > 0:
                buf = Encoding.ASCII.GetBytes(file.serial.ToString());
                return(Errno.NoError);
            }

            if (!ArrayHelpers.ArrayIsNullOrEmpty(file.LisaInfo) && xattr == "com.apple.lisa.label")
            {
                buf = new byte[128];
                Array.Copy(file.LisaInfo, 0, buf, 0, 128);
                return(Errno.NoError);
            }

            if (debug && xattr == "com.apple.lisa.tags")
            {
                return(ReadFile(fileId, out buf, true));
            }

            return(Errno.NoSuchExtendedAttribute);
        }
Beispiel #28
0
        static void ReadSectorLocation(string devPath, Device dev)
        {
            uint   address  = 0;
            bool   physical = false;
            string strDev;
            int    item;

parameters:

            while (true)
            {
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("Parameters for READ SECTOR LOCATION command:");
                AaruConsole.WriteLine("{0} Block Address: {1}", physical ? "Physical" : "Logical", address);
                AaruConsole.WriteLine();
                AaruConsole.WriteLine("Choose what to do:");
                AaruConsole.WriteLine("1.- Change parameters.");
                AaruConsole.WriteLine("2.- Send command with these parameters.");
                AaruConsole.WriteLine("0.- Return to Plasmon vendor commands menu.");

                strDev = System.Console.ReadLine();

                if (!int.TryParse(strDev, out item))
                {
                    AaruConsole.WriteLine("Not a number. Press any key to continue...");
                    System.Console.ReadKey();

                    continue;
                }

                switch (item)
                {
                case 0:
                    AaruConsole.WriteLine("Returning to Plasmon vendor commands menu...");

                    return;

                case 1:
                    AaruConsole.Write("Physical address?: ");
                    strDev = System.Console.ReadLine();

                    if (!bool.TryParse(strDev, out physical))
                    {
                        AaruConsole.WriteLine("Not a boolean. Press any key to continue...");
                        physical = false;
                        System.Console.ReadKey();

                        continue;
                    }

                    AaruConsole.Write("{0} Block Address?: ", physical ? "Physical" : "Logical");
                    strDev = System.Console.ReadLine();

                    if (!uint.TryParse(strDev, out address))
                    {
                        AaruConsole.WriteLine("Not a numbr. Press any key to continue...");
                        address = 0;
                        System.Console.ReadKey();
                    }

                    break;

                case 2: goto start;
                }
            }

start:
            System.Console.Clear();

            bool sense = dev.PlasmonReadSectorLocation(out byte[] buffer, out byte[] senseBuffer, address, physical,
                                                       dev.Timeout, out double duration);

menu:
            AaruConsole.WriteLine("Device: {0}", devPath);
            AaruConsole.WriteLine("Sending READ SECTOR LOCATION to the device:");
            AaruConsole.WriteLine("Command took {0} ms.", duration);
            AaruConsole.WriteLine("Sense is {0}.", sense);
            AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null");
            AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer));
            AaruConsole.WriteLine("Sense buffer is {0} bytes.", senseBuffer?.Length.ToString() ?? "null");
            AaruConsole.WriteLine("Sense buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(senseBuffer));
            AaruConsole.WriteLine();
            AaruConsole.WriteLine("Choose what to do:");
            AaruConsole.WriteLine("1.- Print buffer.");
            AaruConsole.WriteLine("2.- Print sense buffer.");
            AaruConsole.WriteLine("3.- Decode sense buffer.");
            AaruConsole.WriteLine("4.- Send command again.");
            AaruConsole.WriteLine("5.- Change parameters.");
            AaruConsole.WriteLine("0.- Return to Plasmon vendor commands menu.");
            AaruConsole.Write("Choose: ");

            strDev = System.Console.ReadLine();

            if (!int.TryParse(strDev, out item))
            {
                AaruConsole.WriteLine("Not a number. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }

            switch (item)
            {
            case 0:
                AaruConsole.WriteLine("Returning to Plasmon vendor commands menu...");

                return;

            case 1:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("READ SECTOR LOCATION response:");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(buffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 2:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("READ SECTOR LOCATION sense:");

                if (senseBuffer != null)
                {
                    PrintHex.PrintHexArray(senseBuffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 3:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("READ SECTOR LOCATION decoded sense:");
                AaruConsole.Write("{0}", Sense.PrettifySense(senseBuffer));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 4: goto start;

            case 5: goto parameters;

            default:
                AaruConsole.WriteLine("Incorrect option. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }
        }
Beispiel #29
0
        static void TranslateSectorLba(string devPath, Device dev)
        {
            uint   lba = 0;
            string strDev;
            int    item;

parameters:

            while (true)
            {
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("Parameters for TRANSLATE SECTOR command:");
                AaruConsole.WriteLine("LBA: {0}", lba);
                AaruConsole.WriteLine();
                AaruConsole.WriteLine("Choose what to do:");
                AaruConsole.WriteLine("1.- Change parameters.");
                AaruConsole.WriteLine("2.- Send command with these parameters.");
                AaruConsole.WriteLine("0.- Return to CompactFlash commands menu.");

                strDev = System.Console.ReadLine();

                if (!int.TryParse(strDev, out item))
                {
                    AaruConsole.WriteLine("Not a number. Press any key to continue...");
                    System.Console.ReadKey();

                    continue;
                }

                switch (item)
                {
                case 0:
                    AaruConsole.WriteLine("Returning to CompactFlash commands menu...");

                    return;

                case 1:
                    AaruConsole.Write("What logical block address?: ");
                    strDev = System.Console.ReadLine();

                    if (!uint.TryParse(strDev, out lba))
                    {
                        AaruConsole.WriteLine("Not a number. Press any key to continue...");
                        lba = 0;
                        System.Console.ReadKey();

                        continue;
                    }

                    if (lba > 0xFFFFFFF)
                    {
                        AaruConsole.
                        WriteLine("Logical block address cannot be bigger than {0}. Setting it to {0}...",
                                  0xFFFFFFF);

                        lba = 0xFFFFFFF;
                    }

                    break;

                case 2: goto start;
                }
            }

start:
            System.Console.Clear();

            bool sense = dev.TranslateSector(out byte[] buffer, out AtaErrorRegistersLba28 errorRegisters, lba,
                                             dev.Timeout, out double duration);

menu:
            AaruConsole.WriteLine("Device: {0}", devPath);
            AaruConsole.WriteLine("Sending TRANSLATE SECTOR to the device:");
            AaruConsole.WriteLine("Command took {0} ms.", duration);
            AaruConsole.WriteLine("Sense is {0}.", sense);
            AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null");
            AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer));
            AaruConsole.WriteLine();
            AaruConsole.WriteLine("Choose what to do:");
            AaruConsole.WriteLine("1.- Print buffer.");
            AaruConsole.WriteLine("2.- Decode error registers.");
            AaruConsole.WriteLine("3.- Send command again.");
            AaruConsole.WriteLine("4.- Change parameters.");
            AaruConsole.WriteLine("0.- Return to CompactFlash commands menu.");
            AaruConsole.Write("Choose: ");

            strDev = System.Console.ReadLine();

            if (!int.TryParse(strDev, out item))
            {
                AaruConsole.WriteLine("Not a number. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }

            switch (item)
            {
            case 0:
                AaruConsole.WriteLine("Returning to CompactFlash commands menu...");

                return;

            case 1:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("TRANSLATE SECTOR response:");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(buffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 2:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("TRANSLATE SECTOR status registers:");
                AaruConsole.Write("{0}", MainClass.DecodeAtaRegisters(errorRegisters));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 3: goto start;

            case 4: goto parameters;

            default:
                AaruConsole.WriteLine("Incorrect option. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }
        }
Beispiel #30
0
        static void ReadLong(string devPath, Device dev)
        {
            bool   relative    = false;
            uint   address     = 0;
            ushort length      = 1;
            ushort bps         = 512;
            bool   physical    = false;
            bool   sectorCount = true;
            string strDev;
            int    item;

parameters:

            while (true)
            {
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("Parameters for READ LONG command:");
                AaruConsole.WriteLine("{0} Block Address: {1}", physical ? "Physical" : "Logical", address);
                AaruConsole.WriteLine("Relative?: {0}", relative);
                AaruConsole.WriteLine("Will transfer {0} {1}", length, sectorCount ? "sectors" : "bytes");

                if (sectorCount)
                {
                    AaruConsole.WriteLine("Expected sector size: {0} bytes", bps);
                }

                AaruConsole.WriteLine();
                AaruConsole.WriteLine("Choose what to do:");
                AaruConsole.WriteLine("1.- Change parameters.");
                AaruConsole.WriteLine("2.- Send command with these parameters.");
                AaruConsole.WriteLine("0.- Return to Plasmon vendor commands menu.");

                strDev = System.Console.ReadLine();

                if (!int.TryParse(strDev, out item))
                {
                    AaruConsole.WriteLine("Not a number. Press any key to continue...");
                    System.Console.ReadKey();

                    continue;
                }

                switch (item)
                {
                case 0:
                    AaruConsole.WriteLine("Returning to Plasmon vendor commands menu...");

                    return;

                case 1:
                    AaruConsole.Write("Physical address?: ");
                    strDev = System.Console.ReadLine();

                    if (!bool.TryParse(strDev, out physical))
                    {
                        AaruConsole.WriteLine("Not a boolean. Press any key to continue...");
                        physical = false;
                        System.Console.ReadKey();

                        continue;
                    }

                    AaruConsole.Write("Relative address?: ");
                    strDev = System.Console.ReadLine();

                    if (!bool.TryParse(strDev, out relative))
                    {
                        AaruConsole.WriteLine("Not a boolean. Press any key to continue...");
                        relative = false;
                        System.Console.ReadKey();

                        continue;
                    }

                    AaruConsole.Write("{0} Block Address?: ", physical ? "Physical" : "Logical");
                    strDev = System.Console.ReadLine();

                    if (!uint.TryParse(strDev, out address))
                    {
                        AaruConsole.WriteLine("Not a numbr. Press any key to continue...");
                        address = 0;
                        System.Console.ReadKey();

                        continue;
                    }

                    AaruConsole.Write("Transfer sectors?: ");
                    strDev = System.Console.ReadLine();

                    if (!bool.TryParse(strDev, out sectorCount))
                    {
                        AaruConsole.WriteLine("Not a boolean. Press any key to continue...");
                        sectorCount = true;
                        System.Console.ReadKey();

                        continue;
                    }

                    AaruConsole.Write("How many {0} to transfer?: ", sectorCount ? "sectors" : "bytes");
                    strDev = System.Console.ReadLine();

                    if (!ushort.TryParse(strDev, out length))
                    {
                        AaruConsole.WriteLine("Not a number. Press any key to continue...");
                        length = (ushort)(sectorCount ? 1 : 512);
                        System.Console.ReadKey();

                        continue;
                    }

                    if (sectorCount)
                    {
                        AaruConsole.Write("How many bytes to expect per sector?");
                        strDev = System.Console.ReadLine();

                        if (!ushort.TryParse(strDev, out bps))
                        {
                            AaruConsole.WriteLine("Not a numbr. Press any key to continue...");
                            bps = 512;
                            System.Console.ReadKey();
                        }
                    }

                    break;

                case 2: goto start;
                }
            }

start:
            System.Console.Clear();

            bool sense = dev.PlasmonReadLong(out byte[] buffer, out byte[] senseBuffer, relative, address, length, bps,
                                             physical, sectorCount, dev.Timeout, out double duration);

menu:
            AaruConsole.WriteLine("Device: {0}", devPath);
            AaruConsole.WriteLine("Sending READ LONG to the device:");
            AaruConsole.WriteLine("Command took {0} ms.", duration);
            AaruConsole.WriteLine("Sense is {0}.", sense);
            AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null");
            AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer));
            AaruConsole.WriteLine("Sense buffer is {0} bytes.", senseBuffer?.Length.ToString() ?? "null");
            AaruConsole.WriteLine("Sense buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(senseBuffer));
            AaruConsole.WriteLine();
            AaruConsole.WriteLine("Choose what to do:");
            AaruConsole.WriteLine("1.- Print buffer.");
            AaruConsole.WriteLine("2.- Print sense buffer.");
            AaruConsole.WriteLine("3.- Decode sense buffer.");
            AaruConsole.WriteLine("4.- Send command again.");
            AaruConsole.WriteLine("5.- Change parameters.");
            AaruConsole.WriteLine("0.- Return to Plasmon vendor commands menu.");
            AaruConsole.Write("Choose: ");

            strDev = System.Console.ReadLine();

            if (!int.TryParse(strDev, out item))
            {
                AaruConsole.WriteLine("Not a number. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }

            switch (item)
            {
            case 0:
                AaruConsole.WriteLine("Returning to Plasmon vendor commands menu...");

                return;

            case 1:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("READ LONG response:");

                if (buffer != null)
                {
                    PrintHex.PrintHexArray(buffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 2:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("READ LONG sense:");

                if (senseBuffer != null)
                {
                    PrintHex.PrintHexArray(senseBuffer, 64);
                }

                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 3:
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);
                AaruConsole.WriteLine("READ LONG decoded sense:");
                AaruConsole.Write("{0}", Sense.PrettifySense(senseBuffer));
                AaruConsole.WriteLine("Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();
                AaruConsole.WriteLine("Device: {0}", devPath);

                goto menu;

            case 4: goto start;

            case 5: goto parameters;

            default:
                AaruConsole.WriteLine("Incorrect option. Press any key to continue...");
                System.Console.ReadKey();
                System.Console.Clear();

                goto menu;
            }
        }