Beispiel #1
0
        public void ZipFileCloseFailed()
        {
            if (ZipOpen == ZipOpenType.Closed)
            {
                return;
            }

            if (ZipOpen == ZipOpenType.OpenRead)
            {
                if (_zipFs != null)
                {
                    _zipFs.Close();
                    _zipFs.Dispose();
                }
                ZipOpen = ZipOpenType.Closed;
                return;
            }

            _zipFs.Flush();
            _zipFs.Close();
            _zipFs.Dispose();
            RVIO.File.Delete(_zipFileInfo.FullName);
            _zipFileInfo = null;
            ZipOpen      = ZipOpenType.Closed;
        }
Beispiel #2
0
        public void ZipFileClose()
        {
            switch (ZipOpen)
            {
            case ZipOpenType.Closed:
                return;

            case ZipOpenType.OpenRead:
                ZipFileCloseReadStream();
                if (_zipFs != null)
                {
                    _zipFs.Close();
                    _zipFs.Dispose();
                }
                ZipOpen = ZipOpenType.Closed;
                return;

            case ZipOpenType.OpenWrite:
                CloseWriting7Zip();
                if (_zipFileInfo != null)
                {
                    _zipFileInfo = new FileInfo(_zipFileInfo.FullName);
                }
                break;
            }

            ZipOpen = ZipOpenType.Closed;
        }
Beispiel #3
0
        public void ZipFileClose()
        {
            if (ZipOpen == ZipOpenType.Closed)
            {
                return;
            }

            if (ZipOpen == ZipOpenType.OpenRead)
            {
                // if FileInfo is valid (not null), then we created the stream and need to close it.
                // if we open from a stream, then FileInfo will be null, and we do not need to close the stream.
                if (_fileInfo != null && _inStream != null)
                {
                    _inStream.Close();
                    _inStream.Dispose();
                    _inStream = null;
                }
                ZipOpen = ZipOpenType.Closed;
                return;
            }

            if (ZipOpen == ZipOpenType.OpenWrite)
            {
                _inStream.Flush();
                _inStream.Close();
                _inStream.Dispose();
                _inStream = null;
                _fileInfo = new FileInfo(_fileInfo.FullName);
                ZipOpen   = ZipOpenType.Closed;
            }
        }
Beispiel #4
0
        public void ZipFileCloseFailed()
        {
            switch (ZipOpen)
            {
            case ZipOpenType.Closed:
                return;

            case ZipOpenType.OpenRead:
                ZipFileCloseReadStream();
                if (_zipFs != null)
                {
                    _zipFs.Close();
                    _zipFs.Dispose();
                }
                break;

            case ZipOpenType.OpenWrite:
                _zipFs.Flush();
                _zipFs.Close();
                _zipFs.Dispose();
                if (_zipFileInfo != null)
                {
                    RVIO.File.Delete(_zipFileInfo.FullName);
                }
                _zipFileInfo = null;
                break;
            }

            ZipOpen = ZipOpenType.Closed;
        }
Beispiel #5
0
 public ZipReturn ZipFileOpen(Stream inStream)
 {
     ZipFileClose();
     _zipFileInfo = null;
     _zipFs       = inStream;
     ZipOpen      = ZipOpenType.OpenRead;
     ZipStatus    = ZipStatus.None;
     return(ZipFileReadHeaders());
 }
Beispiel #6
0
 public ZipReturn ZipFileOpen(byte[] zipFileBytes)
 {
     ZipFileClose();
     _zipFileInfo   = null;
     _memoryZipFile = zipFileBytes;
     _zipFs         = new MemoryStream(_memoryZipFile, 0, zipFileBytes.Length);
     ZipOpen        = ZipOpenType.OpenRead;
     ZipStatus      = ZipStatus.None;
     return(ZipFileReadHeaders());
 }
Beispiel #7
0
        public ZipReturn ZipFileOpen(byte[] zipBytes)
        {
            ZipFileClose();
            ZipStatus = ZipStatus.None;
            _fileInfo = null;
            _inStream = new MemoryStream(zipBytes);
            ZipOpen   = ZipOpenType.OpenRead;

            //return ZipFileReadHeaders();
            return(ZipReturn.ZipGood);
        }
Beispiel #8
0
        public ZipReturn ZipFileOpen(Stream inStream)
        {
            ZipFileClose();
            ZipStatus = ZipStatus.None;
            _fileInfo = null;
            _inStream = inStream;
            ZipOpen   = ZipOpenType.OpenRead;

            //return ZipFileReadHeaders();
            return(ZipReturn.ZipGood);
        }
Beispiel #9
0
        public ZipReturn ZipFileOpen(string newFilename, long timestamp, bool readHeaders)
        {
            ZipFileClose();
            ZipStatus        = ZipStatus.None;
            _zip64           = false;
            _centralDirStart = 0;
            _centralDirSize  = 0;
            _zipFileInfo     = null;

            try
            {
                if (!RVIO.File.Exists(newFilename))
                {
                    ZipFileClose();
                    return(ZipReturn.ZipErrorFileNotFound);
                }
                _zipFileInfo = new FileInfo(newFilename);
                if (timestamp != -1 && _zipFileInfo.LastWriteTime != timestamp)
                {
                    ZipFileClose();
                    return(ZipReturn.ZipErrorTimeStamp);
                }
                int errorCode = FileStream.OpenFileRead(newFilename, out _zipFs);
                if (errorCode != 0)
                {
                    ZipFileClose();
                    if (errorCode == 32)
                    {
                        return(ZipReturn.ZipFileLocked);
                    }
                    return(ZipReturn.ZipErrorOpeningFile);
                }
            }
            catch (PathTooLongException)
            {
                ZipFileClose();
                return(ZipReturn.ZipFileNameToLong);
            }
            catch (IOException)
            {
                ZipFileClose();
                return(ZipReturn.ZipErrorOpeningFile);
            }
            ZipOpen = ZipOpenType.OpenRead;

            if (!readHeaders)
            {
                return(ZipReturn.ZipGood);
            }


            return(ZipFileReadHeaders());
        }
Beispiel #10
0
        private static void ScanADirNew(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.Length));

            for (int j = 0; j < fi.Length; j++)
            {
                if (_bgw.CancellationPending)
                {
                    return;
                }

                FileInfo f = fi[j];
                _bgw.ReportProgress(0, new bgwValue2(j + 1));
                _bgw.ReportProgress(0, new bgwText2(f.Name));

                bool fileFound = ScanAFile(f.FullName, null, f.Name);

                if (fileFound && DelFiles)
                {
                    File.SetAttributes(f.FullName, FileAttributes.Normal);
                    File.Delete(f.FullName);
                }
            }

            DirectoryInfo[] childdi = di.GetDirectories();
            foreach (DirectoryInfo d in childdi)
            {
                if (_bgw.CancellationPending)
                {
                    return;
                }
                ScanADirNew(d.FullName);
            }

            if (directory == "ToSort")
            {
                return;
            }
            if (IsDirectoryEmpty(directory))
            {
                System.IO.DirectoryInfo dii = new System.IO.DirectoryInfo(directory);
                dii.Attributes &= ~FileAttributes.ReadOnly;

                Directory.Delete(directory);
            }
        }
