1370b324cSopenharmony_ci// ExtractCallbackSfx.h 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci#include "../../../Common/Wildcard.h" 6370b324cSopenharmony_ci 7370b324cSopenharmony_ci#include "../../../Windows/FileDir.h" 8370b324cSopenharmony_ci#include "../../../Windows/FileFind.h" 9370b324cSopenharmony_ci#include "../../../Windows/FileName.h" 10370b324cSopenharmony_ci#include "../../../Windows/PropVariant.h" 11370b324cSopenharmony_ci 12370b324cSopenharmony_ci#include "ExtractCallbackSfx.h" 13370b324cSopenharmony_ci 14370b324cSopenharmony_ciusing namespace NWindows; 15370b324cSopenharmony_ciusing namespace NFile; 16370b324cSopenharmony_ciusing namespace NDir; 17370b324cSopenharmony_ci 18370b324cSopenharmony_cistatic LPCSTR const kCantDeleteFile = "Cannot delete output file"; 19370b324cSopenharmony_cistatic LPCSTR const kCantOpenFile = "Cannot open output file"; 20370b324cSopenharmony_cistatic LPCSTR const kUnsupportedMethod = "Unsupported Method"; 21370b324cSopenharmony_ci 22370b324cSopenharmony_civoid CExtractCallbackImp::Init(IInArchive *archiveHandler, 23370b324cSopenharmony_ci const FString &directoryPath, 24370b324cSopenharmony_ci const UString &itemDefaultName, 25370b324cSopenharmony_ci const FILETIME &defaultMTime, 26370b324cSopenharmony_ci UInt32 defaultAttributes) 27370b324cSopenharmony_ci{ 28370b324cSopenharmony_ci _message.Empty(); 29370b324cSopenharmony_ci _isCorrupt = false; 30370b324cSopenharmony_ci _itemDefaultName = itemDefaultName; 31370b324cSopenharmony_ci _defaultMTime = defaultMTime; 32370b324cSopenharmony_ci _defaultAttributes = defaultAttributes; 33370b324cSopenharmony_ci _archiveHandler = archiveHandler; 34370b324cSopenharmony_ci _directoryPath = directoryPath; 35370b324cSopenharmony_ci NName::NormalizeDirPathPrefix(_directoryPath); 36370b324cSopenharmony_ci} 37370b324cSopenharmony_ci 38370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_CheckBreak() 39370b324cSopenharmony_ci{ 40370b324cSopenharmony_ci #ifndef _NO_PROGRESS 41370b324cSopenharmony_ci return ProgressDialog.Sync.ProcessStopAndPause(); 42370b324cSopenharmony_ci #else 43370b324cSopenharmony_ci return S_OK; 44370b324cSopenharmony_ci #endif 45370b324cSopenharmony_ci} 46370b324cSopenharmony_ci 47370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */) 48370b324cSopenharmony_ci{ 49370b324cSopenharmony_ci return S_OK; 50370b324cSopenharmony_ci} 51370b324cSopenharmony_ci 52370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */) 53370b324cSopenharmony_ci{ 54370b324cSopenharmony_ci #ifndef _NO_PROGRESS 55370b324cSopenharmony_ci return ProgressDialog.Sync.ProcessStopAndPause(); 56370b324cSopenharmony_ci #else 57370b324cSopenharmony_ci return S_OK; 58370b324cSopenharmony_ci #endif 59370b324cSopenharmony_ci} 60370b324cSopenharmony_ci 61370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_Finished() 62370b324cSopenharmony_ci{ 63370b324cSopenharmony_ci return S_OK; 64370b324cSopenharmony_ci} 65370b324cSopenharmony_ci 66370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetTotal(UInt64 size)) 67370b324cSopenharmony_ci{ 68370b324cSopenharmony_ci #ifndef _NO_PROGRESS 69370b324cSopenharmony_ci ProgressDialog.Sync.SetProgress(size, 0); 70370b324cSopenharmony_ci #endif 71370b324cSopenharmony_ci return S_OK; 72370b324cSopenharmony_ci} 73370b324cSopenharmony_ci 74370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetCompleted(const UInt64 *completeValue)) 75370b324cSopenharmony_ci{ 76370b324cSopenharmony_ci #ifndef _NO_PROGRESS 77370b324cSopenharmony_ci RINOK(ProgressDialog.Sync.ProcessStopAndPause()) 78370b324cSopenharmony_ci if (completeValue != NULL) 79370b324cSopenharmony_ci ProgressDialog.Sync.SetPos(*completeValue); 80370b324cSopenharmony_ci #endif 81370b324cSopenharmony_ci return S_OK; 82370b324cSopenharmony_ci} 83370b324cSopenharmony_ci 84370b324cSopenharmony_civoid CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts) 85370b324cSopenharmony_ci{ 86370b324cSopenharmony_ci FString fullPath = _directoryPath; 87370b324cSopenharmony_ci FOR_VECTOR (i, dirPathParts) 88370b324cSopenharmony_ci { 89370b324cSopenharmony_ci fullPath += us2fs(dirPathParts[i]); 90370b324cSopenharmony_ci CreateDir(fullPath); 91370b324cSopenharmony_ci fullPath.Add_PathSepar(); 92370b324cSopenharmony_ci } 93370b324cSopenharmony_ci} 94370b324cSopenharmony_ci 95370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::GetStream(UInt32 index, 96370b324cSopenharmony_ci ISequentialOutStream **outStream, Int32 askExtractMode)) 97370b324cSopenharmony_ci{ 98370b324cSopenharmony_ci #ifndef _NO_PROGRESS 99370b324cSopenharmony_ci if (ProgressDialog.Sync.GetStopped()) 100370b324cSopenharmony_ci return E_ABORT; 101370b324cSopenharmony_ci #endif 102370b324cSopenharmony_ci _outFileStream.Release(); 103370b324cSopenharmony_ci 104370b324cSopenharmony_ci UString fullPath; 105370b324cSopenharmony_ci { 106370b324cSopenharmony_ci NCOM::CPropVariant prop; 107370b324cSopenharmony_ci RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop)) 108370b324cSopenharmony_ci if (prop.vt == VT_EMPTY) 109370b324cSopenharmony_ci fullPath = _itemDefaultName; 110370b324cSopenharmony_ci else 111370b324cSopenharmony_ci { 112370b324cSopenharmony_ci if (prop.vt != VT_BSTR) 113370b324cSopenharmony_ci return E_FAIL; 114370b324cSopenharmony_ci fullPath.SetFromBstr(prop.bstrVal); 115370b324cSopenharmony_ci } 116370b324cSopenharmony_ci _filePath = fullPath; 117370b324cSopenharmony_ci } 118370b324cSopenharmony_ci 119370b324cSopenharmony_ci if (askExtractMode == NArchive::NExtract::NAskMode::kExtract) 120370b324cSopenharmony_ci { 121370b324cSopenharmony_ci NCOM::CPropVariant prop; 122370b324cSopenharmony_ci RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop)) 123370b324cSopenharmony_ci if (prop.vt == VT_EMPTY) 124370b324cSopenharmony_ci _processedFileInfo.Attributes = _defaultAttributes; 125370b324cSopenharmony_ci else 126370b324cSopenharmony_ci { 127370b324cSopenharmony_ci if (prop.vt != VT_UI4) 128370b324cSopenharmony_ci return E_FAIL; 129370b324cSopenharmony_ci _processedFileInfo.Attributes = prop.ulVal; 130370b324cSopenharmony_ci } 131370b324cSopenharmony_ci 132370b324cSopenharmony_ci RINOK(_archiveHandler->GetProperty(index, kpidIsDir, &prop)) 133370b324cSopenharmony_ci _processedFileInfo.IsDir = VARIANT_BOOLToBool(prop.boolVal); 134370b324cSopenharmony_ci 135370b324cSopenharmony_ci bool isAnti = false; 136370b324cSopenharmony_ci { 137370b324cSopenharmony_ci NCOM::CPropVariant propTemp; 138370b324cSopenharmony_ci RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &propTemp)) 139370b324cSopenharmony_ci if (propTemp.vt == VT_BOOL) 140370b324cSopenharmony_ci isAnti = VARIANT_BOOLToBool(propTemp.boolVal); 141370b324cSopenharmony_ci } 142370b324cSopenharmony_ci 143370b324cSopenharmony_ci RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop)) 144370b324cSopenharmony_ci switch (prop.vt) 145370b324cSopenharmony_ci { 146370b324cSopenharmony_ci case VT_EMPTY: _processedFileInfo.MTime = _defaultMTime; break; 147370b324cSopenharmony_ci case VT_FILETIME: _processedFileInfo.MTime = prop.filetime; break; 148370b324cSopenharmony_ci default: return E_FAIL; 149370b324cSopenharmony_ci } 150370b324cSopenharmony_ci 151370b324cSopenharmony_ci UStringVector pathParts; 152370b324cSopenharmony_ci SplitPathToParts(fullPath, pathParts); 153370b324cSopenharmony_ci if (pathParts.IsEmpty()) 154370b324cSopenharmony_ci return E_FAIL; 155370b324cSopenharmony_ci 156370b324cSopenharmony_ci UString processedPath = fullPath; 157370b324cSopenharmony_ci 158370b324cSopenharmony_ci if (!_processedFileInfo.IsDir) 159370b324cSopenharmony_ci pathParts.DeleteBack(); 160370b324cSopenharmony_ci if (!pathParts.IsEmpty()) 161370b324cSopenharmony_ci { 162370b324cSopenharmony_ci if (!isAnti) 163370b324cSopenharmony_ci CreateComplexDirectory(pathParts); 164370b324cSopenharmony_ci } 165370b324cSopenharmony_ci 166370b324cSopenharmony_ci FString fullProcessedPath = _directoryPath + us2fs(processedPath); 167370b324cSopenharmony_ci 168370b324cSopenharmony_ci if (_processedFileInfo.IsDir) 169370b324cSopenharmony_ci { 170370b324cSopenharmony_ci _diskFilePath = fullProcessedPath; 171370b324cSopenharmony_ci 172370b324cSopenharmony_ci if (isAnti) 173370b324cSopenharmony_ci RemoveDir(_diskFilePath); 174370b324cSopenharmony_ci else 175370b324cSopenharmony_ci SetDirTime(_diskFilePath, NULL, NULL, &_processedFileInfo.MTime); 176370b324cSopenharmony_ci return S_OK; 177370b324cSopenharmony_ci } 178370b324cSopenharmony_ci 179370b324cSopenharmony_ci NFind::CFileInfo fileInfo; 180370b324cSopenharmony_ci if (fileInfo.Find(fullProcessedPath)) 181370b324cSopenharmony_ci { 182370b324cSopenharmony_ci if (!DeleteFileAlways(fullProcessedPath)) 183370b324cSopenharmony_ci { 184370b324cSopenharmony_ci _message = kCantDeleteFile; 185370b324cSopenharmony_ci return E_FAIL; 186370b324cSopenharmony_ci } 187370b324cSopenharmony_ci } 188370b324cSopenharmony_ci 189370b324cSopenharmony_ci if (!isAnti) 190370b324cSopenharmony_ci { 191370b324cSopenharmony_ci _outFileStreamSpec = new COutFileStream; 192370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec); 193370b324cSopenharmony_ci if (!_outFileStreamSpec->Create(fullProcessedPath, true)) 194370b324cSopenharmony_ci { 195370b324cSopenharmony_ci _message = kCantOpenFile; 196370b324cSopenharmony_ci return E_FAIL; 197370b324cSopenharmony_ci } 198370b324cSopenharmony_ci _outFileStream = outStreamLoc; 199370b324cSopenharmony_ci *outStream = outStreamLoc.Detach(); 200370b324cSopenharmony_ci } 201370b324cSopenharmony_ci _diskFilePath = fullProcessedPath; 202370b324cSopenharmony_ci } 203370b324cSopenharmony_ci else 204370b324cSopenharmony_ci { 205370b324cSopenharmony_ci *outStream = NULL; 206370b324cSopenharmony_ci } 207370b324cSopenharmony_ci return S_OK; 208370b324cSopenharmony_ci} 209370b324cSopenharmony_ci 210370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::PrepareOperation(Int32 askExtractMode)) 211370b324cSopenharmony_ci{ 212370b324cSopenharmony_ci _extractMode = (askExtractMode == NArchive::NExtract::NAskMode::kExtract); 213370b324cSopenharmony_ci return S_OK; 214370b324cSopenharmony_ci} 215370b324cSopenharmony_ci 216370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult)) 217370b324cSopenharmony_ci{ 218370b324cSopenharmony_ci switch (resultEOperationResult) 219370b324cSopenharmony_ci { 220370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kOK: 221370b324cSopenharmony_ci break; 222370b324cSopenharmony_ci 223370b324cSopenharmony_ci default: 224370b324cSopenharmony_ci { 225370b324cSopenharmony_ci _outFileStream.Release(); 226370b324cSopenharmony_ci switch (resultEOperationResult) 227370b324cSopenharmony_ci { 228370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kUnsupportedMethod: 229370b324cSopenharmony_ci _message = kUnsupportedMethod; 230370b324cSopenharmony_ci break; 231370b324cSopenharmony_ci default: 232370b324cSopenharmony_ci _isCorrupt = true; 233370b324cSopenharmony_ci } 234370b324cSopenharmony_ci return E_FAIL; 235370b324cSopenharmony_ci } 236370b324cSopenharmony_ci } 237370b324cSopenharmony_ci if (_outFileStream != NULL) 238370b324cSopenharmony_ci { 239370b324cSopenharmony_ci _outFileStreamSpec->SetMTime(&_processedFileInfo.MTime); 240370b324cSopenharmony_ci RINOK(_outFileStreamSpec->Close()) 241370b324cSopenharmony_ci } 242370b324cSopenharmony_ci _outFileStream.Release(); 243370b324cSopenharmony_ci if (_extractMode) 244370b324cSopenharmony_ci SetFileAttrib(_diskFilePath, _processedFileInfo.Attributes); 245370b324cSopenharmony_ci return S_OK; 246370b324cSopenharmony_ci} 247