////this file is part of BurnOut ////Copyright (C)2005-2010 Gernot Knippen ////Ported code with augments Copyright (C)2018 Matt Nadareski //// ////This program is free software; you can redistribute it and/or ////modify it under the terms of the GNU General Public License ////as published by the Free Software Foundation; either ////version 2 of the License, or (at your option) any later version. //// ////This program is distributed in the hope that it will be useful, ////but WITHOUT ANY WARRANTY; without even the implied warranty of ////MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ////GNU General Public License for more details. //// ////You can get a copy of the GNU General Public License ////by writing to the Free Software ////Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //using System; //using System.Collections.Generic; //using System.IO; //using System.Linq; //using System.Threading; //using BurnOutSharp.FileType; //using BurnOutSharp.ProtectionType; //namespace BurnOutSharp //{ // public static class ProtectionFind // { // /// // /// Progress indicator // /// // private static IProgress FileProgress = null; // /// // /// Scan a path to find any known copy protection(s) // /// // /// Path to scan for protection(s) // /// True to include scanned copy protection position, false otherwise (default) // /// Optional progress indicator that will return a float in the range from 0 to 1 // /// Dictionary of filename to protection mappings, if possible // public static Dictionary Scan(string path, bool includePosition = false, IProgress progress = null) // { // // Set the progress indicator, if it's not set already // if (FileProgress == null) // FileProgress = progress; // // Initialize the protections dictionary // var protections = new Dictionary(); // // Checkpoint // FileProgress?.Report(new FileProtection(null, 0, null)); // // Temp variables for reporting // string tempFilePath = Path.GetTempPath(); // string tempFilePathWithGuid = Path.Combine(tempFilePath, Guid.NewGuid().ToString()); // // If we have a file // if (File.Exists(path)) // { // // Get the reportable file name // string reportableFileName = path; // if (reportableFileName.StartsWith(tempFilePath)) // reportableFileName = reportableFileName.Substring(tempFilePathWithGuid.Length); // // Checkpoint // FileProgress?.Report(new FileProtection(reportableFileName, 1, "Checking file" + (path != reportableFileName ? " from archive" : string.Empty))); // // Try using just the file first to get protection info // string fileProtection = ScanPath(path, false); // if (!string.IsNullOrWhiteSpace(fileProtection)) // protections[path] = fileProtection; // // Now check to see if the file contains any additional information // string contentProtection = ScanContent(path, includePosition)?.Replace("" + (char)0x00, ""); // if (!string.IsNullOrWhiteSpace(contentProtection)) // { // if (protections.ContainsKey(path)) // protections[path] += $", {contentProtection}"; // else // protections[path] = contentProtection; // } // // Checkpoint // protections.TryGetValue(path, out string fullProtection); // FileProgress?.Report(new FileProtection(reportableFileName, 1, fullProtection ?? string.Empty)); // } // // If we have a directory // else if (Directory.Exists(path)) // { // // Get the lists of files to be used // var files = Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories); // // Try using just the path first to get protection info // string pathProtection = ScanPath(path, true); // if (!string.IsNullOrWhiteSpace(pathProtection)) // protections[path] = pathProtection; // // Loop through all files and scan their contents // for (int i = 0; i < files.Count(); i++) // { // // Get the current file // string file = files.ElementAt(i); // // Get the reportable file name // string reportableFileName = file; // if (reportableFileName.StartsWith(tempFilePath)) // reportableFileName = reportableFileName.Substring(tempFilePathWithGuid.Length); // // Checkpoint // FileProgress?.Report(new FileProtection(reportableFileName, i / (float)files.Count(), "Checking file" + (file != reportableFileName ? " from archive" : string.Empty))); // // Try using just the file first to get protection info // string fileProtection = ScanPath(file, false); // if (!string.IsNullOrWhiteSpace(fileProtection)) // protections[file] = fileProtection; // // Now check to see if the file contains any additional information // string contentProtection = ScanContent(file, includePosition)?.Replace("" + (char)0x00, ""); // if (!string.IsNullOrWhiteSpace(contentProtection)) // { // if (protections.ContainsKey(file)) // protections[file] += $", {contentProtection}"; // else // protections[file] = contentProtection; // } // // Checkpoint // protections.TryGetValue(file, out string fullProtection); // FileProgress?.Report(new FileProtection(reportableFileName, (i + 1) / (float)files.Count(), fullProtection ?? string.Empty)); // } // } // // If we have an empty list, we need to take care of that // if (protections.Count(p => !string.IsNullOrWhiteSpace(p.Value)) == 0) // { // protections = new Dictionary(); // } // return protections; // } // /// // /// Scan a path for indications of copy protection // /// // /// Path to scan file and folder names // /// True if the path is a directory, false otherwise // /// // public static string ScanPath(string path, bool isDirectory) // { // List protections = new List(); // string protection; // // If we have a directory, get the files in the directory for searching // IEnumerable files = null; // if (isDirectory) // files = Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories); // // AACS // protection = AACS.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // Alpha-DVD // protection = AlphaDVD.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // Bitpool // protection = Bitpool.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // ByteShield // protection = ByteShield.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // Cactus Data Shield // protection = CactusDataShield.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // CD-Cops // protection = CDCops.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // CD-Lock // protection = CDLock.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // CD-Protector // protection = CDProtector.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // CD-X // protection = CDX.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // /* // // CopyKiller // protection = CopyKiller.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // */ // // DiscGuard // protection = DiscGuard.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // DVD Crypt // protection = DVDCrypt.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // DVD-Movie-PROTECT // protection = DVDMoviePROTECT.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // FreeLock // protection = FreeLock.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // Games for Windows - Live // protection = GFWL.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // Hexalock AutoLock // protection = HexalockAutoLock.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // Impulse Reactor // protection = ImpulseReactor.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // IndyVCD // protection = IndyVCD.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // Key2Audio XS // protection = Key2AudioXS.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // LaserLock // protection = LaserLock.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // MediaCloQ // protection = MediaCloQ.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // MediaMax CD3 // protection = MediaMaxCD3.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // Origin // protection = Origin.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // Protect DVD-Video // protection = ProtectDVDVideo.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // SafeCast // protection = SafeCast.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // SafeDisc // protection = SafeDisc.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // SafeDisc Lite // protection = SafeDiscLite.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // SafeLock // protection = SafeLock.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // SecuROM // protection = SecuROM.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // SmartE // protection = SmartE.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // SoftLock // protection = SoftLock.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // SolidShield // protection = SolidShield.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // StarForce // protection = StarForce.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // Steam // protection = Steam.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // TAGES // protection = Tages.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // TZCopyProtector // protection = TZCopyProtector.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // Uplay // protection = Uplay.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // VOB ProtectCD/DVD // protection = VOBProtectCDDVD.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // Winlock // protection = Winlock.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // WTM CD Protect // protection = WTMCDProtect.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // XCP // protection = XCP.CheckPath(path, files, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // Zzxzz // protection = Zzxzz.CheckPath(path, isDirectory); // if (!string.IsNullOrWhiteSpace(protection)) // protections.Add(protection); // // Now combine any found protections, or null if empty // if (protections.Count() == 0) // return null; // else // return string.Join(", ", protections); // } // /// // /// Scan an individual file for copy protection // /// // /// File path for scanning // /// True to include scanned copy protection position, false otherwise (default) // public static string ScanContent(string file, bool includePosition = false) // { // try // { // using (FileStream fs = File.OpenRead(file)) // { // return ScanContent(fs, file, includePosition); // } // } // catch // { // return null; // } // } // /// // /// Scan an individual stream for copy protection // /// // /// Generic stream to scan // /// File path to be used for name checks (optional) // /// True to include scanned copy protection position, false otherwise (default) // public static string ScanContent(Stream stream, string file = null, bool includePosition = false) // { // // Get the extension for certain checks // string extension = Path.GetExtension(file).ToLower().TrimStart('.'); // // Assume the first part of the stream is the start of a file // byte[] magic = new byte[16]; // try // { // stream.Read(magic, 0, 16); // stream.Seek(-16, SeekOrigin.Current); // } // catch // { // // We don't care what the issue was, we can't read or seek the file // return null; // } // // Files can be protected in multiple ways // List protections = new List(); // #region Non-Archive Formats // // Executable // if (Executable.ShouldScan(magic)) // protections.AddRange(Executable.Scan(stream, file, includePosition)); // // Text-based files // if (Textfile.ShouldScan(magic, extension)) // protections.AddRange(Textfile.Scan(stream, includePosition)); // #endregion // #region Archive Formats // // 7-Zip archive // if (SevenZip.ShouldScan(magic)) // protections.AddRange(SevenZip.Scan(stream, includePosition)); // // BFPK archive // if (BFPK.ShouldScan(magic)) // protections.AddRange(BFPK.Scan(stream, includePosition)); // // BZip2 // if (BZip2.ShouldScan(magic)) // protections.AddRange(BZip2.Scan(stream, includePosition)); // // GZIP // if (GZIP.ShouldScan(magic)) // protections.AddRange(GZIP.Scan(stream, includePosition)); // // InstallShield Cabinet // if (file != null && InstallShieldCAB.ShouldScan(magic)) // protections.AddRange(InstallShieldCAB.Scan(file, includePosition)); // // Microsoft Cabinet // if (file != null && MicrosoftCAB.ShouldScan(magic)) // protections.AddRange(MicrosoftCAB.Scan(file, includePosition)); // // MSI // if (file != null && MSI.ShouldScan(magic)) // protections.AddRange(MSI.Scan(file, includePosition)); // // MPQ archive // if (file != null && MPQ.ShouldScan(magic)) // protections.AddRange(MPQ.Scan(file, includePosition)); // // PKZIP archive (and derivatives) // if (PKZIP.ShouldScan(magic)) // protections.AddRange(PKZIP.Scan(stream, includePosition)); // // RAR archive // if (RAR.ShouldScan(magic)) // protections.AddRange(RAR.Scan(stream, includePosition)); // // Tape Archive // if (TapeArchive.ShouldScan(magic)) // protections.AddRange(TapeArchive.Scan(stream, includePosition)); // // Valve archive formats // if (file != null && Valve.ShouldScan(magic)) // protections.AddRange(Valve.Scan(file, includePosition)); // // XZ // if (XZ.ShouldScan(magic)) // protections.AddRange(XZ.Scan(stream, includePosition)); // #endregion // // Return blank if nothing found, or comma-separated list of protections // if (protections.Count() == 0) // return string.Empty; // else // return string.Join(", ", protections); // } // /// // /// Scan a disc sector by sector for protection // /// // /// // /// https://stackoverflow.com/questions/8819188/c-sharp-classes-to-undelete-files/8820157#8820157 // /// TODO: Finish implementation // /// // private static string ScanSectors(char driveLetter, int sectorsize) // { // string fsName = Utilities.GetFileSystemName(driveLetter); // // Gets a handle to the physical disk // IntPtr hDisk = Utilities.CreateFile($"\\\\.\\{driveLetter}:", // FileAccess.Read, // FileShare.ReadWrite, // IntPtr.Zero, // FileMode.Open, // 0, // IntPtr.Zero); // // If we have a good pointer // if (hDisk.ToInt32() != -1) // { // // Setup vars // byte[] buffer = new byte[sectorsize]; // IntPtr pt = IntPtr.Zero; // NativeOverlapped no = new NativeOverlapped(); // // Set initial offset // Utilities.SetFilePointerEx( // hDisk, // 0, // ref pt, // Utilities.FileBegin); // // Read a whole sector // while (true) // { // buffer = new byte[sectorsize]; // Utilities.ReadFileEx( // hDisk, // buffer, // (uint)sectorsize, // ref no, // null); // Utilities.SetFilePointerEx( // hDisk, // sectorsize, // ref pt, // Utilities.FileCurrent); // } // } // Utilities.CloseHandle(hDisk); // return null; // } // } //}