Beispiel #11
0
        public ZipReturn ZipFileCreate(string newFilename, bool compressOutput, int dictionarySize = 1 << 24, int numFastBytes = 64)
        {
            if (ZipOpen != ZipOpenType.Closed)
            {
                return(ZipReturn.ZipFileAlreadyOpen);
            }

            DirUtil.CreateDirForFile(newFilename);
            _zipFileInfo = new FileInfo(newFilename);

            int errorCode = FileStream.OpenFileWrite(newFilename, out _zipFs);

            if (errorCode != 0)
            {
                ZipFileClose();
                return(ZipReturn.ZipErrorOpeningFile);
            }
            ZipOpen = ZipOpenType.OpenWrite;

            _signatureHeader = new SignatureHeader();
            _header          = new Header();

            using (BinaryWriter bw = new BinaryWriter(_zipFs, Encoding.UTF8, true))
            {
                _signatureHeader.Write(bw);
            }

            _baseOffset = _zipFs.Position;

            _compressed = compressOutput;

            _unpackedStreamSize = 0;
            if (_compressed)
            {
                LzmaEncoderProperties ep  = new LzmaEncoderProperties(true, dictionarySize, numFastBytes);
                LzmaStream            lzs = new LzmaStream(ep, false, _zipFs);
                _codeMSbytes = lzs.Properties;
                _lzmaStream  = lzs;


                /*
                 * ZstandardStream zss = new ZstandardStream(_zipFs, 22, true);
                 * _codeMSbytes = new byte[] { 1, 4, 18, 0, 0 };
                 * _lzmaStream = zss;
                 */
                _packStreamStart = (ulong)_zipFs.Position;
            }

            return(ZipReturn.ZipGood);
        }
Beispiel #12
0
        public ZipReturn ZipFileOpen(string filename, long timestamp, bool readHeaders)
        {
            ZipFileClose();
            _memoryZipFile = null;
            Debug.WriteLine(filename);
            #region open file stream

            try
            {
                if (!RVIO.File.Exists(filename))
                {
                    ZipFileClose();
                    return(ZipReturn.ZipErrorFileNotFound);
                }
                _zipFileInfo = new FileInfo(filename);
                if ((timestamp != -1) && (_zipFileInfo.LastWriteTime != timestamp))
                {
                    ZipFileClose();
                    return(ZipReturn.ZipErrorTimeStamp);
                }
                int errorCode = FileStream.OpenFileRead(filename, out _zipFs);
                if (errorCode != 0)
                {
                    ZipFileClose();
                    return(ZipReturn.ZipErrorOpeningFile);
                }
            }
            catch (PathTooLongException)
            {
                ZipFileClose();
                return(ZipReturn.ZipFileNameToLong);
            }
            catch (IOException)
            {
                ZipFileClose();
                return(ZipReturn.ZipErrorOpeningFile);
            }

            #endregion

            ZipOpen   = ZipOpenType.OpenRead;
            ZipStatus = ZipStatus.None;

            return(ZipFileReadHeaders());
        }
Beispiel #13
0
        private void zipFileCloseWrite()
        {
            _zip64 = false;
            bool lTrrntzip = true;

            _centerDirStart = (ulong)_zipFs.Position;

            using (CrcCalculatorStream crcCs = new CrcCalculatorStream(_zipFs, true))
            {
                foreach (LocalFile t in _localFiles)
                {
                    t.CenteralDirectoryWrite(crcCs);
                    _zip64    |= t.Zip64;
                    lTrrntzip &= t.TrrntZip;
                }

                crcCs.Flush();
                crcCs.Close();

                _centerDirSize = (ulong)_zipFs.Position - _centerDirStart;

                _fileComment = lTrrntzip ? ZipUtils.GetBytes("TORRENTZIPPED-" + crcCs.Crc.ToString("X8")) : new byte[0];
                ZipStatus    = lTrrntzip ? ZipStatus.TrrntZip : ZipStatus.None;
            }
            _zip64 |= _centerDirStart >= 0xffffffff;
            _zip64 |= _centerDirSize >= 0xffffffff;
            _zip64 |= _localFiles.Count >= 0xffff;

            if (_zip64)
            {
                _endOfCenterDir64 = (ulong)_zipFs.Position;
                Zip64EndOfCentralDirWrite();
                Zip64EndOfCentralDirectoryLocatorWrite();
            }
            EndOfCentralDirWrite();

            _zipFs.SetLength(_zipFs.Position);
            _zipFs.Flush();
            _zipFs.Close();
            _zipFs.Dispose();
            _zipFileInfo = new FileInfo(_zipFileInfo.FullName);
            ZipOpen      = ZipOpenType.Closed;
        }
Beispiel #14
0
        public ZipReturn ZipFileCreate(string newFilename)
        {
            if (ZipOpen != ZipOpenType.Closed)
            {
                return(ZipReturn.ZipFileAlreadyOpen);
            }

            CompressUtils.CreateDirForFile(newFilename);
            _fileInfo = new FileInfo(newFilename);

            int errorCode = FileStream.OpenFileWrite(newFilename, out _inStream);

            if (errorCode != 0)
            {
                ZipFileClose();
                return(ZipReturn.ZipErrorOpeningFile);
            }
            ZipOpen = ZipOpenType.OpenWrite;
            return(ZipReturn.ZipGood);
        }
Beispiel #15
0
        public ZipReturn ZipFileCreate(string newFilename, bool compressOutput)
        {
            if (ZipOpen != ZipOpenType.Closed)
            {
                return(ZipReturn.ZipFileAlreadyOpen);
            }

            DirUtil.CreateDirForFile(newFilename);
            _zipFileInfo = new FileInfo(newFilename);

            int errorCode = FileStream.OpenFileWrite(newFilename, out _zipFs);

            if (errorCode != 0)
            {
                ZipFileClose();
                return(ZipReturn.ZipErrorOpeningFile);
            }
            ZipOpen = ZipOpenType.OpenWrite;

            _signatureHeader = new SignatureHeader();
            _header          = new Header();

            BinaryWriter bw = new BinaryWriter(_zipFs);

            _signatureHeader.Write(bw);

            _compressed = compressOutput;

            _unpackedStreamSize = 0;
            if (_compressed)
            {
                LzmaEncoderProperties ep = new LzmaEncoderProperties(true, 1 << 24, 64);
                _lzmaStream      = new LzmaStream(ep, false, _zipFs);
                _codeMSbytes     = _lzmaStream.Properties;
                _packStreamStart = (ulong)_zipFs.Position;
            }

            return(ZipReturn.ZipGood);
        }
Beispiel #16
0
        public void ZipFileClose()
        {
            if (ZipOpen == ZipOpenType.Closed)
            {
                return;
            }

            if (ZipOpen == ZipOpenType.OpenRead)
            {
                if (_inStream != null)
                {
                    _inStream.Close();
                    _inStream.Dispose();
                }
                ZipOpen = ZipOpenType.Closed;
                return;
            }

            _inStream.Flush();
            _inStream.Close();
            _inStream.Dispose();
            _fileInfo = new FileInfo(_fileInfo.FullName);
            ZipOpen   = ZipOpenType.Closed;
        }
