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 *kIncorrectOutDir = L"Incorrect output directory path"; 38 39#ifndef _SFX 40 41static void AddValuePair(UString &s, UINT resourceID, UInt64 value, bool addColon = true) 42{ 43 AddLangString(s, resourceID); 44 if (addColon) 45 s += L':'; 46 s.Add_Space(); 47 char sz[32]; 48 ConvertUInt64ToString(value, sz); 49 s.AddAscii(sz); 50 s.Add_LF(); 51} 52 53static void AddSizePair(UString &s, UINT resourceID, UInt64 value) 54{ 55 wchar_t sz[32]; 56 AddLangString(s, 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.Add_LF(); 69} 70 71#endif 72 73class CThreadExtracting: public CProgressThreadVirt 74{ 75 HRESULT ProcessVirt(); 76public: 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 93HRESULT 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.Add_LF(); 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.Add_LF(); 134 AddHashBundleRes(s, *HashBundle, UString()); 135 } 136 137 s.Add_LF(); 138 AddLangString(s, IDS_MESSAGE_NO_ERRORS); 139 140 FinalMessage.OkMessage.Title = Title; 141 FinalMessage.OkMessage.Message = s; 142 } 143 #endif 144 return res; 145} 146 147HRESULT 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 s2.Add_LF(); 241 s2 += s; 242 MyMessageBox(s2); 243 return E_FAIL; 244 } 245 */ 246 } 247 248 UString title = LangString(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING); 249 250 extracter.Title = title; 251 extracter.ExtractCallbackSpec = extractCallback; 252 extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog; 253 extracter.ExtractCallback = extractCallback; 254 extracter.ExtractCallbackSpec->Init(); 255 256 extracter.ProgressDialog.CompressingMode = false; 257 258 extracter.ArchivePaths = &archivePaths; 259 extracter.ArchivePathsFull = &archivePathsFull; 260 extracter.WildcardCensor = &wildcardCensor; 261 extracter.Options = &options; 262 #ifndef _SFX 263 extracter.HashBundle = hb; 264 #endif 265 266 extracter.ProgressDialog.IconID = IDI_ICON; 267 268 RINOK(extracter.Create(title, hwndParent)); 269 messageWasDisplayed = extracter.ThreadFinishedOK & 270 extracter.ProgressDialog.MessagesDisplayed; 271 return extracter.Result; 272} 273