Example #1
0
        public FileInfo[] GetFiles(string SearchPattern, bool includeHidden = true)
        {
            List<FileInfo> files = new List<FileInfo>();

            if (Settings.IsUnix)
            {
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(FullName);
                System.IO.FileInfo[] arrDi = di.GetFiles(SearchPattern);
                foreach (System.IO.FileInfo tDi in arrDi)
                {
                    FileInfo lDi = new FileInfo
                    {
                        Name = tDi.Name,
                        FullName = Path.Combine(FullName, tDi.Name),
                        Length = tDi.Length,
                        LastWriteTime = tDi.LastWriteTimeUtc.Ticks
                    };
                    files.Add(lDi);
                }
                return files.ToArray();
            }

            string dirName = NameFix.AddLongPathPrefix(FullName);

            Win32Native.WIN32_FIND_DATA findData = new Win32Native.WIN32_FIND_DATA();
            SafeFindHandle findHandle = Win32Native.FindFirstFile(dirName + @"\" + SearchPattern, findData);

            if (!findHandle.IsInvalid)
            {
                do
                {
                    string currentFileName = findData.cFileName;

                    // if this is a directory, find its contents
                    if ((findData.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0) continue;
                    if (!includeHidden && (findData.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_HIDDEN) != 0) continue;

                    FileInfo fi = new FileInfo
                    {
                        Name = currentFileName,
                        FullName = Path.Combine(FullName, currentFileName),
                        Length = Convert.Length(findData.nFileSizeHigh, findData.nFileSizeLow),
                        LastWriteTime = Convert.Time(findData.ftLastWriteTimeHigh, findData.ftLastWriteTimeLow)
                    };
                    files.Add(fi);
                }
                while (Win32Native.FindNextFile(findHandle, findData));
            }

            // close the find handle
            findHandle.Dispose();

            return files.ToArray();
        }
Example #2
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 ZipFile 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;


            ZipFile zipFileIn = null;

            System.IO.Stream readStream = null;


            bool isZeroLengthFile = DBHelper.IsZeroLengthFile(fileOut);

            if (!isZeroLengthFile)
            {
                #region check that the in and out file match
                if (fileOut.FileStatusIs(FileStatus.SizeFromDAT) && fileOut.Size != null && fileIn.Size != fileOut.Size)
                {
                    error = "Source and destination Size does not match. Logic Error.";
                    return(ReturnCode.LogicError);
                }
                if (fileOut.FileStatusIs(FileStatus.CRCFromDAT) && fileOut.CRC != null && !ArrByte.bCompare(fileIn.CRC, fileOut.CRC))
                {
                    error = "Source and destination CRC does not match. Logic Error.";
                    return(ReturnCode.LogicError);
                }

                if (fileOut.FileStatusIs(FileStatus.SHA1FromDAT) && fileIn.FileStatusIs(FileStatus.SHA1Verified))
                {
                    if (fileIn.SHA1 != null && fileOut.SHA1 != null && !ArrByte.bCompare(fileIn.SHA1, fileOut.SHA1))
                    {
                        error = "Source and destination SHA1 does not match. Logic Error.";
                        return(ReturnCode.LogicError);
                    }
                }
                if (fileOut.FileStatusIs(FileStatus.MD5CHDFromDAT) && fileIn.FileStatusIs(FileStatus.MD5Verified))
                {
                    if (fileIn.MD5 != null && fileOut.MD5 != null && !ArrByte.bCompare(fileIn.MD5, fileOut.MD5))
                    {
                        error = "Source and destination SHA1 does not match. Logic Error.";
                        return(ReturnCode.LogicError);
                    }
                }

                #endregion

                #region Find and Check/Open Input Files

                if (fileIn.FileType == FileType.ZipFile) // Input is a ZipFile
                {
                    RvDir zZipFileIn = fileIn.Parent;
                    if (zZipFileIn.FileType != FileType.Zip)
                    {
                        error = "Zip File Open but Source File is not a zip, Logic Error.";
                        return(ReturnCode.LogicError);
                    }

                    string fileNameIn = zZipFileIn.FullName;

                    sourceTrrntzip = (zZipFileIn.ZipStatus & ZipStatus.TrrntZip) == ZipStatus.TrrntZip;

                    //if (zZipFileIn.ZipFileType == RvZip.ZipType.Zip)
                    //{
                    zipFileIn = new ZipFile();

                    ZipReturn zr1;
                    if (fileIn.ZipFileHeaderPosition != null)
                    {
                        zr1 = zipFileIn.ZipFileOpen(fileNameIn, zZipFileIn.TimeStamp, false);
                    }
                    else
                    {
                        zr1 = zipFileIn.ZipFileOpen(fileNameIn, zZipFileIn.TimeStamp, true);
                    }
                    switch (zr1)
                    {
                    case ZipReturn.ZipGood:
                        break;

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

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

                    default:
                        error = "Error Open Zip" + zr1 + ", with File " + fileIn.DatFullName;
                        return(ReturnCode.FileSystemError);
                    }
                    if (fileIn.ZipFileHeaderPosition != null)
                    {
                        zipFileIn.ZipFileOpenReadStreamQuick((ulong)fileIn.ZipFileHeaderPosition, rawCopy, out readStream, out streamSize, out compressionMethod);
                    }
                    else
                    {
                        zipFileIn.ZipFileOpenReadStream(fileIn.ZipFileIndex, rawCopy, out readStream, out streamSize, out compressionMethod);
                    }
                }
                else // Input is a regular file
                {
                    string fileNameIn = fileIn.FullName;
                    if (!IO.File.Exists(fileNameIn))
                    {
                        error = "Rescan needed, File Changed :" + fileNameIn;
                        return(ReturnCode.RescanNeeded);
                    }
                    IO.FileInfo fileInInfo = new IO.FileInfo(fileNameIn);
                    if (fileInInfo.LastWriteTime != fileIn.TimeStamp)
                    {
                        error = "Rescan needed, File Changed :" + fileNameIn;
                        return(ReturnCode.RescanNeeded);
                    }
                    int errorCode = IO.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);
                    }
                }
                #endregion
            }
            else
            {
                sourceTrrntzip = true;
            }

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

            #region Find and Check/Open Output Files

            System.IO.Stream writeStream;
            if (fileOut.FileType == FileType.ZipFile)
            {
                // if ZipFileOut == null then we have not open the output zip yet so open it from writing.
                if (zipFileOut == null)
                {
                    if (IO.Path.GetFileName(zipFilenameOut) == "__RomVault.tmp")
                    {
                        if (IO.File.Exists(zipFilenameOut))
                        {
                            IO.File.Delete(zipFilenameOut);
                        }
                    }
                    else if (IO.File.Exists(zipFilenameOut))
                    {
                        error = "Rescan needed, File Changed :" + zipFilenameOut;
                        return(ReturnCode.RescanNeeded);
                    }

                    zipFileOut = new ZipFile();
                    ZipReturn zrf = zipFileOut.ZipFileCreate(zipFilenameOut);
                    if (zrf != ZipReturn.ZipGood)
                    {
                        error = "Error Opening Write Stream " + zrf;
                        return(ReturnCode.FileSystemError);
                    }
                }
                else
                {
                    if (zipFileOut.ZipOpen != ZipOpenType.OpenWrite)
                    {
                        error = "Output Zip File is not set to OpenWrite, Logic Error.";
                        return(ReturnCode.LogicError);
                    }

                    if (zipFileOut.ZipFilename != (new IO.FileInfo(zipFilenameOut).FullName))
                    {
                        error = "Output Zip file has changed name from " + zipFileOut.ZipFilename + " to " + zipFilenameOut + ". Logic Error";
                        return(ReturnCode.LogicError);
                    }
                }

                if (fileIn.Size == null)
                {
                    error = "Null File Size found in Fixing File :" + fileIn.FullName;
                    return(ReturnCode.LogicError);
                }
                ZipReturn zr = zipFileOut.ZipFileOpenWriteStream(rawCopy, sourceTrrntzip, fileOut.Name, (ulong)fileIn.Size, compressionMethod, out writeStream);
                if (zr != ZipReturn.ZipGood)
                {
                    error = "Error Opening Write Stream " + zr;
                    return(ReturnCode.FileSystemError);
                }
            }
            else
            {
                if (IO.File.Exists(zipFilenameOut) && fileOut.GotStatus != GotStatus.Corrupt)
                {
                    error = "Rescan needed, File Changed :" + zipFilenameOut;
                    return(ReturnCode.RescanNeeded);
                }
                int errorCode = IO.FileStream.OpenFileWrite(zipFilenameOut, out writeStream);
                if (errorCode != 0)
                {
                    error = new Win32Exception(errorCode).Message + ". " + zipFilenameOut;
                    return(ReturnCode.FileSystemError);
                }
            }
            #endregion

            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();
                            IO.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 && 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 (IO.File.Exists(tmpFilename))
                    //    IO.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)
            {
                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();
                IO.FileInfo fi = new IO.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
                        {
                            IO.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)
                        {
                            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
                        {
                            IO.File.Delete(zipFilenameOut);
                        }

                        return(ReturnCode.SourceCheckSumError);
                    }
                }
            }

            if (fileOut.FileType == FileType.ZipFile)
            {
                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
                {
                    IO.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
                    {
                        IO.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
                    {
                        IO.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);
        }
Example #3
0
        private static ReturnCode MoveZiptoCorrupt(RvDir fixZip)
        {
            string fixZipFullName = fixZip.FullName;
            if (!File.Exists(fixZipFullName))
            {
                _error = "File for move to corrupt not found " + fixZip.FullName;
                return ReturnCode.RescanNeeded;
            }
            FileInfo fi = new FileInfo(fixZipFullName);
            if (fi.LastWriteTime != fixZip.TimeStamp)
            {
                _error = "File for move to corrupt timestamp not correct " + fixZip.FullName;
                return ReturnCode.RescanNeeded;
            }

            string corruptDir = Path.Combine(Settings.ToSort(), "Corrupt");
            if (!Directory.Exists(corruptDir))
            {
                Directory.CreateDirectory(corruptDir);
            }

            RvDir toSort = (RvDir)DB.DirTree.Child(1);
            int indexcorrupt;
            RvDir corruptDirNew = new RvDir(FileType.Dir) { Name = "Corrupt", DatStatus = DatStatus.InToSort };
            int found = toSort.ChildNameSearch(corruptDirNew, out indexcorrupt);
            if (found != 0)
            {
                corruptDirNew.GotStatus = GotStatus.Got;
                indexcorrupt = toSort.ChildAdd(corruptDirNew);
            }

            string toSortFullName = Path.Combine(corruptDir, fixZip.Name + ".zip");
            string toSortFileName = fixZip.Name;
            int fileC = 0;
            while (File.Exists(toSortFullName))
            {
                fileC++;
                toSortFullName = Path.Combine(corruptDir, fixZip.Name + fileC + ".zip");
                toSortFileName = fixZip.Name + fileC;
            }

            if (!File.SetAttributes(fixZipFullName, FileAttributes.Normal))
            {
                int error = Error.GetLastError();
                ReportProgress(new bgwShowError(fixZipFullName, "Error Setting File Attributes to Normal. Before Moving To Corrupt. Code " + error));
            }


            File.Copy(fixZipFullName, toSortFullName);
            FileInfo toSortCorruptFile = new FileInfo(toSortFullName);

            RvDir toSortCorruptGame = new RvDir(FileType.Zip)
            {
                Name = toSortFileName,
                DatStatus = DatStatus.InToSort,
                TimeStamp = toSortCorruptFile.LastWriteTime,
                GotStatus = GotStatus.Corrupt
            };
            ((RvDir)toSort.Child(indexcorrupt)).ChildAdd(toSortCorruptGame);

            return ReturnCode.Good;
        }
Example #4
0
        private static ReturnCode FixZip(RvDir fixZip)
        {
            //Check for error status
            if (fixZip.DirStatus.HasUnknown())
                return ReturnCode.FindFixes; // Error

            bool needsTrrntzipped = fixZip.ZipStatus != ZipStatus.TrrntZip && fixZip.GotStatus == GotStatus.Got && fixZip.DatStatus == DatStatus.InDatCollect && (Settings.FixLevel == eFixLevel.TrrntZipLevel1 || Settings.FixLevel == eFixLevel.TrrntZipLevel2 || Settings.FixLevel == eFixLevel.TrrntZipLevel3);

            // file corrupt and not in tosort
            //      if file cannot be fully fixed copy to corrupt
            //      process zipfile

            if (fixZip.GotStatus == GotStatus.Corrupt && fixZip.DatStatus != DatStatus.InToSort)
            {
                ReturnCode movReturnCode = MoveZiptoCorrupt(fixZip);
                if (movReturnCode != ReturnCode.Good)
                    return movReturnCode;
            }

            // has fixable
            //      process zipfile

            else if (fixZip.DirStatus.HasFixable())
            {
                // do nothing here but continue on to process zip.
            }

            // need trrntzipped
            //      process zipfile

            else if (needsTrrntzipped)
            {
                // do nothing here but continue on to process zip.
            }


            // got empty zip that should be deleted
            //      process zipfile
            else if (fixZip.GotStatus == GotStatus.Got && fixZip.GotStatus != GotStatus.Corrupt && !fixZip.DirStatus.HasAnyFiles())
            {
                // do nothing here but continue on to process zip.
            }

            // else
            //      skip this zipfile
            else
            {
                // nothing can be done to return
                return ReturnCode.Good;
            }



            string fixZipFullName = fixZip.TreeFullName;

            if (!fixZip.DirStatus.HasFixable() && needsTrrntzipped)
                ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), "", 0, "TrrntZipping", "", "", ""));


            CheckCreateParent(fixZip.Parent);
            ReportError.LogOut("");
            ReportError.LogOut(fixZipFullName + " : " + fixZip.RepStatus);
            ReportError.LogOut("------------------------------------------------------------");
            Debug.WriteLine(fixZipFullName + " : " + fixZip.RepStatus);
            ReportError.LogOut("Zip File Status Before Fix:");
            for (int intLoop = 0; intLoop < fixZip.ChildCount; intLoop++)
                ReportError.LogOut((RvFile)fixZip.Child(intLoop));
            ReportError.LogOut("");

            ZipFile tempZipOut = null;

            ZipFile toSortCorruptOut = null;
            ZipFile toSortZipOut = null;

            RvDir toSortGame = null;
            RvDir toSortCorruptGame = null;

            ReturnCode returnCode;
            List<RvFile> fixZipTemp = new List<RvFile>();

            for (int iRom = 0; iRom < fixZip.ChildCount; iRom++)
            {
                RvFile zipFileFixing = new RvFile(FileType.ZipFile);
                fixZip.Child(iRom).CopyTo(zipFileFixing);

                if (iRom == fixZipTemp.Count)
                    fixZipTemp.Add(zipFileFixing);
                else
                    fixZipTemp[iRom] = zipFileFixing;

                ReportError.LogOut(zipFileFixing.RepStatus + " : " + fixZip.Child(iRom).FullName);

                switch (zipFileFixing.RepStatus)
                {
                    #region Nothing to copy
                    // any file we do not have or do not want in the destination zip
                    case RepStatus.Missing:
                    case RepStatus.NotCollected:
                    case RepStatus.Rename:
                    case RepStatus.Delete:
                        if (!
                              (
                            // got the file in the original zip but will be deleting it
                                (zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Got) ||
                                (zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Corrupt) ||
                                (zipFileFixing.DatStatus == DatStatus.InDatMerged && zipFileFixing.GotStatus == GotStatus.Got) ||
                                (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Got) ||
                                (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Corrupt) ||

                                // do not have this file and cannot fix it here
                                (zipFileFixing.DatStatus == DatStatus.InDatCollect && zipFileFixing.GotStatus == GotStatus.NotGot) ||
                                (zipFileFixing.DatStatus == DatStatus.InDatBad && zipFileFixing.GotStatus == GotStatus.NotGot) ||
                                (zipFileFixing.DatStatus == DatStatus.InDatMerged && zipFileFixing.GotStatus == GotStatus.NotGot)
                                )
                            )
                            ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus);

                        if (zipFileFixing.RepStatus == RepStatus.Delete)
                        {
                            returnCode = DoubleCheckDelete(zipFileFixing);
                            if (returnCode != ReturnCode.Good)
                                goto ZipOpenFailed;
                        }

                        zipFileFixing.GotStatus = GotStatus.NotGot;
                        break;
                    #endregion
                    #region Copy from Original to Destination
                    // any files we are just moving from the original zip to the destination zip
                    case RepStatus.Correct:
                    case RepStatus.InToSort:
                    case RepStatus.NeededForFix:
                    case RepStatus.Corrupt:
                        {
                            if (!
                                  (
                                    (zipFileFixing.DatStatus == DatStatus.InDatCollect && zipFileFixing.GotStatus == GotStatus.Got) ||
                                    (zipFileFixing.DatStatus == DatStatus.InDatMerged && zipFileFixing.GotStatus == GotStatus.Got) ||
                                    (zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Got) ||
                                    (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Got) ||
                                    (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Corrupt)
                                  )
                                )
                                ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus);

                            RvFile foundFile;

                            bool rawcopy = (zipFileFixing.RepStatus == RepStatus.InToSort) || (zipFileFixing.RepStatus == RepStatus.Corrupt);
                            // Correct      rawcopy=false
                            // NeededForFix rawcopy=false
                            // InToSort     rawcopy=true
                            // Corrupt      rawcopy=true
                            RepStatus originalStatus = zipFileFixing.RepStatus;

                            returnCode = FixFileCopy.CopyFile(
                                (RvFile)fixZip.Child(iRom),
                                ref tempZipOut,
                                Path.Combine(fixZip.Parent.FullName, "__RomVault.tmp"),
                                zipFileFixing, rawcopy,
                                out _error, out foundFile);

                            switch (returnCode)
                            {
                                case ReturnCode.Good: // correct reply to continue;
                                    if (originalStatus == RepStatus.NeededForFix)
                                        zipFileFixing.RepStatus = RepStatus.NeededForFix;
                                    break;
                                case ReturnCode.SourceCRCCheckSumError:
                                    {
                                        RvFile tFile = (RvFile)fixZip.Child(iRom);
                                        tFile.GotStatus = GotStatus.Corrupt;
                                        ReCheckFile(tFile);

                                        //decrease index so this file gets reprocessed
                                        iRom--;

                                        continue;
                                    }
                                case ReturnCode.SourceCheckSumError:
                                    {
                                        // Set the file in the zip that we thought we correctly had as missing
                                        RvFile tFile = (RvFile)fixZip.Child(iRom);
                                        if (tFile.FileRemove() == EFile.Delete)
                                        {
                                            _error = "Should not mark for delete as it is in a DAT";
                                            return ReturnCode.LogicError;
                                        }

                                        // Add in at the current location the incorrect file. (This file will be reprocessed and then at some point deleted.)
                                        fixZip.ChildAdd(foundFile, iRom);
                                        AddFoundFile(foundFile);

                                        ReCheckFile(tFile);

                                        //decrease index so this file gets reprocessed
                                        iRom--;

                                        continue;
                                    }
                                // not needed as source and destination are the same
                                // case ReturnCode.DestinationCheckSumError:  
                                default:
                                    _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error;
                                    goto ZipOpenFailed;
                            }
                        }
                        break;
                    #endregion

                    #region Case.CanBeFixed
                    case RepStatus.CanBeFixed:
                    case RepStatus.CorruptCanBeFixed:
                        {
                            if (!(zipFileFixing.DatStatus == DatStatus.InDatCollect && (zipFileFixing.GotStatus == GotStatus.NotGot || zipFileFixing.GotStatus == GotStatus.Corrupt)))
                                ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus);

                            ReportError.LogOut("Fixing File:");
                            ReportError.LogOut(zipFileFixing);

                            string strPath = fixZip.Parent.FullName;
                            string tempZipFilename = Path.Combine(strPath, "__RomVault.tmp");


                            if (DBHelper.IsZeroLengthFile(zipFileFixing))
                            {
                                RvFile fileIn = new RvFile(FileType.ZipFile) { Size = 0 };
                                RvFile foundFile;
                                returnCode = FixFileCopy.CopyFile(fileIn, ref tempZipOut, tempZipFilename, zipFileFixing, false, out _error, out foundFile);

                                switch (returnCode)
                                {
                                    case ReturnCode.Good: // correct reply to continue;
                                        break;
                                    default:
                                        _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error;
                                        goto ZipOpenFailed;
                                }
                                break;
                            }

