tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ExtractCallbackSfx.cpp (6346B)


      1 // ExtractCallbackSfx.h
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "../../../Common/Wildcard.h"
      6 
      7 #include "../../../Windows/FileDir.h"
      8 #include "../../../Windows/FileFind.h"
      9 #include "../../../Windows/FileName.h"
     10 #include "../../../Windows/PropVariant.h"
     11 
     12 #include "ExtractCallbackSfx.h"
     13 
     14 using namespace NWindows;
     15 using namespace NFile;
     16 using namespace NDir;
     17 
     18 static LPCSTR const kCantDeleteFile = "Can not delete output file";
     19 static LPCSTR const kCantOpenFile = "Can not open output file";
     20 static LPCSTR const kUnsupportedMethod = "Unsupported Method";
     21 
     22 void CExtractCallbackImp::Init(IInArchive *archiveHandler,
     23    const FString &directoryPath,
     24    const UString &itemDefaultName,
     25    const FILETIME &defaultMTime,
     26    UInt32 defaultAttributes)
     27 {
     28  _message.Empty();
     29  _isCorrupt = false;
     30  _itemDefaultName = itemDefaultName;
     31  _defaultMTime = defaultMTime;
     32  _defaultAttributes = defaultAttributes;
     33  _archiveHandler = archiveHandler;
     34  _directoryPath = directoryPath;
     35  NName::NormalizeDirPathPrefix(_directoryPath);
     36 }
     37 
     38 HRESULT CExtractCallbackImp::Open_CheckBreak()
     39 {
     40  #ifndef _NO_PROGRESS
     41  return ProgressDialog.Sync.ProcessStopAndPause();
     42  #else
     43  return S_OK;
     44  #endif
     45 }
     46 
     47 HRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */)
     48 {
     49  return S_OK;
     50 }
     51 
     52 HRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */)
     53 {
     54  #ifndef _NO_PROGRESS
     55  return ProgressDialog.Sync.ProcessStopAndPause();
     56  #else
     57  return S_OK;
     58  #endif
     59 }
     60 
     61 HRESULT CExtractCallbackImp::Open_Finished()
     62 {
     63  return S_OK;
     64 }
     65 
     66 STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 size)
     67 {
     68  #ifndef _NO_PROGRESS
     69  ProgressDialog.Sync.SetProgress(size, 0);
     70  #endif
     71  return S_OK;
     72 }
     73 
     74 STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue)
     75 {
     76  #ifndef _NO_PROGRESS
     77  RINOK(ProgressDialog.Sync.ProcessStopAndPause());
     78  if (completeValue != NULL)
     79    ProgressDialog.Sync.SetPos(*completeValue);
     80  #endif
     81  return S_OK;
     82 }
     83 
     84 void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts)
     85 {
     86  FString fullPath = _directoryPath;
     87  FOR_VECTOR (i, dirPathParts)
     88  {
     89    fullPath += us2fs(dirPathParts[i]);
     90    CreateDir(fullPath);
     91    fullPath.Add_PathSepar();
     92  }
     93 }
     94 
     95 STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index,
     96    ISequentialOutStream **outStream, Int32 askExtractMode)
     97 {
     98  #ifndef _NO_PROGRESS
     99  if (ProgressDialog.Sync.GetStopped())
    100    return E_ABORT;
    101  #endif
    102  _outFileStream.Release();
    103 
    104  UString fullPath;
    105  {
    106    NCOM::CPropVariant prop;
    107    RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop));
    108    if (prop.vt == VT_EMPTY)
    109      fullPath = _itemDefaultName;
    110    else
    111    {
    112      if (prop.vt != VT_BSTR)
    113        return E_FAIL;
    114      fullPath.SetFromBstr(prop.bstrVal);
    115    }
    116    _filePath = fullPath;
    117  }
    118 
    119  if (askExtractMode == NArchive::NExtract::NAskMode::kExtract)
    120  {
    121    NCOM::CPropVariant prop;
    122    RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop));
    123    if (prop.vt == VT_EMPTY)
    124      _processedFileInfo.Attributes = _defaultAttributes;
    125    else
    126    {
    127      if (prop.vt != VT_UI4)
    128        return E_FAIL;
    129      _processedFileInfo.Attributes = prop.ulVal;
    130    }
    131 
    132    RINOK(_archiveHandler->GetProperty(index, kpidIsDir, &prop));
    133    _processedFileInfo.IsDir = VARIANT_BOOLToBool(prop.boolVal);
    134 
    135    bool isAnti = false;
    136    {
    137      NCOM::CPropVariant propTemp;
    138      RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &propTemp));
    139      if (propTemp.vt == VT_BOOL)
    140        isAnti = VARIANT_BOOLToBool(propTemp.boolVal);
    141    }
    142 
    143    RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop));
    144    switch (prop.vt)
    145    {
    146      case VT_EMPTY: _processedFileInfo.MTime = _defaultMTime; break;
    147      case VT_FILETIME: _processedFileInfo.MTime = prop.filetime; break;
    148      default: return E_FAIL;
    149    }
    150 
    151    UStringVector pathParts;
    152    SplitPathToParts(fullPath, pathParts);
    153    if (pathParts.IsEmpty())
    154      return E_FAIL;
    155 
    156    UString processedPath = fullPath;
    157 
    158    if (!_processedFileInfo.IsDir)
    159      pathParts.DeleteBack();
    160    if (!pathParts.IsEmpty())
    161    {
    162      if (!isAnti)
    163        CreateComplexDirectory(pathParts);
    164    }
    165 
    166    FString fullProcessedPath = _directoryPath + us2fs(processedPath);
    167 
    168    if (_processedFileInfo.IsDir)
    169    {
    170      _diskFilePath = fullProcessedPath;
    171 
    172      if (isAnti)
    173        RemoveDir(_diskFilePath);
    174      else
    175        SetDirTime(_diskFilePath, NULL, NULL, &_processedFileInfo.MTime);
    176      return S_OK;
    177    }
    178 
    179    NFind::CFileInfo fileInfo;
    180    if (fileInfo.Find(fullProcessedPath))
    181    {
    182      if (!DeleteFileAlways(fullProcessedPath))
    183      {
    184        _message = kCantDeleteFile;
    185        return E_FAIL;
    186      }
    187    }
    188 
    189    if (!isAnti)
    190    {
    191      _outFileStreamSpec = new COutFileStream;
    192      CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
    193      if (!_outFileStreamSpec->Create(fullProcessedPath, true))
    194      {
    195        _message = kCantOpenFile;
    196        return E_FAIL;
    197      }
    198      _outFileStream = outStreamLoc;
    199      *outStream = outStreamLoc.Detach();
    200    }
    201    _diskFilePath = fullProcessedPath;
    202  }
    203  else
    204  {
    205    *outStream = NULL;
    206  }
    207  return S_OK;
    208 }
    209 
    210 STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode)
    211 {
    212  _extractMode = (askExtractMode == NArchive::NExtract::NAskMode::kExtract);
    213  return S_OK;
    214 }
    215 
    216 STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult)
    217 {
    218  switch (resultEOperationResult)
    219  {
    220    case NArchive::NExtract::NOperationResult::kOK:
    221      break;
    222 
    223    default:
    224    {
    225      _outFileStream.Release();
    226      switch (resultEOperationResult)
    227      {
    228        case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
    229          _message = kUnsupportedMethod;
    230          break;
    231        default:
    232          _isCorrupt = true;
    233      }
    234      return E_FAIL;
    235    }
    236  }
    237  if (_outFileStream != NULL)
    238  {
    239    _outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);
    240    RINOK(_outFileStreamSpec->Close());
    241  }
    242  _outFileStream.Release();
    243  if (_extractMode)
    244    SetFileAttrib(_diskFilePath, _processedFileInfo.Attributes);
    245  return S_OK;
    246 }