Ejemplo n.º 1
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);
            }

            // 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);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        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);
        }