private static byte[] extractFileFromPartition(IOpticalMediaImage opticalImage, Partition partition, string fileName)
        {
            var iso = new ISO9660();

            try
            {
                //string information;
                //iso.GetInformation(opticalImage, partition, out information, Encoding.ASCII);

                var dict = new Dictionary <string, string>();
                iso.Mount(opticalImage, partition, Encoding.ASCII, dict, "normal");
                //System.Collections.Generic.List<string> strlist = null;
                //iso.ReadDir("/", out strlist);

                if (iso.Stat(fileName, out var stat) == Aaru.CommonTypes.Structs.Errno.NoError && stat.Length > 0)
                {
                    //file exists
                    var buff = new byte[stat.Length];
                    iso.Read(fileName, 0, stat.Length, ref buff);
                    return(buff);
                }
            }
            finally
            {
                iso.Unmount();
            }
            return(null);
        }
        public frmImageEntropy(IMediaImage inputFormat)
        {
            this.inputFormat = inputFormat;
            XamlReader.Load(this);

            IOpticalMediaImage inputOptical = inputFormat as IOpticalMediaImage;

            if (inputOptical?.Tracks != null && inputOptical?.Tracks.Count > 0)
            {
                chkSeparatedTracks.Visible = true;
                chkWholeDisc.Visible       = true;
            }
            else
            {
                chkSeparatedTracks.Checked = false;
                chkWholeDisc.Checked       = true;
            }
        }
