/// <summary> /// Attempt to extract a stream from an archive /// </summary> /// <param name="entryName">Name of the entry to be extracted</param> /// <param name="realEntry">Output representing the entry name that was found</param> /// <returns>MemoryStream representing the entry, null on error</returns> public override (MemoryStream, string) CopyToStream(string entryName) { MemoryStream ms = new MemoryStream(); string realEntry = null; try { SharpCompress.Archives.Rar.RarArchive ra = SharpCompress.Archives.Rar.RarArchive.Open(this.Filename, new ReaderOptions { LeaveStreamOpen = false, }); foreach (RarArchiveEntry entry in ra.Entries) { if (entry != null && !entry.IsDirectory && entry.Key.Contains(entryName)) { // Write the file out realEntry = entry.Key; entry.WriteTo(ms); } } ra.Dispose(); } catch (Exception ex) { Globals.Logger.Error(ex.ToString()); ms = null; realEntry = null; } return(ms, realEntry); }
/// <summary> /// Generate a list of DatItem objects from the header values in an archive /// </summary> /// <param name="omitFromScan">Hash representing the hashes that should be skipped</param> /// <param name="date">True if entry dates should be included, false otherwise (default)</param> /// <returns>List of DatItem objects representing the found data</returns> /// <remarks>TODO: All instances of Hash.DeepHashes should be made into 0x0 eventually</remarks> public override List <BaseFile> GetChildren(Hash omitFromScan = Hash.DeepHashes, bool date = false) { List <BaseFile> found = new List <BaseFile>(); string gamename = Path.GetFileNameWithoutExtension(this.Filename); try { SharpCompress.Archives.Rar.RarArchive ra = SharpCompress.Archives.Rar.RarArchive.Open(Utilities.TryOpenRead(this.Filename)); foreach (RarArchiveEntry entry in ra.Entries.Where(e => e != null && !e.IsDirectory)) { // If secure hashes are disabled, do a quickscan if (omitFromScan == Hash.SecureHashes) { found.Add(new BaseFile { Filename = entry.Key, Size = entry.Size, CRC = BitConverter.GetBytes(entry.Crc), Date = (date && entry.LastModifiedTime != null ? entry.LastModifiedTime?.ToString("yyyy/MM/dd hh:mm:ss") : null), Parent = gamename, }); } // Otherwise, use the stream directly else { Stream entryStream = entry.OpenEntryStream(); BaseFile rarEntryRom = Utilities.GetStreamInfo(entryStream, entry.Size, omitFromScan: omitFromScan); rarEntryRom.Filename = entry.Key; rarEntryRom.Parent = gamename; rarEntryRom.Date = entry.LastModifiedTime?.ToString("yyyy/MM/dd hh:mm:ss"); found.Add(rarEntryRom); entryStream.Dispose(); } } // Dispose of the archive ra.Dispose(); } catch (Exception ex) { Globals.Logger.Error(ex.ToString()); return(null); } return(found); }
/// <summary> /// Generate a list of DatItem objects from the header values in an archive /// </summary> /// <returns>List of DatItem objects representing the found data</returns> public override List <BaseFile> GetChildren() { List <BaseFile> found = new List <BaseFile>(); string gamename = Path.GetFileNameWithoutExtension(this.Filename); try { SharpCompress.Archives.Rar.RarArchive ra = SharpCompress.Archives.Rar.RarArchive.Open(FileExtensions.TryOpenRead(this.Filename)); foreach (RarArchiveEntry entry in ra.Entries.Where(e => e != null && !e.IsDirectory)) { // Create a blank item for the entry BaseFile rarEntryRom = new BaseFile(); // Perform a quickscan, if flagged to if (this.AvailableHashes == Hash.CRC) { rarEntryRom.Size = entry.Size; rarEntryRom.CRC = BitConverter.GetBytes(entry.Crc); } // Otherwise, use the stream directly else { using (Stream entryStream = entry.OpenEntryStream()) { rarEntryRom = entryStream.GetInfo(size: entry.Size, hashes: this.AvailableHashes); } } // Fill in comon details and add to the list rarEntryRom.Filename = entry.Key; rarEntryRom.Parent = gamename; rarEntryRom.Date = entry.LastModifiedTime?.ToString("yyyy/MM/dd hh:mm:ss"); found.Add(rarEntryRom); } // Dispose of the archive ra.Dispose(); } catch (Exception ex) { logger.Error(ex); return(null); } return(found); }
/// <summary> /// Attempt to extract a file as an archive /// </summary> /// <param name="outDir">Output directory for archive extraction</param> /// <returns>True if the extraction was a success, false otherwise</returns> public override bool CopyAll(string outDir) { bool encounteredErrors = true; try { // Create the temp directory Directory.CreateDirectory(outDir); // Extract all files to the temp directory SharpCompress.Archives.Rar.RarArchive ra = SharpCompress.Archives.Rar.RarArchive.Open(this.Filename); foreach (RarArchiveEntry entry in ra.Entries) { entry.WriteToDirectory(outDir, new SharpCompress.Common.ExtractionOptions { PreserveFileTime = true, ExtractFullPath = true, Overwrite = true }); } encounteredErrors = false; ra.Dispose(); } catch (EndOfStreamException ex) { // Catch this but don't count it as an error because SharpCompress is unsafe logger.Verbose(ex); } catch (InvalidOperationException ex) { logger.Warning(ex); encounteredErrors = true; } catch (Exception ex) { logger.Error(ex); encounteredErrors = true; } return(encounteredErrors); }