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