예제 #1
0
        public static bool IsZeroLengthFile(RvFile tFile)
        {
            if (tFile.MD5 != null)
            {
                if (!ArrByte.bCompare(tFile.MD5, ZeroByteMD5))
                {
                    return(false);
                }
            }

            if (tFile.SHA1 != null)
            {
                if (!ArrByte.bCompare(tFile.SHA1, ZeroByteSHA1))
                {
                    return(false);
                }
            }

            if (tFile.CRC != null)
            {
                if (!ArrByte.bCompare(tFile.CRC, ZeroByteCRC))
                {
                    return(false);
                }
            }

            return(tFile.Size == 0);
        }
예제 #2
0
        private static ReturnCode CheckInputAndOutputFile(RvFile fileIn, RvFile fileOut, out string error)
        {
            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);
                }
            }
            error = "";
            return(ReturnCode.Good);
        }
예제 #3
0
        private static void RomCheckCollect(RvRom tRom, bool merge)
        {
            if (merge)
            {
                if (string.IsNullOrEmpty(tRom.Merge))
                {
                    tRom.Merge = "(Auto Merged)";
                }

                tRom.PutInZip = false;
                return;
            }

            if (!string.IsNullOrEmpty(tRom.Merge))
            {
                tRom.Merge = "(No-Merge) " + tRom.Merge;
            }


            if (ArrByte.bCompare(tRom.CRC, new byte[] { 0, 0, 0, 0 }) && (tRom.Size == 0))
            {
                tRom.PutInZip = true;
                return;
            }


            tRom.PutInZip = true;
        }
예제 #4
0
        /*
         * In the mame Dat:
         * status="nodump" has a size but no CRC
         * status="baddump" has a size and crc
         */


        private static void RomCheckCollect(DatFile tRom, bool merge)
        {
            if (merge)
            {
                if (string.IsNullOrEmpty(tRom.Merge))
                {
                    tRom.Merge = "(Auto Merged)";
                }
                tRom.DatStatus = DatFileStatus.InDatMerged;
                return;
            }

            if (!string.IsNullOrEmpty(tRom.Merge))
            {
                tRom.Merge = "(No-Merge) " + tRom.Merge;
            }

            if (tRom.Status == "nodump")
            {
                tRom.DatStatus = DatFileStatus.InDatBad;
                return;
            }

            if (ArrByte.bCompare(tRom.CRC, new byte[] { 0, 0, 0, 0 }) && (tRom.Size == 0))
            {
                tRom.DatStatus = DatFileStatus.InDatCollect;
                return;
            }

            tRom.DatStatus = DatFileStatus.InDatCollect;
        }
        public static void DatSetMakeNonMergeSet(DatDir tDat)
        {
            // look for merged roms, check if a rom exists in a parent set where the Name,Size and CRC all match.

            for (int g = 0; g < tDat.ChildCount; g++)
            {
                DatDir mGame = (DatDir)tDat.Child(g);

                if (mGame.DGame == null)
                {
                    DatSetMakeNonMergeSet(mGame);
                }
                else
                {
                    DatGame dGame = mGame.DGame;

                    if (dGame?.device_ref == null)
                    {
                        continue;
                    }

                    List <DatDir> devices = new List <DatDir> {
                        mGame
                    };

                    foreach (string device in dGame.device_ref)
                    {
                        AddDevice(device, devices, tDat);
                    }
                    devices.RemoveAt(0);


                    foreach (DatDir device in devices)
                    {
                        for (int i = 0; i < device.ChildCount; i++)
                        {
                            DatFile df0      = (DatFile)device.Child(i);
                            bool    crcFound = false;
                            for (int j = 0; j < mGame.ChildCount; j++)
                            {
                                DatFile df1 = (DatFile)mGame.Child(j);
                                if (ArrByte.bCompare(df0.SHA1, df1.SHA1))
                                {
                                    crcFound = true;
                                    break;
                                }
                            }
                            if (!crcFound)
                            {
                                mGame.ChildAdd(device.Child(i));
                            }
                        }
                    }
                }
            }
        }
