1 // ExtractGUI.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../../Common/IntToString.h"
6 #include "../../../Common/StringConvert.h"
7 
8 #include "../../../Windows/FileDir.h"
9 #include "../../../Windows/FileFind.h"
10 #include "../../../Windows/FileName.h"
11 #include "../../../Windows/Thread.h"
12 
13 #include "../FileManager/ExtractCallback.h"
14 #include "../FileManager/FormatUtils.h"
15 #include "../FileManager/LangUtils.h"
16 #include "../FileManager/resourceGui.h"
17 #include "../FileManager/OverwriteDialogRes.h"
18 
19 #include "../Common/ArchiveExtractCallback.h"
20 #include "../Common/PropIDUtils.h"
21 
22 #include "../Explorer/MyMessages.h"
23 
24 #include "resource2.h"
25 #include "ExtractRes.h"
26 
27 #include "ExtractDialog.h"
28 #include "ExtractGUI.h"
29 #include "HashGUI.h"
30 
31 #include "../FileManager/PropertyNameRes.h"
32 
33 using namespace NWindows;
34 using namespace NFile;
35 using namespace NDir;
36 
37 static const wchar_t * const kIncorrectOutDir = L"Incorrect output directory path";
38 
39 #ifndef _SFX
40 
AddValuePair(UString & s,UINT resourceID,UInt64 value,bool addColon=true)41 static void AddValuePair(UString &s, UINT resourceID, UInt64 value, bool addColon = true)
42 {
43   AddLangString(s, resourceID);
44   if (addColon)
45     s += ':';
46   s.Add_Space();
47   char sz[32];
48   ConvertUInt64ToString(value, sz);
49   s += sz;
50   s.Add_LF();
51 }
52 
AddSizePair(UString & s,UINT resourceID,UInt64 value)53 static void AddSizePair(UString &s, UINT resourceID, UInt64 value)
54 {
55   AddLangString(s, resourceID);
56   s += ": ";
57   AddSizeValue(s, value);
58   s.Add_LF();
59 }
60 
61 #endif
62 
63 class CThreadExtracting: public CProgressThreadVirt
64 {
65   HRESULT ProcessVirt();
66 public:
67   CCodecs *codecs;
68   CExtractCallbackImp *ExtractCallbackSpec;
69   const CObjectVector<COpenType> *FormatIndices;
70   const CIntVector *ExcludedFormatIndices;
71 
72   UStringVector *ArchivePaths;
73   UStringVector *ArchivePathsFull;
74   const NWildcard::CCensorNode *WildcardCensor;
75   const CExtractOptions *Options;
76 
77   #ifndef _SFX
78   CHashBundle *HashBundle;
79   virtual void ProcessWasFinished_GuiVirt();
80   #endif
81 
82   CMyComPtr<IExtractCallbackUI> ExtractCallback;
83   UString Title;
84 
85   CPropNameValPairs Pairs;
86 };
87 
88 
89 #ifndef _SFX
ProcessWasFinished_GuiVirt()90 void CThreadExtracting::ProcessWasFinished_GuiVirt()
91 {
92   if (HashBundle && !Pairs.IsEmpty())
93     ShowHashResults(Pairs, *this);
94 }
95 #endif
96 
ProcessVirt()97 HRESULT CThreadExtracting::ProcessVirt()
98 {
99   CDecompressStat Stat;
100 
101   #ifndef _SFX
102   /*
103   if (HashBundle)
104     HashBundle->Init();
105   */
106   #endif
107 
108   HRESULT res = Extract(codecs,
109       *FormatIndices, *ExcludedFormatIndices,
110       *ArchivePaths, *ArchivePathsFull,
111       *WildcardCensor, *Options, ExtractCallbackSpec, ExtractCallback,
112       #ifndef _SFX
113         HashBundle,
114       #endif
115       FinalMessage.ErrorMessage.Message, Stat);
116 
117   #ifndef _SFX
118   if (res == S_OK && ExtractCallbackSpec->IsOK())
119   {
120     if (HashBundle)
121     {
122       AddValuePair(Pairs, IDS_ARCHIVES_COLON, Stat.NumArchives);
123       AddSizeValuePair(Pairs, IDS_PROP_PACKED_SIZE, Stat.PackSize);
124       AddHashBundleRes(Pairs, *HashBundle);
125     }
126     else if (Options->TestMode)
127     {
128       UString s;
129 
130       AddValuePair(s, IDS_ARCHIVES_COLON, Stat.NumArchives, false);
131       AddSizePair(s, IDS_PROP_PACKED_SIZE, Stat.PackSize);
132 
133       if (Stat.NumFolders != 0)
134         AddValuePair(s, IDS_PROP_FOLDERS, Stat.NumFolders);
135       AddValuePair(s, IDS_PROP_FILES, Stat.NumFiles);
136       AddSizePair(s, IDS_PROP_SIZE, Stat.UnpackSize);
137       if (Stat.NumAltStreams != 0)
138       {
139         s.Add_LF();
140         AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, Stat.NumAltStreams);
141         AddSizePair(s, IDS_PROP_ALT_STREAMS_SIZE, Stat.AltStreams_UnpackSize);
142       }
143       s.Add_LF();
144       AddLangString(s, IDS_MESSAGE_NO_ERRORS);
145       FinalMessage.OkMessage.Title = Title;
146       FinalMessage.OkMessage.Message = s;
147     }
148   }
149   #endif
150 
151   return res;
152 }
153 
154 
155 
ExtractGUI(CCodecs * codecs,const CObjectVector<COpenType> & formatIndices,const CIntVector & excludedFormatIndices,UStringVector & archivePaths,UStringVector & archivePathsFull,const NWildcard::CCensorNode & wildcardCensor,CExtractOptions & options,CHashBundle * hb,bool showDialog,bool & messageWasDisplayed,CExtractCallbackImp * extractCallback,HWND hwndParent)156 HRESULT ExtractGUI(
157     CCodecs *codecs,
158     const CObjectVector<COpenType> &formatIndices,
159     const CIntVector &excludedFormatIndices,
160     UStringVector &archivePaths,
161     UStringVector &archivePathsFull,
162     const NWildcard::CCensorNode &wildcardCensor,
163     CExtractOptions &options,
164     #ifndef _SFX
165     CHashBundle *hb,
166     #endif
167     bool showDialog,
168     bool &messageWasDisplayed,
169     CExtractCallbackImp *extractCallback,
170     HWND hwndParent)
171 {
172   messageWasDisplayed = false;
173 
174   CThreadExtracting extracter;
175   extracter.codecs = codecs;
176   extracter.FormatIndices = &formatIndices;
177   extracter.ExcludedFormatIndices = &excludedFormatIndices;
178 
179   if (!options.TestMode)
180   {
181     FString outputDir = options.OutputDir;
182     #ifndef UNDER_CE
183     if (outputDir.IsEmpty())
184       GetCurrentDir(outputDir);
185     #endif
186     if (showDialog)
187     {
188       CExtractDialog dialog;
189       FString outputDirFull;
190       if (!MyGetFullPathName(outputDir, outputDirFull))
191       {
192         ShowErrorMessage(kIncorrectOutDir);
193         messageWasDisplayed = true;
194         return E_FAIL;
195       }
196       NName::NormalizeDirPathPrefix(outputDirFull);
197 
198       dialog.DirPath = fs2us(outputDirFull);
199 
200       dialog.OverwriteMode = options.OverwriteMode;
201       dialog.OverwriteMode_Force = options.OverwriteMode_Force;
202       dialog.PathMode = options.PathMode;
203       dialog.PathMode_Force = options.PathMode_Force;
204       dialog.ElimDup = options.ElimDup;
205 
206       if (archivePathsFull.Size() == 1)
207         dialog.ArcPath = archivePathsFull[0];
208 
209       #ifndef _SFX
210       // dialog.AltStreams = options.NtOptions.AltStreams;
211       dialog.NtSecurity = options.NtOptions.NtSecurity;
212       if (extractCallback->PasswordIsDefined)
213         dialog.Password = extractCallback->Password;
214       #endif
215 
216       if (dialog.Create(hwndParent) != IDOK)
217         return E_ABORT;
218 
219       outputDir = us2fs(dialog.DirPath);
220 
221       options.OverwriteMode = dialog.OverwriteMode;
222       options.PathMode = dialog.PathMode;
223       options.ElimDup = dialog.ElimDup;
224 
225       #ifndef _SFX
226       // options.NtOptions.AltStreams = dialog.AltStreams;
227       options.NtOptions.NtSecurity = dialog.NtSecurity;
228       extractCallback->Password = dialog.Password;
229       extractCallback->PasswordIsDefined = !dialog.Password.IsEmpty();
230       #endif
231     }
232     if (!MyGetFullPathName(outputDir, options.OutputDir))
233     {
234       ShowErrorMessage(kIncorrectOutDir);
235       messageWasDisplayed = true;
236       return E_FAIL;
237     }
238     NName::NormalizeDirPathPrefix(options.OutputDir);
239 
240     /*
241     if (!CreateComplexDirectory(options.OutputDir))
242     {
243       UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError()));
244       UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
245       #ifdef LANG
246       0x02000603,
247       #endif
248       options.OutputDir);
249       s2.Add_LF();
250       s2 += s;
251       MyMessageBox(s2);
252       return E_FAIL;
253     }
254     */
255   }
256 
257   UString title = LangString(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING);
258 
259   extracter.Title = title;
260   extracter.ExtractCallbackSpec = extractCallback;
261   extracter.ExtractCallbackSpec->ProgressDialog = &extracter;
262   extracter.ExtractCallback = extractCallback;
263   extracter.ExtractCallbackSpec->Init();
264 
265   extracter.CompressingMode = false;
266 
267   extracter.ArchivePaths = &archivePaths;
268   extracter.ArchivePathsFull = &archivePathsFull;
269   extracter.WildcardCensor = &wildcardCensor;
270   extracter.Options = &options;
271   #ifndef _SFX
272   extracter.HashBundle = hb;
273   #endif
274 
275   extracter.IconID = IDI_ICON;
276 
277   RINOK(extracter.Create(title, hwndParent));
278   messageWasDisplayed = extracter.ThreadFinishedOK && extracter.MessagesDisplayed;
279   return extracter.Result;
280 }
281