Пример #1
0
        /// <summary>Reads the TOC, processes it, returns the track list and last sector</summary>
        /// <param name="dev">Device</param>
        /// <param name="dumpLog">Dump log</param>
        /// <param name="force">Force dump enabled</param>
        /// <param name="lastSector">Last sector number</param>
        /// <param name="leadOutStarts">Lead-out starts</param>
        /// <param name="mediaTags">Media tags</param>
        /// <param name="stoppingErrorMessage">Stopping error message handler</param>
        /// <param name="toc">Full CD TOC</param>
        /// <param name="trackFlags">Track flags</param>
        /// <param name="updateStatus">Update status handler</param>
        /// <returns>List of tracks</returns>
        public static Track[] GetCdTracks(Device dev, DumpLog dumpLog, bool force, out long lastSector,
                                          Dictionary <int, long> leadOutStarts,
                                          Dictionary <MediaTagType, byte[]> mediaTags,
                                          ErrorMessageHandler stoppingErrorMessage, out FullTOC.CDFullTOC?toc,
                                          Dictionary <byte, byte> trackFlags, UpdateStatusHandler updateStatus)
        {
            byte[]       cmdBuf;                         // Data buffer
            const uint   sectorSize = 2352;              // Full sector size
            bool         sense;                          // Sense indicator
            List <Track> trackList = new List <Track>(); // Tracks in disc

            byte[] tmpBuf;                               // Temporary buffer
            toc        = null;
            lastSector = 0;
            TrackType leadoutTrackType = TrackType.Audio;

            // We discarded all discs that falsify a TOC before requesting a real TOC
            // No TOC, no CD (or an empty one)
            dumpLog?.WriteLine("Reading full TOC");
            updateStatus?.Invoke("Reading full TOC");
            sense = dev.ReadRawToc(out cmdBuf, out _, 0, dev.Timeout, out _);

            if (!sense)
            {
                toc = FullTOC.Decode(cmdBuf);

                if (toc.HasValue)
                {
                    tmpBuf = new byte[cmdBuf.Length - 2];
                    Array.Copy(cmdBuf, 2, tmpBuf, 0, cmdBuf.Length - 2);
                    mediaTags?.Add(MediaTagType.CD_FullTOC, tmpBuf);
                }
            }

            updateStatus?.Invoke("Building track map...");
            dumpLog?.WriteLine("Building track map...");

            if (toc.HasValue)
            {
                FullTOC.TrackDataDescriptor[] sortedTracks =
                    toc.Value.TrackDescriptors.OrderBy(track => track.POINT).ToArray();

                foreach (FullTOC.TrackDataDescriptor trk in sortedTracks.Where(trk => trk.ADR == 1 || trk.ADR == 4))
                {
                    if (trk.POINT >= 0x01 &&
                        trk.POINT <= 0x63)
                    {
                        trackList.Add(new Track
                        {
                            TrackSequence = trk.POINT,
                            TrackSession  = trk.SessionNumber,
                            TrackType     = (TocControl)(trk.CONTROL & 0x0D) == TocControl.DataTrack ||
                                            (TocControl)(trk.CONTROL & 0x0D) == TocControl.DataTrackIncremental
                                            ? TrackType.Data : TrackType.Audio,
                            TrackStartSector =
                                (ulong)((trk.PHOUR * 3600 * 75) + (trk.PMIN * 60 * 75) + (trk.PSEC * 75) + trk.PFRAME -
                                        150),
                            TrackBytesPerSector    = (int)sectorSize,
                            TrackRawBytesPerSector = (int)sectorSize
                        });

                        trackFlags?.Add(trk.POINT, trk.CONTROL);
                    }
                    else if (trk.POINT == 0xA2)
                    {
                        int phour, pmin, psec, pframe;

                        if (trk.PFRAME == 0)
                        {
                            pframe = 74;

                            if (trk.PSEC == 0)
                            {
                                psec = 59;

                                if (trk.PMIN == 0)
                                {
                                    pmin  = 59;
                                    phour = trk.PHOUR - 1;
                                }
                                else
                                {
                                    pmin  = trk.PMIN - 1;
                                    phour = trk.PHOUR;
                                }
                            }
                            else
                            {
                                psec  = trk.PSEC - 1;
                                pmin  = trk.PMIN;
                                phour = trk.PHOUR;
                            }
                        }
                        else
                        {
                            pframe = trk.PFRAME - 1;
                            psec   = trk.PSEC;
                            pmin   = trk.PMIN;
                            phour  = trk.PHOUR;
                        }

                        lastSector = (phour * 3600 * 75) + (pmin * 60 * 75) + (psec * 75) + pframe - 150;
                        leadOutStarts?.Add(trk.SessionNumber, lastSector + 1);
                    }
                    else if (trk.POINT == 0xA0 &&
                             trk.ADR == 1)
                    {
                        leadoutTrackType =
                            (TocControl)(trk.CONTROL & 0x0D) == TocControl.DataTrack ||
                            (TocControl)(trk.CONTROL & 0x0D) == TocControl.DataTrackIncremental ? TrackType.Data
                                : TrackType.Audio;
                    }
                }
            }
            else
            {
                updateStatus?.Invoke("Cannot read RAW TOC, requesting processed one...");
                dumpLog?.WriteLine("Cannot read RAW TOC, requesting processed one...");
                sense = dev.ReadToc(out cmdBuf, out _, false, 0, dev.Timeout, out _);

                TOC.CDTOC?oldToc = TOC.Decode(cmdBuf);

                if ((sense || !oldToc.HasValue) &&
                    !force)
                {
                    dumpLog?.WriteLine("Could not read TOC, if you want to continue, use force, and will try from LBA 0 to 360000...");

                    stoppingErrorMessage?.
                    Invoke("Could not read TOC, if you want to continue, use force, and will try from LBA 0 to 360000...");

                    return(null);
                }

                if (oldToc.HasValue)
                {
                    foreach (TOC.CDTOCTrackDataDescriptor trk in oldToc.Value.TrackDescriptors.
                             OrderBy(t => t.TrackNumber).
                             Where(trk => trk.ADR == 1 || trk.ADR == 4))
                    {
                        if (trk.TrackNumber >= 0x01 &&
                            trk.TrackNumber <= 0x63)
                        {
                            trackList.Add(new Track
                            {
                                TrackSequence = trk.TrackNumber,
                                TrackSession  = 1,
                                TrackType     = (TocControl)(trk.CONTROL & 0x0D) == TocControl.DataTrack ||
                                                (TocControl)(trk.CONTROL & 0x0D) == TocControl.DataTrackIncremental
                                                ? TrackType.Data : TrackType.Audio,
                                TrackStartSector       = trk.TrackStartAddress,
                                TrackBytesPerSector    = (int)sectorSize,
                                TrackRawBytesPerSector = (int)sectorSize
                            });

                            trackFlags?.Add(trk.TrackNumber, trk.CONTROL);
                        }
                        else if (trk.TrackNumber == 0xAA)
                        {
                            leadoutTrackType =
                                (TocControl)(trk.CONTROL & 0x0D) == TocControl.DataTrack ||
                                (TocControl)(trk.CONTROL & 0x0D) == TocControl.DataTrackIncremental ? TrackType.Data
                                    : TrackType.Audio;

                            lastSector = trk.TrackStartAddress - 1;
                        }
                    }
                }
            }

            if (trackList.Count == 0)
            {
                updateStatus?.Invoke("No tracks found, adding a single track from 0 to Lead-Out");
                dumpLog?.WriteLine("No tracks found, adding a single track from 0 to Lead-Out");

                trackList.Add(new Track
                {
                    TrackSequence          = 1,
                    TrackSession           = 1,
                    TrackType              = leadoutTrackType,
                    TrackStartSector       = 0,
                    TrackBytesPerSector    = (int)sectorSize,
                    TrackRawBytesPerSector = (int)sectorSize
                });

                trackFlags?.Add(1, (byte)(leadoutTrackType == TrackType.Audio ? 0 : 4));
            }

            if (lastSector != 0)
            {
                return(trackList.ToArray());
            }

            sense = dev.ReadCapacity16(out cmdBuf, out _, dev.Timeout, out _);

            if (!sense)
            {
                byte[] temp = new byte[8];

                Array.Copy(cmdBuf, 0, temp, 0, 8);
                Array.Reverse(temp);
                lastSector = (long)BitConverter.ToUInt64(temp, 0);
            }
            else
            {
                sense = dev.ReadCapacity(out cmdBuf, out _, dev.Timeout, out _);

                if (!sense)
                {
                    lastSector = (cmdBuf[0] << 24) + (cmdBuf[1] << 16) + (cmdBuf[2] << 8) + cmdBuf[3];
                }
            }

            if (lastSector > 0)
            {
                return(trackList.ToArray());
            }

            if (!force)
            {
                stoppingErrorMessage?.
                Invoke("Could not find Lead-Out, if you want to continue use force option and will continue until 360000 sectors...");

                dumpLog?.WriteLine("Could not find Lead-Out, if you want to continue use force option and will continue until 360000 sectors...");

                return(null);
            }

            updateStatus?.
            Invoke("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before...");

            dumpLog?.WriteLine("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before...");
            lastSector = 360000;

            return(trackList.ToArray());
        }