예제 #6
0
        /*
         * In the mame Dat:
         * status="nodump" has a size but no CRC
         * status="baddump" has a size and crc
         */


        private static void RomCheckCollect(RvFile tRom, bool merge)
        {
            if (merge)
            {
                if (string.IsNullOrEmpty(tRom.Merge))
                {
                    tRom.Merge = "(Auto Merged)";
                }

                tRom.DatStatus = DatStatus.InDatMerged;
                return;
            }

            if (!string.IsNullOrEmpty(tRom.Merge))
            {
                tRom.Merge = "(No-Merge) " + tRom.Merge;
            }

            if (tRom.Status == "nodump")
            {
                tRom.CRC       = null;
                tRom.DatStatus = DatStatus.InDatBad;
                return;
            }

            if (ArrByte.bCompare(tRom.CRC, new byte[] { 0, 0, 0, 0 }) && tRom.Size == 0)
            {
                tRom.DatStatus = DatStatus.InDatCollect;
                return;
            }

            /*
             * if (ArrByte.bCompare(tRom.CRC, new byte[] { 0, 0, 0, 0 }) || (tRom.CRC.Length != 8))
             * {
             *  tRom.CRC = null;
             *  tRom.DatStatus = DatStatus.InDatBad;
             *  return;
             * }
             */

            tRom.DatStatus = DatStatus.InDatCollect;
        }
예제 #7
0
        private static void DatSetRenameAndRemoveDups(RvDir tDat)
        {
            for (int g = 0; g < tDat.ChildCount; g++)
            {
                RvDir tDir = (RvDir)tDat.Child(g);
                if (tDir.Game == null)
                {
                    DatSetRenameAndRemoveDups(tDir);
                }
                else
                {
                    for (int r = 0; r < tDir.ChildCount - 1; r++)
                    {
                        RvFile f0 = (RvFile)tDir.Child(r);
                        RvFile f1 = (RvFile)tDir.Child(r + 1);

                        if (f0.Name != f1.Name)
                        {
                            continue;
                        }

                        if (f0.Size != f1.Size || !ArrByte.bCompare(f0.CRC, f1.CRC))
                        {
                            tDir.ChildRemove(r + 1);                            // remove F1
                            f1.Name = f1.Name + "_" + ArrByte.ToString(f1.CRC); // rename F1;
                            int pos = tDir.ChildAdd(f1);
                            if (pos < r)
                            {
                                r = pos;
                            }
                            // if this rename moved the File back up the list, start checking again from that file.
                        }
                        else
                        {
                            tDir.ChildRemove(r + 1);
                        }
                        r--;
                    }
                }
            }
        }
예제 #8
0
        private static bool CheckIfGotfileAndMatchingFileAreFullMatches(RvFile gotFile, RvFile matchingFile)
        {
            if (gotFile.FileStatusIs(FileStatus.SHA1Verified) && matchingFile.FileStatusIs(FileStatus.SHA1Verified) && !ArrByte.bCompare(gotFile.SHA1, matchingFile.SHA1))
            {
                return(false);
            }
            if (gotFile.FileStatusIs(FileStatus.MD5Verified) && matchingFile.FileStatusIs(FileStatus.MD5Verified) && !ArrByte.bCompare(gotFile.MD5, matchingFile.MD5))
            {
                return(false);
            }

            return(true);
        }
