Beispiel #1
0
        private void CHDOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
        {
            // Collect the process command output.
            if (string.IsNullOrEmpty(outLine.Data))
            {
                return;
            }

            string sOut = outLine.Data;

            //ReportError.LogOut("CHDOutput: " + _outputLineCount + " : " + sOut);
            switch (_outputLineCount)
            {
            case 0:
                if (!Regex.IsMatch(sOut, @"^chdman - MAME Compressed Hunks of Data \(CHD\) manager ([0-9\.]+) \(.*\)"))
                {
                    _result     = "Incorrect startup of CHDMan :" + sOut;
                    _resultType = hdErr.HDERR_CANT_VERIFY;
                }
                break;

            case 1:
                if (sOut != "Raw SHA1 verification successful!")
                {
                    _result     = "Raw SHA1 check failed :" + sOut;
                    _resultType = hdErr.HDERR_DECOMPRESSION_ERROR;
                }
                break;

            case 2:
                if (sOut != "Overall SHA1 verification successful!")
                {
                    _result     = "Overall SHA1 check failed :" + sOut;
                    _resultType = hdErr.HDERR_DECOMPRESSION_ERROR;
                }
                break;

            default:
                _result     = "Unexpected output from chdman :" + sOut;
                _resultType = hdErr.HDERR_DECOMPRESSION_ERROR;
                break;
            }

            _outputLineCount++;
        }
Beispiel #2
0
        internal hdErr ChdCheck(Message progress, hard_disk_info hdi, out string result)
        {

            try
            {

                _progress = progress;
                _result = "";
                _resultType = hard_disk_verify(hdi, progress);

                result = _result;
                return _resultType;
            }
            catch (Exception e)
            {
                result = e.ToString();
                return hdErr.HDERR_DECOMPRESSION_ERROR;
            }
        }
 private void MainLoop()
 {
     while (true)
     {
         _waitEvent.WaitOne();
         if (_finished)
         {
             break;
         }
         try
         {
             SizeRead = read_block_into_cache(_block, _buffer, ref _crc);
         }
         catch (Exception)
         {
             errorState = true;
         }
         _outEvent.Set();
     }
 }