Beispiel #17
0
        public static ReturnCode DecompressSource7ZipFile(RvFile zZipFileIn, bool includeGood, out string error)
        {
            byte[] buffer = new byte[BufferSize];

            RvFile cacheDir = DB.RvFileCache();

            string fileNameIn = zZipFileIn.FullName;

            SevenZ    zipFileIn = new SevenZ();
            ZipReturn zr1       = zipFileIn.ZipFileOpen(fileNameIn, zZipFileIn.TimeStamp, true);

            if (zr1 != ZipReturn.ZipGood)
            {
                error = "Error opening 7zip file for caching";
                return(ReturnCode.RescanNeeded);
            }

            RvFile outDir = new RvFile(FileType.Dir)
            {
                Name      = zZipFileIn.Name + ".cache",
                Parent    = cacheDir,
                DatStatus = DatStatus.InToSort,
                GotStatus = GotStatus.Got
            };

            int nameDirIndex = 0;

            while (cacheDir.ChildNameSearch(outDir, out int index) == 0)
            {
                nameDirIndex++;
                outDir.Name = zZipFileIn.Name + ".cache (" + nameDirIndex + ")";
            }
            cacheDir.ChildAdd(outDir);
            Directory.CreateDirectory(outDir.FullName);

            for (int i = 0; i < zipFileIn.LocalFilesCount(); i++)
            {
                if (zZipFileIn.Child(i).IsDir)
                {
                    continue;
                }
                RvFile thisFile = null;
                for (int j = 0; j < zZipFileIn.ChildCount; j++)
                {
                    if (zZipFileIn.Child(j).ZipFileIndex != i)
                    {
                        continue;
                    }
                    thisFile = zZipFileIn.Child(j);
                    break;
                }

                if (thisFile == null)
                {
                    error = "Error opening 7zip file for caching";
                    return(ReturnCode.RescanNeeded);
                }

                bool extract = true;

                // first check to see if we have a file  version of this compressed file somewhere else.
                foreach (RvFile f in thisFile.FileGroup.Files)
                {
                    if (f.FileType == FileType.File && f.GotStatus == GotStatus.Got)
                    {
                        extract = false;
                    }
                }
                if (!extract)
                {
                    continue;
                }


                extract = false;
                if (includeGood)
                {
                    // if this is the file we are fixing then pull out the correct files.
                    if (thisFile.RepStatus == RepStatus.Correct)
                    {
                        extract = true;
                    }
                }

                // next check to see if we need this extracted to fix another file
                foreach (RvFile f in thisFile.FileGroup.Files)
                {
                    if (f.RepStatus == RepStatus.CanBeFixed)
                    {
                        extract = true;
                        break;
                    }
                }

                if (!extract)
                {
                    continue;
                }

                string cleanedName = thisFile.Name;
                cleanedName = cleanedName.Replace("/", "-");
                cleanedName = cleanedName.Replace("\\", "-");

                RvFile outFile = new RvFile(FileType.File)
                {
                    Name           = cleanedName,
                    Size           = thisFile.Size,
                    CRC            = thisFile.CRC,
                    SHA1           = thisFile.SHA1,
                    MD5            = thisFile.MD5,
                    HeaderFileType = thisFile.HeaderFileType,
                    AltSize        = thisFile.AltSize,
                    AltCRC         = thisFile.AltCRC,
                    AltSHA1        = thisFile.AltSHA1,
                    AltMD5         = thisFile.AltMD5,
                    FileGroup      = thisFile.FileGroup
                };

                outFile.SetStatus(DatStatus.InToSort, GotStatus.Got);
                outFile.FileStatusSet(
                    FileStatus.HeaderFileTypeFromHeader |
                    FileStatus.SizeFromHeader | FileStatus.SizeVerified |
                    FileStatus.CRCFromHeader | FileStatus.CRCVerified |
                    FileStatus.SHA1FromHeader | FileStatus.SHA1Verified |
                    FileStatus.MD5FromHeader | FileStatus.MD5Verified |
                    FileStatus.AltSizeFromHeader | FileStatus.AltSizeVerified |
                    FileStatus.AltCRCFromHeader | FileStatus.AltCRCVerified |
                    FileStatus.AltSHA1FromHeader | FileStatus.AltSHA1Verified |
                    FileStatus.AltMD5FromHeader | FileStatus.AltMD5Verified
                    , thisFile);
                outFile.RepStatus = RepStatus.NeededForFix;

                zipFileIn.ZipFileOpenReadStream(i, out Stream readStream, out ulong unCompressedSize);

                string filenameOut = Path.Combine(outDir.FullName, outFile.Name);

                ThreadMD5  tmd5  = null;
                ThreadSHA1 tsha1 = null;

                ThreadCRC tcrc32 = new ThreadCRC();
                if (Settings.rvSettings.FixLevel != EFixLevel.Level1 && Settings.rvSettings.FixLevel != EFixLevel.TrrntZipLevel1)
                {
                    tmd5  = new ThreadMD5();
                    tsha1 = new ThreadSHA1();
                }

                int errorCode = FileStream.OpenFileWrite(filenameOut, out Stream writeStream);

                ulong sizetogo = unCompressedSize;
                while (sizetogo > 0)
                {
                    int sizenow = sizetogo > BufferSize ? BufferSize : (int)sizetogo;

                    try
                    {
                        readStream.Read(buffer, 0, sizenow);
                    }
                    catch (Exception ex)
                    {
                        if (ex is ZlibException || ex is DataErrorException)
                        {
                            ZipReturn zr = zipFileIn.ZipFileCloseReadStream();
                            if (zr != ZipReturn.ZipGood)
                            {
                                error = "Error Closing " + zr + " Stream :" + zipFileIn.ZipFilename;
                                return(ReturnCode.FileSystemError);
                            }

                            zipFileIn.ZipFileClose();
                            writeStream.Flush();
                            writeStream.Close();
                            if (filenameOut != null)
                            {
                                File.Delete(filenameOut);
                            }

                            thisFile.GotStatus = GotStatus.Corrupt;
                            error = "Unexpected corrupt archive file found:\n" + zZipFileIn.FullName +
                                    "\nRun Find Fixes, and Fix to continue fixing correctly.";
                            return(ReturnCode.SourceDataStreamCorrupt);
                        }

                        error = "Error reading Source File " + ex.Message;
                        return(ReturnCode.FileSystemError);
                    }

                    tcrc32.Trigger(buffer, sizenow);
                    tmd5?.Trigger(buffer, sizenow);
                    tsha1?.Trigger(buffer, sizenow);

                    tcrc32.Wait();
                    tmd5?.Wait();
                    tsha1?.Wait();

                    try
                    {
                        writeStream.Write(buffer, 0, sizenow);
                    }
                    catch (Exception e)
                    {
                        error = "Error writing out file. " + Environment.NewLine + e.Message;
                        return(ReturnCode.FileSystemError);
                    }
                    sizetogo = sizetogo - (ulong)sizenow;
                }
                writeStream.Flush();
                writeStream.Close();
                writeStream.Dispose();

                tcrc32.Finish();
                tmd5?.Finish();
                tsha1?.Finish();

                byte[] bCRC  = tcrc32.Hash;
                byte[] bMD5  = tmd5?.Hash;
                byte[] bSHA1 = tsha1?.Hash;

                tcrc32.Dispose();
                tmd5?.Dispose();
                tsha1?.Dispose();

                FileInfo fi = new FileInfo(filenameOut);
                outFile.TimeStamp = fi.LastWriteTime;

                if (bCRC != null && thisFile.CRC != null && !ArrByte.BCompare(bCRC, thisFile.CRC))
                {
                    // error in file.
                }
                if (bMD5 != null && thisFile.MD5 != null && !ArrByte.BCompare(bMD5, thisFile.MD5))
                {
                    // error in file.
                }
                if (bSHA1 != null && thisFile.SHA1 != null && !ArrByte.BCompare(bSHA1, thisFile.SHA1))
                {
                    // error in file.
                }

                thisFile.FileGroup.Files.Add(outFile);

                outDir.ChildAdd(outFile);
            }

            zipFileIn.ZipFileClose();

            error = "";
            return(ReturnCode.Good);
        }
