static void EnumerateDirectory( const UString &baseFolderPrefix, // base (disk) prefix for scanning const UString &directory, // additional disk prefix starting from baseFolderPrefix const UString &prefix, // logical prefix CObjectVector<CDirItem> &dirItems, UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes) { NFind::CEnumeratorW enumerator(baseFolderPrefix + directory + wchar_t(kAnyStringWildcard)); for (;;) { NFind::CFileInfoW fileInfo; bool found; if (!enumerator.Next(fileInfo, found)) { errorCodes.Add(::GetLastError()); errorPaths.Add(baseFolderPrefix + directory); return; } if (!found) break; AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, dirItems); if (fileInfo.IsDirectory()) { EnumerateDirectory(baseFolderPrefix, directory + fileInfo.Name + wchar_t(kDirDelimiter), prefix + fileInfo.Name + wchar_t(kDirDelimiter), dirItems, errorPaths, errorCodes); } } }
void EnumerateDirItems( const UString &baseFolderPrefix, // base (disk) prefix for scanning const UStringVector &fileNames, // names relative to baseFolderPrefix const UString &archiveNamePrefix, CObjectVector<CDirItem> &dirItems, UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes) { for(int i = 0; i < fileNames.Size(); i++) { const UString &fileName = fileNames[i]; NFind::CFileInfoW fileInfo; if (!NFind::FindFile(baseFolderPrefix + fileName, fileInfo)) { errorCodes.Add(::GetLastError()); errorPaths.Add(baseFolderPrefix + fileName); continue; } AddDirFileInfo(archiveNamePrefix, fileName, fileInfo, dirItems); if (fileInfo.IsDirectory()) { EnumerateDirectory(baseFolderPrefix, fileName + wchar_t(kDirDelimiter), archiveNamePrefix + fileInfo.Name + wchar_t(kDirDelimiter), dirItems, errorPaths, errorCodes); } } }
void CDirItems::EnumerateDirectory(int phyParent, int logParent, const UString &phyPrefix, UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes) { NFind::CEnumeratorW enumerator(phyPrefix + (wchar_t)kAnyStringWildcard); for (;;) { NFind::CFileInfoW fi; bool found; if (!enumerator.Next(fi, found)) { errorCodes.Add(::GetLastError()); errorPaths.Add(phyPrefix); return; } if (!found) break; AddDirFileInfo(phyParent, logParent, fi, Items); if (fi.IsDir()) { const UString name2 = fi.Name + (wchar_t)kDirDelimiter; int parent = AddPrefix(phyParent, logParent, name2); EnumerateDirectory(parent, parent, phyPrefix + name2, errorPaths, errorCodes); } } }
void CDirItems::EnumerateDirItems2(const UString &phyPrefix, const UString &logPrefix, const UStringVector &filePaths, UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes) { int phyParent = phyPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, phyPrefix); int logParent = logPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, logPrefix); for (int i = 0; i < filePaths.Size(); i++) { const UString &filePath = filePaths[i]; NFind::CFileInfoW fi; const UString phyPath = phyPrefix + filePath; if (!fi.Find(phyPath)) { errorCodes.Add(::GetLastError()); errorPaths.Add(phyPath); continue; } int delimiter = filePath.ReverseFind((wchar_t)kDirDelimiter); UString phyPrefixCur; int phyParentCur = phyParent; if (delimiter >= 0) { phyPrefixCur = filePath.Left(delimiter + 1); phyParentCur = AddPrefix(phyParent, logParent, phyPrefixCur); } AddDirFileInfo(phyParentCur, logParent, fi, Items); if (fi.IsDir()) { const UString name2 = fi.Name + (wchar_t)kDirDelimiter; int parent = AddPrefix(phyParentCur, logParent, name2); EnumerateDirectory(parent, parent, phyPrefix + phyPrefixCur + name2, errorPaths, errorCodes); } } ReserveDown(); }
HRESULT CPanel::OpenParentArchiveFolder() { CDisableTimerProcessing disableTimerProcessing1(*this); if (_parentFolders.Size() < 2) return S_OK; const CFolderLink &folderLink = _parentFolders.Back(); NFind::CFileInfoW newFileInfo; if (newFileInfo.Find(folderLink.FilePath)) { if (folderLink.WasChanged(newFileInfo)) { UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, 0x03020280, folderLink.ItemName); if (::MessageBoxW(HWND(*this), message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK) { if (OnOpenItemChanged(folderLink.FolderPath, folderLink.ItemName, folderLink.UsePassword, folderLink.Password) != S_OK) { ::MessageBoxW(HWND(*this), MyFormatNew(IDS_CANNOT_UPDATE_FILE, 0x03020281, folderLink.FilePath), L"7-Zip", MB_OK | MB_ICONSTOP); return S_OK; } } } } folderLink.DeleteDirAndFile(); return S_OK; }
static THREAD_FUNC_DECL MyThreadFunction(void *param) { CMyAutoPtr<CTmpProcessInfo> tmpProcessInfoPtr((CTmpProcessInfo *)param); const CTmpProcessInfo *tmpProcessInfo = tmpProcessInfoPtr.get(); HANDLE hProcess = tmpProcessInfo->ProcessHandle; HANDLE events[2] = { g_ExitEventLauncher._exitEvent, hProcess}; DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); ::CloseHandle(hProcess); if (waitResult == WAIT_OBJECT_0 + 0) return 0; if (waitResult != WAIT_OBJECT_0 + 1) return 1; Sleep(200); NFind::CFileInfoW newFileInfo; if (newFileInfo.Find(tmpProcessInfo->FilePath)) { if (tmpProcessInfo->WasChanged(newFileInfo)) { UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, 0x03020280, tmpProcessInfo->ItemName); if (::MessageBoxW(g_HWND, message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK) { if (SendMessage(tmpProcessInfo->Window, kOpenItemChanged, 0, (LONG_PTR)tmpProcessInfo) != 1) { ::MessageBoxW(g_HWND, MyFormatNew(IDS_CANNOT_UPDATE_FILE, 0x03020281, tmpProcessInfo->FilePath), L"7-Zip", MB_OK | MB_ICONSTOP); return 0; } } } } tmpProcessInfo->DeleteDirAndFile(); return 0; }
void ReadPluginInfoList(CObjectVector<CPluginInfo> &plugins) { plugins.Clear(); UString baseFolderPrefix; GetProgramFolderPath(baseFolderPrefix); { CPluginInfo pluginInfo; pluginInfo.FilePath = baseFolderPrefix + L"7-zip.dll"; if (::ReadPluginInfo(pluginInfo, false)) plugins.Add(pluginInfo); } UString folderPath = baseFolderPrefix + L"Plugins" WSTRING_PATH_SEPARATOR; NFind::CEnumeratorW enumerator(folderPath + L"*"); NFind::CFileInfoW fileInfo; while (enumerator.Next(fileInfo)) { if (fileInfo.IsDir()) continue; CPluginInfo pluginInfo; pluginInfo.FilePath = folderPath + fileInfo.Name; if (::ReadPluginInfo(pluginInfo, true)) plugins.Add(pluginInfo); } }
CSysString GetBaseFolderPrefixFromRegistry() { CSysString moduleFolderPrefix = GetLibraryFolderPrefix(); #ifdef _UNICODE NFind::CFileInfoW fi; #else NFind::CFileInfo fi; #endif if (NFind::FindFile(moduleFolderPrefix + kMainDll, fi)) if (!fi.IsDir()) return moduleFolderPrefix; if (NFind::FindFile(moduleFolderPrefix + kCodecsFolderName, fi)) if (fi.IsDir()) return moduleFolderPrefix; if (NFind::FindFile(moduleFolderPrefix + kFormatsFolderName, fi)) if (fi.IsDir()) return moduleFolderPrefix; #ifdef _WIN32 CSysString path; if (ReadPathFromRegistry(HKEY_CURRENT_USER, path)) return path; if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, path)) return path; #endif return moduleFolderPrefix; }
static void ConvertToLongName(const UString &prefix, UString &name) { if (name.IsEmpty() || DoesNameContainWildCard(name)) return; NFind::CFileInfoW fi; if (fi.Find(prefix + name)) name = fi.Name; }
static UString GetBaseFolderPrefixFromRegistry() { UString moduleFolderPrefix = GetModuleFolderPrefix(); NFind::CFileInfoW fileInfo; if (NFind::FindFile(moduleFolderPrefix + kFormatFolderName, fileInfo)) if (fileInfo.IsDirectory()) return moduleFolderPrefix; UString path; #ifdef _WIN32 if(ReadPathFromRegistry(HKEY_CURRENT_USER, path)) return path; if(ReadPathFromRegistry(HKEY_LOCAL_MACHINE, path)) return path; #endif return moduleFolderPrefix; }
bool CDirEnumerator::GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UString &resPath, DWORD &errorCode) { filled = false; for (;;) { if (Enumerators.IsEmpty()) { if (Index >= FileNames.Size()) return true; const UString &path = FileNames[Index]; int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR); resPath.Empty(); if (pos >= 0) resPath = path.Left(pos + 1); if (!NFind::FindFile(BasePrefix + path, fileInfo)) { errorCode = ::GetLastError(); resPath = path; return false; } Index++; break; } bool found; if (!Enumerators.Back().Next(fileInfo, found)) { errorCode = ::GetLastError(); resPath = Prefixes.Back(); return false; } if (found) { resPath = Prefixes.Back(); break; } Enumerators.DeleteBack(); Prefixes.DeleteBack(); } resPath += fileInfo.Name; if (!FlatMode && fileInfo.IsDir()) { UString prefix = resPath + (UString)(wchar_t)kDirDelimiter; Enumerators.Add(NFind::CEnumeratorW(BasePrefix + prefix + (UString)(wchar_t)kAnyStringWildcard)); Prefixes.Add(prefix); } filled = true; return true; }
void AddDirFileInfo( const UString &prefix, // prefix for logical path const UString &fullPathName, // path on disk: can be relative to some basePrefix const NFind::CFileInfoW &fileInfo, CObjectVector<CDirItem> &dirItems) { CDirItem item; item.Attributes = fileInfo.getAttributes(); item.Size = fileInfo.getSize(); item.CreationTime = fileInfo.getCreationTime(); item.LastAccessTime = fileInfo.getLastAccessTime(); item.LastWriteTime = fileInfo.getLastWriteTime(); item.Name = prefix + fileInfo.getFileName(); item.FullPath = fullPathName; dirItems.Add(item); }
int Main2( #ifndef _WIN32 int numArguments, const char *arguments[] #endif ) { #ifdef _WIN32 SetFileApisToOEM(); #endif g_StdOut << kCopyrightString; UStringVector commandStrings; #ifdef _WIN32 NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); #else GetArguments(numArguments, arguments, commandStrings); #endif UString archiveName = commandStrings.Front(); commandStrings.Delete(0); NCommandLineParser::CParser parser(kNumSwitches); try { parser.ParseStrings(kSwitchForms, commandStrings); } catch(...) { PrintHelpAndExit(); } if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs) { PrintHelp(); return 0; } const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; int numNonSwitchStrings = nonSwitchStrings.Size(); CArchiveCommand command; if (numNonSwitchStrings == 0) command.CommandType = NCommandType::kFullExtract; else { if (numNonSwitchStrings > 1) PrintHelpAndExit(); if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], command)) PrintHelpAndExit(); } NRecursedType::EEnum recursedType; recursedType = command.DefaultRecursedType(); NWildcard::CCensor wildcardCensor; bool thereAreSwitchIncludeWildCards; thereAreSwitchIncludeWildCards = false; AddToCensorFromNonSwitchesStrings(wildcardCensor, nonSwitchStrings, recursedType, thereAreSwitchIncludeWildCards); bool yesToAll = parser[NKey::kYes].ThereIs; #ifdef _WIN32 if (archiveName.Right(kDefaultExtLength).CompareNoCase(kDefaultExt) != 0) archiveName += kDefaultExt; #endif // NExtractMode::EEnum extractMode; // bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode); bool passwordEnabled = parser[NKey::kPassword].ThereIs; UString password; if(passwordEnabled) password = parser[NKey::kPassword].PostStrings[0]; NFind::CFileInfoW archiveFileInfo; if (!NFind::FindFile(archiveName, archiveFileInfo)) throw kCantFindSFX; if (archiveFileInfo.IsDir()) throw kCantFindSFX; UString outputDir; if(parser[NKey::kOutputDir].ThereIs) { outputDir = parser[NKey::kOutputDir].PostStrings[0]; NName::NormalizeDirPathPrefix(outputDir); } { UStringVector v1, v2; v1.Add(archiveName); v2.Add(archiveName); const NWildcard::CCensorNode &wildcardCensorHead = wildcardCensor.Pairs.Front().Head; CCodecs *codecs = new CCodecs; CMyComPtr< #ifdef EXTERNAL_CODECS ICompressCodecsInfo #else IUnknown #endif > compressCodecsInfo = codecs; HRESULT result = codecs->Load(); if (result != S_OK) throw CSystemException(result); if(command.CommandType != NCommandType::kList) { CExtractCallbackConsole *ecs = new CExtractCallbackConsole; CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs; ecs->OutStream = g_StdStream; ecs->PasswordIsDefined = passwordEnabled; ecs->Password = password; ecs->Init(); COpenCallbackConsole openCallback; openCallback.OutStream = g_StdStream; openCallback.PasswordIsDefined = passwordEnabled; openCallback.Password = password; CExtractOptions eo; eo.StdOutMode = false; eo.PathMode = NExtract::NPathMode::kFullPathnames; eo.TestMode = command.CommandType == NCommandType::kTest; eo.OverwriteMode = yesToAll ? NExtract::NOverwriteMode::kWithoutPrompt : NExtract::NOverwriteMode::kAskBefore; eo.OutputDir = outputDir; eo.YesToAll = yesToAll; UString errorMessage; CDecompressStat stat; HRESULT result = DecompressArchives( codecs, CIntVector(), v1, v2, wildcardCensorHead, eo, &openCallback, ecs, errorMessage, stat); if (!errorMessage.IsEmpty()) { (*g_StdStream) << endl << "Error: " << errorMessage;; if (result == S_OK) result = E_FAIL; } if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0) { if (ecs->NumArchiveErrors != 0) (*g_StdStream) << endl << "Archive Errors: " << ecs->NumArchiveErrors << endl; if (ecs->NumFileErrors != 0) (*g_StdStream) << endl << "Sub items Errors: " << ecs->NumFileErrors << endl; return NExitCode::kFatalError; } if (result != S_OK) throw CSystemException(result); } else { UInt64 numErrors = 0; HRESULT result = ListArchives( codecs, CIntVector(), v1, v2, wildcardCensorHead, true, false, passwordEnabled, password, numErrors); if (numErrors > 0) { g_StdOut << endl << "Errors: " << numErrors; return NExitCode::kFatalError; } if (result != S_OK) throw CSystemException(result); } } return 0; }
static HRESULT ShowDialog( CCodecs *codecs, const NWildcard::CCensor &censor, CUpdateOptions &options, CUpdateCallbackGUI *callback, HWND hwndParent) { if (options.Commands.Size() != 1) throw "It must be one command"; UString currentDirPrefix; #ifndef UNDER_CE { if (!NDirectory::MyGetCurrentDirectory(currentDirPrefix)) return E_FAIL; NName::NormalizeDirPathPrefix(currentDirPrefix); } #endif bool oneFile = false; NFind::CFileInfoW fileInfo; UString name; if (censor.Pairs.Size() > 0) { const NWildcard::CPair &pair = censor.Pairs[0]; if (pair.Head.IncludeItems.Size() > 0) { const NWildcard::CItem &item = pair.Head.IncludeItems[0]; if (item.ForFile) { name = pair.Prefix; for (int i = 0; i < item.PathParts.Size(); i++) { if (i > 0) name += WCHAR_PATH_SEPARATOR; name += item.PathParts[i]; } if (fileInfo.Find(name)) { if (censor.Pairs.Size() == 1 && pair.Head.IncludeItems.Size() == 1) oneFile = !fileInfo.IsDir(); } } } } CCompressDialog dialog; NCompressDialog::CInfo &di = dialog.Info; dialog.ArcFormats = &codecs->Formats; for (int i = 0; i < codecs->Formats.Size(); i++) { const CArcInfoEx &ai = codecs->Formats[i]; if (ai.Name.CompareNoCase(L"swfc") == 0) if (!oneFile || name.Right(4).CompareNoCase(L".swf") != 0) continue; if (ai.UpdateEnabled && (oneFile || !ai.KeepName)) dialog.ArcIndices.Add(i); } if (dialog.ArcIndices.Size() == 0) { ShowErrorMessage(L"No Update Engines"); return E_FAIL; } // di.ArchiveName = options.ArchivePath.GetFinalPath(); di.ArchiveName = options.ArchivePath.GetPathWithoutExt(); dialog.OriginalFileName = options.ArchivePath.Prefix + fileInfo.Name; di.CurrentDirPrefix = currentDirPrefix; di.SFXMode = options.SfxMode; di.OpenShareForWrite = options.OpenShareForWrite; if (callback->PasswordIsDefined) di.Password = callback->Password; di.KeepName = !oneFile; if (dialog.Create(hwndParent) != IDOK) return E_ABORT; options.VolumesSizes = di.VolumeSizes; /* if (di.VolumeSizeIsDefined) { MyMessageBox(L"Splitting to volumes is not supported"); return E_FAIL; } */ NUpdateArchive::CActionSet &actionSet = options.Commands.Front().ActionSet; switch(di.UpdateMode) { case NCompressDialog::NUpdateMode::kAdd: actionSet = NUpdateArchive::kAddActionSet; break; case NCompressDialog::NUpdateMode::kUpdate: actionSet = NUpdateArchive::kUpdateActionSet; break; case NCompressDialog::NUpdateMode::kFresh: actionSet = NUpdateArchive::kFreshActionSet; break; case NCompressDialog::NUpdateMode::kSynchronize: actionSet = NUpdateArchive::kSynchronizeActionSet; break; default: throw 1091756; } const CArcInfoEx &archiverInfo = codecs->Formats[di.FormatIndex]; callback->PasswordIsDefined = (!di.Password.IsEmpty()); if (callback->PasswordIsDefined) callback->Password = di.Password; options.MethodMode.Properties.Clear(); bool is7z = archiverInfo.Name.CompareNoCase(L"7z") == 0; bool methodOverride = IsThereMethodOverride(is7z, di.Options); SetOutProperties( options.MethodMode.Properties, is7z, di.Level, !methodOverride, di.Method, di.Dictionary, di.OrderMode, di.Order, di.SolidIsSpecified, di.SolidBlockSize, di.MultiThreadIsAllowed, di.NumThreads, di.EncryptionMethod, di.EncryptHeadersIsAllowed, di.EncryptHeaders, di.SFXMode); options.OpenShareForWrite = di.OpenShareForWrite; ParseAndAddPropertires(options.MethodMode.Properties, di.Options); if (di.SFXMode) options.SfxMode = true; options.MethodMode.FormatIndex = di.FormatIndex; options.ArchivePath.VolExtension = archiverInfo.GetMainExt(); if (di.SFXMode) options.ArchivePath.BaseExtension = kSFXExtension; else options.ArchivePath.BaseExtension = options.ArchivePath.VolExtension; options.ArchivePath.ParseFromPath(di.ArchiveName); NWorkDir::CInfo workDirInfo; workDirInfo.Load(); options.WorkingDir.Empty(); if (workDirInfo.Mode != NWorkDir::NMode::kCurrent) { UString fullPath; NDirectory::MyGetFullPathName(di.ArchiveName, fullPath); options.WorkingDir = GetWorkDir(workDirInfo, fullPath); NDirectory::CreateComplexDirectory(options.WorkingDir); } return S_OK; }
void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) { archivers.Clear(); #ifdef EXCLUDE_COM #ifdef FORMAT_7Z { CArchiverInfo item; item.UpdateEnabled = true; item.Name = L"7z"; item.Extensions.Add(CArchiverExtInfo(L"7z")); #ifndef _SFX const unsigned char kSig[] = {'7' , 'z', 0xBC, 0xAF, 0x27, 0x1C}; SetBuffer(item.StartSignature, kSig, 6); #endif archivers.Add(item); } #endif #ifdef FORMAT_BZIP2 { CArchiverInfo item; item.UpdateEnabled = true; item.KeepName = true; item.Name = L"BZip2"; item.Extensions.Add(CArchiverExtInfo(L"bz2")); item.Extensions.Add(CArchiverExtInfo(L"tbz2", L".tar")); #ifndef _SFX const unsigned char sig[] = {'B' , 'Z', 'h' }; SetBuffer(item.StartSignature, sig, 3); #endif archivers.Add(item); } #endif #ifdef FORMAT_GZIP { CArchiverInfo item; item.UpdateEnabled = true; item.Name = L"GZip"; item.Extensions.Add(CArchiverExtInfo(L"gz")); item.Extensions.Add(CArchiverExtInfo(L"tgz", L".tar")); #ifndef _SFX const unsigned char sig[] = { 0x1F, 0x8B }; SetBuffer(item.StartSignature, sig, 2); #endif archivers.Add(item); } #endif #ifdef FORMAT_SPLIT { CArchiverInfo item; item.UpdateEnabled = false; item.KeepName = true; item.Name = L"Split"; item.Extensions.Add(CArchiverExtInfo(L"001")); archivers.Add(item); } #endif #ifdef FORMAT_TAR { CArchiverInfo item; item.UpdateEnabled = true; item.Name = L"Tar"; item.Extensions.Add(CArchiverExtInfo(L"tar")); archivers.Add(item); } #endif #ifdef FORMAT_ZIP { CArchiverInfo item; item.UpdateEnabled = true; item.Name = L"Zip"; item.Extensions.Add(CArchiverExtInfo(L"zip")); #ifndef _SFX const unsigned char sig[] = { 0x50, 0x4B, 0x03, 0x04 }; SetBuffer(item.StartSignature, sig, 4); #endif archivers.Add(item); } #endif #ifdef FORMAT_CPIO { CArchiverInfo item; item.Name = L"Cpio"; item.Extensions.Add(CArchiverExtInfo(L"cpio")); archivers.Add(item); } #endif #ifdef FORMAT_RPM { CArchiverInfo item; item.Name = L"Rpm"; item.Extensions.Add(CArchiverExtInfo(L"rpm", L".cpio.gz")); archivers.Add(item); } #endif #ifdef FORMAT_ARJ { CArchiverInfo item; item.Name = L"Arj"; item.Extensions.Add(CArchiverExtInfo(L"arj")); #ifndef _SFX const unsigned char sig[] = { 0x60, 0xEA }; SetBuffer(item.StartSignature, sig, 2); #endif archivers.Add(item); } #endif #ifdef FORMAT_Z { CArchiverInfo item; item.Name = L"Z"; item.Extensions.Add(CArchiverExtInfo(L"Z")); #ifndef _SFX const unsigned char sig[] = { 0x1F, 0x9D }; SetBuffer(item.StartSignature, sig, 2); #endif archivers.Add(item); } #endif #else UString folderPath = GetBaseFolderPrefixFromRegistry() + (UString)kFormatFolderName + (UString)WSTRING_PATH_SEPARATOR; NFind::CEnumeratorW enumerator(folderPath + L"*"); NFind::CFileInfoW fileInfo; while (enumerator.Next(fileInfo)) { if (fileInfo.IsDirectory()) continue; UString filePath = folderPath + fileInfo.Name; { NDLL::CLibrary library; if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE)) continue; } NDLL::CLibrary library; if (!library.Load(filePath)) continue; GetHandlerPropertyFunc getHandlerProperty = (GetHandlerPropertyFunc) library.GetProcAddress("GetHandlerProperty"); if (getHandlerProperty == NULL) continue; CArchiverInfo item; item.FilePath = filePath; NWindows::NCOM::CPropVariant prop; if (getHandlerProperty(NArchive::kName, &prop) != S_OK) continue; if (prop.vt != VT_BSTR) continue; item.Name = prop.bstrVal; prop.Clear(); if (getHandlerProperty(NArchive::kClassID, &prop) != S_OK) continue; if (prop.vt != VT_BSTR) continue; item.ClassID = *(const GUID *)prop.bstrVal; prop.Clear(); if (getHandlerProperty(NArchive::kExtension, &prop) != S_OK) continue; if (prop.vt != VT_BSTR) continue; UString ext = prop.bstrVal; UString addExt; prop.Clear(); if (getHandlerProperty(NArchive::kAddExtension, &prop) != S_OK) continue; if (prop.vt == VT_BSTR) { addExt = prop.bstrVal; } else if (prop.vt != VT_EMPTY) continue; prop.Clear(); UStringVector exts, addExts; SplitString(ext, exts); SplitString(addExt, addExts); prop.Clear(); for (int i = 0; i < exts.Size(); i++) { CArchiverExtInfo extInfo; extInfo.Ext = exts[i]; if (addExts.Size() > 0) extInfo.AddExt = addExts[i]; if (extInfo.AddExt == L"*") extInfo.AddExt.Empty(); item.Extensions.Add(extInfo); } if (getHandlerProperty(NArchive::kUpdate, &prop) == S_OK) if (prop.vt == VT_BOOL) item.UpdateEnabled = VARIANT_BOOLToBool(prop.boolVal); prop.Clear(); if (item.UpdateEnabled) { if (getHandlerProperty(NArchive::kKeepName, &prop) == S_OK) if (prop.vt == VT_BOOL) item.KeepName = VARIANT_BOOLToBool(prop.boolVal); prop.Clear(); } if (getHandlerProperty(NArchive::kStartSignature, &prop) == S_OK) { if (prop.vt == VT_BSTR) { UINT len = ::SysStringByteLen(prop.bstrVal); item.StartSignature.SetCapacity(len); memmove(item.StartSignature, prop.bstrVal, len); } } prop.Clear(); if (getHandlerProperty(NArchive::kAssociate, &prop) == S_OK) if (prop.vt == VT_BOOL) item.Associate = VARIANT_BOOLToBool(prop.boolVal); prop.Clear(); archivers.Add(item); } #endif }
static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode, int phyParent, int logParent, const UString &phyPrefix, const UStringVector &addArchivePrefix, // prefix from curNode CDirItems &dirItems, bool enterToSubFolders, IEnumDirItemCallback *callback, UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes) { if (!enterToSubFolders) if (curNode.NeedCheckSubDirs()) enterToSubFolders = true; if (callback) RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), phyPrefix)); // try direct_names case at first if (addArchivePrefix.IsEmpty() && !enterToSubFolders) { // check that all names are direct int i; for (i = 0; i < curNode.IncludeItems.Size(); i++) { const NWildcard::CItem &item = curNode.IncludeItems[i]; if (item.Recursive || item.PathParts.Size() != 1) break; const UString &name = item.PathParts.Front(); if (name.IsEmpty() || DoesNameContainWildCard(name)) break; } if (i == curNode.IncludeItems.Size()) { // all names are direct (no wildcards) // so we don't need file_system's dir enumerator CRecordVector<bool> needEnterVector; for (i = 0; i < curNode.IncludeItems.Size(); i++) { const NWildcard::CItem &item = curNode.IncludeItems[i]; const UString &name = item.PathParts.Front(); const UString fullPath = phyPrefix + name; NFind::CFileInfoW fi; if (!fi.Find(fullPath)) { errorCodes.Add(::GetLastError()); errorPaths.Add(fullPath); continue; } bool isDir = fi.IsDir(); if (isDir && !item.ForDir || !isDir && !item.ForFile) { errorCodes.Add((DWORD)E_FAIL); errorPaths.Add(fullPath); continue; } { UStringVector pathParts; pathParts.Add(fi.Name); if (curNode.CheckPathToRoot(false, pathParts, !isDir)) continue; } AddDirFileInfo(phyParent, logParent, fi, dirItems.Items); if (!isDir) continue; UStringVector addArchivePrefixNew; const NWildcard::CCensorNode *nextNode = 0; int index = curNode.FindSubNode(name); if (index >= 0) { for (int t = needEnterVector.Size(); t <= index; t++) needEnterVector.Add(true); needEnterVector[index] = false; nextNode = &curNode.SubNodes[index]; } else { nextNode = &curNode; addArchivePrefixNew.Add(name); // don't change it to fi.Name. It's for shortnames support } RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix, addArchivePrefixNew, dirItems, true, callback, errorPaths, errorCodes)); } for (i = 0; i < curNode.SubNodes.Size(); i++) { if (i < needEnterVector.Size()) if (!needEnterVector[i]) continue; const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i]; const UString fullPath = phyPrefix + nextNode.Name; NFind::CFileInfoW fi; if (!fi.Find(fullPath)) { if (!nextNode.AreThereIncludeItems()) continue; errorCodes.Add(::GetLastError()); errorPaths.Add(fullPath); continue; } if (!fi.IsDir()) { errorCodes.Add((DWORD)E_FAIL); errorPaths.Add(fullPath); continue; } RINOK(EnumerateDirItems_Spec(nextNode, phyParent, logParent, fi.Name, phyPrefix, UStringVector(), dirItems, false, callback, errorPaths, errorCodes)); } return S_OK; } } NFind::CEnumeratorW enumerator(phyPrefix + wchar_t(kAnyStringWildcard)); for (int ttt = 0; ; ttt++) { NFind::CFileInfoW fi; bool found; if (!enumerator.Next(fi, found)) { errorCodes.Add(::GetLastError()); errorPaths.Add(phyPrefix); break; } if (!found) break; if (callback && (ttt & 0xFF) == 0xFF) RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), phyPrefix)); const UString &name = fi.Name; bool enterToSubFolders2 = enterToSubFolders; UStringVector addArchivePrefixNew = addArchivePrefix; addArchivePrefixNew.Add(name); { UStringVector addArchivePrefixNewTemp(addArchivePrefixNew); if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fi.IsDir())) continue; } if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fi.IsDir())) { AddDirFileInfo(phyParent, logParent, fi, dirItems.Items); if (fi.IsDir()) enterToSubFolders2 = true; } if (!fi.IsDir()) continue; const NWildcard::CCensorNode *nextNode = 0; if (addArchivePrefix.IsEmpty()) { int index = curNode.FindSubNode(name); if (index >= 0) nextNode = &curNode.SubNodes[index]; } if (!enterToSubFolders2 && nextNode == 0) continue; addArchivePrefixNew = addArchivePrefix; if (nextNode == 0) { nextNode = &curNode; addArchivePrefixNew.Add(name); } RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, name, phyPrefix, addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPaths, errorCodes)); } return S_OK; }
static HRESULT EnumerateDirItems( const NWildcard::CCensorNode &curNode, const UString &diskPrefix, // full disk path prefix const UString &archivePrefix, // prefix from root const UStringVector &addArchivePrefix, // prefix from curNode CObjectVector<CDirItem> &dirItems, bool enterToSubFolders, IEnumDirItemCallback *callback, UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes) { if (!enterToSubFolders) if (curNode.NeedCheckSubDirs()) enterToSubFolders = true; if (callback) RINOK(callback->CheckBreak()); // try direct_names case at first if (addArchivePrefix.IsEmpty() && !enterToSubFolders) { // check that all names are direct int i; for (i = 0; i < curNode.IncludeItems.Size(); i++) { const NWildcard::CItem &item = curNode.IncludeItems[i]; if (item.Recursive || item.PathParts.Size() != 1) break; const UString &name = item.PathParts.Front(); if (name.IsEmpty() || DoesNameContainWildCard(name)) break; } if (i == curNode.IncludeItems.Size()) { // all names are direct (no wildcards) // so we don't need file_system's dir enumerator CRecordVector<bool> needEnterVector; for (i = 0; i < curNode.IncludeItems.Size(); i++) { const NWildcard::CItem &item = curNode.IncludeItems[i]; const UString &name = item.PathParts.Front(); const UString fullPath = diskPrefix + name; NFind::CFileInfoW fileInfo; if (!NFind::FindFile(fullPath, fileInfo)) { errorCodes.Add(::GetLastError()); errorPaths.Add(fullPath); continue; } bool isDir = fileInfo.IsDirectory(); if (isDir && !item.ForDir || !isDir && !item.ForFile) { errorCodes.Add((DWORD)E_FAIL); errorPaths.Add(fullPath); continue; } const UString realName = fileInfo.getFileName(); const UString realDiskPath = diskPrefix + realName; { UStringVector pathParts; pathParts.Add(fileInfo.getFileName()); if (curNode.CheckPathToRoot(false, pathParts, !isDir)) continue; } AddDirFileInfo(archivePrefix, realDiskPath, fileInfo, dirItems); if (!isDir) continue; UStringVector addArchivePrefixNew; const NWildcard::CCensorNode *nextNode = 0; int index = curNode.FindSubNode(name); if (index >= 0) { for (int t = needEnterVector.Size(); t <= index; t++) needEnterVector.Add(true); needEnterVector[index] = false; nextNode = &curNode.SubNodes[index]; } else { nextNode = &curNode; addArchivePrefixNew.Add(name); // don't change it to realName. It's for shortnames support } RINOK(EnumerateDirItems(*nextNode, realDiskPath + wchar_t(kDirDelimiter), archivePrefix + realName + wchar_t(kDirDelimiter), addArchivePrefixNew, dirItems, true, callback, errorPaths, errorCodes)); } for (i = 0; i < curNode.SubNodes.Size(); i++) { if (i < needEnterVector.Size()) if (!needEnterVector[i]) continue; const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i]; const UString fullPath = diskPrefix + nextNode.Name; NFind::CFileInfoW fileInfo; if (!NFind::FindFile(fullPath, fileInfo)) { if (!nextNode.AreThereIncludeItems()) continue; errorCodes.Add(::GetLastError()); errorPaths.Add(fullPath); continue; } if (!fileInfo.IsDirectory()) { errorCodes.Add((DWORD)E_FAIL); errorPaths.Add(fullPath); continue; } RINOK(EnumerateDirItems(nextNode, diskPrefix + fileInfo.getFileName() + wchar_t(kDirDelimiter), archivePrefix + fileInfo.getFileName() + wchar_t(kDirDelimiter), UStringVector(), dirItems, false, callback, errorPaths, errorCodes)); } return S_OK; } } NFind::CEnumeratorW enumerator(diskPrefix + wchar_t(kAnyStringWildcard)); for (;;) { NFind::CFileInfoW fileInfo; bool found; if (!enumerator.Next(fileInfo, found)) { errorCodes.Add(::GetLastError()); errorPaths.Add(diskPrefix); break; } if (!found) break; if (callback) RINOK(callback->CheckBreak()); const UString &name = fileInfo.getFileName(); bool enterToSubFolders2 = enterToSubFolders; UStringVector addArchivePrefixNew = addArchivePrefix; addArchivePrefixNew.Add(name); { UStringVector addArchivePrefixNewTemp(addArchivePrefixNew); if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fileInfo.IsDirectory())) continue; } if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fileInfo.IsDirectory())) { AddDirFileInfo(archivePrefix, diskPrefix + name, fileInfo, dirItems); if (fileInfo.IsDirectory()) enterToSubFolders2 = true; } if (!fileInfo.IsDirectory()) continue; const NWildcard::CCensorNode *nextNode = 0; if (addArchivePrefix.IsEmpty()) { int index = curNode.FindSubNode(name); if (index >= 0) nextNode = &curNode.SubNodes[index]; } if (!enterToSubFolders2 && nextNode == 0) continue; addArchivePrefixNew = addArchivePrefix; if (nextNode == 0) { nextNode = &curNode; addArchivePrefixNew.Add(name); } RINOK(EnumerateDirItems(*nextNode, diskPrefix + name + wchar_t(kDirDelimiter), archivePrefix + name + wchar_t(kDirDelimiter), addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPaths, errorCodes)); } return S_OK; }