예제 #9
0
        public static void RemoveDupes(DatDir tDat, bool testName = true, bool testWithMergeName = false)
        {
            for (int g = 0; g < tDat.ChildCount; g++)
            {
                DatDir mGame = (DatDir)tDat.Child(g);

                if (mGame.DGame == null)
                {
                    RemoveDupes(mGame, testName);
                }
                else
                {
                    bool found = true;
                    while (found)
                    {
                        found = false;


                        for (int r = 0; r < mGame.ChildCount; r++)
                        {
                            DatFile df0 = (DatFile)mGame.Child(r);
                            for (int t = r + 1; t < mGame.ChildCount; t++)
                            {
                                DatFile df1 = (DatFile)mGame.Child(t);

                                if (testName && df0.Name != df1.Name)
                                {
                                    continue;
                                }
                                bool hasCRC = df0.CRC != null && df1.CRC != null;
                                if (hasCRC && !ArrByte.bCompare(df0.CRC, df1.CRC))
                                {
                                    continue;
                                }
                                bool hasSHA1 = df0.SHA1 != null && df1.SHA1 != null;
                                if (hasSHA1 && !ArrByte.bCompare(df0.SHA1, df1.SHA1))
                                {
                                    continue;
                                }
                                bool hasMD5 = df0.MD5 != null && df1.MD5 != null;
                                if (hasMD5 && !ArrByte.bCompare(df0.MD5, df1.MD5))
                                {
                                    continue;
                                }
                                if (!hasCRC && !hasSHA1 && !hasMD5)
                                {
                                    continue;
                                }

                                found = true;

                                string name0 = df0.Name;
                                string name1 = df1.Name;

                                bool nS0 = name0.Contains("\\");
                                bool ns1 = name1.Contains("\\");

                                if (nS0 && !ns1)
                                {
                                    mGame.ChildRemove(df0);
                                }
                                else if (!nS0 && ns1)
                                {
                                    mGame.ChildRemove(df1);
                                }
                                else if (nS0 && ns1)
                                {
                                    string s0 = name0.Substring(0, name0.IndexOf("\\", StringComparison.Ordinal));
                                    string s1 = name1.Substring(0, name1.IndexOf("\\", StringComparison.Ordinal));
                                    if (s0 != s1)
                                    {
                                        mGame.ChildRemove(df1);
                                    }
                                    else
                                    {
                                        int res = AlphanumComparatorFast.Compare(name0, name1);
                                        mGame.ChildRemove(res >= 0 ? df0 : df1);
                                    }
                                }
                                else if ((name0 == name1) || (testWithMergeName && (name0 == df1.Merge)))
                                {
                                    mGame.ChildRemove(df1);
                                }
                                else
                                {
                                    found = false;
                                    continue;
                                }
                                r = mGame.ChildCount;
                                t = mGame.ChildCount;
                            }
                        }
                    }
                }
            }
        }