Пример #2
0
        public pnlImageInfo(string imagePath, IFilter filter, IMediaImage imageFormat)
        {
            this.imagePath   = imagePath;
            this.filter      = filter;
            this.imageFormat = imageFormat;
            XamlReader.Load(this);

            Stream logo =
                ResourceHandler
                .GetResourceStream($"DiscImageChef.Gui.Assets.Logos.Media.{imageFormat.Info.MediaType}.svg");

            /*            if(logo != null)
             *          {
             *              svgMediaLogo.SvgStream = logo;
             *              svgMediaLogo.Visible   = true;
             *          }
             *          else
             *          {*/
            logo =
                ResourceHandler
                .GetResourceStream($"DiscImageChef.Gui.Assets.Logos.Media.{imageFormat.Info.MediaType}.png");
            if (logo != null)
            {
                imgMediaLogo.Image   = new Bitmap(logo);
                imgMediaLogo.Visible = true;
            }
            //}

            lblImagePath.Text   = $"Path: {imagePath}";
            lblFilter.Text      = $"Filter: {filter.Name}";
            lblImageFormat.Text = $"Image format identified by {imageFormat.Name} ({imageFormat.Id}).";
            lblImageFormat.Text = !string.IsNullOrWhiteSpace(imageFormat.Info.Version)
                                      ? $"Format: {imageFormat.Format} version {imageFormat.Info.Version}"
                                      : $"Format: {imageFormat.Format}";
            lblImageSize.Text = $"Image without headers is {imageFormat.Info.ImageSize} bytes long";
            lblSectors.Text   =
                $"Contains a media of {imageFormat.Info.Sectors} sectors with a maximum sector size of {imageFormat.Info.SectorSize} bytes (if all sectors are of the same size this would be {imageFormat.Info.Sectors * imageFormat.Info.SectorSize} bytes)";
            lblMediaType.Text =
                $"Contains a media of type {imageFormat.Info.MediaType} and XML type {imageFormat.Info.XmlMediaType}";
            lblHasPartitions.Text = $"{(imageFormat.Info.HasPartitions ? "Has" : "Doesn't have")} partitions";
            lblHasSessions.Text   = $"{(imageFormat.Info.HasSessions ? "Has" : "Doesn't have")} sessions";

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.Application))
            {
                lblApplication.Visible = true;
                lblApplication.Text    = !string.IsNullOrWhiteSpace(imageFormat.Info.ApplicationVersion)
                                          ? $"Was created with {imageFormat.Info.Application} version {imageFormat.Info.ApplicationVersion}"
                                          : $"Was created with {imageFormat.Info.Application}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.Creator))
            {
                lblCreator.Visible = true;
                lblCreator.Text    = $"Created by: {imageFormat.Info.Creator}";
            }

            if (imageFormat.Info.CreationTime != DateTime.MinValue)
            {
                lblCreationTime.Visible = true;
                lblCreationTime.Text    = $"Created on {imageFormat.Info.CreationTime}";
            }

            if (imageFormat.Info.LastModificationTime != DateTime.MinValue)
            {
                lblLastModificationTime.Visible = true;
                lblLastModificationTime.Text    = $"Last modified on {imageFormat.Info.LastModificationTime}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.Comments))
            {
                grpComments.Visible = true;
                txtComments.Text    = imageFormat.Info.Comments;
            }

            if (imageFormat.Info.MediaSequence != 0 && imageFormat.Info.LastMediaSequence != 0)
            {
                lblMediaSequence.Visible = true;
                lblMediaSequence.Text    =
                    $"Media is number {imageFormat.Info.MediaSequence} on a set of {imageFormat.Info.LastMediaSequence} medias";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaTitle))
            {
                lblMediaTitle.Visible = true;
                lblMediaTitle.Text    = $"Media title: {imageFormat.Info.MediaTitle}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaManufacturer))
            {
                lblMediaManufacturer.Visible = true;
                lblMediaManufacturer.Text    = $"Media manufacturer: {imageFormat.Info.MediaManufacturer}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaModel))
            {
                lblMediaModel.Visible = true;
                lblMediaModel.Text    = $"Media model: {imageFormat.Info.MediaModel}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaSerialNumber))
            {
                lblMediaSerialNumber.Visible = true;
                lblMediaSerialNumber.Text    = $"Media serial number: {imageFormat.Info.MediaSerialNumber}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaBarcode))
            {
                lblMediaBarcode.Visible = true;
                lblMediaBarcode.Text    = $"Media barcode: {imageFormat.Info.MediaBarcode}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaPartNumber))
            {
                lblMediaPartNumber.Visible = true;
                lblMediaPartNumber.Text    = $"Media part number: {imageFormat.Info.MediaPartNumber}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveManufacturer))
            {
                lblDriveManufacturer.Visible = true;
                lblDriveManufacturer.Text    = $"Drive manufacturer: {imageFormat.Info.DriveManufacturer}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveModel))
            {
                lblDriveModel.Visible = true;
                lblDriveModel.Text    = $"Drive model: {imageFormat.Info.DriveModel}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveSerialNumber))
            {
                lblDriveSerialNumber.Visible = true;
                lblDriveSerialNumber.Text    = $"Drive serial number: {imageFormat.Info.DriveSerialNumber}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveFirmwareRevision))
            {
                lblDriveFirmwareRevision.Visible = true;
                lblDriveFirmwareRevision.Text    = $"Drive firmware info: {imageFormat.Info.DriveFirmwareRevision}";
            }

            if (imageFormat.Info.Cylinders > 0 && imageFormat.Info.Heads > 0 &&
                imageFormat.Info.SectorsPerTrack > 0 &&
                imageFormat.Info.XmlMediaType != XmlMediaType.OpticalDisc &&
                (!(imageFormat is ITapeImage tapeImage) || !tapeImage.IsTape))
            {
                lblMediaGeometry.Visible = true;
                lblMediaGeometry.Text    =
                    $"Media geometry: {imageFormat.Info.Cylinders} cylinders, {imageFormat.Info.Heads} heads, {imageFormat.Info.SectorsPerTrack} sectors per track";
            }

            grpMediaInfo.Visible = lblMediaSequence.Visible || lblMediaTitle.Visible ||
                                   lblMediaManufacturer.Visible ||
                                   lblMediaModel.Visible || lblMediaSerialNumber.Visible ||
                                   lblMediaBarcode.Visible ||
                                   lblMediaPartNumber.Visible;
            grpDriveInfo.Visible = lblDriveManufacturer.Visible || lblDriveModel.Visible ||
                                   lblDriveSerialNumber.Visible || lblDriveFirmwareRevision.Visible ||
                                   lblMediaGeometry.Visible;

            if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Count > 0)
            {
                TreeGridItemCollection mediaTagList = new TreeGridItemCollection();

                treeMediaTags.Columns.Add(new GridColumn {
                    HeaderText = "Tag", DataCell = new TextBoxCell(0)
                });

                treeMediaTags.AllowMultipleSelection = false;
                treeMediaTags.ShowHeader             = false;
                treeMediaTags.DataStore = mediaTagList;

                foreach (MediaTagType tag in imageFormat.Info.ReadableMediaTags.OrderBy(t => t))
                {
                    mediaTagList.Add(new TreeGridItem {
                        Values = new object[] { tag.ToString() }
                    });
                }

                grpMediaTags.Visible = true;
            }

            if (imageFormat.Info.ReadableSectorTags != null && imageFormat.Info.ReadableSectorTags.Count > 0)
            {
                TreeGridItemCollection sectorTagList = new TreeGridItemCollection();

                treeSectorTags.Columns.Add(new GridColumn {
                    HeaderText = "Tag", DataCell = new TextBoxCell(0)
                });

                treeSectorTags.AllowMultipleSelection = false;
                treeSectorTags.ShowHeader             = false;
                treeSectorTags.DataStore = sectorTagList;

                foreach (SectorTagType tag in imageFormat.Info.ReadableSectorTags.OrderBy(t => t))
                {
                    sectorTagList.Add(new TreeGridItem {
                        Values = new object[] { tag.ToString() }
                    });
                }

                grpSectorTags.Visible = true;
            }

            PeripheralDeviceTypes scsiDeviceType = PeripheralDeviceTypes.DirectAccess;

            byte[] scsiInquiryData          = null;
            Inquiry.SCSIInquiry?scsiInquiry = null;
            Modes.DecodedMode?  scsiMode    = null;
            byte[] scsiModeSense6           = null;
            byte[] scsiModeSense10          = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SCSI_INQUIRY))
            {
                scsiInquiryData = imageFormat.ReadDiskTag(MediaTagType.SCSI_INQUIRY);

                scsiDeviceType = (PeripheralDeviceTypes)(scsiInquiryData[0] & 0x1F);

                scsiInquiry = Inquiry.Decode(scsiInquiryData);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SCSI_MODESENSE_6))
            {
                scsiModeSense6 = imageFormat.ReadDiskTag(MediaTagType.SCSI_MODESENSE_6);
                scsiMode       = Modes.DecodeMode6(scsiModeSense6, scsiDeviceType);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SCSI_MODESENSE_10))
            {
                scsiModeSense10 = imageFormat.ReadDiskTag(MediaTagType.SCSI_MODESENSE_10);
                scsiMode        = Modes.DecodeMode10(scsiModeSense10, scsiDeviceType);
            }

            tabScsiInfo tabScsiInfo = new tabScsiInfo();

            tabScsiInfo.LoadData(scsiInquiryData, scsiInquiry, null, scsiMode, scsiDeviceType, scsiModeSense6,
                                 scsiModeSense10, null);
            tabInfos.Pages.Add(tabScsiInfo);

            byte[] ataIdentify   = null;
            byte[] atapiIdentify = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.ATA_IDENTIFY))
            {
                ataIdentify = imageFormat.ReadDiskTag(MediaTagType.ATA_IDENTIFY);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.ATAPI_IDENTIFY))
            {
                atapiIdentify = imageFormat.ReadDiskTag(MediaTagType.ATAPI_IDENTIFY);
            }

            tabAtaInfo tabAtaInfo = new tabAtaInfo();

            tabAtaInfo.LoadData(ataIdentify, atapiIdentify, null);
            tabInfos.Pages.Add(tabAtaInfo);

            byte[]                toc                  = null;
            TOC.CDTOC?            decodedToc           = null;
            byte[]                fullToc              = null;
            FullTOC.CDFullTOC?    decodedFullToc       = null;
            byte[]                pma                  = null;
            byte[]                atip                 = null;
            ATIP.CDATIP?          decodedAtip          = null;
            byte[]                cdtext               = null;
            CDTextOnLeadIn.CDText?decodedCdText        = null;
            string                mediaCatalogueNumber = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_TOC))
            {
                toc = imageFormat.ReadDiskTag(MediaTagType.CD_TOC);

                if (toc.Length > 0)
                {
                    ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(toc, 0));
                    if (dataLen + 2 != toc.Length)
                    {
                        byte[] tmp = new byte[toc.Length + 2];
                        Array.Copy(toc, 0, tmp, 2, toc.Length);
                        tmp[0] = (byte)((toc.Length & 0xFF00) >> 8);
                        tmp[1] = (byte)(toc.Length & 0xFF);
                        toc    = tmp;
                    }

                    decodedToc = TOC.Decode(toc);
                }
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_FullTOC))
            {
                fullToc = imageFormat.ReadDiskTag(MediaTagType.CD_FullTOC);

                if (fullToc.Length > 0)
                {
                    ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(fullToc, 0));
                    if (dataLen + 2 != fullToc.Length)
                    {
                        byte[] tmp = new byte[fullToc.Length + 2];
                        Array.Copy(fullToc, 0, tmp, 2, fullToc.Length);
                        tmp[0]  = (byte)((fullToc.Length & 0xFF00) >> 8);
                        tmp[1]  = (byte)(fullToc.Length & 0xFF);
                        fullToc = tmp;
                    }

                    decodedFullToc = FullTOC.Decode(fullToc);
                }
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_PMA))
            {
                pma = imageFormat.ReadDiskTag(MediaTagType.CD_PMA);

                if (pma.Length > 0)
                {
                    ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(pma, 0));
                    if (dataLen + 2 != pma.Length)
                    {
                        byte[] tmp = new byte[pma.Length + 2];
                        Array.Copy(pma, 0, tmp, 2, pma.Length);
                        tmp[0] = (byte)((pma.Length & 0xFF00) >> 8);
                        tmp[1] = (byte)(pma.Length & 0xFF);
                        pma    = tmp;
                    }
                }
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_ATIP))
            {
                atip = imageFormat.ReadDiskTag(MediaTagType.CD_ATIP);

                uint dataLen = Swapping.Swap(BitConverter.ToUInt32(atip, 0));
                if (dataLen + 4 != atip.Length)
                {
                    byte[] tmp = new byte[atip.Length + 4];
                    Array.Copy(atip, 0, tmp, 4, atip.Length);
                    tmp[0] = (byte)((atip.Length & 0xFF000000) >> 24);
                    tmp[1] = (byte)((atip.Length & 0xFF0000) >> 16);
                    tmp[2] = (byte)((atip.Length & 0xFF00) >> 8);
                    tmp[3] = (byte)(atip.Length & 0xFF);
                    atip   = tmp;
                }

                decodedAtip = ATIP.Decode(atip);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_TEXT))
            {
                cdtext = imageFormat.ReadDiskTag(MediaTagType.CD_TEXT);

                uint dataLen = Swapping.Swap(BitConverter.ToUInt32(cdtext, 0));
                if (dataLen + 4 != cdtext.Length)
                {
                    byte[] tmp = new byte[cdtext.Length + 4];
                    Array.Copy(cdtext, 0, tmp, 4, cdtext.Length);
                    tmp[0] = (byte)((cdtext.Length & 0xFF000000) >> 24);
                    tmp[1] = (byte)((cdtext.Length & 0xFF0000) >> 16);
                    tmp[2] = (byte)((cdtext.Length & 0xFF00) >> 8);
                    tmp[3] = (byte)(cdtext.Length & 0xFF);
                    cdtext = tmp;
                }

                decodedCdText = CDTextOnLeadIn.Decode(cdtext);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_MCN))
            {
                byte[] mcn = imageFormat.ReadDiskTag(MediaTagType.CD_MCN);

                mediaCatalogueNumber = Encoding.UTF8.GetString(mcn);
            }

            tabCompactDiscInfo tabCompactDiscInfo = new tabCompactDiscInfo();

            tabCompactDiscInfo.LoadData(toc, atip, null, null, fullToc, pma, cdtext, decodedToc, decodedAtip, null,
                                        decodedFullToc, decodedCdText, null, mediaCatalogueNumber, null);
            tabInfos.Pages.Add(tabCompactDiscInfo);

            byte[] dvdPfi = null;
            byte[] dvdDmi = null;
            byte[] dvdCmi = null;
            byte[] hddvdCopyrightInformation = null;
            byte[] dvdBca = null;
            PFI.PhysicalFormatInformation?decodedPfi = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_PFI))
            {
                dvdPfi     = imageFormat.ReadDiskTag(MediaTagType.DVD_PFI);
                decodedPfi = PFI.Decode(dvdPfi);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_DMI))
            {
                dvdDmi = imageFormat.ReadDiskTag(MediaTagType.DVD_DMI);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_CMI))
            {
                dvdCmi = imageFormat.ReadDiskTag(MediaTagType.DVD_CMI);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.HDDVD_CPI))
            {
                hddvdCopyrightInformation = imageFormat.ReadDiskTag(MediaTagType.HDDVD_CPI);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_BCA))
            {
                dvdBca = imageFormat.ReadDiskTag(MediaTagType.DVD_BCA);
            }

            tabDvdInfo tabDvdInfo = new tabDvdInfo();

            tabDvdInfo.LoadData(imageFormat.Info.MediaType, dvdPfi, dvdDmi, dvdCmi, hddvdCopyrightInformation, dvdBca,
                                null, decodedPfi);
            tabInfos.Pages.Add(tabDvdInfo);

            byte[] dvdRamDds                     = null;
            byte[] dvdRamCartridgeStatus         = null;
            byte[] dvdRamSpareArea               = null;
            byte[] lastBorderOutRmd              = null;
            byte[] dvdPreRecordedInfo            = null;
            byte[] dvdrMediaIdentifier           = null;
            byte[] dvdrPhysicalInformation       = null;
            byte[] hddvdrMediumStatus            = null;
            byte[] dvdrLayerCapacity             = null;
            byte[] dvdrDlMiddleZoneStart         = null;
            byte[] dvdrDlJumpIntervalSize        = null;
            byte[] dvdrDlManualLayerJumpStartLba = null;
            byte[] dvdPlusAdip                   = null;
            byte[] dvdPlusDcb                    = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDRAM_DDS))
            {
                dvdRamDds = imageFormat.ReadDiskTag(MediaTagType.DVDRAM_DDS);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDRAM_MediumStatus))
            {
                dvdRamCartridgeStatus = imageFormat.ReadDiskTag(MediaTagType.DVDRAM_MediumStatus);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDRAM_SpareArea))
            {
                dvdRamSpareArea = imageFormat.ReadDiskTag(MediaTagType.DVDRAM_SpareArea);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_RMD))
            {
                lastBorderOutRmd = imageFormat.ReadDiskTag(MediaTagType.DVDR_RMD);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_PreRecordedInfo))
            {
                dvdPreRecordedInfo = imageFormat.ReadDiskTag(MediaTagType.DVDR_PreRecordedInfo);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_MediaIdentifier))
            {
                dvdrMediaIdentifier = imageFormat.ReadDiskTag(MediaTagType.DVDR_MediaIdentifier);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_PFI))
            {
                dvdrPhysicalInformation = imageFormat.ReadDiskTag(MediaTagType.DVDR_PFI);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.HDDVD_MediumStatus))
            {
                hddvdrMediumStatus = imageFormat.ReadDiskTag(MediaTagType.HDDVD_MediumStatus);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_LayerCapacity))
            {
                dvdrLayerCapacity = imageFormat.ReadDiskTag(MediaTagType.DVDDL_LayerCapacity);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_MiddleZoneAddress))
            {
                dvdrDlMiddleZoneStart = imageFormat.ReadDiskTag(MediaTagType.DVDDL_MiddleZoneAddress);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_JumpIntervalSize))
            {
                dvdrDlJumpIntervalSize = imageFormat.ReadDiskTag(MediaTagType.DVDDL_JumpIntervalSize);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_ManualLayerJumpLBA))
            {
                dvdrDlManualLayerJumpStartLba = imageFormat.ReadDiskTag(MediaTagType.DVDDL_ManualLayerJumpLBA);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_ADIP))
            {
                dvdPlusAdip = imageFormat.ReadDiskTag(MediaTagType.DVD_ADIP);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DCB))
            {
                dvdPlusDcb = imageFormat.ReadDiskTag(MediaTagType.DCB);
            }

            tabDvdWritableInfo tabDvdWritableInfo = new tabDvdWritableInfo();

            tabDvdWritableInfo.LoadData(imageFormat.Info.MediaType, dvdRamDds, dvdRamCartridgeStatus, dvdRamSpareArea,
                                        lastBorderOutRmd, dvdPreRecordedInfo, dvdrMediaIdentifier,
                                        dvdrPhysicalInformation, hddvdrMediumStatus, null, dvdrLayerCapacity,
                                        dvdrDlMiddleZoneStart, dvdrDlJumpIntervalSize, dvdrDlManualLayerJumpStartLba,
                                        null, dvdPlusAdip, dvdPlusDcb);
            tabInfos.Pages.Add(tabDvdWritableInfo);

            byte[] blurayBurstCuttingArea = null;
            byte[] blurayCartridgeStatus  = null;
            byte[] blurayDds                  = null;
            byte[] blurayDiscInformation      = null;
            byte[] blurayPowResources         = null;
            byte[] bluraySpareAreaInformation = null;
            byte[] blurayTrackResources       = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_BCA))
            {
                blurayBurstCuttingArea = imageFormat.ReadDiskTag(MediaTagType.BD_BCA);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_CartridgeStatus))
            {
                blurayCartridgeStatus = imageFormat.ReadDiskTag(MediaTagType.BD_CartridgeStatus);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_DDS))
            {
                blurayDds = imageFormat.ReadDiskTag(MediaTagType.BD_DDS);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_DI))
            {
                blurayDiscInformation = imageFormat.ReadDiskTag(MediaTagType.BD_DI);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_POWResourcesInformation))
            {
                blurayPowResources = imageFormat.ReadDiskTag(MediaTagType.MMC_POWResourcesInformation);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_SpareArea))
            {
                bluraySpareAreaInformation = imageFormat.ReadDiskTag(MediaTagType.BD_SpareArea);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_TrackResourcesInformation))
            {
                bluraySpareAreaInformation = imageFormat.ReadDiskTag(MediaTagType.MMC_TrackResourcesInformation);
            }

            tabBlurayInfo tabBlurayInfo = new tabBlurayInfo();

            tabBlurayInfo.LoadData(blurayDiscInformation, blurayBurstCuttingArea, blurayDds, blurayCartridgeStatus,
                                   bluraySpareAreaInformation, blurayPowResources, blurayTrackResources, null, null);
            tabInfos.Pages.Add(tabBlurayInfo);

            byte[]            xboxDmi                   = null;
            byte[]            xboxSecuritySector        = null;
            SS.SecuritySector?decodedXboxSecuritySector = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.Xbox_DMI))
            {
                xboxDmi = imageFormat.ReadDiskTag(MediaTagType.Xbox_DMI);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.Xbox_SecuritySector))
            {
                xboxSecuritySector        = imageFormat.ReadDiskTag(MediaTagType.Xbox_SecuritySector);
                decodedXboxSecuritySector = SS.Decode(xboxSecuritySector);
            }

            tabXboxInfo tabXboxInfo = new tabXboxInfo();

            tabXboxInfo.LoadData(null, xboxDmi, xboxSecuritySector, decodedXboxSecuritySector);
            tabInfos.Pages.Add(tabXboxInfo);

            byte[] pcmciaCis = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.PCMCIA_CIS))
            {
                pcmciaCis = imageFormat.ReadDiskTag(MediaTagType.PCMCIA_CIS);
            }

            tabPcmciaInfo tabPcmciaInfo = new tabPcmciaInfo();

            tabPcmciaInfo.LoadData(pcmciaCis);
            tabInfos.Pages.Add(tabPcmciaInfo);

            DeviceType deviceType = DeviceType.Unknown;

            byte[] cid         = null;
            byte[] csd         = null;
            byte[] ocr         = null;
            byte[] extendedCsd = null;
            byte[] scr         = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_CID))
            {
                cid        = imageFormat.ReadDiskTag(MediaTagType.SD_CID);
                deviceType = DeviceType.SecureDigital;
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_CSD))
            {
                csd        = imageFormat.ReadDiskTag(MediaTagType.SD_CSD);
                deviceType = DeviceType.SecureDigital;
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_OCR))
            {
                ocr        = imageFormat.ReadDiskTag(MediaTagType.SD_OCR);
                deviceType = DeviceType.SecureDigital;
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_SCR))
            {
                scr        = imageFormat.ReadDiskTag(MediaTagType.SD_SCR);
                deviceType = DeviceType.SecureDigital;
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_CID))
            {
                cid        = imageFormat.ReadDiskTag(MediaTagType.MMC_CID);
                deviceType = DeviceType.MMC;
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_CSD))
            {
                csd        = imageFormat.ReadDiskTag(MediaTagType.MMC_CSD);
                deviceType = DeviceType.MMC;
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_OCR))
            {
                ocr        = imageFormat.ReadDiskTag(MediaTagType.MMC_OCR);
                deviceType = DeviceType.MMC;
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_ExtendedCSD))
            {
                extendedCsd = imageFormat.ReadDiskTag(MediaTagType.MMC_ExtendedCSD);
                deviceType  = DeviceType.MMC;
            }

            tabSdMmcInfo tabSdMmcInfo = new tabSdMmcInfo();

            tabSdMmcInfo.LoadData(deviceType, cid, csd, ocr, extendedCsd, scr);
            tabInfos.Pages.Add(tabSdMmcInfo);

            if (imageFormat is IOpticalMediaImage opticalMediaImage)
            {
                try
                {
                    if (opticalMediaImage.Sessions != null && opticalMediaImage.Sessions.Count > 0)
                    {
                        TreeGridItemCollection sessionList = new TreeGridItemCollection();

                        treeSessions.Columns.Add(new GridColumn
                        {
                            HeaderText = "Session", DataCell = new TextBoxCell(0)
                        });
                        treeSessions.Columns.Add(new GridColumn
                        {
                            HeaderText = "First track", DataCell = new TextBoxCell(1)
                        });
                        treeSessions.Columns.Add(new GridColumn
                        {
                            HeaderText = "Last track", DataCell = new TextBoxCell(2)
                        });
                        treeSessions.Columns.Add(new GridColumn {
                            HeaderText = "Start", DataCell = new TextBoxCell(3)
                        });
                        treeSessions.Columns.Add(new GridColumn {
                            HeaderText = "End", DataCell = new TextBoxCell(4)
                        });

                        treeSessions.AllowMultipleSelection = false;
                        treeSessions.ShowHeader             = true;
                        treeSessions.DataStore = sessionList;

                        foreach (Session session in opticalMediaImage.Sessions)
                        {
                            sessionList.Add(new TreeGridItem
                            {
                                Values = new object[]
                                {
                                    session.SessionSequence, session.StartTrack,
                                    session.EndTrack, session.StartSector, session.EndSector
                                }
                            });
                        }

                        tabSessions.Visible = true;
                    }
                }
                catch
                {
                    // ignored
                }

                try
                {
                    if (opticalMediaImage.Tracks != null && opticalMediaImage.Tracks.Count > 0)
                    {
                        TreeGridItemCollection tracksList = new TreeGridItemCollection();

                        treeTracks.Columns.Add(new GridColumn {
                            HeaderText = "Track", DataCell = new TextBoxCell(0)
                        });
                        treeTracks.Columns.Add(new GridColumn {
                            HeaderText = "Type", DataCell = new TextBoxCell(1)
                        });
                        treeTracks.Columns.Add(new GridColumn {
                            HeaderText = "Bps", DataCell = new TextBoxCell(2)
                        });
                        treeTracks.Columns.Add(new GridColumn {
                            HeaderText = "Raw bps", DataCell = new TextBoxCell(3)
                        });
                        treeTracks.Columns.Add(new GridColumn
                        {
                            HeaderText = "Subchannel", DataCell = new TextBoxCell(4)
                        });
                        treeTracks.Columns.Add(new GridColumn {
                            HeaderText = "Pregap", DataCell = new TextBoxCell(5)
                        });
                        treeTracks.Columns.Add(new GridColumn {
                            HeaderText = "Start", DataCell = new TextBoxCell(6)
                        });
                        treeTracks.Columns.Add(new GridColumn {
                            HeaderText = "End", DataCell = new TextBoxCell(7)
                        });

                        treeTracks.AllowMultipleSelection = false;
                        treeTracks.ShowHeader             = true;
                        treeTracks.DataStore = tracksList;

                        foreach (Track track in opticalMediaImage.Tracks)
                        {
                            tracksList.Add(new TreeGridItem
                            {
                                Values = new object[]
                                {
                                    track.TrackSequence, track.TrackType,
                                    track.TrackBytesPerSector, track.TrackRawBytesPerSector,
                                    track.TrackSubchannelType, track.TrackPregap,
                                    track.TrackStartSector, track.TrackEndSector
                                }
                            });
                        }

                        tabTracks.Visible = true;
                    }
                }
                catch
                {
                    // ignored
                }
            }

            if (imageFormat.DumpHardware == null)
            {
                return;
            }

            TreeGridItemCollection dumpHardwareList = new TreeGridItemCollection();

            treeDumpHardware.Columns.Add(new GridColumn {
                HeaderText = "Manufacturer", DataCell = new TextBoxCell(0)
            });
            treeDumpHardware.Columns.Add(new GridColumn {
                HeaderText = "Model", DataCell = new TextBoxCell(1)
            });
            treeDumpHardware.Columns.Add(new GridColumn {
                HeaderText = "Serial", DataCell = new TextBoxCell(2)
            });
            treeDumpHardware.Columns.Add(new GridColumn {
                HeaderText = "Software", DataCell = new TextBoxCell(3)
            });
            treeDumpHardware.Columns.Add(new GridColumn {
                HeaderText = "Version", DataCell = new TextBoxCell(4)
            });
            treeDumpHardware.Columns.Add(new GridColumn
            {
                HeaderText = "Operating system", DataCell = new TextBoxCell(5)
            });
            treeDumpHardware.Columns.Add(new GridColumn {
                HeaderText = "Start", DataCell = new TextBoxCell(6)
            });
            treeDumpHardware.Columns.Add(new GridColumn {
                HeaderText = "End", DataCell = new TextBoxCell(7)
            });

            treeDumpHardware.AllowMultipleSelection = false;
            treeDumpHardware.ShowHeader             = true;
            treeDumpHardware.DataStore = dumpHardwareList;

            foreach (DumpHardwareType dump in imageFormat.DumpHardware)
            {
                foreach (ExtentType extent in dump.Extents)
                {
                    dumpHardwareList.Add(new TreeGridItem
                    {
                        Values = new object[]
                        {
                            dump.Manufacturer, dump.Model, dump.Serial, dump.Software.Name,
                            dump.Software.Version, dump.Software.OperatingSystem,
                            extent.Start, extent.End
                        }
                    });
                }
            }

            tabDumpHardware.Visible = true;
        }
