diff --git a/src/plugin/FarStorage.cpp b/src/plugin/FarStorage.cpp index 8ef39e12..3436bcff 100644 --- a/src/plugin/FarStorage.cpp +++ b/src/plugin/FarStorage.cpp @@ -111,7 +111,7 @@ int StorageObject::ReadFileList(bool &aborted) __int64 nTotalSize = 0; DWORD nNumFiles = 0, nNumDirs = 0; - ExternalModule &module = m_pModules->modules[m_nModuleIndex]; + const ExternalModule &module = m_pModules->GetModule(m_nModuleIndex); DWORD item_index = 0; StorageItemInfo item_info; @@ -185,7 +185,7 @@ int StorageObject::ReadFileList(bool &aborted) int StorageObject::Extract( ExtractOperationParams ¶ms ) { - return m_pModules->modules[m_nModuleIndex].Extract(m_pStoragePtr, params); + return m_pModules->GetModule(m_nModuleIndex).Extract(m_pStoragePtr, params); } int StorageObject::ChangeCurrentDir( const wchar_t* path ) diff --git a/src/plugin/FarStorage.h b/src/plugin/FarStorage.h index aefff96a..9102c998 100644 --- a/src/plugin/FarStorage.h +++ b/src/plugin/FarStorage.h @@ -45,7 +45,7 @@ class StorageObject ContentTreeNode* GetItem(size_t index); ContentTreeNode* CurrentDir() const { return m_pCurrentDir; } - const wchar_t* GetModuleName() const { return (m_nModuleIndex >= 0) ? m_pModules->modules[m_nModuleIndex].ModuleName : NULL; } + const wchar_t* GetModuleName() const { return (m_nModuleIndex >= 0) ? m_pModules->GetModule(m_nModuleIndex).Name() : NULL; } const wchar_t* StoragePath() const { return m_wszStoragePath; } __int64 TotalSize() const { return m_nTotalSize; } int NumFiles() const { return m_nNumFiles; } diff --git a/src/plugin/ModulesController.cpp b/src/plugin/ModulesController.cpp index d48a8239..f36b8b0c 100644 --- a/src/plugin/ModulesController.cpp +++ b/src/plugin/ModulesController.cpp @@ -4,6 +4,41 @@ #define SECTION_BUF_SIZE 1024 +static bool DoesExtensionFilterMatch( const wchar_t* path, const vector &filter ) +{ + if (filter.size() == 0) + return true; + + for (size_t i = 0; i < filter.size(); i++) + { + if (PathMatchSpec(path, filter[i].c_str())) + return true; + } + + return false; +} + +static void ParseExtensionList(const wchar_t* listval, ExternalModule& module) +{ + if (!listval || !listval[0]) return; + + wchar_t* context = NULL; + wchar_t* strList = _wcsdup(listval); + + wchar_t* token = wcstok_s(strList, L";", &context); + while (token) + { + if (wcslen(token) > 0) + { + while(!token[0]) token++; + module.ExtensionFilter.push_back(token); + } + + token = wcstok_s(NULL, L";", &context); + } + free(strList); +} + int ModulesController::Init( const wchar_t* basePath, const wchar_t* configPath ) { Cleanup(); @@ -21,21 +56,20 @@ int ModulesController::Init( const wchar_t* basePath, const wchar_t* configPath { OptionsItem nextOpt = mModulesList->GetOption(i); - ExternalModule module = {0}; - wcscpy_s(module.ModuleName, ARRAY_SIZE(module.ModuleName), nextOpt.key); - wcscpy_s(module.LibraryFile, ARRAY_SIZE(module.LibraryFile), nextOpt.value); + ExternalModule module(nextOpt.key, nextOpt.value); // Get module specific settings section memset(wszModuleSection, 0, sizeof(wszModuleSection)); - optFile.GetSectionLines(module.ModuleName, wszModuleSection, SECTION_BUF_SIZE); + optFile.GetSectionLines(module.Name(), wszModuleSection, SECTION_BUF_SIZE); if (LoadModule(basePath, module, wszModuleSection)) { // Read extensions filter for each module if (mFiltersList != NULL) { - mFiltersList->GetValue(module.ModuleName, module.ExtensionFilter, ARRAY_SIZE(module.ExtensionFilter)); - _wcsupr_s(module.ExtensionFilter); + wchar_t extList[OPT_VAL_MAXLEN] = {0}; + mFiltersList->GetValue(module.Name(), extList, ARRAY_SIZE(extList)); + ParseExtensionList(extList, module); } modules.push_back(module); @@ -101,11 +135,11 @@ void ModulesController::CloseStorageFile(int moduleIndex, HANDLE storage) bool ModulesController::LoadModule( const wchar_t* basePath, ExternalModule &module, const wchar_t* moduleSettings ) { - if (!module.ModuleName[0] || !module.LibraryFile[0]) + if (!module.Name()[0] || !module.LibraryFile()[0]) return false; wchar_t wszFullModulePath[MAX_PATH] = {0}; - swprintf_s(wszFullModulePath, MAX_PATH, L"%s%s", basePath, module.LibraryFile); + swprintf_s(wszFullModulePath, MAX_PATH, L"%s%s", basePath, module.LibraryFile()); module.ModuleHandle = LoadLibraryEx(wszFullModulePath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (module.ModuleHandle != NULL) @@ -143,37 +177,10 @@ bool ModulesController::LoadModule( const wchar_t* basePath, ExternalModule &mod DWORD err = GetLastError(); wchar_t msgText[200] = {0}; - swprintf_s(msgText, ARRAY_SIZE(msgText), L"Can not load modules (Error: %d, Path: %s)", err, module.LibraryFile); + swprintf_s(msgText, ARRAY_SIZE(msgText), L"Can not load modules (Error: %d, Path: %s)", err, module.LibraryFile()); MessageBox(0, msgText, L"Error", MB_OK); } #endif return false; } - -bool ModulesController::DoesExtensionFilterMatch( const wchar_t* path, const wchar_t* filter ) -{ - if (!filter || !*filter) - return true; - - const wchar_t* extPtr = wcsrchr(path, '.'); - if (extPtr != NULL && wcschr(extPtr, '\\') == NULL) - { - bool result = false; - - wchar_t* extStr = _wcsdup(extPtr); - _wcsupr_s(extStr, wcslen(extStr)+1); - - const wchar_t* posInFilter = wcsstr(filter, extStr); - if (posInFilter != NULL) - { - size_t extLen = wcslen(extStr); - result = (posInFilter[extLen] == 0) || (posInFilter[extLen] == ';'); - } - - free(extStr); - return result; - } - - return false; -} diff --git a/src/plugin/ModulesController.h b/src/plugin/ModulesController.h index fac7389e..457327c1 100644 --- a/src/plugin/ModulesController.h +++ b/src/plugin/ModulesController.h @@ -5,10 +5,19 @@ struct ExternalModule { - wchar_t ModuleName[32]; - wchar_t LibraryFile[32]; + ExternalModule(const wchar_t* Name, const wchar_t* Library) + : m_sModuleName(Name), m_sLibraryFile(Library), ModuleHandle(0), ModuleVersion(0) + { + LoadModule = NULL; + UnloadModule = NULL; + OpenStorage = NULL; + CloseStorage = NULL; + GetNextItem = NULL; + Extract = NULL; + } + HMODULE ModuleHandle; - wchar_t ExtensionFilter[128]; + std::vector ExtensionFilter; LoadSubModuleFunc LoadModule; UnloadSubModuleFunc UnloadModule; @@ -18,6 +27,13 @@ struct ExternalModule CloseStorageFunc CloseStorage; GetItemFunc GetNextItem; ExtractFunc Extract; + + const wchar_t* Name() const { return m_sModuleName.c_str(); } + const wchar_t* LibraryFile() const { return m_sLibraryFile.c_str(); } + +private: + std::wstring m_sModuleName; + std::wstring m_sLibraryFile; }; struct OpenStorageFileInParams @@ -31,18 +47,19 @@ struct OpenStorageFileInParams class ModulesController { private: + vector modules; + bool LoadModule(const wchar_t* basePath, ExternalModule &module, const wchar_t* moduleSettings); - bool DoesExtensionFilterMatch(const wchar_t* path, const wchar_t* filter); public: - vector modules; - ModulesController(void) {}; ~ModulesController(void) { this->Cleanup(); }; int Init(const wchar_t* basePath, const wchar_t* configPath); void Cleanup(); - size_t NumModules() { return modules.size(); }; + + size_t NumModules() { return modules.size(); } + const ExternalModule& GetModule(int index) { return modules[index]; } int OpenStorageFile(OpenStorageFileInParams srcParams, int *moduleIndex, HANDLE *storage, StorageGeneralInfo *info); void CloseStorageFile(int moduleIndex, HANDLE storage); diff --git a/src/plugin/Observer.vcproj b/src/plugin/Observer.vcproj index 6cff2c5a..1476fb69 100644 --- a/src/plugin/Observer.vcproj +++ b/src/plugin/Observer.vcproj @@ -77,6 +77,7 @@ /> #include +#include // STL #include diff --git a/src/plugin/text/observer.ini b/src/plugin/text/observer.ini index fe81a767..698cdd97 100644 --- a/src/plugin/text/observer.ini +++ b/src/plugin/text/observer.ini @@ -15,20 +15,20 @@ VDISK=modules\vdisk.so MPQ=modules\mpq.so [Filters] -MSI=.msi;.msm -NSIS=.exe -WISE=.exe -VP=.vp -RELIC=.big;.sga -PST=.pst -VALVE=.bsp;.gcf;.vbsp;.vpk;.pak;.xzp;.wad +MSI=*.msi;*.msm +NSIS=*.exe +WISE=*.exe +VP=*.vp +RELIC=*.big;*.sga +PST=*.pst +VALVE=*.bsp;*.gcf;*.vbsp;*.vpk;*.pak;*.xzp;*.wad UDF= ISO= -X-CAT=.cat;.pck;.pbd;.pbb +X-CAT=*.cat;*.pck;*.pbd;*.pbb MBOX= MIME= VDISK= -MPQ=.mpq;.exe;.S2MA;.SC2Data;.SC2Map;.SC2Mod;.SC2Assets;.SC2Archive;.mpqe +MPQ=*.mpq;*.exe;*.S2MA;*.SC2Data;*.SC2Map;*.SC2Mod;*.SC2Assets;*.SC2Archive;*.mpqe [General] PanelHeaderPrefix= diff --git a/src/plugin/text/whatsnew.txt b/src/plugin/text/whatsnew.txt index f81ca1dc..a73edaf3 100644 --- a/src/plugin/text/whatsnew.txt +++ b/src/plugin/text/whatsnew.txt @@ -3,6 +3,7 @@ Changes history: 1.8.0 - Added support for files in Mbox format. - Replaced MIME module. It should be faster and more standard compliant. +- Now standard wildcards are used in filter extensions. - VALVE: Fixed signature detection for VPK files. - VALVE: Fixed possible crash on some VBSP files. - MSI: File {msi_info.txt} have creation/modification date from package info. diff --git a/src/plugin/text/whatsnew_ru.txt b/src/plugin/text/whatsnew_ru.txt index 5f9b4098..3eae24a4 100644 --- a/src/plugin/text/whatsnew_ru.txt +++ b/src/plugin/text/whatsnew_ru.txt @@ -3,6 +3,7 @@ 1.8.0 - Добавлена поддержка для файлов формата Mbox. - Заменён модуль MIME. Увеличена скорость работы и совместимость со стандартом. +- Теперь для фильтров расширения используются стандартные маски. - VALVE: Исправлено определение сигнатуры для VPK файлов. - VALVE: Исправлено падение на некоторых VBSP файлах. - MSI: Файл {msi_info}.txt имеет дату создания/модификации из параметров пакета.