Beispiel #18
0
        private static ReturnCode OpenInputStream(RvFile fileIn, bool rawCopy, out ICompress zipFileIn, out bool sourceTrrntzip, out Stream readStream, out ulong streamSize, out ushort compressionMethod, out string error)
        {
            zipFileIn         = null;
            sourceTrrntzip    = false;
            readStream        = null;
            streamSize        = 0;
            compressionMethod = 0;

            if (fileIn.FileType == FileType.ZipFile || fileIn.FileType == FileType.SevenZipFile) // Input is a ZipFile
            {
                RvFile zZipFileIn = fileIn.Parent;
                if (zZipFileIn.FileType != DBTypeGet.DirFromFile(fileIn.FileType))
                {
                    error = "File Open but Source File is not correct type, Logic Error.";
                    return(ReturnCode.LogicError);
                }

                string    fileNameIn = zZipFileIn.FullNameCase;
                ZipReturn zr1;


                if (zZipFileIn.FileType == FileType.SevenZip)
                {
                    sourceTrrntzip = false;
                    zipFileIn      = new SevenZ();
                    zr1            = zipFileIn.ZipFileOpen(fileNameIn, zZipFileIn.FileModTimeStamp);
                }
                else
                {
                    sourceTrrntzip = (zZipFileIn.ZipStatus & ZipStatus.TrrntZip) == ZipStatus.TrrntZip;
                    zipFileIn      = new Zip();
                    zr1            = zipFileIn.ZipFileOpen(fileNameIn, zZipFileIn.FileModTimeStamp, fileIn.ZipFileHeaderPosition == null);
                }

                switch (zr1)
                {
                case ZipReturn.ZipGood:
                    break;

                case ZipReturn.ZipErrorFileNotFound:
                    error = "File not found, Rescan required before fixing " + fileIn.Name;
                    return(ReturnCode.RescanNeeded);

                case ZipReturn.ZipErrorTimeStamp:
                    error = "File has changed, Rescan required before fixing " + fileIn.Name;
                    return(ReturnCode.RescanNeeded);

                default:
                    error = "Error Open Zip" + zr1 + ", with File " + fileIn.DatTreeFullName;
                    return(ReturnCode.FileSystemError);
                }

                if (fileIn.FileType == FileType.SevenZipFile)
                {
                    ((SevenZ)zipFileIn).ZipFileOpenReadStream(fileIn.ZipFileIndex, out readStream, out streamSize);
                }
                else
                {
                    if (fileIn.ZipFileHeaderPosition != null)
                    {
                        ((Zip)zipFileIn).ZipFileOpenReadStreamQuick((ulong)fileIn.ZipFileHeaderPosition, rawCopy, out readStream, out streamSize, out compressionMethod);
                    }
                    else
                    {
                        ((Zip)zipFileIn).ZipFileOpenReadStream(fileIn.ZipFileIndex, rawCopy, out readStream, out streamSize, out compressionMethod);
                    }
                }
            }
            else // Input is a regular file
            {
                string fileNameIn = fileIn.FullName;
                if (!File.Exists(fileNameIn))
                {
                    error = "Rescan needed, File Not Found :" + fileNameIn;
                    return(ReturnCode.RescanNeeded);
                }
                FileInfo fileInInfo = new FileInfo(fileNameIn);
                if (fileInInfo.LastWriteTime != fileIn.FileModTimeStamp)
                {
                    error = "Rescan needed, File Changed :" + fileNameIn;
                    return(ReturnCode.RescanNeeded);
                }
                int errorCode = FileStream.OpenFileRead(fileNameIn, out readStream);
                if (errorCode != 0)
                {
                    error = new Win32Exception(errorCode).Message + ". " + fileNameIn;
                    return(ReturnCode.FileSystemError);
                }
                if (fileIn.Size == null)
                {
                    error = "Null File Size found in Fixing File :" + fileNameIn;
                    return(ReturnCode.LogicError);
                }
                streamSize = (ulong)fileIn.Size;
                if ((ulong)readStream.Length != streamSize)
                {
                    error = "Rescan needed, File Length Changed :" + fileNameIn;
                    return(ReturnCode.RescanNeeded);
                }
            }

            error = "";
            return(ReturnCode.Good);
        }
