HRESULT CThreadCrc::ProcessVirt() { Hash.Init(); CMyBuffer buf; if (!buf.Allocate(kBufSize)) return E_OUTOFMEMORY; CProgressSync &sync = ProgressDialog.Sync; SetStatus(LangString(IDS_SCANNING)); Enumerator.Init(); FString path; NFind::CFileInfo fi; UInt64 numFiles = 0; UInt64 numItems = 0, numItems_Prev = 0; UInt64 totalSize = 0; for (;;) { bool filled; DWORD error = Enumerator.GetNextFile(fi, filled, path); if (error != 0) { AddErrorMessage(error, path); continue; } if (!filled) break; if (!fi.IsDir()) { totalSize += fi.Size; numFiles++; } numItems++; bool needPrint = false; // if (fi.IsDir()) { if (numItems - numItems_Prev >= 100) { needPrint = true; numItems_Prev = numItems; } } /* else if (numFiles - numFiles_Prev >= 200) { needPrint = true; numFiles_Prev = numFiles; } */ if (needPrint) { RINOK(sync.ScanProgress(numFiles, totalSize, path, fi.IsDir())); } } RINOK(sync.ScanProgress(numFiles, totalSize, FString(), false)); // sync.SetNumFilesTotal(numFiles); // sync.SetProgress(totalSize, 0); // SetStatus(LangString(IDS_CHECKSUM_CALCULATING)); // sync.SetCurFilePath(L""); SetStatus(L""); Enumerator.Init(); FString tempPath; FString firstFilePath; bool isFirstFile = true; UInt64 errorsFilesSize = 0; for (;;) { bool filled; DWORD error = Enumerator.GetNextFile(fi, filled, path); if (error != 0) { AddErrorMessage(error, path); continue; } if (!filled) break; error = 0; Hash.InitForNewFile(); if (!fi.IsDir()) { NIO::CInFile inFile; tempPath = Enumerator.BasePrefix_for_Open; tempPath += path; if (!inFile.Open(tempPath)) { error = GetNormalizedError(); AddErrorMessage(error, path); continue; } if (isFirstFile) { firstFilePath = path; isFirstFile = false; } sync.Set_FilePath(fs2us(path)); sync.Set_NumFilesCur(Hash.NumFiles); UInt64 progress_Prev = 0; for (;;) { UInt32 size; if (!inFile.Read(buf, kBufSize, size)) { error = GetNormalizedError(); AddErrorMessage(error, path); UInt64 errorSize = 0; if (inFile.GetLength(errorSize)) errorsFilesSize += errorSize; break; } if (size == 0) break; Hash.Update(buf, size); if (Hash.CurSize - progress_Prev >= ((UInt32)1 << 21)) { RINOK(sync.Set_NumBytesCur(errorsFilesSize + Hash.FilesSize + Hash.CurSize)); progress_Prev = Hash.CurSize; } } } if (error == 0) Hash.Final(fi.IsDir(), false, fs2us(path)); RINOK(sync.Set_NumBytesCur(errorsFilesSize + Hash.FilesSize)); } RINOK(sync.Set_NumBytesCur(errorsFilesSize + Hash.FilesSize)); sync.Set_NumFilesCur(Hash.NumFiles); if (Hash.NumFiles != 1) sync.Set_FilePath(L""); SetStatus(L""); CProgressMessageBoxPair &pair = GetMessagePair(Hash.NumErrors != 0); AddHashBundleRes(pair.Message, Hash, fs2us(firstFilePath)); LangString(IDS_CHECKSUM_INFORMATION, pair.Title); return S_OK; }
HRESULT CThreadCrc::ProcessVirt() { DataSize = NumFolders = NumFiles = NumFilesScan = DataCrcSum = DataNameCrcSum = 0; memset(Sha256Sum, 0, SHA256_DIGEST_SIZE); // ProgressDialog.WaitCreating(); CMyBuffer bufferObject; if (!bufferObject.Allocate(kBufSize)) return E_OUTOFMEMORY; Byte *buffer = (Byte *)(void *)bufferObject; UInt64 totalSize = 0; Enumerator.Init(); UString scanningStr = LangString(IDS_SCANNING, 0x03020800); scanningStr += L' '; CProgressSync &sync = ProgressDialog.Sync; for (;;) { NFind::CFileInfo fileInfo; bool filled; FString resPath; HRESULT errorCode = Enumerator.GetNextFile(fileInfo, filled, resPath); if (errorCode != 0) { SetErrorPath1(resPath); return errorCode; } if (!filled) break; if (!fileInfo.IsDir()) { totalSize += fileInfo.Size; NumFilesScan++; } sync.SetCurrentFileName(scanningStr + fs2us(resPath)); sync.SetProgress(totalSize, 0); RINOK(sync.SetPosAndCheckPaused(0)); } sync.SetNumFilesTotal(NumFilesScan); sync.SetProgress(totalSize, 0); Enumerator.Init(); for (;;) { NFind::CFileInfo fileInfo; bool filled; FString resPath; HRESULT errorCode = Enumerator.GetNextFile(fileInfo, filled, resPath); if (errorCode != 0) { SetErrorPath1(resPath); return errorCode; } if (!filled) break; UInt32 crc = CRC_INIT_VAL; CSha256 sha256; Sha256_Init(&sha256); if (fileInfo.IsDir()) NumFolders++; else { NIO::CInFile inFile; if (!inFile.Open(Enumerator.BasePrefix + resPath)) { errorCode = GetNormalizedError(); SetErrorPath1(resPath); return errorCode; } sync.SetCurrentFileName(fs2us(resPath)); sync.SetNumFilesCur(NumFiles); NumFiles++; for (;;) { UInt32 processedSize; if (!inFile.Read(buffer, kBufSize, processedSize)) { errorCode = GetNormalizedError(); SetErrorPath1(resPath); return errorCode; } if (processedSize == 0) break; crc = CrcUpdate(crc, buffer, processedSize); if (NumFilesScan == 1) Sha256_Update(&sha256, buffer, processedSize); DataSize += processedSize; RINOK(sync.SetPosAndCheckPaused(DataSize)); } DataCrcSum += CRC_GET_DIGEST(crc); if (NumFilesScan == 1) Sha256_Final(&sha256, Sha256Sum); } for (int i = 0; i < resPath.Length(); i++) { wchar_t c = resPath[i]; crc = CRC_UPDATE_BYTE(crc, ((Byte)(c & 0xFF))); crc = CRC_UPDATE_BYTE(crc, ((Byte)((c >> 8) & 0xFF))); } DataNameCrcSum += CRC_GET_DIGEST(crc); RINOK(sync.SetPosAndCheckPaused(DataSize)); } sync.SetNumFilesCur(NumFiles); OkMessage = GetResultMessage(); OkMessageTitle = LangString(IDS_CHECKSUM_INFORMATION, 0x03020720); return S_OK; }