示例#1
0
        public static void WriteIso(UmdDisc disc, string filename)
        {
            using var stream = new FileStream(filename, FileMode.Open, FileAccess.Write);
            using var writer = new BinaryWriter(stream);

            foreach (var sector in disc.Sectors)
            {
            }
        }
示例#2
0
 public static byte[] DecodeData(UmdDiscSector sector, UmdDisc disc, UmdDisc parentDisc)
 {
     return(sector.Encoding switch
     {
         UmdEncoding.None => sector.Data ?? throw new InvalidOperationException("No data in sector"),
         UmdEncoding.InternalLink => DecodeInternalLink(sector, disc) ?? throw new InvalidOperationException("Internally linked sector has no data."),
         UmdEncoding.ExternalLink => DecodeExternalLink(sector, parentDisc) ?? throw new InvalidOperationException("Internally linked sector has no data."),
         _ => throw new InvalidOperationException("Unsupported encoding")
     });
示例#3
0
        // TODO: optimize this method
        public static async Task Merge(UmdDisc masterDisc, UmdDisc disc)
        {
            var masterSectors = masterDisc.Sectors.Where(s => s.Encoding == UmdEncoding.None).OrderBy(s => s.Crc32).ToList();
            var sectors       = disc.Sectors.Where(s => s.Encoding == UmdEncoding.None).OrderBy(s => s.Crc32).ToList();

            // if nothing to compare return
            if ((masterSectors == null) ||
                (sectors == null) ||
                (!masterSectors.Any()) ||
                (!sectors.Any()))
            {
                return;
            }

            int masterCursor = 0, cursor = 0;

            // sync cursors
            while ((masterCursor < masterSectors.Count) && (cursor < sectors.Count))
            {
                if (masterSectors[masterCursor].Crc32 == sectors[cursor].Crc32)
                {
                    int subCursor = 0;
                    while ((masterCursor + subCursor < masterSectors.Count) && (masterSectors[masterCursor].Crc32 == masterSectors[masterCursor + subCursor].Crc32))
                    {
                        if ((masterSectors[masterCursor + subCursor].Data != null) &&
                            (sectors[cursor].Data != null) &&
                            (await BinaryComparer.Compare(masterSectors[masterCursor + subCursor].Data, 0, sectors[cursor].Data, 0, UmdDisc.SectorSize)))
                        {
                            sectors[cursor].Encoding = UmdEncoding.ExternalLink;
                            sectors[cursor].Data     = GetLinkData(masterSectors[masterCursor + subCursor].Id);
                            sectors[cursor].Length   = 4;
                            sectors[cursor].Crc32    = Crc32Algorithm.Compute(sectors[cursor].Data, 0, 4);
                            break;
                        }
                        subCursor++;
                    }

                    cursor++;
                    continue;
                }

                if (masterSectors[masterCursor].Crc32 < sectors[cursor].Crc32)
                {
                    masterCursor++;
                    continue;
                }

                if (masterSectors[masterCursor].Crc32 > sectors[cursor].Crc32)
                {
                    cursor++;
                    continue;
                }
            }
        }
示例#4
0
        public static async Task InternalMerge(UmdDisc disc)
        {
            IEnumerable <UmdDiscSector> sectors = disc.Sectors.Where(s => s.Encoding == UmdEncoding.None).ToList();
            uint pass = 1;

            while (sectors.Any())
            {
                System.Console.WriteLine($"Internal merge pass {pass}: {sectors.Count()} sectors.");
                sectors = await InternalMergePass(sectors);

                pass++;
            }
        }
示例#5
0
        public static UmdDisc?ReadFromIso(string filename, bool withData = false)
        {
            const ushort sectorSize = 2048;

            try
            {
                var result   = new UmdDisc();
                var fileInfo = new FileInfo(filename);
                if (fileInfo.Length % sectorSize != 0)
                {
                    return(null);
                }

                var buffer = new byte[sectorSize];
                using var stream = new FileStream(filename, FileMode.Open, FileAccess.Read);
                using var reader = new BinaryReader(stream);
                uint sectorCount = (uint)(fileInfo.Length / sectorSize);
                for (uint i = 0; i < sectorCount; i++)
                {
                    reader.Read(buffer, 0, sectorSize);

                    var sector = new UmdDiscSector
                    {
                        Id            = i,
                        Crc32         = Crc32Algorithm.Compute(buffer, 0, sectorSize),
                        Length        = sectorSize,
                        StartPostiion = (uint)(i * sectorSize)
                    };

                    if (withData)
                    {
                        sector.Data = buffer;
                        buffer      = new byte[sectorSize];
                    }

                    result.Sectors.Add(sector);
                }

                return(result);
            }
            catch
            {
                return(null);
            }
        }
示例#6
0
        private static byte[]? DecodeInternalLink(UmdDiscSector sector, UmdDisc disc)
        {
            var sectorId = BitConverter.ToInt32(sector.Data);

            return(disc.Sectors[sectorId].Data);
        }