public static VirtualFileSystemEntry ToVirtualFileSystemEntry(this CDReader isoFileSystem, string path) { if (isoFileSystem.FileExists(path)) { var fileName = Path.GetFileName(path); if (fileName.EndsWith(";1")) { fileName = fileName.Substring(0, fileName.Length - 2); } return(new VirtualFile(null, isoFileSystem.OpenFile(path, FileMode.Open), fileName)); } else { var directory = new VirtualDirectory(null, Path.GetFileName(path)); foreach (var file in isoFileSystem.GetFiles(path)) { var entry = ToVirtualFileSystemEntry(isoFileSystem, file); entry.MoveTo(directory); } foreach (var subDirectory in isoFileSystem.GetDirectories(path)) { var entry = ToVirtualFileSystemEntry(isoFileSystem, subDirectory); entry.MoveTo(directory); } return(directory); } }
/// <summary> /// Retrieve the VOL stream(s) and the corresponding filename. /// </summary> /// <returns></returns> public IEnumerable <(Stream stream, string fileName)> GetStreams() { if (!_parsed) { GetFileType(); } switch (_fileType) { case FileType.TOC31_VOL: yield return(new FileStream(_filePath, FileMode.Open, FileAccess.Read), Path.GetFileName(_filePath)); break; case FileType.TOC31_ISO: using (FileStream isoStream = File.Open(_filePath, FileMode.Open)) { CDReader cd = new CDReader(isoStream, true, true); var nextDescriptor = cd.ClusterSize * cd.TotalClusters; var vols = cd.GetFiles("", "*.*", SearchOption.AllDirectories) .ToList() .Where(x => x.EndsWith(".VOL", StringComparison.OrdinalIgnoreCase)) .ToArray(); foreach (var volFile in vols) { yield return(cd.OpenFile(volFile, FileMode.Open), Path.GetFileName(volFile)); } // Check for second descriptor if (nextDescriptor != isoStream.Length) { isoStream.Seek(nextDescriptor - 0x8000, SeekOrigin.Begin); CDReader cd2 = new CDReader(new OffsetStreamDecorator(isoStream), true, true); vols = cd2.GetFiles("", "*.*", SearchOption.AllDirectories) .ToList() .Where(x => x.EndsWith(".VOL", StringComparison.OrdinalIgnoreCase)) .ToArray(); foreach (var volFile in vols) { yield return(cd2.OpenFile(volFile, FileMode.Open), Path.GetFileName(volFile)); } } } break; case FileType.UNKNOWN: case FileType.TOC22_VOL: case FileType.TOC22_ISO: case FileType.GTPSP_VOL: case FileType.GTPSP_ISO: default: throw new Exception("Invalid VOL type, can't get streams."); } }
static string FindGameId(string srcIso) { var regex = new Regex("(SCUS|SLUS|SLES|SCES|SCED|SLPS|SLPM|SCPS|SLED|SLPS|SIPS|ESPM|PBPX)[_-](\\d{3})\\.(\\d{2})", RegexOptions.IgnoreCase); var bootRegex = new Regex("BOOT\\s*=\\s*cdrom:\\\\?(?:.*?\\\\)?(.*?);1"); using (var stream = new FileStream(srcIso, FileMode.Open)) { var cdReader = new CDReader(stream, false, 2352); // Why doesn't a root file check not work? //foreach (var file in cdReader.GetFiles("\\")) //{ // var filename = file.Substring(1, file.LastIndexOf(";")); // var match = regex.Match(filename); // if (match.Success) // { // gameId = $"{match.Groups[1].Value}{match.Groups[2].Value}{match.Groups[3].Value}"; // break; // } //} var syscnfFound = false; foreach (var file in cdReader.GetFiles("\\")) { var filename = file.Substring(1, file.LastIndexOf(";") - 1); if (filename != "SYSTEM.CNF") { continue; } syscnfFound = true; using (var datastream = cdReader.OpenFile(file, FileMode.Open)) { datastream.Seek(24, SeekOrigin.Begin); var textReader = new StreamReader(datastream); var bootLine = textReader.ReadLine(); var bootmatch = bootRegex.Match(bootLine); if (!bootmatch.Success) { continue; } var match = regex.Match(bootmatch.Groups[1].Value); if (match.Success) { return($"{match.Groups[1].Value}{match.Groups[2].Value}{match.Groups[3].Value}"); } } } } return(null); }
private IEnumerable <string> ListFiles(string dirPath) { var fileList = new List <string>(); foreach (var subDir in _cd.GetDirectories(dirPath)) { fileList.AddRange(_cd.GetFiles(subDir)); fileList.AddRange(ListFiles(subDir)); } return(fileList); }
/// <summary> /// Determine which kind of VOL(s) the ISO contains (if any). /// </summary> /// <returns>FileType</returns> private FileType GetISOType() { var fileType = FileType.UNKNOWN; using (FileStream isoStream = File.Open(_filePath, FileMode.Open)) { CDReader cd = new CDReader(isoStream, true, true); var vols = cd.GetFiles("", "*.*", SearchOption.AllDirectories) .ToList() .Where(x => x.EndsWith(".VOL", StringComparison.OrdinalIgnoreCase)) .ToArray(); if (vols.Length <= 0) { throw new ArgumentException("Invalid ISO file, no VOL inside."); } try { using (var fs = cd.OpenFile(vols.First(), FileMode.Open)) { var volType = GetVOLType(fs); switch (volType) { case FileType.TOC22_VOL: fileType = FileType.TOC22_ISO; break; case FileType.TOC31_VOL: fileType = FileType.TOC31_ISO; break; case FileType.GTPSP_VOL: fileType = FileType.GTPSP_ISO; break; case FileType.TOC22_ISO: case FileType.TOC31_ISO: case FileType.GTPSP_ISO: throw new Exception("Something went wrong when parsing the VOL file inside the ISO file."); case FileType.UNKNOWN: default: fileType = FileType.UNKNOWN; break; } } } catch (ArgumentException) { throw new ArgumentException("Invalid ISO file, no VOL inside."); } } return(fileType); }
public static List <string> GetFilenames(this Ird ird) { using (var decompressedStream = new MemoryStream()) { using (var compressedStream = new MemoryStream(ird.Header, false)) using (var gzip = new GZipStream(compressedStream, CompressionMode.Decompress)) gzip.CopyTo(decompressedStream); decompressedStream.Seek(0, SeekOrigin.Begin); var reader = new CDReader(decompressedStream, true, true); return(reader.GetFiles(reader.Root.FullName, "*.*", SearchOption.AllDirectories).Distinct().Select(n => n.TrimStart('\\').Replace('\\', '/').TrimEnd('.')).ToList()); } }
public IsoSource(string path) { if (!File.Exists(path)) { throw new FileNotFoundException($"Cannot find file {path}"); } _isoStream = File.OpenRead(path); _cd = new CDReader(_isoStream, joliet: true, hideVersions: true); Root = _cd.Root.ToString(); Paths = _cd.GetFiles("\\", "*.*", SearchOption.AllDirectories); }
private void CloneCdDirectory(string dir, CDReader cdr, CDBuilder cdb) { foreach (string fileName in cdr.GetFiles(dir)) { if (fileName == "\\reactos\\unattend.inf") continue; var stream = cdr.OpenFile(fileName, FileMode.Open); cdb.AddFile(fileName.Remove(0, 1), stream); stream.Close(); } foreach (string dirName in cdr.GetDirectories(dir)) { CloneCdDirectory(dirName, cdr, cdb); } }
static public void ExtractIso(string isoPath, string targetDir) { using (FileStream isoStream = File.Open(isoPath, FileMode.Open, System.IO.FileAccess.Read)) { CDReader cd = new CDReader(isoStream, true); Stack <string> dirs = new Stack <string>(20); string root = @"\"; dirs.Push(root); while (dirs.Count > 0) { string currentDir = dirs.Pop(); Debug.WriteLine($"Scanning directory {currentDir}"); string tempPathDirectory = Pathy.Combine(targetDir, currentDir); Directory.CreateDirectory(tempPathDirectory); string[] subDirs = cd.GetDirectories(currentDir); try { string[] files = cd.GetFiles(currentDir); foreach (string file in files) { string normalizedFileName = file.Remove(file.Length - 2); string onIsoPath = Pathy.Combine(currentDir, file); string newPath = Pathy.Combine(targetDir, normalizedFileName); Debug.WriteLine($"Copying from {onIsoPath} to {newPath}"); using (var fileStream = File.Create(newPath)) { using (var gameFileStream = cd.OpenFile(file, FileMode.Open)) { gameFileStream.CopyTo(fileStream); } } } } catch (Exception err) { Debug.WriteLine(err); Debug.WriteLine($"Error ({err.Message}) in {currentDir}"); throw; } foreach (string str in subDirs) { dirs.Push(str); } } } }
private void ExtractISO_Directory(CDReader cd, string outputFolder, string cd_path) { var real_directory = string.Format("{0}/{1}", outputFolder, cd_path); if (!Directory.Exists(real_directory)) { Directory.CreateDirectory(real_directory); } var cd_directories = cd.GetDirectories(cd_path); foreach (var cd_directory in cd_directories) { ExtractISO_Directory(cd, outputFolder, cd_directory); } var cd_files = cd.GetFiles(cd_path); foreach (var cd_file in cd_files) { var fileStream = cd.OpenFile(cd_file, FileMode.Open); var attributes = cd.GetAttributes(cd_file); var real_file = string.Format("{0}/{1}", outputFolder, cd_file); Log($"extracting {cd_file} to {real_file}"); using (var writerStream = File.OpenWrite(real_file)) { var max_chunk = 1024; var buffer = new byte[max_chunk]; for (var b = 0; b < fileStream.Length; b += max_chunk) { var amount = (int)Math.Min(max_chunk, fileStream.Length - b); fileStream.Read(buffer, 0, amount); writerStream.Write(buffer, 0, amount); } } fileStream.Dispose(); } }
private void GenerateFileList(CDReader iso, string directory, List <string> fileList) { foreach (var file in iso.GetFiles(directory)) { if (file[0] == '\\') { fileList.Add(file.Substring(1, file.Length - 1)); // ISOs reasonably use \ as their root and derive all paths from it, but this causes problems later on when we try to use the ISO paths to build NTFS paths } else { fileList.Add(file); } } foreach (var dir in iso.GetDirectories(directory)) { GenerateFileList(iso, dir, fileList); } }
private void ExtractIso(string isoPath, string destDir) { using (FileStream isoStream = File.Open(isoPath, FileMode.Open)) { CDReader cd = new CDReader(isoStream, true); var files = cd.GetFiles("\\", "*.*", SearchOption.AllDirectories); foreach (var file in files) { using (var stream = cd.OpenFile(file, FileMode.Open)) { var destFile = destDir.TrimEnd('\\') + "\\" + Regex.Replace(file.Replace("/", "\\"), @";\d*$", "").TrimStart('\\'); // Create directories var destFolder = Path.GetDirectoryName(destFile); destFolder = destFolder.Equals(destDir) ? string.Empty : destFolder; var finalDestFolder = destDir; if (!string.IsNullOrEmpty(destFolder)) { finalDestFolder = Path.Combine(destDir, destFolder); } if (!Directory.Exists(finalDestFolder)) { Directory.CreateDirectory(finalDestFolder); } // Create the file using (FileStream sw = new FileStream(destFile, FileMode.CreateNew)) { byte[] buffer = new byte[2048]; int bytesRead; while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0) { sw.Write(buffer, 0, bytesRead); } } } } } }
public void HideVersions() { CDBuilder builder = new CDBuilder(); builder.UseJoliet = true; builder.AddFile("FILE.TXT;1", new byte[] { }); MemoryStream ms = new MemoryStream(); SparseStream.Pump(builder.Build(), ms); CDReader reader = new CDReader(ms, true, false); Assert.Equal("\\FILE.TXT;1", reader.GetFiles("")[0]); Assert.Equal("\\FILE.TXT;1", reader.GetFileSystemEntries("")[0]); reader = new CDReader(ms, true, true); Assert.Equal("\\FILE.TXT", reader.GetFiles("")[0]); Assert.Equal("\\FILE.TXT", reader.GetFileSystemEntries("")[0]); }
public static List <FileRecord> GetFilesystemStructure(this CDReader reader) { var filenames = reader.GetFiles(reader.Root.FullName, "*.*", SearchOption.AllDirectories).Distinct().Select(n => n.TrimStart('\\')).ToList(); var result = new List <FileRecord>(); foreach (var filename in filenames) { var clusterRange = reader.PathToClusters(filename); if (clusterRange.Length != 1) { Log.Warn($"{filename} is split in {clusterRange.Length} ranges"); } if (filename.EndsWith(".")) { Log.Warn($"Fixing potential mastering error in {filename}"); } result.Add(new FileRecord(filename.TrimEnd('.'), clusterRange.Min(r => r.Offset), reader.GetFileLength(filename))); } return(result.OrderBy(r => r.StartSector).ToList()); }
// Recursive function that reads all the directories in an .iso file. public void recurse_iso(string[] directories, CDReader cd, string iso) { foreach (var d in directories) { foreach (var f in cd.GetFiles(d)) { var index = f.LastIndexOf('\\'); var filename = f.Substring(index + 1, f.Length - index - 1); foreach (var item in search_terms) { if (filename.ToLower().Contains(item)) { file_list.Add(new File_Info(iso + f, filename)); } } } var dir = cd.GetDirectories(d); recurse_iso(dir, cd, iso); } }
private void Recursive_CreateDirs(CDReader cd, string dir, Stream fileStreamFrom, Stream fileStreamTo) { foreach (string directory in cd.GetDirectories(dir)) { Directory.CreateDirectory(TempPath + @"\" + directory); if (cd.GetDirectoryInfo(directory).GetFiles().Length > 0) { foreach (string file in cd.GetFiles(directory)) { fileStreamFrom = cd.OpenFile(file, FileMode.Open); fileStreamTo = File.Open(TempPath + @"\" + file, FileMode.OpenOrCreate); fileStreamFrom.CopyTo(fileStreamTo); fileStreamFrom.Close(); fileStreamTo.Close(); } } if (cd.GetDirectories(directory).Length > 0) { Recursive_CreateDirs(cd, directory, fileStreamFrom, fileStreamTo); } } }
private static void ScanFiles() { var parsers = new List <Action <BinaryReader, string> >(); if (_checkAll || _checkTim) { parsers.Add((binaryReader, fileTitle) => { var timParser = new TIMParser((tmdEntity, fp) => { AllTextures.Add(tmdEntity); UpdateProgress(fp, $"Found Texture {tmdEntity.Width}x{tmdEntity.Height} {tmdEntity.Bpp}bpp"); PreviewForm.ReloadItems(); }); Logger.WriteLine(""); Logger.WriteLine("Scanning for TIM Images at file {0}", fileTitle); timParser.LookForTim(binaryReader, fileTitle); }); } if (_checkTimAlt) { parsers.Add((binaryReader, fileTitle) => { var timParser = new TIMParserOld((tmdEntity, fp) => { AllTextures.Add(tmdEntity); UpdateProgress(fp, $"Found Texture {tmdEntity.Width}x{tmdEntity.Height} {tmdEntity.Bpp}bpp"); PreviewForm.ReloadItems(); }); Logger.WriteLine(""); Logger.WriteLine("Scanning for TIM Images (alt) at file {0}", fileTitle); timParser.LookForTim(binaryReader, fileTitle); }); } if (_checkAll || _checkTmd) { parsers.Add((binaryReader, fileTitle) => { var tmdParser = new TMDParser((tmdEntity, fp) => { AllEntities.Add(tmdEntity); UpdateProgress(fp, $"Found Model with {tmdEntity.ChildCount} objects"); PreviewForm.ReloadItems(); }); Logger.WriteLine(""); Logger.WriteLine("Scanning for TMD Models at file {0}", fileTitle); tmdParser.LookForTmd(binaryReader, fileTitle); }); } if (_checkTmdAlt) { parsers.Add((binaryReader, fileTitle) => { var tmdParser = new TMDParserAlternative((tmdEntity, fp) => { AllEntities.Add(tmdEntity); UpdateProgress(fp, $"Found Model with {tmdEntity.ChildCount} objects"); PreviewForm.ReloadItems(); }); Logger.WriteLine(""); Logger.WriteLine("Scanning for TMD Models (alt) at file {0}", fileTitle); tmdParser.LookForTmd(binaryReader, fileTitle); }); } if (_checkAll || _checkPmd) { parsers.Add((binaryReader, fileTitle) => { var pmdParser = new PMDParser((pmdEntity, fp) => { AllEntities.Add(pmdEntity); UpdateProgress(fp, $"Found Model with {pmdEntity.ChildCount} objects"); PreviewForm.ReloadItems(); }); Logger.WriteLine(""); Logger.WriteLine("Scanning for PMD Models at file {0}", fileTitle); pmdParser.LookForPMD(binaryReader, fileTitle); }); } if (_checkAll || _checkTod) { parsers.Add((binaryReader, fileTitle) => { var todParser = new TODParser((todEntity, fp) => { AllAnimations.Add(todEntity); UpdateProgress(fp, $"Found Animation with {todEntity.ObjectCount} objects and {todEntity.FrameCount} frames"); PreviewForm.ReloadItems(); }); Logger.WriteLine(""); Logger.WriteLine("Scanning for TOD Animations at file {0}", fileTitle); todParser.LookForTOD(binaryReader, fileTitle); }); } if (_checkHmdModels) { parsers.Add((binaryReader, fileTitle) => { var hmdParser = new HMDParser((hmdEntity, fp) => { AllEntities.Add(hmdEntity); UpdateProgress(fp, $"Found Model with {hmdEntity.ChildCount} objects"); PreviewForm.ReloadItems(); }); Logger.WriteLine(""); Logger.WriteLine("Scanning for HMD Models at file {0}", fileTitle); hmdParser.LookForHMDEntities(binaryReader, fileTitle); }); } if (_path.ToLowerInvariant().EndsWith(".iso")) { using (var isoStream = File.Open(_path, FileMode.Open)) { var cdReader = new CDReader(isoStream, true); var files = cdReader.GetFiles("", _filter ?? "*.*", SearchOption.AllDirectories); foreach (var file in files) { if (file.ToLowerInvariant().Contains(".str;")) { continue; } var fileInfo = cdReader.GetFileInfo(file); if (fileInfo.Exists) { foreach (var parser in parsers) { using (var stream = fileInfo.OpenRead()) { ProcessFile(stream, file, parser); } } } } } } else if (File.Exists(_path)) { Parallel.ForEach(parsers, parser => { using (var fs = File.Open(_path, FileMode.Open, FileAccess.Read, FileShare.Read)) { ProcessFile(fs, _path, parser); } }); } else { ProcessFiles(_path, _filter, parsers); } }
public async Task PublishAsync(CancellationToken aCancellationToken, TextWriter aOutputPaneWriter) { var xProjectProperties = await ProjectProperties.GetConfigurationGeneralPropertiesAsync().ConfigureAwait(false); var xOutputType = await xProjectProperties.OutputType.GetEvaluatedValueAtEndAsync().ConfigureAwait(false); var xOutputISO = await xProjectProperties.OutputISO.GetEvaluatedValueAtEndAsync().ConfigureAwait(false); xOutputISO = ConfiguredProject.UnconfiguredProject.MakeRooted(xOutputISO); if (String.Equals(xOutputType, OutputTypeValues.Bootable, StringComparison.OrdinalIgnoreCase)) { if (mPublishSettings == null) { await aOutputPaneWriter.WriteAsync("Publish settings are null!").ConfigureAwait(false); return; } switch (mPublishSettings.PublishType) { case PublishType.ISO: await aOutputPaneWriter.WriteLineAsync("Publishing ISO!").ConfigureAwait(false); if (String.IsNullOrWhiteSpace(mPublishSettings.PublishPath)) { throw new Exception($"Invalid publish path! Publish path: '{mPublishSettings.PublishPath}'"); } File.Copy(xOutputISO, mPublishSettings.PublishPath, true); break; case PublishType.USB: await aOutputPaneWriter.WriteLineAsync("Publishing USB!").ConfigureAwait(false); DriveInfo xDriveInfo; try { xDriveInfo = new DriveInfo(mPublishSettings.PublishPath); } catch (ArgumentException) { throw new Exception($"Invalid drive letter! Drive letter: '{mPublishSettings.PublishPath}'"); } // todo: format USB drive if requested? how? var xDrivePath = xDriveInfo.RootDirectory.FullName; using (var xStream = File.OpenRead(xOutputISO)) { using (var xReader = new CDReader(xStream, true)) { foreach (var xFile in xReader.GetFiles("")) { using (var xFileStream = xReader.OpenFile(xFile, FileMode.Open)) { using (var xNewFile = File.Create(Path.Combine(xDrivePath, Path.GetFileName(xFile)))) { await xFileStream.CopyToAsync(xNewFile).ConfigureAwait(false); } } } } } break; default: await aOutputPaneWriter.WriteLineAsync( $"Unknown publish type! Publish type: '{mPublishSettings.PublishType}'").ConfigureAwait(false); break; } } else { await ConfiguredProject.Services.Build.BuildAsync( ImmutableArray.Create("Publish"), CancellationToken.None, true).ConfigureAwait(false); } await aOutputPaneWriter.WriteLineAsync("Publish successful!").ConfigureAwait(false); }
/// <summary> /// /// </summary> /// <exception cref="ApplicationException"></exception> public void ExtractBin(string cueFileName) { if (!Directory.Exists(Directory.GetCurrentDirectory() + @"\" + _outFileNameBase)) { Directory.CreateDirectory(Directory.GetCurrentDirectory() + @"\" + _outFileNameBase); } var save_dir = Directory.GetCurrentDirectory() + @"\" + _outFileNameBase; try { CueFile cueFile; try { cueFileName = Path.ChangeExtension(cueFileName, CueExtension); cueFile = new CueFile(cueFileName); } catch (Exception e) { throw new ApplicationException($"Could not read CUE {cueFileName}:\n{e.Message}"); } Stream binStream; try { File.Copy(cueFile.BinFileName, save_dir + @"\" + _outFileNameBase + ".bin"); binStream = File.OpenRead(cueFile.BinFileName); } catch (Exception e) { throw new ApplicationException($"Could not open BIN {cueFile.BinFileName}: {e.Message}"); } Console.WriteLine(Environment.NewLine + "Writing tracks:"); foreach (Track curTrack in cueFile.TrackList) { Console.WriteLine(curTrack.Modes); Console.WriteLine(curTrack.FileExtension); Console.WriteLine(cueFile.TrackList.Count); // Include track number when more than 1 track. if (cueFile.TrackList.Count > 1) { _outFileName = $"{_outFileNameBase}{curTrack.TrackNumber:00}.{curTrack.FileExtension.ToString().ToLower()}"; } else { _outFileName = $"{_outFileNameBase}.{curTrack.FileExtension.ToString().ToLower()}"; } curTrack.Write(binStream, _outFileName); } } catch (Exception e) { Console.WriteLine(e.Message); } Console.WriteLine("discutils"); using (FileStream isoStream = File.OpenRead(_outFileName)) { CDReader cd = new CDReader(isoStream, false); Console.WriteLine(cd.Root.FullName); string[] files = cd.GetFiles(cd.Root.FullName); string[] dirs = cd.GetDirectories(cd.Root.FullName); bool mrgdone = false; foreach (string c in files) { Console.WriteLine(c); if (c == @"\SLUS_014.11;1") { FileStream fs = File.Create(save_dir + @"\SLUS_014.11"); SparseStream isf = cd.OpenFile(c, FileMode.Open); byte[] dat = new byte[isf.Length]; int result = AsyncContext.Run(() => isf.ReadAsync(dat, 0, (int)isf.Length)); Task task = Task.Run(async() => { await fs.WriteAsync(dat, 0, dat.Length); }); task.Wait(); fs.Close(); } foreach (string e in cd.GetFiles("\\DATA")) { Console.WriteLine(e); if (e == @"\DATA\WA_MRG.MRG;1" && !mrgdone) { FileStream fs = File.Create(save_dir + @"\WA_MRG.MRG"); SparseStream isf = cd.OpenFile(e, FileMode.Open); byte[] dat = new byte[isf.Length]; int result = AsyncContext.Run(() => isf.ReadAsync(dat, 0, (int)isf.Length)); Task task = Task.Run(async() => { await fs.WriteAsync(dat, 0, dat.Length); }); task.Wait(); mrgdone = true; fs.Close(); break; } } Static.SlusPath = save_dir + @"\SLUS_014.11"; Static.WaPath = save_dir + @"\WA_MRG.MRG"; Static.IsoPath = save_dir + @"\" + _outFileNameBase + ".bin"; } isoStream.Close(); File.Delete(_outFileName); } }
public static GameEntry FindGameInfo(string srcIso, string name = "PS1 Game") { var regex = new Regex("(S[LC]\\w{2})[_-](\\d{3})\\.(\\d{2})"); var bootRegex = new Regex("BOOT\\s*=\\s*cdrom:\\\\?(?:.*?\\\\)?(S[LC]\\w{2}[_-]?\\d{3}\\.\\d{2});1"); GameEntry game = null; using (var stream = new FileStream(srcIso, FileMode.Open)) { var cdReader = new CDReader(stream, false, 2352); string gameId = ""; //foreach (var file in cdReader.GetFiles("\\")) //{ // var filename = file.Substring(1, file.LastIndexOf(";")); // var match = regex.Match(filename); // if (match.Success) // { // gameId = $"{match.Groups[1].Value}{match.Groups[2].Value}{match.Groups[3].Value}"; // break; // } //} foreach (var file in cdReader.GetFiles("\\")) { var filename = file.Substring(1, file.LastIndexOf(";") - 1); if (filename == "SYSTEM.CNF") { using (var datastream = cdReader.OpenFile(file, FileMode.Open)) { datastream.Seek(24, SeekOrigin.Begin); var textReader = new StreamReader(datastream); var bootLine = textReader.ReadLine(); var bootmatch = bootRegex.Match(bootLine); if (bootmatch.Success) { var match = regex.Match(bootmatch.Groups[1].Value); if (match.Success) { gameId = $"{match.Groups[1].Value}{match.Groups[2].Value}{match.Groups[3].Value}"; GameEntry gm = new GameEntry(); gm.GameID = gameId; gm.ScannerID = gameId; gm.SaveFolderName = gameId; switch (gameId[2]) // Leave the option avalible for the user to correct it { case 'J': gm.Format = "NTSC"; break; case 'U': gm.Format = "NTSC"; break; case 'E': gm.Format = "PAL"; break; } game = gm; break; } } } } } } return(game); }