Beispiel #4
0
        public static void FromAFile(RvFile file, string directory, EScanLevel eScanLevel, ThreadWorker bgw, ref bool fileErrorAbort)
        {
            _bgw = bgw;
            string    filename   = Path.Combine(directory, string.IsNullOrWhiteSpace(file.FileName) ? file.Name : file.FileName);
            ICompress fileToScan = new Compress.File.File();
            ZipReturn zr         = fileToScan.ZipFileOpen(filename, file.FileModTimeStamp);

            if (zr == ZipReturn.ZipFileLocked)
            {
                file.GotStatus = GotStatus.FileLocked;
                return;
            }

            if (zr != ZipReturn.ZipGood)
            {
                ReportError.Show("File: " + filename + " Error: " + zr + ". Scan Aborted.");
                file.GotStatus = GotStatus.FileLocked;
                fileErrorAbort = true;
                return;
            }

            if (_fs == null)
            {
                _fs = new FileScan();
            }
            List <FileScan.FileResults> fr = _fs.Scan(fileToScan, true, eScanLevel == EScanLevel.Level2 || eScanLevel == EScanLevel.Level3);

            file.HeaderFileType = fr[0].HeaderFileType;
            file.Size           = fr[0].Size;
            file.CRC            = fr[0].CRC;
            file.SHA1           = fr[0].SHA1;
            file.MD5            = fr[0].MD5;
            file.AltSize        = fr[0].AltSize;
            file.AltCRC         = fr[0].AltCRC;
            file.AltSHA1        = fr[0].AltSHA1;
            file.AltMD5         = fr[0].AltMD5;


            file.FileStatusSet(
                FileStatus.SizeVerified |
                (file.HeaderFileType != HeaderFileType.Nothing ? FileStatus.HeaderFileTypeFromHeader : 0) |
                (file.CRC != null ? FileStatus.CRCVerified : 0) |
                (file.SHA1 != null ? FileStatus.SHA1Verified : 0) |
                (file.MD5 != null ? FileStatus.MD5Verified : 0) |
                (file.AltSize != null ? FileStatus.AltSizeVerified : 0) |
                (file.AltCRC != null ? FileStatus.AltCRCVerified : 0) |
                (file.AltSHA1 != null ? FileStatus.AltSHA1Verified : 0) |
                (file.AltMD5 != null ? FileStatus.AltMD5Verified : 0)
                );

            if (fr[0].HeaderFileType == HeaderFileType.CHD)
            {
                bool deepCheck = (eScanLevel == EScanLevel.Level2 || eScanLevel == EScanLevel.Level3);
                CHD.fileProcess     = FileProcess;
                CHD.fileProgress    = FileProgress;
                CHD.fileSystemError = FileSystemError;
                CHD.fileError       = FileError;
                CHD.generalError    = GeneralError;
                hdErr result = CHD.CheckFile(file.Name, directory, Settings.isLinux, ref deepCheck, out uint?chdVersion, out byte[] chdSHA1, out byte[] chdMD5, ref fileErrorAbort);
                switch (result)
                {
                case hdErr.HDERR_NONE:
                    file.CHDVersion = chdVersion;
                    if (chdSHA1 != null)
                    {
                        file.AltSHA1 = chdSHA1;
                        file.FileStatusSet(FileStatus.AltSHA1FromHeader);
                        if (deepCheck)
                        {
                            file.FileStatusSet(FileStatus.AltSHA1Verified);
                        }
                    }

                    if (chdMD5 != null)
                    {
                        file.AltMD5 = chdMD5;
                        file.FileStatusSet(FileStatus.AltMD5FromHeader);
                        if (deepCheck)
                        {
                            file.FileStatusSet(FileStatus.AltMD5Verified);
                        }
                    }
                    break;

                case hdErr.HDERR_OUT_OF_MEMORY:
                case hdErr.HDERR_INVALID_FILE:
                case hdErr.HDERR_INVALID_DATA:
                case hdErr.HDERR_READ_ERROR:
                case hdErr.HDERR_DECOMPRESSION_ERROR:
                case hdErr.HDERR_CANT_VERIFY:
                    file.GotStatus = GotStatus.Corrupt;
                    break;

                default:
                    ReportError.UnhandledExceptionHandler(result.ToString());
                    break;
                }
            }
            fileToScan.ZipFileClose();
        }
Beispiel #5
0
        internal hdErr ChdCheck(Message progress, bool isLinux, string filename, out string result)
        {
            _progress   = progress;
            _result     = "";
            _resultType = hdErr.HDERR_NONE;

            string chdExe = "chdman.exe";

            if (isLinux)
            {
                chdExe = "chdman";
            }

            string chdPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, chdExe);

            if (!File.Exists(chdPath))
            {
                result = chdExe + " Not Found.";
                return(hdErr.HDERR_CHDMAN_NOT_FOUND);
            }

            if (!File.Exists(filename))
            {
                result = filename + " Not Found.";
                return(hdErr.HDERR_CHDMAN_NOT_FOUND);
            }

            using (Process exeProcess = new Process())
            {
                exeProcess.StartInfo.FileName = chdPath;

                exeProcess.StartInfo.Arguments = "verify -i \"" + Path.GetFileName(filename) + "\"";

                exeProcess.StartInfo.WorkingDirectory = Path.GetDirectoryName(filename);

                // Set UseShellExecute to false for redirection.
                exeProcess.StartInfo.UseShellExecute = false;
                // Stops the Command window from popping up.
                exeProcess.StartInfo.CreateNoWindow = true;

                // Redirect the standard output.
                // This stream is read asynchronously using an event handler.
                exeProcess.StartInfo.RedirectStandardOutput = true;
                exeProcess.StartInfo.RedirectStandardError  = true;

                // Set our event handler to asynchronously read the process output.
                exeProcess.OutputDataReceived += CHDOutputHandler;
                exeProcess.ErrorDataReceived  += CHDErrorHandler;

                _outputLineCount = 0;
                _errorLines      = 0;

                exeProcess.Start();

                // Start the asynchronous read of the process output stream.
                exeProcess.BeginOutputReadLine();
                exeProcess.BeginErrorReadLine();

                // Wait for the process finish.
                exeProcess.WaitForExit();
            }

            result = _result;
            _progress?.Invoke("");

            return(_resultType);
        }