#if NEWFINDFIX
                            List<RvFile> lstFixRomTable = new List<RvFile>();
                            List<RvFile> family = zipFileFixing.MyFamily.Family;
                            for (int iFind = 0; iFind < family.Count; iFind++)
                            {
                                if (family[iFind].GotStatus == GotStatus.Got && FindFixes.CheckIfMissingFileCanBeFixedByGotFile(zipFileFixing, family[iFind]))
                                    lstFixRomTable.Add(family[iFind]);
                            }
#else
                            List<RvFile> lstFixRomTable;
                            DBHelper.RomSearchFindFixes(zipFileFixing, _lstRomTableSortedCRCSize, out lstFixRomTable);
#endif

                            ReportError.LogOut("Found Files To use for Fixes:");
                            foreach (RvFile t in lstFixRomTable)
                                ReportError.LogOut(t);

                            if (lstFixRomTable.Count > 0)
                            {

                                string ts = lstFixRomTable[0].Parent.FullName;
                                string sourceDir;
                                string sourceFile;
                                if (lstFixRomTable[0].FileType == FileType.ZipFile)
                                {
                                    sourceDir = Path.GetDirectoryName(ts);
                                    sourceFile = Path.GetFileName(ts);
                                }
                                else
                                {
                                    sourceDir = ts;
                                    sourceFile = "";
                                }
                                ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), zipFileFixing.Name, zipFileFixing.Size, "<--", sourceDir, sourceFile, lstFixRomTable[0].Name));

                                RvFile foundFile;
                                returnCode = FixFileCopy.CopyFile(lstFixRomTable[0], ref tempZipOut, tempZipFilename, zipFileFixing, false, out _error, out foundFile);
                                switch (returnCode)
                                {
                                    case ReturnCode.Good: // correct reply so continue;
                                        break;

                                    case ReturnCode.SourceCRCCheckSumError:
                                        {
                                            ReportProgress(new bgwShowFixError("CRC Error"));
                                            // the file we used for fix turns out to be corrupt

                                            RvFile tFile = (RvFile)fixZip.Child(iRom);

                                            // mark the source file as Corrupt
                                            lstFixRomTable[0].GotStatus = GotStatus.Corrupt;

                                            // recheck for the fix
                                            ReCheckFile(tFile);

                                            // if the file being used from the fix is actually from this file then we have a big mess, and we are just going to
                                            // start over on this zip.
                                            if (lstFixRomTable[0].Parent == fixZip)
                                            {
                                                returnCode = ReturnCode.StartOver;
                                                goto ZipOpenFailed;
                                            }

                                            // add the fixing source zip into the processList so that it is also reprocessed and we just changed it.
                                            if (!_processList.Contains(lstFixRomTable[0].Parent))
                                                _processList.Add(lstFixRomTable[0].Parent);

                                            // and go back one and try again.
                                            iRom--;
                                            continue;
                                        }


                                    case ReturnCode.SourceCheckSumError:
                                        {
                                            ReportProgress(new bgwShowFixError("Failed"));
                                            // the file we used for fix turns out not not match its own DAT's correct MD5/SHA1
                                            // (Problem with logic here is that it could still match the file being fixed, but this case is not correctly handled)

                                            RvFile tFile = (RvFile)fixZip.Child(iRom);

                                            // remove the file we thought we correctly had (The file that we where trying to use for the fix)
                                            if (lstFixRomTable[0].FileRemove() == EFile.Delete)
                                            {
                                                _error = "Should not mark for delete as it is in a DAT";
                                                return ReturnCode.LogicError;
                                            }

                                            // possibly use a check here to see if the index of the found file is futher down the zip and so we can just contine
                                            // instead of restarting.

                                            // add in the actual file we found
                                            lstFixRomTable[0].Parent.ChildAdd(foundFile);
                                            AddFoundFile(foundFile);

                                            // recheck for the fix
                                            ReCheckFile(tFile);

                                            // if the file being used from the fix is actually from this file then we have a big mess, and we are just going to
                                            // start over on this zip.
                                            if (lstFixRomTable[0].Parent == fixZip)
                                            {
                                                returnCode = ReturnCode.StartOver;
                                                goto ZipOpenFailed;
                                            }

                                            // add the fixing source zip into the processList so that it is also reprocessed and we just changed it.
                                            if (!_processList.Contains(lstFixRomTable[0].Parent))
                                                _processList.Add(lstFixRomTable[0].Parent);

                                            // and go back one and try again.
                                            iRom--;
                                            continue;
                                        }
                                    case ReturnCode.DestinationCheckSumError:
                                        {
                                            ReportProgress(new bgwShowFixError("Failed"));
                                            // the file we used for fix turns out not to have the correct MD5/SHA1 
                                            RvFile tFile = (RvFile)fixZip.Child(iRom);

                                            // recheck for the fix
                                            ReCheckFile(tFile);

                                            // if the file being used from the fix is actually from this file then we have a big mess, and we are just going to
                                            // start over on this zip.
                                            // The need for this is that the file being pulled in from inside this zip will be marked as Rename
                                            // and so would then automatically be deleted, in the case this exception happens, this source file instead
                                            // should be set to move to tosort. 
                                            if (lstFixRomTable[0].Parent == fixZip)
                                            {
                                                returnCode = ReturnCode.StartOver;
                                                goto ZipOpenFailed;
                                            }

                                            // and go back one and try again.
                                            iRom--;
                                            continue;
                                        }
                                    default:
                                        //_error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + Environment.NewLine + _error;
                                        goto ZipOpenFailed;
                                }

                                //Check to see if the files used for fix, can now be set to delete
                                CheckReprocessClearList();

                                foreach (RvFile tFixRom in lstFixRomTable)
                                {
                                    if (tFixRom.RepStatus == RepStatus.NeededForFix)
                                    {
                                        tFixRom.RepStatus = RepStatus.Delete;
                                        ReportError.LogOut("Setting File Status to Delete:");
                                        ReportError.LogOut(tFixRom);
                                        CheckReprocess(tFixRom, true);
                                    }
                                }
                                CheckReprocessFinalCheck();

                                _fixed++;
                            }
                            else
                                // thought we could fix it, turns out we cannot
                                zipFileFixing.GotStatus = GotStatus.NotGot;
                        }
                        break;
                    #endregion
                    #region Case.MoveToSort
                    case RepStatus.MoveToSort:
                        {
                            if (!(zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Got))
                                ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus);

                            ReportError.LogOut("Moving File out to ToSort:");
                            ReportError.LogOut(zipFileFixing);
                            // move the rom out to the To Sort Directory

                            if (toSortGame == null)
                            {
                                string toSortFullName = Path.Combine(Settings.ToSort(), fixZip.Name + ".zip");
                                string toSortFileName = fixZip.Name;
                                int fileC = 0;
                                while (File.Exists(toSortFullName))
                                {
                                    fileC++;
                                    toSortFullName = Path.Combine(Settings.ToSort(), fixZip.Name + fileC + ".zip");
                                    toSortFileName = fixZip.Name + fileC;
                                }

                                toSortGame = new RvDir(FileType.Zip)
                                                 {
                                                     Name = toSortFileName,
                                                     DatStatus = DatStatus.InToSort,
                                                     GotStatus = GotStatus.Got
                                                 };
                            }

                            RvFile toSortRom = new RvFile(FileType.ZipFile)
                                                      {
                                                          Name = zipFileFixing.Name,
                                                          Size = zipFileFixing.Size,
                                                          CRC = zipFileFixing.CRC,
                                                          SHA1 = zipFileFixing.SHA1,
                                                          MD5 = zipFileFixing.MD5
                                                      };
                            toSortRom.SetStatus(DatStatus.InToSort, GotStatus.Got);
                            toSortRom.FileStatusSet(
                                FileStatus.SizeFromHeader | FileStatus.SizeVerified |
                                FileStatus.CRCFromHeader | FileStatus.CRCVerified |
                                FileStatus.SHA1FromHeader | FileStatus.SHA1Verified |
                                FileStatus.MD5FromHeader | FileStatus.MD5Verified
                                , zipFileFixing);

                            toSortGame.ChildAdd(toSortRom);

                            string destination = Path.Combine(Settings.ToSort(), toSortGame.Name + ".zip");
                            ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), zipFileFixing.Name, zipFileFixing.Size, "-->", "ToSort", Path.GetFileName(destination), toSortRom.Name));

                            RvFile foundFile;
                            returnCode = FixFileCopy.CopyFile((RvFile)fixZip.Child(iRom), ref toSortZipOut, destination, toSortRom, true, out _error, out foundFile);
                            switch (returnCode)
                            {
                                case ReturnCode.Good: // correct reply to continue;
                                    break;
                                //raw copying so Checksums are not checked
                                //case ReturnCode.SourceCRCCheckSumError: 
                                //case ReturnCode.SourceCheckSumError:
                                //case ReturnCode.DestinationCheckSumError: 
                                default:
                                    _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error;
                                    goto ZipOpenFailed;
                            }
                            zipFileFixing.GotStatus = GotStatus.NotGot; // Changes RepStatus to Deleted
                        }
                        break;
                    #endregion
                    #region Case.MoveToCorrupt
                    case RepStatus.MoveToCorrupt:
                        {
                            if (!((zipFileFixing.DatStatus == DatStatus.InDatCollect || zipFileFixing.DatStatus == DatStatus.NotInDat) && zipFileFixing.GotStatus == GotStatus.Corrupt))
                                ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus);

                            ReportError.LogOut("Moving File to Corrupt");
                            ReportError.LogOut(zipFileFixing);

                            string toSortFullName;
                            if (toSortCorruptGame == null)
                            {
                                string corruptDir = Path.Combine(Settings.ToSort(), "Corrupt");
                                if (!Directory.Exists(corruptDir))
                                {
                                    Directory.CreateDirectory(corruptDir);
                                }

                                toSortFullName = Path.Combine(corruptDir, fixZip.Name + ".zip");
                                string toSortFileName = fixZip.Name;
                                int fileC = 0;
                                while (File.Exists(toSortFullName))
                                {
                                    fileC++;
                                    toSortFullName = Path.Combine(corruptDir, fixZip.Name + fileC + ".zip");
                                    toSortFileName = fixZip.Name + fileC;
                                }

                                toSortCorruptGame = new RvDir(FileType.Zip)
                                                        {
                                                            Name = toSortFileName,
                                                            DatStatus = DatStatus.InToSort,
                                                            GotStatus = GotStatus.Got
                                                        };
                            }
                            else
                            {
                                string corruptDir = Path.Combine(Settings.ToSort(), "Corrupt");
                                toSortFullName = Path.Combine(corruptDir, toSortCorruptGame.Name + ".zip");
                            }

                            RvFile toSortCorruptRom = new RvFile(FileType.ZipFile)
                                                             {
                                                                 Name = zipFileFixing.Name,
                                                                 Size = zipFileFixing.Size,
                                                                 CRC = zipFileFixing.CRC
                                                             };
                            toSortCorruptRom.SetStatus(DatStatus.InToSort, GotStatus.Corrupt);
                            toSortCorruptGame.ChildAdd(toSortCorruptRom);

                            ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), zipFileFixing.Name, zipFileFixing.Size, "-->", "Corrupt", Path.GetFileName(toSortFullName), zipFileFixing.Name));

                            RvFile foundFile;
                            returnCode = FixFileCopy.CopyFile((RvFile)fixZip.Child(iRom), ref toSortCorruptOut, toSortFullName, toSortCorruptRom, true, out _error, out foundFile);
                            switch (returnCode)
                            {
                                case ReturnCode.Good: // correct reply to continue;
                                    break;

                                // doing a raw copy so not needed
                                // case ReturnCode.SourceCRCCheckSumError: 
                                // case ReturnCode.SourceCheckSumError:
                                // case ReturnCode.DestinationCheckSumError: 
                                default:
                                    _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error;
                                    goto ZipOpenFailed;
                            }
                            zipFileFixing.GotStatus = GotStatus.NotGot;
                        }
                        break;
                    #endregion
                    default:



                        ReportError.UnhandledExceptionHandler("Unknown file status found " + zipFileFixing.RepStatus + " while fixing file " + fixZip.Name + " Dat Status = " + zipFileFixing.DatStatus + " GotStatus " + zipFileFixing.GotStatus);
                        break;
                }
            }


            #region if ToSort Zip Made then close the zip and add this new zip to the Database
            if (toSortGame != null)
            {
                toSortZipOut.ZipFileClose();

                toSortGame.TimeStamp = toSortZipOut.TimeStamp;
                toSortGame.DatStatus = DatStatus.InToSort;
                toSortGame.GotStatus = GotStatus.Got;
                toSortGame.ZipStatus = toSortZipOut.ZipStatus;

                RvDir toSort = (RvDir)DB.DirTree.Child(1);
                toSort.ChildAdd(toSortGame);
            }
            #endregion

            #region if Corrupt Zip Made then close the zip and add this new zip to the Database
            if (toSortCorruptGame != null)
            {
                toSortCorruptOut.ZipFileClose();

                toSortCorruptGame.TimeStamp = toSortCorruptOut.TimeStamp;
                toSortCorruptGame.DatStatus = DatStatus.InToSort;
                toSortCorruptGame.GotStatus = GotStatus.Got;

                RvDir toSort = (RvDir)DB.DirTree.Child(1);
                int indexcorrupt;
                RvDir corruptDir = new RvDir(FileType.Dir) { Name = "Corrupt", DatStatus = DatStatus.InToSort };
                int found = toSort.ChildNameSearch(corruptDir, out indexcorrupt);
                if (found != 0)
                {
                    corruptDir.GotStatus = GotStatus.Got;
                    indexcorrupt = toSort.ChildAdd(corruptDir);
                }
                ((RvDir)toSort.Child(indexcorrupt)).ChildAdd(toSortCorruptGame);
            }
            #endregion



            #region Process original Zip
            string filename = fixZip.FullName;
            if (File.Exists(filename))
            {
                if (!File.SetAttributes(filename, FileAttributes.Normal))
                {
                    int error = Error.GetLastError();
                    ReportProgress(new bgwShowError(filename, "Error Setting File Attributes to Normal. Deleting Original Fix File. Code " + error));
                }
                try
                {
                    File.Delete(filename);
                }
                catch (Exception)
                {
                    int error = Error.GetLastError();
                    _error = "Error While trying to delete file " + filename + ". Code " + error;

                    if (tempZipOut != null && tempZipOut.ZipOpen != ZipOpenType.Closed)
                        tempZipOut.ZipFileClose();

                    return ReturnCode.RescanNeeded;
                }

            }
            #endregion

            bool checkDelete = false;
            #region process the temp Zip rename it to the original Zip
            if (tempZipOut != null && tempZipOut.ZipOpen != ZipOpenType.Closed)
            {
                string tempFilename = tempZipOut.ZipFilename;
                tempZipOut.ZipFileClose();

                if (tempZipOut.LocalFilesCount() > 0)
                {
                    // now rename the temp fix file to the correct filename
                    File.Move(tempFilename, filename);
                    FileInfo nFile = new FileInfo(filename);
                    RvDir tmpZip = new RvDir(FileType.Zip)
                                       {
                                           Name = Path.GetFileNameWithoutExtension(filename),
                                           TimeStamp = nFile.LastWriteTime
                                       };
                    tmpZip.SetStatus(fixZip.DatStatus, GotStatus.Got);

                    fixZip.FileAdd(tmpZip);
                    fixZip.ZipStatus = tempZipOut.ZipStatus;
                }
                else
                {
                    File.Delete(tempFilename);
                    checkDelete = true;
                }
            }
            else
                checkDelete = true;
            #endregion

            #region Now put the New Game Status information into the Database.
            int intLoopFix = 0;
            foreach (RvFile tmpZip in fixZipTemp)
            {
                tmpZip.CopyTo(fixZip.Child(intLoopFix));

                if (fixZip.Child(intLoopFix).RepStatus == RepStatus.Deleted)
                    if (fixZip.Child(intLoopFix).FileRemove() == EFile.Delete)
                    {
                        fixZip.ChildRemove(intLoopFix);
                        continue;
                    }

                intLoopFix++;
            }
            #endregion

            if (checkDelete)
                CheckDeleteObject(fixZip);

            ReportError.LogOut("");
            ReportError.LogOut("Zip File Status After Fix:");
            for (int intLoop = 0; intLoop < fixZip.ChildCount; intLoop++)
                ReportError.LogOut((RvFile)fixZip.Child(intLoop));
            ReportError.LogOut("");

            return ReturnCode.Good;


        ZipOpenFailed:
            if (tempZipOut != null) tempZipOut.ZipFileCloseFailed();
            if (toSortZipOut != null) toSortZipOut.ZipFileCloseFailed();
            if (toSortCorruptOut != null) toSortCorruptOut.ZipFileCloseFailed();
            return returnCode;

        }
