Пример #1
0
        public bool Identify(IFilter imageFilter)
        {
            OobBlock header = new OobBlock();
            Stream   stream = imageFilter.GetDataForkStream();

            stream.Seek(0, SeekOrigin.Begin);
            if (stream.Length < Marshal.SizeOf(header))
            {
                return(false);
            }

            byte[] hdr = new byte[Marshal.SizeOf(header)];
            stream.Read(hdr, 0, Marshal.SizeOf(header));

            IntPtr hdrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(header));

            Marshal.Copy(hdr, 0, hdrPtr, Marshal.SizeOf(header));
            header = (OobBlock)Marshal.PtrToStructure(hdrPtr, typeof(OobBlock));
            Marshal.FreeHGlobal(hdrPtr);

            OobBlock footer = new OobBlock();

            stream.Seek(-Marshal.SizeOf(footer), SeekOrigin.End);

            hdr = new byte[Marshal.SizeOf(footer)];
            stream.Read(hdr, 0, Marshal.SizeOf(footer));

            hdrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(footer));
            Marshal.Copy(hdr, 0, hdrPtr, Marshal.SizeOf(footer));
            footer = (OobBlock)Marshal.PtrToStructure(hdrPtr, typeof(OobBlock));
            Marshal.FreeHGlobal(hdrPtr);

            return(header.blockId == BlockIds.Oob && header.blockType == OobTypes.KFInfo &&
                   footer.blockId == BlockIds.Oob && footer.blockType == OobTypes.EOF && footer.length == 0x0D0D);
        }
Пример #2
0
        public bool Identify(IFilter imageFilter)
        {
            Stream stream = imageFilter.GetDataForkStream();

            stream.Seek(0, SeekOrigin.Begin);
            if (stream.Length < Marshal.SizeOf <OobBlock>())
            {
                return(false);
            }

            byte[] hdr = new byte[Marshal.SizeOf <OobBlock>()];
            stream.Read(hdr, 0, Marshal.SizeOf <OobBlock>());

            OobBlock header = Marshal.ByteArrayToStructureLittleEndian <OobBlock>(hdr);

            stream.Seek(-Marshal.SizeOf <OobBlock>(), SeekOrigin.End);

            hdr = new byte[Marshal.SizeOf <OobBlock>()];
            stream.Read(hdr, 0, Marshal.SizeOf <OobBlock>());

            OobBlock footer = Marshal.ByteArrayToStructureLittleEndian <OobBlock>(hdr);

            return(header.blockId == BlockIds.Oob && header.blockType == OobTypes.KFInfo &&
                   footer.blockId == BlockIds.Oob && footer.blockType == OobTypes.EOF && footer.length == 0x0D0D);
        }