Beispiel #6
0
        private void CHDErrorHandler(object sendingProcess, DataReceivedEventArgs outLine)
        {
            // Collect the process command output.
            if (string.IsNullOrEmpty(outLine.Data))
            {
                return;
            }

            // We can get fed multiple lines worth of data because of \r line feeds
            string[] sLines = outLine.Data.Split(new[] { "\r" }, StringSplitOptions.None);

            foreach (string sLine in sLines)
            {
                if (String.IsNullOrEmpty(sLine))
                {
                    continue;
                }
                _progress?.Invoke(sLine);

                if (_resultType != hdErr.HDERR_NONE)
                {
                    if (_errorLines > 0)
                    {
                        _errorLines -= 1;
                        _result     += "\r\n" + sLine;
                    }
                }
                else if (Regex.IsMatch(sLine, @"^No verification to be done; CHD has (uncompressed|no checksum)"))
                {
                    _result     = sLine;
                    _resultType = hdErr.HDERR_CANT_VERIFY;
                }
                else if (Regex.IsMatch(sLine, @"^Error (opening|reading) CHD file.*"))
                {
                    _result     = sLine;
                    _resultType = hdErr.HDERR_DECOMPRESSION_ERROR;
                }
                else if (Regex.IsMatch(sLine, @"^Error opening parent CHD file .*:"))
                {
                    _result     = sLine;
                    _resultType = hdErr.HDERR_CANNOT_OPEN_FILE;
                }
                else if (Regex.IsMatch(sLine, @"^Error: (Raw|Overall) SHA1 in header"))
                {
                    _result     = sLine;
                    _resultType = hdErr.HDERR_DECOMPRESSION_ERROR;
                }
                else if (Regex.IsMatch(sLine, @"^Out of memory"))
                {
                    _result     = sLine;
                    _resultType = hdErr.HDERR_OUT_OF_MEMORY;
                }
                // Verifying messages are a non-error
                else if (Regex.IsMatch(sLine, @"Verifying, \d+\.\d+\% complete\.\.\."))
                {
                }
                else
                {
                    _result     = "Unknown message : " + sLine;
                    _resultType = hdErr.HDERR_INVALID_FILE;
                }
            }
        }
Beispiel #7
0
        private hdErr read_block_into_cache(hard_disk_info info, int block)
        {
            bool checkCrc = true;
            mapentry mapEntry = info.map[block];
            switch (mapEntry.flags & mapFlags.MAP_ENTRY_FLAG_TYPE_MASK)
            {
                case mapFlags.MAP_ENTRY_TYPE_COMPRESSED:
                    {

                        if (mapEntry.BlockCache != null)
                        {
                            Buffer.BlockCopy(mapEntry.BlockCache, 0, cache, 0, (int)info.blocksize);
                            //already checked CRC for this block when the cache was made
                            checkCrc = false;
                            break;
                        }

                        info.file.Seek((long)info.map[block].offset, SeekOrigin.Begin);

                        switch (info.compression)
                        {
                            case HDCOMPRESSION_ZLIB:
                            case HDCOMPRESSION_ZLIB_PLUS:
                                {
                                    using (var st = new System.IO.Compression.DeflateStream(info.file, System.IO.Compression.CompressionMode.Decompress, true))
                                    {
                                        int bytes = st.Read(cache, 0, (int)info.blocksize);
                                        if (bytes != (int)info.blocksize)
                                            return hdErr.HDERR_READ_ERROR;

                                        if (mapEntry.UseCount > 0)
                                        {
                                            mapEntry.BlockCache = new byte[bytes];
                                            Buffer.BlockCopy(cache, 0, mapEntry.BlockCache, 0, bytes);
                                        }

                                    }
                                    break;
                                }
                            default:
                                {
                                    Console.WriteLine("Unknown compression");
                                    return hdErr.HDERR_DECOMPRESSION_ERROR;

                                }
                        }
                        break;
                    }

                case mapFlags.MAP_ENTRY_TYPE_UNCOMPRESSED:
                    {
                        info.file.Seek((long)info.map[block].offset, SeekOrigin.Begin);
                        int bytes = info.file.Read(cache, 0, (int)info.blocksize);

                        if (bytes != (int)info.blocksize)
                            return hdErr.HDERR_READ_ERROR;
                        break;
                    }

                case mapFlags.MAP_ENTRY_TYPE_MINI:
                    {
                        byte[] tmp = BitConverter.GetBytes(info.map[block].offset);
                        for (int i = 0; i < 8; i++)
                        {
                            cache[i] = tmp[7 - i];
                        }

                        for (int i = 8; i < info.blocksize; i++)
                        {
                            cache[i] = cache[i - 8];
                        }

                        break;
                    }

                case mapFlags.MAP_ENTRY_TYPE_SELF_HUNK:
                    {
                        hdErr ret = read_block_into_cache(info, (int)mapEntry.offset);
                        if (ret != hdErr.HDERR_NONE)
                            return ret;
                        // check CRC in the read_block_into_cache call
                        checkCrc = false;
                        break;
                    }
                default:
                    return hdErr.HDERR_DECOMPRESSION_ERROR;

            }

            if (checkCrc && (mapEntry.flags & mapFlags.MAP_ENTRY_FLAG_NO_CRC) == 0)
            {
                if (!CRC.VerifyDigest(mapEntry.crc, cache, 0, info.blocksize))
                    return hdErr.HDERR_DECOMPRESSION_ERROR;
            }
            return hdErr.HDERR_NONE;
        }
