internal static IpBin GetIpData(byte[] ipData)
        {
            var dreamcastip = Aaru.Decoders.Sega.Dreamcast.DecodeIPBin(ipData);

            if (dreamcastip == null)
            {
                return(null);
            }

            var ipbin = dreamcastip.Value;

            var special     = SpecialDisc.None;
            var releaseDate = GetString(ipbin.release_date);
            var version     = GetString(ipbin.product_version);

            string disc;

            if (ipbin.disc_no == 32 || ipbin.disc_total_nos == 32)
            {
                disc = "1/1";
                if (GetString(ipbin.dreamcast_media) == "FCD" && releaseDate == "20000627" && version == "V1.000" && GetString(ipbin.boot_filename) == "PELICAN.BIN")
                {
                    special = SpecialDisc.CodeBreaker;
                }
            }
            else
            {
                disc = $"{(char)ipbin.disc_no}/{(char)ipbin.disc_total_nos}";
            }

            //int iPeripherals = int.Parse(Encoding.ASCII.GetString(ipbin.peripherals), System.Globalization.NumberStyles.HexNumber);

            var ip = new IpBin
            {
                CRC           = GetString(ipbin.dreamcast_crc),
                Disc          = disc,
                Region        = GetString(ipbin.region_codes),
                Vga           = ipbin.peripherals[5] == 49,
                ProductNumber = GetString(ipbin.product_no),
                Version       = version,
                ReleaseDate   = releaseDate,
                Name          = GetString(ipbin.product_name),
                SpecialDisc   = special
            };

            return(ip);
        }
Example #2
0
        private void FillListText(StringBuilder sb, IpBin ip, string name, int number)
        {
            string strnumber = FormatFolderNumber(number);

            sb.AppendLine($"{strnumber}.name={name}");
            if (ip.SpecialDisc == SpecialDisc.CodeBreaker)
            {
                sb.AppendLine($"{strnumber}.disc=");
            }
            else
            {
                sb.AppendLine($"{strnumber}.disc={ip.Disc}");
            }
            sb.AppendLine($"{strnumber}.vga={(ip.Vga ? '1' : '0')}");
            sb.AppendLine($"{strnumber}.region={ip.Region}");
            sb.AppendLine($"{strnumber}.version={ip.Version}");
            sb.AppendLine($"{strnumber}.date={ip.ReleaseDate}");
            sb.AppendLine();
        }
Example #3
0
        private void FillListText(StringBuilder sb, IpBin ip, string name, int number, bool is_openmenu = false)
        {
            string strnumber = FormatFolderNumber(number);

            sb.AppendLine($"{strnumber}.name={name}");
            if (ip.SpecialDisc == SpecialDisc.CodeBreaker)
            {
                sb.AppendLine($"{strnumber}.disc=");
            }
            else
            {
                sb.AppendLine($"{strnumber}.disc={ip.Disc}");
            }
            sb.AppendLine($"{strnumber}.vga={(ip.Vga ? '1' : '0')}");
            sb.AppendLine($"{strnumber}.region={ip.Region}");
            sb.AppendLine($"{strnumber}.version={ip.Version}");
            sb.AppendLine($"{strnumber}.date={ip.ReleaseDate}");
            if (is_openmenu)
            {
                string productid = ip.ProductNumber?.Replace("-", "").Split(' ')[0];
                sb.AppendLine($"{strnumber}.product={productid}");
            }
            sb.AppendLine();
        }