Beispiel #19
0
        // This Function returns:
        // Good            : Everything Worked Correctly
        // RescanNeeded     : Something unexpectedly changed in the files, so Stop fixing and prompt user to rescan.
        // LogicError       : This Should never happen and is a logic problem in the code.
        // FileSystemError  : Something is wrong with the files, like it was locked and could not be opened.
        // SourceDataStreamCorrupt : This happens when either zlib returns ZlibException, or the CRC does not match the extracted zip.
        // SourceCheckSumMismatch  : If the extracted files does not match its expected SHA1 or MD5
        // DestinationCheckSumMismatch : If the extracted files does not match the file to be fixed expected CRC,SHA1 or MD5.


        /// <summary>
        ///     Performs the RomVault File Copy, with the source and destination being files or zipped files
        /// </summary>
        /// <param name="fileIn">This is the file being copied, it may be a zipped file or a regular file system file</param>
        /// <param name="zipFileOut">This is the zip file that is being written to.</param>
        /// <param name="filenameOut">This is the name of the file to be written to if we are just making a file</param>
        /// <param name="fileOut">This is the actual output filename</param>
        /// <param name="forceRaw">if true then we will do a raw copy, this is so that we can copy corrupt zips</param>
        /// <param name="error">This is the returned error message if this copy fails</param>
        /// <returns>ReturnCode.Good is the valid return code otherwise we have an error</returns>
        public static ReturnCode CopyFile(RvFile fileIn, ICompress zipFileOut, string filenameOut, RvFile fileOut, bool forceRaw, out string error)
        {
            if (zipFileOut == null && filenameOut == null)
            {
                throw new Exception("Error in CopyFile: Both Outputs are null");
            }
            if (zipFileOut != null && filenameOut != null)
            {
                throw new Exception("Error in CopyFile: Both Outputs are set");
            }

            ICompress  zipFileIn  = null;
            Stream     readStream = null;
            ThreadCRC  tcrc32     = null;
            ThreadMD5  tmd5       = null;
            ThreadSHA1 tsha1      = null;


            ReturnCode retC;

            error = "";

            if (_buffer == null)
            {
                _buffer = new byte[BufferSize];
            }

            bool rawCopy = TestRawCopy(fileIn, fileOut, forceRaw);

            ulong  streamSize        = 0;
            ushort compressionMethod = 8;
            bool   sourceTrrntzip;



            bool isZeroLengthFile = DBHelper.IsZeroLengthFile(fileOut);

            if (!isZeroLengthFile)
            {
                //check that the in and out file match
                retC = CheckInputAndOutputFile(fileIn, fileOut, out error);
                if (retC != ReturnCode.Good)
                {
                    return(retC);
                }

                //Find and Check/Open Input Files
                retC = OpenInputStream(fileIn, rawCopy, out zipFileIn, out sourceTrrntzip, out readStream, out streamSize, out compressionMethod, out error);
                if (retC != ReturnCode.Good)
                {
                    return(retC);
                }
            }
            else
            {
                sourceTrrntzip = true;
            }

            if (!rawCopy)
            {
                compressionMethod = 8;
            }

            //Find and Check/Open Output Files
            retC = OpenOutputStream(fileOut, fileIn, zipFileOut, filenameOut, compressionMethod, rawCopy, sourceTrrntzip, null, out Stream writeStream, out error);
            if (retC != ReturnCode.Good)
            {
                return(retC);
            }

            byte[] bCRC;
            byte[] bMD5  = null;
            byte[] bSHA1 = null;
            if (!isZeroLengthFile)
            {
                #region Do Data Tranfer


                if (!rawCopy)
                {
                    tcrc32 = new ThreadCRC();
                    if (Settings.rvSettings.FixLevel != EFixLevel.Level1)
                    {
                        tmd5  = new ThreadMD5();
                        tsha1 = new ThreadSHA1();
                    }
                }

                ulong sizetogo = streamSize;

                while (sizetogo > 0)
                {
                    int sizenow = sizetogo > BufferSize ? BufferSize : (int)sizetogo;

                    try
                    {
                        readStream.Read(_buffer, 0, sizenow);
                    }
                    catch (Exception ex)
                    {
                        if (ex is ZlibException || ex is DataErrorException)
                        {
                            if ((fileIn.FileType == FileType.ZipFile || fileIn.FileType == FileType.SevenZipFile) && zipFileIn != null)
                            {
                                ZipReturn zr = zipFileIn.ZipFileCloseReadStream();
                                if (zr != ZipReturn.ZipGood)
                                {
                                    error = "Error Closing " + zr + " Stream :" + zipFileIn.ZipFilename;
                                    return(ReturnCode.FileSystemError);
                                }

                                zipFileIn.ZipFileClose();
                            }
                            else
                            {
                                readStream.Close();
                            }

                            writeStream.Flush();
                            writeStream.Close();
                            if (filenameOut != null)
                            {
                                File.Delete(filenameOut);
                            }

                            error = "Unexpected corrupt archive file found:\n" + fileIn.FullName +
                                    "\nRun Find Fixes, and Fix to continue fixing correctly.";
                            return(ReturnCode.SourceDataStreamCorrupt);
                        }

                        error = "Error reading Source File " + ex.Message;
                        return(ReturnCode.FileSystemError);
                    }

                    tcrc32?.Trigger(_buffer, sizenow);
                    tmd5?.Trigger(_buffer, sizenow);
                    tsha1?.Trigger(_buffer, sizenow);
                    try
                    {
                        writeStream.Write(_buffer, 0, sizenow);
                    }
                    catch (Exception e)
                    {
                        error = "Error writing out file. " + Environment.NewLine + e.Message;
                        return(ReturnCode.FileSystemError);
                    }
                    tcrc32?.Wait();
                    tmd5?.Wait();
                    tsha1?.Wait();
                    sizetogo = sizetogo - (ulong)sizenow;


                    if (Report.CancellationPending())
                    {
                        tcrc32?.Dispose();
                        tmd5?.Dispose();
                        tsha1?.Dispose();

                        if ((fileIn.FileType == FileType.ZipFile || fileIn.FileType == FileType.SevenZipFile) && zipFileIn != null)
                        {
                            ZipReturn zr = zipFileIn.ZipFileCloseReadStream();
                            if (zr != ZipReturn.ZipGood)
                            {
                                error = "Error Closing " + zr + " Stream :" + zipFileIn.ZipFilename;
                                return(ReturnCode.FileSystemError);
                            }
                            zipFileIn.ZipFileClose();
                        }
                        else
                        {
                            readStream.Close();
                        }

                        if (fileOut.FileType == FileType.ZipFile || fileOut.FileType == FileType.SevenZipFile)
                        {
                            zipFileOut.ZipFileCloseFailed();
                        }
                        else
                        {
                            writeStream.Flush();
                            writeStream.Close();
                        }

                        return(ReturnCode.Cancel);
                    }
                }
                writeStream.Flush();

                #endregion

                #region Collect Checksums

                // if we did a full copy then we just calculated all the checksums while doing the copy
                if (!rawCopy)
                {
                    tcrc32.Finish();
                    tmd5?.Finish();
                    tsha1?.Finish();

                    bCRC  = tcrc32.Hash;
                    bMD5  = tmd5?.Hash;
                    bSHA1 = tsha1?.Hash;

                    tcrc32.Dispose();
                    tmd5?.Dispose();
                    tsha1?.Dispose();
                }
                // if we raw copied and the source file has been FileChecked then we can trust the checksums in the source file
                else
                {
                    bCRC = fileIn.CRC.Copy();
                    if (fileIn.FileStatusIs(FileStatus.MD5Verified))
                    {
                        bMD5 = fileIn.MD5.Copy();
                    }
                    if (fileIn.FileStatusIs(FileStatus.SHA1Verified))
                    {
                        bSHA1 = fileIn.SHA1.Copy();
                    }
                }

                #endregion

                #region close the ReadStream

                if ((fileIn.FileType == FileType.ZipFile || fileIn.FileType == FileType.SevenZipFile) && zipFileIn != null)
                {
                    ZipReturn zr = zipFileIn.ZipFileCloseReadStream();
                    if (zr != ZipReturn.ZipGood)
                    {
                        error = "Error Closing " + zr + " Stream :" + zipFileIn.ZipFilename;
                        return(ReturnCode.FileSystemError);
                    }
                    zipFileIn.ZipFileClose();
                }
                else
                {
                    readStream.Close();
                }

                #endregion
            }
            else
            {
                CopyZeroLengthFile(fileOut, zipFileOut, out bCRC, out bMD5, out bSHA1);
            }

            #region close the WriteStream

            if (fileOut.FileType == FileType.ZipFile || fileOut.FileType == FileType.SevenZipFile)
            {
                ZipReturn zr = zipFileOut.ZipFileCloseWriteStream(bCRC);
                if (zr != ZipReturn.ZipGood)
                {
                    error = "Error Closing Stream " + zr;
                    return(ReturnCode.FileSystemError);
                }
                fileOut.ZipFileIndex          = zipFileOut.LocalFilesCount() - 1;
                fileOut.ZipFileHeaderPosition = zipFileOut.GetLocalFile(fileOut.ZipFileIndex).LocalHead;
                fileOut.FileModTimeStamp      = 629870671200000000;
            }
            else
            {
                writeStream.Flush();
                writeStream.Close();
                FileInfo fi = new FileInfo(filenameOut);
                fileOut.FileModTimeStamp = fi.LastWriteTime;
            }

            #endregion

            if (!isZeroLengthFile)
            {
                if (!rawCopy)
                {
                    retC = ValidateFileIn(fileIn, bCRC, bSHA1, bMD5, out error);
                    if (retC != ReturnCode.Good)
                    {
                        return(retC);
                    }
                }
            }

            retC = ValidateFileOut(fileIn, fileOut, rawCopy, bCRC, bSHA1, bMD5, out error);
            if (retC != ReturnCode.Good)
            {
                return(retC);
            }


            return(ReturnCode.Good);
        }
