/// <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() { if (_children == null || _children.Count == 0) { _children = new List <BaseFile>(); string gamename = Path.GetFileNameWithoutExtension(this.Filename); BaseFile possibleTgz = GetTorrentGZFileInfo(); // If it was, then add it to the outputs and continue if (possibleTgz != null && possibleTgz.Filename != null) { _children.Add(possibleTgz); } else { try { // Create a blank item for the entry BaseFile gzipEntryRom = new BaseFile(); // Perform a quickscan, if flagged to if (this.AvailableHashes == Hash.CRC) { gzipEntryRom.Filename = gamename; using (BinaryReader br = new BinaryReader(FileExtensions.TryOpenRead(this.Filename))) { br.BaseStream.Seek(-8, SeekOrigin.End); gzipEntryRom.CRC = br.ReadBytesBigEndian(4); gzipEntryRom.Size = br.ReadInt32BigEndian(); } } // Otherwise, use the stream directly else { var gz = new gZip(); ZipReturn ret = gz.ZipFileOpen(this.Filename); ret = gz.ZipFileOpenReadStream(0, out Stream gzstream, out ulong streamSize); gzipEntryRom = gzstream.GetInfo(hashes: this.AvailableHashes); gzipEntryRom.Filename = gz.Filename(0); gzipEntryRom.Parent = gamename; gzipEntryRom.Date = (gz.TimeStamp > 0 ? gz.TimeStamp.ToString() : null); gzstream.Dispose(); } // Fill in comon details and add to the list gzipEntryRom.Parent = gamename; _children.Add(gzipEntryRom); } catch (Exception ex) { logger.Error(ex); return(null); } } } return(_children); }
/// <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; try { // Decompress the _filename stream realEntry = Path.GetFileNameWithoutExtension(this.Filename); var gz = new gZip(); ZipReturn ret = gz.ZipFileOpen(this.Filename); ret = gz.ZipFileOpenReadStream(0, out Stream gzstream, out ulong streamSize); // Write the file out byte[] gbuffer = new byte[_bufferSize]; int glen; while ((glen = gzstream.Read(gbuffer, 0, _bufferSize)) > 0) { ms.Write(gbuffer, 0, glen); ms.Flush(); } // Dispose of the streams gzstream.Dispose(); } catch (Exception ex) { logger.Error(ex); ms = null; realEntry = null; } return(ms, realEntry); }
/// <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); // Decompress the _filename stream FileStream outstream = FileExtensions.TryCreate(Path.Combine(outDir, Path.GetFileNameWithoutExtension(this.Filename))); var gz = new gZip(); ZipReturn ret = gz.ZipFileOpen(this.Filename); ret = gz.ZipFileOpenReadStream(0, out Stream gzstream, out ulong streamSize); gzstream.CopyTo(outstream); // Dispose of the streams outstream.Dispose(); ret = gz.ZipFileCloseReadStream(); gz.ZipFileClose(); encounteredErrors = false; } 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); }
private static void ScanRomRoot(string directory) { _bgw.ReportProgress(0, new bgwText("Scanning Dir : " + directory)); DirectoryInfo di = new DirectoryInfo(directory); FileInfo[] fi = di.GetFiles(); _bgw.ReportProgress(0, new bgwRange2Visible(true)); _bgw.ReportProgress(0, new bgwSetRange2(fi.Count())); for (int j = 0; j < fi.Count(); j++) { if (_bgw.CancellationPending) { return; } FileInfo f = fi[j]; _bgw.ReportProgress(0, new bgwValue2(j)); _bgw.ReportProgress(0, new bgwText2(f.Name)); string ext = Path.GetExtension(f.Name); if (ext.ToLower() == ".gz") { gZip gZipTest = new gZip(); ZipReturn errorcode = gZipTest.ZipFileOpen(f.FullName); if (errorcode != ZipReturn.ZipGood) { _bgw.ReportProgress(0, new bgwShowError(f.FullName, "gz File corrupt")); if (!Directory.Exists("corrupt")) { Directory.CreateDirectory("corrupt"); } File.Move(f.FullName, Path.Combine("corrupt", f.Name)); continue; } RvFile tFile = RvFile.fromGZip(f.FullName, gZipTest.ExtraData, gZipTest.CompressedSize); gZipTest.ZipFileClose(); FindStatus res = fileneededTest(tFile); if (res != FindStatus.FoundFileInArchive) { if (deep) { gZipTest = new gZip(); try { errorcode = gZipTest.ZipFileOpen(f.FullName); if (errorcode == ZipReturn.ZipGood) { FileScan fs = new FileScan(); List <FileScan.FileResults> gRes = fs.Scan(gZipTest, true, true); errorcode = gRes[0].FileStatus; gZipTest.ZipFileClose(); } } catch { gZipTest.ZipFileClose(); _bgw.ReportProgress(0, new bgwShowError(f.FullName, "gz Crashed Compression")); if (!Directory.Exists("corrupt")) { Directory.CreateDirectory("corrupt"); } File.Move(f.FullName, Path.Combine("corrupt", f.Name)); continue; } if (errorcode != ZipReturn.ZipGood) { _bgw.ReportProgress(0, new bgwShowError(f.FullName, "gz File corrupt")); if (!Directory.Exists("corrupt")) { Directory.CreateDirectory("corrupt"); } File.Move(f.FullName, Path.Combine("corrupt", f.Name)); continue; } } tFile.DBWrite(); } } if (_bgw.CancellationPending) { return; } } DirectoryInfo[] childdi = di.GetDirectories(); foreach (DirectoryInfo d in childdi) { if (_bgw.CancellationPending) { return; } ScanRomRoot(d.FullName); } }
private static bool ScanAFile(string realFilename, Stream memzip, string displayFilename) { Compress.File.File fStream = new Compress.File.File(); if (string.IsNullOrEmpty(realFilename) && memzip != null) { fStream.ZipFileOpen(memzip); } else { ZipReturn zRet = fStream.ZipFileOpen(realFilename, -1, true); if (zRet != ZipReturn.ZipGood) { return(false); } } bool ret = false; FileScan fScan = new FileScan(); List <FileScan.FileResults> resScan = fScan.Scan(fStream, true, true); HeaderFileType foundFileType = resScan[0].HeaderFileType; if (foundFileType == HeaderFileType.CHD) { // read altheader values from CHD file. } RvFile tFile = new RvFile { Size = resScan[0].Size, CRC = resScan[0].CRC, MD5 = resScan[0].MD5, SHA1 = resScan[0].SHA1, AltType = resScan[0].HeaderFileType, AltSize = resScan[0].AltSize, AltCRC = resScan[0].AltCRC, AltMD5 = resScan[0].AltMD5, AltSHA1 = resScan[0].AltSHA1 }; // test if needed. FindStatus res = RvRomFileMatchup.FileneededTest(tFile); if (res == FindStatus.FileNeededInArchive) { _bgw?.ReportProgress(0, new bgwShowError(displayFilename, "found")); Debug.WriteLine("Reading file as " + tFile.SHA1); string outfile = RomRootDir.Getfilename(tFile.SHA1); gZip gz1 = new gZip(); gz1.ZipFileCreate(outfile); gz1.ExtraData = tFile.SetExtraData(); gz1.ZipFileOpenWriteStream(false, true, "", tFile.Size, 8, out Stream write, null); fStream.ZipFileOpenReadStream(0, out Stream s, out ulong _); // do copy StreamCopier.StreamCopy(s, write, tFile.Size); fStream.ZipFileCloseReadStream(); fStream.ZipFileClose(); gz1.ZipFileCloseWriteStream(tFile.CRC); tFile.CompressedSize = gz1.CompressedSize; gz1.ZipFileClose(); tFile.DBWrite(); ret = true; } else if (res == FindStatus.FoundFileInArchive) { ret = true; } fStream.ZipFileClose(); if (foundFileType == HeaderFileType.ZIP || foundFileType == HeaderFileType.SevenZip || foundFileType == HeaderFileType.GZ) { ICompress fz; switch (foundFileType) { case HeaderFileType.SevenZip: fz = new SevenZ(); break; case HeaderFileType.GZ: fz = new gZip(); break; //case HeaderFileType.ZIP: default: fz = new Zip(); break; } ZipReturn zp; if (string.IsNullOrEmpty(realFilename) && memzip != null) { memzip.Position = 0; zp = fz.ZipFileOpen(memzip); } else { zp = fz.ZipFileOpen(realFilename); } if (zp == ZipReturn.ZipGood) { bool allZipFound = true; for (int i = 0; i < fz.LocalFilesCount(); i++) { LocalFile lf = fz.GetLocalFile(i); ZipReturn openFile = fz.ZipFileOpenReadStream(i, out Stream stream, out ulong streamSize); if (streamSize <= _inMemorySize) { if (openFile == ZipReturn.ZipTryingToAccessADirectory) { continue; } byte[] tmpFile = new byte[streamSize]; stream.Read(tmpFile, 0, (int)streamSize); using (Stream memStream = new MemoryStream(tmpFile, false)) { allZipFound &= ScanAFile(null, memStream, lf.Filename); } } else { string file = Path.Combine(_tmpDir, Guid.NewGuid().ToString()); FileStream.OpenFileWrite(file, out Stream fs); ulong sizetogo = streamSize; while (sizetogo > 0) { int sizenow = sizetogo > (ulong)Buffersize ? Buffersize : (int)sizetogo; stream.Read(Buffer, 0, sizenow); fs.Write(Buffer, 0, sizenow); sizetogo -= (ulong)sizenow; } fs.Close(); allZipFound &= ScanAFile(file, null, lf.Filename); File.Delete(file); } //fz.ZipFileCloseReadStream(); } fz.ZipFileClose(); ret |= allZipFound; } else { ret = false; } } return(ret); }
public static void extract(string dirName, string outPath) { if (CommandFindRomsInGame == null) { CommandFindRomsInGame = new SQLiteCommand( @"SELECT ROM.RomId, ROM.name, FILES.size, FILES.compressedsize, FILES.crc, FILES.sha1 FROM ROM,FILES WHERE ROM.FileId=FILES.FileId AND ROM.GameId=@GameId AND ROM.PutInZip ORDER BY ROM.RomId", DBSqlite.db.Connection); } CommandFindRomsInGame.Parameters.Add(new SQLiteParameter("GameId")); Debug.WriteLine(dirName); SQLiteCommand getfiles = new SQLiteCommand(@"SELECT dir.FullName,GameId,game.Name FROM dir,dat,game where dat.dirid=dir.dirid and game.datid=dat.datid and dir.fullname like '" + dirName + "%'", DBSqlite.db.Connection); DbDataReader reader = getfiles.ExecuteReader(); while (reader.Read()) { string outputFile = reader["fullname"].ToString() + reader["Name"].ToString() + ".zip"; outputFile = outputFile.Substring(dirName.Length); outputFile = Path.Combine(outPath, outputFile).Replace(@"/", @"\"); Debug.WriteLine(outputFile); int GameId = Convert.ToInt32(reader["GameId"]); string GameName = reader["name"].ToString(); Debug.WriteLine("Game " + GameId + " Name: " + GameName); Zip memZip = new Zip(); memZip.ZipCreateFake(); ulong fileOffset = 0; Stream zipFs = null; int romCount = 0; using (DbDataReader drRom = ZipSetGetRomsInGame(GameId)) { while (drRom.Read()) { int RomId = Convert.ToInt32(drRom["RomId"]); string RomName = drRom["name"].ToString(); ulong size = Convert.ToUInt64(drRom["size"]); ulong compressedSize = Convert.ToUInt64(drRom["compressedsize"]); byte[] CRC = VarFix.CleanMD5SHA1(drRom["crc"].ToString(), 8); byte[] sha1 = VarFix.CleanMD5SHA1(drRom["sha1"].ToString(), 32); Debug.WriteLine(" Rom " + RomId + " Name: " + RomName + " Size: " + size + " Compressed: " + compressedSize + " CRC: " + VarFix.ToString(CRC)); byte[] localHeader; memZip.ZipFileAddFake(RomName, fileOffset, size, compressedSize, CRC, out localHeader); //ZipSetLocalFileHeader(RomId, localHeader, fileOffset); if (romCount == 0) { CompressUtils.CreateDirForFile(outputFile); int errorCode = FileStream.OpenFileWrite(outputFile, out zipFs); } zipFs.Write(localHeader, 0, localHeader.Length); gZip GZip = new gZip(); string strFilename = RomRootDir.Getfilename(sha1); GZip.ZipFileOpen(strFilename, -1, true); GZip.ZipFileOpenReadStream(0, true, out Stream oStr, out ulong _); StreamCopier.StreamCopy(oStr, zipFs, compressedSize); GZip.ZipFileCloseReadStream(); GZip.ZipFileClose(); fileOffset += (ulong)localHeader.Length + compressedSize; zipFs.Position = (long)fileOffset; romCount += 1; } } memZip.ZipFileCloseFake(fileOffset, out byte[] centeralDir); if (romCount > 0) { zipFs.Write(centeralDir, 0, centeralDir.Length); zipFs.Flush(); zipFs.Close(); zipFs.Dispose(); } } }
private static bool ScanAFile(string realFilename, Stream memzip, string displayFilename) { Stream fStream; if (string.IsNullOrEmpty(realFilename) && memzip != null) { fStream = memzip; } else { int errorCode = FileStream.OpenFileRead(realFilename, out fStream); if (errorCode != 0) { return(false); } } bool ret = false; HeaderFileType foundFileType = FileHeaderReader.FileHeaderReader.GetType(fStream, out int offset); fStream.Position = 0; RvFile tFile = UnCompFiles.CheckSumRead(fStream, offset); tFile.AltType = foundFileType; if (foundFileType == HeaderFileType.CHD) { // read altheader values from CHD file. } // test if needed. FindStatus res = RvRomFileMatchup.FileneededTest(tFile); if (res == FindStatus.FileNeededInArchive) { _bgw?.ReportProgress(0, new bgwShowError(displayFilename, "found")); Debug.WriteLine("Reading file as " + tFile.SHA1); GZip gz = new GZip(tFile); string outfile = RomRootDir.Getfilename(tFile.SHA1); fStream.Position = 0; gz.WriteGZip(outfile, fStream, false); tFile.CompressedSize = gz.compressedSize; tFile.DBWrite(); ret = true; } else if (res == FindStatus.FoundFileInArchive) { ret = true; } if (foundFileType == HeaderFileType.ZIP || foundFileType == HeaderFileType.SevenZip || foundFileType == HeaderFileType.GZ) { ICompress fz; switch (foundFileType) { case HeaderFileType.SevenZip: fz = new SevenZ(); break; case HeaderFileType.GZ: fz = new gZip(); break; //case HeaderFileType.ZIP: default: fz = new Zip(); break; } fStream.Position = 0; ZipReturn zp; if (string.IsNullOrEmpty(realFilename) && memzip != null) { zp = fz.ZipFileOpen(memzip); } else { zp = fz.ZipFileOpen(realFilename); } if (zp == ZipReturn.ZipGood) { bool allZipFound = true; for (int i = 0; i < fz.LocalFilesCount(); i++) { ZipReturn openFile = fz.ZipFileOpenReadStream(i, out Stream stream, out ulong streamSize); if (streamSize <= _inMemorySize) { if (openFile == ZipReturn.ZipTryingToAccessADirectory) { continue; } byte[] tmpFile = new byte[streamSize]; stream.Read(tmpFile, 0, (int)streamSize); using (Stream memStream = new MemoryStream(tmpFile, false)) { allZipFound &= ScanAFile(null, memStream, fz.Filename(i)); } } else { string file = Path.Combine(_tmpDir, Guid.NewGuid().ToString()); FileStream.OpenFileWrite(file, out Stream fs); ulong sizetogo = streamSize; while (sizetogo > 0) { int sizenow = sizetogo > (ulong)Buffersize ? Buffersize : (int)sizetogo; stream.Read(Buffer, 0, sizenow); fs.Write(Buffer, 0, sizenow); sizetogo -= (ulong)sizenow; } fs.Close(); allZipFound &= ScanAFile(file, null, fz.Filename(i)); File.Delete(file); } //fz.ZipFileCloseReadStream(); } fz.ZipFileClose(); ret |= allZipFound; } else { ret = false; } } if (!string.IsNullOrEmpty(realFilename) || memzip == null) { fStream.Close(); fStream.Dispose(); } return(ret); }