Source code

Revision control

Copy as Markdown

Other Tools

// ExtractCallbackSfx.h↩
#include "StdAfx.h"
#include "../../../Common/Wildcard.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileFind.h"
#include "../../../Windows/FileName.h"
#include "../../../Windows/PropVariant.h"
#include "ExtractCallbackSfx.h"
using namespace NWindows;↩
using namespace NFile;↩
using namespace NDir;↩
static LPCSTR const kCantDeleteFile = "Can not delete output file";↩
static LPCSTR const kCantOpenFile = "Can not open output file";↩
static LPCSTR const kUnsupportedMethod = "Unsupported Method";↩
void CExtractCallbackImp::Init(IInArchive *archiveHandler,↩
const FString &directoryPath,↩
const UString &itemDefaultName,↩
const FILETIME &defaultMTime,↩
UInt32 defaultAttributes)↩
{↩
_message.Empty();↩
_isCorrupt = false;↩
_itemDefaultName = itemDefaultName;↩
_defaultMTime = defaultMTime;↩
_defaultAttributes = defaultAttributes;↩
_archiveHandler = archiveHandler;↩
_directoryPath = directoryPath;↩
NName::NormalizeDirPathPrefix(_directoryPath);↩
}↩
HRESULT CExtractCallbackImp::Open_CheckBreak()↩
{↩
#ifndef _NO_PROGRESS↩
return ProgressDialog.Sync.ProcessStopAndPause();↩
#else
return S_OK;↩
#endif
}↩
HRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */)↩
{↩
return S_OK;↩
}↩
HRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */)↩
{↩
#ifndef _NO_PROGRESS↩
return ProgressDialog.Sync.ProcessStopAndPause();↩
#else
return S_OK;↩
#endif
}↩
HRESULT CExtractCallbackImp::Open_Finished()↩
{↩
return S_OK;↩
}↩
STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 size)↩
{↩
#ifndef _NO_PROGRESS↩
ProgressDialog.Sync.SetProgress(size, 0);↩
#endif
return S_OK;↩
}↩
STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue)↩
{↩
#ifndef _NO_PROGRESS↩
RINOK(ProgressDialog.Sync.ProcessStopAndPause());↩
if (completeValue != NULL)↩
ProgressDialog.Sync.SetPos(*completeValue);↩
#endif
return S_OK;↩
}↩
void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts)↩
{↩
FString fullPath = _directoryPath;↩
FOR_VECTOR (i, dirPathParts)↩
{↩
fullPath += us2fs(dirPathParts[i]);↩
CreateDir(fullPath);↩
fullPath.Add_PathSepar();↩
}↩
}↩
STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index,↩
ISequentialOutStream **outStream, Int32 askExtractMode)↩
{↩
#ifndef _NO_PROGRESS↩
if (ProgressDialog.Sync.GetStopped())↩
return E_ABORT;↩
#endif
_outFileStream.Release();↩
UString fullPath;↩
{↩
NCOM::CPropVariant prop;↩
RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop));↩
if (prop.vt == VT_EMPTY)↩
fullPath = _itemDefaultName;↩
else
{↩
if (prop.vt != VT_BSTR)↩
return E_FAIL;↩
fullPath.SetFromBstr(prop.bstrVal);↩
}↩
_filePath = fullPath;↩
}↩
if (askExtractMode == NArchive::NExtract::NAskMode::kExtract)↩
{↩
NCOM::CPropVariant prop;↩
RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop));↩
if (prop.vt == VT_EMPTY)↩
_processedFileInfo.Attributes = _defaultAttributes;↩
else
{↩
if (prop.vt != VT_UI4)↩
return E_FAIL;↩
_processedFileInfo.Attributes = prop.ulVal;↩
}↩
RINOK(_archiveHandler->GetProperty(index, kpidIsDir, &prop));↩
_processedFileInfo.IsDir = VARIANT_BOOLToBool(prop.boolVal);↩
bool isAnti = false;↩
{↩
NCOM::CPropVariant propTemp;↩
RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &propTemp));↩
if (propTemp.vt == VT_BOOL)↩
isAnti = VARIANT_BOOLToBool(propTemp.boolVal);↩
}↩
RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop));↩
switch (prop.vt)↩
{↩
case VT_EMPTY: _processedFileInfo.MTime = _defaultMTime; break;↩
case VT_FILETIME: _processedFileInfo.MTime = prop.filetime; break;↩
default: return E_FAIL;↩
}↩
UStringVector pathParts;↩
SplitPathToParts(fullPath, pathParts);↩
if (pathParts.IsEmpty())↩
return E_FAIL;↩
UString processedPath = fullPath;↩
if (!_processedFileInfo.IsDir)↩
pathParts.DeleteBack();↩
if (!pathParts.IsEmpty())↩
{↩
if (!isAnti)↩
CreateComplexDirectory(pathParts);↩
}↩
FString fullProcessedPath = _directoryPath + us2fs(processedPath);↩
if (_processedFileInfo.IsDir)↩
{↩
_diskFilePath = fullProcessedPath;↩
if (isAnti)↩
RemoveDir(_diskFilePath);↩
else
SetDirTime(_diskFilePath, NULL, NULL, &_processedFileInfo.MTime);↩
return S_OK;↩
}↩
NFind::CFileInfo fileInfo;↩
if (fileInfo.Find(fullProcessedPath))↩
{↩
if (!DeleteFileAlways(fullProcessedPath))↩
{↩
_message = kCantDeleteFile;↩
return E_FAIL;↩
}↩
}↩
if (!isAnti)↩
{↩
_outFileStreamSpec = new COutFileStream;↩
CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);↩
if (!_outFileStreamSpec->Create(fullProcessedPath, true))↩
{↩
_message = kCantOpenFile;↩
return E_FAIL;↩
}↩
_outFileStream = outStreamLoc;↩
*outStream = outStreamLoc.Detach();↩
}↩
_diskFilePath = fullProcessedPath;↩
}↩
else
{↩
*outStream = NULL;↩
}↩
return S_OK;↩
}↩
STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode)↩
{↩
_extractMode = (askExtractMode == NArchive::NExtract::NAskMode::kExtract);↩
return S_OK;↩
}↩
STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult)↩
{↩
switch (resultEOperationResult)↩
{↩
case NArchive::NExtract::NOperationResult::kOK:↩
break;↩
default:↩
{↩
_outFileStream.Release();↩
switch (resultEOperationResult)↩
{↩
case NArchive::NExtract::NOperationResult::kUnsupportedMethod:↩
_message = kUnsupportedMethod;↩
break;↩
default:↩
_isCorrupt = true;↩
}↩
return E_FAIL;↩
}↩
}↩
if (_outFileStream != NULL)↩
{↩
_outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);↩
RINOK(_outFileStreamSpec->Close());↩
}↩
_outFileStream.Release();↩
if (_extractMode)↩
SetFileAttrib(_diskFilePath, _processedFileInfo.Attributes);↩
return S_OK;↩
}↩