From 9d4bc6bfabb7aef0d5fb7444b9e8cef96b72243d Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Mon, 18 Sep 2023 00:59:37 -0400 Subject: [PATCH] Move psxt001z to its own library --- BurnOutSharp.sln | 6 - BurnOutSharp/BurnOutSharp.csproj | 4 - README.md | 1 - psxt001z/CRC16.cs | 53 -- psxt001z/CRC32.cs | 57 -- psxt001z/Common.cs | 19 - psxt001z/FileTools.cs | 178 ------ psxt001z/Functions.cs | 108 ---- psxt001z/Info.cs | 293 --------- psxt001z/LibCrypt.cs | 825 ------------------------ psxt001z/Main.cs | 1004 ------------------------------ psxt001z/Scramble.cs | 110 ---- psxt001z/Track.cs | 310 --------- psxt001z/psxt001z.csproj | 22 - 14 files changed, 2990 deletions(-) delete mode 100644 psxt001z/CRC16.cs delete mode 100644 psxt001z/CRC32.cs delete mode 100644 psxt001z/Common.cs delete mode 100644 psxt001z/FileTools.cs delete mode 100644 psxt001z/Functions.cs delete mode 100644 psxt001z/Info.cs delete mode 100644 psxt001z/LibCrypt.cs delete mode 100644 psxt001z/Main.cs delete mode 100644 psxt001z/Scramble.cs delete mode 100644 psxt001z/Track.cs delete mode 100644 psxt001z/psxt001z.csproj diff --git a/BurnOutSharp.sln b/BurnOutSharp.sln index 47a2970c..0b3c430e 100644 --- a/BurnOutSharp.sln +++ b/BurnOutSharp.sln @@ -16,8 +16,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution README.md = README.md EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "psxt001z", "psxt001z\psxt001z.csproj", "{D9574B47-0D6B-445A-97BF-272B5EF9AD3F}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BinaryObjectScanner.Compression", "BinaryObjectScanner.Compression\BinaryObjectScanner.Compression.csproj", "{B55206B2-58FD-4A47-AADC-74982FEA8FAD}" EndProject Global @@ -34,10 +32,6 @@ Global {88735BA2-778D-4192-8EB2-FFF6843719E2}.Debug|Any CPU.Build.0 = Debug|Any CPU {88735BA2-778D-4192-8EB2-FFF6843719E2}.Release|Any CPU.ActiveCfg = Release|Any CPU {88735BA2-778D-4192-8EB2-FFF6843719E2}.Release|Any CPU.Build.0 = Release|Any CPU - {D9574B47-0D6B-445A-97BF-272B5EF9AD3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D9574B47-0D6B-445A-97BF-272B5EF9AD3F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D9574B47-0D6B-445A-97BF-272B5EF9AD3F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D9574B47-0D6B-445A-97BF-272B5EF9AD3F}.Release|Any CPU.Build.0 = Release|Any CPU {B55206B2-58FD-4A47-AADC-74982FEA8FAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B55206B2-58FD-4A47-AADC-74982FEA8FAD}.Debug|Any CPU.Build.0 = Debug|Any CPU {B55206B2-58FD-4A47-AADC-74982FEA8FAD}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/BurnOutSharp/BurnOutSharp.csproj b/BurnOutSharp/BurnOutSharp.csproj index d39ade6d..f18e24e3 100644 --- a/BurnOutSharp/BurnOutSharp.csproj +++ b/BurnOutSharp/BurnOutSharp.csproj @@ -46,10 +46,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - diff --git a/README.md b/README.md index 0d2364dd..174ace02 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ C# protection, packer, and archive scanning library. This currently compiles as The following libraries (or ports thereof) are used for file handling: - [openmcdf](https://github.com/ironfede/openmcdf) - MSI extraction -- [psxt001z](https://github.com/Dremora/psxt001z) - PS1 LibCrypt detection [Ported to C#] - [SharpCompress](https://github.com/adamhathcock/sharpcompress) - Common archive format extraction - [SharpZipLib](https://github.com/icsharpcode/SharpZipLib) - zlib-based extraction - [StormLibSharp](https://github.com/robpaveza/stormlibsharp) - MoPaQ extraction [Unused in .NET 6.0 builds due to Windows-specific libraries] diff --git a/psxt001z/CRC16.cs b/psxt001z/CRC16.cs deleted file mode 100644 index ed146ade..00000000 --- a/psxt001z/CRC16.cs +++ /dev/null @@ -1,53 +0,0 @@ -namespace psxt001z -{ - public class CRC16 - { - // Table of CRC constants - implements x^16+x^12+x^5+1 - private static ushort[] CRC16Table = new ushort[] - { - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, - 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, - 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, - 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, - 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, - 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, - 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, - 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, - 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, - 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, - 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, - 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, - 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, - 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, - 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, - 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, - 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, - 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, - 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, - 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, - 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, - 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, - 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, - }; - - public static ushort Calculate(byte[] buf, int bufPtr, int len) - { - ushort cksum = 0; - for (int i = 0; i < len; i++) - { - cksum = (ushort)(CRC16Table[((cksum >> 8) ^ buf[bufPtr++]) & 0xFF] ^ (cksum << 8)); - } - - return (ushort)(~cksum); - } - } -} diff --git a/psxt001z/CRC32.cs b/psxt001z/CRC32.cs deleted file mode 100644 index cf3830e3..00000000 --- a/psxt001z/CRC32.cs +++ /dev/null @@ -1,57 +0,0 @@ -namespace psxt001z -{ - internal class CRC32 - { - #region Constants - - private const uint CRC_POLY = 0xEDB88320; - - private const uint CRC_MASK = 0xD202EF8D; - - #endregion - - #region Properties - - protected uint[] Table { get; private set; } = new uint[256]; - - public uint m_crc32 { get; set; } - - #endregion - - #region Constructor - - public CRC32() - { - for (uint i = 0; i < 256; i++) - { - uint r, j; - for (r = i, j = 8; j != 0; j--) - { - r = ((r & 1) != 0) ? (r >> 1) ^ CRC_POLY : r >> 1; - } - - Table[i] = r; - } - - m_crc32 = 0; - } - - #endregion - - #region Functions - - public void ProcessCRC(byte[] pData, int pDataPtr, int nLen) - { - uint crc = m_crc32; - while (nLen-- != 0) - { - crc = Table[(byte)(crc ^ pData[pDataPtr++])] ^ crc >> 8; - crc ^= CRC_MASK; - } - - m_crc32 = crc; - } - - #endregion - } -} diff --git a/psxt001z/Common.cs b/psxt001z/Common.cs deleted file mode 100644 index 7c2fa434..00000000 --- a/psxt001z/Common.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace psxt001z -{ - public static class Common - { - public const int ZERO = 0; - - public const string VERSION = "v0.21 beta 1"; - - /// - /// BCD to u_char - /// - public static byte btoi(byte b) => (byte)(((b) / 16 * 10 + (b) % 16)); - - /// - /// u_char to BCD - /// - public static byte itob(byte i) => (byte)(((i) / 10 * 16 + (i) % 10)); - } -} diff --git a/psxt001z/FileTools.cs b/psxt001z/FileTools.cs deleted file mode 100644 index 82b30fc4..00000000 --- a/psxt001z/FileTools.cs +++ /dev/null @@ -1,178 +0,0 @@ -using System; -using System.IO; -using System.Text; - -namespace psxt001z -{ - internal class FileTools - { - #region Properties - - private Stream InputStream { get; set; } - - private byte[] ExeName { get; set; } = new byte[20]; - - private byte[] DateValue { get; set; } = new byte[11]; - - #endregion - - #region Constructor - - public FileTools(Stream file) - { - InputStream = file; - } - - #endregion - - #region Functions - - /// - /// Get file size - /// - public long size() => InputStream.Length; - - /// - /// Get executable name - /// - public string exe() - { - InputStream.Seek(51744, SeekOrigin.Begin); - - string filename = string.Empty; - while (filename != "SYSTEM.CNF") - { - byte[] buf = new byte[10]; - InputStream.Read(buf, 0, 10); - filename = Encoding.ASCII.GetString(buf); - InputStream.Seek(-9, SeekOrigin.Current); - } - - byte[] buffer = new byte[20]; - - InputStream.Seek(-32, SeekOrigin.Current); - InputStream.Read(buffer, 0, 4); - uint lba = BitConverter.ToUInt32(buffer, 0); - - InputStream.Seek((2352 * lba) + 29, SeekOrigin.Begin); - InputStream.Read(buffer, 0, 6); - - string iniLine = Encoding.ASCII.GetString(buffer); - while (iniLine != "cdrom:") - { - InputStream.Seek(-5, SeekOrigin.Current); - InputStream.Read(buffer, 0, 6); - iniLine = Encoding.ASCII.GetString(buffer); - } - - InputStream.Read(buffer, 0, 1); - if (buffer[0] != '\\') - InputStream.Seek(-1, SeekOrigin.Current); - - int i = -1; - do - { - InputStream.Read(buffer, ++i, 1); - } while (buffer[i] != ';'); - - for (long a = 0; a < i; a++) - { - ExeName[a] = (byte)char.ToUpper((char)buffer[a]); - } - - return Encoding.ASCII.GetString(ExeName); - } - - /// - /// Get human-readable date - /// - public string date() - { - byte[] buffer = new byte[12], datenofrmt = new byte[3]; - - InputStream.Seek(51744, SeekOrigin.Begin); - - do - { - InputStream.Read(buffer, 0, 11); - buffer[11] = 0; - InputStream.Seek(-10, SeekOrigin.Current); - } while (Encoding.ASCII.GetString(ExeName) != Encoding.ASCII.GetString(buffer)); - - InputStream.Seek(-16, SeekOrigin.Current); - InputStream.Read(datenofrmt, 0, 3); - - if (datenofrmt[0] < 50) - { - byte[] year = Encoding.ASCII.GetBytes($"{2000 + datenofrmt[0]}"); - Array.Copy(year, 0, buffer, 0, 4); - } - else - { - byte[] year = Encoding.ASCII.GetBytes($"{1900 + datenofrmt[0]}"); - Array.Copy(year, 0, buffer, 0, 4); - } - - DateValue[4] = (byte)'-'; - if (datenofrmt[1] < 10) - { - byte[] month = Encoding.ASCII.GetBytes($"0{datenofrmt[1]}"); - Array.Copy(month, 0, buffer, 5, 2); - } - else - { - byte[] month = Encoding.ASCII.GetBytes($"{datenofrmt[1]}"); - Array.Copy(month, 0, buffer, 5, 2); - } - - DateValue[7] = (byte)'-'; - if (datenofrmt[2] < 10) - { - byte[] day = Encoding.ASCII.GetBytes($"0{datenofrmt[2]}"); - Array.Copy(day, 0, buffer, 8, 2); - } - else - { - byte[] day = Encoding.ASCII.GetBytes($"{datenofrmt[2]}"); - Array.Copy(day, 0, buffer, 8, 2); - } - - return Encoding.ASCII.GetString(DateValue); - } - - /// - /// Resize the image - /// - public int resize(long newsize) - { - long oldsize = size(); - if (oldsize < newsize) - { - InputStream.SetLength(newsize); - return 1; - } - else if (oldsize > newsize) - { - InputStream.SetLength(newsize); - return 2; - } - else - { - return 0; - } - } - - /// - /// Get the reported sector count from the image - /// - public int imagesize() - { - InputStream.Seek(0x9368, SeekOrigin.Begin); - byte[] sizebuf = new byte[4]; - InputStream.Read(sizebuf, 0, 4); - return BitConverter.ToInt32(sizebuf, 0); - } - - #endregion - } -} diff --git a/psxt001z/Functions.cs b/psxt001z/Functions.cs deleted file mode 100644 index ddf4b012..00000000 --- a/psxt001z/Functions.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.IO; -using System.Text; -using static psxt001z.Common; - -namespace psxt001z -{ - internal static class Functions - { - public static int CalculateEDC(in byte[] src, int srcPtr, int size, int[] edc_lut) - { - int edc = 0; - while (size-- != 0) - { - edc = (edc >> 8) ^ edc_lut[(edc ^ src[srcPtr++]) & 0xFF]; - } - - return edc; - } - - public static bool ZeroCompare(byte[] buffer, int bufferPtr, int bsize) - { - for (int i = 0; i < bsize; i++) - { - if (buffer[bufferPtr + i] != 0x00) - return false; - } - - return true; - } - - public static void MSF(long lba, byte[] buffer, int bufferOffset) - { - lba += 150; - - double mindbl = lba / 60 / 75; - byte min = (byte)Math.Floor(mindbl); - double secdbl = (lba - (min * 60 * 75)) / 75; - byte sec = (byte)Math.Floor(secdbl); - byte frame = (byte)(lba - (min * 60 * 75) - (sec * 75)); - - buffer[bufferOffset] = itob(min); - buffer[bufferOffset + 1] = itob(sec); - buffer[bufferOffset + 2] = itob(frame); - - return; - } - - public static bool GetEDCStatus(Stream file) - { - long currentposition = file.Position; - - file.Seek(30572, SeekOrigin.Begin); - - byte[] buffer = new byte[4]; - file.Read(buffer, 0, 4); - - file.Seek(currentposition, SeekOrigin.Begin); - - return BitConverter.ToInt32(buffer, 0) == 0; - } - - public static byte[] ExecutableName(Stream file) - { - byte[] buffer = new byte[20]; - byte[] exename = new byte[20]; - - //Searching for SYSTEM.CNF - file.Seek(51744, SeekOrigin.Begin); - while (Encoding.ASCII.GetString(buffer) != "SYSTEM.CNF") - { - file.Read(buffer, 0, 10); - buffer[10] = 0; - file.Seek(-9, SeekOrigin.Current); - } - - file.Seek(-32, SeekOrigin.Current); - byte[] lba = new byte[4]; - file.Read(lba, 0, 4); - file.Seek((2352 * BitConverter.ToInt32(lba, 0)) + 29, SeekOrigin.Begin); - file.Read(buffer, 0, 6); - buffer[6] = 0; - while (Encoding.ASCII.GetString(buffer) != "cdrom:") - { - file.Seek(-5, SeekOrigin.Current); - file.Read(buffer, 0, 6); - } - - file.Read(buffer, 0, 1); - if (buffer[0] != '\\') - file.Seek(-1, SeekOrigin.Current); - - int i = -1; - do - { - file.Read(buffer, ++i, 1); - } while (buffer[i] != ';'); - - for (int a = 0; a < i; a++) - { - exename[a] = (byte)char.ToUpper((char)buffer[a]); - } - - exename[i] = 0; - return exename; - } - } -} diff --git a/psxt001z/Info.cs b/psxt001z/Info.cs deleted file mode 100644 index 84af29c1..00000000 --- a/psxt001z/Info.cs +++ /dev/null @@ -1,293 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using static psxt001z.Functions; - -namespace psxt001z -{ - public class Info - { - #region Constants - - private static readonly byte[] edc_form_2 = { 0x3F, 0x13, 0xB0, 0xBE }; - - private static readonly byte[] syncheader = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - private static readonly byte[] subheader = { 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00 }; - - #endregion - - #region Functions - - public static int GetInfo(string filename, bool fix) - { - // Variables - bool errors = false; - byte[] buffer = new byte[2352], buffer2 = new byte[2352]; - int mode = 15; // synñheader[15]; - - #region Opening image - - Stream image; - try - { - FileAccess open_mode = fix ? FileAccess.ReadWrite : FileAccess.Read; - image = File.Open(filename, FileMode.Open, open_mode); - } - catch (Exception ex) - { - Console.Error.WriteLine(ex); - return 1; - } - - long size = image.Length; - Console.WriteLine($"File: {filename}"); - - #endregion - - #region Type - - image.Read(buffer, 0, 12); - - int sectorsize; - if (buffer.Take(12).SequenceEqual(syncheader.Take(12))) - { - sectorsize = 2352; - } - else - { - sectorsize = 2048; - } - if (size % sectorsize != 0) - { - Console.WriteLine($"{filename}: not ModeX/{sectorsize} image!"); - return 1; - } - - long sectors = size / sectorsize; - - #endregion - - #region Mode - - if (sectorsize == 2352) - { - image.Seek(0xF, SeekOrigin.Begin); - mode = image.ReadByte(); - if (mode != 1 && mode != 2) - { - Console.WriteLine($"{filename}: unknown mode!"); - return 1; - } - } - else - { - mode = -1; - } - - #endregion - - #region Size - - image.Seek(sectorsize * 16 + ((mode == 2) ? 24 : ((mode == 1) ? 16 : 0)) + 0x50, SeekOrigin.Begin); - - // ISO size - byte[] buf = new byte[4]; - image.Read(buf, 0, 4); - int realsectors = BitConverter.ToInt32(buf, 0); - - image.Seek(0, SeekOrigin.Begin); - int realsize = realsectors * sectorsize; - if (sectors == realsectors) - { - Console.WriteLine($"Size (bytes): {size} (OK)"); - Console.WriteLine($"Size (sectors): {sectors} (OK)"); - } - else - { - Console.WriteLine($"Size (bytes): {size}"); - Console.WriteLine($"From image: {realsize}"); - Console.WriteLine($"Size (sectors): {sectors}"); - Console.WriteLine($"From image: {realsectors}"); - } - - #endregion - - #region Mode - - if (mode > 0) - Console.WriteLine($"Mode: {mode}"); - - if (mode == 2) - { - #region EDC in Form 2 - - bool imageedc = GetEDCStatus(image); - Console.WriteLine($"EDC in Form 2 sectors: {(imageedc ? "YES" : "NO")}"); - - #endregion - - #region Sysarea - - string systemArea = "System area: "; - image.Seek(0, SeekOrigin.Begin); - - CRC32 crc = new CRC32(); - for (int i = 0; i < 16; i++) - { - image.Read(buffer, 0, 2352); - crc.ProcessCRC(buffer, 0, 2352); - } - - uint imagecrc = crc.m_crc32; - systemArea += GetEdcType(imagecrc); - - Console.WriteLine(systemArea); - - #endregion - - #region Postgap - - image.Seek((sectors - 150) * sectorsize + 16, SeekOrigin.Begin); - image.Read(buffer, 0, 2336); - - string postgap = "Postgap type: Form "; - if ((buffer[2] >> 5 & 0x1) != 0) - { - postgap += "2"; - if (buffer.Take(8).SequenceEqual(subheader)) - postgap += ", zero subheader"; - else - postgap += ", non-zero subheader"; - - if (ZeroCompare(buffer, 8, 2324)) - postgap += ", zero data"; - else - postgap += ", non-zero data"; - - if (ZeroCompare(buffer, 2332, 4)) - postgap += ", no EDC"; - else - postgap += ", EDC"; - } - else - { - postgap += "1"; - if (ZeroCompare(buffer, 0, 8)) - postgap += ", zero subheader"; - else - postgap += ", non-zero subheader"; - - if (ZeroCompare(buffer, 8, 2328)) - postgap += ", zero data"; - else - postgap += ", non-zero data"; - } - - Console.WriteLine(postgap); - Array.Copy(buffer, buffer2, 2336); - - #endregion - } - - if (mode < 0) - return 0; - - for (long sector = sectors - 150; sector < sectors; sector++) - { - bool bad = false; - image.Seek(sector * sectorsize, SeekOrigin.Begin); - image.Read(buffer, 0, sectorsize); - - // Sync - string sectorInfo = string.Empty; - - MSF(sector, syncheader, 12); - if (!syncheader.SequenceEqual(buffer.Take(16))) - { - sectorInfo += $"Sector {sector}: Sync/Header"; - bad = true; - if (fix) - { - image.Seek(sector * sectorsize, SeekOrigin.Begin); - image.Write(syncheader, 0, 16); - sectorInfo += (" (fixed)"); - } - } - - // Mode 2 - if (mode == 2 && buffer.Skip(16).Take(2336).SequenceEqual(buffer2)) - { - if (bad) - { - sectorInfo += ", Subheader/Data/EDC/ECC"; - } - else - { - sectorInfo = $"Sector {sector}: Subheader/Data/EDC/ECC"; - bad = true; - } - - if (fix) - { - image.Seek(sector * sectorsize + 16, SeekOrigin.Begin); - image.Write(buffer2, 0, 2336); - sectorInfo += " (fixed)"; - } - } - - Console.WriteLine(sectorInfo); - - if (bad && (sector + 1 != sectors)) - errors = true; - } - - if (errors) - { - Console.WriteLine("NOTICE: One or more errors were found not in the last sector."); - Console.WriteLine("Please mention this when submitting dump info."); - } - else - { - Console.WriteLine("Done."); - } - - #endregion - - return 0; - } - - #endregion - - #region Utilities - - internal static string GetEdcType(uint imageCrc) - { - switch (imageCrc) - { - case 0x11e3052d: - return "Eu EDC"; - case 0x808c19f6: - return "Eu NoEDC"; - case 0x70ffa73e: - return "Eu Alt NoEDC"; - case 0x7f9a25b1: - return "Eu Alt 2 EDC"; - case 0x783aca30: - return "Jap EDC"; - case 0xe955d6eb: - return "Jap NoEDC"; - case 0x9b519a2e: - return "US EDC"; - case 0x0a3e86f5: - return "US NoEDC"; - case 0x6773d4db: - return "US Alt NoEDC"; - default: - return $"Unknown, crc {imageCrc:8x}"; - } - } - - #endregion - } -} diff --git a/psxt001z/LibCrypt.cs b/psxt001z/LibCrypt.cs deleted file mode 100644 index cda89e67..00000000 --- a/psxt001z/LibCrypt.cs +++ /dev/null @@ -1,825 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Text; -using static psxt001z.Common; - -namespace psxt001z -{ - internal class ScsiPassThroughDirect - { - public ushort Length { get; set; } - - public byte ScsiStatus { get; set; } - - public byte PathId { get; set; } - - public byte TargetId { get; set; } - - public byte Lun { get; set; } - - public byte CDBLength { get; set; } - - public byte SenseInfoLength { get; set; } - - public byte DataIn { get; set; } - - public uint DataTransferLength { get; set; } - - public uint TimeOutValue { get; set; } - - public byte[] DataBuffer { get; set; } - - public uint SenseInfoOffset { get; set; } - - public byte[] CDB { get; set; } = new byte[16]; - } - - public class LibCrypt - { - #region OLD - - public static bool CheckSubfile(string subFilePath) - { - // Check the file exists first - if (!File.Exists(subFilePath)) - return false; - - // Check the extension is a subfile - string ext = Path.GetExtension(subFilePath).TrimStart('.').ToLowerInvariant(); - if (ext != "sub") - return false; - - // Open and check the subfile for LibCrypt - try - { - using (FileStream subfile = File.OpenRead(subFilePath)) - { - return CheckSubfile(subfile); - } - } - catch - { - return false; - } - } - - public static bool CheckSubfile(Stream subfile) - { - // Check the length is valid for subfiles - long size = subfile.Length; - if (size % 96 != 0) - return false; - - // Persistent values - byte[] buffer = new byte[16]; - byte[] sub = new byte[16]; - int tpos = 0; - int modifiedSectors = 0; - - // Check each sector for modifications - for (uint sector = 150; sector < ((size / 96) + 150); sector++) - { - subfile.Seek(12, SeekOrigin.Current); - if (subfile.Read(buffer, 0, 12) == 0) - return modifiedSectors != 0; - - subfile.Seek(72, SeekOrigin.Current); - - // New track - if ((btoi(buffer[1]) == (btoi(sub[1]) + 1)) && (buffer[2] == 0 || buffer[2] == 1)) - { - Array.Copy(buffer, sub, 6); - tpos = ((btoi((byte)(buffer[3] * 60)) + btoi(buffer[4])) * 75) + btoi(buffer[5]); - } - - // New index - else if (btoi(buffer[2]) == (btoi(sub[2]) + 1) && buffer[1] == sub[1]) - { - Array.Copy(buffer, 2, sub, 2, 4); - tpos = ((btoi((byte)(buffer[3] * 60)) + btoi(buffer[4])) * 75) + btoi(buffer[5]); - } - - // MSF1 [3-5] - else - { - if (sub[2] == 0) - tpos--; - else - tpos++; - - sub[3] = itob((byte)(tpos / 60 / 75)); - sub[4] = itob((byte)((tpos / 75) % 60)); - sub[5] = itob((byte)(tpos % 75)); - } - - // MSF2 [7-9] - sub[7] = itob((byte)(sector / 60 / 75)); - sub[8] = itob((byte)((sector / 75) % 60)); - sub[9] = itob((byte)(sector % 75)); - - // CRC-16 [10-11] - ushort crc = CRC16.Calculate(sub, 0, 10); - byte[] crcBytes = BitConverter.GetBytes(crc); - sub[10] = crcBytes[0]; - sub[11] = crcBytes[1]; - - // If any byte (except position 6) is different, it's a modified sector - for (int i = 0; i < 12; i++) - { - if (i == 6) - continue; - - if (buffer[i] != sub[i]) - { - modifiedSectors++; - break; - } - } - } - - return modifiedSectors != 0; - } - - #endregion - - #region Constants - - private const uint IOCTL_SCSI_PASS_THROUGH_DIRECT = 0x4D014; - private const byte SCSI_IOCTL_DATA_IN = 0x1; - private const byte RAW_READ_CMD = 0xBE; - private const int BUFFER_LEN = 96; - private const int SENSE_SIZE = 0; //14 - private const string F_NAME = "sectors.log"; - private const int CYCLES = 5; - private const int LIBCRYPT_NUM_SECTORS = 64; - private const int READ_TIMES = 5; - - private static readonly uint[] lc_addresses = new uint[LIBCRYPT_NUM_SECTORS] -{ - 13955, 13960, 14081, 14086, 14335, 14340, 14429, 14434, - 14499, 14504, 14749, 14754, 14906, 14911, 14980, 14985, - 15092, 15097, 15162, 15167, 15228, 15233, 15478, 15483, - 15769, 15774, 15881, 15886, 15951, 15956, 16017, 16022, - 41895, 41900, 42016, 42021, 42282, 42287, 42430, 42435, - 42521, 42526, 42663, 42668, 42862, 42867, 43027, 43032, - 43139, 43144, 43204, 43209, 43258, 43263, 43484, 43489, - 43813, 43818, 43904, 43909, 44009, 44014, 44162, 44167 -}; - - private static readonly byte[] lc1_sectors_contents = new byte[768] - { - 0x41, 0x01, 0x01, 0x07, 0x06, 0x05, 0x00, 0x23, 0x08, 0x05, 0x38, 0x39, - 0x41, 0x01, 0x01, 0x03, 0x06, 0x11, 0x00, 0x03, 0x08, 0x90, 0x5d, 0xa0, - 0x41, 0x01, 0x01, 0x07, 0x07, 0x56, 0x00, 0x23, 0x09, 0x56, 0xdf, 0xde, - 0x41, 0x01, 0x01, 0x03, 0x07, 0x60, 0x00, 0x03, 0x09, 0xe1, 0xf2, 0x50, - 0x41, 0x01, 0x01, 0x03, 0x13, 0x10, 0x00, 0x03, 0x53, 0x10, 0x50, 0xec, - 0x41, 0x01, 0x01, 0x43, 0x11, 0x15, 0x00, 0x01, 0x13, 0x15, 0x23, 0x1e, - 0x41, 0x01, 0x01, 0x03, 0x12, 0x09, 0x00, 0x03, 0x14, 0x2d, 0x04, 0x73, - 0x41, 0x01, 0x01, 0x03, 0x1a, 0x34, 0x00, 0x03, 0x04, 0x34, 0xe2, 0xcf, - 0x41, 0x01, 0x01, 0x03, 0x13, 0x20, 0x00, 0x03, 0x15, 0x04, 0x82, 0x35, - 0x41, 0x01, 0x01, 0x01, 0x13, 0x29, 0x00, 0x43, 0x15, 0x29, 0x72, 0xe2, - 0x41, 0x01, 0x01, 0x03, 0x1e, 0x49, 0x00, 0x03, 0x08, 0x49, 0x32, 0xc5, - 0x41, 0x01, 0x01, 0x01, 0x16, 0x54, 0x00, 0x43, 0x18, 0x54, 0xd4, 0x79, - 0x41, 0x01, 0x01, 0x03, 0x18, 0x57, 0x00, 0x03, 0x20, 0xd6, 0xbc, 0x27, - 0x41, 0x01, 0x01, 0x03, 0x38, 0x61, 0x00, 0x03, 0x24, 0x61, 0x91, 0xa9, - 0x41, 0x01, 0x01, 0x0b, 0x19, 0x55, 0x00, 0x13, 0x21, 0x55, 0x14, 0x07, - 0x41, 0x01, 0x01, 0x03, 0x19, 0x62, 0x00, 0x03, 0x21, 0x20, 0x5d, 0x48, - 0x41, 0x01, 0x01, 0x03, 0x23, 0x17, 0x00, 0x03, 0x63, 0x17, 0x6d, 0xc6, - 0x41, 0x01, 0x01, 0x43, 0x21, 0x22, 0x00, 0x01, 0x23, 0x22, 0x24, 0x89, - 0x41, 0x01, 0x01, 0x03, 0x02, 0x12, 0x00, 0x03, 0x20, 0x12, 0x49, 0x43, - 0x41, 0x01, 0x01, 0x03, 0x22, 0x07, 0x00, 0x03, 0x24, 0x1f, 0x3a, 0xb1, - 0x41, 0x01, 0x01, 0x03, 0x23, 0x13, 0x00, 0x03, 0x25, 0x0b, 0x93, 0xc9, - 0x41, 0x01, 0x01, 0x0b, 0x23, 0x08, 0x00, 0x13, 0x25, 0x08, 0xce, 0x5d, - 0x41, 0x01, 0x01, 0x03, 0x06, 0x28, 0x00, 0x03, 0x2c, 0x28, 0xd7, 0xd6, - 0x41, 0x01, 0x01, 0x0b, 0x26, 0x33, 0x00, 0x13, 0x28, 0x33, 0x9c, 0x29, - 0x41, 0x01, 0x01, 0x03, 0x30, 0x59, 0x00, 0x03, 0x32, 0x1b, 0x2c, 0xc6, - 0x41, 0x01, 0x01, 0x03, 0x20, 0x24, 0x00, 0x03, 0x3a, 0x24, 0xe6, 0xac, - 0x41, 0x01, 0x01, 0x13, 0x31, 0x56, 0x00, 0x0b, 0x33, 0x56, 0x97, 0xed, - 0x41, 0x01, 0x01, 0x03, 0x31, 0x65, 0x00, 0x03, 0x33, 0x41, 0xba, 0x63, - 0x41, 0x01, 0x01, 0x01, 0x32, 0x51, 0x00, 0x43, 0x34, 0x51, 0xd7, 0xa9, - 0x41, 0x01, 0x01, 0x03, 0x33, 0x56, 0x00, 0x03, 0xb4, 0x56, 0xc0, 0x9a, - 0x41, 0x01, 0x01, 0x03, 0x32, 0x42, 0x00, 0x03, 0xb5, 0x42, 0x69, 0xe2, - 0x41, 0x01, 0x01, 0x03, 0x33, 0x07, 0x00, 0x03, 0x35, 0x45, 0x1a, 0x10, - 0x41, 0x01, 0x01, 0x09, 0x18, 0x65, 0x00, 0x09, 0x20, 0x41, 0x40, 0x72, - 0x41, 0x01, 0x01, 0x19, 0x18, 0x50, 0x00, 0x01, 0x20, 0x50, 0x25, 0xeb, - 0x41, 0x01, 0x01, 0x08, 0x20, 0x16, 0x00, 0x89, 0x22, 0x16, 0x95, 0xa8, - 0x41, 0x01, 0x01, 0x09, 0x20, 0x01, 0x00, 0x09, 0x22, 0x25, 0xb8, 0x26, - 0x41, 0x01, 0x01, 0x09, 0x23, 0x53, 0x00, 0x09, 0x25, 0x77, 0x21, 0x03, - 0x41, 0x01, 0x01, 0x0b, 0x23, 0x62, 0x00, 0x49, 0x25, 0x62, 0x68, 0x4c, - 0x41, 0x01, 0x01, 0x0d, 0x25, 0x55, 0x00, 0x29, 0x27, 0x55, 0xae, 0x41, - 0x41, 0x01, 0x01, 0x09, 0x25, 0x61, 0x00, 0x09, 0x27, 0xe0, 0xe7, 0x0e, - 0x41, 0x01, 0x01, 0x08, 0x26, 0x71, 0x00, 0x89, 0x28, 0x71, 0x95, 0xcb, - 0x41, 0x01, 0x01, 0x09, 0x27, 0x21, 0x00, 0x09, 0x29, 0x05, 0x80, 0x4b, - 0x41, 0x01, 0x01, 0x0b, 0x28, 0x63, 0x00, 0x49, 0x30, 0x63, 0xed, 0x18, - 0x41, 0x01, 0x01, 0x09, 0x29, 0x68, 0x00, 0x09, 0xb0, 0x68, 0xb0, 0x8c, - 0x41, 0x01, 0x01, 0x29, 0x31, 0x37, 0x00, 0x0d, 0x33, 0x37, 0x6c, 0x68, - 0x41, 0x01, 0x01, 0x09, 0x31, 0x4a, 0x00, 0x09, 0x33, 0x52, 0x7c, 0x8b, - 0x41, 0x01, 0x01, 0x09, 0x73, 0x52, 0x00, 0x09, 0x37, 0x52, 0x4b, 0x06, - 0x41, 0x01, 0x01, 0x19, 0x33, 0x57, 0x00, 0x01, 0x35, 0x57, 0x38, 0xf4, - 0x41, 0x01, 0x01, 0x09, 0x35, 0x04, 0x00, 0x09, 0x37, 0x1c, 0x54, 0x6a, - 0x41, 0x01, 0x01, 0x09, 0x31, 0x19, 0x00, 0x09, 0x17, 0x19, 0xa4, 0xbd, - 0x41, 0x01, 0x01, 0x01, 0x36, 0x04, 0x00, 0x19, 0x38, 0x04, 0x9c, 0xdf, - 0x41, 0x01, 0x01, 0x09, 0x36, 0x0b, 0x00, 0x09, 0x38, 0x49, 0x6c, 0x08, - 0x41, 0x01, 0x01, 0x49, 0x36, 0x58, 0x00, 0x0b, 0x38, 0x58, 0x99, 0xbf, - 0x41, 0x01, 0x01, 0x09, 0x36, 0x73, 0x00, 0x09, 0x38, 0x6b, 0xfe, 0x96, - 0x41, 0x01, 0x01, 0x0b, 0x39, 0x59, 0x00, 0x49, 0x41, 0x59, 0x54, 0x0d, - 0x41, 0x01, 0x01, 0x09, 0x39, 0x24, 0x00, 0x09, 0x41, 0x66, 0x9e, 0x67, - 0x41, 0x01, 0x01, 0x09, 0x44, 0x1b, 0x00, 0x09, 0x46, 0x03, 0x78, 0x0d, - 0x41, 0x01, 0x01, 0x09, 0x46, 0x18, 0x00, 0x09, 0x06, 0x18, 0x25, 0x99, - 0x41, 0x01, 0x01, 0x09, 0x45, 0x2b, 0x00, 0x09, 0x47, 0x69, 0xd3, 0xc5, - 0x41, 0x01, 0x01, 0x09, 0x05, 0x34, 0x00, 0x09, 0x45, 0x34, 0x35, 0x79, - 0x41, 0x01, 0x01, 0x09, 0x44, 0x59, 0x00, 0x09, 0x08, 0x59, 0x6e, 0x0a, - 0x41, 0x01, 0x01, 0x49, 0x46, 0x64, 0x00, 0x0b, 0x48, 0x64, 0xa4, 0x60, - 0x41, 0x01, 0x01, 0x09, 0x08, 0x62, 0x00, 0x09, 0x52, 0x62, 0x03, 0x5a, - 0x41, 0x01, 0x01, 0x19, 0x48, 0x67, 0x00, 0x01, 0x50, 0x67, 0x70, 0xa8 - }; - - #endregion - - // TODO: Enable the following only if reading from a drive directly - - /* - internal static byte LibCryptDrive(string[] args) - { - byte offset = 0; - string path = $"\\\\.\\{args[0][0]}:"; - byte i; - byte[] sub = new byte[12], buffer = new byte[BUFFER_LEN], buffer2352 = new byte[23520], buffer2 = new byte[BUFFER_LEN], buffer3 = new byte[BUFFER_LEN], buffer4 = new byte[BUFFER_LEN]; - byte[] status; - ushort crc; - uint sector, sector_start, sector_end, a, lcsectors = 0, todo = 9300, done = 0; - - if (args.Length != 1 || (args.Length == 1 && (args[0][1] != 0 && (args[0][1] != ':' || args[0][2] != 0)))) - { - Console.WriteLine("LibCrypt drive detector"); - Console.WriteLine("nUsage: psxt001z.exe --libcryptdrv "); - return 0; - } - - Stream hDevice; - try - { - hDevice = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); - } - catch (Exception ex) - { - Console.WriteLine("Can't open device!"); - return 0; - } - - Stream f; - try - { - f = File.Open(F_NAME, FileMode.Open, FileAccess.Write); - } - catch (Exception ex) - { - Console.WriteLine($"Can't open file {F_NAME}!"); - return 0; - } - - byte[] status1 = new byte[4650]; - byte[] status2 = new byte[4650]; - - // Offset detection - Console.WriteLine("Determining offset...\r"); - ScsiPassThroughDirect SRB = new ScsiPassThroughDirect(); - ReadSub(buffer, 0, f, offset, hDevice, SRB); - - switch (buffer[8]) - { - case 0x01: - offset = (byte)(75 - btoi(buffer[9])); - break; - case 0x02: - offset = (byte)(-btoi(buffer[9])); - break; - default: - Console.WriteLine("Can't determine offset!"); - Console.WriteLine(BitConverter.ToString(buffer).Replace('-', ' ')); - return 0; - } - - sub[0] = buffer[0]; - sub[1] = 0x01; - sub[2] = 0x01; - sub[6] = 0x00; - - Console.WriteLine($"Subchannels offset correction: {offset}"); - - // Section 1) 02:58:00 - 03:69:74 -- status1 - // Section 2) 08:58:00 - 09:69:74 -- status2 - - // Step 1 - - for (i = 0; i < CYCLES * 3; i++) - { - - if (todo == 0) - goto end; - - if (i % 3 == 0) - { - sector_start = 13350; - sector_end = 18000; - status = status1; - } - else if (i % 3 == 1) - { - sector_start = 40350; - sector_end = 45000; - status = status2; - } - else - { - Console.WriteLine($"Left: {todo:4} / Flushing cache... \r"); - ClearCache(buffer2352, f, offset, hDevice, SRB); - continue; - } - - for (sector = sector_start; sector < sector_end; sector++) - { - if (status[sector - sector_start] != 0) - continue; - - ReadSub(buffer, sector, f, offset, hDevice, SRB); - Console.WriteLine("Left: %4u / Sector %u... \r", todo, sector); - // generating q-channel - sub[3] = itob((byte)(sector / 60 / 75)); - sub[4] = itob((byte)((sector / 75) % 60)); - sub[5] = itob((byte)(sector % 75)); - sub[7] = itob((byte)((sector + 150) / 60 / 75)); - sub[8] = itob((byte)(((sector + 150) / 75) % 60)); - sub[9] = itob((byte)((sector + 150) % 75)); - crc = CRC16.Calculate(sub, 0, 10); - sub[10] = (byte)(crc >> 8); - sub[11] = (byte)(crc & 0xFF); - if (sub.SequenceEqual(buffer.Take(12))) - { - status[sector - sector_start] = 1; - todo--; - done++; - } - } - } - - // Step 2 - - for (i = 0; i < 2; i++) - { - if (i == 0) - { - sector_start = 13350; - sector_end = 18000; - status = status1; - } - else - { - sector_start = 40350; - sector_end = 45000; - status = status2; - } - - for (sector = sector_start; sector < sector_end; sector++) - { - if (status[sector - sector_start] != 0) - continue; - ReadSub(buffer, sector, f, offset, hDevice, SRB); - Console.WriteLine($"Left: {todo:4} / Sector {sector}... \r"); - - // generating q-channel - sub[3] = itob((byte)(sector / 60 / 75)); - sub[4] = itob((byte)((sector / 75) % 60)); - sub[5] = itob((byte)(sector % 75)); - sub[7] = itob((byte)((sector + 150) / 60 / 75)); - sub[8] = itob((byte)(((sector + 150) / 75) % 60)); - sub[9] = itob((byte)((sector + 150) % 75)); - crc = CRC16.Calculate(sub, 0, 10); - sub[10] = (byte)(crc >> 8); - sub[11] = (byte)(crc ^ 0xFF); - if (sub.SequenceEqual(buffer.Take(12))) - { - Console.WriteLine($"Left: {todo:4} / Sector {sector}: flushing cache... \r"); - do - { - ReadSub(buffer, sector, f, offset, hDevice, SRB); - ClearCache(buffer2352, f, offset, hDevice, SRB); - ReadSub(buffer2, sector, f, offset, hDevice, SRB); - ClearCache(buffer2352, f, offset, hDevice, SRB); - ReadSub(buffer3, sector, f, offset, hDevice, SRB); - ClearCache(buffer2352, f, offset, hDevice, SRB); - } while (!buffer.SequenceEqual(buffer2) || !buffer.SequenceEqual(buffer3)); - //} while (!matrix(buffer, buffer2, buffer3, buffer4, BUFFER_LEN)); - - if (buffer.SequenceEqual(sub)) - { - byte[] buf = Encoding.ASCII.GetBytes($"MSF: {sub[7]:2x}:{sub[8]:2x}:{sub[9]:2x} Q-Data: {BitConverter.ToString(buffer.Take(12).ToArray()).Replace('-', ' ')}"); - f.Write(buf, 0, buf.Length); - lcsectors++; - //fwrite(SRB.SRB_BufPointer, 1, SRB.SRB_BufLen - 4, f); - f.Flush(); - } - } - - todo--; - done++; - } - } - - end: - - Console.WriteLine($"Done! \nProtected sectors: {(lcsectors == 0 ? "None" : lcsectors.ToString())}"); - - f.Close(); - return 1; - } - - internal static int LibCryptDriveFast(string[] args) - { - Stream f; - Stream hDevice; - ScsiPassThroughDirect SRB; - s8 offset = 0, path[] = "\\\\.\\X:"; - u8 buffer[BUFFER_LEN], buffer2352[23520], sub[12], lc1sectors = 0, lc2sectors = 0, othersectors = 0; - u16 crc; - - if (argc != 1 || (argc == 1 && (args[0][1] != 0 && (args[0][1] != ':' || args[0][2] != 0)))) - { - Console.WriteLine("LibCrypt drive detector (fast)\nUsage: psxt001z.exe --libcryptdrvfast \n"); - return 0; - } - - path[4] = args[0][0]; - - if ((hDevice = CreateFile(path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) - { - Console.WriteLine("Can't open device!\n"); - return 0; - } - - if (fopen_s(&f, F_NAME, "wb") != 0) - { - Console.WriteLine("Can\'t open file %s!\n", F_NAME); - return 0; - } - - // Offset detection - ReadSub(buffer, 0, f, offset, hDevice, SRB); - //if (buffer[5] != buffer[9]) { - // Console.WriteLine("Error determining offset!\nSector 0: %02x%02x%02x %02x:%02x:%02x %02x %02x:%02x:%02x %02x%02x\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11]); - //} - switch (buffer[8]) - { - case 0x01: - offset = 75 - btoi(buffer[9]); - break; - case 0x02: - offset = -btoi(buffer[9]); - break; - default: - Console.WriteLine("Can't determine offset!\nSector 0: %02x%02x%02x %02x:%02x:%02x %02x %02x:%02x:%02x %02x%02x\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11]); - return 0; - } - Console.WriteLine("Subchannels offset correction: %d\n", offset); - sub[0] = buffer[0]; - sub[1] = 0x01; - sub[2] = 0x01; - sub[6] = 0x00; - - for (int i = 0; i < LIBCRYPT_NUM_SECTORS; i++) - { - Console.WriteLine("\nReading sector %u... ", lc_addresses[i]); - ReadSub(buffer, lc_addresses[i], f, offset, hDevice, SRB); - // generating q-channel - sub[3] = itob(lc_addresses[i] / 60 / 75); - sub[4] = itob((lc_addresses[i] / 75) % 60); - sub[5] = itob(lc_addresses[i] % 75); - sub[7] = itob((lc_addresses[i] + 150) / 60 / 75); - sub[8] = itob(((lc_addresses[i] + 150) / 75) % 60); - sub[9] = itob((lc_addresses[i] + 150) % 75); - crc = crc16(sub, 10); - sub[10] = HIbyte(crc); - sub[11] = LObyte(crc); - for (int a = 1; a <= READ_TIMES; a++) - { - if (!memcmp(sub, buffer, 12)) - { - Console.WriteLine("original sector"); - break; - } - else if (!memcmp(lc1_sectors_contents + (12 * i), buffer, 12)) - { - Console.WriteLine("LibCrypt, LC1 sector"); - fConsole.WriteLine(f, "MSF: %02x:%02x:%02x Q-Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", sub[7], sub[8], sub[9], buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11]); - lc1sectors++; - break; - } - else - { - if (a < READ_TIMES) - { - ClearCache(buffer2352, 0, offset, hDevice, SRB); - continue; - } - else - { - Console.WriteLine("unknown"); - fConsole.WriteLine(f, "MSF: %02x:%02x:%02x Q-Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", sub[7], sub[8], sub[9], buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11]); - othersectors++; - } - } - } - - - - } - Console.WriteLine("\n\nOriginal sectors: %u", LIBCRYPT_NUM_SECTORS - lc1sectors - lc2sectors - othersectors); - Console.WriteLine("\nLC1 sectors: %u", lc1sectors); - Console.WriteLine("\nLC2 sectors: %u", lc2sectors); - Console.WriteLine("\nOther sectors: %u", othersectors); - - fConsole.WriteLine(f, "\nOriginal sectors: %u", LIBCRYPT_NUM_SECTORS - lc1sectors - lc2sectors - othersectors); - fConsole.WriteLine(f, "\nLC1 sectors: %u", lc1sectors); - fConsole.WriteLine(f, "\nLC2 sectors: %u", lc2sectors); - fConsole.WriteLine(f, "\nOther sectors: %u", othersectors); - fclose(f); - return 1; - } - - internal static void ReadSub(byte[] buffer, uint sector, Stream f, byte offset, Stream hDevice, ScsiPassThroughDirect SRB) - { - uint returned; - ZeroMemory(&SRB, sizeof(ScsiPassThroughDirect)); - SRB.Length = sizeof(ScsiPassThroughDirect); - SRB.CDBLength = 12; - SRB.DataIn = SCSI_IOCTL_DATA_IN; - SRB.DataTransferLength = BUFFER_LEN; - SRB.TimeOutValue = 30; - SRB.DataBuffer = buffer; - SRB.CDB[0] = RAW_READ_CMD; - SRB.CDB[2] = HIbyte(HIWORD(sector + offset)); - SRB.CDB[3] = LObyte(HIWORD(sector + offset)); - SRB.CDB[4] = HIbyte(LOWORD(sector + offset)); - SRB.CDB[5] = LObyte(LOWORD(sector + offset)); - SRB.CDB[8] = 1; - SRB.CDB[10] = 1; - - if (!DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &SRB, sizeof(ScsiPassThroughDirect), &SRB, SENSE_SIZE, &returned, 0)) - { - Console.WriteLine("\nError reading subchannel data!\n"); - if (f != 0) - fConsole.WriteLine(f, "Error reading subchannel data!"); - - return 0; - } - - Deinterleave(buffer); - return; - } - - internal static void ClearCache(byte[] buffer, Stream f, byte offset, Stream hDevice, ScsiPassThroughDirect SRB) - { - static uint returned; - for (uint sector = 0; sector < 1000; sector += 10) - { - ZeroMemory(&SRB, sizeof(ScsiPassThroughDirect)); - SRB.Length = sizeof(ScsiPassThroughDirect); - SRB.CDBLength = 12; - SRB.DataIn = SCSI_IOCTL_DATA_IN; - SRB.DataTransferLength = 23520; - SRB.TimeOutValue = 30; - SRB.DataBuffer = buffer; - SRB.CDB[0] = RAW_READ_CMD; - SRB.CDB[2] = HIbyte(HIWORD(sector + offset)); - SRB.CDB[3] = LObyte(HIWORD(sector + offset)); - SRB.CDB[4] = HIbyte(LOWORD(sector + offset)); - SRB.CDB[5] = LObyte(LOWORD(sector + offset)); - SRB.CDB[8] = 10; - SRB.CDB[9] = 0xF8; - - DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &SRB, sizeof(ScsiPassThroughDirect), &SRB, SENSE_SIZE, &returned, 0); - - if (!DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &SRB, sizeof(ScsiPassThroughDirect), &SRB, SENSE_SIZE, &returned, 0)) - { - Console.WriteLine("\nError clearing cache!\n"); - if (f != 0) - fConsole.WriteLine(f, "Error clearing cache!"); - exit(0); - } - } - return; - } - */ - - internal static bool Matrix(byte[] buffer, byte[] buffer2, byte[] buffer3, byte[] buffer4, uint length) - { - for (int i = 0; i < length; i++) - { - if (buffer[i] == buffer2[i]) - { - if (buffer[i] == buffer3[i]) - continue; - if (buffer[i] == buffer4[i]) - continue; - } - else if (buffer[i] == buffer3[i] && buffer[i] == buffer4[i]) - { - continue; - } - else if (buffer2[i] == buffer3[i] && buffer2[i] == buffer4[i]) - { - continue; - } - - return false; - } - - return true; - } - - internal static void Deinterleave(byte[] buffer) - { - byte[] buffertmp = new byte[12]; - for (int i = 0; i < 12; i++) - { - buffertmp[i] |= (byte)((buffer[i * 8] & 0x40) << 1); - buffertmp[i] |= (byte)((buffer[i * 8 + 1] & 0x40)); - buffertmp[i] |= (byte)((buffer[i * 8 + 2] & 0x40) >> 1); - buffertmp[i] |= (byte)((buffer[i * 8 + 3] & 0x40) >> 2); - buffertmp[i] |= (byte)((buffer[i * 8 + 4] & 0x40) >> 3); - buffertmp[i] |= (byte)((buffer[i * 8 + 5] & 0x40) >> 4); - buffertmp[i] |= (byte)((buffer[i * 8 + 6] & 0x40) >> 5); - buffertmp[i] |= (byte)((buffer[i * 8 + 7] & 0x40) >> 6); - } - - Array.Copy(buffertmp, buffer, 12); - return; - } - - internal static bool LibCryptDetect(string subPath, string sbiPath) - { - if (string.IsNullOrWhiteSpace(subPath) || !File.Exists(subPath)) - return false; - - // Variables - byte[] buffer = new byte[16], sub = new byte[16];//, pregap = 0; - uint sector, psectors = 0, tpos = 0; - - // Opening .sub - Stream subfile = File.OpenRead(subPath); - - // checking extension - if (Path.GetExtension(subPath).TrimStart('.').ToLowerInvariant() != "sub") - { - Console.WriteLine($"{subPath}: unknown file extension"); - return false; - } - - // filesize - long size = subfile.Length; - if (size % 96 != 0) - { - Console.WriteLine($"{subfile}: wrong size"); - return false; - } - - // sbi - Stream sbi = null; - if (sbiPath != null) - { - sbi = File.OpenWrite(sbiPath); - sbi.Write(Encoding.ASCII.GetBytes("SBI\0"), 0, 4); - } - - for (sector = 150; sector < ((size / 96) + 150); sector++) - { - subfile.Seek(12, SeekOrigin.Current); - if (subfile.Read(buffer, 0, 12) != 12) - return true; - - subfile.Seek(72, SeekOrigin.Current); - - // New track - if ((btoi(buffer[1]) == (btoi(sub[1]) + 1)) && (buffer[2] == 0 || buffer[2] == 1)) - { - Array.Copy(buffer, sub, 6); - tpos = (uint)((btoi((byte)(buffer[3] * 60)) + btoi(buffer[4])) * 75) + btoi(buffer[5]); - } - - // New index - else if (btoi(buffer[2]) == (btoi(sub[2]) + 1) && buffer[1] == sub[1]) - { - Array.Copy(buffer, 2, sub, 2, 4); - tpos = (uint)((btoi((byte)(buffer[3] * 60)) + btoi(buffer[4])) * 75) + btoi(buffer[5]); - } - - // MSF1 [3-5] - else - { - if (sub[2] == 0) - tpos--; - else - tpos++; - - sub[3] = itob((byte)(tpos / 60 / 75)); - sub[4] = itob((byte)((tpos / 75) % 60)); - sub[5] = itob((byte)(tpos % 75)); - } - - //MSF2 [7-9] - sub[7] = itob((byte)(sector / 60 / 75)); - sub[8] = itob((byte)((sector / 75) % 60)); - sub[9] = itob((byte)(sector % 75)); - - // CRC-16 [10-11] - ushort crc = CRC16.Calculate(sub, 0, 10); - sub[10] = (byte)(crc >> 8); - sub[11] = (byte)(crc & 0xFF); - - //if (buffer[10] != sub[10] && buffer[11] != sub[11] && (buffer[3] != sub[3] || buffer[7] != sub[7] || buffer[4] != sub[4] || buffer[8] != sub[8] || buffer[5] != sub[5] || buffer[9] != sub[9])) { - //if (buffer[10] != sub[10] || buffer[11] != sub[11] || buffer[3] != sub[3] || buffer[7] != sub[7] || buffer[4] != sub[4] || buffer[8] != sub[8] || buffer[5] != sub[5] || buffer[9] != sub[9]) { - if (!buffer.Take(6).SequenceEqual(sub.Take(6)) || !buffer.Skip(7).Take(5).SequenceEqual(sub.Skip(7).Take(5))) - { - Console.WriteLine($"MSF: {sub[7]:2x}:{sub[8]:2x}:{sub[9]:2x} Q-Data: {buffer[0]:2x}{buffer[1]:2x}{buffer[2]:2x} {buffer[3]:2x}:{buffer[4]:2x}:{buffer[5]:2x} {buffer[6]:2x} {buffer[7]:2x}:{buffer[8]:2x}:{buffer[9]:2x} {buffer[10]:2x}{buffer[11]:2x} xor {crc ^ ((buffer[10] << 8) + buffer[11]):4x} {CRC16.Calculate(buffer, 0, 10) ^ ((buffer[10] << 8) + buffer[11]):4x}"); - //Console.WriteLine("\nMSF: %02x:%02x:%02x Q-Data: %02x%02x%02x %02x:%02x:%02x %02x %02x:%02x:%02x %02x%02x", sub[7], sub[8], sub[9], sub[0], sub[1], sub[2], sub[3], sub[4], sub[5], sub[6], sub[7], sub[8], sub[9], sub[10], sub[11]); - - if (buffer[3] != sub[3] && buffer[7] != sub[7] && buffer[4] == sub[4] && buffer[8] == sub[8] && buffer[5] == sub[5] && buffer[9] == sub[9]) - Console.WriteLine($" P1 xor {buffer[3] ^ sub[3]:2x} {buffer[7] ^ sub[7]:2x}"); - else if (buffer[3] == sub[3] && buffer[7] == sub[7] && buffer[4] != sub[4] && buffer[8] != sub[8] && buffer[5] == sub[5] && buffer[9] == sub[9]) - Console.WriteLine($" P2 xor {buffer[4] ^ sub[4]:2x} {buffer[8] ^ sub[8]:2x}"); - else if (buffer[3] == sub[3] && buffer[7] == sub[7] && buffer[4] == sub[4] && buffer[8] == sub[8] && buffer[5] != sub[5] && buffer[9] != sub[9]) - Console.WriteLine($" P3 xor {buffer[5] ^ sub[5]:2x} {buffer[9] ^ sub[9]:2x}"); - else - Console.WriteLine(" ?"); - - Console.WriteLine("\n"); - psectors++; - if (sbi != null) - { - sbi.Write(sub, 7, 3); - sbi.Write(new byte[] { 0x01 }, 0, 1); - sbi.Write(buffer, 0, 10); - } - } - } - // } - - Console.WriteLine($"Number of modified sectors: {psectors}"); - return true; - } - - internal static int XorLibCrypt() - { - sbyte b; - byte d; - byte i, a, x; - byte[] sub = new byte[12] - { - 0x41, 0x01, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - - ushort crc; - for (i = 0; i < LIBCRYPT_NUM_SECTORS; i++) - { - sub[3] = itob((byte)(lc_addresses[i] / 60 / 75)); - sub[4] = itob((byte)((lc_addresses[i] / 75) % 60)); - sub[5] = itob((byte)(lc_addresses[i] % 75)); - sub[7] = itob((byte)((lc_addresses[i] + 150) / 60 / 75)); - sub[8] = itob((byte)(((lc_addresses[i] + 150) / 75) % 60)); - sub[9] = itob((byte)((lc_addresses[i] + 150) % 75)); - crc = CRC16.Calculate(sub, 0, 10); - sub[10] = (byte)(crc >> 8); - sub[11] = (byte)(crc & 0xFF); - - Console.WriteLine($"%u %02x:%02x:%02x", lc_addresses[i], sub[7], sub[8], sub[9]); - Console.WriteLine($" %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x %02x%02x", sub[0], sub[1], sub[2], sub[3], sub[4], sub[5], sub[6], sub[7], sub[8], sub[9], sub[10], sub[11]); - Console.WriteLine($" %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x %02x%02x", lc1_sectors_contents[i * 12], lc1_sectors_contents[(i * 12) + 1], lc1_sectors_contents[(i * 12) + 2], lc1_sectors_contents[(i * 12) + 3], lc1_sectors_contents[(i * 12) + 4], lc1_sectors_contents[(i * 12) + 5], lc1_sectors_contents[(i * 12) + 6], lc1_sectors_contents[(i * 12) + 7], lc1_sectors_contents[(i * 12) + 8], lc1_sectors_contents[(i * 12) + 9], lc1_sectors_contents[(i * 12) + 10], lc1_sectors_contents[(i * 12) + 11]); - - d = 0; - - for (a = 3; a < 12; a++) - { - x = (byte)(lc1_sectors_contents[(i * 12) + a] ^ sub[a]); - Console.WriteLine($" %x%x%x%x%x%x%x%x", (x >> 7) & 0x1, (x >> 6) & 0x1, (x >> 5) & 0x1, (x >> 4) & 0x1, (x >> 3) & 0x1, (x >> 2) & 0x1, (x >> 1) & 0x1, x & 0x1); - if (x == 0) - continue; - for (b = 7; b >= 0; b--) - { - if (((x >> b) & 0x1) != 0) - { - d = (byte)(d << 1); - d |= (byte)((sub[a] >> b) & 0x1); - } - } - } - - Console.WriteLine($" {(d >> 3) & 0x1:x}{(d >> 2) & 0x1:x}{(d >> 1) & 0x1:x}{d & 0x1}"); - } - - return 1; - } - } -} diff --git a/psxt001z/Main.cs b/psxt001z/Main.cs deleted file mode 100644 index 01ca2ec9..00000000 --- a/psxt001z/Main.cs +++ /dev/null @@ -1,1004 +0,0 @@ -using System; -using System.IO; -using System.Security.Cryptography; -using static psxt001z.Common; -using static psxt001z.Functions; - -namespace psxt001z -{ - public class Main - { - public static int main(string[] args) - { - Console.WriteLine($"psxt001z by Dremora, {VERSION}"); - Console.WriteLine(); - - if (args == null || args.Length == 0) - { - Help(); - return -1; - } - - if (args.Length == 1) - GetInfo(args[0]); - - string feature = args[0]; - switch (feature) - { - case "--checksums": - case "-c": - Checksums(args); - break; - - case "--libcrypt": - case "-l": - { - if (args.Length != 1 && args.Length != 2) - { - LibCryptHelp(); - return 0; - } - - string subPath = args[0]; - string sbiPath = null; - if (args.Length == 2) - sbiPath = args[1]; - - if (!LibCrypt.LibCryptDetect(subPath, sbiPath)) - LibCryptHelp(); - - break; - } - - case "--xorlibcrypt": - LibCrypt.XorLibCrypt(); - break; - - case "--zektor": - ClearEDCData(args[1]); - break; - - case "--antizektor": - SetEDCData(args[1]); - break; - - case "--patch": - { - string output = args[1]; - string input = args[2]; - int skip = 0; - if (args.Length == 4) - skip = int.Parse(args[3]); - - Patch(output, input, skip); - break; - } - - case "--resize": - { - string input = args[1]; - long newsize = long.Parse(args[2]); - Resize(input, newsize); - break; - } - - case "--track": - { - string filename = args[1]; - int start = int.Parse(args[2]); - int size = int.Parse(args[3]); - uint crc = uint.Parse(args[4]); - - bool isRiff = false; - bool? mode = null; - string output = null; - for (int i = 5; i < args.Length; i++) - { - if (args[i] == "r") - isRiff = true; - else if (args[i][0] == '+') - mode = true; - else if (args[i][1] == '-') - mode = false; - else if (args[i] == "s") - output = args[++i]; - } - - Track trackfix = new Track(filename, start, size, crc, isRiff, mode, output); - while (!trackfix.FindTrack()) ; - trackfix.Done(); - - break; - } - - case "--str": - SplitStr(args); - break; - - case "--str2bs": - StrToBs(args); - break; - - case "--gen": - Generate(args); - break; - - case "--scan": - Info.GetInfo(args[2], false); - break; - - case "--fix": - Info.GetInfo(args[2], true); - break; - - case "--sub": - CreateSubchannel(args[2], args[3]); - break; - - case "--m3s": - M3S(args[2]); - break; - - case "--matrix": - { - Matrix(args); - break; - } - - //case "--libcryptdrv": - // LibCrypt.LibCryptDrive(argv + 2); - // break; - //case "--libcryptdrvfast": - // LibCrypt.LibCryptDriveFast(argv + 2); - // break; - - default: - Help(); - break; - } - - return 1; - } - - public static void GetInfo(string filename) - { - Stream image; - try - { - image = File.OpenRead(filename); - } - catch (Exception ex) - { - Console.WriteLine($"Error opening file \"{filename}\"! {ex}"); - return; - } - - FileTools file = new FileTools(image); - long imagesize = image.Length; - - Console.WriteLine($"File: {filename}"); - if (imagesize % 2352 != 0) - { - Console.WriteLine($"File \"{filename}\" is not Mode2/2352 image!"); - image.Close(); - return; - } - - long realsectors = file.imagesize(); - long imagesectors = imagesize / 2352; - long realsize = realsectors * 2352; - if (imagesize == realsize) - { - Console.WriteLine($"Size (bytes): {imagesize} (OK)"); - Console.WriteLine($"Size (sectors): {imagesectors} (OK)"); - } - else - { - Console.WriteLine($"Size (bytes): {imagesize}"); - Console.WriteLine($"From image: {realsize}"); - Console.WriteLine($"Size (sectors): {imagesectors}"); - Console.WriteLine($"From image: {realsectors}"); - } - - Console.WriteLine($"EDC in Form 2 sectors: {(GetEDCStatus(image) ? "YES" : "NO")}"); - - string exe = file.exe(); - Console.WriteLine($"ID: {exe.Substring(0, 4)}-{exe.Substring(5)}"); - Console.WriteLine($"Date: {file.date()}"); - - Console.Write("System area: "); - image.Seek(0, SeekOrigin.Begin); - - byte[] buffer = new byte[2352]; - CRC32 crc = new CRC32(); - for (uint i = 0; i < 16; i++) - { - image.Read(buffer, 0, 2352); - crc.ProcessCRC(buffer, 0, 2352); - } - - uint imagecrc = crc.m_crc32; - Console.WriteLine($"{Info.GetEdcType(imagecrc)}"); - Console.WriteLine(); - - image.Close(); - return; - } - - public static void Help() - { - Console.Write("Usage:\n"); - - Console.Write("======\n"); - - Console.Write("psxt001z.exe image.bin\n"); - Console.Write(" Display image's info.\n\n"); - - Console.Write("psxt001z.exe --scan image.bin\n"); - Console.Write(" Scan image.bin postgap for errors.\n\n"); - - Console.Write("psxt001z.exe --fix image.bin\n"); - Console.Write(" Scan image.bin postgap for errors and fix them.\n\n"); - - //Console.Write("psxt001z.exe --libcryptdrvfast \n"); - //Console.Write(" Check subchannels for LibCrypt protection using new detection\n method (disc).\n\n"); - - Console.Write("psxt001z.exe --checksums file [start [end]]\n"); - Console.Write(" Calculate file's checksums (CRC-32, MD5, SHA-1).\n"); - Console.Write(" [in] file Specifies the file, which checksums will be calculated.\n"); - Console.Write(" start Specifies start position for checksums calculation.\n"); - Console.Write(" size Specifies size of block for checksums calculation.\n\n"); - - Console.Write("psxt001z.exe --zektor image.bin\n"); - Console.Write(" Zektor. Replace EDC in Form 2 Mode 2 sectors with zeroes.\n\n"); - - Console.Write("psxt001z.exe --antizektor image.bin\n"); - Console.Write(" Antizektor. Restore EDC in Form 2 Mode 2 sectors.\n\n"); - - Console.Write("psxt001z.exe --resize image.bin size\n"); - Console.Write(" Resize file to requested size.\n\n"); - - Console.Write("psxt001z.exe --patch image.bin patch.bin offset\n"); - Console.Write(" Insert patch.bin into image.bin, skipping given number of bytes from the\n offset.\n\n"); - - Console.Write("psxt001z.exe --track image.bin bytes_to_skip size crc-32 [r] [+/-/f] [s filename]\n"); - Console.Write(" Try to guess an offset correction of the image dump by searching a track with\n given size and CRC-32.\n r - Calculate crc with RIFF header.\n +/- - Search only for positive or negative offset correction.\n s - Save track with given filename.\n\n"); - - Console.Write("psxt001z.exe --gen file.bin filesize [-r]\n"); - Console.Write(" Generate a file of the requested size.\n -r - add RIFF header.\n\n"); - - Console.Write("psxt001z.exe --str file.str video.str audio.xa\n"); - Console.Write(" Deinterleave file.str to video.str and audio.xa.\n\n"); - - Console.Write("psxt001z.exe --str2bs file.str\n"); - Console.Write(" Convert file.str to .bs-files.\n\n"); - - Console.Write("psxt001z.exe --sub subchannel.sub size\n"); - Console.Write(" Generate RAW subchannel with given size (in sectors).\n\n"); - - Console.Write("psxt001z.exe --m3s subchannel.m3s\n"); - Console.Write(" Generate M3S subchannel.\n\n"); - - Console.Write("psxt001z.exe --libcrypt []\n"); - Console.Write("Usage: psxt001z.exe --libcrypt []\n"); - Console.Write(" Check subchannels for LibCrypt protection. (file)\n"); - Console.Write(" [in] Specifies the subchannel file to be scanned.\n"); - Console.Write(" [out] Specifies the subchannel file in SBI format where protected\n sectors will be written.\n\n"); - - //Console.Write("psxt001z.exe --libcryptdrv \n"); - //Console.Write(" Check subchannels for LibCrypt protection (disc).\n\n"); - - Console.Write("Press any key to continue..."); - Console.ReadKey(); - } - - public static bool Patch(string output, string input, int skip = 0) - { - Stream f1, f2; - try - { - f1 = File.Open(output, FileMode.Open, FileAccess.ReadWrite); - f2 = File.Open(input, FileMode.Open, FileAccess.Read); - - f1.Seek(skip, SeekOrigin.Begin); - - Console.WriteLine($"Patching \"{output}\" with \"{input}\", skipping {skip} bytes..."); - - int i = 0; - while (f1.Position < f1.Length && f2.Position < f2.Length) - { - byte[] buffer = new byte[1]; - f2.Read(buffer, 0, 1); - f1.Write(buffer, 0, 1); - i++; - } - - Console.WriteLine("Done!"); - Console.WriteLine(); - Console.WriteLine($"{i} bytes were replaced"); - Console.WriteLine("File was successully patched!"); - - return true; - } - catch (Exception ex) - { - Console.WriteLine(ex); - return false; - } - } - - public static bool Resize(string input, long newsize) - { - Stream f; - try - { - f = File.Open(input, FileMode.Open, FileAccess.ReadWrite); - } - catch (Exception ex) - { - Console.WriteLine(ex); - return false; - } - - FileTools image = new FileTools(f); - switch (image.resize(newsize)) - { - case 0: - Console.Write($"File's \"{input}\" size is already {newsize} bytes!"); - break; - case 1: - Console.Write($"File \"{input}\" was successfully resized to {newsize} bytes!"); - break; - case 2: - Console.Write($"File \"{input}\" was successfully truncated to {newsize} bytes!"); - break; - } - - return true; - } - - public static bool Copy(string input, string output, long startbyte, long length) - { - Stream infile; - try - { - infile = File.Open(input, FileMode.Open, FileAccess.Read); - } - catch (Exception ex) - { - Console.WriteLine($"File {input} can't be found."); - return true; - } - - return true; - //HANDLE hfile = CreateFileW(argv[1], GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0); - //SetFilePointer(hfile, newsize, 0, FILE_BEGIN); - //SetEndOfFile(hfile); - } - - /// - /// Generate EDC data for a Mode2/2352 image - /// - public static void SetEDCData(string filename) - { - Stream image = File.Open(filename, FileMode.Open, FileAccess.ReadWrite); - - byte[] ecc_f_lut = new byte[256]; - byte[] ecc_b_lut = new byte[256]; - int[] edc_lut = new int[256]; - - for (int a = 0; a < 256; a++) - { - int b = ((a << 1) ^ ((a & 0x80) != 0 ? 0x11D : 0)); - - ecc_f_lut[a] = (byte)b; - ecc_b_lut[a ^ b] = (byte)a; - - int edc_init = a; - for (b = 0; b < 8; b++) - { - edc_init = (int)((edc_init >> 1) ^ ((edc_init & 1) != 0 ? 0xD8018001 : 0)); - } - - edc_lut[a] = edc_init; - } - - long filesize = image.Length; - if (filesize % 2352 != 0) - { - Console.Write($"File '{filename}' is not Mode2/2352 image!"); - image.Close(); - return; - } - - long sectors = filesize / 2352; - Console.WriteLine("Converting image..."); - for (long sector = 0; sector < sectors; sector++) - { - image.Seek(sector * 2352 + 18, SeekOrigin.Begin); - - byte[] z = new byte[1]; - image.Read(z, 0, 1); - if ((z[0] >> 5 & 0x1) != 0) - { - image.Seek(-3, SeekOrigin.Current); - - byte[] buffer = new byte[2332]; - image.Read(buffer, 0, 2332); - image.Seek(0, SeekOrigin.Current); - - buffer = BitConverter.GetBytes(CalculateEDC(buffer, 0, 2332, edc_lut)); - image.Write(buffer, 0, 4); - } - } - - image.Close(); - Console.WriteLine("Done!"); - return; - } - - /// - /// Calculate CRC-32, MD5, and SHA-1 checksums - /// - public static byte Checksums(string[] args) - { - if (args.Length < 3 || args.Length > 5) - { - ChecksumsHelp(); - return 0; - } - - // Opening file - Stream file = File.OpenRead(args[2]); - Console.WriteLine($"File: {args[2]}"); - - double percents = 0; - - long filesize = file.Length; - - long start; - if (args.Length > 3) - { - start = long.Parse(args[3]); - if (start >= filesize) - { - Console.WriteLine("Error: start position can't be larger than filesize!"); - return 0; - } - - Console.WriteLine($"Start: {start}"); - } - else - { - start = 0; - } - - long block; - if (args.Length > 4) - { - block = long.Parse(args[4]); - if (block > filesize) - { - Console.WriteLine("Error: block size can't be larger than filesize!"); - return 0; - } - - if (block == 0) - { - Console.WriteLine("Error: block size can't equal with zero!"); - return 0; - } - } - else - { - block = filesize - start; - } - - if (block + start > filesize) - { - Console.WriteLine("Error: block size and start position can't be larger than file size!"); - return 0; - } - - Console.Write($"Size: {block}"); - long total = (long)Math.Ceiling((double)block / 1024); - - // checksums - byte[] Message_Digest = new byte[20]; - byte[] buffer = new byte[1024], digest = new byte[16]; - int len; - - CRC32 crc = new CRC32(); - MD5 md5 = MD5.Create(); - md5.Initialize(); - SHA1 sha1 = SHA1.Create(); - - file.Seek(start, SeekOrigin.Begin); - - for (uint i = 0; i < total; i++) - { - if (i * 100 / total > percents) - { - percents = i * 100 / total; - Console.Write($"\rCalculating checksums: {percents}%"); - } - - len = file.Read(buffer, 0, 1024); - - if (block <= len) - { - len = (int)block; - block = 0; - } - else - { - block -= 1024; - } - - md5.TransformBlock(buffer, 0, len, null, 0); - sha1.TransformBlock(buffer, 0, len, null, 0); - crc.ProcessCRC(buffer, 0, len); - } - - md5.TransformFinalBlock(digest, 0, digest.Length); - sha1.TransformFinalBlock(Message_Digest, 0, Message_Digest.Length); - - Console.Write($"\rCRC-32: {crc.m_crc32:8x} \n"); - Console.Write($"MD5: {BitConverter.ToString(md5.Hash).Replace("-", string.Empty)}"); - Console.WriteLine($"MD5: {BitConverter.ToString(md5.Hash).Replace("-", string.Empty)}"); - Console.WriteLine($"SHA-1: {BitConverter.ToString(sha1.Hash).Replace("-", string.Empty)}"); - Console.WriteLine(); - return 1; - } - - /// - /// Generate missing RIFF headers - /// - public static void Generate(string[] args) - { - Stream f = File.OpenWrite(args[2]); - byte[] riff = new byte[44]; - long size = long.Parse(args[3]); - - if (args.Length == 5) - { - if (args[4] == "-r") - { - riff[0] = 0x52; - riff[1] = 0x49; - riff[2] = 0x46; - riff[3] = 0x46; - riff[4] = (byte)((size - 8) & 0xFF); - riff[5] = (byte)((size - 8) >> 8); - riff[6] = (byte)((size - 8) >> 16); - riff[7] = (byte)((size - 8) >> 24); - riff[8] = 0x57; - riff[9] = 0x41; - riff[10] = 0x56; - riff[11] = 0x45; - riff[12] = 0x66; - riff[13] = 0x6D; - riff[14] = 0x74; - riff[15] = 0x20; - riff[16] = 0x10; - riff[17] = 0x00; - riff[18] = 0x00; - riff[19] = 0x00; - riff[20] = 0x01; - riff[21] = 0x00; - riff[22] = 0x02; - riff[23] = 0x00; - riff[24] = 0x44; - riff[25] = 0xAC; - riff[26] = 0x00; - riff[27] = 0x00; - riff[28] = 0x10; - riff[29] = 0xB1; - riff[30] = 0x02; - riff[31] = 0x00; - riff[32] = 0x04; - riff[33] = 0x00; - riff[34] = 0x10; - riff[35] = 0x00; - riff[36] = 0x64; - riff[37] = 0x61; - riff[38] = 0x74; - riff[39] = 0x61; - riff[40] = (byte)((size - 44) & 0xFF); - riff[41] = (byte)((size - 44) >> 8); - riff[42] = (byte)((size - 44) >> 16); - riff[43] = (byte)((size - 44) >> 24); - - f.Write(riff, 0, 44); - } - } - - f.Seek(size - 1, SeekOrigin.Begin); - f.WriteByte(0x00); - f.Close(); - - Console.WriteLine($"File '{args[2]}' with size {size} bytes was successfully generated!"); - return; - } - - /// - /// Create a generic M3S subchannel file for a sector count - /// - /// - public static void M3S(string filename) - { - byte[] buffer = { 0x41, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - Stream subchannel = File.Open(filename, FileMode.Create, FileAccess.Write); - Console.Write($"File: {filename}"); - - for (long sector = 13350, sector2 = sector + 150; sector < 17850; sector++, sector2++) - { - double mindbl = sector / 60 / 75; - byte min = (byte)Math.Floor(mindbl); - - double secdbl = (sector - (min * 60 * 75)) / 75; - byte sec = (byte)Math.Floor(secdbl); - - byte frame = (byte)(sector - (min * 60 * 75) - (sec * 75)); - - buffer[3] = itob(min); - buffer[4] = itob(sec); - buffer[5] = itob(frame); - - mindbl = sector2 / 60 / 75; - min = (byte)Math.Floor(mindbl); - - secdbl = (sector2 - (min * 60 * 75)) / 75; - sec = (byte)Math.Floor(secdbl); - - frame = (byte)(sector2 - (min * 60 * 75) - (sec * 75)); - - buffer[7] = itob(min); - buffer[8] = itob(sec); - buffer[9] = itob(frame); - - ushort crc = CRC16.Calculate(buffer, 0, 10); - subchannel.Write(buffer, 0, 10); - subchannel.WriteByte((byte)(crc >> 8)); - subchannel.WriteByte((byte)(crc & 0xFF)); - - for (int i = 0; i < 4; i++) - { - subchannel.WriteByte(0x00); - } - - Console.WriteLine($"Creating M3S: {100 * sector}%\r"); - } - - Console.WriteLine("Creating M3S: 100%"); - - subchannel.Close(); - - Console.WriteLine("Done!"); - return; - } - - /// - /// Matrix 3 input files into a single output - /// - public static void Matrix(string[] args) - { - Stream f1 = File.Open(args[2], FileMode.Open, FileAccess.ReadWrite); - Stream f2 = File.Open(args[3], FileMode.Open, FileAccess.ReadWrite); - Stream f3 = File.Open(args[4], FileMode.Open, FileAccess.ReadWrite); - Stream f4 = File.Open(args[5], FileMode.Create, FileAccess.Write); - - long subsize = f1.Length; - for (long i = 0; i < subsize; i++) - { - byte[] r1 = new byte[1]; - f1.Read(r1, 0, 1); - - byte[] r2 = new byte[1]; - f2.Read(r2, 0, 1); - - byte[] r3 = new byte[1]; - f3.Read(r3, 0, 1); - - if (r1 == r2) - { - f4.Write(r1, 0, 1); - } - else if (r1 == r3) - { - f4.Write(r1, 0, 1); - } - else if (r2 == r3) - { - f4.Write(r2, 0, 1); - } - else - { - Console.WriteLine($"Byte 0x{i:x} ({i}) is different!"); - Console.WriteLine($"{args[2]}: {r1[0]:2x}"); - Console.WriteLine($"{args[3]}: {r2[0]:2x}"); - Console.WriteLine($"{args[4]}: {r3[0]:2x}"); - Console.WriteLine(); - return; - } - } - - Console.WriteLine("Done!"); - return; - } - - /// - /// Split a STR-formatted image into audio and video - /// - public static void SplitStr(string[] argv) - { - Stream str = File.OpenRead(argv[2]); - long filesize = str.Length; - if (filesize % 2336 != 0) - { - Console.Write($"File '{argv[2]}' is not in STR format!"); - str.Close(); - return; - } - - long sectors = filesize / 2336; - Stream video = File.OpenWrite(argv[3]); - - sectors = filesize / 2336; - Stream audio = File.OpenWrite(argv[4]); - - for (long i = 0; i < sectors; i++) - { - str.Seek(2, SeekOrigin.Current); - - byte[] ctrlbyte = new byte[1]; - str.Read(ctrlbyte, 0, 1); - - byte[] buffer = new byte[2336]; - if ((ctrlbyte[0] >> 5 & 0x1) != 0) - { - str.Seek(-3, SeekOrigin.Current); - str.Read(buffer, 0, 2336); - audio.Write(buffer, 0, 2336); - } - else - { - str.Seek(5, SeekOrigin.Current); - str.Read(buffer, 0, 2048); - video.Write(buffer, 0, 2048); - str.Seek(280, SeekOrigin.Current); - } - } - - str.Close(); - audio.Close(); - video.Close(); - - Console.WriteLine("Done!"); - - return; - } - - /// - /// Split a STR-formatted file into BS-formatted blocks - /// - public static void StrToBs(string[] argv) - { - byte[] buffer = new byte[2016]; - int filenamesize = argv[2].Length; - string directory = $"{argv[2]}-bs"; - - Stream str = File.OpenRead(argv[2]); - long filesize = str.Length; - if (filesize % 2048 != 0) - { - Console.Write($"File '{argv[2]}; is not in STR format!"); - str.Close(); - return; - } - - /*wchar_t newfilename[2048]; - for (u8 f = 0; f < strlen(filename); f++) { - newfilename[f] = filename[f]; - *((char *)newfilename +f*2 +1) = 0; - }*/ - - Directory.CreateDirectory(directory); - - long numblocks = filesize / 2048; - Stream bs = File.OpenWrite(directory + "\\000001.bs"); - - ushort a = 1; - ushort b = 0; - ushort c = 0; - - byte[] ax = { 0, 0 }; - byte[] bx = { 0, 0 }; - byte[] cx = { 0, 0 }; - - str.Seek(32, SeekOrigin.Current); - str.Read(buffer, 0, 2016); - Console.WriteLine(directory); - - bs.Write(buffer, 0, 2016); - Console.WriteLine("2"); - Console.WriteLine($"Creating: {directory}\\000001.bs"); - - for (uint i = 1; i < numblocks; i++) - { - str.Seek(1, SeekOrigin.Current); - - byte[] byt = new byte[1]; - str.Read(byt, 0, 1); - - if (byt[0] == 0) - { - bs.Close(); - bs = File.OpenWrite(directory + $"\\{i.ToString().PadLeft(6, '0')}.bs"); - Console.WriteLine($"Creating: {directory}\\{i.ToString().PadLeft(6, '0')}.bs"); - } - - str.Seek(30, SeekOrigin.Current); - str.Read(buffer, 0, 2016); - bs.Write(buffer, 0, 2016); - } - - bs.Close(); - str.Close(); - - Console.WriteLine(); - Console.WriteLine("Done!"); - - return; - } - - /// - /// Create a generic SUB subchannel file for a sector count - /// - public static void CreateSubchannel(string filename, string strsectors) - { - long sectors = long.Parse(strsectors); - if (sectors == 0 || sectors == -1) - { - Console.WriteLine("Wrong size!"); - return; - } - - Stream subchannel = File.Open(filename, FileMode.Create, FileAccess.Write); - - Console.Write($"File: {filename}"); - Console.Write($"Size (bytes): {sectors * 96}"); - Console.Write($"Size (sectors): {sectors}"); - - byte[] buffer = new byte[10]; - buffer[0] = 0x41; - buffer[1] = 0x01; - buffer[2] = 0x01; - buffer[6] = 0x00; - - for (long sector = 0, sector2 = 150; sector < sectors; sector++, sector2++) - { - /*if (sector2 == 4350) { - buffer[1] = 0x02; - sector = 0; - }*/ - - double mindbl = sector / 60 / 75; - byte min = (byte)Math.Floor(mindbl); - - double secdbl = (sector - (min * 60 * 75)) / 75; - byte sec = (byte)Math.Floor(secdbl); - - byte frame = (byte)(sector - (min * 60 * 75) - (sec * 75)); - - buffer[3] = itob(min); - buffer[4] = itob(sec); - buffer[5] = itob(frame); - - mindbl = sector2 / 60 / 75; - min = (byte)Math.Floor(mindbl); - - secdbl = (sector2 - (min * 60 * 75)) / 75; - sec = (byte)Math.Floor(secdbl); - - frame = (byte)(sector2 - (min * 60 * 75) - (sec * 75)); - - buffer[7] = itob(min); - buffer[8] = itob(sec); - buffer[9] = itob(frame); - - ushort crc = CRC16.Calculate(buffer, 0, 10); - - for (int i = 0; i < 12; i++) - { - subchannel.WriteByte(0x00); - } - - subchannel.Write(buffer, 0, 10); - subchannel.WriteByte((byte)(crc >> 8)); - subchannel.WriteByte((byte)(crc & 0xFF)); - - for (int i = 0; i < 72; i++) - { - subchannel.WriteByte(0x00); - } - - Console.Write("Creating: %02u%%\r", (100 * sector) / sectors); - } - - subchannel.Seek(0, SeekOrigin.Begin); - for (int i = 0; i < 12; i++) - { - subchannel.WriteByte(0xFF); - } - - Console.WriteLine("Creating: 100%"); - - subchannel.Close(); - - Console.WriteLine("Done!"); - return; - } - - /// - /// Clear EDC data from a Mode2/2352 image - /// - public static void ClearEDCData(string filename) - { - byte[] zero = { 0x00, 0x00, 0x00, 0x00 }; - - Stream image = File.Open(filename, FileMode.Open, FileAccess.ReadWrite); - long filesize = image.Length; - if (filesize % 2352 != 0) - { - Console.WriteLine($"File '{filename}' is not Mode2/2352 image!"); - image.Close(); - return; - } - - Console.WriteLine("Converting image..."); - - long sectors = filesize / 2352; - for (long sector = 0; sector < sectors; sector++) - { - image.Seek(sector * 2352 + 18, SeekOrigin.Begin); - - byte[] z = new byte[1]; - image.Read(z, 0, 1); - if ((z[0] >> 5 & 0x1) != 0) - { - image.Seek(2329, SeekOrigin.Current); - image.Write(zero, 0, 4); - } - } - - image.Close(); - Console.WriteLine("Done!"); - return; - } - - #region Help - - private static void ChecksumsHelp() - { - Console.WriteLine("psxt001z.exe --checksums file [start [end]]"); - Console.WriteLine(" Calculate file's checksums (CRC-32, MD5, SHA-1)."); - Console.WriteLine(" [in] file Specifies the file, which checksums will be calculated."); - Console.WriteLine(" start Specifies start position for checksums calculation."); - Console.WriteLine(" size Specifies size of block for checksums calculation."); - Console.WriteLine(); - } - - private static void LibCryptHelp() - { - Console.WriteLine("LibCrypt detector\nUsage: psxt001z.exe --libcrypt []"); - Console.WriteLine(" Check subchannel for LibCrypt protection."); - Console.WriteLine(" [in] Specifies the subchannel file to be scanned."); - Console.WriteLine(" [out] Specifies the subchannel file in SBI format where protected\n sectors will be written."); - Console.WriteLine(); - } - - #endregion - } -} diff --git a/psxt001z/Scramble.cs b/psxt001z/Scramble.cs deleted file mode 100644 index b3194e51..00000000 --- a/psxt001z/Scramble.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Text; -using static psxt001z.Common; - -namespace psxt001z -{ - public class Scramble - { - private static readonly byte[] sync = new byte[12] { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 }; - - public int __main(string[] args) - { - if (args.Length < 2 || args.Length > 3) - { - Console.WriteLine("Syntax: px_p8 [-t] filename"); - return 1; - } - - int sectors; - if (args.Length == 2 && args[0] == "-t") - { - args[0] = args[1]; - sectors = 2352; - } - else - { - sectors = 4704; - } - - Stream sector_file; - try - { - sector_file = File.OpenRead(args[1]); - } - catch (Exception ex) - { - Console.Error.WriteLine(ex); - return 1; - } - - byte[] sector = new byte[sectors]; - if (args.Length == 2) - { - uint hex; - for (int i = 0; sector_file.Position < sector_file.Length && i < 3252; i++) - { - byte[] buf = new byte[2]; - hex = uint.Parse(Encoding.ASCII.GetString(buf), NumberStyles.HexNumber); - sector[i] = (byte)hex; - } - } - else - { - sector_file.Read(sector, 0, sectors); - } - - int offset = MemSearch(sector, sync, sectors, 12); - if (offset == -1) - { - Console.WriteLine("Error searching for sync!"); - return 1; - } - - Console.WriteLine($"MSF: {sector[offset + 12]:2x}:{sector[offset + 12 + 1]:2x}:{sector[offset + 12 + 2]:2x}"); - - int shiftRegister = 0x1; - for (int i = 0; i < 3; i++) - { - sector[offset + 12 + i] ^= (byte)(shiftRegister & 0xFF); - for (int j = 0; j < 8; j++) - { - int hibit = ((shiftRegister & 1) ^ ((shiftRegister & 2) >> 1)) << 15; - shiftRegister = (hibit | shiftRegister) >> 1; - } - } - - int start_sector = (btoi(sector[offset + 12]) * 60 + btoi(sector[offset + 13])) * 75 + btoi(sector[offset + 14]) - 150; - - Console.WriteLine($"MSF: {sector[offset + 12]:2x}:{sector[offset + 12 + 1]:2x}:{sector[offset + 12 + 2]:2x}"); - - offset -= start_sector * 2352; - - Console.WriteLine($"Combined offset: {offset} bytes / {offset / 4} samples"); - return 0; - } - - /// - /// Search for a byte array in another - /// - private int MemSearch(in byte[] buf_where, in byte[] buf_search, int buf_where_len, int buf_search_len) - { - for (int i = 0; i <= buf_where_len - buf_search_len; i++) - { - for (int j = 0; j < buf_search_len; j++) - { - if (buf_where[i + j] != buf_search[j]) - break; - - if (j + 1 == buf_search_len) - return i; - } - } - - return -1; - } - } -} diff --git a/psxt001z/Track.cs b/psxt001z/Track.cs deleted file mode 100644 index 08f32984..00000000 --- a/psxt001z/Track.cs +++ /dev/null @@ -1,310 +0,0 @@ -using System; -using System.IO; - -namespace psxt001z -{ - internal class Track - { - #region Properties - - /// - /// Original input path for the track - /// - private string InputPath { get; set; } - - /// - /// Stream representing the track data - /// - private Stream InputStream { get; set; } - - /// - /// Output for saving the track data - /// - private string OutputPath { get; set; } - - /// - /// Starting offset within the file - /// - private int Start { get; set; } - - /// - /// Size of the input file - /// - private int Size { get; set; } - - /// - /// CRC-32 of the track data to compare against - /// - private uint CRC32 { get; set; } - - /// - /// Audio data header - /// - private byte[] RiffData { get; set; } = new byte[44]; - - /// - /// True if the track is audio data - /// - private bool IsRiff { get; set; } - - /// - /// True if the file is under ~100MB - /// - private bool SmallFile { get; set; } = false; - - /// - /// True to write out the track data - /// - private bool SaveTrack { get; set; } - - /// - /// True means '+' or 'p' - /// False means '-' or 'n' - /// Null means neither - /// - private bool? Mode { get; set; } - - /// - /// Cache for small file data - /// - private byte[] FileContents { get; set; } - - /// - /// Cached file offset - /// - private int Offset { get; set; } = 0; - - /// - /// Current file offset - /// - private int Current { get; set; } = 0; - - #endregion - - #region Constructor - - public Track(string filename, int start, int size, uint crc, bool isRiff = false, bool? mode = null, string output = null) - { - InputPath = filename; - InputStream = File.OpenRead(filename); - OutputPath = output; - - Start = start; - Size = size; - CRC32 = crc; - Mode = mode; - - IsRiff = isRiff; - SmallFile = Size <= 100_000_000; - SaveTrack = output != null; - - Console.WriteLine($"File: {InputPath}\nStart: {Start}\nSize: {Size}\nCRC-32: {CRC32:8x}"); - Console.WriteLine(); - - if (IsRiff) - PopulateRiffData(); - - if (SmallFile) - CacheFileData(); - } - - #endregion - - #region Functions - - public bool FindTrack() - { - // Positive mode - if (Mode == true) - { - if (Current > 20000) - { - Mode = null; - return true; - } - - Offset = Current; - Current += 4; - return MatchesCRC(); - } - - // Negative mode - else if (Mode == false) - { - if (Current > 20000) - { - Mode = null; - return true; - } - - Offset = -Current; - Current += 4; - return MatchesCRC(); - } - - // Neutral mode - else - { - if (Current > 20000) - { - Mode = null; - return true; - } - - Offset = Current; - if (MatchesCRC()) - { - return true; - } - else - { - Offset = -Current; - Current += 4; - return MatchesCRC(); - } - } - } - - public bool MatchesCRC() - { - CRC32 calc = new CRC32(); - if (SmallFile) - { - if (IsRiff) - calc.ProcessCRC(RiffData, 0, 44); - - calc.ProcessCRC(FileContents, (int)(20000 + Offset), (int)Size); - } - else - { - InputStream.Seek(Start + Offset, SeekOrigin.Begin); - if (IsRiff) - calc.ProcessCRC(RiffData, 0, 44); - - for (long i = 0; i < Size; i++) - { - byte[] buffer = new byte[1]; - if (InputStream.Read(buffer, 0, 1) != 1) - { - buffer[0] = 0x00; - InputStream.Seek(Start + Offset + i + 1, SeekOrigin.Begin); - } - - calc.ProcessCRC(buffer, 0, 1); - } - } - - Console.Write($"Offset correction {Offset} bytes, {Offset / 4} samples, CRC-32 {calc.m_crc32:8x}"); - return (calc.m_crc32 == CRC32); - } - - public void Done() - { - if (SmallFile) - FileContents = null; - - if (Mode == null) - { - Console.WriteLine(); - Console.WriteLine("Can't find offset!"); - return; - } - - if (SaveTrack) - { - byte[] buffer = new byte[1]; - Stream f2 = File.Open(OutputPath, FileMode.Create, FileAccess.ReadWrite); - if (IsRiff) - f2.Write(RiffData, 0, 44); - - InputStream.Seek(Start + Offset, SeekOrigin.Begin); - for (long i = 0; i < Size; i++) - { - if (InputStream.Read(buffer, 0, 1) != 1) - { - buffer[0] = 0x00; - InputStream.Seek(Start + Offset + i + 1, SeekOrigin.Begin); - } - - f2.Write(buffer, 0, 1); - } - } - - Console.WriteLine(); - Console.Write("DONE!"); - Console.WriteLine(); - Console.Write($"Offset correction: {Offset} bytes / {Offset / 4} samples"); - } - - #endregion - - #region Utilities - - // TODO: Figure out what this actually does - private void CacheFileData() - { - FileContents = new byte[Size + 40000]; - InputStream.Seek(Start - 20000, SeekOrigin.Begin); - - for (int i = 0; i < Size + 40000; i++) - { - if (Start + i <= 20000) - InputStream.Seek(Start + i - 20000, SeekOrigin.Begin); - - if (InputStream.Read(new byte[1], 0, 1) != 1) - FileContents[i] = 0x00; - } - } - - private void PopulateRiffData() - { - RiffData[0] = 0x52; - RiffData[1] = 0x49; - RiffData[2] = 0x46; - RiffData[3] = 0x46; - - byte[] temp = BitConverter.GetBytes(Size - 8); - Array.Copy(temp, 0, RiffData, 4, 4); - - RiffData[8] = 0x57; - RiffData[9] = 0x41; - RiffData[10] = 0x56; - RiffData[11] = 0x45; - RiffData[12] = 0x66; - RiffData[13] = 0x6D; - RiffData[14] = 0x74; - RiffData[15] = 0x20; - RiffData[16] = 0x10; - RiffData[17] = 0x00; - RiffData[18] = 0x00; - RiffData[19] = 0x00; - RiffData[20] = 0x01; - RiffData[21] = 0x00; - RiffData[22] = 0x02; - RiffData[23] = 0x00; - RiffData[24] = 0x44; - RiffData[25] = 0xAC; - RiffData[26] = 0x00; - RiffData[27] = 0x00; - RiffData[28] = 0x10; - RiffData[29] = 0xB1; - RiffData[30] = 0x02; - RiffData[31] = 0x00; - RiffData[32] = 0x04; - RiffData[33] = 0x00; - RiffData[34] = 0x10; - RiffData[35] = 0x00; - RiffData[36] = 0x64; - RiffData[37] = 0x61; - RiffData[38] = 0x74; - RiffData[39] = 0x61; - - temp = BitConverter.GetBytes(Size - 44); - Array.Copy(temp, 0, RiffData, 40, 4); - - Size -= 44; - } - - #endregion - } -} diff --git a/psxt001z/psxt001z.csproj b/psxt001z/psxt001z.csproj deleted file mode 100644 index cb862821..00000000 --- a/psxt001z/psxt001z.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - - net48;net6.0;net7.0 - win-x86;win-x64;linux-x64;osx-x64 - 0.21-beta1 - true - - - Matt Nadareski;Dremora - BurnOutSharp - Copyright (c)2013 Dremora, Copyright (c)2018-2023 Matt Nadareski - https://github.com/SabreTools/ - https://github.com/mnadareski/BurnOutSharp - git - MIT - true - true - - -