diff options
Diffstat (limited to 'plugins/PluginUpdater/src')
| -rw-r--r-- | plugins/PluginUpdater/src/Common.h | 83 | ||||
| -rw-r--r-- | plugins/PluginUpdater/src/DlgListNew.cpp | 69 | ||||
| -rw-r--r-- | plugins/PluginUpdater/src/DlgUpdate.cpp | 103 | ||||
| -rw-r--r-- | plugins/PluginUpdater/src/Events.cpp | 4 | ||||
| -rw-r--r-- | plugins/PluginUpdater/src/PluginUpdater.cpp | 2 | ||||
| -rw-r--r-- | plugins/PluginUpdater/src/Services.cpp | 68 | ||||
| -rw-r--r-- | plugins/PluginUpdater/src/Utils.cpp | 80 | 
7 files changed, 217 insertions, 192 deletions
diff --git a/plugins/PluginUpdater/src/Common.h b/plugins/PluginUpdater/src/Common.h index e843f07125..151904a83d 100644 --- a/plugins/PluginUpdater/src/Common.h +++ b/plugins/PluginUpdater/src/Common.h @@ -122,38 +122,8 @@ extern aPopups PopupsList[POPUPS];  extern HANDLE Timer, hPipe;
  extern HWND hwndDialog;
 -void InitPopupList();
 -void LoadOptions();
 -BOOL NetlibInit();
 -void IcoLibInit();
 -void NetlibUnInit();
 -int  ModulesLoaded(WPARAM wParam, LPARAM lParam);
 -
 -int  OnFoldersChanged(WPARAM, LPARAM);
 -int  OnPreShutdown(WPARAM, LPARAM);
 -int  OptInit(WPARAM, LPARAM);
 -
 -void BackupFile(TCHAR *ptszSrcFileName, TCHAR *ptszBackFileName);
 -
  void DoCheck(int iFlag);
  void DoGetList(int iFlag);
 -BOOL DownloadFile(LPCTSTR tszURL, LPCTSTR tszLocal, int CRCsum);
 -void ShowPopup(HWND hDlg, LPCTSTR Title, LPCTSTR Text, int Number, int ActType);
 -void __stdcall RestartMe(void*);
 -void __stdcall OpenPluginOptions(void*);
 -BOOL AllowUpdateOnStartup();
 -void InitTimer();
 -
 -INT_PTR MenuCommand(WPARAM wParam,LPARAM lParam);
 -INT_PTR ShowListCommand(WPARAM wParam,LPARAM lParam);
 -INT_PTR EmptyFolder(WPARAM wParam,LPARAM lParam);
 -
 -INT_PTR CALLBACK DlgMsgPop(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
 -
 -int  ImageList_AddIconFromIconLib(HIMAGELIST hIml, const char *name);
 -
 -bool unzip(const TCHAR *ptszZipFile, TCHAR *ptszDestPath, TCHAR *ptszBackPath);
 -void strdel(TCHAR *parBuffer, int len);
  ///////////////////////////////////////////////////////////////////////////////
 @@ -161,33 +131,64 @@ struct ServListEntry  {
  	ServListEntry(const char* _name, const char* _hash, int _crc) :
  		m_name( mir_a2t(_name)),
 -		m_bNeedFree(true),
  		m_crc(_crc)
  	{
  		strncpy(m_szHash, _hash, sizeof(m_szHash));
  	}
 -	ServListEntry(TCHAR* _name) :
 -		m_name(_name),
 -		m_bNeedFree(false)
 -	{
 -	}
 -
  	~ServListEntry()
  	{
 -		if (m_bNeedFree)
 -			mir_free(m_name);
 +		mir_free(m_name);
  	}
  	TCHAR *m_name;
 +	int    m_crc;
  	char   m_szHash[32+1];
 -	bool   m_bNeedFree;
 -	int  m_crc;
  };
  typedef OBJLIST<ServListEntry> SERVLIST;
  ///////////////////////////////////////////////////////////////////////////////
 +
 +void  InitPopupList();
 +void  LoadOptions();
 +BOOL  NetlibInit();
 +void  IcoLibInit();
 +void  ServiceInit();
 +void  NetlibUnInit();
 +int   ModulesLoaded(WPARAM wParam, LPARAM lParam);
 +
 +int   OnFoldersChanged(WPARAM, LPARAM);
 +int   OnPreShutdown(WPARAM, LPARAM);
 +int   OptInit(WPARAM, LPARAM);
 +
 +void  BackupFile(TCHAR *ptszSrcFileName, TCHAR *ptszBackFileName);
 +
 +bool  ParseHashes(const TCHAR *ptszUrl, ptrT &baseUrl, SERVLIST &arHashes);
 +int   CompareHashes(const ServListEntry *p1, const ServListEntry *p2);
 +
 +TCHAR* GetDefaultUrl();
 +BOOL   DownloadFile(LPCTSTR tszURL, LPCTSTR tszLocal, int CRCsum);
 +
 +void  ShowPopup(HWND hDlg, LPCTSTR Title, LPCTSTR Text, int Number, int ActType);
 +void  __stdcall RestartMe(void*);
 +void  __stdcall OpenPluginOptions(void*);
 +BOOL  AllowUpdateOnStartup();
 +void  InitTimer();
 +
 +INT_PTR MenuCommand(WPARAM wParam,LPARAM lParam);
 +INT_PTR ShowListCommand(WPARAM wParam,LPARAM lParam);
 +INT_PTR EmptyFolder(WPARAM wParam,LPARAM lParam);
 +
 +INT_PTR CALLBACK DlgMsgPop(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
 +
 +int  ImageList_AddIconFromIconLib(HIMAGELIST hIml, const char *name);
 +
 +bool unzip(const TCHAR *ptszZipFile, TCHAR *ptszDestPath, TCHAR *ptszBackPath);
 +void strdel(TCHAR *parBuffer, int len);
 +
 +///////////////////////////////////////////////////////////////////////////////
 +
  int CalculateModuleHash(const TCHAR *tszFileName, char *dest);
  BOOL IsRunAsAdmin();
 diff --git a/plugins/PluginUpdater/src/DlgListNew.cpp b/plugins/PluginUpdater/src/DlgListNew.cpp index 3e19a30bd4..5bf9e37746 100644 --- a/plugins/PluginUpdater/src/DlgListNew.cpp +++ b/plugins/PluginUpdater/src/DlgListNew.cpp @@ -373,78 +373,24 @@ static void __stdcall LaunchListDialog(void *param)  static void GetList(void *)
  {
  	char szKey[64] = {0};
 -	DBVARIANT dbVar = {0};
  	TCHAR tszTempPath[MAX_PATH];
  	DWORD dwLen = GetTempPath(SIZEOF(tszTempPath), tszTempPath);
  	if (tszTempPath[dwLen-1] == '\\')
  		tszTempPath[dwLen-1] = 0;
 -	// Load files info
 -	if (db_get_ts(NULL, MODNAME, "UpdateURL", &dbVar)) { // URL is not set
 -		db_set_ts(NULL, MODNAME, "UpdateURL", _T(DEFAULT_UPDATE_URL));
 -		db_get_ts(NULL, MODNAME, "UpdateURL", &dbVar);
 -	}
 -
 -	REPLACEVARSARRAY vars[2];
 -	vars[0].lptzKey = _T("platform");
 -	#ifdef WIN64
 -		vars[0].lptzValue = _T("64");
 -	#else
 -		vars[0].lptzValue = _T("32");
 -	#endif
 -	vars[1].lptzKey = vars[1].lptzValue = 0;
 -
 -	REPLACEVARSDATA dat = { sizeof(REPLACEVARSDATA) };
 -	dat.dwFlags = RVF_TCHAR;
 -	dat.variables = vars;
 -	mir_ptr<TCHAR> tszBaseUrl((TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)dbVar.ptszVal, (LPARAM)&dat));
 -	db_free(&dbVar);
 -
 -	// Download version info
 -	ShowPopup(NULL, TranslateT("Plugin Updater"), TranslateT("Downloading version info..."), 4, 0);
 -
 -	FILEURL pFileUrl;
 -	mir_sntprintf(pFileUrl.tszDownloadURL, SIZEOF(pFileUrl.tszDownloadURL), _T("%s/hashes.zip"), (TCHAR*)tszBaseUrl);
 -	mir_sntprintf(pFileUrl.tszDiskPath, SIZEOF(pFileUrl.tszDiskPath), _T("%s\\hashes.zip"), tszTempPath);
 -	if (!DownloadFile(pFileUrl.tszDownloadURL, pFileUrl.tszDiskPath, 0)) {
 -		ShowPopup(0, LPGENT("Plugin Updater"), LPGENT("An error occured while downloading the update."), 1, 0);
 -		hListThread = NULL;
 -		return;
 -	}
 -
 -	unzip(pFileUrl.tszDiskPath, tszTempPath, NULL);
 -	DeleteFile(pFileUrl.tszDiskPath);
 -
 -	TCHAR tszTmpIni[MAX_PATH] = {0};
 -	mir_sntprintf(tszTmpIni, SIZEOF(tszTmpIni), _T("%s\\hashes.txt"), tszTempPath);
 -	FILE *fp = _tfopen(tszTmpIni, _T("r"));
 -	if (!fp) {
 +	ptrT updateUrl( GetDefaultUrl()), baseUrl;
 +	SERVLIST hashes(50, CompareHashes);
 +	if ( !ParseHashes(updateUrl, baseUrl, hashes)) {
  		hListThread = NULL;
  		return;
  	}
  	FILELIST *UpdateFiles = new FILELIST(20);
 -	char str[200];
  	TCHAR *dirname = Utils_ReplaceVarsT(_T("%miranda_path%"));
 -	while(fgets(str, SIZEOF(str), fp) != NULL) {
 -		rtrim(str);
 -		char *p = strchr(str, ' ');
 -		if (p == NULL)
 -			continue;
 -		*p++ = 0;
 -		_strlwr(p);
 -
 -		int dwCrc32;
 -		char *p1 = strchr(p, ' ');
 -		if (p1 == NULL)
 -			dwCrc32 = 0;
 -		else {
 -			*p1++ = 0;
 -			sscanf(p1, "%08x", &dwCrc32);
 -		}
 -		ServListEntry hash(str, p, dwCrc32);
 +	for (int i=0; i < hashes.getCount(); i++) {
 +		ServListEntry &hash = hashes[i];
  		TCHAR tszPath[MAX_PATH];
  		mir_sntprintf(tszPath, SIZEOF(tszPath), _T("%s\\%s"), dirname, hash.m_name);
 @@ -468,14 +414,12 @@ static void GetList(void *)  		_tcslwr(tp);
  		mir_sntprintf(FileInfo->File.tszDiskPath, SIZEOF(FileInfo->File.tszDiskPath), _T("%s\\Temp\\%s.zip"), tszRoot, tszFileName);
 -		mir_sntprintf(FileInfo->File.tszDownloadURL, SIZEOF(FileInfo->File.tszDownloadURL), _T("%s/%s.zip"), tszBaseUrl, tszRelFileName);
 +		mir_sntprintf(FileInfo->File.tszDownloadURL, SIZEOF(FileInfo->File.tszDownloadURL), _T("%s/%s.zip"), baseUrl, tszRelFileName);
  		for (tp = _tcschr(FileInfo->File.tszDownloadURL, '\\'); tp != 0; tp = _tcschr(tp, '\\'))
  			*tp++ = '/';
  		FileInfo->File.CRCsum = hash.m_crc;
  		UpdateFiles->insert(FileInfo);
  	}
 -	fclose(fp);
 -	DeleteFile(tszTmpIni);
  	mir_free(dirname);
 @@ -483,6 +427,7 @@ static void GetList(void *)  	if (UpdateFiles->getCount() == 0) {
  		if ( !opts.bSilent)
  			ShowPopup(0, LPGENT("Plugin Updater"), LPGENT("List is empty."), 2, 0);
 +		delete UpdateFiles;
  	}
  	else CallFunctionAsync(LaunchListDialog, UpdateFiles);
 diff --git a/plugins/PluginUpdater/src/DlgUpdate.cpp b/plugins/PluginUpdater/src/DlgUpdate.cpp index 59c950ad25..38980a08d0 100644 --- a/plugins/PluginUpdater/src/DlgUpdate.cpp +++ b/plugins/PluginUpdater/src/DlgUpdate.cpp @@ -391,11 +391,6 @@ static bool CheckFileRename(const TCHAR *ptszOldName, TCHAR *pNewName)  /////////////////////////////////////////////////////////////////////////////////////////
 -static int CompareHashes(const ServListEntry *p1, const ServListEntry *p2)
 -{
 -	return _tcsicmp(p1->m_name, p2->m_name);
 -}
 -
  static bool isValidExtension(const TCHAR *ptszFileName)
  {
  	const TCHAR *pExt = _tcsrchr(ptszFileName, '.');
 @@ -456,8 +451,8 @@ static void ScanFolder(const TCHAR *tszFolder, size_t cbBaseLen, int level, cons  		// this file is not marked for deletion
  		if (tszNewName[0]) {
 -			ServListEntry tmp(tszNewName);
 -			ServListEntry *item = hashes.find(&tmp);
 +			TCHAR *pName = tszNewName;
 +			ServListEntry *item = hashes.find((ServListEntry*)&pName);
  			if (item == NULL) {
  				TCHAR *p = _tcsrchr(tszNewName, '.');
  				if (p[-1] != 'w' && p[-1] != 'W')
 @@ -465,7 +460,7 @@ static void ScanFolder(const TCHAR *tszFolder, size_t cbBaseLen, int level, cons  				int iPos = int(p - tszNewName)-1;
  				strdel(p-1, 1);
 -				if ((item = hashes.find(&tmp)) == NULL)
 +				if ((item = hashes.find((ServListEntry*)&pName)) == NULL)
  					continue;
  				strdel(tszNewName+iPos, 1);
 @@ -521,96 +516,30 @@ static void ScanFolder(const TCHAR *tszFolder, size_t cbBaseLen, int level, cons  static void CheckUpdates(void *)
  {
  	char szKey[64] = {0};
 -	DBVARIANT dbVar = {0};
  	TCHAR tszTempPath[MAX_PATH];
  	DWORD dwLen = GetTempPath(SIZEOF(tszTempPath), tszTempPath);
  	if (tszTempPath[dwLen-1] == '\\')
  		tszTempPath[dwLen-1] = 0;
 -	// Load files info
 -	if (db_get_ts(NULL, MODNAME, "UpdateURL", &dbVar)) { // URL is not set
 -		db_set_ts(NULL, MODNAME, "UpdateURL", _T(DEFAULT_UPDATE_URL));
 -		db_get_ts(NULL, MODNAME, "UpdateURL", &dbVar);
 -	}
 -
 -	REPLACEVARSARRAY vars[2];
 -	vars[0].lptzKey = _T("platform");
 -	#ifdef WIN64
 -		vars[0].lptzValue = _T("64");
 -	#else
 -		vars[0].lptzValue = _T("32");
 -	#endif
 -	vars[1].lptzKey = vars[1].lptzValue = 0;
 -
 -	REPLACEVARSDATA dat = { sizeof(REPLACEVARSDATA) };
 -	dat.dwFlags = RVF_TCHAR;
 -	dat.variables = vars;
 -	ptrT tszBaseUrl((TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)dbVar.ptszVal, (LPARAM)&dat));
 -	db_free(&dbVar);
 -
 -	// Download version info
 -	ShowPopup(NULL, TranslateT("Plugin Updater"), TranslateT("Downloading version info..."), 4, 0);
 -
 -	FILEURL pFileUrl;
 -	mir_sntprintf(pFileUrl.tszDownloadURL, SIZEOF(pFileUrl.tszDownloadURL), _T("%s/hashes.zip"), (TCHAR*)tszBaseUrl);
 -	mir_sntprintf(pFileUrl.tszDiskPath, SIZEOF(pFileUrl.tszDiskPath), _T("%s\\hashes.zip"), tszTempPath);
 -	if (!DownloadFile(pFileUrl.tszDownloadURL, pFileUrl.tszDiskPath, 0)) {
 -		ShowPopup(0, LPGENT("Plugin Updater"), LPGENT("An error occured while downloading the update."), 1, 0);
 -		hCheckThread = NULL;
 -		return;
 -	}
 -
 -	unzip(pFileUrl.tszDiskPath, tszTempPath, NULL);
 -	DeleteFile(pFileUrl.tszDiskPath);
 -
 -	TCHAR tszTmpIni[MAX_PATH] = {0};
 -	mir_sntprintf(tszTmpIni, SIZEOF(tszTmpIni), _T("%s\\hashes.txt"), tszTempPath);
 -	FILE *fp = _tfopen(tszTmpIni, _T("r"));
 -	if (!fp) {
 -		hCheckThread = NULL;
 -		return;
 -	}
 +	ptrT updateUrl( GetDefaultUrl()), baseUrl;
  	SERVLIST hashes(50, CompareHashes);
 -	char str[200];
 -	while(fgets(str, SIZEOF(str), fp) != NULL) {
 -		rtrim(str);
 -		char *p = strchr(str, ' ');
 -		if (p == NULL)
 -			continue;
 -
 -		*p++ = 0;
 -		if ( !opts.bUpdateIcons && !_strnicmp(str, "icons\\", 6))
 -			continue;
 -
 -		_strlwr(p);
 -
 -		int dwCrc32;
 -		char *p1 = strchr(p, ' ');
 -		if (p1 == NULL)
 -			dwCrc32 = 0;
 -		else {
 -			*p1++ = 0;
 -			sscanf(p1, "%08x", &dwCrc32);
 +	if ( ParseHashes(updateUrl, baseUrl, hashes)) {
 +		FILELIST *UpdateFiles = new FILELIST(20);
 +		TCHAR *dirname = Utils_ReplaceVarsT(_T("%miranda_path%"));
 +		ScanFolder(dirname, lstrlen(dirname)+1, 0, baseUrl, hashes, UpdateFiles);
 +		mir_free(dirname);
 +
 +		// Show dialog
 +		if (UpdateFiles->getCount() == 0) {
 +			if ( !opts.bSilent)
 +				ShowPopup(0, LPGENT("Plugin Updater"), LPGENT("No updates found."), 2, 0);
  		}
 -		hashes.insert(new ServListEntry(str, p, dwCrc32));
 -	}
 -	fclose(fp);
 -	DeleteFile(tszTmpIni);
 -
 -	FILELIST *UpdateFiles = new FILELIST(20);
 -	TCHAR *dirname = Utils_ReplaceVarsT(_T("%miranda_path%"));
 -	ScanFolder(dirname, lstrlen(dirname)+1, 0, tszBaseUrl, hashes, UpdateFiles);
 -	mir_free(dirname);
 -
 -	// Show dialog
 -	if (UpdateFiles->getCount() == 0) {
 -		if ( !opts.bSilent)
 -			ShowPopup(0, LPGENT("Plugin Updater"), LPGENT("No updates found."), 2, 0);
 +		else CallFunctionAsync(LaunchDialog, UpdateFiles);
  	}
 -	else CallFunctionAsync(LaunchDialog, UpdateFiles);
 +	hashes.destroy();
  	hCheckThread = NULL;
  }
 diff --git a/plugins/PluginUpdater/src/Events.cpp b/plugins/PluginUpdater/src/Events.cpp index d55ce08022..c740a77f44 100644 --- a/plugins/PluginUpdater/src/Events.cpp +++ b/plugins/PluginUpdater/src/Events.cpp @@ -54,14 +54,14 @@ int ModulesLoaded(WPARAM wParam, LPARAM lParam)  INT_PTR MenuCommand(WPARAM wParam,LPARAM lParam)
  {
  	opts.bSilent = false;
 -	DoCheck(1);
 +	DoCheck(true);
  	return 0;
  }
  INT_PTR ShowListCommand(WPARAM wParam,LPARAM lParam)
  {
  	opts.bSilent = false;
 -	DoGetList(1);
 +	DoGetList(true);
  	return 0;
  }
 diff --git a/plugins/PluginUpdater/src/PluginUpdater.cpp b/plugins/PluginUpdater/src/PluginUpdater.cpp index 090e9f5b5b..2a6a4dfe67 100644 --- a/plugins/PluginUpdater/src/PluginUpdater.cpp +++ b/plugins/PluginUpdater/src/PluginUpdater.cpp @@ -84,6 +84,8 @@ extern "C" __declspec(dllexport) int Load(PLUGINLINK *link)  extern "C" __declspec(dllexport) int Load(void)
  {
  	mir_getLP(&pluginInfoEx);
 +
 +	ServiceInit();
  #endif
  	hPluginUpdaterFolder = FoldersRegisterCustomPathT(MODULEA, LPGEN("Plugin Updater"), MIRANDA_PATHT _T("\\")DEFAULT_UPDATES_FOLDER);
  	if (hPluginUpdaterFolder)
 diff --git a/plugins/PluginUpdater/src/Services.cpp b/plugins/PluginUpdater/src/Services.cpp new file mode 100644 index 0000000000..cf5df545b9 --- /dev/null +++ b/plugins/PluginUpdater/src/Services.cpp @@ -0,0 +1,68 @@ +/*
 +Copyright (C) 2010 Mataes
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt.  If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA.
 +*/
 +
 +#include "common.h"
 +
 +#include "m_pluginupdater.h"
 +
 +static INT_PTR srvParseHashes(WPARAM wParam, LPARAM lParam)
 +{
 +	LPCTSTR ptszUrl = (LPCTSTR)wParam;
 +	LPTSTR  ptszBaseUrl = (LPTSTR)lParam;
 +	if (ptszUrl == NULL || ptszBaseUrl == NULL)
 +		return NULL;
 +
 +	SERVLIST *pList = new SERVLIST(50, CompareHashes);
 +	ptrT baseUrl;
 +	if ( ParseHashes(ptszUrl, baseUrl, *pList)) {
 +		_tcsncpy(ptszBaseUrl, baseUrl, MAX_PATH);
 +		return (INT_PTR)pList;
 +	}
 +
 +	delete pList;
 +	*ptszBaseUrl = 0;
 +	return NULL;
 +}
 +
 +static INT_PTR srvFreeHashes(WPARAM wParam, LPARAM lParam)
 +{
 +	SERVLIST *pList = (SERVLIST*)lParam;
 +	delete pList;
 +	return 0;
 +}
 +
 +static INT_PTR srvGetHashCount(WPARAM wParam, LPARAM lParam)
 +{
 +	SERVLIST *pList = (SERVLIST*)lParam;
 +	return (pList == NULL) ? 0 : pList->getCount();
 +}
 +
 +static INT_PTR srvGetNthHash(WPARAM wParam, LPARAM lParam)
 +{
 +	SERVLIST *pList = (SERVLIST*)lParam;
 +	return (pList == NULL) ? 0 : INT_PTR(&(*pList)[wParam]);
 +}
 +
 +void ServiceInit()
 +{
 +	CreateServiceFunction(MS_PU_PARSEHASHES,  srvParseHashes);
 +	CreateServiceFunction(MS_PU_FREEHASHES,   srvFreeHashes);
 +	CreateServiceFunction(MS_PU_GETHASHCOUNT, srvGetHashCount);
 +	CreateServiceFunction(MS_PU_GETNTHHASH,   srvGetNthHash);
 +}
 diff --git a/plugins/PluginUpdater/src/Utils.cpp b/plugins/PluginUpdater/src/Utils.cpp index 83d85f7a7a..27d2a13185 100644 --- a/plugins/PluginUpdater/src/Utils.cpp +++ b/plugins/PluginUpdater/src/Utils.cpp @@ -177,6 +177,86 @@ int Get_CRC(unsigned char* buffer, ULONG bufsize)  	return crc^0xffffffff;
  }
 +TCHAR* GetDefaultUrl()
 +{
 +	TCHAR *result = db_get_tsa(NULL, MODNAME, "UpdateURL");
 +	if (result == NULL) { // URL is not set
 +		db_set_ts(NULL, MODNAME, "UpdateURL", _T(DEFAULT_UPDATE_URL));
 +		result = mir_tstrdup( _T(DEFAULT_UPDATE_URL));
 +	}
 +	return result;
 +}
 +
 +int CompareHashes(const ServListEntry *p1, const ServListEntry *p2)
 +{
 +	return _tcsicmp(p1->m_name, p2->m_name);
 +}
 +
 +bool ParseHashes(const TCHAR *ptszUrl, ptrT& baseUrl, SERVLIST& arHashes)
 +{
 +	REPLACEVARSARRAY vars[2];
 +	vars[0].lptzKey = _T("platform");
 +	#ifdef WIN64
 +		vars[0].lptzValue = _T("64");
 +	#else
 +		vars[0].lptzValue = _T("32");
 +	#endif
 +	vars[1].lptzKey = vars[1].lptzValue = 0;
 +
 +	REPLACEVARSDATA dat = { sizeof(REPLACEVARSDATA) };
 +	dat.dwFlags = RVF_TCHAR;
 +	dat.variables = vars;
 +	baseUrl = (TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)ptszUrl, (LPARAM)&dat);
 +
 +	// Download version info
 +	ShowPopup(NULL, TranslateT("Plugin Updater"), TranslateT("Downloading version info..."), 4, 0);
 +
 +	FILEURL pFileUrl;
 +	mir_sntprintf(pFileUrl.tszDownloadURL, SIZEOF(pFileUrl.tszDownloadURL), _T("%s/hashes.zip"), baseUrl);
 +	mir_sntprintf(pFileUrl.tszDiskPath, SIZEOF(pFileUrl.tszDiskPath), _T("%s\\hashes.zip"), tszTempPath);
 +	if (!DownloadFile(pFileUrl.tszDownloadURL, pFileUrl.tszDiskPath, 0)) {
 +		ShowPopup(0, LPGENT("Plugin Updater"), LPGENT("An error occured while downloading the update."), 1, 0);
 +		return false;
 +	}
 +
 +	unzip(pFileUrl.tszDiskPath, tszTempPath, NULL);
 +	DeleteFile(pFileUrl.tszDiskPath);
 +
 +	TCHAR tszTmpIni[MAX_PATH] = {0};
 +	mir_sntprintf(tszTmpIni, SIZEOF(tszTmpIni), _T("%s\\hashes.txt"), tszTempPath);
 +	FILE *fp = _tfopen(tszTmpIni, _T("r"));
 +	if (!fp)
 +		return false;
 +
 +	char str[200];
 +	while(fgets(str, SIZEOF(str), fp) != NULL) {
 +		rtrim(str);
 +		char *p = strchr(str, ' ');
 +		if (p == NULL)
 +			continue;
 +
 +		*p++ = 0;
 +		if ( !opts.bUpdateIcons && !_strnicmp(str, "icons\\", 6))
 +			continue;
 +
 +		_strlwr(p);
 +
 +		int dwCrc32;
 +		char *p1 = strchr(p, ' ');
 +		if (p1 == NULL)
 +			dwCrc32 = 0;
 +		else {
 +			*p1++ = 0;
 +			sscanf(p1, "%08x", &dwCrc32);
 +		}
 +		arHashes.insert(new ServListEntry(str, p, dwCrc32));
 +	}
 +	fclose(fp);
 +	DeleteFile(tszTmpIni);
 +	return true;
 +}
 +
 +
  BOOL DownloadFile(LPCTSTR tszURL, LPCTSTR tszLocal, int CRCsum)
  {
  	DWORD dwBytes;
  | 
