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