Example #5
0
        private static ReturnCode DoubleCheckDelete(RvFile fileDeleting)
        {
            if (!Settings.DoubleCheckDelete)
                return ReturnCode.Good;


            ReportError.LogOut("Double Check deleting file ");
            ReportError.LogOut(fileDeleting);

            if (DBHelper.IsZeroLengthFile(fileDeleting))
                return ReturnCode.Good;

#if NEWFINDFIX
            List<RvFile> lstFixRomTable = new List<RvFile>();
            List<RvFile> family = fileDeleting.MyFamily.Family;
            for (int iFind = 0; iFind < family.Count; iFind++)
            {
                if (family[iFind].GotStatus == GotStatus.Got && FindFixes.CheckIfMissingFileCanBeFixedByGotFile(fileDeleting, family[iFind]))
                    lstFixRomTable.Add(family[iFind]);
            }
#else
            List<RvFile> lstFixRomTableCRCSize;
            List<RvFile> lstFixRomTableSHA1CHD;

            DBHelper.RomSearchFindFixes(fileDeleting, _lstRomTableSortedCRCSize, out lstFixRomTableCRCSize);
            DBHelper.RomSearchFindFixesSHA1CHD(fileDeleting, _lstRomTableSortedSHA1CHD, out lstFixRomTableSHA1CHD);

            List<RvFile> lstFixRomTable = new List<RvFile>();
            lstFixRomTable.AddRange(lstFixRomTableCRCSize);
            lstFixRomTable.AddRange(lstFixRomTableSHA1CHD);
#endif
            RvFile fileToCheck = null;
            int i = 0;
            while (i < lstFixRomTable.Count && fileToCheck == null)
            {

                switch (lstFixRomTable[i].RepStatus)
                {
                    case RepStatus.Delete:
                        i++;
                        break;
                    case RepStatus.Correct:
                    case RepStatus.InToSort:
                    case RepStatus.Rename:
                    case RepStatus.NeededForFix:
                    case RepStatus.MoveToSort:
                    case RepStatus.Ignore:
                        fileToCheck = lstFixRomTable[i];
                        break;
                    default:

                        ReportError.LogOut("Double Check Delete Error Unknown " + lstFixRomTable[i].FullName + " " + lstFixRomTable[i].RepStatus);
                        ReportError.UnhandledExceptionHandler("Unknown double check delete status " + lstFixRomTable[i].RepStatus);
                        break;
                }
            }
            //ReportError.LogOut("Found Files when double check deleting");
            //foreach (RvFile t in lstFixRomTable)
            //    ReportError.LogOut(t);

            if (fileToCheck == null)
            {
                ReportError.UnhandledExceptionHandler("Double Check Delete could not find the correct file. (" + fileDeleting.FullName + ")");
                //this line of code never gets called because the above line terminates the program.
                return ReturnCode.LogicError;
            }

            //if it is a file then 
            // check it exists and the filestamp matches
            //if it is a ZipFile then
            // check the parent zip exists and the filestamp matches

            switch (fileToCheck.FileType)
            {
                case FileType.ZipFile:
                    {
                        string fullPathCheckDelete = fileToCheck.Parent.FullName;
                        if (!File.Exists(fullPathCheckDelete))
                        {
                            _error = "Deleting " + fileDeleting.FullName + " Correct file not found. Resan for " + fullPathCheckDelete;
                            return ReturnCode.RescanNeeded;
                        }
                        FileInfo fi = new FileInfo(fullPathCheckDelete);
                        if (fi.LastWriteTime != fileToCheck.Parent.TimeStamp)
                        {
                            _error = "Deleting " + fileDeleting.FullName + " Correct file timestamp not found. Resan for " + fileToCheck.FullName;
                            return ReturnCode.RescanNeeded;
                        }
                        break;
                    }
                case FileType.File:
                    {
                        string fullPathCheckDelete = fileToCheck.FullName;
                        if (!File.Exists(fullPathCheckDelete))
                        {
                            _error = "Deleting " + fileDeleting.FullName + " Correct file not found. Resan for " + fullPathCheckDelete;
                            return ReturnCode.RescanNeeded;
                        }
                        FileInfo fi = new FileInfo(fullPathCheckDelete);
                        if (fi.LastWriteTime != fileToCheck.TimeStamp)
                        {
                            _error = "Deleting " + fileDeleting.FullName + " Correct file timestamp not found. Resan for " + fileToCheck.FullName;
                            return ReturnCode.RescanNeeded;
                        }
                        break;
                    }
                default:
                    ReportError.UnhandledExceptionHandler("Unknown double check delete status " + fileToCheck.RepStatus);
                    break;
            }


            return ReturnCode.Good;
        }