diff options
Diffstat (limited to 'installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/PanelCrc.cpp')
-rw-r--r-- | installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/PanelCrc.cpp | 368 |
1 files changed, 368 insertions, 0 deletions
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/PanelCrc.cpp b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/PanelCrc.cpp new file mode 100644 index 000000000..61490b578 --- /dev/null +++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/PanelCrc.cpp @@ -0,0 +1,368 @@ +// PanelSplitFile.cpp + +#include "StdAfx.h" + +#include "resource.h" + +extern "C" +{ + #include "../../../../C/Alloc.h" + #include "../../../../C/7zCrc.h" +} + +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#include "Windows/FileIO.h" +#include "Windows/FileFind.h" +#include "Windows/FileName.h" +#include "Windows/Thread.h" +#include "Windows/Error.h" + +#include "ProgressDialog2.h" +#include "OverwriteDialogRes.h" + +#include "App.h" +#include "FormatUtils.h" +#include "LangUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NName; + +static const UInt32 kBufSize = (1 << 15); + +struct CDirEnumerator +{ + bool FlatMode; + UString BasePrefix; + UStringVector FileNames; + + CObjectVector<NFind::CEnumeratorW> Enumerators; + UStringVector Prefixes; + int Index; + bool GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UString &fullPath, DWORD &errorCode); + void Init(); + + CDirEnumerator(): FlatMode(false) {}; +}; + +void CDirEnumerator::Init() +{ + Enumerators.Clear(); + Prefixes.Clear(); + Index = 0; +} + +bool CDirEnumerator::GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UString &resPath, DWORD &errorCode) +{ + filled = false; + for (;;) + { + if (Enumerators.IsEmpty()) + { + if (Index >= FileNames.Size()) + return true; + const UString &path = FileNames[Index]; + int pos = path.ReverseFind('\\'); + resPath.Empty(); + if (pos >= 0) + resPath = path.Left(pos + 1); + if (!NFind::FindFile(BasePrefix + path, fileInfo)) + { + errorCode = ::GetLastError(); + resPath = path; + return false; + } + Index++; + break; + } + bool found; + if (!Enumerators.Back().Next(fileInfo, found)) + { + errorCode = ::GetLastError(); + resPath = Prefixes.Back(); + return false; + } + if (found) + { + resPath = Prefixes.Back(); + break; + } + Enumerators.DeleteBack(); + Prefixes.DeleteBack(); + } + resPath += fileInfo.Name; + if (!FlatMode && fileInfo.IsDir()) + { + UString prefix = resPath + (UString)(wchar_t)kDirDelimiter; + Enumerators.Add(NFind::CEnumeratorW(BasePrefix + prefix + (UString)(wchar_t)kAnyStringWildcard)); + Prefixes.Add(prefix); + } + filled = true; + return true; +} + +struct CThreadCrc +{ + class CMyBuffer + { + void *_data; + public: + CMyBuffer(): _data(0) {} + operator void *() { return _data; } + bool Allocate(size_t size) + { + if (_data != 0) + return false; + _data = ::MidAlloc(size); + return _data != 0; + } + ~CMyBuffer() { ::MidFree(_data); } + }; + + CProgressDialog *ProgressDialog; + + CDirEnumerator DirEnumerator; + + UInt64 NumFiles; + UInt64 NumFolders; + UInt64 DataSize; + UInt32 DataCrcSum; + UInt32 DataNameCrcSum; + + HRESULT Result; + DWORD ErrorCode; + UString ErrorPath; + UString Error; + bool ThereIsError; + + void Process2() + { + DataSize = NumFolders = NumFiles = DataCrcSum = DataNameCrcSum = 0; + ProgressDialog->WaitCreating(); + + CMyBuffer bufferObject; + if (!bufferObject.Allocate(kBufSize)) + { + Error = L"Can not allocate memory"; + ThereIsError = true; + return; + } + Byte *buffer = (Byte *)(void *)bufferObject; + + UInt64 totalSize = 0; + + DirEnumerator.Init(); + + UString scanningStr = LangString(IDS_SCANNING, 0x03020800); + scanningStr += L" "; + + for (;;) + { + NFile::NFind::CFileInfoW fileInfo; + bool filled; + UString resPath; + if (!DirEnumerator.GetNextFile(fileInfo, filled, resPath, ErrorCode)) + { + ThereIsError = true; + ErrorPath = resPath; + return; + } + if (!filled) + break; + if (!fileInfo.IsDir()) + totalSize += fileInfo.Size; + ProgressDialog->ProgressSynch.SetCurrentFileName(scanningStr + resPath); + ProgressDialog->ProgressSynch.SetProgress(totalSize, 0); + Result = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(0); + if (Result != S_OK) + return; + } + + ProgressDialog->ProgressSynch.SetProgress(totalSize, 0); + + DirEnumerator.Init(); + + for (;;) + { + NFile::NFind::CFileInfoW fileInfo; + bool filled; + UString resPath; + if (!DirEnumerator.GetNextFile(fileInfo, filled, resPath, ErrorCode)) + { + ThereIsError = true; + ErrorPath = resPath; + return; + } + if (!filled) + break; + + UInt32 crc = CRC_INIT_VAL; + if (fileInfo.IsDir()) + NumFolders++; + else + { + NFile::NIO::CInFile inFile; + if (!inFile.Open(DirEnumerator.BasePrefix + resPath)) + { + ErrorCode = ::GetLastError(); + ThereIsError = true; + ErrorPath = resPath; + return; + } + NumFiles++; + ProgressDialog->ProgressSynch.SetCurrentFileName(resPath); + for (;;) + { + UInt32 processedSize; + if (!inFile.Read(buffer, kBufSize, processedSize)) + { + ErrorCode = ::GetLastError(); + ThereIsError = true; + ErrorPath = resPath; + return; + } + if (processedSize == 0) + break; + crc = CrcUpdate(crc, buffer, processedSize); + DataSize += processedSize; + Result = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(DataSize); + if (Result != S_OK) + return; + } + DataCrcSum += CRC_GET_DIGEST(crc); + } + 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); + Result = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(DataSize); + if (Result != S_OK) + return; + } + } + DWORD Process() + { + try { Process2(); } + catch(...) { Error = L"Error"; ThereIsError = true;} + ProgressDialog->MyClose(); + return 0; + } + + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + return ((CThreadCrc *)param)->Process(); + } +}; + +static void ConvertUInt32ToHex(UInt32 value, wchar_t *s) +{ + for (int i = 0; i < 8; i++) + { + int t = value & 0xF; + value >>= 4; + s[7 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10))); + } + s[8] = L'\0'; +} + +void CApp::CalculateCrc() +{ + int srcPanelIndex = GetFocusedPanelIndex(); + CPanel &srcPanel = Panels[srcPanelIndex]; + if (!srcPanel.IsFSFolder()) + { + srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208); + return; + } + CRecordVector<UInt32> indices; + srcPanel.GetOperatedItemIndices(indices); + if (indices.IsEmpty()) + return; + + CThreadCrc combiner; + for (int i = 0; i < indices.Size(); i++) + combiner.DirEnumerator.FileNames.Add(srcPanel.GetItemRelPath(indices[i])); + combiner.DirEnumerator.BasePrefix = srcPanel._currentFolderPrefix; + combiner.DirEnumerator.FlatMode = GetFlatMode(); + + { + CProgressDialog progressDialog; + combiner.ProgressDialog = &progressDialog; + combiner.ErrorCode = 0; + combiner.Result = S_OK; + combiner.ThereIsError = false; + + UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000); + UString title = LangString(IDS_CHECKSUM_CALCULATING, 0x03020710); + + progressDialog.MainWindow = _window; + progressDialog.MainTitle = progressWindowTitle; + progressDialog.MainAddTitle = title + UString(L" "); + + NWindows::CThread thread; + if (thread.Create(CThreadCrc::MyThreadFunction, &combiner) != S_OK) + return; + progressDialog.Create(title, _window); + + if (combiner.Result != S_OK) + { + if (combiner.Result != E_ABORT) + srcPanel.MessageBoxError(combiner.Result); + } + else if (combiner.ThereIsError) + { + if (combiner.Error.IsEmpty()) + { + UString message = combiner.DirEnumerator.BasePrefix + combiner.ErrorPath; + message += L"\n"; + message += NError::MyFormatMessageW(combiner.ErrorCode); + srcPanel.MessageBoxMyError(message); + } + else + srcPanel.MessageBoxMyError(combiner.Error); + } + else + { + UString s; + { + wchar_t sz[32]; + + s += LangString(IDS_FILES_COLON, 0x02000320); + s += L" "; + ConvertUInt64ToString(combiner.NumFiles, sz); + s += sz; + s += L"\n"; + + s += LangString(IDS_FOLDERS_COLON, 0x02000321); + s += L" "; + ConvertUInt64ToString(combiner.NumFolders, sz); + s += sz; + s += L"\n"; + + s += LangString(IDS_SIZE_COLON, 0x02000322); + s += L" "; + ConvertUInt64ToString(combiner.DataSize, sz); + s += MyFormatNew(IDS_FILE_SIZE, 0x02000982, sz);; + s += L"\n"; + + s += LangString(IDS_CHECKSUM_CRC_DATA, 0x03020721); + s += L" "; + ConvertUInt32ToHex(combiner.DataCrcSum, sz); + s += sz; + s += L"\n"; + + s += LangString(IDS_CHECKSUM_CRC_DATA_NAMES, 0x03020722); + s += L" "; + ConvertUInt32ToHex(combiner.DataNameCrcSum, sz); + s += sz; + } + srcPanel.MessageBoxInfo(s, LangString(IDS_CHECKSUM_INFORMATION, 0x03020720)); + } + } + RefreshTitleAlways(); +} |