Files
easy7zip/7zip/FileManager/ExtractCallback.cpp
Igor Pavlov 8c1b5c7b7e 3.13
2016-05-28 00:15:41 +01:00

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;
}