示例#1
0
        public bool Identify(IFilter imageFilter)
        {
            Stream stream = imageFilter.GetDataForkStream();

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

            byte[] hdr = new byte[40];
            stream.Read(hdr, 0, 40);

            header = new SaveDskFHeader();
            IntPtr hdrPtr = Marshal.AllocHGlobal(40);

            Marshal.Copy(hdr, 0, hdrPtr, 40);
            header = (SaveDskFHeader)Marshal.PtrToStructure(hdrPtr, typeof(SaveDskFHeader));
            Marshal.FreeHGlobal(hdrPtr);

            return((header.magic == SDF_MAGIC || header.magic == SDF_MAGIC_COMPRESSED ||
                    header.magic == SDF_MAGIC_OLD) && header.fatCopies <= 2 && header.padding == 0 &&
                   header.commentOffset < stream.Length &&
                   header.dataOffset < stream.Length);
        }
示例#2
0
        public bool Create(string path, MediaType mediaType, Dictionary <string, string> options, ulong sectors,
                           uint sectorSize)
        {
            if (sectorSize == 0)
            {
                ErrorMessage = "Unsupported sector size";

                return(false);
            }

            if (sectors > ushort.MaxValue)
            {
                ErrorMessage = "Too many sectors";

                return(false);
            }

            if (!SupportedMediaTypes.Contains(mediaType))
            {
                ErrorMessage = $"Unsupport media format {mediaType}";

                return(false);
            }

            imageInfo = new ImageInfo
            {
                MediaType = mediaType, SectorSize = sectorSize, Sectors = sectors
            };

            try
            {
                writingStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
            }
            catch (IOException e)
            {
                ErrorMessage = $"Could not create new image file, exception {e.Message}";

                return(false);
            }

            (ushort cylinders, byte heads, ushort sectorsPerTrack, uint bytesPerSector, MediaEncoding encoding, bool
             variableSectorsPerTrack, MediaType type)geometry = Geometry.GetGeometry(mediaType);

            header = new SaveDskFHeader
            {
                cylinders     = geometry.cylinders, dataOffset = 512, heads = geometry.heads, magic = SDF_MAGIC,
                sectorsCopied = (ushort)sectors, sectorsPerTrack = geometry.sectorsPerTrack,
                sectorSize    = (ushort)sectorSize
            };

            IsWriting    = true;
            ErrorMessage = null;

            return(true);
        }
示例#3
0
        public bool Open(IFilter imageFilter)
        {
            Stream stream = imageFilter.GetDataForkStream();

            stream.Seek(0, SeekOrigin.Begin);

            byte[] hdr = new byte[40];

            stream.Read(hdr, 0, 40);
            header = new SaveDskFHeader();
            IntPtr hdrPtr = Marshal.AllocHGlobal(40);

            Marshal.Copy(hdr, 0, hdrPtr, 40);
            header = (SaveDskFHeader)Marshal.PtrToStructure(hdrPtr, typeof(SaveDskFHeader));
            Marshal.FreeHGlobal(hdrPtr);

            DicConsole.DebugWriteLine("SaveDskF plugin", "header.magic = 0x{0:X4}", header.magic);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.mediaType = 0x{0:X2}", header.mediaType);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorSize = {0}", header.sectorSize);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.clusterMask = {0}", header.clusterMask);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.clusterShift = {0}", header.clusterShift);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.reservedSectors = {0}", header.reservedSectors);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.fatCopies = {0}", header.fatCopies);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.rootEntries = {0}", header.rootEntries);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.firstCluster = {0}", header.firstCluster);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.clustersCopied = {0}", header.clustersCopied);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorsPerFat = {0}", header.sectorsPerFat);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.checksum = 0x{0:X8}", header.checksum);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.cylinders = {0}", header.cylinders);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.heads = {0}", header.heads);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorsPerTrack = {0}", header.sectorsPerTrack);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.padding = {0}", header.padding);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorsCopied = {0}", header.sectorsCopied);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.commentOffset = {0}", header.commentOffset);
            DicConsole.DebugWriteLine("SaveDskF plugin", "header.dataOffset = {0}", header.dataOffset);

            if (header.dataOffset == 0 && header.magic == SDF_MAGIC_OLD)
            {
                header.dataOffset = 512;
            }

            byte[] cmt = new byte[header.dataOffset - header.commentOffset];
            stream.Seek(header.commentOffset, SeekOrigin.Begin);
            stream.Read(cmt, 0, cmt.Length);
            if (cmt.Length > 1)
            {
                imageInfo.Comments = StringHandlers.CToString(cmt, Encoding.GetEncoding("ibm437"));
            }

            calculatedChk = 0;
            stream.Seek(0, SeekOrigin.Begin);

            int b;

            do
            {
                b = stream.ReadByte();
                if (b >= 0)
                {
                    calculatedChk += (uint)b;
                }
            }while(b >= 0);

            DicConsole.DebugWriteLine("SaveDskF plugin", "Calculated checksum = 0x{0:X8}, {1}", calculatedChk,
                                      calculatedChk == header.checksum);

            imageInfo.Application          = "SaveDskF";
            imageInfo.CreationTime         = imageFilter.GetCreationTime();
            imageInfo.LastModificationTime = imageFilter.GetLastWriteTime();
            imageInfo.MediaTitle           = imageFilter.GetFilename();
            imageInfo.ImageSize            = (ulong)(stream.Length - header.dataOffset);
            imageInfo.Sectors    = (ulong)(header.sectorsPerTrack * header.heads * header.cylinders);
            imageInfo.SectorSize = header.sectorSize;

            imageInfo.MediaType = Geometry.GetMediaType((header.cylinders, (byte)header.heads, header.sectorsPerTrack,
                                                         header.sectorSize, MediaEncoding.MFM, false));

            imageInfo.XmlMediaType = XmlMediaType.BlockMedia;

            DicConsole.VerboseWriteLine("SaveDskF image contains a disk of type {0}", imageInfo.MediaType);
            if (!string.IsNullOrEmpty(imageInfo.Comments))
            {
                DicConsole.VerboseWriteLine("SaveDskF comments: {0}", imageInfo.Comments);
            }

            // TODO: Support compressed images
            if (header.magic == SDF_MAGIC_COMPRESSED)
            {
                throw new
                      FeatureSupportedButNotImplementedImageException("Compressed SaveDskF images are not supported.");
            }

            // SaveDskF only ommits ending clusters, leaving no gaps behind, so reading all data we have...
            stream.Seek(header.dataOffset, SeekOrigin.Begin);
            decodedDisk = new byte[imageInfo.Sectors * imageInfo.SectorSize];
            stream.Read(decodedDisk, 0, (int)(stream.Length - header.dataOffset));

            imageInfo.Cylinders       = header.cylinders;
            imageInfo.Heads           = header.heads;
            imageInfo.SectorsPerTrack = header.sectorsPerTrack;

            return(true);
        }