Beispiel #20
0
        public static ReturnCode MoveFile(RvFile fileIn, RvFile fileOut, string outFilename, out bool fileMoved, out string error)
        {
            error     = "";
            fileMoved = false;

            bool fileMove = TestFileMove(fileIn, fileOut);

            if (!fileMove)
            {
                return(ReturnCode.Good);
            }

            byte[] bCRC;
            byte[] bMD5  = null;
            byte[] bSHA1 = null;

            string fileNameIn = fileIn.FullName;

            if (!File.Exists(fileNameIn))
            {
                error = "Rescan needed, File Not Found :" + fileNameIn;
                return(ReturnCode.RescanNeeded);
            }
            FileInfo fileInInfo = new FileInfo(fileNameIn);

            if (fileInInfo.LastWriteTime != fileIn.FileModTimeStamp)
            {
                error = "Rescan needed, File Changed :" + fileNameIn;
                return(ReturnCode.RescanNeeded);
            }

            string fileNameOut = outFilename ?? fileOut.FullName;

            File.Move(fileNameIn, fileNameOut);

            bCRC = fileIn.CRC.Copy();
            if (fileIn.FileStatusIs(FileStatus.MD5Verified))
            {
                bMD5 = fileIn.MD5.Copy();
            }

            if (fileIn.FileStatusIs(FileStatus.SHA1Verified))
            {
                bSHA1 = fileIn.SHA1.Copy();
            }

            FileInfo fi = new FileInfo(fileNameOut);

            fileOut.FileModTimeStamp = fi.LastWriteTime;

            ReturnCode retC = ValidateFileOut(fileIn, fileOut, true, bCRC, bSHA1, bMD5, out error);

            if (retC != ReturnCode.Good)
            {
                return(retC);
            }

            CheckDeleteFile(fileIn);

            fileMoved = true;
            return(ReturnCode.Good);
        }
Beispiel #21
0
        public ZipReturn ZipFileCreate(string newFilename, SevenZipCompressType compressOutput, int dictionarySize = 1 << 24, int numFastBytes = 64)
        {
            if (ZipOpen != ZipOpenType.Closed)
            {
                return(ZipReturn.ZipFileAlreadyOpen);
            }

            CompressUtils.CreateDirForFile(newFilename);
            _zipFileInfo = new FileInfo(newFilename);

            int errorCode = FileStream.OpenFileWrite(newFilename, out _zipFs);

            if (errorCode != 0)
            {
                ZipFileClose();
                return(ZipReturn.ZipErrorOpeningFile);
            }
            ZipOpen = ZipOpenType.OpenWrite;

            _signatureHeader = new SignatureHeader();
            _header          = new Header();

            using (BinaryWriter bw = new(_zipFs, Encoding.UTF8, true))
            {
                _signatureHeader.Write(bw);
            }
            _baseOffset = _zipFs.Position;


            _packedOutStreams = new List <outStreams>();

            _compType = compressOutput;

#if solid
            outStreams newStream = new()
            {
                packedStart     = (ulong)_zipFs.Position,
                compType        = compressOutput,
                packedSize      = 0,
                unpackedStreams = new List <UnpackedStreamInfo>()
            };
            switch (compressOutput)
            {
            case SevenZipCompressType.lzma:
                LzmaEncoderProperties ep  = new(true, dictionarySize, numFastBytes);
                LzmaStream            lzs = new(ep, false, _zipFs);

                newStream.Method     = new byte[] { 3, 1, 1 };
                newStream.Properties = lzs.Properties;
                _compressStream      = lzs;
                break;

            case SevenZipCompressType.zstd:
                ZstdSharp.CompressionStream zss = new(_zipFs, 19);
                newStream.Method     = new byte[] { 4, 247, 17, 1 };
                newStream.Properties = new byte[] { 1, 5, 19, 0, 0 };
                _compressStream      = zss;
                break;

            case SevenZipCompressType.uncompressed:
                newStream.Method     = new byte[] { 0 };
                newStream.Properties = null;
                _compressStream      = _zipFs;
                break;
            }

            _packedOutStreams.Add(newStream);
#endif
            return(ZipReturn.ZipGood);
        }
Beispiel #22
0
        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);
            }
        }