Пример #3
0
        public bool Open(IFilter imageFilter)
        {
            Stream stream = imageFilter.GetDataForkStream();

            stream.Seek(0, SeekOrigin.Begin);

            if (stream.Length < Marshal.SizeOf <OobBlock>())
            {
                return(false);
            }

            byte[] hdr = new byte[Marshal.SizeOf <OobBlock>()];
            stream.Read(hdr, 0, Marshal.SizeOf <OobBlock>());

            OobBlock header = Marshal.ByteArrayToStructureLittleEndian <OobBlock>(hdr);

            stream.Seek(-Marshal.SizeOf <OobBlock>(), SeekOrigin.End);

            hdr = new byte[Marshal.SizeOf <OobBlock>()];
            stream.Read(hdr, 0, Marshal.SizeOf <OobBlock>());

            OobBlock footer = Marshal.ByteArrayToStructureLittleEndian <OobBlock>(hdr);

            if (header.blockId != BlockIds.Oob ||
                header.blockType != OobTypes.KFInfo ||
                footer.blockId != BlockIds.Oob ||
                footer.blockType != OobTypes.EOF ||
                footer.length != 0x0D0D)
            {
                return(false);
            }

            // TODO: This is supposing NoFilter, shouldn't
            tracks = new SortedDictionary <byte, IFilter>();
            byte step    = 1;
            byte heads   = 2;
            bool topHead = false;

            string basename = Path.Combine(imageFilter.GetParentFolder(),
                                           imageFilter.GetFilename().
                                           Substring(0, imageFilter.GetFilename().Length - 8));

            for (byte t = 0; t < 166; t += step)
            {
                int cylinder = t / heads;
                int head     = topHead ? 1 : t % heads;

                string trackfile = Directory.Exists(basename) ? Path.Combine(basename, $"{cylinder:D2}.{head:D1}.raw")
                                       : $"{basename}{cylinder:D2}.{head:D1}.raw";

                if (!File.Exists(trackfile))
                {
                    if (cylinder == 0)
                    {
                        if (head == 0)
                        {
                            AaruConsole.DebugWriteLine("KryoFlux plugin",
                                                       "Cannot find cyl 0 hd 0, supposing only top head was dumped");

                            topHead = true;
                            heads   = 1;

                            continue;
                        }

                        AaruConsole.DebugWriteLine("KryoFlux plugin",
                                                   "Cannot find cyl 0 hd 1, supposing only bottom head was dumped");

                        heads = 1;

                        continue;
                    }
                    else if (cylinder == 1)
                    {
                        AaruConsole.DebugWriteLine("KryoFlux plugin", "Cannot find cyl 1, supposing double stepping");
                        step = 2;

                        continue;
                    }
                    else
                    {
                        AaruConsole.DebugWriteLine("KryoFlux plugin", "Arrived end of disk at cylinder {0}", cylinder);

                        break;
                    }
                }

                var trackFilter = new ZZZNoFilter();
                trackFilter.Open(trackfile);

                if (!trackFilter.IsOpened())
                {
                    throw new IOException("Could not open KryoFlux track file.");
                }

                imageInfo.CreationTime         = DateTime.MaxValue;
                imageInfo.LastModificationTime = DateTime.MinValue;

                Stream trackStream = trackFilter.GetDataForkStream();

                while (trackStream.Position < trackStream.Length)
                {
                    byte blockId = (byte)trackStream.ReadByte();

                    switch (blockId)
                    {
                    case (byte)BlockIds.Oob:
                    {
                        trackStream.Position--;

                        byte[] oob = new byte[Marshal.SizeOf <OobBlock>()];
                        trackStream.Read(oob, 0, Marshal.SizeOf <OobBlock>());

                        OobBlock oobBlk = Marshal.ByteArrayToStructureLittleEndian <OobBlock>(oob);

                        if (oobBlk.blockType == OobTypes.EOF)
                        {
                            trackStream.Position = trackStream.Length;

                            break;
                        }

                        if (oobBlk.blockType != OobTypes.KFInfo)
                        {
                            trackStream.Position += oobBlk.length;

                            break;
                        }

                        byte[] kfinfo = new byte[oobBlk.length];
                        trackStream.Read(kfinfo, 0, oobBlk.length);
                        string kfinfoStr = StringHandlers.CToString(kfinfo);

                        string[] lines = kfinfoStr.Split(new[]
                            {
                                ','
                            }, StringSplitOptions.RemoveEmptyEntries);

                        DateTime blockDate = DateTime.Now;
                        DateTime blockTime = DateTime.Now;
                        bool     foundDate = false;

                        foreach (string[] kvp in lines.Select(line => line.Split('=')).Where(kvp => kvp.Length == 2))
                        {
                            kvp[0] = kvp[0].Trim();
                            kvp[1] = kvp[1].Trim();
                            AaruConsole.DebugWriteLine("KryoFlux plugin", "\"{0}\" = \"{1}\"", kvp[0], kvp[1]);

                            switch (kvp[0])
                            {
                            case _hostDate:
                                if (DateTime.TryParseExact(kvp[1], "yyyy.MM.dd", CultureInfo.InvariantCulture,
                                                           DateTimeStyles.AssumeLocal, out blockDate))
                                {
                                    foundDate = true;
                                }

                                break;

                            case _hostTime:
                                DateTime.TryParseExact(kvp[1], "HH:mm:ss", CultureInfo.InvariantCulture,
                                                       DateTimeStyles.AssumeLocal, out blockTime);

                                break;

                            case _kfName:
                                imageInfo.Application = kvp[1];

                                break;

                            case _kfVersion:
                                imageInfo.ApplicationVersion = kvp[1];

                                break;
                            }
                        }

                        if (foundDate)
                        {
                            var blockTimestamp = new DateTime(blockDate.Year, blockDate.Month, blockDate.Day,
                                                              blockTime.Hour, blockTime.Minute, blockTime.Second);

                            AaruConsole.DebugWriteLine("KryoFlux plugin", "Found timestamp: {0}", blockTimestamp);

                            if (blockTimestamp < Info.CreationTime)
                            {
                                imageInfo.CreationTime = blockTimestamp;
                            }

                            if (blockTimestamp > Info.LastModificationTime)
                            {
                                imageInfo.LastModificationTime = blockTimestamp;
                            }
                        }

                        break;
                    }

                    case (byte)BlockIds.Flux2:
                    case (byte)BlockIds.Flux2_1:
                    case (byte)BlockIds.Flux2_2:
                    case (byte)BlockIds.Flux2_3:
                    case (byte)BlockIds.Flux2_4:
                    case (byte)BlockIds.Flux2_5:
                    case (byte)BlockIds.Flux2_6:
                    case (byte)BlockIds.Flux2_7:
                    case (byte)BlockIds.Nop2:
                        trackStream.Position++;

                        continue;

                    case (byte)BlockIds.Nop3:
                    case (byte)BlockIds.Flux3:
                        trackStream.Position += 2;

                        continue;

                    default: continue;
                    }
                }

                tracks.Add(t, trackFilter);
            }

            imageInfo.Heads     = heads;
            imageInfo.Cylinders = (uint)(tracks.Count / heads);

            throw new NotImplementedException("Flux decoding is not yet implemented.");
        }