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 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 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 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 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