예제 #10
0
        public static void DatSetMakeSplitSet(DatDir tDat)
        {
            // look for merged roms, check if a rom exists in a parent set where the Name,Size and CRC all match.

            for (int g = 0; g < tDat.ChildCount; g++)
            {
                DatDir mGame = (DatDir)tDat.Child(g);

                if (mGame.DGame == null)
                {
                    DatSetMakeSplitSet(mGame);
                }
                else
                {
                    // find all parents of this game
                    List <DatDir> lstParentGames = new List <DatDir>();
                    DatFindParentSets.FindParentSet(mGame, tDat, true, ref lstParentGames);

                    // if no parents are found then just set all children as kept
                    if (lstParentGames.Count == 0)
                    {
                        for (int r = 0; r < mGame.ChildCount; r++)
                        {
                            if (mGame.Child(r) is DatFile dfGame)
                            {
                                RomCheckCollect(dfGame, false);
                            }
                        }
                    }
                    else
                    {
                        for (int r = 0; r < mGame.ChildCount; r++)
                        {
                            if (((DatFile)mGame.Child(r)).Status == "nodump")
                            {
                                RomCheckCollect((DatFile)mGame.Child(r), false);
                                continue;
                            }

                            bool found = false;
                            foreach (DatDir romofGame in lstParentGames)
                            {
                                for (int r1 = 0; r1 < romofGame.ChildCount; r1++)
                                {
                                    // size/checksum compare, so name does not need to match
                                    // if (!string.Equals(mGame.Child(r).Name, romofGame.Child(r1).Name, StringComparison.OrdinalIgnoreCase))
                                    // {
                                    //     continue;
                                    // }

                                    ulong?size0 = ((DatFile)mGame.Child(r)).Size;
                                    ulong?size1 = ((DatFile)romofGame.Child(r1)).Size;
                                    if ((size0 != null) && (size1 != null) && (size0 != size1))
                                    {
                                        continue;
                                    }

                                    byte[] crc0 = ((DatFile)mGame.Child(r)).CRC;
                                    byte[] crc1 = ((DatFile)romofGame.Child(r1)).CRC;
                                    if ((crc0 != null) && (crc1 != null) && !ArrByte.bCompare(crc0, crc1))
                                    {
                                        continue;
                                    }

                                    byte[] sha0 = ((DatFile)mGame.Child(r)).SHA1;
                                    byte[] sha1 = ((DatFile)romofGame.Child(r1)).SHA1;
                                    if ((sha0 != null) && (sha1 != null) && !ArrByte.bCompare(sha0, sha1))
                                    {
                                        continue;
                                    }

                                    byte[] md50 = ((DatFile)mGame.Child(r)).MD5;
                                    byte[] md51 = ((DatFile)romofGame.Child(r1)).MD5;
                                    if ((md50 != null) && (md51 != null) && !ArrByte.bCompare(md50, md51))
                                    {
                                        continue;
                                    }

                                    if (((DatFile)mGame.Child(r)).isDisk != ((DatFile)romofGame.Child(r1)).isDisk)
                                    {
                                        continue;
                                    }

                                    // not needed as we are now checking for nodumps at the top of this code
                                    // don't merge if only one of the ROM is nodump
                                    //if (((DatFile)romofGame.Child(r1)).Status == "nodump" != (((DatFile)mGame.Child(r)).Status == "nodump"))
                                    //{
                                    //    continue;
                                    //}

                                    found = true;
                                    break;
                                }
                                if (found)
                                {
                                    break;
                                }
                            }

                            RomCheckCollect((DatFile)mGame.Child(r), found);
                        }
                    }
                }
            }
        }
예제 #11
0
        private static void DatSetCheckCollect(RvDat tDat)
        {
            if (tDat.Games == null)
            {
                return;
            }

            // now look for merged roms.
            // check if a rom exists in a parent set where the Name,Size and CRC all match.

            for (int g = 0; g < tDat.Games.Count; g++)
            {
                RvGame        mGame          = tDat.Games[g];
                List <RvGame> lstParentGames = new List <RvGame>();
                FindParentSet(mGame, tDat, ref lstParentGames);

                if ((lstParentGames.Count == 0) || (mGame.IsBios?.ToLower() == "yes"))
                {
                    for (int r = 0; r < mGame.RomCount; r++)
                    {
                        RomCheckCollect(mGame.Roms[r], false);
                    }
                }
                else
                {
                    for (int r = 0; r < mGame.RomCount; r++)
                    {
                        bool found = false;
                        foreach (RvGame romofGame in lstParentGames)
                        {
                            for (int r1 = 0; r1 < romofGame.RomCount; r1++)
                            {
                                if (mGame.Roms[r].Name.ToLower() != romofGame.Roms[r1].Name.ToLower())
                                {
                                    continue;
                                }

                                ulong?Size0 = mGame.Roms[r].Size;
                                ulong?Size1 = romofGame.Roms[r1].Size;
                                if ((Size0 != null) && (Size1 != null) && (Size0 != Size1))
                                {
                                    continue;
                                }

                                byte[] CRC0 = mGame.Roms[r].CRC;
                                byte[] CRC1 = romofGame.Roms[r1].CRC;
                                if ((CRC0 != null) && (CRC1 != null) && !ArrByte.bCompare(CRC0, CRC1))
                                {
                                    continue;
                                }

                                byte[] SHA0 = mGame.Roms[r].SHA1;
                                byte[] SHA1 = romofGame.Roms[r1].SHA1;
                                if ((SHA0 != null) && (SHA1 != null) && !ArrByte.bCompare(SHA0, SHA1))
                                {
                                    continue;
                                }

                                byte[] MD50 = mGame.Roms[r].MD5;
                                byte[] MD51 = romofGame.Roms[r1].MD5;
                                if ((MD50 != null) && (MD51 != null) && !ArrByte.bCompare(MD50, MD51))
                                {
                                    continue;
                                }

                                // don't merge if only one of the ROM is nodump
                                if (romofGame.Roms[r1].Status == "nodump" != (mGame.Roms[r].Status == "nodump"))
                                {
                                    continue;
                                }

                                found = true;
                                break;
                            }
                            if (found)
                            {
                                break;
                            }
                        }
                        RomCheckCollect(mGame.Roms[r], found);
                    }
                }
            }
        }
