• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 LPCSTR const kCantFindArchive = "Cannot find archive file";
22 static LPCSTR const kCantOpenArchive = "Cannot 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 
Process2CThreadExtracting37   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       ErrorMessage = kCantOpenArchive;
59       return;
60     }
61 
62     FString dirPath = DestFolder;
63     NName::NormalizeDirPathPrefix(dirPath);
64 
65     if (!CreateComplexDir(dirPath))
66     {
67       ErrorMessage = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, fs2us(dirPath));
68       Result = E_FAIL;
69       return;
70     }
71 
72     ExtractCallbackSpec->Init(ArchiveLink.GetArchive(), dirPath, (UString)"Default", fi.MTime, 0);
73 
74     Result = ArchiveLink.GetArchive()->Extract(NULL, (UInt32)(Int32)-1 , BoolToInt(false), ExtractCallback);
75   }
76 
ProcessCThreadExtracting77   void Process()
78   {
79     try
80     {
81       #ifndef _NO_PROGRESS
82       CProgressCloser closer(ExtractCallbackSpec->ProgressDialog);
83       #endif
84       Process2();
85     }
86     catch(...) { Result = E_FAIL; }
87   }
88 
MyThreadFunctionCThreadExtracting89   static THREAD_FUNC_DECL MyThreadFunction(void *param)
90   {
91     ((CThreadExtracting *)param)->Process();
92     return 0;
93   }
94 };
95 
ExtractArchive(CCodecs * codecs,const FString & fileName,const FString & destFolder,bool showProgress,bool & isCorrupt,UString & errorMessage)96 HRESULT ExtractArchive(CCodecs *codecs, const FString &fileName, const FString &destFolder,
97     bool showProgress, bool &isCorrupt, UString &errorMessage)
98 {
99   isCorrupt = false;
100   CThreadExtracting t;
101 
102   t.Codecs = codecs;
103   t.FileName = fileName;
104   t.DestFolder = destFolder;
105 
106   t.ExtractCallbackSpec = new CExtractCallbackImp;
107   t.ExtractCallback = t.ExtractCallbackSpec;
108 
109   #ifndef _NO_PROGRESS
110 
111   if (showProgress)
112   {
113     t.ExtractCallbackSpec->ProgressDialog.IconID = IDI_ICON;
114     NWindows::CThread thread;
115     const WRes wres = thread.Create(CThreadExtracting::MyThreadFunction, &t);
116     if (wres != 0)
117       return HRESULT_FROM_WIN32(wres);
118 
119     UString title;
120     LangString(IDS_PROGRESS_EXTRACTING, title);
121     t.ExtractCallbackSpec->StartProgressDialog(title, thread);
122   }
123   else
124 
125   #endif
126   {
127     t.Process2();
128   }
129 
130   errorMessage = t.ErrorMessage;
131   if (errorMessage.IsEmpty())
132     errorMessage = t.ExtractCallbackSpec->_message;
133   isCorrupt = t.ExtractCallbackSpec->_isCorrupt;
134   return t.Result;
135 }
136