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); } // TODO: Check this (ushort cylinders, byte heads, ushort sectorsPerTrack, uint bytesPerSector, MediaEncoding encoding, bool variableSectorsPerTrack, MediaType type)geometry = Geometry.GetGeometry(mediaType); footer = new DriFooter { signature = new byte[51], bpb = new DriBpb { five = 5, driveCode = DriDriveCodes.mf2ed, cylinders = geometry.cylinders, bps = (ushort)imageInfo.SectorSize, sectors = (ushort)imageInfo.Sectors, sptrack = (ushort)imageInfo.SectorsPerTrack, heads = (ushort)imageInfo.Heads, sptrack2 = (ushort)imageInfo.SectorsPerTrack, unknown5 = new byte[144] } }; Array.Copy(Encoding.ASCII.GetBytes("DiskImage 2.01 (C) 1990,1991 Digital Research Inc"), 0, footer.signature, 0, 49); footer.bpbcopy = footer.bpb; IsWriting = true; ErrorMessage = null; return(true); }
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); }
public bool Open(IFilter imageFilter) { Stream stream = imageFilter.GetDataForkStream(); if ((stream.Length - Marshal.SizeOf(typeof(DriFooter))) % 512 != 0) { return(false); } byte[] buffer = new byte[Marshal.SizeOf(typeof(DriFooter))]; stream.Seek(-buffer.Length, SeekOrigin.End); stream.Read(buffer, 0, buffer.Length); footer = new DriFooter(); IntPtr ftrPtr = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, ftrPtr, buffer.Length); footer = (DriFooter)Marshal.PtrToStructure(ftrPtr, typeof(DriFooter)); Marshal.FreeHGlobal(ftrPtr); string sig = StringHandlers.CToString(footer.signature); Regex regexSignature = new Regex(REGEX_DRI); Match matchSignature = regexSignature.Match(sig); if (!matchSignature.Success) { return(false); } if (footer.bpb.sptrack * footer.bpb.cylinders * footer.bpb.heads != footer.bpb.sectors) { return(false); } if (footer.bpb.sectors * footer.bpb.bps + Marshal.SizeOf(footer) != stream.Length) { return(false); } imageInfo.Cylinders = footer.bpb.cylinders; imageInfo.Heads = footer.bpb.heads; imageInfo.SectorsPerTrack = footer.bpb.sptrack; imageInfo.Sectors = footer.bpb.sectors; imageInfo.SectorSize = footer.bpb.bps; imageInfo.ApplicationVersion = matchSignature.Groups["version"].Value; driImageFilter = imageFilter; imageInfo.ImageSize = (ulong)(stream.Length - Marshal.SizeOf(footer)); imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "Image application = {0} version {1}", imageInfo.Application, imageInfo.ApplicationVersion); // Correct some incorrect data in images of NEC 2HD disks if (imageInfo.Cylinders == 77 && imageInfo.Heads == 2 && imageInfo.SectorsPerTrack == 16 && imageInfo.SectorSize == 512 && (footer.bpb.driveCode == DriDriveCodes.md2hd || footer.bpb.driveCode == DriDriveCodes.mf2hd)) { imageInfo.SectorsPerTrack = 8; imageInfo.SectorSize = 1024; } imageInfo.MediaType = Geometry.GetMediaType(((ushort)imageInfo.Cylinders, (byte)imageInfo.Heads, (ushort)imageInfo.SectorsPerTrack, imageInfo.SectorSize, MediaEncoding.MFM, false)); switch (imageInfo.MediaType) { case MediaType.NEC_525_HD when footer.bpb.driveCode == DriDriveCodes.mf2hd || footer.bpb.driveCode == DriDriveCodes.mf2ed: imageInfo.MediaType = MediaType.NEC_35_HD_8; break; case MediaType.DOS_525_HD when footer.bpb.driveCode == DriDriveCodes.mf2hd || footer.bpb.driveCode == DriDriveCodes.mf2ed: imageInfo.MediaType = MediaType.NEC_35_HD_15; break; case MediaType.RX50 when footer.bpb.driveCode == DriDriveCodes.md2dd || footer.bpb.driveCode == DriDriveCodes.md2hd: imageInfo.MediaType = MediaType.ATARI_35_SS_DD; break; } imageInfo.XmlMediaType = XmlMediaType.BlockMedia; DicConsole.VerboseWriteLine("Digital Research DiskCopy image contains a disk of type {0}", imageInfo.MediaType); return(true); }