예제 #12
0
        public static void DatSetMakeMergeSet(DatDir tDat, bool mergeWithGameName = true)
        {
            // look for merged roms, check if a rom exists in a parent set where the Name,Size and CRC all match.

            for (int g = 0; g < tDat.ChildCount; g++)
            {
                DatDir mGame = (DatDir)tDat.Child(g);

                if (mGame.DGame == null)
                {
                    DatSetMakeMergeSet(mGame, mergeWithGameName);
                    continue;
                }

                // find all parents of this game
                List <DatDir> lstParentGames = new List <DatDir>();
                DatFindParentSets.FindParentSet(mGame, tDat, true, ref lstParentGames);

                // if no parents are found then just set all children as kept
                if (lstParentGames.Count == 0)
                {
                    for (int r = 0; r < mGame.ChildCount; r++)
                    {
                        if (mGame.Child(r) is DatFile dfGame)
                        {
                            RomCheckCollect(dfGame, false);
                        }
                    }

                    continue;
                }

                List <DatDir> pGames = new List <DatDir>();
                List <DatDir> pBios  = new List <DatDir>();
                foreach (DatDir dd in lstParentGames)
                {
                    if (dd.DGame.IsBios?.ToLower() == "yes")
                    {
                        pBios.Add(dd);
                    }
                    else
                    {
                        pGames.Add(dd);
                    }
                }

                DatBase[]      mGameTest = mGame.ToArray();
                List <DatBase> mGameKeep = new List <DatBase>();

                foreach (DatBase tGame in mGameTest)
                {
                    if (((DatFile)tGame).Status == "nodump")
                    {
                        mGame.ChildAdd(tGame);
                        continue;
                    }

                    // first remove any file that is in a parent BIOS set
                    bool found = false;
                    foreach (DatDir romofGame in pBios)
                    {
                        for (int r1 = 0; r1 < romofGame.ChildCount; r1++)
                        {
                            // size/checksum compare, so name does not need to match
                            // if (!string.Equals(mGame[r].Name, romofGame.Child(r1).Name, StringComparison.OrdinalIgnoreCase))
                            // {
                            //     continue;
                            // }

                            ulong?size0 = ((DatFile)tGame).Size;
                            ulong?size1 = ((DatFile)romofGame.Child(r1)).Size;
                            if ((size0 != null) && (size1 != null) && (size0 != size1))
                            {
                                continue;
                            }

                            byte[] crc0 = ((DatFile)tGame).CRC;
                            byte[] crc1 = ((DatFile)romofGame.Child(r1)).CRC;
                            if ((crc0 != null) && (crc1 != null) && !ArrByte.bCompare(crc0, crc1))
                            {
                                continue;
                            }

                            byte[] sha0 = ((DatFile)tGame).SHA1;
                            byte[] sha1 = ((DatFile)romofGame.Child(r1)).SHA1;
                            if ((sha0 != null) && (sha1 != null) && !ArrByte.bCompare(sha0, sha1))
                            {
                                continue;
                            }

                            byte[] md50 = ((DatFile)tGame).MD5;
                            byte[] md51 = ((DatFile)romofGame.Child(r1)).MD5;
                            if ((md50 != null) && (md51 != null) && !ArrByte.bCompare(md50, md51))
                            {
                                continue;
                            }

                            if (((DatFile)tGame).isDisk != ((DatFile)romofGame.Child(r1)).isDisk)
                            {
                                continue;
                            }

                            // not needed as we are now checking for nodumps at the top of this code
                            // don't merge if only one of the ROM is nodump
                            //if (((DatFile)romofGame.Child(r1)).Status == "nodump" != (((DatFile)mGame[r]).Status == "nodump"))
                            //{
                            //    continue;
                            //}

                            found = true;
                            break;
                        }

                        if (found)
                        {
                            break;
                        }
                    }

                    if (!found)
                    {
                        mGameKeep.Add(tGame);
                    }
                }

                mGame.ChildrenClear();

                if (pGames.Count == 0)
                {
                    foreach (DatBase tGame in mGameKeep)
                    {
                        mGame.ChildAdd(tGame);
                    }

                    continue;
                }

                DatDir romOfTopParent = pGames[pGames.Count - 1];

                foreach (DatBase tGame in mGameKeep)
                {
                    if (mergeWithGameName && !((DatFile)tGame).isDisk)
                    {
                        tGame.Name = mGame.Name + "\\" + tGame.Name;
                    }
                    romOfTopParent.ChildAdd(tGame);
                }
            }
        }