Пример #3
0
        public ImageInfoViewModel(string imagePath, IFilter filter, IMediaImage imageFormat, Window view)

        {
            _imagePath   = imagePath;
            _filter      = filter;
            _imageFormat = imageFormat;
            _view        = view;
            IAssetLoader assets = AvaloniaLocator.Current.GetService <IAssetLoader>();

            MediaTagsList         = new ObservableCollection <string>();
            SectorTagsList        = new ObservableCollection <string>();
            Sessions              = new ObservableCollection <Session>();
            Tracks                = new ObservableCollection <Track>();
            DumpHardwareList      = new ObservableCollection <DumpHardwareModel>();
            EntropyCommand        = ReactiveCommand.Create(ExecuteEntropyCommand);
            VerifyCommand         = ReactiveCommand.Create(ExecuteVerifyCommand);
            ChecksumCommand       = ReactiveCommand.Create(ExecuteChecksumCommand);
            ConvertCommand        = ReactiveCommand.Create(ExecuteConvertCommand);
            CreateSidecarCommand  = ReactiveCommand.Create(ExecuteCreateSidecarCommand);
            ViewSectorsCommand    = ReactiveCommand.Create(ExecuteViewSectorsCommand);
            DecodeMediaTagCommand = ReactiveCommand.Create(ExecuteDecodeMediaTagCommand);

            var genericHddIcon =
                new Bitmap(assets.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/drive-harddisk.png")));

            var genericOpticalIcon =
                new Bitmap(assets.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/drive-optical.png")));

            var genericFolderIcon =
                new Bitmap(assets.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/inode-directory.png")));

            var mediaResource = new Uri($"avares://Aaru.Gui/Assets/Logos/Media/{imageFormat.Info.MediaType}.png");

            MediaLogo = assets.Exists(mediaResource)
                            ? new Bitmap(assets.Open(mediaResource))
                            : imageFormat.Info.XmlMediaType == XmlMediaType.BlockMedia
                                ? genericHddIcon
                                : imageFormat.Info.XmlMediaType == XmlMediaType.OpticalDisc
                                    ? genericOpticalIcon
                                    : genericFolderIcon;

            ImagePathText       = $"Path: {imagePath}";
            FilterText          = $"Filter: {filter.Name}";
            ImageIdentifiedText = $"Image format identified by {imageFormat.Name} ({imageFormat.Id}).";

            ImageFormatText = !string.IsNullOrWhiteSpace(imageFormat.Info.Version)
                                  ? $"Format: {imageFormat.Format} version {imageFormat.Info.Version}"
                                  : $"Format: {imageFormat.Format}";

            ImageSizeText = $"Image without headers is {imageFormat.Info.ImageSize} bytes long";

            SectorsText =
                $"Contains a media of {imageFormat.Info.Sectors} sectors with a maximum sector size of {imageFormat.Info.SectorSize} bytes (if all sectors are of the same size this would be {imageFormat.Info.Sectors * imageFormat.Info.SectorSize} bytes)";

            MediaTypeText =
                $"Contains a media of type {imageFormat.Info.MediaType} and XML type {imageFormat.Info.XmlMediaType}";

            HasPartitionsText = $"{(imageFormat.Info.HasPartitions ? "Has" : "Doesn't have")} partitions";
            HasSessionsText   = $"{(imageFormat.Info.HasSessions ? "Has" : "Doesn't have")} sessions";

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.Application))
            {
                ApplicationText = !string.IsNullOrWhiteSpace(imageFormat.Info.ApplicationVersion)
                                      ? $"Was created with {imageFormat.Info.Application} version {imageFormat.Info.ApplicationVersion}"
                                      : $"Was created with {imageFormat.Info.Application}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.Creator))
            {
                CreatorText = $"Created by: {imageFormat.Info.Creator}";
            }

            if (imageFormat.Info.CreationTime != DateTime.MinValue)
            {
                CreationTimeText = $"Created on {imageFormat.Info.CreationTime}";
            }

            if (imageFormat.Info.LastModificationTime != DateTime.MinValue)
            {
                LastModificationTimeText = $"Last modified on {imageFormat.Info.LastModificationTime}";
            }

            if (imageFormat.Info.MediaSequence != 0 &&
                imageFormat.Info.LastMediaSequence != 0)
            {
                MediaSequenceText =
                    $"Media is number {imageFormat.Info.MediaSequence} on a set of {imageFormat.Info.LastMediaSequence} medias";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaTitle))
            {
                MediaTitleText = $"Media title: {imageFormat.Info.MediaTitle}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaManufacturer))
            {
                MediaManufacturerText = $"Media manufacturer: {imageFormat.Info.MediaManufacturer}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaModel))
            {
                MediaModelText = $"Media model: {imageFormat.Info.MediaModel}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaSerialNumber))
            {
                MediaSerialNumberText = $"Media serial number: {imageFormat.Info.MediaSerialNumber}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaBarcode))
            {
                MediaBarcodeText = $"Media barcode: {imageFormat.Info.MediaBarcode}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaPartNumber))
            {
                MediaPartNumberText = $"Media part number: {imageFormat.Info.MediaPartNumber}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveManufacturer))
            {
                DriveManufacturerText = $"Drive manufacturer: {imageFormat.Info.DriveManufacturer}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveModel))
            {
                DriveModelText = $"Drive model: {imageFormat.Info.DriveModel}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveSerialNumber))
            {
                DriveSerialNumberText = $"Drive serial number: {imageFormat.Info.DriveSerialNumber}";
            }

            if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveFirmwareRevision))
            {
                DriveFirmwareRevisionText = $"Drive firmware info: {imageFormat.Info.DriveFirmwareRevision}";
            }

            if (imageFormat.Info.Cylinders > 0 &&
                imageFormat.Info.Heads > 0 &&
                imageFormat.Info.SectorsPerTrack > 0 &&
                imageFormat.Info.XmlMediaType != XmlMediaType.OpticalDisc &&
                (!(imageFormat is ITapeImage tapeImage) || !tapeImage.IsTape))
            {
                MediaGeometryText =
                    $"Media geometry: {imageFormat.Info.Cylinders} cylinders, {imageFormat.Info.Heads} heads, {imageFormat.Info.SectorsPerTrack} sectors per track";
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Count > 0)
            {
                foreach (MediaTagType tag in imageFormat.Info.ReadableMediaTags.OrderBy(t => t))
                {
                    MediaTagsList.Add(tag.ToString());
                }
            }

            if (imageFormat.Info.ReadableSectorTags != null &&
                imageFormat.Info.ReadableSectorTags.Count > 0)
            {
                foreach (SectorTagType tag in imageFormat.Info.ReadableSectorTags.OrderBy(t => t))
                {
                    SectorTagsList.Add(tag.ToString());
                }
            }

            PeripheralDeviceTypes scsiDeviceType = PeripheralDeviceTypes.DirectAccess;

            byte[]  scsiInquiryData = null;
            Inquiry?scsiInquiry     = null;

            Modes.DecodedMode?scsiMode        = null;
            byte[]            scsiModeSense6  = null;
            byte[]            scsiModeSense10 = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SCSI_INQUIRY))
            {
                scsiInquiryData = imageFormat.ReadDiskTag(MediaTagType.SCSI_INQUIRY);

                scsiDeviceType = (PeripheralDeviceTypes)(scsiInquiryData[0] & 0x1F);

                scsiInquiry = Inquiry.Decode(scsiInquiryData);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SCSI_MODESENSE_6))
            {
                scsiModeSense6 = imageFormat.ReadDiskTag(MediaTagType.SCSI_MODESENSE_6);
                scsiMode       = Modes.DecodeMode6(scsiModeSense6, scsiDeviceType);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SCSI_MODESENSE_10))
            {
                scsiModeSense10 = imageFormat.ReadDiskTag(MediaTagType.SCSI_MODESENSE_10);
                scsiMode        = Modes.DecodeMode10(scsiModeSense10, scsiDeviceType);
            }

            ScsiInfo = new ScsiInfo
            {
                DataContext = new ScsiInfoViewModel(scsiInquiryData, scsiInquiry, null, scsiMode, scsiDeviceType,
                                                    scsiModeSense6, scsiModeSense10, null, _view)
            };

            byte[] ataIdentify   = null;
            byte[] atapiIdentify = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.ATA_IDENTIFY))
            {
                ataIdentify = imageFormat.ReadDiskTag(MediaTagType.ATA_IDENTIFY);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.ATAPI_IDENTIFY))
            {
                atapiIdentify = imageFormat.ReadDiskTag(MediaTagType.ATAPI_IDENTIFY);
            }

            AtaInfo = new AtaInfo
            {
                DataContext = new AtaInfoViewModel(ataIdentify, atapiIdentify, null, _view)
            };

            byte[]                toc                  = null;
            TOC.CDTOC?            decodedToc           = null;
            byte[]                fullToc              = null;
            FullTOC.CDFullTOC?    decodedFullToc       = null;
            byte[]                pma                  = null;
            byte[]                atip                 = null;
            ATIP.CDATIP?          decodedAtip          = null;
            byte[]                cdtext               = null;
            CDTextOnLeadIn.CDText?decodedCdText        = null;
            string                mediaCatalogueNumber = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_TOC))
            {
                toc = imageFormat.ReadDiskTag(MediaTagType.CD_TOC);

                if (toc.Length > 0)
                {
                    ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(toc, 0));

                    if (dataLen + 2 != toc.Length)
                    {
                        byte[] tmp = new byte[toc.Length + 2];
                        Array.Copy(toc, 0, tmp, 2, toc.Length);
                        tmp[0] = (byte)((toc.Length & 0xFF00) >> 8);
                        tmp[1] = (byte)(toc.Length & 0xFF);
                        toc    = tmp;
                    }

                    decodedToc = TOC.Decode(toc);
                }
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_FullTOC))
            {
                fullToc = imageFormat.ReadDiskTag(MediaTagType.CD_FullTOC);

                if (fullToc.Length > 0)
                {
                    ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(fullToc, 0));

                    if (dataLen + 2 != fullToc.Length)
                    {
                        byte[] tmp = new byte[fullToc.Length + 2];
                        Array.Copy(fullToc, 0, tmp, 2, fullToc.Length);
                        tmp[0]  = (byte)((fullToc.Length & 0xFF00) >> 8);
                        tmp[1]  = (byte)(fullToc.Length & 0xFF);
                        fullToc = tmp;
                    }

                    decodedFullToc = FullTOC.Decode(fullToc);
                }
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_PMA))
            {
                pma = imageFormat.ReadDiskTag(MediaTagType.CD_PMA);

                if (pma.Length > 0)
                {
                    ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(pma, 0));

                    if (dataLen + 2 != pma.Length)
                    {
                        byte[] tmp = new byte[pma.Length + 2];
                        Array.Copy(pma, 0, tmp, 2, pma.Length);
                        tmp[0] = (byte)((pma.Length & 0xFF00) >> 8);
                        tmp[1] = (byte)(pma.Length & 0xFF);
                        pma    = tmp;
                    }
                }
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_ATIP))
            {
                atip = imageFormat.ReadDiskTag(MediaTagType.CD_ATIP);

                uint dataLen = Swapping.Swap(BitConverter.ToUInt32(atip, 0));

                if (dataLen + 4 != atip.Length)
                {
                    byte[] tmp = new byte[atip.Length + 4];
                    Array.Copy(atip, 0, tmp, 4, atip.Length);
                    tmp[0] = (byte)((atip.Length & 0xFF000000) >> 24);
                    tmp[1] = (byte)((atip.Length & 0xFF0000) >> 16);
                    tmp[2] = (byte)((atip.Length & 0xFF00) >> 8);
                    tmp[3] = (byte)(atip.Length & 0xFF);
                    atip   = tmp;
                }

                decodedAtip = ATIP.Decode(atip);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_TEXT))
            {
                cdtext = imageFormat.ReadDiskTag(MediaTagType.CD_TEXT);

                uint dataLen = Swapping.Swap(BitConverter.ToUInt32(cdtext, 0));

                if (dataLen + 4 != cdtext.Length)
                {
                    byte[] tmp = new byte[cdtext.Length + 4];
                    Array.Copy(cdtext, 0, tmp, 4, cdtext.Length);
                    tmp[0] = (byte)((cdtext.Length & 0xFF000000) >> 24);
                    tmp[1] = (byte)((cdtext.Length & 0xFF0000) >> 16);
                    tmp[2] = (byte)((cdtext.Length & 0xFF00) >> 8);
                    tmp[3] = (byte)(cdtext.Length & 0xFF);
                    cdtext = tmp;
                }

                decodedCdText = CDTextOnLeadIn.Decode(cdtext);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_MCN))
            {
                byte[] mcn = imageFormat.ReadDiskTag(MediaTagType.CD_MCN);

                mediaCatalogueNumber = Encoding.UTF8.GetString(mcn);
            }

            CompactDiscInfo = new CompactDiscInfo
            {
                DataContext = new CompactDiscInfoViewModel(toc, atip, null, null, fullToc, pma, cdtext, decodedToc,
                                                           decodedAtip, null, decodedFullToc, decodedCdText, null,
                                                           mediaCatalogueNumber, null, _view)
            };

            byte[] dvdPfi = null;
            byte[] dvdDmi = null;
            byte[] dvdCmi = null;
            byte[] hddvdCopyrightInformation = null;
            byte[] dvdBca = null;
            PFI.PhysicalFormatInformation?decodedPfi = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_PFI))
            {
                dvdPfi     = imageFormat.ReadDiskTag(MediaTagType.DVD_PFI);
                decodedPfi = PFI.Decode(dvdPfi);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_DMI))
            {
                dvdDmi = imageFormat.ReadDiskTag(MediaTagType.DVD_DMI);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_CMI))
            {
                dvdCmi = imageFormat.ReadDiskTag(MediaTagType.DVD_CMI);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.HDDVD_CPI))
            {
                hddvdCopyrightInformation = imageFormat.ReadDiskTag(MediaTagType.HDDVD_CPI);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_BCA))
            {
                dvdBca = imageFormat.ReadDiskTag(MediaTagType.DVD_BCA);
            }

            DvdInfo = new DvdInfo
            {
                DataContext = new DvdInfoViewModel(imageFormat.Info.MediaType, dvdPfi, dvdDmi, dvdCmi,
                                                   hddvdCopyrightInformation, dvdBca, null, decodedPfi, _view)
            };

            byte[] dvdRamDds                     = null;
            byte[] dvdRamCartridgeStatus         = null;
            byte[] dvdRamSpareArea               = null;
            byte[] lastBorderOutRmd              = null;
            byte[] dvdPreRecordedInfo            = null;
            byte[] dvdrMediaIdentifier           = null;
            byte[] dvdrPhysicalInformation       = null;
            byte[] hddvdrMediumStatus            = null;
            byte[] dvdrLayerCapacity             = null;
            byte[] dvdrDlMiddleZoneStart         = null;
            byte[] dvdrDlJumpIntervalSize        = null;
            byte[] dvdrDlManualLayerJumpStartLba = null;
            byte[] dvdPlusAdip                   = null;
            byte[] dvdPlusDcb                    = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDRAM_DDS))
            {
                dvdRamDds = imageFormat.ReadDiskTag(MediaTagType.DVDRAM_DDS);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDRAM_MediumStatus))
            {
                dvdRamCartridgeStatus = imageFormat.ReadDiskTag(MediaTagType.DVDRAM_MediumStatus);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDRAM_SpareArea))
            {
                dvdRamSpareArea = imageFormat.ReadDiskTag(MediaTagType.DVDRAM_SpareArea);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_RMD))
            {
                lastBorderOutRmd = imageFormat.ReadDiskTag(MediaTagType.DVDR_RMD);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_PreRecordedInfo))
            {
                dvdPreRecordedInfo = imageFormat.ReadDiskTag(MediaTagType.DVDR_PreRecordedInfo);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_MediaIdentifier))
            {
                dvdrMediaIdentifier = imageFormat.ReadDiskTag(MediaTagType.DVDR_MediaIdentifier);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_PFI))
            {
                dvdrPhysicalInformation = imageFormat.ReadDiskTag(MediaTagType.DVDR_PFI);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.HDDVD_MediumStatus))
            {
                hddvdrMediumStatus = imageFormat.ReadDiskTag(MediaTagType.HDDVD_MediumStatus);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_LayerCapacity))
            {
                dvdrLayerCapacity = imageFormat.ReadDiskTag(MediaTagType.DVDDL_LayerCapacity);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_MiddleZoneAddress))
            {
                dvdrDlMiddleZoneStart = imageFormat.ReadDiskTag(MediaTagType.DVDDL_MiddleZoneAddress);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_JumpIntervalSize))
            {
                dvdrDlJumpIntervalSize = imageFormat.ReadDiskTag(MediaTagType.DVDDL_JumpIntervalSize);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_ManualLayerJumpLBA))
            {
                dvdrDlManualLayerJumpStartLba = imageFormat.ReadDiskTag(MediaTagType.DVDDL_ManualLayerJumpLBA);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_ADIP))
            {
                dvdPlusAdip = imageFormat.ReadDiskTag(MediaTagType.DVD_ADIP);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DCB))
            {
                dvdPlusDcb = imageFormat.ReadDiskTag(MediaTagType.DCB);
            }

            DvdWritableInfo = new DvdWritableInfo
            {
                DataContext = new DvdWritableInfoViewModel(imageFormat.Info.MediaType, dvdRamDds, dvdRamCartridgeStatus,
                                                           dvdRamSpareArea, lastBorderOutRmd, dvdPreRecordedInfo,
                                                           dvdrMediaIdentifier, dvdrPhysicalInformation,
                                                           hddvdrMediumStatus, null, dvdrLayerCapacity,
                                                           dvdrDlMiddleZoneStart, dvdrDlJumpIntervalSize,
                                                           dvdrDlManualLayerJumpStartLba, null, dvdPlusAdip, dvdPlusDcb,
                                                           _view)
            };

            byte[] blurayBurstCuttingArea = null;
            byte[] blurayCartridgeStatus  = null;
            byte[] blurayDds                  = null;
            byte[] blurayDiscInformation      = null;
            byte[] blurayPowResources         = null;
            byte[] bluraySpareAreaInformation = null;
            byte[] blurayTrackResources       = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_BCA))
            {
                blurayBurstCuttingArea = imageFormat.ReadDiskTag(MediaTagType.BD_BCA);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_CartridgeStatus))
            {
                blurayCartridgeStatus = imageFormat.ReadDiskTag(MediaTagType.BD_CartridgeStatus);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_DDS))
            {
                blurayDds = imageFormat.ReadDiskTag(MediaTagType.BD_DDS);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_DI))
            {
                blurayDiscInformation = imageFormat.ReadDiskTag(MediaTagType.BD_DI);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_POWResourcesInformation))
            {
                blurayPowResources = imageFormat.ReadDiskTag(MediaTagType.MMC_POWResourcesInformation);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_SpareArea))
            {
                bluraySpareAreaInformation = imageFormat.ReadDiskTag(MediaTagType.BD_SpareArea);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_TrackResourcesInformation))
            {
                bluraySpareAreaInformation = imageFormat.ReadDiskTag(MediaTagType.MMC_TrackResourcesInformation);
            }

            BlurayInfo = new BlurayInfo
            {
                DataContext = new BlurayInfoViewModel(blurayDiscInformation, blurayBurstCuttingArea, blurayDds,
                                                      blurayCartridgeStatus, bluraySpareAreaInformation,
                                                      blurayPowResources, blurayTrackResources, null, null, _view)
            };

            byte[]            xboxDmi                   = null;
            byte[]            xboxSecuritySector        = null;
            SS.SecuritySector?decodedXboxSecuritySector = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.Xbox_DMI))
            {
                xboxDmi = imageFormat.ReadDiskTag(MediaTagType.Xbox_DMI);
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.Xbox_SecuritySector))
            {
                xboxSecuritySector        = imageFormat.ReadDiskTag(MediaTagType.Xbox_SecuritySector);
                decodedXboxSecuritySector = SS.Decode(xboxSecuritySector);
            }

            XboxInfo = new XboxInfo
            {
                DataContext = new XboxInfoViewModel(null, xboxDmi, xboxSecuritySector, decodedXboxSecuritySector, _view)
            };

            byte[] pcmciaCis = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.PCMCIA_CIS))
            {
                pcmciaCis = imageFormat.ReadDiskTag(MediaTagType.PCMCIA_CIS);
            }

            PcmciaInfo = new PcmciaInfo
            {
                DataContext = new PcmciaInfoViewModel(pcmciaCis, _view)
            };

            DeviceType deviceType = DeviceType.Unknown;

            byte[] cid         = null;
            byte[] csd         = null;
            byte[] ocr         = null;
            byte[] extendedCsd = null;
            byte[] scr         = null;

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_CID))
            {
                cid        = imageFormat.ReadDiskTag(MediaTagType.SD_CID);
                deviceType = DeviceType.SecureDigital;
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_CSD))
            {
                csd        = imageFormat.ReadDiskTag(MediaTagType.SD_CSD);
                deviceType = DeviceType.SecureDigital;
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_OCR))
            {
                ocr        = imageFormat.ReadDiskTag(MediaTagType.SD_OCR);
                deviceType = DeviceType.SecureDigital;
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_SCR))
            {
                scr        = imageFormat.ReadDiskTag(MediaTagType.SD_SCR);
                deviceType = DeviceType.SecureDigital;
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_CID))
            {
                cid        = imageFormat.ReadDiskTag(MediaTagType.MMC_CID);
                deviceType = DeviceType.MMC;
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_CSD))
            {
                csd        = imageFormat.ReadDiskTag(MediaTagType.MMC_CSD);
                deviceType = DeviceType.MMC;
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_OCR))
            {
                ocr        = imageFormat.ReadDiskTag(MediaTagType.MMC_OCR);
                deviceType = DeviceType.MMC;
            }

            if (imageFormat.Info.ReadableMediaTags != null &&
                imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_ExtendedCSD))
            {
                extendedCsd = imageFormat.ReadDiskTag(MediaTagType.MMC_ExtendedCSD);
                deviceType  = DeviceType.MMC;
            }

            SdMmcInfo = new SdMmcInfo
            {
                DataContext = new SdMmcInfoViewModel(deviceType, cid, csd, ocr, extendedCsd, scr)
            };

            if (imageFormat is IOpticalMediaImage opticalMediaImage)
            {
                try
                {
                    if (opticalMediaImage.Sessions != null &&
                        opticalMediaImage.Sessions.Count > 0)
                    {
                        foreach (Session session in opticalMediaImage.Sessions)
                        {
                            Sessions.Add(session);
                        }
                    }
                }
                catch
                {
                    // ignored
                }

                try
                {
                    if (opticalMediaImage.Tracks != null &&
                        opticalMediaImage.Tracks.Count > 0)
                    {
                        foreach (Track track in opticalMediaImage.Tracks)
                        {
                            Tracks.Add(track);
                        }
                    }
                }
                catch
                {
                    // ignored
                }
            }

            if (imageFormat.DumpHardware is null)
            {
                return;
            }

            foreach (DumpHardwareType dump in imageFormat.DumpHardware)
            {
                foreach (ExtentType extent in dump.Extents)
                {
                    DumpHardwareList.Add(new DumpHardwareModel
                    {
                        Manufacturer    = dump.Manufacturer, Model = dump.Model, Serial = dump.Serial,
                        SoftwareName    = dump.Software.Name, SoftwareVersion = dump.Software.Version,
                        OperatingSystem = dump.Software.OperatingSystem, Start = extent.Start, End = extent.End
                    });
                }
            }
        }