summaryrefslogtreecommitdiff
path: root/updater/scan.cpp
diff options
context:
space:
mode:
authorsje <sje@4f64403b-2f21-0410-a795-97e2b3489a10>2006-11-01 14:48:34 +0000
committersje <sje@4f64403b-2f21-0410-a795-97e2b3489a10>2006-11-01 14:48:34 +0000
commitd123e0ce94bf90b2adb0a4000930eb467e293226 (patch)
treed414dea59908105c4d2f256199a610e0a69c8690 /updater/scan.cpp
parenta13e82647294da4add976a24335fec50d7bfe905 (diff)
git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@16 4f64403b-2f21-0410-a795-97e2b3489a10
Diffstat (limited to 'updater/scan.cpp')
-rw-r--r--updater/scan.cpp388
1 files changed, 388 insertions, 0 deletions
diff --git a/updater/scan.cpp b/updater/scan.cpp
new file mode 100644
index 0000000..cab6cbc
--- /dev/null
+++ b/updater/scan.cpp
@@ -0,0 +1,388 @@
+#include "common.h"
+#include "scan.h"
+
+typedef PLUGININFO * (__cdecl * Miranda_Plugin_Info) ( DWORD mirandaVersion );
+
+typedef std::map<std::string, std::string> AlternateShortNameMap;
+
+AlternateShortNameMap alternate_shortname_map;
+
+void InitAlternateShortNameMap() {
+ alternate_shortname_map["Version Informations"] = "Version Information";
+ alternate_shortname_map["Jabber Protocol"] = "JabberG Protocol";
+ alternate_shortname_map["Jabber Protocol (Unicode)"] = "JabberG Protocol (Unicode)";
+ //alternate_shortname_map["PopUp Interoperability"] = "PopUp Plus"; - disabled since popup plus archive structure is incompatible
+ //alternate_shortname_map["Messaging Style Conversation"] = "nConvers++"; // will this conflict with other nConvers'?
+ alternate_shortname_map["MimQQ-libeva"] = "MirandaQQ (libeva Version)";
+ alternate_shortname_map["Icons Library Manager (Unicode)"] = "Icons library manager";
+}
+
+void ScanPlugins(FilenameMap *fn_map, UpdateList *update_list) {
+ if(!XMLDataAvailable(MC_PLUGINS)) return;
+
+ TCHAR mir_exe[MAX_PATH], plugins_folder[MAX_PATH],
+ dll_path[MAX_PATH];
+ TCHAR *dll_name;
+ Miranda_Plugin_Info dll_info_func;
+ DWORD mirandaVersion = (DWORD)CallService(MS_SYSTEM_GETVERSION, 0, 0);
+ PLUGININFO *pluginInfo;
+ HMODULE hModule;
+
+ GetModuleFileName(0, mir_exe, MAX_PATH);
+
+ // get plugin folder
+ _tcscpy(plugins_folder, mir_exe);
+ TCHAR *p = _tcsrchr(plugins_folder, _T('\\'));
+ if(p) *p = 0;
+ _tcscat(plugins_folder, _T("\\Plugins"));
+
+ _tcscpy(dll_path, plugins_folder);
+ _tcscat(dll_path, _T("\\"));
+ // set dll_name to point into the dll_path string, at the point where we can write the plugin name
+ // to end up with the full dll path
+ dll_name = dll_path + _tcslen(dll_path);
+
+ // add filemask
+ _tcscat(plugins_folder, _T("\\*.dll"));
+
+ WIN32_FIND_DATA findData;
+ HANDLE hFileSearch = FindFirstFile(plugins_folder, &findData);
+ int file_id;
+ if(hFileSearch != INVALID_HANDLE_VALUE) {
+ do {
+ _tcscpy(dll_name, findData.cFileName);
+ if(hModule = LoadLibrary(dll_path)) {
+ dll_info_func = (Miranda_Plugin_Info)GetProcAddress(hModule, "MirandaPluginInfo");
+ if(dll_info_func && (pluginInfo = dll_info_func(mirandaVersion))) {
+
+ // *** This is a dodgy and unfair hack...
+ // In order to disable new plugins that may be unintentionally installed whith an update,
+ // updater will check for the 'plugindisabled' setting for each dll. The problem is that
+ // this setting may not be there for running plugins - and isn't there for new ones. So,
+ // we'll disable anything new when the setting isn't found anyway - but we write the
+ // value below for all plugins so that we can expect to find it
+ char *lowname = GetAString(findData.cFileName); strlwr(lowname);
+ if(DBGetContactSettingByte(0, "PluginDisable", lowname, 255) == 255) // setting not present
+ DBWriteContactSettingByte(0, "PluginDisable", lowname, 0);
+ free(lowname);
+
+ std::string shortName(pluginInfo->shortName);
+ AlternateShortNameMap::iterator i = alternate_shortname_map.find(shortName);
+ if(i != alternate_shortname_map.end()) {
+ if((file_id = FindFileID(i->second.c_str(), MC_PLUGINS, update_list)) != -1) {
+ RegisterForFileListing(file_id, i->second.c_str(), pluginInfo->version, true, MC_PLUGINS);
+ if(fn_map) (*fn_map)[file_id].push_back(findData.cFileName);
+ }
+ } else {
+ if((file_id = FindFileID(pluginInfo->shortName, MC_PLUGINS, update_list)) != -1) {
+ RegisterForFileListing(file_id, pluginInfo, true);
+ if(fn_map) (*fn_map)[file_id].push_back(findData.cFileName);
+ }
+ }
+ }
+ FreeLibrary(hModule);
+ }
+ } while(FindNextFile(hFileSearch, &findData));
+ FindClose(hFileSearch);
+ }
+}
+
+typedef struct LangpackData_tag {
+ DWORD version;
+ char *fl_name;
+} LangpackData;
+
+
+bool GetLangpackData(const TCHAR *filename, LangpackData *ld) {
+
+#ifdef _UNICODE
+ char *temp_str = GetAString(filename);
+ //typedef std::char_traits<wchar_t> wchar_traits;
+ //typedef std::basic_ifstream<wchar_t, wchar_traits> wifstream;
+ //wifstream lp_file(temp_str);
+ std::wifstream lp_file(temp_str);
+
+ free(temp_str);
+#else
+ std::ifstream lp_file(filename);
+#endif
+ char *conv;
+ if(lp_file.is_open()) {
+ STDString line;
+ while(!lp_file.eof()) {
+ std::getline(lp_file, line);
+ if(line.length() > 14 && _tcscmp(line.substr(0, 7).c_str(), _T("; FLID:")) == 0) {
+ size_t verpos = line.find_last_of(_T(' '));
+ conv = GetAString(line.substr(verpos + 1).c_str());
+ if(line.length() - verpos >= 7 && VersionFromString(conv, &ld->version)) {
+ free(conv);
+ // got valid version string, now get fl name
+ ld->fl_name = (char *)malloc(verpos - 8 + 1); // +1 for sz
+ conv = GetAString(line.substr(8).c_str());
+ strncpy(ld->fl_name, conv, verpos-8);
+ free(conv);
+ ld->fl_name[verpos - 8] = 0;
+ lp_file.close();
+ return true;
+ }
+ free(conv);
+ }
+ }
+
+ lp_file.close();
+ return false;
+ } else
+ return false;
+}
+
+void ScanLangpacks(FilenameMap *fn_map, UpdateList *update_list) {
+ if(!XMLDataAvailable(MC_LOCALIZATION)) return;
+
+ TCHAR mir_folder[MAX_PATH], langpack_path[MAX_PATH], *langpack_name;
+
+ GetModuleFileName(0, mir_folder, MAX_PATH);
+
+ // get program folder
+ TCHAR *p = _tcsrchr(mir_folder, _T('\\'));
+ if(p) *p = 0;
+ _tcscat(mir_folder, _T("\\"));
+
+ _tcscpy(langpack_path, mir_folder);
+
+ // set langpack_name to point into the langpack_name string, at the point where we can write the file name
+ // to end up with the full path
+ langpack_name = langpack_path + _tcslen(langpack_path);
+
+ // add filemask
+ _tcscat(mir_folder, _T("\\langpack_*.txt"));
+
+ WIN32_FIND_DATA findData;
+ HANDLE hFileSearch = FindFirstFile(mir_folder, &findData);
+ int file_id;
+ if(hFileSearch != INVALID_HANDLE_VALUE) {
+ do {
+ _tcscpy(langpack_name, findData.cFileName);
+ LangpackData ld = {0};
+ if(GetLangpackData(langpack_path, &ld)) {
+ if((file_id = FindFileID(ld.fl_name, MC_LOCALIZATION, update_list)) != -1) {
+ RegisterForFileListing(file_id, ld.fl_name, ld.version, true, MC_LOCALIZATION);
+ if(fn_map) (*fn_map)[file_id].push_back(findData.cFileName);
+ }
+
+ if(ld.fl_name) free(ld.fl_name);
+ }
+ } while(FindNextFile(hFileSearch, &findData));
+ FindClose(hFileSearch);
+ }
+}
+
+
+
+bool RearrangeDlls(char *shortName, STDStringList &filenames) {
+ bool dll_enabled = false;
+
+ char *lowname = _strdup(shortName); strlwr(lowname);
+
+ TCHAR file_path[MAX_PATH], updates_folder[MAX_PATH], new_filename[MAX_PATH];
+ TCHAR *dll_name;
+ BYTE disabled_val;
+
+ Miranda_Plugin_Info dll_info_func;
+ DWORD mirandaVersion = (DWORD)CallService(MS_SYSTEM_GETVERSION, 0, 0);
+ PLUGININFO *pluginInfo;
+ HMODULE hModule;
+
+ _tcscpy(file_path, options.temp_folder);
+ _tcscat(file_path, _T("\\"));
+ // set dll_name to point into the file_path string, at the point where we can write the plugin name
+ // to end up with the full dll path
+ dll_name = file_path + _tcslen(file_path);
+
+ // add filemask
+ _tcscpy(updates_folder, options.temp_folder);
+ _tcscat(updates_folder, _T("\\*.dll"));
+
+ WIN32_FIND_DATA findData;
+ HANDLE hFileSearch = FindFirstFile(updates_folder, &findData);
+ if(hFileSearch != INVALID_HANDLE_VALUE) {
+ do {
+ _tcscpy(dll_name, findData.cFileName);
+ _tcslwr(findData.cFileName);
+
+ if(hModule = LoadLibrary(file_path)) {
+ dll_info_func = (Miranda_Plugin_Info)GetProcAddress(hModule, "MirandaPluginInfo");
+ if(dll_info_func && (pluginInfo = dll_info_func(mirandaVersion))) {
+ std::string strShortName(pluginInfo->shortName);
+ AlternateShortNameMap::iterator i = alternate_shortname_map.find(strShortName);
+ if(i != alternate_shortname_map.end())
+ strShortName = i->second;
+ //transform (strShortName.begin(),strShortName.end(), strShortName.begin(), tolower);
+ for(unsigned int st = 0; st < strShortName.length(); st++) strShortName[st] = tolower(strShortName[st]);
+ if(strShortName == lowname) {
+ bool moved = false;
+ STDString newname;
+ for(STDStringList::iterator j = filenames.begin(); j != filenames.end(); j++) {
+ _tcscpy(new_filename, options.temp_folder);
+ _tcscat(new_filename, _T("\\"));
+ _tcscat(new_filename, j->c_str());
+
+ for(unsigned int st = 0; st < j->length(); st++) j->operator[](st) = tolower(j->operator[](st));
+
+ // disable any new plugins (i.e. not installed before) that somehome got into the
+ // dowloaded archives (e.g. loadavatars comes with loadavatarsw - installing both is not good!)
+ char *temp_str = GetAString(j->c_str());
+ disabled_val = DBGetContactSettingByte(0, "PluginDisable", temp_str, 255);
+ if(disabled_val == 255) { // assume this means setting not in db (should be 1 or 0)
+ DBWriteContactSettingByte(0, "PluginDisable", temp_str, 1);
+ disabled_val = 1;
+ }
+ free(temp_str);
+
+ dll_enabled |= (disabled_val == 0);
+
+ //MessageBox(0, new_filename, "New Filename", MB_OK);
+ if(!moved) {
+ if(_tcscmp(findData.cFileName, j->c_str()) != 0)
+ MoveFile(file_path, new_filename);
+ newname = new_filename;
+ moved = true;
+ } else {
+ //char msg[2048];
+ //sprintf(msg, "Copying %s to %s", newname.c_str(), new_filename);
+ //MessageBox(0, msg, "msg", MB_OK);
+ CopyFile(newname.c_str(), new_filename, FALSE);
+ }
+ }
+ FreeLibrary(hModule);
+ break;
+ }
+ } //else
+ //MessageBox(0, _T("Library does not contain Miranda PluginInfo function"), findData.cFileName, MB_OK);
+ FreeLibrary(hModule);
+ } //else
+ //MessageBox(0, _T("File not loadable as library"), findData.cFileName, MB_OK);
+ } while(FindNextFile(hFileSearch, &findData));
+ FindClose(hFileSearch);
+ }
+
+ // do exactly the same thing again, for the updates/plugins folder... :(
+
+ _tcscpy(file_path, options.temp_folder);
+ _tcscat(file_path, _T("\\Plugins\\"));
+ dll_name = file_path + _tcslen(file_path);
+
+ // add filemask
+ _tcscpy(updates_folder, options.temp_folder);
+ _tcscat(updates_folder, _T("\\Plugins\\*.dll"));
+
+ hFileSearch = FindFirstFile(updates_folder, &findData);
+ if(hFileSearch != INVALID_HANDLE_VALUE) {
+ do {
+ _tcscpy(dll_name, findData.cFileName);
+ _tcslwr(findData.cFileName);
+
+ if(hModule = LoadLibrary(file_path)) {
+ dll_info_func = (Miranda_Plugin_Info)GetProcAddress(hModule, "MirandaPluginInfo");
+ if(dll_info_func && (pluginInfo = dll_info_func(mirandaVersion))) {
+ std::string strShortName(pluginInfo->shortName);
+ AlternateShortNameMap::iterator i = alternate_shortname_map.find(strShortName);
+ if(i != alternate_shortname_map.end())
+ strShortName = i->second;
+ //transform (strShortName.begin(),strShortName.end(), strShortName.begin(), tolower);
+ for(unsigned int st = 0; st < strShortName.length(); st++) strShortName[st] = tolower(strShortName[st]);
+ if(strShortName == lowname) {
+ bool moved = false;
+ STDString newname;
+ for(STDStringList::iterator j = filenames.begin(); j != filenames.end(); j++) {
+ _tcscpy(new_filename, options.temp_folder);
+ _tcscat(new_filename, _T("\\Plugins\\"));
+ _tcscat(new_filename, j->c_str());
+
+ for(unsigned int st = 0; st < j->length(); st++) j->operator[](st) = tolower(j->operator[](st));
+
+ // disable any new plugins (i.e. not installed before) that somehome got into the
+ // dowloaded archives (e.g. loadavatars comes with loadavatarsw - installing both is not good!)
+ char *temp_str = GetAString(j->c_str());
+ disabled_val = DBGetContactSettingByte(0, "PluginDisable", temp_str, 255);
+ if(disabled_val == 255) { // assume this means setting not in db (should be 1 or 0)
+ DBWriteContactSettingByte(0, "PluginDisable", temp_str, 1);
+ disabled_val = 1;
+ }
+ free(temp_str);
+
+ dll_enabled |= (disabled_val == 0);
+
+ if(!moved) {
+ if(_tcscmp(findData.cFileName, j->c_str()) != 0)
+ MoveFile(file_path, new_filename);
+ newname = new_filename;
+ moved = true;
+ } else
+ CopyFile(newname.c_str(), new_filename, FALSE);
+ }
+ FreeLibrary(hModule);
+ break;
+ }
+ }
+ FreeLibrary(hModule);
+ }
+ } while(FindNextFile(hFileSearch, &findData));
+ FindClose(hFileSearch);
+ }
+
+ free(lowname);
+ return dll_enabled;
+}
+
+bool RearrangeLangpacks(char *shortName, STDStringList &filenames) {
+ char *lowname = _strdup(shortName); strlwr(lowname);
+
+ TCHAR file_path[MAX_PATH], updates_folder[MAX_PATH], new_filename[MAX_PATH], *langpack_name;
+ // do exactly the same thing again, for the updates/plugins folder... :(
+
+ _tcscpy(file_path, options.temp_folder);
+ _tcscat(file_path, _T("\\"));
+ langpack_name = file_path + _tcslen(file_path);
+
+ // add filemask
+ _tcscpy(updates_folder, options.temp_folder);
+ _tcscat(updates_folder, _T("\\langpack_*.txt"));
+
+ WIN32_FIND_DATA findData;
+ HANDLE hFileSearch = FindFirstFile(updates_folder, &findData);
+ hFileSearch = FindFirstFile(updates_folder, &findData);
+ if(hFileSearch != INVALID_HANDLE_VALUE) {
+ do {
+ _tcscpy(langpack_name, findData.cFileName);
+
+ LangpackData ld = {0};
+ if(GetLangpackData(file_path, &ld)) {
+
+ std::string strShortName(ld.fl_name);
+ //transform (strShortName.begin(),strShortName.end(), strShortName.begin(), tolower);
+ for(unsigned int st = 0; st < strShortName.length(); st++) strShortName[st] = tolower(strShortName[st]);
+ if(strShortName == lowname) {
+ bool moved = false;
+ STDString newname;
+ for(STDStringList::iterator j = filenames.begin(); j != filenames.end(); j++) {
+ _tcscpy(new_filename, options.temp_folder);
+ _tcscat(new_filename, _T("\\"));
+ _tcscat(new_filename, j->c_str());
+ if(!moved) {
+ if(_tcscmp(findData.cFileName, j->c_str()) != 0)
+ MoveFile(file_path, new_filename);
+ newname = new_filename;
+ moved = true;
+ } else
+ CopyFile(newname.c_str(), new_filename, FALSE);
+ }
+ break;
+ }
+ }
+ } while(FindNextFile(hFileSearch, &findData));
+ FindClose(hFileSearch);
+ }
+
+ free(lowname);
+ return true;
+}