Home | History | Annotate | Download | only in SFXSetup
      1 // ExtractEngine.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "../../../Windows/FileDir.h"
      6 #include "../../../Windows/FileName.h"
      7 #include "../../../Windows/Thread.h"
      8 
      9 #include "../../UI/Common/OpenArchive.h"
     10 
     11 #include "../../UI/FileManager/FormatUtils.h"
     12 #include "../../UI/FileManager/LangUtils.h"
     13 
     14 #include "ExtractCallbackSfx.h"
     15 #include "ExtractEngine.h"
     16 
     17 using namespace NWindows;
     18 using namespace NFile;
     19 using namespace NDir;
     20 
     21 static LPCWSTR kCantFindArchive = L"Can not find archive file";
     22 static LPCWSTR kCantOpenArchive = L"Can not open the file as archive";
     23 
     24 struct CThreadExtracting
     25 {
     26   CCodecs *Codecs;
     27   FString FileName;
     28   FString DestFolder;
     29 
     30   CExtractCallbackImp *ExtractCallbackSpec;
     31   CMyComPtr<IArchiveExtractCallback> ExtractCallback;
     32 
     33   CArchiveLink ArchiveLink;
     34   HRESULT Result;
     35   UString ErrorMessage;
     36 
     37   void Process2()
     38   {
     39     NFind::CFileInfo fi;
     40     if (!fi.Find(FileName))
     41     {
     42       ErrorMessage = kCantFindArchive;
     43       Result = E_FAIL;
     44       return;
     45     }
     46 
     47     CObjectVector<COpenType> incl;
     48     CIntVector excl;
     49     COpenOptions options;
     50     options.codecs = Codecs;
     51     options.types = &incl;
     52     options.excludedFormats = &excl;
     53     options.filePath = fs2us(FileName);
     54 
     55     Result = ArchiveLink.Open2(options, ExtractCallbackSpec);
     56     if (Result != S_OK)
     57     {
     58       if (Result != S_OK)
     59         ErrorMessage = kCantOpenArchive;
     60       return;
     61     }
     62 
     63     FString dirPath = DestFolder;
     64     NName::NormalizeDirPathPrefix(dirPath);
     65 
     66     if (!CreateComplexDir(dirPath))
     67     {
     68       ErrorMessage = MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
     69         #ifdef LANG
     70         0x02000603,
     71         #endif
     72         fs2us(dirPath));
     73       Result = E_FAIL;
     74       return;
     75     }
     76 
     77     ExtractCallbackSpec->Init(ArchiveLink.GetArchive(), dirPath, L"Default", fi.MTime, 0);
     78 
     79     Result = ArchiveLink.GetArchive()->Extract(0, (UInt32)(Int32)-1 , BoolToInt(false), ExtractCallback);
     80   }
     81 
     82   void Process()
     83   {
     84     try
     85     {
     86       #ifndef _NO_PROGRESS
     87       CProgressCloser closer(ExtractCallbackSpec->ProgressDialog);
     88       #endif
     89       Process2();
     90     }
     91     catch(...) { Result = E_FAIL; }
     92   }
     93 
     94   static THREAD_FUNC_DECL MyThreadFunction(void *param)
     95   {
     96     ((CThreadExtracting *)param)->Process();
     97     return 0;
     98   }
     99 };
    100 
    101 HRESULT ExtractArchive(CCodecs *codecs, const FString &fileName, const FString &destFolder,
    102     bool showProgress, bool &isCorrupt, UString &errorMessage)
    103 {
    104   isCorrupt = false;
    105   CThreadExtracting t;
    106 
    107   t.Codecs = codecs;
    108   t.FileName = fileName;
    109   t.DestFolder = destFolder;
    110 
    111   t.ExtractCallbackSpec = new CExtractCallbackImp;
    112   t.ExtractCallback = t.ExtractCallbackSpec;
    113 
    114   #ifndef _NO_PROGRESS
    115 
    116   if (showProgress)
    117   {
    118     t.ExtractCallbackSpec->ProgressDialog.IconID = IDI_ICON;
    119     NWindows::CThread thread;
    120     RINOK(thread.Create(CThreadExtracting::MyThreadFunction, &t));
    121 
    122     UString title;
    123     LangString(IDS_PROGRESS_EXTRACTING, title);
    124     t.ExtractCallbackSpec->StartProgressDialog(title, thread);
    125   }
    126   else
    127 
    128   #endif
    129   {
    130     t.Process2();
    131   }
    132 
    133   errorMessage = t.ErrorMessage;
    134   if (errorMessage.IsEmpty())
    135     errorMessage = t.ExtractCallbackSpec->_message;
    136   isCorrupt = t.ExtractCallbackSpec->_isCorrupt;
    137   return t.Result;
    138 }
    139