Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/UI/FileManager/PanelCrc.cpp')
-rw-r--r--[-rwxr-xr-x]CPP/7zip/UI/FileManager/PanelCrc.cpp427
1 files changed, 224 insertions, 203 deletions
diff --git a/CPP/7zip/UI/FileManager/PanelCrc.cpp b/CPP/7zip/UI/FileManager/PanelCrc.cpp
index 2dd5e7ce..ab93ecba 100755..100644
--- a/CPP/7zip/UI/FileManager/PanelCrc.cpp
+++ b/CPP/7zip/UI/FileManager/PanelCrc.cpp
@@ -1,24 +1,19 @@
-// PanelSplitFile.cpp
+// PanelCrc.cpp
#include "StdAfx.h"
-#include "../../../../C/7zCrc.h"
-#include "../../../../C/Sha256.h"
+#include "../../../Common/MyException.h"
-#include "Common/IntToString.h"
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/FileIO.h"
-#include "Windows/FileFind.h"
-#include "Windows/FileIO.h"
-#include "Windows/FileName.h"
+#include "../Common/LoadCodecs.h"
-#include "OverwriteDialogRes.h"
+#include "../GUI/HashGUI.h"
#include "App.h"
-#include "FormatUtils.h"
#include "LangUtils.h"
-#include "../Common/PropIDUtils.h"
-
#include "resource.h"
using namespace NWindows;
@@ -28,17 +23,18 @@ static const UInt32 kBufSize = (1 << 15);
struct CDirEnumerator
{
- bool FlatMode;
+ bool EnterToDirs;
FString BasePrefix;
- FStringVector FileNames;
+ FStringVector FilePaths;
CObjectVector<NFind::CEnumerator> Enumerators;
FStringVector Prefixes;
- int Index;
- HRESULT GetNextFile(NFind::CFileInfo &fileInfo, bool &filled, FString &fullPath);
+ unsigned Index;
+
+ CDirEnumerator(): EnterToDirs(false), Index(0) {};
+
void Init();
-
- CDirEnumerator(): FlatMode(false) {};
+ DWORD GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &resPath);
};
void CDirEnumerator::Init()
@@ -48,295 +44,320 @@ void CDirEnumerator::Init()
Index = 0;
}
-static HRESULT GetNormalizedError()
+static DWORD GetNormalizedError()
{
- HRESULT errorCode = GetLastError();
- return (errorCode == 0) ? E_FAIL : errorCode;
+ DWORD error = GetLastError();
+ return (error == 0) ? E_FAIL : error;
}
-HRESULT CDirEnumerator::GetNextFile(NFind::CFileInfo &fileInfo, bool &filled, FString &resPath)
+DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &resPath)
{
filled = false;
+ resPath.Empty();
for (;;)
{
if (Enumerators.IsEmpty())
{
- if (Index >= FileNames.Size())
+ if (Index >= FilePaths.Size())
return S_OK;
- const FString &path = FileNames[Index];
+ const FString &path = FilePaths[Index++];
int pos = path.ReverseFind(FCHAR_PATH_SEPARATOR);
- resPath.Empty();
if (pos >= 0)
- resPath = path.Left(pos + 1);
+ resPath.SetFrom(path, pos + 1);
#ifdef _WIN32
- // it's for "c:" paths/
- if (BasePrefix.IsEmpty() && path.Length() == 2 && path[1] == ':')
+ if (BasePrefix.IsEmpty() && path.Len() == 2 && path[1] == ':')
{
- fileInfo.Name = path;
- fileInfo.Attrib = FILE_ATTRIBUTE_DIRECTORY;
- fileInfo.Size = 0;
+ // we use "c:" item as directory item
+ fi.Clear();
+ fi.Name = path;
+ fi.SetAsDir();
+ fi.Size = 0;
}
else
#endif
- if (!fileInfo.Find(BasePrefix + path))
+ if (!fi.Find(BasePrefix + path))
{
- WRes errorCode = GetNormalizedError();
+ DWORD error = GetNormalizedError();
resPath = path;
- return errorCode;
+ return error;
}
- Index++;
break;
}
bool found;
- if (!Enumerators.Back().Next(fileInfo, found))
+ if (Enumerators.Back().Next(fi, found))
{
- HRESULT errorCode = GetNormalizedError();
- resPath = Prefixes.Back();
- return errorCode;
+ if (found)
+ {
+ resPath = Prefixes.Back();
+ break;
+ }
}
- if (found)
+ else
{
+ DWORD error = GetNormalizedError();
resPath = Prefixes.Back();
- break;
+ Enumerators.DeleteBack();
+ Prefixes.DeleteBack();
+ return error;
}
Enumerators.DeleteBack();
Prefixes.DeleteBack();
}
- resPath += fileInfo.Name;
- if (!FlatMode && fileInfo.IsDir())
+ resPath += fi.Name;
+ if (EnterToDirs && fi.IsDir())
{
- FString prefix = resPath + FCHAR_PATH_SEPARATOR;
- Enumerators.Add(NFind::CEnumerator(BasePrefix + prefix + FCHAR_ANY_MASK));
- Prefixes.Add(prefix);
+ FString s = resPath;
+ s += FCHAR_PATH_SEPARATOR;
+ Prefixes.Add(s);
+ s += FCHAR_ANY_MASK;
+ Enumerators.Add(NFind::CEnumerator(BasePrefix + s));
}
filled = true;
return S_OK;
}
-static void ConvertByteToHex(unsigned value, wchar_t *s)
-{
- for (int i = 0; i < 2; i++)
- {
- unsigned t = value & 0xF;
- value >>= 4;
- s[1 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10)));
- }
-}
-
class CThreadCrc: public CProgressThreadVirt
{
- UInt64 NumFilesScan;
- UInt64 NumFiles;
- UInt64 NumFolders;
- UInt64 DataSize;
- UInt32 DataCrcSum;
- Byte Sha256Sum[SHA256_DIGEST_SIZE];
- UInt32 DataNameCrcSum;
-
- UString GetResultMessage() const;
HRESULT ProcessVirt();
public:
CDirEnumerator Enumerator;
-
+ CHashBundle Hash;
+
+ void SetStatus(const UString &s);
+ void AddErrorMessage(DWORD systemError, const FChar *name);
};
-UString CThreadCrc::GetResultMessage() const
+void CThreadCrc::AddErrorMessage(DWORD systemError, const FChar *name)
{
- UString s;
- wchar_t sz[32];
-
- s += LangString(IDS_FILES_COLON, 0x02000320);
- s += L' ';
- ConvertUInt64ToString(NumFiles, sz);
- s += sz;
- s += L'\n';
-
- s += LangString(IDS_FOLDERS_COLON, 0x02000321);
- s += L' ';
- ConvertUInt64ToString(NumFolders, sz);
- s += sz;
- s += L'\n';
-
- s += LangString(IDS_SIZE_COLON, 0x02000322);
- s += L' ';
- ConvertUInt64ToString(DataSize, sz);
- s += MyFormatNew(IDS_FILE_SIZE, 0x02000982, sz);
- s += L'\n';
-
- s += LangString(IDS_CHECKSUM_CRC_DATA, 0x03020721);
- s += L' ';
- ConvertUInt32ToHex(DataCrcSum, sz);
- s += sz;
- s += L'\n';
-
- s += LangString(IDS_CHECKSUM_CRC_DATA_NAMES, 0x03020722);
- s += L' ';
- ConvertUInt32ToHex(DataNameCrcSum, sz);
- s += sz;
- s += L'\n';
-
- if (NumFiles == 1 && NumFilesScan == 1)
+ ProgressDialog.Sync.AddError_Code_Name(systemError, fs2us(Enumerator.BasePrefix + name));
+ Hash.NumErrors++;
+}
+
+void CThreadCrc::SetStatus(const UString &s2)
+{
+ UString s = s2;
+ if (Enumerator.BasePrefix)
{
- s += L"SHA-256: ";
- for (int i = 0; i < SHA256_DIGEST_SIZE; i++)
- {
- wchar_t s2[4];
- ConvertByteToHex(Sha256Sum[i], s2);
- s2[2] = 0;
- s += s2;
- }
+ if (!s.IsEmpty())
+ s += L' ';
+ s += fs2us(Enumerator.BasePrefix);
}
- return s;
+ ProgressDialog.Sync.Set_Status(s);
}
HRESULT CThreadCrc::ProcessVirt()
{
- DataSize = NumFolders = NumFiles = NumFilesScan = DataCrcSum = DataNameCrcSum = 0;
- memset(Sha256Sum, 0, SHA256_DIGEST_SIZE);
- // ProgressDialog.WaitCreating();
+ Hash.Init();
- CMyBuffer bufferObject;
- if (!bufferObject.Allocate(kBufSize))
+ CMyBuffer buf;
+ if (!buf.Allocate(kBufSize))
return E_OUTOFMEMORY;
- Byte *buffer = (Byte *)(void *)bufferObject;
-
- UInt64 totalSize = 0;
+
+ CProgressSync &sync = ProgressDialog.Sync;
+ SetStatus(LangString(IDS_SCANNING));
+
Enumerator.Init();
-
- UString scanningStr = LangString(IDS_SCANNING, 0x03020800);
- scanningStr += L' ';
-
- CProgressSync &sync = ProgressDialog.Sync;
+
+ FString path;
+ NFind::CFileInfo fi;
+ UInt64 numFiles = 0;
+ UInt64 numItems = 0, numItems_Prev = 0;
+ UInt64 totalSize = 0;
for (;;)
{
- NFind::CFileInfo fileInfo;
bool filled;
- FString resPath;
- HRESULT errorCode = Enumerator.GetNextFile(fileInfo, filled, resPath);
- if (errorCode != 0)
+ DWORD error = Enumerator.GetNextFile(fi, filled, path);
+ if (error != 0)
{
- SetErrorPath1(resPath);
- return errorCode;
+ AddErrorMessage(error, path);
+ continue;
}
if (!filled)
break;
- if (!fileInfo.IsDir())
+ if (!fi.IsDir())
+ {
+ totalSize += fi.Size;
+ numFiles++;
+ }
+ numItems++;
+ bool needPrint = false;
+ // if (fi.IsDir())
{
- totalSize += fileInfo.Size;
- NumFilesScan++;
+ 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, fs2us(path), fi.IsDir()));
}
- sync.SetCurrentFileName(scanningStr + fs2us(resPath));
- sync.SetProgress(totalSize, 0);
- RINOK(sync.SetPosAndCheckPaused(0));
}
- sync.SetNumFilesTotal(NumFilesScan);
- sync.SetProgress(totalSize, 0);
-
+ RINOK(sync.ScanProgress(numFiles, totalSize, L"", 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 (;;)
{
- NFind::CFileInfo fileInfo;
bool filled;
- FString resPath;
- HRESULT errorCode = Enumerator.GetNextFile(fileInfo, filled, resPath);
- if (errorCode != 0)
+ DWORD error = Enumerator.GetNextFile(fi, filled, path);
+ if (error != 0)
{
- SetErrorPath1(resPath);
- return errorCode;
+ AddErrorMessage(error, path);
+ continue;
}
if (!filled)
break;
- UInt32 crc = CRC_INIT_VAL;
- CSha256 sha256;
- Sha256_Init(&sha256);
-
- if (fileInfo.IsDir())
- NumFolders++;
- else
+ error = 0;
+ Hash.InitForNewFile();
+ if (!fi.IsDir())
{
NIO::CInFile inFile;
- if (!inFile.Open(Enumerator.BasePrefix + resPath))
+ tempPath = Enumerator.BasePrefix;
+ tempPath += path;
+ if (!inFile.Open(tempPath))
+ {
+ error = GetNormalizedError();
+ AddErrorMessage(error, path);
+ continue;
+ }
+ if (isFirstFile)
{
- errorCode = GetNormalizedError();
- SetErrorPath1(resPath);
- return errorCode;
+ firstFilePath = path;
+ isFirstFile = false;
}
- sync.SetCurrentFileName(fs2us(resPath));
- sync.SetNumFilesCur(NumFiles);
- NumFiles++;
+ sync.Set_FilePath(fs2us(path));
+ sync.Set_NumFilesCur(Hash.NumFiles);
+ UInt64 progress_Prev = 0;
for (;;)
{
- UInt32 processedSize;
- if (!inFile.Read(buffer, kBufSize, processedSize))
+ UInt32 size;
+ if (!inFile.Read(buf, kBufSize, size))
{
- errorCode = GetNormalizedError();
- SetErrorPath1(resPath);
- return errorCode;
+ error = GetNormalizedError();
+ AddErrorMessage(error, path);
+ UInt64 errorSize = 0;
+ if (inFile.GetLength(errorSize))
+ errorsFilesSize += errorSize;
+ break;
}
- if (processedSize == 0)
+ if (size == 0)
break;
- crc = CrcUpdate(crc, buffer, processedSize);
- if (NumFilesScan == 1)
- Sha256_Update(&sha256, buffer, processedSize);
-
- DataSize += processedSize;
- RINOK(sync.SetPosAndCheckPaused(DataSize));
+ 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;
+ }
}
- 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));
+ if (error == 0)
+ Hash.Final(fi.IsDir(), false, fs2us(path));
+ RINOK(sync.Set_NumBytesCur(errorsFilesSize + Hash.FilesSize));
}
- sync.SetNumFilesCur(NumFiles);
- OkMessage = GetResultMessage();
- OkMessageTitle = LangString(IDS_CHECKSUM_INFORMATION, 0x03020720);
+ 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;
}
-void CApp::CalculateCrc()
+static void ThrowException_if_Error(HRESULT res)
+{
+ if (res != S_OK)
+ throw CSystemException(res);
+}
+
+void CApp::CalculateCrc(const UString &methodName)
{
int srcPanelIndex = GetFocusedPanelIndex();
CPanel &srcPanel = Panels[srcPanelIndex];
- if (!srcPanel.IsFsOrDrivesFolder())
- {
- srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);
- return;
- }
+
CRecordVector<UInt32> indices;
- srcPanel.GetOperatedItemIndices(indices);
+ srcPanel.GetOperatedIndicesSmart(indices);
if (indices.IsEmpty())
return;
+ if (!srcPanel.IsFsOrDrivesFolder())
{
- CThreadCrc t;
- for (int i = 0; i < indices.Size(); i++)
- t.Enumerator.FileNames.Add(us2fs(srcPanel.GetItemRelPath(indices[i])));
- t.Enumerator.BasePrefix = us2fs(srcPanel.GetFsPath());
- t.Enumerator.FlatMode = GetFlatMode();
+ CCopyToOptions options;
+ options.streamMode = true;
+ options.showErrorMessages = true;
+ options.hashMethods.Add(methodName);
- t.ProgressDialog.ShowCompressionInfo = false;
+ UStringVector messages;
+ HRESULT res = srcPanel.CopyTo(options, indices, &messages);
+ if (res != S_OK)
+ {
+ if (res != E_ABORT)
+ srcPanel.MessageBoxError(res);
+ }
+ return;
+ }
- UString title = LangString(IDS_CHECKSUM_CALCULATING, 0x03020710);
+ CCodecs *codecs = new CCodecs;
+ #ifdef EXTERNAL_CODECS
+ CExternalCodecs __externalCodecs;
+ __externalCodecs.GetCodecs = codecs;
+ __externalCodecs.GetHashers = codecs;
+ #else
+ CMyComPtr<IUnknown> compressCodecsInfo = codecs;
+ #endif
+ ThrowException_if_Error(codecs->Load());
- t.ProgressDialog.MainWindow = _window;
- t.ProgressDialog.MainTitle = LangString(IDS_APP_TITLE, 0x03000000);
- t.ProgressDialog.MainAddTitle = title + UString(L' ');
+ #ifdef EXTERNAL_CODECS
+ ThrowException_if_Error(__externalCodecs.LoadCodecs());
+ #endif
- if (t.Create(title, _window) != S_OK)
- return;
+ {
+ CThreadCrc t;
+ {
+ UStringVector methods;
+ methods.Add(methodName);
+ t.Hash.SetMethods(EXTERNAL_CODECS_VARS methods);
+ }
+ FOR_VECTOR (i, indices)
+ t.Enumerator.FilePaths.Add(us2fs(srcPanel.GetItemRelPath(indices[i])));
+ t.Enumerator.BasePrefix = us2fs(srcPanel.GetFsPath());
+ t.Enumerator.EnterToDirs = !GetFlatMode();
+
+ t.ProgressDialog.ShowCompressionInfo = false;
+
+ UString title = LangString(IDS_CHECKSUM_CALCULATING);
+
+ t.ProgressDialog.MainWindow = _window;
+ t.ProgressDialog.MainTitle = L"7-Zip"; // LangString(IDS_APP_TITLE);
+ t.ProgressDialog.MainAddTitle = title + UString(L' ');
+
+ if (t.Create(title, _window) != S_OK)
+ return;
}
RefreshTitleAlways();
}