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); }
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); }
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); }