mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-11 14:07:13 -06:00
313 lines
7.9 KiB
C++
Executable File
313 lines
7.9 KiB
C++
Executable File
// ExtractCallback.h
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "ExtractCallback.h"
|
|
|
|
#include "Windows/FileFind.h"
|
|
#include "Windows/FileDir.h"
|
|
|
|
#include "Resource/OverwriteDialog/OverwriteDialog.h"
|
|
#include "Resource/PasswordDialog/PasswordDialog.h"
|
|
#include "Resource/MessagesDialog/MessagesDialog.h"
|
|
#include "../UI/Resource/Extract/resource.h"
|
|
|
|
#include "Common/WildCard.h"
|
|
#include "Common/StringConvert.h"
|
|
|
|
#include "FormatUtils.h"
|
|
|
|
#include "../Common/FilePathAutoRename.h"
|
|
|
|
using namespace NWindows;
|
|
using namespace NFile;
|
|
using namespace NFind;
|
|
|
|
CExtractCallbackImp::~CExtractCallbackImp()
|
|
{
|
|
if (!_messages.IsEmpty())
|
|
{
|
|
CMessagesDialog messagesDialog;
|
|
messagesDialog._messages = &_messages;
|
|
messagesDialog.Create(_parentWindow);
|
|
}
|
|
}
|
|
|
|
void CExtractCallbackImp::Init(
|
|
NExtractionMode::NOverwrite::EEnum overwriteMode,
|
|
bool passwordIsDefined,
|
|
const UString &password)
|
|
{
|
|
_overwriteMode = overwriteMode;
|
|
_passwordIsDefined = passwordIsDefined;
|
|
_password = password;
|
|
_messages.Clear();
|
|
}
|
|
|
|
void CExtractCallbackImp::AddErrorMessage(LPCTSTR message)
|
|
{
|
|
_messages.Add(message);
|
|
}
|
|
|
|
STDMETHODIMP CExtractCallbackImp::SetTotal(UINT64 total)
|
|
{
|
|
ProgressDialog.ProgressSynch.SetProgress(total, 0);
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CExtractCallbackImp::SetCompleted(const UINT64 *completeValue)
|
|
{
|
|
while(true)
|
|
{
|
|
if(ProgressDialog.ProgressSynch.GetStopped())
|
|
return E_ABORT;
|
|
if(!ProgressDialog.ProgressSynch.GetPaused())
|
|
break;
|
|
::Sleep(100);
|
|
}
|
|
if (completeValue != NULL)
|
|
ProgressDialog.ProgressSynch.SetPos(*completeValue);
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CExtractCallbackImp::AskOverwrite(
|
|
const wchar_t *existName, const FILETIME *existTime, const UINT64 *existSize,
|
|
const wchar_t *newName, const FILETIME *newTime, const UINT64 *newSize,
|
|
INT32 *answer)
|
|
{
|
|
COverwriteDialog dialog;
|
|
|
|
dialog.OldFileInfo.Time = *existTime;
|
|
if (dialog.OldFileInfo.SizeIsDefined = (existSize != NULL))
|
|
dialog.OldFileInfo.Size = *existSize;
|
|
dialog.OldFileInfo.Name = existName;
|
|
|
|
if (newTime == 0)
|
|
dialog.NewFileInfo.TimeIsDefined = false;
|
|
else
|
|
{
|
|
dialog.NewFileInfo.TimeIsDefined = true;
|
|
dialog.NewFileInfo.Time = *newTime;
|
|
}
|
|
|
|
if (dialog.NewFileInfo.SizeIsDefined = (newSize != NULL))
|
|
dialog.NewFileInfo.Size = *newSize;
|
|
dialog.NewFileInfo.Name = newName;
|
|
|
|
/*
|
|
NOverwriteDialog::NResult::EEnum writeAnswer =
|
|
NOverwriteDialog::Execute(oldFileInfo, newFileInfo);
|
|
*/
|
|
int writeAnswer = dialog.Create(NULL); // _parentWindow doesn't work with 7z
|
|
|
|
switch(writeAnswer)
|
|
{
|
|
case IDCANCEL:
|
|
return E_ABORT;
|
|
// askResult = NAskOverwriteAnswer::kCancel;
|
|
// break;
|
|
case IDNO:
|
|
*answer = NOverwriteAnswer::kNo;
|
|
break;
|
|
case IDC_BUTTON_OVERWRITE_NO_TO_ALL:
|
|
*answer = NOverwriteAnswer::kNoToAll;
|
|
break;
|
|
case IDC_BUTTON_OVERWRITE_YES_TO_ALL:
|
|
*answer = NOverwriteAnswer::kYesToAll;
|
|
break;
|
|
case IDC_BUTTON_OVERWRITE_AUTO_RENAME:
|
|
*answer = NOverwriteAnswer::kAutoRename;
|
|
break;
|
|
case IDYES:
|
|
*answer = NOverwriteAnswer::kYes;
|
|
break;
|
|
default:
|
|
throw 20413;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, INT32 askExtractMode)
|
|
{
|
|
_currentFilePath = name;
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *message)
|
|
{
|
|
AddErrorMessage(GetSystemString(message));
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CExtractCallbackImp::ShowMessage(const wchar_t *message)
|
|
{
|
|
AddErrorMessage(GetSystemString(message));
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CExtractCallbackImp::SetOperationResult(INT32 operationResult)
|
|
{
|
|
switch(operationResult)
|
|
{
|
|
case NArchive::NExtract::NOperationResult::kOK:
|
|
break;
|
|
default:
|
|
{
|
|
UINT messageID;
|
|
UINT32 langID;
|
|
switch(operationResult)
|
|
{
|
|
case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
|
|
messageID = IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_UNSUPPORTED_METHOD;
|
|
langID = 0x02000A91;
|
|
break;
|
|
case NArchive::NExtract::NOperationResult::kDataError:
|
|
messageID = IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR;
|
|
langID = 0x02000A92;
|
|
break;
|
|
case NArchive::NExtract::NOperationResult::kCRCError:
|
|
messageID = IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC;
|
|
langID = 0x02000A93;
|
|
break;
|
|
default:
|
|
return E_FAIL;
|
|
}
|
|
AddErrorMessage(
|
|
GetSystemString(MyFormatNew(messageID,
|
|
#ifdef LANG
|
|
langID,
|
|
#endif
|
|
_currentFilePath)));
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password)
|
|
{
|
|
if (!_passwordIsDefined)
|
|
{
|
|
CPasswordDialog dialog;
|
|
|
|
if (dialog.Create(_parentWindow) == IDCANCEL)
|
|
return E_ABORT;
|
|
|
|
_password = GetUnicodeString((LPCTSTR)dialog._password);
|
|
_passwordIsDefined = true;
|
|
}
|
|
CMyComBSTR tempName = _password;
|
|
*password = tempName.Detach();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
// IExtractCallBack3
|
|
STDMETHODIMP CExtractCallbackImp::AskWrite(
|
|
const wchar_t *srcPath, INT32 srcIsFolder,
|
|
const FILETIME *srcTime, const UINT64 *srcSize,
|
|
const wchar_t *destPath,
|
|
BSTR *destPathResult,
|
|
INT32 *writeAnswer)
|
|
{
|
|
UString destPathResultTemp = destPath;
|
|
/*
|
|
{
|
|
CMyComBSTR destPathResultBSTR = destPath;
|
|
*destPathResult = destPathResultBSTR.Detach();
|
|
}
|
|
*/
|
|
*destPathResult = 0;
|
|
*writeAnswer = BoolToInt(false);
|
|
|
|
UString destPathSpec = destPath;
|
|
UString destPathSys = destPathSpec;
|
|
bool srcIsFolderSpec = IntToBool(srcIsFolder);
|
|
CFileInfoW destFileInfo;
|
|
if (FindFile(destPathSys, destFileInfo))
|
|
{
|
|
if (srcIsFolderSpec)
|
|
{
|
|
if (!destFileInfo.IsDirectory())
|
|
{
|
|
UString message = UString(L"can not replace file \'")
|
|
+ destPathSpec +
|
|
UString(L"\' with folder with same name");
|
|
RINOK(MessageError(message));
|
|
return E_ABORT;
|
|
}
|
|
*writeAnswer = BoolToInt(false);
|
|
return S_OK;
|
|
}
|
|
if (destFileInfo.IsDirectory())
|
|
{
|
|
UString message = UString(L"can not replace folder \'")
|
|
+ destPathSpec +
|
|
UString(L"\' with file with same name");
|
|
RINOK(MessageError(message));
|
|
return E_FAIL;
|
|
}
|
|
|
|
switch(_overwriteMode)
|
|
{
|
|
case NExtractionMode::NOverwrite::kSkipExisting:
|
|
return S_OK;
|
|
case NExtractionMode::NOverwrite::kAskBefore:
|
|
{
|
|
INT32 overwiteResult;
|
|
RINOK(AskOverwrite(
|
|
destPathSpec,
|
|
&destFileInfo.LastWriteTime, &destFileInfo.Size,
|
|
srcPath,
|
|
srcTime, srcSize,
|
|
&overwiteResult));
|
|
switch(overwiteResult)
|
|
{
|
|
case NOverwriteAnswer::kCancel:
|
|
return E_ABORT;
|
|
case NOverwriteAnswer::kNo:
|
|
return S_OK;
|
|
case NOverwriteAnswer::kNoToAll:
|
|
_overwriteMode = NExtractionMode::NOverwrite::kSkipExisting;
|
|
return S_OK;
|
|
case NOverwriteAnswer::kYesToAll:
|
|
_overwriteMode = NExtractionMode::NOverwrite::kWithoutPrompt;
|
|
break;
|
|
case NOverwriteAnswer::kYes:
|
|
break;
|
|
case NOverwriteAnswer::kAutoRename:
|
|
_overwriteMode = NExtractionMode::NOverwrite::kAutoRename;
|
|
break;
|
|
default:
|
|
throw 20413;
|
|
}
|
|
}
|
|
}
|
|
if (_overwriteMode == NExtractionMode::NOverwrite::kAutoRename)
|
|
{
|
|
if (!AutoRenamePath(destPathSys))
|
|
{
|
|
UString message = UString(L"can not create name of file ")
|
|
+ destPathSys;
|
|
RINOK(MessageError(message));
|
|
return E_ABORT;
|
|
}
|
|
destPathResultTemp = destPathSys;
|
|
}
|
|
else
|
|
if (!NFile::NDirectory::DeleteFileAlways(destPathSys))
|
|
{
|
|
UString message = UString(L"can not delete output file ")
|
|
+ destPathSys;
|
|
RINOK(MessageError(message));
|
|
return E_ABORT;
|
|
}
|
|
}
|
|
CMyComBSTR destPathResultBSTR = destPathResultTemp;
|
|
*destPathResult = destPathResultBSTR.Detach();
|
|
*writeAnswer = BoolToInt(true);
|
|
return S_OK;
|
|
}
|
|
|