Пример #1
0
        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);
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        /// <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);
        }