예제 #13
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);
        }
예제 #14
0
        // find fix files, if the gotFile has been fully scanned check the SHA1/MD5, if not then just return true as the CRC/Size is all we have to go on.
        // this means that if the gotfile has not been fully scanned this will return true even with the source and destination SHA1/MD5 possibly different.
        public static bool CheckIfMissingFileCanBeFixedByGotFile(RvFile missingFile, RvFile gotFile)
        {
            if (missingFile.FileStatusIs(FileStatus.SHA1FromDAT) && gotFile.FileStatusIs(FileStatus.SHA1Verified) && !ArrByte.bCompare(missingFile.SHA1, gotFile.SHA1))
            {
                return(false);
            }
            if (missingFile.FileStatusIs(FileStatus.MD5FromDAT) && gotFile.FileStatusIs(FileStatus.MD5Verified) && !ArrByte.bCompare(missingFile.MD5, gotFile.MD5))
            {
                return(false);
            }

            return(true);
        }
예제 #15
0
        public static void ScanFiles(object sender, DoWorkEventArgs e)
        {
            try
            {
                _bgw = sender as BackgroundWorker;
                if (_bgw == null)
                {
                    return;
                }

                Program.SyncCont = e.Argument as SynchronizationContext;
                if (Program.SyncCont == null)
                {
                    _bgw = null;
                    return;
                }

                _bgw.ReportProgress(0, new bgwText("Clearing DB Status"));
                RepairStatus.ReportStatusReset(DB.DirTree);

                List <RvFile> lstRomTableSortedCRCSize;
                List <RvFile> lstRomTableSortedSHA1CHD;

                _bgw.ReportProgress(0, new bgwText("Loading Rom List"));
                DBHelper.GetSelectedFilesSortCRCSize(out lstRomTableSortedCRCSize);
                DBHelper.GetSelectedFilesSortSHA1CHD(out lstRomTableSortedSHA1CHD);

                _bgw.ReportProgress(0, new bgwText("Scanning for Fixes"));
                _bgw.ReportProgress(0, new bgwSetRange(lstRomTableSortedCRCSize.Count));

                int romIndex0 = 0;
                int romIndex1 = 1;
                while (romIndex1 < lstRomTableSortedCRCSize.Count)
                {
                    if (romIndex1 % 100 == 0)
                    {
                        _bgw.ReportProgress(romIndex1);
                    }

                    if (!ArrByte.bCompare(lstRomTableSortedCRCSize[romIndex0].CRC, lstRomTableSortedCRCSize[romIndex1].CRC) || (lstRomTableSortedCRCSize[romIndex0].Size != lstRomTableSortedCRCSize[romIndex1].Size))
                    {
                        ListCheck(lstRomTableSortedCRCSize, romIndex0, romIndex1 - romIndex0);
                        romIndex0 = romIndex1;
                    }
                    romIndex1++;
                }

                ListCheck(lstRomTableSortedCRCSize, romIndex0, romIndex1 - romIndex0);


                _bgw.ReportProgress(0, new bgwSetRange(lstRomTableSortedSHA1CHD.Count));

                romIndex0 = 0;
                romIndex1 = 1;
                while (romIndex1 < lstRomTableSortedSHA1CHD.Count)
                {
                    if (romIndex1 % 100 == 0)
                    {
                        _bgw.ReportProgress(romIndex1);
                    }

                    if (!ArrByte.bCompare(lstRomTableSortedSHA1CHD[romIndex0].SHA1CHD, lstRomTableSortedSHA1CHD[romIndex1].SHA1CHD))
                    {
                        ListCheckSHA1CHD(lstRomTableSortedSHA1CHD, romIndex0, romIndex1 - romIndex0);
                        romIndex0 = romIndex1;
                    }
                    romIndex1++;
                }

                ListCheckSHA1CHD(lstRomTableSortedSHA1CHD, romIndex0, romIndex1 - romIndex0);


                _bgw             = null;
                Program.SyncCont = null;
            }
            catch (Exception exc)
            {
                ReportError.UnhandledExceptionHandler(exc);

                if (_bgw != null)
                {
                    _bgw.ReportProgress(0, new bgwText("Updating Cache"));
                }
                DB.Write();
                if (_bgw != null)
                {
                    _bgw.ReportProgress(0, new bgwText("Complete"));
                }

                _bgw             = null;
                Program.SyncCont = null;
            }
        }
