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 s.Add_UInt64(value);
48 s.Add_LF();
49 }
50
AddSizePair(UString & s,UINT resourceID,UInt64 value)51 static void AddSizePair(UString &s, UINT resourceID, UInt64 value)
52 {
53 AddLangString(s, resourceID);
54 s += ": ";
55 AddSizeValue(s, value);
56 s.Add_LF();
57 }
58
59 #endif
60
61 class CThreadExtracting: public CProgressThreadVirt
62 {
63 HRESULT ProcessVirt();
64 public:
65 /*
66 #ifdef EXTERNAL_CODECS
67 const CExternalCodecs *externalCodecs;
68 #endif
69 */
70
71 CCodecs *codecs;
72 CExtractCallbackImp *ExtractCallbackSpec;
73 const CObjectVector<COpenType> *FormatIndices;
74 const CIntVector *ExcludedFormatIndices;
75
76 UStringVector *ArchivePaths;
77 UStringVector *ArchivePathsFull;
78 const NWildcard::CCensorNode *WildcardCensor;
79 const CExtractOptions *Options;
80
81 #ifndef _SFX
82 CHashBundle *HashBundle;
83 virtual void ProcessWasFinished_GuiVirt();
84 #endif
85
86 CMyComPtr<IExtractCallbackUI> ExtractCallback;
87 UString Title;
88
89 CPropNameValPairs Pairs;
90 };
91
92
93 #ifndef _SFX
ProcessWasFinished_GuiVirt()94 void CThreadExtracting::ProcessWasFinished_GuiVirt()
95 {
96 if (HashBundle && !Pairs.IsEmpty())
97 ShowHashResults(Pairs, *this);
98 }
99 #endif
100
ProcessVirt()101 HRESULT CThreadExtracting::ProcessVirt()
102 {
103 CDecompressStat Stat;
104
105 #ifndef _SFX
106 /*
107 if (HashBundle)
108 HashBundle->Init();
109 */
110 #endif
111
112 HRESULT res = Extract(
113 /*
114 #ifdef EXTERNAL_CODECS
115 externalCodecs,
116 #endif
117 */
118 codecs,
119 *FormatIndices, *ExcludedFormatIndices,
120 *ArchivePaths, *ArchivePathsFull,
121 *WildcardCensor, *Options, ExtractCallbackSpec, ExtractCallback,
122 #ifndef _SFX
123 HashBundle,
124 #endif
125 FinalMessage.ErrorMessage.Message, Stat);
126
127 #ifndef _SFX
128 if (res == S_OK && ExtractCallbackSpec->IsOK())
129 {
130 if (HashBundle)
131 {
132 AddValuePair(Pairs, IDS_ARCHIVES_COLON, Stat.NumArchives);
133 AddSizeValuePair(Pairs, IDS_PROP_PACKED_SIZE, Stat.PackSize);
134 AddHashBundleRes(Pairs, *HashBundle);
135 }
136 else if (Options->TestMode)
137 {
138 UString s;
139
140 AddValuePair(s, IDS_ARCHIVES_COLON, Stat.NumArchives, false);
141 AddSizePair(s, IDS_PROP_PACKED_SIZE, Stat.PackSize);
142
143 if (Stat.NumFolders != 0)
144 AddValuePair(s, IDS_PROP_FOLDERS, Stat.NumFolders);
145 AddValuePair(s, IDS_PROP_FILES, Stat.NumFiles);
146 AddSizePair(s, IDS_PROP_SIZE, Stat.UnpackSize);
147 if (Stat.NumAltStreams != 0)
148 {
149 s.Add_LF();
150 AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, Stat.NumAltStreams);
151 AddSizePair(s, IDS_PROP_ALT_STREAMS_SIZE, Stat.AltStreams_UnpackSize);
152 }
153 s.Add_LF();
154 AddLangString(s, IDS_MESSAGE_NO_ERRORS);
155 FinalMessage.OkMessage.Title = Title;
156 FinalMessage.OkMessage.Message = s;
157 }
158 }
159 #endif
160
161 return res;
162 }
163
164
165
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)166 HRESULT ExtractGUI(
167 // DECL_EXTERNAL_CODECS_LOC_VARS
168 CCodecs *codecs,
169 const CObjectVector<COpenType> &formatIndices,
170 const CIntVector &excludedFormatIndices,
171 UStringVector &archivePaths,
172 UStringVector &archivePathsFull,
173 const NWildcard::CCensorNode &wildcardCensor,
174 CExtractOptions &options,
175 #ifndef _SFX
176 CHashBundle *hb,
177 #endif
178 bool showDialog,
179 bool &messageWasDisplayed,
180 CExtractCallbackImp *extractCallback,
181 HWND hwndParent)
182 {
183 messageWasDisplayed = false;
184
185 CThreadExtracting extracter;
186 /*
187 #ifdef EXTERNAL_CODECS
188 extracter.externalCodecs = __externalCodecs;
189 #endif
190 */
191 extracter.codecs = codecs;
192 extracter.FormatIndices = &formatIndices;
193 extracter.ExcludedFormatIndices = &excludedFormatIndices;
194
195 if (!options.TestMode)
196 {
197 FString outputDir = options.OutputDir;
198 #ifndef UNDER_CE
199 if (outputDir.IsEmpty())
200 GetCurrentDir(outputDir);
201 #endif
202 if (showDialog)
203 {
204 CExtractDialog dialog;
205 FString outputDirFull;
206 if (!MyGetFullPathName(outputDir, outputDirFull))
207 {
208 ShowErrorMessage(kIncorrectOutDir);
209 messageWasDisplayed = true;
210 return E_FAIL;
211 }
212 NName::NormalizeDirPathPrefix(outputDirFull);
213
214 dialog.DirPath = fs2us(outputDirFull);
215
216 dialog.OverwriteMode = options.OverwriteMode;
217 dialog.OverwriteMode_Force = options.OverwriteMode_Force;
218 dialog.PathMode = options.PathMode;
219 dialog.PathMode_Force = options.PathMode_Force;
220 dialog.ElimDup = options.ElimDup;
221
222 if (archivePathsFull.Size() == 1)
223 dialog.ArcPath = archivePathsFull[0];
224
225 #ifndef _SFX
226 // dialog.AltStreams = options.NtOptions.AltStreams;
227 dialog.NtSecurity = options.NtOptions.NtSecurity;
228 if (extractCallback->PasswordIsDefined)
229 dialog.Password = extractCallback->Password;
230 #endif
231
232 if (dialog.Create(hwndParent) != IDOK)
233 return E_ABORT;
234
235 outputDir = us2fs(dialog.DirPath);
236
237 options.OverwriteMode = dialog.OverwriteMode;
238 options.PathMode = dialog.PathMode;
239 options.ElimDup = dialog.ElimDup;
240
241 #ifndef _SFX
242 // options.NtOptions.AltStreams = dialog.AltStreams;
243 options.NtOptions.NtSecurity = dialog.NtSecurity;
244 extractCallback->Password = dialog.Password;
245 extractCallback->PasswordIsDefined = !dialog.Password.IsEmpty();
246 #endif
247 }
248 if (!MyGetFullPathName(outputDir, options.OutputDir))
249 {
250 ShowErrorMessage(kIncorrectOutDir);
251 messageWasDisplayed = true;
252 return E_FAIL;
253 }
254 NName::NormalizeDirPathPrefix(options.OutputDir);
255
256 /*
257 if (!CreateComplexDirectory(options.OutputDir))
258 {
259 UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError()));
260 UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
261 #ifdef LANG
262 0x02000603,
263 #endif
264 options.OutputDir);
265 s2.Add_LF();
266 s2 += s;
267 MyMessageBox(s2);
268 return E_FAIL;
269 }
270 */
271 }
272
273 UString title = LangString(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING);
274
275 extracter.Title = title;
276 extracter.ExtractCallbackSpec = extractCallback;
277 extracter.ExtractCallbackSpec->ProgressDialog = &extracter;
278 extracter.ExtractCallback = extractCallback;
279 extracter.ExtractCallbackSpec->Init();
280
281 extracter.CompressingMode = false;
282
283 extracter.ArchivePaths = &archivePaths;
284 extracter.ArchivePathsFull = &archivePathsFull;
285 extracter.WildcardCensor = &wildcardCensor;
286 extracter.Options = &options;
287 #ifndef _SFX
288 extracter.HashBundle = hb;
289 #endif
290
291 extracter.IconID = IDI_ICON;
292
293 RINOK(extracter.Create(title, hwndParent));
294 messageWasDisplayed = extracter.ThreadFinishedOK && extracter.MessagesDisplayed;
295 return extracter.Result;
296 }
297