Example #4
0
        private async Task <GdItem> LazyLoadItemFromCard(int sdNumber, string folderPath)
        {
            var files = await Helper.GetFilesAsync(folderPath);

            var itemName = string.Empty;
            var nameFile = files.FirstOrDefault(x => Path.GetFileName(x).Equals(Constants.NameTextFile, StringComparison.OrdinalIgnoreCase));

            if (nameFile != null)
            {
                itemName = await Helper.ReadAllTextAsync(nameFile);
            }

            if (string.IsNullOrWhiteSpace(nameFile))
            {
                return(null);
            }

            var itemSerial = string.Empty;
            var serialFile = files.FirstOrDefault(x => Path.GetFileName(x).Equals(Constants.SerialTextFile, StringComparison.OrdinalIgnoreCase));

            if (serialFile != null)
            {
                itemSerial = await Helper.ReadAllTextAsync(serialFile);
            }

            itemName   = itemName.Trim();
            itemSerial = itemSerial.Trim();

            var itemIP = new IpBin();

            itemIP.ProductNumber = itemSerial;

            string itemImageFile = null;

            //is uncompressed?
            foreach (var file in files)
            {
                if (supportedImageFormats.Any(x => x.Equals(Path.GetExtension(file), StringComparison.OrdinalIgnoreCase)))
                {
                    itemImageFile = file;
                    break;
                }
            }

            if (itemImageFile == null)
            {
                throw new Exception("No valid image found on folder");
            }

            var item = new GdItem
            {
                Guid           = Guid.NewGuid().ToString(),
                FullFolderPath = folderPath,
                FileFormat     = FileFormat.Uncompressed,
                SdNumber       = sdNumber,
                Name           = itemName,
                Ip             = itemIP,
                Length         = ByteSizeLib.ByteSize.FromBytes(new DirectoryInfo(folderPath).GetFiles().Sum(x => x.Length)),
            };

            item.ImageFiles.Add(Path.GetFileName(itemImageFile));

            return(item);
        }
        internal static async Task <GdItem> CreateGdItem2Async(string filePath)
        {
            string folderPath = Path.GetDirectoryName(filePath);

            var item = new GdItem
            {
                Guid           = Guid.NewGuid().ToString(),
                FullFolderPath = folderPath,
                FileFormat     = FileFormat.Uncompressed
            };

            IpBin ip = null;

            var    ext           = Path.GetExtension(filePath).ToLower();
            string itemImageFile = null;

            item.ImageFiles.Add(Path.GetFileName(filePath));

            if (ext == ".gdi")
            {
                itemImageFile = filePath;

                var gdi = await GetGdiFileListAsync(filePath);

                foreach (var datafile in gdi.Where(x => !x.EndsWith(".raw", StringComparison.InvariantCultureIgnoreCase)).Skip(1))
                {
                    ip = await Task.Run(() => GetIpData(Path.Combine(item.FullFolderPath, datafile)));

                    if (ip != null)
                    {
                        break;
                    }
                }

                var gdifiles = gdi.Distinct().ToArray();
                item.ImageFiles.AddRange(gdifiles);
            }
            else
            {
                var    imageNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath);
                string dataFile;
                if (ext == ".ccd")
                {
                    var img = Path.ChangeExtension(filePath, ".img");
                    if (!File.Exists(img))
                    {
                        throw new Exception("Missing file: " + img);
                    }
                    item.ImageFiles.Add(Path.GetFileName(img));

                    var sub = Path.ChangeExtension(filePath, ".sub");
                    if (File.Exists(sub))
                    {
                        item.ImageFiles.Add(Path.GetFileName(sub));
                    }

                    dataFile = img;
                }
                else if (ext == ".mds")
                {
                    var mdf = Path.ChangeExtension(filePath, ".mdf");
                    if (!File.Exists(mdf))
                    {
                        throw new Exception("Missing file: " + mdf);
                    }
                    item.ImageFiles.Add(Path.GetFileName(mdf));

                    dataFile = mdf;
                }
                else //cdi
                {
                    dataFile = filePath;
                }

                ip = await Task.Run(() => GetIpData(dataFile));
            }


            if (ip == null)
            {
                throw new Exception("Cant't read data from file");
            }


            item.Ip   = ip;
            item.Name = ip.Name;

            var itemNamePath = Path.Combine(item.FullFolderPath, Constants.NameTextFile);

            if (await Helper.FileExistsAsync(itemNamePath))
            {
                item.Name = await Helper.ReadAllTextAsync(itemNamePath);
            }

            var itemSerialPath = Path.Combine(item.FullFolderPath, Constants.SerialTextFile);

            if (await Helper.FileExistsAsync(itemSerialPath))
            {
                item.Ip.ProductNumber = await Helper.ReadAllTextAsync(itemSerialPath);
            }

            item.Name             = item.Name.Trim();
            item.Ip.ProductNumber = item.Ip.ProductNumber.Trim();

            if (item.FullFolderPath.StartsWith(Manager.sdPath, StringComparison.InvariantCultureIgnoreCase) && int.TryParse(new DirectoryInfo(item.FullFolderPath).Name, out int number))
            {
                item.SdNumber = number;
            }

            Manager.UpdateItemLength(item);

            return(item);
        }
        public static async Task <GdItem> CreateGdItemAsync(string fileOrFolderPath)
        {
            string folderPath;

            string[] files;

            FileAttributes attr = await Helper.GetAttributesAsync(fileOrFolderPath);//path is a file or folder?

            if (attr.HasFlag(FileAttributes.Directory))
            {
                folderPath = fileOrFolderPath;
                files      = await Helper.GetFilesAsync(folderPath);
            }
            else
            {
                folderPath = Path.GetDirectoryName(fileOrFolderPath);
                files      = new string[] { fileOrFolderPath };
            }

            var item = new GdItem
            {
                Guid           = Guid.NewGuid().ToString(),
                FullFolderPath = folderPath,
                FileFormat     = FileFormat.Uncompressed
            };

            IpBin  ip            = null;
            string itemImageFile = null;

            //is uncompressed?
            foreach (var file in files)
            {
                var fileExt = Path.GetExtension(file).ToLower();
                if (Manager.supportedImageFormats.Any(x => x == fileExt))
                {
                    itemImageFile = file;
                    break;
                }
            }

            //is compressed?
            if (itemImageFile == null && files.Any(Helper.CompressedFileExpression))
            {
                string compressedFile = files.First(Helper.CompressedFileExpression);

                var filesInsideArchive = await Task.Run(() => Helper.DependencyManager.GetArchiveFiles(compressedFile));

                foreach (var file in filesInsideArchive.Keys)
                {
                    var fileExt = Path.GetExtension(file).ToLower();
                    if (Manager.supportedImageFormats.Any(x => x == fileExt))
                    {
                        itemImageFile = file;
                        break;
                    }
                }

                item.CanApplyGDIShrink = filesInsideArchive.Keys.Any(x => Path.GetExtension(x).Equals(".gdi", StringComparison.InvariantCultureIgnoreCase));

                if (!string.IsNullOrEmpty(itemImageFile))
                {
                    item.ImageFiles.Add(Path.GetFileName(compressedFile));

                    var itemName = Path.GetFileNameWithoutExtension(compressedFile);
                    var m        = RegularExpressions.TosecnNameRegexp.Match(itemName);
                    if (m.Success)
                    {
                        itemName = itemName.Substring(0, m.Index);
                    }

                    ip = new IpBin
                    {
                        Name = itemName,
                        Disc = "?/?"
                    };

                    item.Length     = ByteSizeLib.ByteSize.FromBytes(filesInsideArchive.Sum(x => x.Value));
                    item.FileFormat = FileFormat.SevenZip;
                }
            }

            if (itemImageFile == null)
            {
                throw new Exception("Cant't read data from file");
            }

            if (item.FileFormat == FileFormat.Uncompressed)
            {
                var     filtersList = new FiltersList();
                IFilter inputFilter = null;
                try
                {
                    inputFilter = await Task.Run(() => filtersList.GetFilter(itemImageFile));

                    //todo check inputFilter null Cannot open specified file.

                    IOpticalMediaImage opticalImage;

                    switch (Path.GetExtension(itemImageFile).ToLower())
                    {
                    case ".gdi":
                        opticalImage = new Aaru.DiscImages.Gdi();
                        break;

                    case ".cdi":
                        opticalImage = new Aaru.DiscImages.DiscJuggler();
                        break;

                    case ".mds":
                        opticalImage = new Aaru.DiscImages.Alcohol120();
                        break;

                    case ".ccd":
                        opticalImage = new Aaru.DiscImages.CloneCd();
                        break;

                    default:
                        throw new NotSupportedException();
                    }

                    //if(!opticalImage.Identify(inputFilter))
                    //    throw new NotSupportedException();

                    //todo check imageFormat null Image format not identified.

                    try
                    {
                        bool useAaru;
                        try
                        {
                            useAaru = await Task.Run(() => opticalImage.Open(inputFilter));
                        }
                        catch (Exception)
                        {
                            useAaru = false;
                            opticalImage?.Close();
                        }


                        if (useAaru) //try to load file using Aaru
                        {
                            try
                            {
                                Partition partition;

                                if (Path.GetExtension(itemImageFile).Equals(".gdi", StringComparison.InvariantCultureIgnoreCase))//first track not audio and skip one
                                {
                                    partition = opticalImage.Partitions.Where(x => x.Type != "Audio").Skip(1).First();
                                    ip        = await GetIpData(opticalImage, partition);
                                }
                                else//try to find from last
                                {
                                    for (int i = opticalImage.Partitions.Count - 1; i >= 0; i--)
                                    {
                                        partition = opticalImage.Partitions[i];
                                        ip        = await GetIpData(opticalImage, partition);

                                        if (ip != null)
                                        {
                                            break;
                                        }
                                    }
                                }

                                //Aaru fails to read the ip.bin from some cdis in CdMode2Formless.
                                if (ip == null)
                                {
                                    throw new Exception();
                                }

                                //var imageFiles = new List<string> { Path.GetFileName(item.ImageFile) };
                                item.ImageFiles.Add(Path.GetFileName(itemImageFile));
                                foreach (var track in opticalImage.Tracks)
                                {
                                    if (!string.IsNullOrEmpty(track.TrackFile) && !item.ImageFiles.Any(x => x.Equals(track.TrackFile, StringComparison.InvariantCultureIgnoreCase)))
                                    {
                                        item.ImageFiles.Add(track.TrackFile);
                                    }
                                    if (!string.IsNullOrEmpty(track.TrackSubchannelFile) && !item.ImageFiles.Any(x => x.Equals(track.TrackSubchannelFile, StringComparison.InvariantCultureIgnoreCase)))
                                    {
                                        item.ImageFiles.Add(track.TrackSubchannelFile);
                                    }
                                }

                                item.CanApplyGDIShrink = Path.GetExtension(itemImageFile).Equals(".gdi", StringComparison.InvariantCultureIgnoreCase);

                                Manager.UpdateItemLength(item);
                            }
                            catch
                            {
                                useAaru = false;
                            }
                            finally
                            {
                                opticalImage?.Close();
                            }
                        }


                        if (!useAaru) //if cant open using Aaru, try to parse file manually
                        {
                            if (inputFilter != null && inputFilter.IsOpened())
                            {
                                inputFilter.Close();
                            }

                            var temp = await CreateGdItem2Async(itemImageFile);

                            if (temp == null || temp.Ip == null)
                            {
                                throw new Exception("Unable to open image format");
                            }

                            ip   = temp.Ip;
                            item = temp;
                        }
                    }
                    finally
                    {
                        opticalImage?.Close();
                    }
                }
                //catch (Exception ex)
                //{

                //    throw;
                //}
                finally
                {
                    if (inputFilter != null && inputFilter.IsOpened())
                    {
                        inputFilter.Close();
                    }
                }
            }

            if (ip == null)
            {
                throw new Exception("Cant't read data from file");
            }


            item.Ip   = ip;
            item.Name = ip.Name;

            var itemNamePath = Path.Combine(item.FullFolderPath, Constants.NameTextFile);

            if (await Helper.FileExistsAsync(itemNamePath))
            {
                item.Name = await Helper.ReadAllTextAsync(itemNamePath);
            }

            var itemSerialPath = Path.Combine(item.FullFolderPath, Constants.SerialTextFile);

            if (await Helper.FileExistsAsync(itemSerialPath))
            {
                item.Ip.ProductNumber = await Helper.ReadAllTextAsync(itemSerialPath);
            }

            item.Name             = item.Name.Trim();
            item.Ip.ProductNumber = item.Ip.ProductNumber.Trim();

            if (item.FullFolderPath.StartsWith(Manager.sdPath, StringComparison.InvariantCultureIgnoreCase) && int.TryParse(Path.GetFileName(Path.GetDirectoryName(itemImageFile)), out int number))
            {
                item.SdNumber = number;
            }

            //item.ImageFile = Path.GetFileName(item.ImageFile);

            return(item);
        }