예제 #16
0
        private static void DatSetCheckCollect(RvDir tDat)
        {
            // now look for merged roms.
            // check if a rom exists in a parent set where the Name,Size and CRC all match.

            for (int g = 0; g < tDat.ChildCount; g++)
            {
                RvDir mGame = (RvDir)tDat.Child(g);

                if (mGame.Game == null)
                {
                    DatSetCheckCollect(mGame);
                }
                else
                {
                    List <RvDir> lstParentGames = new List <RvDir>();
                    FindParentSet(mGame, tDat, ref lstParentGames);

                    if (lstParentGames.Count == 0)
                    {
                        for (int r = 0; r < mGame.ChildCount; r++)
                        {
                            RomCheckCollect((RvFile)mGame.Child(r), false);
                        }
                    }
                    else
                    {
                        for (int r = 0; r < mGame.ChildCount; r++)
                        {
                            bool found = false;
                            foreach (RvDir romofGame in lstParentGames)
                            {
                                for (int r1 = 0; r1 < romofGame.ChildCount; r1++)
                                {
                                    if (mGame.Child(r).Name != romofGame.Child(r1).Name)
                                    {
                                        continue;
                                    }

                                    ulong?Size0 = ((RvFile)mGame.Child(r)).Size;
                                    ulong?Size1 = ((RvFile)romofGame.Child(r1)).Size;
                                    if (Size0 != null && Size1 != null && Size0 != Size1)
                                    {
                                        continue;
                                    }

                                    byte[] CRC0 = ((RvFile)mGame.Child(r)).CRC;
                                    byte[] CRC1 = ((RvFile)romofGame.Child(r1)).CRC;
                                    if (CRC0 != null && CRC1 != null && !ArrByte.bCompare(CRC0, CRC1))
                                    {
                                        continue;
                                    }

                                    byte[] SHA0 = ((RvFile)mGame.Child(r)).SHA1;
                                    byte[] SHA1 = ((RvFile)romofGame.Child(r1)).SHA1;
                                    if (SHA0 != null && SHA1 != null && !ArrByte.bCompare(SHA0, SHA1))
                                    {
                                        continue;
                                    }

                                    byte[] MD50 = ((RvFile)mGame.Child(r)).MD5;
                                    byte[] MD51 = ((RvFile)romofGame.Child(r1)).MD5;
                                    if (MD50 != null && MD51 != null && !ArrByte.bCompare(MD50, MD51))
                                    {
                                        continue;
                                    }

                                    byte[] chdSHA0 = ((RvFile)mGame.Child(r)).SHA1CHD;
                                    byte[] chdSHA1 = ((RvFile)romofGame.Child(r1)).SHA1CHD;
                                    if (chdSHA0 != null && chdSHA1 != null && !ArrByte.bCompare(chdSHA0, chdSHA1))
                                    {
                                        continue;
                                    }

                                    byte[] chdMD50 = ((RvFile)mGame.Child(r)).MD5CHD;
                                    byte[] chdMD51 = ((RvFile)romofGame.Child(r1)).MD5CHD;
                                    if (chdMD50 != null && chdMD51 != null && !ArrByte.bCompare(chdMD50, chdMD51))
                                    {
                                        continue;
                                    }


                                    found = true;
                                    break;
                                }
                                if (found)
                                {
                                    break;
                                }
                            }
                            RomCheckCollect((RvFile)mGame.Child(r), found);
                        }
                    }
                }
            }
        }
