/// <summary> /// Builds a file where all the references to voice IDs in the /// ISO file are mapped. To be used as a cache by ISOModifier /// </summary> static void Main() { string isoFile = Properties.Settings.Default.ISOPath; string workDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); long startPos = Convert.ToInt64(Properties.Settings.Default.StartAddressOfScan, 16); // long endPos = Convert.ToInt64(Properties.Settings.Default.EndAddressOfScan, 16); var listeOfVoiceIDsToFind = SoundInfo.GetAllVoiceIDs(); List <Tuple <string, int> > listeOfPositionsAndVoiceId = new List <Tuple <string, int> >(); string logFilePath = Path.Combine(workDir, "output.log"); List <string> logLines = new List <string>(); if (File.Exists(logFilePath)) { File.Delete(logFilePath); } string errorsLogFilePath = Path.Combine(workDir, "errors.log"); List <string> errorsLines = new List <string>(); if (File.Exists(errorsLogFilePath)) { File.Delete(errorsLogFilePath); } string outputFilePath = Path.Combine(workDir, "VoiceIDsAddressesCache.csv"); if (File.Exists(outputFilePath)) { File.Delete(outputFilePath); } var binReader = new BinaryReader(File.OpenRead(isoFile)); binReader.BaseStream.Position = startPos; Console.WriteLine("Searching..."); File.AppendAllLines(logFilePath, new string[] { "Searching..." }); using (binReader) { var areaOfInterest = binReader.ReadBytes((int)(binReader.BaseStream.Length - binReader.BaseStream.Position)); Parallel.ForEach(listeOfVoiceIDsToFind, voiceIdToSeek => { byte[] voiceIdToSeekAsByteArray = ASCIIEncoding.ASCII.GetBytes(voiceIdToSeek.ToString()); List <byte> voiceIdSurroundedByZeroes = new List <byte>(); List <byte> voiceIdTailedWithZero = new List <byte>(); List <byte> voiceIdPrefixedWithZero = new List <byte>(); //To avoid false positives voiceIdPrefixedWithZero.Add(BitConverter.GetBytes(0)[0]); voiceIdSurroundedByZeroes.Add(BitConverter.GetBytes(0)[0]); voiceIdSurroundedByZeroes.AddRange(voiceIdToSeekAsByteArray); voiceIdPrefixedWithZero.AddRange(voiceIdToSeekAsByteArray); voiceIdTailedWithZero.AddRange(voiceIdToSeekAsByteArray); //To avoid false positives voiceIdSurroundedByZeroes.Add(BitConverter.GetBytes(0)[0]); voiceIdTailedWithZero.Add(BitConverter.GetBytes(0)[0]); int indexOfVoiceId = GetIndexOfBytePattern(areaOfInterest, voiceIdSurroundedByZeroes.ToArray()); if (indexOfVoiceId != -1) { indexOfVoiceId += 1; } if (indexOfVoiceId == -1) { indexOfVoiceId = GetIndexOfBytePattern(areaOfInterest, voiceIdPrefixedWithZero.ToArray()); if (indexOfVoiceId != -1) { indexOfVoiceId += 1; } } if (indexOfVoiceId == -1) { indexOfVoiceId = GetIndexOfBytePattern(areaOfInterest, voiceIdTailedWithZero.ToArray()); } if (indexOfVoiceId == -1) { indexOfVoiceId = GetIndexOfBytePattern(areaOfInterest, voiceIdToSeekAsByteArray); } if (indexOfVoiceId != -1) { long finalIndex = indexOfVoiceId + startPos; string logLineVoiceId = @"index found for voiceID : " + voiceIdToSeek + "->" + Convert.ToString(finalIndex, 16); Console.WriteLine(logLineVoiceId); logLines.Add(logLineVoiceId); listeOfPositionsAndVoiceId.Add(new Tuple <string, int>(Convert.ToString(finalIndex, 16), voiceIdToSeek)); } else { string logLineFailure = @"/!\ index NOT found for voiceID : " + voiceIdToSeek; logLines.Add(logLineFailure); errorsLines.Add(logLineFailure); Console.WriteLine(logLineFailure); listeOfPositionsAndVoiceId.Add(new Tuple <string, int>(indexOfVoiceId.ToString(), voiceIdToSeek)); } }); } string logLine = "Writing results to " + outputFilePath; logLines.Add(logLine); Console.WriteLine(logLine); File.AppendAllLines(logFilePath, logLines.ToArray()); File.AppendAllLines(errorsLogFilePath, errorsLines.ToArray()); List <string> outputContent = new List <string>(); Parallel.ForEach(listeOfPositionsAndVoiceId.AsParallel().OrderBy(x => x.Item2), IndexAndVoiceId => { string line = string.Format("{0},{1}", IndexAndVoiceId.Item1, IndexAndVoiceId.Item2.ToString()); outputContent.Add(line); }); File.WriteAllLines(outputFilePath, outputContent); string finalLogLine = "Done ! :)"; File.AppendAllLines(logFilePath, new string[] { finalLogLine }); Console.WriteLine(finalLogLine); }