/************************************************************* *************************************************************/ public bool AnalyseISO(ODD odd) { bool IsPlain = true; try { using (DiscStream inputStream = new DiscStream(odd)) { byte[] buffer = new byte[0x1000]; inputStream.Read(buffer, 0, 0x1000); NumPlainRegions = BitConverter.ToUInt32(buffer, 0).Swap(); Regions = new Region[(NumPlainRegions * 2) - 1]; if (buffer[0xF70 + 0xA] != '3' || buffer[0xF70 + 0xB] != 'K') { Interaction.Instance.ReportMessage("Invalid ISO file. This file does not contain PIC/D1/D2 data"); return(false); } IsDecrypting = buffer[0xF70] != 0x44; // Begins with E or D IsBuildedISO = buffer[0xF70 + 0xD] == 0x42; // End in BLD IsValidHash = IsBuildedISO && buffer[0xF70 + 0xF] != 0x44; // Ends in BLF int pos = 8; UInt32 Current = BitConverter.ToUInt32(buffer, pos).Swap(); pos += 4; for (UInt32 i = 0; i < (2 * NumPlainRegions) - 1; i++) { UInt32 Next = BitConverter.ToUInt32(buffer, pos).Swap(); pos += 4; if (IsPlain) { Regions[i] = new PlainRegion(i, IsDecrypting, IsBuildedISO, IsValidHash, Current, Next); } else { Regions[i] = IsDecrypting ? (Region) new CryptedRegion(i, inputStream.Data1, inputStream.Data2, Current, Next, false) : new DecryptedRegion(i, inputStream.Data1, inputStream.Data2, Current, Next, false); } IsPlain = !IsPlain; Current = Next; } /* Record this for later */ amountOfSectors = Current; // Game ID is at offset 0x810, length = 10 GameID = Encoding.ASCII.GetString(buffer, 0x810, 10); } } catch (Exception e) { Console.WriteLine(e); return(false); } return(true); }
/***************************************************** *****************************************************/ public async Task DoRip(CancellationToken cancellation) { string isoFileName = await Interaction.Instance.GetIsoPath(null); if (string.IsNullOrEmpty(isoFileName)) { return; } Interaction.Instance.TaskBegin(); try { using (FileStream isoFile = new FileStream(isoFileName, FileMode.Create, FileAccess.Write)) { using (DiscStream ds = new DiscStream(this)) { long amountOfBytesToRead = ds.Length; long totalRead = 0; Interaction.Instance.SetProgressMaximum((int)amountOfBytesToRead.RoundToSector()); while (amountOfBytesToRead > 0) { byte[] buffer = new byte[0x20 * Utilities.SectorSize]; int bytesRead = await ds.ReadAsync(buffer, 0, buffer.Length); await isoFile.WriteAsync(buffer, 0, bytesRead); if (cancellation.IsCancellationRequested) { break; } totalRead += bytesRead; amountOfBytesToRead -= bytesRead; Interaction.Instance.ReportProgress((int)totalRead.RoundToSector()); } } } Interaction.Instance.ReportMessage("Rip complete"); } catch (Exception e) { Interaction.Instance.ReportMessage(e.Message, ReportType.Fail); } Interaction.Instance.TaskComplete(); /* * UInt32 CurrentSector = 0; * byte[] picData = new byte[0x73]; * byte[] Data1 = new byte[0x10]; * byte[] Data2 = new byte[0x10]; * * byte[] DataBuffer = new byte[0x20 * Utilities.SectorSize]; * * FileStream ISOFile; * BinaryWriter bw; * * // Read the PIC data * if (CDB.DoReadPICZone(picData) != CDB.IoResult.OK) * { * Interaction.Instance.ReportMessage("Cannot read PIC data", ReportType.Fail); * Interaction.Instance.TaskComplete(); * return; * } * // Read the Data1/Data2 * if (EstablishSessionKeys(0, Key1, Key2) == false) * { * Interaction.Instance.ReportMessage("Cannot establish session keys", ReportType.Fail); * Interaction.Instance.TaskComplete(); * return; * } * if (GetData(Data1, Data2) == false) * { * Interaction.Instance.ReportMessage("Cannot extract D1/D2 keys", ReportType.Fail); * Interaction.Instance.TaskComplete(); * return; * } * if (EstablishSessionKeys(1, FixedKey30, FixedKey31) == false) * { * Interaction.Instance.ReportMessage("Cannot establish session keys", ReportType.Fail); * Interaction.Instance.TaskComplete(); * return; * } * * // Read the game capacity * uint NumSectors = GetNumSectors(); * * if (ReadWithRetry(DataBuffer, CurrentSector, 0x20) == false) * { * Interaction.Instance.ReportMessage("Failed to read from the disc", ReportType.Fail); * Interaction.Instance.TaskComplete(); * return; * } * * // Open the ISO file * try * { * ISOFile = new FileStream(theIsoFileName, FileMode.Create, FileAccess.Write); * bw = new BinaryWriter(ISOFile); * } * catch (Exception ee) * { * string fail = ee.Message; * gameRipWorker.ReportProgress(0, fail); * return false; * } * * Array.Copy(Utilities.Encrypted3KISO, 0, DataBuffer, 0xF70, 0x10); * Array.Copy(Data1, 0, DataBuffer, 0xF80, 0x10); * Array.Copy(Data2, 0, DataBuffer, 0xF90, 0x10); * Array.Copy(picData, 0, DataBuffer, 0xFA0, 0x73); * bw.Write(DataBuffer, 0, (int)(0x20 * Utilities.SectorSize)); * * CurrentSector = 0x20; * * CDB.DoSetCDROMSpeed(0xFFFF); * * while (CurrentSector <= NumSectors) * { * if (gameRipWorker.CancellationPending) * { * bw.Close(); * ISOFile.Close(); * return true; * } * if (ReadWithRetry(DataBuffer, CurrentSector, 0x20) == false) * { * bw.Close(); * ISOFile.Close(); * return false; * } * bw.Write(DataBuffer, 0, (int)(0x20 * Utilities.SectorSize)); * * CurrentSector += 0x20; * gameRipWorker.ReportProgress((int)CurrentSector, null); * } * * if (NumSectors > CurrentSector) * { * if (gameRipWorker.CancellationPending) * { * bw.Close(); * ISOFile.Close(); * return true; * } * if (ReadWithRetry(DataBuffer, CurrentSector, (NumSectors - CurrentSector)) == false) * { * bw.Close(); * ISOFile.Close(); * return false; * } * bw.Write(DataBuffer, 0, (int)((NumSectors - CurrentSector) * Utilities.SectorSize)); * } * bw.Close(); * ISOFile.Close(); * return true; */ }