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++; }
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(); } }
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(); }
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); }
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; } } }
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; }
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); }