예제 #17
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);
        }
예제 #18
0
        public static void RemoveDupes(DatDir tDat)
        {
            for (int g = 0; g < tDat.ChildCount; g++)
            {
                DatDir mGame = (DatDir)tDat.Child(g);

                if (mGame.DGame == null)
                {
                    RemoveDupes(mGame);
                }
                else
                {
                    bool found = true;
                    while (found)
                    {
                        found = false;


                        for (int r = 0; r < mGame.ChildCount; r++)
                        {
                            DatFile df0 = (DatFile)mGame.Child(r);
                            for (int t = r + 1; t < mGame.ChildCount; t++)
                            {
                                DatFile df1 = (DatFile)mGame.Child(t);

                                if (!ArrByte.bCompare(df0.CRC, df1.CRC))
                                {
                                    continue;
                                }

                                found = true;

                                string name0 = df0.Name;
                                string name1 = df1.Name;

                                bool nS0 = name0.Contains("\\");
                                bool ns1 = name1.Contains("\\");

                                if (nS0 && !ns1)
                                {
                                    mGame.ChildRemove(df0);
                                }
                                else if (!nS0 && ns1)
                                {
                                    mGame.ChildRemove(df1);
                                }
                                else if (nS0 && ns1)
                                {
                                    string s0 = name0.Substring(0, name0.IndexOf("\\", StringComparison.Ordinal));
                                    string s1 = name1.Substring(0, name1.IndexOf("\\", StringComparison.Ordinal));
                                    if (s0 != s1)
                                    {
                                        mGame.ChildRemove(df1);
                                    }
                                    else
                                    {
                                        int res = AlphanumComparatorFast.Compare(name0, name1);
                                        mGame.ChildRemove(res >= 0 ? df0 : df1);
                                    }
                                }
                                else if (name0 == name1)
                                {
                                    mGame.ChildRemove(df1);
                                }
                                else
                                {
                                    found = false;
                                    continue;
                                }
                                r = mGame.ChildCount;
                                t = mGame.ChildCount;
                            }
                        }
                    }
                }
            }
        }