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