Beispiel #8
0
        public static hdErr CheckFile(string file, string directory, bool isLinux, ref bool deepCheck, out uint?chdVersion, out byte[] chdSHA1, out byte[] chdMD5, ref bool fileErrorAbort)
        {
            chdSHA1    = null;
            chdMD5     = null;
            chdVersion = null;
            string filename = Path.Combine(directory, file);

            fileProcess?.Invoke(filename);

            //string ext = Path.GetExtension(filename).ToLower();
            //if (ext != ".chd")
            //{
            //    return hdErr.HDERR_INVALID_FILE;
            //}

            if (!File.Exists(filename))
            {
                fileSystemError?.Invoke("File: " + filename + " Error: File Could not be opened.");
                fileErrorAbort = true;
                return(hdErr.HDERR_CANNOT_OPEN_FILE);
            }

            Stream s;
            int    retval = FileStream.OpenFileRead(filename, out s);

            if (retval != 0)
            {
                fileSystemError?.Invoke("File: " + filename + " Error: File Could not be opened.");
                fileErrorAbort = true;
                return(hdErr.HDERR_CANNOT_OPEN_FILE);
            }
            if (s == null)
            {
                fileSystemError?.Invoke("File: " + filename + " Error: File Could not be opened.");
                fileErrorAbort = true;
                return(hdErr.HDERR_CANNOT_OPEN_FILE);
            }
            if (s.Length < MaxHeader)
            {
                s.Close();
                s.Dispose();
                return(hdErr.HDERR_INVALID_FILE);
            }
            hard_disk_info hdi = new hard_disk_info();
            hdErr          res = ReadCHDHeader(s, ref hdi);

            if (res != hdErr.HDERR_NONE)
            {
                return(res);
            }
            chdVersion = hdi.version;
            chdMD5     = hdi.md5;
            chdSHA1    = hdi.sha1;


            if (!deepCheck)
            {
                s.Close();
                s.Dispose();
                return(res);
            }

            string error = null;

            if (hdi.version < 4 && hdi.compression < 3)
            {
                hdi.file = s;
                CHDLocalCheck clc = new CHDLocalCheck();
                res = clc.ChdCheck(fileProgress, hdi, out error);

                s.Close();
                s.Dispose();
            }
            else
            {
                s.Close();
                s.Dispose();

                CHDManCheck cmc = new CHDManCheck();
                res = cmc.ChdCheck(fileProgress, isLinux, filename, out error);
            }

            switch (res)
            {
            case hdErr.HDERR_NONE:
                break;

            case hdErr.HDERR_CHDMAN_NOT_FOUND:
                deepCheck = false;
                res       = hdErr.HDERR_NONE;
                break;

            case hdErr.HDERR_DECOMPRESSION_ERROR:
                fileError?.Invoke(filename, error);
                break;

            case hdErr.HDERR_FILE_NOT_FOUND:
                fileSystemError?.Invoke("File: " + filename + " Error: Not Found scan Aborted.");
                fileErrorAbort = true;
                break;

            default:
                generalError?.Invoke(res + " " + error);
                break;
            }

            return(res);
        }
        public hdErr read_block_into_cache(int block, byte[] cache, ref byte[] crc)
        {
            crc = null;
            mapentry mapEntry = _hd.map[block];

            switch (mapEntry.flags & mapFlags.MAP_ENTRY_FLAG_TYPE_MASK)
            {
            case mapFlags.MAP_ENTRY_TYPE_COMPRESSED:
            {
                if (mapEntry.BlockCache != null)
                {
                    Buffer.BlockCopy(mapEntry.BlockCache, 0, cache, 0, (int)_hd.blocksize);
                    //already checked CRC for this block when the cache was made
                    break;
                }

                _hd.file.Seek((long)_hd.map[block].offset, SeekOrigin.Begin);

                switch (_hd.compression)
                {
                case HDCOMPRESSION_ZLIB:
                case HDCOMPRESSION_ZLIB_PLUS:
                {
                    using (var st = new System.IO.Compression.DeflateStream(_hd.file, System.IO.Compression.CompressionMode.Decompress, true))
                    {
                        int bytes = st.Read(cache, 0, (int)_hd.blocksize);
                        if (bytes != (int)_hd.blocksize)
                        {
                            return(hdErr.HDERR_READ_ERROR);
                        }

                        if (mapEntry.UseCount > 0)
                        {
                            mapEntry.BlockCache = new byte[bytes];
                            Buffer.BlockCopy(cache, 0, mapEntry.BlockCache, 0, bytes);
                        }
                    }

                    if ((mapEntry.flags & mapFlags.MAP_ENTRY_FLAG_NO_CRC) == 0)
                    {
                        _crc = BitConverter.GetBytes(mapEntry.crc);
                    }
                    break;
                }

                default:
                {
                    Console.WriteLine("Unknown compression");
                    return(hdErr.HDERR_DECOMPRESSION_ERROR);
                }
                }
                break;
            }

            case mapFlags.MAP_ENTRY_TYPE_UNCOMPRESSED:
            {
                _hd.file.Seek((long)_hd.map[block].offset, SeekOrigin.Begin);
                int bytes = _hd.file.Read(cache, 0, (int)_hd.blocksize);

                if (bytes != (int)_hd.blocksize)
                {
                    return(hdErr.HDERR_READ_ERROR);
                }
                if ((mapEntry.flags & mapFlags.MAP_ENTRY_FLAG_NO_CRC) == 0)
                {
                    _crc = BitConverter.GetBytes(mapEntry.crc);
                }
                break;
            }

            case mapFlags.MAP_ENTRY_TYPE_MINI:
            {
                byte[] tmp = BitConverter.GetBytes(_hd.map[block].offset);
                for (int i = 0; i < 8; i++)
                {
                    cache[i] = tmp[7 - i];
                }

                for (int i = 8; i < _hd.blocksize; i++)
                {
                    cache[i] = cache[i - 8];
                }
                if ((mapEntry.flags & mapFlags.MAP_ENTRY_FLAG_NO_CRC) == 0)
                {
                    _crc = BitConverter.GetBytes(mapEntry.crc);
                }
                break;
            }

            case mapFlags.MAP_ENTRY_TYPE_SELF_HUNK:
            {
                hdErr ret = read_block_into_cache((int)mapEntry.offset, cache, ref crc);
                if (ret != hdErr.HDERR_NONE)
                {
                    return(ret);
                }
                break;
            }

            default:
                return(hdErr.HDERR_DECOMPRESSION_ERROR);
            }
            return(hdErr.HDERR_NONE);
        }