From 8f5a7b54eb953bbfc877ec915e26b3a95ec28d00 Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@4f64403b-2f21-0410-a795-97e2b3489a10> Date: Sun, 21 Feb 2010 23:00:56 +0000 Subject: New updater with 3x reduced footprint and fully W7 and x64 compatible git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@476 4f64403b-2f21-0410-a795-97e2b3489a10 --- updater/scan.cpp | 346 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 190 insertions(+), 156 deletions(-) (limited to 'updater/scan.cpp') diff --git a/updater/scan.cpp b/updater/scan.cpp index 8a9e15b..04cff9e 100644 --- a/updater/scan.cpp +++ b/updater/scan.cpp @@ -4,26 +4,40 @@ 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"; +struct AlternateShortName +{ + const char* from; + const char* to; +}; + +static const AlternateShortName alternate_shortname_map[] = +{ + { "Version Informations", "Version Information" }, + { "Jabber Protocol", "JabberG Protocol" }, + { "Jabber Protocol (Unicode)", "JabberG Protocol (Unicode)" }, + //{ "PopUp Interoperability", "PopUp Plus" }, - disabled since popup plus archive structure is incompatible + //{ "Messaging Style Conversation", "nConvers++" }, // will this conflict with other nConvers'? + { "MimQQ-libeva", "MirandaQQ (libeva Version)" }, + { "Icons Library Manager (Unicode)", "Icons library manager" }, // grr - alternate_shortname_map["Updater"] = __PLUGIN_NAME; - alternate_shortname_map["Updater (Unicode)"] = __PLUGIN_NAME; + { "Updater", __PLUGIN_NAME }, + { "Updater (Unicode)", __PLUGIN_NAME }, +}; + +const char* findAlternateShortName(const char* name) +{ + for (int i = 0; i < SIZEOF(alternate_shortname_map); ++i) + { + if (strcmp(name, alternate_shortname_map[i].from) == 0) + return alternate_shortname_map[i].to; + } + return NULL; } -void ScanPlugins(FilenameMap *fn_map, UpdateList *update_list) { - if(!XMLDataAvailable(MC_PLUGINS)) return; +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]; @@ -53,41 +67,69 @@ void ScanPlugins(FilenameMap *fn_map, UpdateList *update_list) { WIN32_FIND_DATA findData; HANDLE hFileSearch = FindFirstFile(plugins_folder, &findData); - int file_id; - if(hFileSearch != INVALID_HANDLE_VALUE) { + if(hFileSearch != INVALID_HANDLE_VALUE) + { do { _tcscpy(dll_name, findData.cFileName); - if(hModule = LoadLibrary(dll_path)) { + hModule = GetModuleHandle(dll_path); + bool notLoaded = hModule == NULL; + if (notLoaded) hModule = LoadLibrary(dll_path); + if (hModule) + { 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)))) { - + 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); + char *lowname = mir_t2a(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); + mir_free(lowname); + + const char* alternateName = findAlternateShortName(pluginInfo->shortName); + if (alternateName) + { + int file_id = FindFileID(alternateName, MC_PLUGINS, update_list); + if (file_id != -1) + { + RegisterForFileListing(file_id, alternateName, pluginInfo->version, true, MC_PLUGINS); + if (fn_map) + { + FileNameStruct* fns = fn_map->find((FileNameStruct*)&file_id); + if (fns == NULL) + { + fns = new FileNameStruct(file_id); + fn_map->insert(fns); + } + fns->list.insert(mir_tstrdup(findData.cFileName)); + } } - } else { - if((file_id = FindFileID(pluginInfo->shortName, MC_PLUGINS, update_list)) != -1) { + } + else + { + int file_id = FindFileID(pluginInfo->shortName, MC_PLUGINS, update_list); + if (file_id != -1) + { RegisterForFileListing(file_id, pluginInfo, true); - if(fn_map) (*fn_map)[file_id].push_back(findData.cFileName); + if (fn_map) + { + FileNameStruct* fns = fn_map->find((FileNameStruct*)&file_id); + if (fns == NULL) + { + fns = new FileNameStruct(file_id); + fn_map->insert(fns); + } + fns->list.insert(mir_tstrdup(findData.cFileName)); + } } } } - FreeLibrary(hModule); + if (notLoaded) FreeLibrary(hModule); } } while(FindNextFile(hFileSearch, &findData)); FindClose(hFileSearch); @@ -100,49 +142,42 @@ typedef struct LangpackData_tag { } 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; +bool GetLangpackData(const TCHAR *filename, LangpackData *ld) +{ + char line[1024], *ver, *conv; + + FILE *fp = _tfopen(filename, _T("r")); + if (fp == NULL) return false; + + while (fgets(line, sizeof(line), fp)) + { + conv = strstr(line, "; FLID:"); + if (conv) + { + conv += 7; + + while (*conv == ' ') conv++; + + ver = strchr(conv, 0) + 1; + while (ver >= conv) if (*ver != ' ') break; else *ver-- = 0; + + ver = strrchr(conv, ' '); + if (ver) + { + *ver = 0; + VersionFromString(++ver, &ld->version); + } + ld->fl_name = mir_strdup(conv); + fclose(fp); + return true; + } + } + fclose(fp); + return false; } -void ScanLangpacks(FilenameMap *fn_map, UpdateList *update_list) { +void ScanLangpacks(FilenameMap *fn_map, UpdateList *update_list) +{ if(!XMLDataAvailable(MC_LOCALIZATION)) return; TCHAR mir_folder[MAX_PATH], langpack_path[MAX_PATH], *langpack_name; @@ -165,18 +200,29 @@ void ScanLangpacks(FilenameMap *fn_map, UpdateList *update_list) { WIN32_FIND_DATA findData; HANDLE hFileSearch = FindFirstFile(mir_folder, &findData); - int file_id; - if(hFileSearch != INVALID_HANDLE_VALUE) { + 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) { + if (GetLangpackData(langpack_path, &ld)) + { + int file_id = FindFileID(ld.fl_name, MC_LOCALIZATION, update_list); + if (file_id != -1) + { RegisterForFileListing(file_id, ld.fl_name, ld.version, true, MC_LOCALIZATION); - if(fn_map) (*fn_map)[file_id].push_back(findData.cFileName); + if (fn_map) + { + FileNameStruct* fns = fn_map->find((FileNameStruct*)&file_id); + if (fns == NULL) + { + fns = new FileNameStruct(file_id); + fn_map->insert(fns); + } + fns->list.insert(mir_tstrdup(findData.cFileName)); + } } - - if(ld.fl_name) free(ld.fl_name); + mir_free(ld.fl_name); } } while(FindNextFile(hFileSearch, &findData)); FindClose(hFileSearch); @@ -185,11 +231,10 @@ void ScanLangpacks(FilenameMap *fn_map, UpdateList *update_list) { -bool RearrangeDlls(char *shortName, STDStringList &filenames) { +bool RearrangeDlls(char *shortName, StrList &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; @@ -200,68 +245,62 @@ bool RearrangeDlls(char *shortName, STDStringList &filenames) { PLUGININFO *pluginInfo; HMODULE hModule; - _tcscpy(file_path, options.temp_folder); - _tcscat(file_path, _T("\\")); + mir_sntprintf(file_path, SIZEOF(file_path), _T("%s\\"), options.temp_folder); // 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")); + mir_sntprintf(updates_folder, SIZEOF(updates_folder), _T("%s\\*.dll"), options.temp_folder); 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()); + if((dll_info_func_ex && (pluginInfo = (PLUGININFO *)dll_info_func_ex(mirandaVersion))) || (dll_info_func && (pluginInfo = dll_info_func(mirandaVersion)))) + { + const char* alternateName = findAlternateShortName(pluginInfo->shortName); + if (alternateName == NULL) alternateName = pluginInfo->shortName; - for(unsigned int st = 0; st < j->length(); st++) j->operator[](st) = tolower(j->operator[](st)); + if (_stricmp(alternateName, shortName) == 0) + { + bool moved = false; + TCHAR* newname = NULL; + for (int j = 0; j < filenames.getCount(); j++) + { + TCHAR* fileName = filenames[j]; + mir_sntprintf(new_filename, SIZEOF(new_filename), _T("%s\\%s"), options.temp_folder, fileName); // 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()); + char *temp_str = mir_t2a(fileName); 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); + mir_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) + if (!moved) { + if (_tcsicmp(findData.cFileName, fileName)) MoveFile(file_path, new_filename); - newname = new_filename; + + mir_free(newname); newname = mir_tstrdup(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); + CopyFile(newname, new_filename, FALSE); } } + mir_free(newname); FreeLibrary(hModule); break; } @@ -293,43 +332,41 @@ bool RearrangeDlls(char *shortName, STDStringList &filenames) { 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()); + if((dll_info_func_ex && (pluginInfo = (PLUGININFO *)dll_info_func_ex(mirandaVersion))) || (dll_info_func && (pluginInfo = dll_info_func(mirandaVersion)))) + { + const char* alternateName = findAlternateShortName(pluginInfo->shortName); + if (alternateName == NULL) alternateName = pluginInfo->shortName; - for(unsigned int st = 0; st < j->length(); st++) j->operator[](st) = tolower(j->operator[](st)); + if (_stricmp(alternateName, shortName) == 0) + { + bool moved = false; + TCHAR* newname = NULL; + for (int j = 0; j < filenames.getCount(); j++) + { + TCHAR *fileName = filenames[j]; + mir_sntprintf(new_filename, SIZEOF(new_filename), _T("%s\\Plugins\\%s"), options.temp_folder, fileName); // 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()); + char *temp_str = mir_t2a(fileName); 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); + mir_free(temp_str); dll_enabled |= (disabled_val == 0); if(!moved) { - if(_tcscmp(findData.cFileName, j->c_str()) != 0) + if (_tcsicmp(findData.cFileName, fileName) != 0) MoveFile(file_path, new_filename); - newname = new_filename; + mir_free(newname); newname = mir_tstrdup(new_filename); moved = true; } else - CopyFile(newname.c_str(), new_filename, FALSE); + CopyFile(newname, new_filename, FALSE); } + mir_free(newname); FreeLibrary(hModule); break; } @@ -340,23 +377,20 @@ bool RearrangeDlls(char *shortName, STDStringList &filenames) { FindClose(hFileSearch); } - free(lowname); return dll_enabled; } -bool RearrangeLangpacks(char *shortName, STDStringList &filenames) { - char *lowname = _strdup(shortName); strlwr(lowname); +bool RearrangeLangpacks(char *shortName, StrList &filenames) +{ 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("\\")); + mir_sntprintf(file_path, SIZEOF(file_path), _T("%s\\"), options.temp_folder); langpack_name = file_path + _tcslen(file_path); // add filemask - _tcscpy(updates_folder, options.temp_folder); - _tcscat(updates_folder, _T("\\langpack_*.txt")); + mir_sntprintf(updates_folder, SIZEOF(updates_folder), _T("%s\\langpack_*.txt"), options.temp_folder); WIN32_FIND_DATA findData; HANDLE hFileSearch = FindFirstFile(updates_folder, &findData); @@ -366,26 +400,27 @@ bool RearrangeLangpacks(char *shortName, STDStringList &filenames) { _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) { + if (GetLangpackData(file_path, &ld)) + { + if (_stricmp(ld.fl_name, shortName) == 0) + { 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) + TCHAR *newname = NULL; + for (int j = 0; j < filenames.getCount(); j++) + { + TCHAR *fileName = filenames[j]; + mir_sntprintf(new_filename, SIZEOF(new_filename), _T("%s\\%s"), options.temp_folder, fileName); + + if (!moved) + { + if (_tcscmp(findData.cFileName, fileName) != 0) MoveFile(file_path, new_filename); - newname = new_filename; + mir_free(newname); newname = mir_tstrdup(new_filename); moved = true; } else - CopyFile(newname.c_str(), new_filename, FALSE); + CopyFile(newname, new_filename, FALSE); } + mir_free(newname); break; } } @@ -393,6 +428,5 @@ bool RearrangeLangpacks(char *shortName, STDStringList &filenames) { FindClose(hFileSearch); } - free(lowname); return true; } -- cgit v1.2.3