Beispiel #3
0
        /// <summary>Creates a metadata sidecar for an optical disc (e.g. CD, DVD, GD, BD, XGD, GOD)</summary>
        /// <param name="image">Image</param>
        /// <param name="filterId">Filter uuid</param>
        /// <param name="imagePath">Image path</param>
        /// <param name="fi">Image file information</param>
        /// <param name="plugins">Image plugins</param>
        /// <param name="imgChecksums">List of image checksums</param>
        /// <param name="sidecar">Metadata sidecar</param>
        void OpticalDisc(IOpticalMediaImage image, Guid filterId, string imagePath, FileInfo fi, PluginBase plugins,
                         List <ChecksumType> imgChecksums, ref CICMMetadataType sidecar, Encoding encoding)
        {
            if (aborted)
            {
                return;
            }

            sidecar.OpticalDisc = new[]
            {
                new OpticalDiscType
                {
                    Checksums = imgChecksums.ToArray(), Image = new ImageType
                    {
                        format = image.Format, offset = 0, offsetSpecified = true, Value = Path.GetFileName(imagePath)
                    },
                    Size = (ulong)fi.Length, Sequence = new SequenceType
                    {
                        MediaTitle = image.Info.MediaTitle
                    }
                }
            };

            if (image.Info.MediaSequence != 0 &&
                image.Info.LastMediaSequence != 0)
            {
                sidecar.OpticalDisc[0].Sequence.MediaSequence = (uint)image.Info.MediaSequence;
                sidecar.OpticalDisc[0].Sequence.TotalMedia    = (uint)image.Info.LastMediaSequence;
            }
            else
            {
                sidecar.OpticalDisc[0].Sequence.MediaSequence = 1;
                sidecar.OpticalDisc[0].Sequence.TotalMedia    = 1;
            }

            MediaType dskType = image.Info.MediaType;

            UpdateStatus("Hashing media tags...");

            foreach (MediaTagType tagType in image.Info.ReadableMediaTags)
            {
                if (aborted)
                {
                    return;
                }

                switch (tagType)
                {
                case MediaTagType.CD_ATIP:
                    sidecar.OpticalDisc[0].ATIP = new DumpType
                    {
                        Image     = Path.GetFileName(imagePath),
                        Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.CD_ATIP)).ToArray(),
                        Size      = (ulong)image.ReadDiskTag(MediaTagType.CD_ATIP).Length
                    };

                    ATIP.CDATIP?atip = ATIP.Decode(image.ReadDiskTag(MediaTagType.CD_ATIP));

                    if (atip.HasValue)
                    {
                        if (atip.Value.DDCD)
                        {
                            dskType = atip.Value.DiscType ? MediaType.DDCDRW : MediaType.DDCDR;
                        }
                        else
                        {
                            dskType = atip.Value.DiscType ? MediaType.CDRW : MediaType.CDR;
                        }
                    }

                    break;

                case MediaTagType.DVD_BCA:
                    sidecar.OpticalDisc[0].BCA = new DumpType
                    {
                        Image     = Path.GetFileName(imagePath),
                        Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.DVD_BCA)).ToArray(),
                        Size      = (ulong)image.ReadDiskTag(MediaTagType.DVD_BCA).Length
                    };

                    break;

                case MediaTagType.BD_BCA:
                    sidecar.OpticalDisc[0].BCA = new DumpType
                    {
                        Image     = Path.GetFileName(imagePath),
                        Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.BD_BCA)).ToArray(),
                        Size      = (ulong)image.ReadDiskTag(MediaTagType.BD_BCA).Length
                    };

                    break;

                case MediaTagType.DVD_CMI:
                    sidecar.OpticalDisc[0].CMI = new DumpType
                    {
                        Image     = Path.GetFileName(imagePath),
                        Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.DVD_CMI)).ToArray(),
                        Size      = (ulong)image.ReadDiskTag(MediaTagType.DVD_CMI).Length
                    };

                    CSS_CPRM.LeadInCopyright?cmi =
                        CSS_CPRM.DecodeLeadInCopyright(image.ReadDiskTag(MediaTagType.DVD_CMI));

                    if (cmi.HasValue)
                    {
                        switch (cmi.Value.CopyrightType)
                        {
                        case CopyrightType.AACS:
                            sidecar.OpticalDisc[0].CopyProtection = "AACS";

                            break;

                        case CopyrightType.CSS:
                            sidecar.OpticalDisc[0].CopyProtection = "CSS";

                            break;

                        case CopyrightType.CPRM:
                            sidecar.OpticalDisc[0].CopyProtection = "CPRM";

                            break;
                        }
                    }

                    break;

                case MediaTagType.DVD_DMI:
                    sidecar.OpticalDisc[0].DMI = new DumpType
                    {
                        Image     = Path.GetFileName(imagePath),
                        Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.DVD_DMI)).ToArray(),
                        Size      = (ulong)image.ReadDiskTag(MediaTagType.DVD_DMI).Length
                    };

                    if (DMI.IsXbox(image.ReadDiskTag(MediaTagType.DVD_DMI)))
                    {
                        dskType = MediaType.XGD;

                        sidecar.OpticalDisc[0].Dimensions = new DimensionsType
                        {
                            Diameter = 120, Thickness = 1.2
                        };
                    }
                    else if (DMI.IsXbox360(image.ReadDiskTag(MediaTagType.DVD_DMI)))
                    {
                        dskType = MediaType.XGD2;

                        sidecar.OpticalDisc[0].Dimensions = new DimensionsType
                        {
                            Diameter = 120, Thickness = 1.2
                        };
                    }

                    break;

                case MediaTagType.DVD_PFI:
                    sidecar.OpticalDisc[0].PFI = new DumpType
                    {
                        Image     = Path.GetFileName(imagePath),
                        Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.DVD_PFI)).ToArray(),
                        Size      = (ulong)image.ReadDiskTag(MediaTagType.DVD_PFI).Length
                    };

                    PFI.PhysicalFormatInformation?pfi = PFI.Decode(image.ReadDiskTag(MediaTagType.DVD_PFI));

                    if (pfi.HasValue)
                    {
                        if (dskType != MediaType.XGD &&
                            dskType != MediaType.XGD2 &&
                            dskType != MediaType.XGD3 &&
                            dskType != MediaType.PS2DVD &&
                            dskType != MediaType.PS3DVD &&
                            dskType != MediaType.Nuon)
                        {
                            switch (pfi.Value.DiskCategory)
                            {
                            case DiskCategory.DVDPR:
                                dskType = MediaType.DVDPR;

                                break;

                            case DiskCategory.DVDPRDL:
                                dskType = MediaType.DVDPRDL;

                                break;

                            case DiskCategory.DVDPRW:
                                dskType = MediaType.DVDPRW;

                                break;

                            case DiskCategory.DVDPRWDL:
                                dskType = MediaType.DVDPRWDL;

                                break;

                            case DiskCategory.DVDR:
                                dskType = MediaType.DVDR;

                                break;

                            case DiskCategory.DVDRAM:
                                dskType = MediaType.DVDRAM;

                                break;

                            case DiskCategory.DVDROM:
                                dskType = MediaType.DVDROM;

                                break;

                            case DiskCategory.DVDRW:
                                dskType = MediaType.DVDRW;

                                break;

                            case DiskCategory.HDDVDR:
                                dskType = MediaType.HDDVDR;

                                break;

                            case DiskCategory.HDDVDRAM:
                                dskType = MediaType.HDDVDRAM;

                                break;

                            case DiskCategory.HDDVDROM:
                                dskType = MediaType.HDDVDROM;

                                break;

                            case DiskCategory.HDDVDRW:
                                dskType = MediaType.HDDVDRW;

                                break;

                            case DiskCategory.Nintendo:
                                dskType = MediaType.GOD;

                                break;

                            case DiskCategory.UMD:
                                dskType = MediaType.UMD;

                                break;
                            }

                            if (dskType == MediaType.DVDR &&
                                pfi.Value.PartVersion == 6)
                            {
                                dskType = MediaType.DVDRDL;
                            }

                            if (dskType == MediaType.DVDRW &&
                                pfi.Value.PartVersion == 3)
                            {
                                dskType = MediaType.DVDRWDL;
                            }

                            if (dskType == MediaType.GOD &&
                                pfi.Value.DiscSize == DVDSize.OneTwenty)
                            {
                                dskType = MediaType.WOD;
                            }

                            sidecar.OpticalDisc[0].Dimensions = new DimensionsType();

                            if (dskType == MediaType.UMD)
                            {
                                sidecar.OpticalDisc[0].Dimensions.Height          = 64;
                                sidecar.OpticalDisc[0].Dimensions.HeightSpecified = true;
                                sidecar.OpticalDisc[0].Dimensions.Width           = 63;
                                sidecar.OpticalDisc[0].Dimensions.WidthSpecified  = true;
                                sidecar.OpticalDisc[0].Dimensions.Thickness       = 4;
                            }
                            else
                            {
                                switch (pfi.Value.DiscSize)
                                {
                                case DVDSize.Eighty:
                                    sidecar.OpticalDisc[0].Dimensions.Diameter          = 80;
                                    sidecar.OpticalDisc[0].Dimensions.DiameterSpecified = true;
                                    sidecar.OpticalDisc[0].Dimensions.Thickness         = 1.2;

                                    break;

                                case DVDSize.OneTwenty:
                                    sidecar.OpticalDisc[0].Dimensions.Diameter          = 120;
                                    sidecar.OpticalDisc[0].Dimensions.DiameterSpecified = true;
                                    sidecar.OpticalDisc[0].Dimensions.Thickness         = 1.2;

                                    break;
                                }
                            }
                        }
                    }

                    break;

                case MediaTagType.CD_PMA:
                    sidecar.OpticalDisc[0].PMA = new DumpType
                    {
                        Image     = Path.GetFileName(imagePath),
                        Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.CD_PMA)).ToArray(),
                        Size      = (ulong)image.ReadDiskTag(MediaTagType.CD_PMA).Length
                    };

                    break;

                case MediaTagType.CD_FullTOC:
                    sidecar.OpticalDisc[0].TOC = new DumpType
                    {
                        Image     = Path.GetFileName(imagePath),
                        Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.CD_FullTOC)).ToArray(),
                        Size      = (ulong)image.ReadDiskTag(MediaTagType.CD_FullTOC).Length
                    };

                    break;

                case MediaTagType.CD_FirstTrackPregap:
                    sidecar.OpticalDisc[0].FirstTrackPregrap = new[]
                    {
                        new BorderType
                        {
                            Image     = Path.GetFileName(imagePath),
                            Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.CD_FirstTrackPregap)).
                                        ToArray(),
                            Size = (ulong)image.ReadDiskTag(MediaTagType.CD_FirstTrackPregap).Length
                        }
                    };

                    break;

                case MediaTagType.CD_LeadIn:
                    sidecar.OpticalDisc[0].LeadIn = new[]
                    {
                        new BorderType
                        {
                            Image     = Path.GetFileName(imagePath),
                            Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.CD_LeadIn)).ToArray(),
                            Size      = (ulong)image.ReadDiskTag(MediaTagType.CD_LeadIn).Length
                        }
                    };

                    break;

                case MediaTagType.Xbox_SecuritySector:
                    if (sidecar.OpticalDisc[0].Xbox == null)
                    {
                        sidecar.OpticalDisc[0].Xbox = new XboxType();
                    }

                    sidecar.OpticalDisc[0].Xbox.SecuritySectors = new[]
                    {
                        new XboxSecuritySectorsType
                        {
                            RequestNumber = 0, RequestVersion = 1, SecuritySectors = new DumpType
                            {
                                Image     = Path.GetFileName(imagePath),
                                Checksums = Checksum.
                                            GetChecksums(image.ReadDiskTag(MediaTagType.Xbox_SecuritySector)).
                                            ToArray(),
                                Size = (ulong)image.ReadDiskTag(MediaTagType.Xbox_SecuritySector).Length
                            }
                        }
                    };

                    break;

                case MediaTagType.Xbox_PFI:
                    if (sidecar.OpticalDisc[0].Xbox == null)
                    {
                        sidecar.OpticalDisc[0].Xbox = new XboxType();
                    }

                    sidecar.OpticalDisc[0].Xbox.PFI = new DumpType
                    {
                        Image     = Path.GetFileName(imagePath),
                        Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.Xbox_PFI)).ToArray(),
                        Size      = (ulong)image.ReadDiskTag(MediaTagType.Xbox_PFI).Length
                    };

                    break;

                case MediaTagType.Xbox_DMI:
                    if (sidecar.OpticalDisc[0].Xbox == null)
                    {
                        sidecar.OpticalDisc[0].Xbox = new XboxType();
                    }

                    sidecar.OpticalDisc[0].Xbox.DMI = new DumpType
                    {
                        Image     = Path.GetFileName(imagePath),
                        Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.Xbox_DMI)).ToArray(),
                        Size      = (ulong)image.ReadDiskTag(MediaTagType.Xbox_DMI).Length
                    };

                    break;
                }
            }

            try
            {
                List <Session> sessions = image.Sessions;
                sidecar.OpticalDisc[0].Sessions = (uint)(sessions?.Count ?? 1);
            }
            catch
            {
                sidecar.OpticalDisc[0].Sessions = 1;
            }

            List <Track>     tracks  = image.Tracks;
            List <TrackType> trksLst = null;

            if (tracks != null)
            {
                sidecar.OpticalDisc[0].Tracks    = new uint[1];
                sidecar.OpticalDisc[0].Tracks[0] = (uint)tracks.Count;
                trksLst = new List <TrackType>();
            }

            if (sidecar.OpticalDisc[0].Dimensions == null &&
                image.Info.MediaType != MediaType.Unknown)
            {
                sidecar.OpticalDisc[0].Dimensions = Dimensions.DimensionsFromMediaType(image.Info.MediaType);
            }

            if (aborted)
            {
                return;
            }

            InitProgress();

            UpdateStatus("Checking filesystems");
            List <Partition> partitions = Partitions.GetAll(image);

            Partitions.AddSchemesToStats(partitions);

            UpdateStatus("Hashing tracks...");

            foreach (Track trk in tracks)
            {
                if (aborted)
                {
                    EndProgress();

                    return;
                }

                var xmlTrk = new TrackType();

                switch (trk.TrackType)
                {
                case CommonTypes.Enums.TrackType.Audio:
                    xmlTrk.TrackType1 = TrackTypeTrackType.audio;

                    break;

                case CommonTypes.Enums.TrackType.CdMode2Form2:
                    xmlTrk.TrackType1 = TrackTypeTrackType.m2f2;

                    break;

                case CommonTypes.Enums.TrackType.CdMode2Formless:
                    xmlTrk.TrackType1 = TrackTypeTrackType.mode2;

                    break;

                case CommonTypes.Enums.TrackType.CdMode2Form1:
                    xmlTrk.TrackType1 = TrackTypeTrackType.m2f1;

                    break;

                case CommonTypes.Enums.TrackType.CdMode1:
                    xmlTrk.TrackType1 = TrackTypeTrackType.mode1;

                    break;

                case CommonTypes.Enums.TrackType.Data:
                    switch (sidecar.OpticalDisc[0].DiscType)
                    {
                    case "BD":
                        xmlTrk.TrackType1 = TrackTypeTrackType.bluray;

                        break;

                    case "DDCD":
                        xmlTrk.TrackType1 = TrackTypeTrackType.ddcd;

                        break;

                    case "DVD":
                        xmlTrk.TrackType1 = TrackTypeTrackType.dvd;

                        break;

                    case "HD DVD":
                        xmlTrk.TrackType1 = TrackTypeTrackType.hddvd;

                        break;

                    default:
                        xmlTrk.TrackType1 = TrackTypeTrackType.mode1;

                        break;
                    }

                    break;
                }

                xmlTrk.Sequence = new TrackSequenceType
                {
                    Session = trk.TrackSession, TrackNumber = trk.TrackSequence
                };

                xmlTrk.StartSector = trk.TrackStartSector;
                xmlTrk.EndSector   = trk.TrackEndSector;

                if (trk.Indexes != null &&
                    trk.Indexes.ContainsKey(0))
                {
                    if (trk.Indexes.TryGetValue(0, out ulong idx0))
                    {
                        xmlTrk.StartSector = idx0;
                    }
                }

                switch (sidecar.OpticalDisc[0].DiscType)
                {
                case "CD":
                case "GD":
                    xmlTrk.StartMSF = LbaToMsf((long)xmlTrk.StartSector);
                    xmlTrk.EndMSF   = LbaToMsf((long)xmlTrk.EndSector);

                    break;

                case "DDCD":
                    xmlTrk.StartMSF = DdcdLbaToMsf((long)xmlTrk.StartSector);
                    xmlTrk.EndMSF   = DdcdLbaToMsf((long)xmlTrk.EndSector);

                    break;
                }

                xmlTrk.Image = new ImageType
                {
                    Value = Path.GetFileName(trk.TrackFile), format = trk.TrackFileType
                };

                if (trk.TrackFileOffset > 0)
                {
                    xmlTrk.Image.offset          = trk.TrackFileOffset;
                    xmlTrk.Image.offsetSpecified = true;
                }

                xmlTrk.Size = ((xmlTrk.EndSector - xmlTrk.StartSector) + 1) * (ulong)trk.TrackRawBytesPerSector;

                xmlTrk.BytesPerSector = (uint)trk.TrackBytesPerSector;

                uint  sectorsToRead = 512;
                ulong sectors       = (xmlTrk.EndSector - xmlTrk.StartSector) + 1;
                ulong doneSectors   = 0;

                // If there is only one track, and it's the same as the image file (e.g. ".iso" files), don't re-checksum.
                if (image.Id == new Guid("12345678-AAAA-BBBB-CCCC-123456789000") &&

                    // Only if filter is none...
                    (filterId == new Guid("12345678-AAAA-BBBB-CCCC-123456789000") ||

                     // ...or AppleDouble
                     filterId == new Guid("1b2165ee-c9df-4b21-bbbb-9e5892b2df4d")))
                {
                    xmlTrk.Checksums = sidecar.OpticalDisc[0].Checksums;
                }
                else
                {
                    UpdateProgress("Track {0} of {1}", trk.TrackSequence, tracks.Count);

                    // For fast debugging, skip checksum
                    //goto skipChecksum;

                    var trkChkWorker = new Checksum();

                    InitProgress2();

                    while (doneSectors < sectors)
                    {
                        if (aborted)
                        {
                            EndProgress();
                            EndProgress2();

                            return;
                        }

                        byte[] sector;

                        if (sectors - doneSectors >= sectorsToRead)
                        {
                            sector = image.ReadSectorsLong(doneSectors, sectorsToRead, xmlTrk.Sequence.TrackNumber);

                            UpdateProgress2("Hashings sector {0} of {1}", (long)doneSectors,
                                            (long)((trk.TrackEndSector - trk.TrackStartSector) + 1));

                            doneSectors += sectorsToRead;
                        }
                        else
                        {
                            sector = image.ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors),
                                                           xmlTrk.Sequence.TrackNumber);

                            UpdateProgress2("Hashings sector {0} of {1}", (long)doneSectors,
                                            (long)((trk.TrackEndSector - trk.TrackStartSector) + 1));

                            doneSectors += sectors - doneSectors;
                        }

                        trkChkWorker.Update(sector);
                    }

                    List <ChecksumType> trkChecksums = trkChkWorker.End();

                    xmlTrk.Checksums = trkChecksums.ToArray();

                    EndProgress2();
                }

                if (trk.TrackSubchannelType != TrackSubchannelType.None)
                {
                    xmlTrk.SubChannel = new SubChannelType
                    {
                        Image = new ImageType
                        {
                            Value = trk.TrackSubchannelFile
                        },

                        // TODO: Packed subchannel has different size?
                        Size = ((xmlTrk.EndSector - xmlTrk.StartSector) + 1) * 96
                    };

                    switch (trk.TrackSubchannelType)
                    {
                    case TrackSubchannelType.Packed:
                    case TrackSubchannelType.PackedInterleaved:
                        xmlTrk.SubChannel.Image.format = "rw";

                        break;

                    case TrackSubchannelType.Raw:
                    case TrackSubchannelType.RawInterleaved:
                        xmlTrk.SubChannel.Image.format = "rw_raw";

                        break;

                    case TrackSubchannelType.Q16:
                    case TrackSubchannelType.Q16Interleaved:
                        xmlTrk.SubChannel.Image.format = "q16";

                        break;
                    }

                    if (trk.TrackFileOffset > 0)
                    {
                        xmlTrk.SubChannel.Image.offset          = trk.TrackSubchannelOffset;
                        xmlTrk.SubChannel.Image.offsetSpecified = true;
                    }

                    var subChkWorker = new Checksum();

                    sectors     = (xmlTrk.EndSector - xmlTrk.StartSector) + 1;
                    doneSectors = 0;

                    InitProgress2();

                    while (doneSectors < sectors)
                    {
                        if (aborted)
                        {
                            EndProgress();
                            EndProgress2();

                            return;
                        }

                        byte[] sector;

                        if (sectors - doneSectors >= sectorsToRead)
                        {
                            sector = image.ReadSectorsTag(doneSectors, sectorsToRead, xmlTrk.Sequence.TrackNumber,
                                                          SectorTagType.CdSectorSubchannel);

                            UpdateProgress2("Hashings subchannel sector {0} of {1}", (long)doneSectors,
                                            (long)((trk.TrackEndSector - trk.TrackStartSector) + 1));

                            doneSectors += sectorsToRead;
                        }
                        else
                        {
                            sector = image.ReadSectorsTag(doneSectors, (uint)(sectors - doneSectors),
                                                          xmlTrk.Sequence.TrackNumber,
                                                          SectorTagType.CdSectorSubchannel);

                            UpdateProgress2("Hashings subchannel sector {0} of {1}", (long)doneSectors,
                                            (long)((trk.TrackEndSector - trk.TrackStartSector) + 1));

                            doneSectors += sectors - doneSectors;
                        }

                        subChkWorker.Update(sector);
                    }

                    List <ChecksumType> subChecksums = subChkWorker.End();

                    xmlTrk.SubChannel.Checksums = subChecksums.ToArray();

                    EndProgress2();
                }

                // For fast debugging, skip checksum
                //skipChecksum:

                List <Partition> trkPartitions = partitions.
                                                 Where(p => p.Start >= trk.TrackStartSector &&
                                                       p.End <= trk.TrackEndSector).ToList();

                xmlTrk.FileSystemInformation = new PartitionType[1];

                if (trkPartitions.Count > 0)
                {
                    xmlTrk.FileSystemInformation = new PartitionType[trkPartitions.Count];

                    for (int i = 0; i < trkPartitions.Count; i++)
                    {
                        xmlTrk.FileSystemInformation[i] = new PartitionType
                        {
                            Description = trkPartitions[i].Description, EndSector = trkPartitions[i].End,
                            Name        = trkPartitions[i].Name, Sequence = (uint)trkPartitions[i].Sequence,
                            StartSector = trkPartitions[i].Start, Type = trkPartitions[i].Type
                        };

                        List <FileSystemType> lstFs = new List <FileSystemType>();

                        foreach (IFilesystem plugin in plugins.PluginsList.Values)
                        {
                            try
                            {
                                if (aborted)
                                {
                                    EndProgress();

                                    return;
                                }

                                if (!plugin.Identify(image, trkPartitions[i]))
                                {
                                    continue;
                                }

                                plugin.GetInformation(image, trkPartitions[i], out _, encoding);
                                lstFs.Add(plugin.XmlFsType);
                                Statistics.AddFilesystem(plugin.XmlFsType.Type);

                                switch (plugin.XmlFsType.Type)
                                {
                                case "Opera":
                                    dskType = MediaType.ThreeDO;

                                    break;

                                case "PC Engine filesystem":
                                    dskType = MediaType.SuperCDROM2;

                                    break;

                                case "Nintendo Wii filesystem":
                                    dskType = MediaType.WOD;

                                    break;

                                case "Nintendo Gamecube filesystem":
                                    dskType = MediaType.GOD;

                                    break;
                                }
                            }
                        }
Beispiel #4
0
        public void Test()
        {
            // How many sectors to read at once
            const uint sectorsToRead = 256;

            Environment.CurrentDirectory =
                Path.Combine(Consts.TEST_FILES_ROOT, "Media image formats", "MagicISO", "Cuesheet");

            IFilter[] filters = new IFilter[_testFiles.Length];

            for (int i = 0; i < _testFiles.Length; i++)
            {
                filters[i] = new ZZZNoFilter();
                filters[i].Open(_testFiles[i]);
            }

            IOpticalMediaImage[] images = new IOpticalMediaImage[_testFiles.Length];

            for (int i = 0; i < _testFiles.Length; i++)
            {
                images[i] = new CdrWin();
                Assert.AreEqual(true, images[i].Open(filters[i]), $"Open: {_testFiles[i]}");
            }

            for (int i = 0; i < _testFiles.Length; i++)
            {
                Assert.AreEqual(_sectors[i], images[i].Info.Sectors, $"Sectors: {_testFiles[i]}");
            }

            for (int i = 0; i < _testFiles.Length; i++)
            {
                Assert.AreEqual(_mediaTypes[i], images[i].Info.MediaType, $"Media type: {_testFiles[i]}");
            }

            for (int i = 0; i < _testFiles.Length; i++)
            {
                Assert.AreEqual(_tracks[i], images[i].Tracks.Count, $"Tracks: {_testFiles[i]}");
            }

            for (int i = 0; i < _testFiles.Length; i++)
            {
                images[i].Tracks.Select(t => t.TrackSession).Should().
                BeEquivalentTo(_trackSessions[i], $"Track session: {_testFiles[i]}");
            }

            for (int i = 0; i < _testFiles.Length; i++)
            {
                images[i].Tracks.Select(t => t.TrackStartSector).Should().
                BeEquivalentTo(_trackStarts[i], $"Track start: {_testFiles[i]}");
            }

            for (int i = 0; i < _testFiles.Length; i++)
            {
                images[i].Tracks.Select(t => t.TrackEndSector).Should().
                BeEquivalentTo(_trackEnds[i], $"Track end: {_testFiles[i]}");
            }

            for (int i = 0; i < _testFiles.Length; i++)
            {
                images[i].Tracks.Select(t => t.TrackPregap).Should().
                BeEquivalentTo(_trackPregaps[i], $"Track pregap: {_testFiles[i]}");
            }

            for (int i = 0; i < _testFiles.Length; i++)
            {
                int trackNo = 0;

                foreach (Track currentTrack in images[i].Tracks)
                {
                    if (images[i].Info.ReadableSectorTags.Contains(SectorTagType.CdTrackFlags))
                    {
                        Assert.AreEqual(_trackFlags[i][trackNo],
                                        images[i].ReadSectorTag(currentTrack.TrackSequence, SectorTagType.CdTrackFlags)
                                        [0], $"Track flags: {_testFiles[i]}, track {currentTrack.TrackSequence}");
                    }

                    trackNo++;
                }
            }

            foreach (bool @long in new[]
            {
                false, true
            })
            {
                for (int i = 0; i < _testFiles.Length; i++)
                {
                    var ctx = new Md5Context();

                    foreach (Track currentTrack in images[i].Tracks)
                    {
                        ulong sectors     = currentTrack.TrackEndSector - currentTrack.TrackStartSector + 1;
                        ulong doneSectors = 0;

                        while (doneSectors < sectors)
                        {
                            byte[] sector;

                            if (sectors - doneSectors >= sectorsToRead)
                            {
                                sector = @long ? images[i].
                                         ReadSectorsLong(doneSectors, sectorsToRead, currentTrack.TrackSequence)
                                             : images[i].
                                         ReadSectors(doneSectors, sectorsToRead, currentTrack.TrackSequence);

                                doneSectors += sectorsToRead;
                            }
                            else
                            {
                                sector = @long ? images[i].ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors),
                                                                           currentTrack.TrackSequence)
                                             : images[i].ReadSectors(doneSectors, (uint)(sectors - doneSectors),
                                                                     currentTrack.TrackSequence);

                                doneSectors += sectors - doneSectors;
                            }

                            ctx.Update(sector);
                        }
                    }

                    Assert.AreEqual(@long ? _longMd5S[i] : _md5S[i], ctx.End(),
                                    $"{(@long ? "Long hash" : "Hash")}: {_testFiles[i]}");
                }
            }

            for (int i = 0; i < _testFiles.Length; i++)
            {
                if (images[i].Info.ReadableSectorTags.Contains(SectorTagType.CdSectorSubchannel))
                {
                    var ctx = new Md5Context();

                    foreach (Track currentTrack in images[i].Tracks)
                    {
                        ulong sectors     = currentTrack.TrackEndSector - currentTrack.TrackStartSector + 1;
                        ulong doneSectors = 0;

                        while (doneSectors < sectors)
                        {
                            byte[] sector;

                            if (sectors - doneSectors >= sectorsToRead)
                            {
                                sector = images[i].ReadSectorsTag(doneSectors, sectorsToRead,
                                                                  currentTrack.TrackSequence,
                                                                  SectorTagType.CdSectorSubchannel);

                                doneSectors += sectorsToRead;
                            }
                            else
                            {
                                sector = images[i].ReadSectorsTag(doneSectors, (uint)(sectors - doneSectors),
                                                                  currentTrack.TrackSequence,
                                                                  SectorTagType.CdSectorSubchannel);

                                doneSectors += sectors - doneSectors;
                            }

                            ctx.Update(sector);
                        }
                    }

                    Assert.AreEqual(_subchannelMd5S[i], ctx.End(), $"Subchannel hash: {_testFiles[i]}");
                }
            }
        }
        void DoWork()
        {
            IOpticalMediaImage opticalMediaImage = inputFormat as IOpticalMediaImage;
            bool formatHasTracks = false;

            if (opticalMediaImage != null)
            {
                try { formatHasTracks = opticalMediaImage.Tracks?.Count > 0; }
                catch { formatHasTracks = false; }
            }

            // Setup progress bars
            Application.Instance.Invoke(() =>
            {
                stkProgress.Visible   = true;
                prgProgress.MaxValue  = 1;
                prgProgress2.MaxValue = (int)(inputFormat.Info.Sectors / SECTORS_TO_READ);

                if (formatHasTracks && chkChecksumTracks.Checked == true && opticalMediaImage != null)
                {
                    prgProgress.MaxValue += opticalMediaImage.Tracks.Count;
                }
                else
                {
                    prgProgress.MaxValue = 2;
                    prgProgress2.Visible = false;
                    lblProgress2.Visible = false;
                }
            });

            EnableChecksum enabledChecksums = new EnableChecksum();

            if (chkAdler32.Checked == true)
            {
                enabledChecksums |= EnableChecksum.Adler32;
            }
            if (chkCrc16.Checked == true)
            {
                enabledChecksums |= EnableChecksum.Crc16;
            }
            if (chkCrc32.Checked == true)
            {
                enabledChecksums |= EnableChecksum.Crc32;
            }
            if (chkCrc64.Checked == true)
            {
                enabledChecksums |= EnableChecksum.Crc64;
            }
            if (chkMd5.Checked == true)
            {
                enabledChecksums |= EnableChecksum.Md5;
            }
            if (chkSha1.Checked == true)
            {
                enabledChecksums |= EnableChecksum.Sha1;
            }
            if (chkSha256.Checked == true)
            {
                enabledChecksums |= EnableChecksum.Sha256;
            }
            if (chkSha384.Checked == true)
            {
                enabledChecksums |= EnableChecksum.Sha384;
            }
            if (chkSha512.Checked == true)
            {
                enabledChecksums |= EnableChecksum.Sha512;
            }
            if (chkSpamsum.Checked == true)
            {
                enabledChecksums |= EnableChecksum.SpamSum;
            }
            if (chkFletcher16.Checked == true)
            {
                enabledChecksums |= EnableChecksum.Fletcher16;
            }
            if (chkFletcher32.Checked == true)
            {
                enabledChecksums |= EnableChecksum.Fletcher32;
            }

            Checksum mediaChecksum = null;

            TreeGridItemCollection trackHashes = new TreeGridItemCollection();
            TreeGridItemCollection mediaHashes = new TreeGridItemCollection();

            if (opticalMediaImage != null)
            {
                try
                {
                    Checksum trackChecksum = null;

                    if (chkChecksumMedia.Checked == true)
                    {
                        mediaChecksum = new Checksum(enabledChecksums);
                    }

                    ulong previousTrackEnd = 0;

                    foreach (Track currentTrack in opticalMediaImage.Tracks)
                    {
                        Application.Instance.Invoke(() =>
                        {
                            lblProgress.Text =
                                $"Hashing track {currentTrack.TrackSequence} of {opticalMediaImage.Tracks.Count}";
                            prgProgress.Value++;
                        });

                        if (currentTrack.TrackStartSector - previousTrackEnd != 0 && chkChecksumMedia.Checked == true)
                        {
                            for (ulong i = previousTrackEnd + 1; i < currentTrack.TrackStartSector; i++)
                            {
                                ulong sector = i;
                                Application.Instance.Invoke(() =>
                                {
                                    prgProgress2.Value = (int)(sector / SECTORS_TO_READ);
                                    lblProgress2.Text  = $"Hashing track-less sector {sector}";
                                });

                                byte[] hiddenSector = opticalMediaImage.ReadSector(i);

                                mediaChecksum?.Update(hiddenSector);
                            }
                        }

                        DicConsole.DebugWriteLine("Checksum command",
                                                  "Track {0} starts at sector {1} and ends at sector {2}",
                                                  currentTrack.TrackSequence, currentTrack.TrackStartSector,
                                                  currentTrack.TrackEndSector);

                        if (chkChecksumTracks.Checked == true)
                        {
                            trackChecksum = new Checksum(enabledChecksums);
                        }

                        ulong sectors     = currentTrack.TrackEndSector - currentTrack.TrackStartSector + 1;
                        ulong doneSectors = 0;

                        while (doneSectors < sectors)
                        {
                            if (cancel)
                            {
                                Application.Instance.Invoke(() =>
                                {
                                    btnClose.Visible = true;
                                    btnStart.Visible = false;
                                    btnStop.Visible  = false;
                                });
                                return;
                            }

                            byte[] sector;

                            if (sectors - doneSectors >= SECTORS_TO_READ)
                            {
                                sector = opticalMediaImage.ReadSectors(doneSectors, SECTORS_TO_READ,
                                                                       currentTrack.TrackSequence);

                                ulong doneSectorsToInvoke = doneSectors;
                                Application.Instance.Invoke(() =>
                                {
                                    prgProgress2.Value = (int)(doneSectorsToInvoke / SECTORS_TO_READ);
                                    lblProgress2.Text  =
                                        $"Hashings sectors {doneSectorsToInvoke} to {doneSectorsToInvoke + SECTORS_TO_READ} of track {currentTrack.TrackSequence}";
                                });

                                doneSectors += SECTORS_TO_READ;
                            }
                            else
                            {
                                sector = opticalMediaImage.ReadSectors(doneSectors, (uint)(sectors - doneSectors),
                                                                       currentTrack.TrackSequence);

                                ulong doneSectorsToInvoke = doneSectors;
                                Application.Instance.Invoke(() =>
                                {
                                    prgProgress2.Value = (int)(doneSectorsToInvoke / SECTORS_TO_READ);
                                    lblProgress2.Text  =
                                        $"Hashings sectors {doneSectorsToInvoke} to {doneSectorsToInvoke + (sectors - doneSectorsToInvoke)} of track {currentTrack.TrackSequence}";
                                });

                                doneSectors += sectors - doneSectors;
                            }

                            if (chkChecksumMedia.Checked == true)
                            {
                                mediaChecksum?.Update(sector);
                            }

                            if (chkChecksumTracks.Checked == true)
                            {
                                trackChecksum?.Update(sector);
                            }
                        }

                        if (chkChecksumTracks.Checked == true)
                        {
                            if (trackChecksum != null)
                            {
                                foreach (ChecksumType chk in trackChecksum.End())
                                {
                                    trackHashes.Add(new TreeGridItem
                                    {
                                        Values = new object[]
                                        {
                                            currentTrack.TrackSequence, chk.type, chk.Value
                                        }
                                    });
                                }
                            }
                        }

                        previousTrackEnd = currentTrack.TrackEndSector;
                    }

                    if (opticalMediaImage.Info.Sectors - previousTrackEnd != 0 && chkChecksumMedia.Checked == true)
                    {
                        for (ulong i = previousTrackEnd + 1; i < opticalMediaImage.Info.Sectors; i++)
                        {
                            ulong sector = i;
                            Application.Instance.Invoke(() =>
                            {
                                prgProgress2.Value = (int)(sector / SECTORS_TO_READ);
                                lblProgress2.Text  = $"Hashing track-less sector {sector}";
                            });

                            byte[] hiddenSector = opticalMediaImage.ReadSector(i);
                            mediaChecksum?.Update(hiddenSector);
                        }
                    }

                    if (chkChecksumMedia.Checked == true)
                    {
                        if (mediaChecksum != null)
                        {
                            foreach (ChecksumType chk in mediaChecksum.End())
                            {
                                mediaHashes.Add(new TreeGridItem {
                                    Values = new object[] { chk.type, chk.Value }
                                });
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    DicConsole.DebugWriteLine("Could not get tracks because {0}", ex.Message);
                    DicConsole.WriteLine("Unable to get separate tracks, not checksumming them");
                }
            }
            else
            {
                Application.Instance.Invoke(() => { stkProgress1.Visible = false; });
                mediaChecksum = new Checksum(enabledChecksums);

                ulong doneSectors = 0;

                while (doneSectors < inputFormat.Info.Sectors)
                {
                    if (cancel)
                    {
                        Application.Instance.Invoke(() =>
                        {
                            btnClose.Visible = true;
                            btnStart.Visible = false;
                            btnStop.Visible  = false;
                        });
                        return;
                    }

                    byte[] sector;

                    if (inputFormat.Info.Sectors - doneSectors >= SECTORS_TO_READ)
                    {
                        sector = inputFormat.ReadSectors(doneSectors, SECTORS_TO_READ);

                        ulong doneSectorsToInvoke = doneSectors;
                        Application.Instance.Invoke(() =>
                        {
                            prgProgress2.Value = (int)(doneSectorsToInvoke / SECTORS_TO_READ);
                            lblProgress2.Text  =
                                $"Hashings sectors {doneSectorsToInvoke} to {doneSectorsToInvoke + SECTORS_TO_READ}";
                        });
                        doneSectors += SECTORS_TO_READ;
                    }
                    else
                    {
                        sector = inputFormat.ReadSectors(doneSectors, (uint)(inputFormat.Info.Sectors - doneSectors));
                        ulong doneSectorsToInvoke = doneSectors;
                        Application.Instance.Invoke(() =>
                        {
                            prgProgress2.Value = (int)(doneSectorsToInvoke / SECTORS_TO_READ);
                            lblProgress2.Text  =
                                $"Hashings sectors {doneSectorsToInvoke} to {doneSectorsToInvoke + (inputFormat.Info.Sectors - doneSectorsToInvoke)}";
                        });
                        doneSectors += inputFormat.Info.Sectors - doneSectors;
                    }

                    mediaChecksum.Update(sector);
                }

                foreach (ChecksumType chk in mediaChecksum.End())
                {
                    mediaHashes.Add(new TreeGridItem {
                        Values = new object[] { chk.type, chk.Value }
                    });
                }
            }

            if (chkChecksumTracks.Checked == true)
            {
                Application.Instance.Invoke(() =>
                {
                    grpTrackChecksums.Text    = "Track checksums:";
                    stkTrackChecksums.Visible = true;

                    treeTrackChecksums.Columns.Add(new GridColumn
                    {
                        HeaderText = "Track", DataCell = new TextBoxCell(0)
                    });
                    treeTrackChecksums.Columns.Add(new GridColumn
                    {
                        HeaderText = "Algorithm", DataCell = new TextBoxCell(1)
                    });
                    treeTrackChecksums.Columns.Add(new GridColumn {
                        HeaderText = "Hash", DataCell = new TextBoxCell(2)
                    });

                    treeTrackChecksums.AllowMultipleSelection = false;
                    treeTrackChecksums.ShowHeader             = true;
                    treeTrackChecksums.DataStore = trackHashes;
                });
            }

            if (chkChecksumMedia.Checked == true)
            {
                Application.Instance.Invoke(() =>
                {
                    grpMediaChecksums.Text    = "Media checksums:";
                    stkMediaChecksums.Visible = true;

                    treeMediaChecksums.Columns.Add(new GridColumn
                    {
                        HeaderText = "Algorithm", DataCell = new TextBoxCell(0)
                    });
                    treeMediaChecksums.Columns.Add(new GridColumn {
                        HeaderText = "Hash", DataCell = new TextBoxCell(1)
                    });

                    treeMediaChecksums.AllowMultipleSelection = false;
                    treeMediaChecksums.ShowHeader             = true;
                    treeMediaChecksums.DataStore = mediaHashes;
                });
            }

            Statistics.AddCommand("checksum");

            Application.Instance.Invoke(() =>
            {
                stkOptions.Visible  = false;
                stkResults.Visible  = true;
                stkProgress.Visible = false;
                btnStart.Visible    = false;
                btnStop.Visible     = false;
                btnClose.Visible    = true;
            });
        }
 private static Task <IpBin> GetIpData(IOpticalMediaImage opticalImage, Partition partition)
 {
     return(Task.Run(() => GetIpData(opticalImage.ReadSector(partition.Start))));
 }
Beispiel #7
0
        void DoWork()
        {
            bool?correctDisc    = null;
            long totalSectors   = 0;
            long errorSectors   = 0;
            long correctSectors = 0;
            long unknownSectors = 0;
            bool formatHasTracks;

            IOpticalMediaImage      inputOptical           = inputFormat as IOpticalMediaImage;
            IVerifiableSectorsImage verifiableSectorsImage = inputFormat as IVerifiableSectorsImage;

            try { formatHasTracks = inputOptical?.Tracks?.Count > 0; }
            catch { formatHasTracks = false; }

            // Setup progress bars
            Application.Instance.Invoke(() =>
            {
                stkProgress.Visible  = true;
                prgProgress.MaxValue = 0;

                if (chkVerifyImage.Checked == true || chkVerifySectors.Checked == true)
                {
                    prgProgress.MaxValue = 1;
                }

                if (formatHasTracks && inputOptical != null)
                {
                    prgProgress.MaxValue += inputOptical.Tracks.Count;
                }
                else
                {
                    if (chkVerifySectors.Checked == true)
                    {
                        prgProgress.MaxValue = 2;
                        prgProgress2.Visible = false;
                        lblProgress2.Visible = false;
                    }
                    else
                    {
                        prgProgress2.Visible = true;
                        lblProgress2.Visible = true;
                    }
                }

                prgProgress.MaxValue++;
            });

            if (chkVerifyImage.Checked == true)
            {
                if (!(inputFormat is IVerifiableImage verifiableImage))
                {
                    Application.Instance.Invoke(() =>
                    {
                        lblImageResult.Visible = true;
                        lblImageResult.Text    = "Disc image does not support verification.";
                    });
                }
                else
                {
                    Application.Instance.Invoke(() =>
                    {
                        lblProgress.Text = "Checking media image...";
                        if (chkVerifySectors.Checked == true)
                        {
                            prgProgress.Value = 1;
                        }
                        else
                        {
                            prgProgress.Indeterminate = true;
                        }

                        prgProgress2.Indeterminate = true;
                    });

                    DateTime startCheck      = DateTime.UtcNow;
                    bool?    discCheckStatus = verifiableImage.VerifyMediaImage();
                    DateTime endCheck        = DateTime.UtcNow;

                    TimeSpan checkTime = endCheck - startCheck;

                    Application.Instance.Invoke(() =>
                    {
                        lblImageResult.Visible = true;
                        switch (discCheckStatus)
                        {
                        case true:
                            lblImageResult.Text = "Disc image checksums are correct";
                            break;

                        case false:
                            lblImageResult.Text = "Disc image checksums are incorrect";
                            break;

                        case null:
                            lblImageResult.Text = "Disc image does not contain checksums";
                            break;
                        }
                    });

                    correctDisc = discCheckStatus;
                    DicConsole.VerboseWriteLine("Checking disc image checksums took {0} seconds",
                                                checkTime.TotalSeconds);
                }
            }