Beispiel #23
0
        // This Function returns:
        // Good            : Everything Worked Correctly
        // RescanNeeded     : Something unexpectidly changed in the files, so Stop prompt user to rescan.
        // LogicError       : This Should never happen and is a logic problem in the code
        // FileSystemError  : Something is wrong with the files


        /// <summary>
        ///     Performs the RomVault File Copy, with the source and destination being files or zipped files
        /// </summary>
        /// <param name="fileIn">This is the file being copied, it may be a zipped file or a regular file system file</param>
        /// <param name="zipFileOut">
        ///     This is the zip file that is being writen to, if it is null a new zip file will be made if we
        ///     are coping to a zip
        /// </param>
        /// <param name="zipFilenameOut">This is the name of the .zip file to be made that will be created in zipFileOut</param>
        /// <param name="fileOut">This is the actual output filename</param>
        /// <param name="forceRaw">if true then we will do a raw copy, this is so that we can copy corrupt zips</param>
        /// <param name="error">This is the returned error message if this copy fails</param>
        /// <param name="foundFile">
        ///     If we are SHA1/MD5 checking the source file for the first time, and it is different from what
        ///     we expected the correct values for this file are returned in foundFile
        /// </param>
        /// <returns>ReturnCode.Good is the valid return code otherwire we have an error</returns>
        public static ReturnCode CopyFile(RvFile fileIn, ref ICompress zipFileOut, string zipFilenameOut, RvFile fileOut, bool forceRaw, out string error, out RvFile foundFile)
        {
            foundFile = null;
            error     = "";

            if (_buffer == null)
            {
                _buffer = new byte[BufferSize];
            }

            bool rawCopy = RawCopy(fileIn, fileOut, forceRaw);

            ulong  streamSize        = 0;
            ushort compressionMethod = 8;
            bool   sourceTrrntzip    = false;

            ICompress  zipFileIn  = null;
            Stream     readStream = null;
            ReturnCode retC;


            bool isZeroLengthFile = DBHelper.IsZeroLengthFile(fileOut);

            if (!isZeroLengthFile)
            {
                //check that the in and out file match
                retC = CheckInputAndOutputFile(fileIn, fileOut, out error);
                if (retC != ReturnCode.Good)
                {
                    return(retC);
                }

                //Find and Check/Open Input Files
                retC = OpenInputStream(fileIn, rawCopy, out zipFileIn, out sourceTrrntzip, out readStream, out streamSize, out compressionMethod, out error);
                if (retC != ReturnCode.Good)
                {
                    return(retC);
                }
            }
            else
            {
                sourceTrrntzip = true;
            }

            if (!rawCopy && ((Program.rvSettings.FixLevel == eFixLevel.TrrntZipLevel1) || (Program.rvSettings.FixLevel == eFixLevel.TrrntZipLevel2) || (Program.rvSettings.FixLevel == eFixLevel.TrrntZipLevel3)))
            {
                compressionMethod = 8;
            }

            //Find and Check/Open Output Files
            Stream writeStream;

            retC = OpenOutputStream(fileOut, fileIn, ref zipFileOut, zipFilenameOut, compressionMethod, rawCopy, sourceTrrntzip, out writeStream, out error);
            if (retC != ReturnCode.Good)
            {
                return(retC);
            }

            byte[] bCRC;
            byte[] bMD5  = null;
            byte[] bSHA1 = null;
            if (!isZeroLengthFile)
            {
                #region Do Data Tranfer

                ThreadCRC  tcrc32 = null;
                ThreadMD5  tmd5   = null;
                ThreadSHA1 tsha1  = null;

                if (!rawCopy)
                {
                    tcrc32 = new ThreadCRC();
                    tmd5   = new ThreadMD5();
                    tsha1  = new ThreadSHA1();
                }

                ulong sizetogo = streamSize;

                while (sizetogo > 0)
                {
                    int sizenow = sizetogo > BufferSize ? BufferSize : (int)sizetogo;

                    try
                    {
                        readStream.Read(_buffer, 0, sizenow);
                    }
                    catch (ZlibException)
                    {
                        if ((fileIn.FileType == FileType.ZipFile) && (zipFileIn != null))
                        {
                            ZipReturn zr = zipFileIn.ZipFileCloseReadStream();
                            if (zr != ZipReturn.ZipGood)
                            {
                                error = "Error Closing " + zr + " Stream :" + zipFileIn.Filename(fileIn.ReportIndex);
                                return(ReturnCode.FileSystemError);
                            }
                            zipFileIn.ZipFileClose();
                        }
                        else
                        {
                            readStream.Close();
                        }

                        if (fileOut.FileType == FileType.ZipFile)
                        {
                            ZipReturn zr = zipFileOut.ZipFileCloseWriteStream(new byte[] { 0, 0, 0, 0 });
                            if (zr != ZipReturn.ZipGood)
                            {
                                error = "Error Closing Stream " + zr;
                                return(ReturnCode.FileSystemError);
                            }
                            zipFileOut.ZipFileRollBack();
                        }
                        else
                        {
                            writeStream.Flush();
                            writeStream.Close();
                            File.Delete(zipFilenameOut);
                        }

                        error = "Error in Data Stream";
                        return(ReturnCode.SourceCRCCheckSumError);
                    }
                    catch (Exception e)
                    {
                        error = "Error reading Source File " + e.Message;
                        return(ReturnCode.FileSystemError);
                    }

                    if (!rawCopy)
                    {
                        tcrc32.Trigger(_buffer, sizenow);
                        tmd5.Trigger(_buffer, sizenow);
                        tsha1.Trigger(_buffer, sizenow);

                        tcrc32.Wait();
                        tmd5.Wait();
                        tsha1.Wait();
                    }
                    try
                    {
                        writeStream.Write(_buffer, 0, sizenow);
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine(e.Message);
                        error = "Error writing out file. " + Environment.NewLine + e.Message;
                        return(ReturnCode.FileSystemError);
                    }
                    sizetogo = sizetogo - (ulong)sizenow;
                }
                writeStream.Flush();

                #endregion

                #region Collect Checksums

                // if we did a full copy then we just calculated all the checksums while doing the copy
                if (!rawCopy)
                {
                    tcrc32.Finish();
                    tmd5.Finish();
                    tsha1.Finish();

                    bCRC  = tcrc32.Hash;
                    bMD5  = tmd5.Hash;
                    bSHA1 = tsha1.Hash;

                    tcrc32.Dispose();
                    tmd5.Dispose();
                    tsha1.Dispose();
                }
                // if we raw copied and the source file has been FileChecked then we can trust the checksums in the source file
                else
                {
                    bCRC = ArrByte.Copy(fileIn.CRC);
                    if (fileIn.FileStatusIs(FileStatus.MD5Verified))
                    {
                        bMD5 = ArrByte.Copy(fileIn.MD5);
                    }
                    if (fileIn.FileStatusIs(FileStatus.SHA1Verified))
                    {
                        bSHA1 = ArrByte.Copy(fileIn.SHA1);
                    }
                }

                #endregion

                #region close the ReadStream

                if (((fileIn.FileType == FileType.ZipFile) || (fileIn.FileType == FileType.SevenZipFile)) && (zipFileIn != null))
                {
                    ZipReturn zr = zipFileIn.ZipFileCloseReadStream();
                    if (zr != ZipReturn.ZipGood)
                    {
                        error = "Error Closing " + zr + " Stream :" + zipFileIn.Filename(fileIn.ReportIndex);
                        return(ReturnCode.FileSystemError);
                    }
                    zipFileIn.ZipFileClose();
                }
                else
                {
                    readStream.Close();

                    //if (RVIO.File.Exists(tmpFilename))
                    //    RVIO.File.Delete(tmpFilename);
                }

                #endregion
            }
            else
            {
                // Zero Length File (Directory in a Zip)
                if (fileOut.FileType == FileType.ZipFile)
                {
                    zipFileOut.ZipFileAddDirectory();
                }
                bCRC  = VarFix.CleanMD5SHA1("00000000", 8);
                bMD5  = VarFix.CleanMD5SHA1("d41d8cd98f00b204e9800998ecf8427e", 32);
                bSHA1 = VarFix.CleanMD5SHA1("da39a3ee5e6b4b0d3255bfef95601890afd80709", 40);
            }

            #region close the WriteStream

            if ((fileOut.FileType == FileType.ZipFile) || (fileOut.FileType == FileType.SevenZipFile))
            {
                ZipReturn zr = zipFileOut.ZipFileCloseWriteStream(bCRC);
                if (zr != ZipReturn.ZipGood)
                {
                    error = "Error Closing Stream " + zr;
                    return(ReturnCode.FileSystemError);
                }
                fileOut.ZipFileIndex          = zipFileOut.LocalFilesCount() - 1;
                fileOut.ZipFileHeaderPosition = zipFileOut.LocalHeader(fileOut.ZipFileIndex);
            }
            else
            {
                writeStream.Flush();
                writeStream.Close();
                FileInfo fi = new FileInfo(zipFilenameOut);
                fileOut.TimeStamp = fi.LastWriteTime;
            }

            #endregion

            if (!isZeroLengthFile)
            {
                if (!rawCopy)
                {
                    if (!ArrByte.bCompare(bCRC, fileIn.CRC))
                    {
                        fileIn.GotStatus = GotStatus.Corrupt;
                        error            = "Source CRC does not match Source Data stream, corrupt Zip";

                        if (fileOut.FileType == FileType.ZipFile)
                        {
                            zipFileOut.ZipFileRollBack();
                        }
                        else
                        {
                            File.Delete(zipFilenameOut);
                        }

                        return(ReturnCode.SourceCRCCheckSumError);
                    }

                    fileIn.FileStatusSet(FileStatus.CRCVerified | FileStatus.SizeVerified);

                    bool sourceFailed = false;

                    // check to see if we have a MD5 from the DAT file
                    if (fileIn.FileStatusIs(FileStatus.MD5FromDAT))
                    {
                        if (fileIn.MD5 == null)
                        {
                            error = "Should have an filein MD5 from Dat but not found. Logic Error.";
                            return(ReturnCode.LogicError);
                        }

                        if (!ArrByte.bCompare(fileIn.MD5, bMD5))
                        {
                            sourceFailed = true;
                        }
                        else
                        {
                            fileIn.FileStatusSet(FileStatus.MD5Verified);
                        }
                    }
                    // check to see if we have an MD5 (not from the DAT) so must be from previously scanning this file.
                    else if (fileIn.MD5 != null)
                    {
                        if (!ArrByte.bCompare(fileIn.MD5, bMD5))
                        {
                            // if we had an MD5 from a preview scan and it now does not match, something has gone really bad.
                            error = "The MD5 found does not match a previously scanned MD5, this should not happen, unless something got corrupt.";
                            return(ReturnCode.LogicError);
                        }
                    }
                    else // (FileIn.MD5 == null)
                    {
                        fileIn.MD5 = bMD5;
                        fileIn.FileStatusSet(FileStatus.MD5Verified);
                    }


                    // check to see if we have a SHA1 from the DAT file
                    if (fileIn.FileStatusIs(FileStatus.SHA1FromDAT))
                    {
                        if (fileIn.SHA1 == null)
                        {
                            error = "Should have an filein SHA1 from Dat but not found. Logic Error.";
                            return(ReturnCode.LogicError);
                        }

                        if (!ArrByte.bCompare(fileIn.SHA1, bSHA1))
                        {
                            sourceFailed = true;
                        }
                        else
                        {
                            fileIn.FileStatusSet(FileStatus.SHA1Verified);
                        }
                    }
                    // check to see if we have an SHA1 (not from the DAT) so must be from previously scanning this file.
                    else if (fileIn.SHA1 != null)
                    {
                        if (!ArrByte.bCompare(fileIn.SHA1, bSHA1))
                        {
                            // if we had an SHA1 from a preview scan and it now does not match, something has gone really bad.
                            error = "The SHA1 found does not match a previously scanned SHA1, this should not happen, unless something got corrupt.";
                            return(ReturnCode.LogicError);
                        }
                    }
                    else // (FileIn.SHA1 == null)
                    {
                        fileIn.SHA1 = bSHA1;
                        fileIn.FileStatusSet(FileStatus.SHA1Verified);
                    }


                    if (sourceFailed)
                    {
                        if ((fileIn.FileType == FileType.ZipFile) || (fileIn.FileType == FileType.SevenZipFile))
                        {
                            RvFile tZFile = new RvFile(FileType.ZipFile);
                            foundFile                    = tZFile;
                            tZFile.ZipFileIndex          = fileIn.ZipFileIndex;
                            tZFile.ZipFileHeaderPosition = fileIn.ZipFileHeaderPosition;
                        }
                        else
                        {
                            foundFile = new RvFile(fileIn.FileType);
                        }

                        foundFile.Name      = fileIn.Name;
                        foundFile.Size      = fileIn.Size;
                        foundFile.CRC       = bCRC;
                        foundFile.MD5       = bMD5;
                        foundFile.SHA1      = bSHA1;
                        foundFile.TimeStamp = fileIn.TimeStamp;
                        foundFile.SetStatus(DatStatus.NotInDat, GotStatus.Got);

                        foundFile.FileStatusSet(FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.MD5Verified | FileStatus.SHA1Verified);

                        if (fileOut.FileType == FileType.ZipFile)
                        {
                            zipFileOut.ZipFileRollBack();
                        }
                        else
                        {
                            File.Delete(zipFilenameOut);
                        }

                        return(ReturnCode.SourceCheckSumError);
                    }
                }
            }

            if ((fileOut.FileType == FileType.ZipFile) || (fileOut.FileType == FileType.SevenZipFile))
            {
                fileOut.FileStatusSet(FileStatus.SizeFromHeader | FileStatus.CRCFromHeader);
            }

            if (fileOut.FileStatusIs(FileStatus.CRCFromDAT) && (fileOut.CRC != null) && !ArrByte.bCompare(fileOut.CRC, bCRC))
            {
                //Rollback the file
                if (fileOut.FileType == FileType.ZipFile)
                {
                    zipFileOut.ZipFileRollBack();
                }
                else
                {
                    File.Delete(zipFilenameOut);
                }

                return(ReturnCode.DestinationCheckSumError);
            }

            fileOut.CRC = bCRC;
            if (!rawCopy || fileIn.FileStatusIs(FileStatus.CRCVerified))
            {
                fileOut.FileStatusSet(FileStatus.CRCVerified);
            }


            if (bSHA1 != null)
            {
                if (fileOut.FileStatusIs(FileStatus.SHA1FromDAT) && (fileOut.SHA1 != null) && !ArrByte.bCompare(fileOut.SHA1, bSHA1))
                {
                    //Rollback the file
                    if (fileOut.FileType == FileType.ZipFile)
                    {
                        zipFileOut.ZipFileRollBack();
                    }
                    else
                    {
                        File.Delete(zipFilenameOut);
                    }

                    return(ReturnCode.DestinationCheckSumError);
                }

                fileOut.SHA1 = bSHA1;
                fileOut.FileStatusSet(FileStatus.SHA1Verified);
            }

            if (bMD5 != null)
            {
                if (fileOut.FileStatusIs(FileStatus.MD5FromDAT) && (fileOut.MD5 != null) && !ArrByte.bCompare(fileOut.MD5, bMD5))
                {
                    //Rollback the file
                    if (fileOut.FileType == FileType.ZipFile)
                    {
                        zipFileOut.ZipFileRollBack();
                    }
                    else
                    {
                        File.Delete(zipFilenameOut);
                    }

                    return(ReturnCode.DestinationCheckSumError);
                }
                fileOut.MD5 = bMD5;
                fileOut.FileStatusSet(FileStatus.MD5Verified);
            }

            if (fileIn.Size != null)
            {
                fileOut.Size = fileIn.Size;
                fileOut.FileStatusSet(FileStatus.SizeVerified);
            }


            if (fileIn.GotStatus == GotStatus.Corrupt)
            {
                fileOut.GotStatus = GotStatus.Corrupt;
            }
            else
            {
                fileOut.GotStatus = GotStatus.Got; // Changes RepStatus to Correct
            }

            fileOut.FileStatusSet(FileStatus.SizeVerified);

            if ((fileOut.SHA1CHD == null) && (fileIn.SHA1CHD != null))
            {
                fileOut.SHA1CHD = fileIn.SHA1CHD;
            }
            if ((fileOut.MD5CHD == null) && (fileIn.MD5CHD != null))
            {
                fileOut.MD5CHD = fileIn.MD5CHD;
            }


            fileOut.CHDVersion = fileIn.CHDVersion;

            fileOut.FileStatusSet(FileStatus.SHA1CHDFromHeader | FileStatus.MD5CHDFromHeader | FileStatus.SHA1CHDVerified | FileStatus.MD5CHDVerified, fileIn);


            return(ReturnCode.Good);
        }