private static void CheckADir(RvDir dbDir, bool report) { if (_cacheSaveTimer.Elapsed.TotalMinutes > Settings.CacheSaveTimePeriod) { _bgw.ReportProgress(0, "Saving Cache"); DB.Write(); _bgw.ReportProgress(0, "Saving Cache Complete"); _cacheSaveTimer.Reset(); _cacheSaveTimer.Start(); } string fullDir = dbDir.FullName; if (report) { _bgw.ReportProgress(0, new bgwText2(fullDir)); } DatStatus chechingDatStatus = dbDir.IsInToSort ? DatStatus.InToSort : DatStatus.NotInDat; // this is a temporary rvDir structure to store the data about the actual directory/files we are scanning // we will first populate this variable with the real file data from the directory, and then compare it // with the data in dbDir. RvDir fileDir = null; Debug.WriteLine(fullDir); FileType ft = dbDir.FileType; #region "Populate fileDir" // if we are scanning a ZIP file then populate scanDir from the ZIP file switch (ft) { case FileType.Zip: { fileDir = new RvDir(ft); // open the zip file ZipFile checkZ = new ZipFile(); ZipReturn zr = checkZ.ZipFileOpen(fullDir, dbDir.TimeStamp, true); if (zr == ZipReturn.ZipGood) { dbDir.ZipStatus = checkZ.ZipStatus; // to be Scanning a ZIP file means it is either new or has changed. // as the code below only calls back here if that is true. // // Level1: Only use header CRC's // Just get the CRC for the ZIP headers. // // Level2: Fully checksum changed only files // We know this file has been changed to do a full checksum scan. // // Level3: Fully checksum everything // So do a full checksum scan. if (EScanLevel == eScanLevel.Level2 || EScanLevel == eScanLevel.Level3) { checkZ.DeepScan(); } // add all of the file information from the zip file into scanDir for (int i = 0; i < checkZ.LocalFilesCount(); i++) { RvFile tFile = new RvFile(DBTypeGet.FileFromDir(ft)) { Name = checkZ.Filename(i), ZipFileIndex = i, ZipFileHeaderPosition = checkZ.LocalHeader(i), Size = checkZ.UncompressedSize(i), CRC = checkZ.CRC32(i) }; // all 3 levels read the CRC from the ZIP header tFile.SetStatus(chechingDatStatus, GotStatus.Got); tFile.FileStatusSet(FileStatus.SizeFromHeader | FileStatus.CRCFromHeader); // if we are in level 2 or level 3 then do a full CheckSum Scan. if (EScanLevel == eScanLevel.Level2 || EScanLevel == eScanLevel.Level3) { // DeepScan will return ZipReturn.ZipCRCDecodeError if the headers CRC and // the actual CRC do not match. // So we just need to set the MD5 and SHA1 from the ZIP file. zr = checkZ.FileStatus(i); if (zr == ZipReturn.ZipUntested) { _bgw.ReportProgress(0, new bgwShowCorrupt(zr, fullDir + " : " + checkZ.Filename(i))); } else if (zr != ZipReturn.ZipGood) { _bgw.ReportProgress(0, new bgwShowCorrupt(zr, fullDir + " : " + checkZ.Filename(i))); tFile.GotStatus = GotStatus.Corrupt; } else { tFile.MD5 = checkZ.MD5(i); tFile.SHA1 = checkZ.SHA1(i); tFile.FileStatusSet(FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.SHA1Verified | FileStatus.MD5Verified); } } fileDir.ChildAdd(tFile); } } else if (zr == ZipReturn.ZipFileLocked) { _bgw.ReportProgress(0, new bgwShowError(fullDir, "Zip File Locked")); dbDir.TimeStamp = 0; dbDir.GotStatus = GotStatus.FileLocked; } else { _bgw.ReportProgress(0, new bgwShowCorrupt(zr, fullDir)); dbDir.GotStatus = GotStatus.Corrupt; } checkZ.ZipFileClose(); } break; case FileType.Dir: { fileDir = new RvDir(FileType.Dir); DirectoryInfo oDir = new DirectoryInfo(fullDir); DirectoryInfo[] oDirs = oDir.GetDirectories(); FileInfo[] oFiles = oDir.GetFiles(); // add all the subdirectories into scanDir foreach (DirectoryInfo dir in oDirs) { RvBase tDir = new RvDir(FileType.Dir) { Name = dir.Name, TimeStamp = dir.LastWriteTime, }; tDir.SetStatus(chechingDatStatus, GotStatus.Got); fileDir.ChildAdd(tDir); } // add all the files into scanDir foreach (FileInfo oFile in oFiles) { // if we find any zip files add them as zip files. string fExt = Path.GetExtension(oFile.Name); switch (fExt.ToLower()) { case ".zip": { RvDir tGame = new RvDir(FileType.Zip) { Name = Path.GetFileNameWithoutExtension(oFile.Name), TimeStamp = oFile.LastWriteTime, }; tGame.SetStatus(chechingDatStatus, GotStatus.Got); fileDir.ChildAdd(tGame); } break; default: { string fName = oFile.Name; if (fName == "__RomVault.tmp") { File.Delete(oFile.FullName); continue; } // Scanning a file // // Level1 & 2 : (are the same for files) Fully checksum changed only files // Here we are just getting the TimeStamp of the File, and later // if the TimeStamp was not matched we will have to read the files CRC, MD5 & SHA1 // // Level3: Fully checksum everything // Get everything about the file right here so // read CRC, MD5 & SHA1 // add all the files in the sub-directory to scanDir RvFile tFile = new RvFile(FileType.File) { Name = fName, Size = (ulong)oFile.Length, TimeStamp = oFile.LastWriteTime }; tFile.FileStatusSet(FileStatus.SizeVerified); int errorCode = CHD.CheckFile(oFile, out tFile.SHA1CHD, out tFile.MD5CHD, out tFile.CHDVersion); if (errorCode == 0) { if (tFile.SHA1CHD != null) { tFile.FileStatusSet(FileStatus.SHA1CHDFromHeader); } if (tFile.MD5CHD != null) { tFile.FileStatusSet(FileStatus.MD5CHDFromHeader); } tFile.SetStatus(chechingDatStatus, GotStatus.Got); // if we are scanning at Level3 then we get all the info here if (EScanLevel == eScanLevel.Level3) { DeepScanFile(fullDir, tFile); ChdManCheck(fullDir, tFile); } } else if (errorCode == 32) { tFile.GotStatus = GotStatus.FileLocked; _bgw.ReportProgress(0, new bgwShowError(fullDir, "File Locked")); } else { string filename = Path.Combine(fullDir, tFile.Name); ReportError.Show("File: " + filename + " Error: " + new Win32Exception(errorCode).Message + ". Scan Aborted."); _fileErrorAbort = true; return; } fileDir.ChildAdd(tFile); } break; } } } break; default: ReportError.SendAndShow("Un supported file type in CheckADir " + ft); break; } #endregion if (fileDir == null) { ReportError.SendAndShow("Unknown Reading File Type in Dir Scanner"); return; } if (report) { _bgw.ReportProgress(0, new bgwSetRange2(fileDir.ChildCount - 1)); _bgw.ReportProgress(0, new bgwRange2Visible(true)); } if (!DBTypeGet.isCompressedDir(ft) && _bgw.CancellationPending) { return; } Compare(dbDir, fileDir, report, true); }
/// <summary> /// Write a set of input files to a torrentzip archive (assuming the same output archive name) /// </summary> /// <param name="inputFile">Input filenames to be moved</param> /// <param name="outDir">Output directory to build to</param> /// <param name="rom">List of Rom representing the new information</param> /// <param name="date">True if the date from the DAT should be used if available, false otherwise (default)</param> /// <param name="romba">True if files should be output in Romba depot folders, false otherwise</param> /// <returns>True if the archive was written properly, false otherwise</returns> public override bool Write(List <string> inputFiles, string outDir, List <Rom> roms, bool date = false, bool romba = false) { bool success = false; string tempFile = Path.Combine(outDir, "tmp" + Guid.NewGuid().ToString()); // If either list of roms is null or empty, return if (inputFiles == null || roms == null || inputFiles.Count == 0 || roms.Count == 0) { return(success); } // If the number of inputs is less than the number of available roms, return if (inputFiles.Count < roms.Count) { return(success); } // If one of the files doesn't exist, return foreach (string file in inputFiles) { if (!File.Exists(file)) { return(success); } } // Get the output archive name from the first rebuild rom string archiveFileName = Path.Combine(outDir, Utilities.RemovePathUnsafeCharacters(roms[0].MachineName) + (roms[0].MachineName.EndsWith(".zip") ? "" : ".zip")); // Set internal variables Stream writeStream = null; ZipFile oldZipFile = new ZipFile(); ZipFile zipFile = new ZipFile(); ZipReturn zipReturn = ZipReturn.ZipGood; try { // If the full output path doesn't exist, create it if (!Directory.Exists(Path.GetDirectoryName(archiveFileName))) { Directory.CreateDirectory(Path.GetDirectoryName(archiveFileName)); } // If the archive doesn't exist, create it and put the single file if (!File.Exists(archiveFileName)) { zipReturn = zipFile.Create(tempFile); // Map all inputs to index Dictionary <string, int> inputIndexMap = new Dictionary <string, int>(); for (int i = 0; i < inputFiles.Count; i++) { inputIndexMap.Add(roms[i].Name.Replace('\\', '/'), i); } // Sort the keys in TZIP order List <string> keys = inputIndexMap.Keys.ToList(); keys.Sort(ZipFile.TorrentZipStringCompare); // Now add all of the files in order foreach (string key in keys) { // Get the index mapped to the key int index = inputIndexMap[key]; // Open the input file for reading Stream freadStream = Utilities.TryOpenRead(inputFiles[index]); ulong istreamSize = (ulong)(new FileInfo(inputFiles[index]).Length); DateTime dt = DateTime.Now; if (date && !String.IsNullOrWhiteSpace(roms[index].Date) && DateTime.TryParse(roms[index].Date.Replace('\\', '/'), out dt)) { uint msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); zipFile.OpenWriteStream(false, false, roms[index].Name.Replace('\\', '/'), istreamSize, SabreTools.Library.Data.CompressionMethod.Deflated, out writeStream, lastMod: msDosDateTime); } else { zipFile.OpenWriteStream(false, true, roms[index].Name.Replace('\\', '/'), istreamSize, SabreTools.Library.Data.CompressionMethod.Deflated, out writeStream); } // Copy the input stream to the output byte[] ibuffer = new byte[_bufferSize]; int ilen; while ((ilen = freadStream.Read(ibuffer, 0, _bufferSize)) > 0) { writeStream.Write(ibuffer, 0, ilen); writeStream.Flush(); } freadStream.Dispose(); zipFile.CloseWriteStream(Convert.ToUInt32(roms[index].CRC, 16)); } } // Otherwise, sort the input files and write out in the correct order else { // Open the old archive for reading oldZipFile.Open(archiveFileName, new FileInfo(archiveFileName).LastWriteTime.Ticks, true); // Map all inputs to index Dictionary <string, int> inputIndexMap = new Dictionary <string, int>(); for (int i = 0; i < inputFiles.Count; i++) { // If the old one contains the new file, then just skip out if (oldZipFile.Contains(roms[i].Name.Replace('\\', '/'))) { continue; } inputIndexMap.Add(roms[i].Name.Replace('\\', '/'), -(i + 1)); } // Then add all of the old entries to it too for (int i = 0; i < oldZipFile.EntriesCount; i++) { inputIndexMap.Add(oldZipFile.Filename(i), i); } // If the number of entries is the same as the old archive, skip out if (inputIndexMap.Keys.Count <= oldZipFile.EntriesCount) { success = true; return(success); } // Otherwise, process the old zipfile zipFile.Create(tempFile); // Get the order for the entries with the new file List <string> keys = inputIndexMap.Keys.ToList(); keys.Sort(ZipFile.TorrentZipStringCompare); // Copy over all files to the new archive foreach (string key in keys) { // Get the index mapped to the key int index = inputIndexMap[key]; // If we have the input file, add it now if (index < 0) { // Open the input file for reading Stream freadStream = Utilities.TryOpenRead(inputFiles[-index - 1]); ulong istreamSize = (ulong)(new FileInfo(inputFiles[-index - 1]).Length); DateTime dt = DateTime.Now; if (date && !String.IsNullOrWhiteSpace(roms[-index - 1].Date) && DateTime.TryParse(roms[-index - 1].Date.Replace('\\', '/'), out dt)) { uint msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); zipFile.OpenWriteStream(false, false, roms[-index - 1].Name.Replace('\\', '/'), istreamSize, SabreTools.Library.Data.CompressionMethod.Deflated, out writeStream, lastMod: msDosDateTime); } else { zipFile.OpenWriteStream(false, true, roms[-index - 1].Name.Replace('\\', '/'), istreamSize, SabreTools.Library.Data.CompressionMethod.Deflated, out writeStream); } // Copy the input stream to the output byte[] ibuffer = new byte[_bufferSize]; int ilen; while ((ilen = freadStream.Read(ibuffer, 0, _bufferSize)) > 0) { writeStream.Write(ibuffer, 0, ilen); writeStream.Flush(); } freadStream.Dispose(); zipFile.CloseWriteStream(Convert.ToUInt32(roms[-index - 1].CRC, 16)); } // Otherwise, copy the file from the old archive else { // Instantiate the streams oldZipFile.OpenReadStream(index, false, out Stream zreadStream, out ulong istreamSize, out SabreTools.Library.Data.CompressionMethod icompressionMethod, out uint lastMod); zipFile.OpenWriteStream(false, lastMod == Constants.TorrentZipFileDateTime, oldZipFile.Filename(index), istreamSize, SabreTools.Library.Data.CompressionMethod.Deflated, out writeStream, lastMod: lastMod); // Copy the input stream to the output byte[] ibuffer = new byte[_bufferSize]; int ilen; while ((ilen = zreadStream.Read(ibuffer, 0, _bufferSize)) > 0) { writeStream.Write(ibuffer, 0, ilen); writeStream.Flush(); } zipFile.CloseWriteStream(BitConverter.ToUInt32(oldZipFile.CRC32(index), 0)); } } } // Close the output zip file zipFile.Close(); success = true; } catch (Exception ex) { Console.WriteLine(ex); success = false; } finally { zipFile.Dispose(); oldZipFile.Dispose(); } // If the old file exists, delete it and replace if (File.Exists(archiveFileName)) { Utilities.TryDeleteFile(archiveFileName); } File.Move(tempFile, archiveFileName); return(true); }
/// <summary> /// Write an input stream to a torrentzip archive /// </summary> /// <param name="inputStream">Input filename to be moved</param> /// <param name="outDir">Output directory to build to</param> /// <param name="rom">DatItem representing the new information</param> /// <returns>True if the archive was written properly, false otherwise</returns> public override bool Write(Stream inputStream, string outDir, Rom rom) { bool success = false; string tempFile = Path.Combine(outDir, $"tmp{Guid.NewGuid()}"); // If either input is null or empty, return if (inputStream == null || rom == null || rom.Name == null) { return(success); } // If the stream is not readable, return if (!inputStream.CanRead) { return(success); } // Seek to the beginning of the stream inputStream.Seek(0, SeekOrigin.Begin); // Get the output archive name from the first rebuild rom string archiveFileName = Path.Combine(outDir, Sanitizer.RemovePathUnsafeCharacters(rom.Machine.Name) + (rom.Machine.Name.EndsWith(".zip") ? string.Empty : ".zip")); // Set internal variables Stream writeStream = null; ZipFile oldZipFile = new ZipFile(); ZipFile zipFile = new ZipFile(); ZipReturn zipReturn = ZipReturn.ZipGood; try { // If the full output path doesn't exist, create it if (!Directory.Exists(Path.GetDirectoryName(archiveFileName))) { Directory.CreateDirectory(Path.GetDirectoryName(archiveFileName)); } // If the archive doesn't exist, create it and put the single file if (!File.Exists(archiveFileName)) { inputStream.Seek(0, SeekOrigin.Begin); zipReturn = zipFile.ZipFileCreate(tempFile); // Open the input file for reading ulong istreamSize = (ulong)(inputStream.Length); DateTime dt = DateTime.Now; if (UseDates && !string.IsNullOrWhiteSpace(rom.Date) && DateTime.TryParse(rom.Date.Replace('\\', '/'), out dt)) { uint msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); zipFile.ZipFileOpenWriteStream(false, false, rom.Name.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, msDosDateTime, out writeStream); } else { zipFile.ZipFileOpenWriteStream(false, true, rom.Name.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, null, out writeStream); } // Copy the input stream to the output byte[] ibuffer = new byte[_bufferSize]; int ilen; while ((ilen = inputStream.Read(ibuffer, 0, _bufferSize)) > 0) { writeStream.Write(ibuffer, 0, ilen); writeStream.Flush(); } zipFile.ZipFileCloseWriteStream(Utilities.StringToByteArray(rom.CRC)); } // Otherwise, sort the input files and write out in the correct order else { // Open the old archive for reading oldZipFile.ZipFileOpen(archiveFileName, -1, true); // Map all inputs to index Dictionary <string, int> inputIndexMap = new Dictionary <string, int>(); var oldZipFileContents = new List <string>(); for (int i = 0; i < oldZipFile.LocalFilesCount(); i++) { oldZipFileContents.Add(oldZipFile.Filename(i)); } // If the old one doesn't contain the new file, then add it if (!oldZipFileContents.Contains(rom.Name.Replace('\\', '/'))) { inputIndexMap.Add(rom.Name.Replace('\\', '/'), -1); } // Then add all of the old entries to it too for (int i = 0; i < oldZipFile.LocalFilesCount(); i++) { inputIndexMap.Add(oldZipFile.Filename(i), i); } // If the number of entries is the same as the old archive, skip out if (inputIndexMap.Keys.Count <= oldZipFile.LocalFilesCount()) { success = true; return(success); } // Otherwise, process the old zipfile zipFile.ZipFileCreate(tempFile); // Get the order for the entries with the new file List <string> keys = inputIndexMap.Keys.ToList(); keys.Sort(ZipFile.TrrntZipStringCompare); // Copy over all files to the new archive foreach (string key in keys) { // Get the index mapped to the key int index = inputIndexMap[key]; // If we have the input file, add it now if (index < 0) { // Open the input file for reading ulong istreamSize = (ulong)(inputStream.Length); DateTime dt = DateTime.Now; if (UseDates && !string.IsNullOrWhiteSpace(rom.Date) && DateTime.TryParse(rom.Date.Replace('\\', '/'), out dt)) { uint msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); zipFile.ZipFileOpenWriteStream(false, false, rom.Name.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, msDosDateTime, out writeStream); } else { zipFile.ZipFileOpenWriteStream(false, true, rom.Name.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, null, out writeStream); } // Copy the input stream to the output byte[] ibuffer = new byte[_bufferSize]; int ilen; while ((ilen = inputStream.Read(ibuffer, 0, _bufferSize)) > 0) { writeStream.Write(ibuffer, 0, ilen); writeStream.Flush(); } zipFile.ZipFileCloseWriteStream(Utilities.StringToByteArray(rom.CRC)); } // Otherwise, copy the file from the old archive else { // Instantiate the streams oldZipFile.ZipFileOpenReadStream(index, false, out Stream zreadStream, out ulong istreamSize, out ushort icompressionMethod); uint msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(oldZipFile.LastModified(index)); zipFile.ZipFileOpenWriteStream(false, true, oldZipFile.Filename(index), istreamSize, (ushort)CompressionMethod.Deflated, msDosDateTime, out writeStream); // Copy the input stream to the output byte[] ibuffer = new byte[_bufferSize]; int ilen; while ((ilen = zreadStream.Read(ibuffer, 0, _bufferSize)) > 0) { writeStream.Write(ibuffer, 0, ilen); writeStream.Flush(); } oldZipFile.ZipFileCloseReadStream(); zipFile.ZipFileCloseWriteStream(oldZipFile.CRC32(index)); } } } // Close the output zip file zipFile.ZipFileClose(); oldZipFile.ZipFileClose(); success = true; } catch (Exception ex) { logger.Error(ex); success = false; } finally { } // If the old file exists, delete it and replace if (File.Exists(archiveFileName)) { FileExtensions.TryDelete(archiveFileName); } File.Move(tempFile, archiveFileName); return(true); }
private static void ScanADir(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() == ".zip") { ZipFile fz = new ZipFile(); ZipReturn zr = fz.ZipFileOpen(f.FullName, f.LastWriteTime, true); if (zr != ZipReturn.ZipGood) { continue; } fz.DeepScan(); int FileUsedCount = 0; for (int i = 0; i < fz.LocalFilesCount(); i++) { Debug.WriteLine(fz.Filename(i)); RvFile tFile = new RvFile(); tFile.Size = fz.UncompressedSize(i); tFile.CRC = fz.CRC32(i); tFile.MD5 = fz.MD5(i); tFile.SHA1 = fz.SHA1(i); Debug.WriteLine("CRC " + VarFix.ToString(tFile.CRC)); Debug.WriteLine("MD5 " + VarFix.ToString(tFile.MD5)); Debug.WriteLine("SHA1 " + VarFix.ToString(tFile.SHA1)); FindStatus res = fileneededTest(tFile); if (res == FindStatus.FileUnknown) { continue; } FileUsedCount++; if (res != FindStatus.FoundFileInArchive) { GZip gz = new GZip(); gz.crc = tFile.CRC; gz.md5Hash = tFile.MD5; gz.sha1Hash = tFile.SHA1; gz.uncompressedSize = tFile.Size; bool isZipTrrntzip = (fz.ZipStatus == ZipStatus.TrrntZip); ulong compressedSize; ushort method; Stream zds; fz.ZipFileOpenReadStream(i, isZipTrrntzip, out zds, out compressedSize, out method); gz.compressedSize = compressedSize; string outfile = Getfilename(tFile.SHA1); gz.WriteGZip(outfile, zds, isZipTrrntzip); tFile.CompressedSize = gz.compressedSize; fz.ZipFileCloseReadStream(); tFile.DBWrite(); } } fz.ZipFileClose(); if (delFiles && FileUsedCount == fz.LocalFilesCount()) { File.SetAttributes(f.FullName, FileAttributes.Normal); File.Delete(f.FullName); } } else if (ext.ToLower() == ".gz") { GZip gZipTest = new GZip(); ZipReturn errorcode = gZipTest.ReadGZip(f.FullName, true); if (errorcode != ZipReturn.ZipGood) { continue; } RvFile tFile = new RvFile(); tFile.CRC = gZipTest.crc; tFile.MD5 = gZipTest.md5Hash; tFile.SHA1 = gZipTest.sha1Hash; tFile.Size = gZipTest.uncompressedSize; FindStatus res = fileneededTest(tFile); if (res == FindStatus.FileUnknown) { continue; } if (res != FindStatus.FoundFileInArchive) { GZip gz = new GZip(); gz.crc = tFile.CRC; gz.md5Hash = tFile.MD5; gz.sha1Hash = tFile.SHA1; gz.uncompressedSize = tFile.Size; Stream ds; gZipTest.GetStream(out ds); string outfile = Getfilename(tFile.SHA1); gz.WriteGZip(outfile, ds, false); ds.Close(); ds.Dispose(); gZipTest.Close(); tFile.CompressedSize = gz.compressedSize; tFile.DBWrite(); } if (delFiles) { File.SetAttributes(f.FullName, FileAttributes.Normal); File.Delete(f.FullName); } } else { RvFile tFile = new RvFile(); int errorcode = UnCompFiles.CheckSumRead(f.FullName, true, out tFile.CRC, out tFile.MD5, out tFile.SHA1, out tFile.Size); if (errorcode != 0) { continue; } // test if needed. FindStatus res = fileneededTest(tFile); if (res == FindStatus.FileUnknown) { continue; } if (res != FindStatus.FoundFileInArchive) { GZip gz = new GZip(); gz.crc = tFile.CRC; gz.md5Hash = tFile.MD5; gz.sha1Hash = tFile.SHA1; gz.uncompressedSize = tFile.Size; Stream ds; int errorCode = IO.FileStream.OpenFileRead(f.FullName, out ds); string outfile = Getfilename(tFile.SHA1); gz.WriteGZip(outfile, ds, false); ds.Close(); ds.Dispose(); tFile.CompressedSize = gz.compressedSize; tFile.DBWrite(); } if (delFiles) { File.SetAttributes(f.FullName, FileAttributes.Normal); File.Delete(f.FullName); } } } DirectoryInfo[] childdi = di.GetDirectories(); foreach (DirectoryInfo d in childdi) { if (_bgw.CancellationPending) { return; } ScanADir(d.FullName); } if (directory != rootDir && IsDirectoryEmpty(directory)) { Directory.Delete(directory); } }
/// <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 { ZipFile zf = new ZipFile(); ZipReturn zr = zf.ZipFileOpen(this.Filename, -1, true); if (zr != ZipReturn.ZipGood) { throw new Exception(ZipFile.ZipErrorMessageText(zr)); } for (int i = 0; i < zf.LocalFilesCount(); i++) { // If the entry is a directory (or looks like a directory), we don't want to open it if (zf.IsDirectory(i) || zf.Filename(i).EndsWith(Path.DirectorySeparatorChar.ToString()) || zf.Filename(i).EndsWith(Path.AltDirectorySeparatorChar.ToString()) || zf.Filename(i).EndsWith(Path.PathSeparator.ToString())) { continue; } // Open the read stream zr = zf.ZipFileOpenReadStream(i, false, out Stream readStream, out ulong streamsize, out ushort cm); // If we get a read error, log it and continue if (zr != ZipReturn.ZipGood) { logger.Warning($"An error occurred while reading archive {this.Filename}: Zip Error - {zr}"); zr = zf.ZipFileCloseReadStream(); continue; } // Create a blank item for the entry BaseFile zipEntryRom = new BaseFile(); // Perform a quickscan, if flagged to if (this.AvailableHashes == Hash.CRC) { zipEntryRom.Size = (long)zf.UncompressedSize(i); zipEntryRom.CRC = zf.CRC32(i); } // Otherwise, use the stream directly else { zipEntryRom = readStream.GetInfo(size: (long)zf.UncompressedSize(i), hashes: this.AvailableHashes, keepReadOpen: true); } // Fill in comon details and add to the list zipEntryRom.Filename = zf.Filename(i); zipEntryRom.Parent = gamename; zipEntryRom.Date = zf.LastModified(i).ToString("yyyy/MM/dd hh:mm:ss"); found.Add(zipEntryRom); } // Dispose of the archive zr = zf.ZipFileCloseReadStream(); zf.ZipFileClose(); } catch (Exception ex) { logger.Error(ex); return(null); } return(found); }