#include "common.h" #include "scan.h" typedef PLUGININFO * (__cdecl * Miranda_Plugin_Info) ( DWORD mirandaVersion ); typedef PLUGININFOEX * (__cdecl * Miranda_Plugin_Info_Ex) ( DWORD mirandaVersion ); typedef std::map 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"; // grr alternate_shortname_map["Updater"] = __PLUGIN_NAME; alternate_shortname_map["Updater (Unicode)"] = __PLUGIN_NAME; } 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; Miranda_Plugin_Info_Ex dll_info_func_ex; 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"); dll_info_func_ex = (Miranda_Plugin_Info_Ex)GetProcAddress(hModule, "MirandaPluginInfoEx"); if((dll_info_func_ex && (pluginInfo = (PLUGININFO *)dll_info_func_ex(mirandaVersion))) || (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 with 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_traits; //typedef std::basic_ifstream 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; Miranda_Plugin_Info_Ex dll_info_func_ex; 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"); dll_info_func_ex = (Miranda_Plugin_Info_Ex)GetProcAddress(hModule, "MirandaPluginInfoEx"); if((dll_info_func_ex && (pluginInfo = (PLUGININFO *)dll_info_func_ex(mirandaVersion))) || (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"); dll_info_func_ex = (Miranda_Plugin_Info_Ex)GetProcAddress(hModule, "MirandaPluginInfoEx"); if((dll_info_func_ex && (pluginInfo = (PLUGININFO *)dll_info_func_ex(mirandaVersion))) || (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; }