//returns null if file not exists on image. throw on any error public static async Task <byte[]> GetGdText(string itemImageFile) { var filtersList = new FiltersList(); IFilter inputFilter = null; try { inputFilter = 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 { if (!await Task.Run(() => opticalImage.Open(inputFilter))) { throw new Exception("Can't load game file"); } Partition partition; string filename = "0GDTEX.PVR"; 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(); return(await Task.Run(() => extractFileFromPartition(opticalImage, partition, filename))); } else//try to find from last { for (int i = opticalImage.Partitions.Count - 1; i >= 0; i--) { partition = opticalImage.Partitions[i]; if ((await GetIpData(opticalImage, partition)) != null) { return(await Task.Run(() => extractFileFromPartition(opticalImage, partition, filename))); } } } return(null); } finally { opticalImage?.Close(); } } finally { if (inputFilter != null && inputFilter.IsOpened()) { inputFilter.Close(); } } }
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); }