From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- src/modules/updatenotify/updatenotify.cpp | 680 ++++++++++++++++++++++++++++++ 1 file changed, 680 insertions(+) create mode 100644 src/modules/updatenotify/updatenotify.cpp (limited to 'src/modules/updatenotify') diff --git a/src/modules/updatenotify/updatenotify.cpp b/src/modules/updatenotify/updatenotify.cpp new file mode 100644 index 0000000000..ef955ba3c5 --- /dev/null +++ b/src/modules/updatenotify/updatenotify.cpp @@ -0,0 +1,680 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2009 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "commonheaders.h" + +#define UN_MOD "UpdateNotify" +#define UN_ENABLE "UpdateNotifyEnable" +#define UN_ENABLE_DEF 1 +#define UN_LASTCHECK "UpdateNotifyLastCheck" +#define UN_SERVERPERIOD "UpdateNotifyPingDelayPeriod" +#define UN_CURRENTVERSION "UpdateNotifyCurrentVersion" +#define UN_CURRENTVERSIONFND "UpdateNotifyCurrentVersionFound" +#define UN_NOTIFYTYPE "UpdateNotifyType" +#define UN_NOTIFYTYPE_STABLE 1 +#define UN_NOTIFYTYPE_BETA 2 +#define UN_NOTIFYTYPE_ALPHA 3 +#define UN_NOTIFYTYPE_DEF UN_NOTIFYTYPE_STABLE +#define UN_CUSTOMXMLURL "UpdateNotifyCustomXMLURL" +#define UN_URLXML "http://update.miranda-im.org/update.xml" +#define UN_MINCHECKTIME 60*60 /* Check no more than once an hour */ +#define UN_DEFAULTCHECKTIME 60*48*60 /* Default to check once every 48 hours */ +#define UN_FIRSTCHECK 15 /* First check 15 seconds after startup */ +#define UN_REPEATNOTIFYDLY 24*60*60 /* 24 hours before showing release notification again */ + +typedef struct { + int isNew; + int isManual; + char version[64]; + char versionReal[16]; + char notesUrl[256]; + char downloadUrl[256]; + DWORD reqTime; +} UpdateNotifyData; + +typedef struct { + DWORD dwVersion; + char *szVersionPublic; + char *szVersion; + char *szDownload; + char *szNotes; +} UpdateNotifyReleaseData; + +static BOOL bModuleInitialized = FALSE; +static HANDLE hNetlibUser = 0, hHookModules, hHookPreShutdown; +static UINT_PTR updateTimerId; +static HANDLE dwUpdateThreadID = 0; +static HWND hwndUpdateDlg = 0, hwndManualUpdateDlg = 0; +static XML_API xun; + +static int UpdateNotifyOptInit(WPARAM wParam, LPARAM lParam); +static INT_PTR UpdateNotifyMenuCommand(WPARAM wParam, LPARAM lParam); +static VOID CALLBACK UpdateNotifyTimerCheck(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime); +static int UpdateNotifyMakeRequest(UpdateNotifyData *und); +static void UpdateNotifyPerform(void *m); +static INT_PTR CALLBACK UpdateNotifyProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK UpdateNotifyOptsProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +static int UpdateNotifyModulesLoaded(WPARAM, LPARAM) { + NETLIBUSER nlu; + + ZeroMemory(&nlu, sizeof(nlu)); + nlu.cbSize = sizeof(nlu); + nlu.flags = NUF_OUTGOING|NUF_HTTPCONNS; + nlu.szSettingsModule = UN_MOD; + nlu.szDescriptiveName = Translate("Update notification"); + hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); + return 0; +} + +static int UpdateNotifyPreShutdown(WPARAM, LPARAM) { + if (IsWindow(hwndUpdateDlg)) { + SendMessage(hwndUpdateDlg, WM_COMMAND, MAKELONG(IDOK, 0), 0); + } + if (IsWindow(hwndManualUpdateDlg)) { + SendMessage(hwndManualUpdateDlg, WM_COMMAND, MAKELONG(IDOK, 0), 0); + } + return 0; +} + +int LoadUpdateNotifyModule(void) { + CLISTMENUITEM mi = { 0 }; + + bModuleInitialized = TRUE; + + // Upgrade Routine + if (DBGetContactSettingByte(NULL, UN_MOD, "UpdateNotifyNotifyAlpha", 0)) { + DBDeleteContactSetting(NULL, UN_MOD, "UpdateNotifyNotifyAlpha"); + DBWriteContactSettingByte(NULL, UN_MOD, UN_NOTIFYTYPE, UN_NOTIFYTYPE_ALPHA); + } + // Ene Upgrade Routine + + CreateServiceFunction("UpdateNotify/UpdateCommand", UpdateNotifyMenuCommand); + mi.cbSize = sizeof(mi); + mi.flags = CMIF_ICONFROMICOLIB; + mi.icolibItem = GetSkinIconHandle(SKINICON_OTHER_EMPTYBLOB); + mi.pszPopupName = LPGEN("&Help"); + mi.position = 2000030000; + mi.pszName = LPGEN("Check for Update"); + mi.pszService = "UpdateNotify/UpdateCommand"; + CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi); + + hHookModules = HookEvent(ME_SYSTEM_MODULESLOADED, UpdateNotifyModulesLoaded); + hHookPreShutdown = HookEvent(ME_SYSTEM_PRESHUTDOWN, UpdateNotifyPreShutdown); + HookEvent(ME_OPT_INITIALISE, UpdateNotifyOptInit); + updateTimerId = SetTimer(NULL, 0, 1000*UN_FIRSTCHECK, UpdateNotifyTimerCheck); + mir_getXI(&xun); + return 0; +} + +void UnloadUpdateNotifyModule() +{ + if (!bModuleInitialized) return; + UnhookEvent(hHookModules); + UnhookEvent(hHookPreShutdown); +} + +static int UpdateNotifyOptInit(WPARAM wParam, LPARAM) { + OPTIONSDIALOGPAGE odp; + + ZeroMemory(&odp, sizeof(odp)); + odp.cbSize = sizeof(odp); + odp.position = 100000000; + odp.hInstance = hMirandaInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_UPDATENOTIFY); + odp.pszGroup = LPGEN("Events"); + odp.pszTitle = LPGEN("Update Notify"); + odp.pfnDlgProc = UpdateNotifyOptsProc; + odp.flags = ODPF_BOLDGROUPS; + CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); + return 0; +} + +static INT_PTR UpdateNotifyMenuCommand(WPARAM, LPARAM) { + UpdateNotifyData und; + + if (IsWindow(hwndManualUpdateDlg)) { + SetForegroundWindow(hwndManualUpdateDlg); + return 0; + } + ZeroMemory(&und, sizeof(und)); + UpdateNotifyMakeRequest(&und); + if (und.isNew) { + DBWriteContactSettingString(NULL, UN_MOD, UN_CURRENTVERSION, und.versionReal); + DBWriteContactSettingDword(NULL, UN_MOD, UN_CURRENTVERSIONFND, und.reqTime); + } + und.isManual = 1; + DialogBoxParam(hMirandaInst, MAKEINTRESOURCE(IDD_UPDATE_NOTIFY), 0, UpdateNotifyProc,(LPARAM)&und); + hwndManualUpdateDlg = 0; + return 0; +} + +static VOID CALLBACK UpdateNotifyTimerCheck(HWND, UINT, UINT_PTR, DWORD) +{ + KillTimer(NULL, updateTimerId); + if (!DBGetContactSettingByte(NULL, UN_MOD, UN_ENABLE, UN_ENABLE_DEF)) + return; + if (dwUpdateThreadID!=0) { + Netlib_Logf(hNetlibUser, "Update notification already running, ignoring attempt"); + return; + } + { + DWORD lastCheck = 0; + + if (!hNetlibUser) + return; + lastCheck = DBGetContactSettingDword(NULL, UN_MOD, UN_LASTCHECK, 0); + if (!lastCheck) { // never checked for update before + Netlib_Logf(hNetlibUser, "Running update notify check for the first time."); + dwUpdateThreadID = mir_forkthread(UpdateNotifyPerform, 0); + } + else { + DWORD dwNow = time(NULL), dwTimeDiff; + DWORD dwServerPing = DBGetContactSettingDword(NULL, UN_MOD, UN_SERVERPERIOD, UN_DEFAULTCHECKTIME); + + if (lastCheck>dwNow) { + // time for last check is after the current date so reset lastcheck and quit + DBWriteContactSettingDword(NULL, UN_MOD, UN_LASTCHECK, dwNow); + return; + } + dwTimeDiff = dwNow - lastCheck; + if (dwServerPingdwServerPing) + dwUpdateThreadID = mir_forkthread(UpdateNotifyPerform, 0); + } + updateTimerId = SetTimer(NULL, 0, 1000*UN_MINCHECKTIME, UpdateNotifyTimerCheck); + } +} + +static DWORD UpdateNotifyMakeVersion(char *str) { + DWORD a1,a2,a3,a4; + if (!str) + return 0; + sscanf(str, "%u.%u.%u.%u", &a1, &a2, &a3, &a4); + return PLUGIN_MAKE_VERSION(a1, a2, a3, a4); +} + +static int UpdateNotifyIsNewer(DWORD dwCurrent, DWORD dwTest) { + if (dwTest>dwCurrent) + return 1; + return 0; +} + +static int UpdateNotifyReleaseDataValid(UpdateNotifyReleaseData *d) { + if (d&&d->szVersionPublic&&d->szVersion&&d->szDownload&&d->szNotes) + return 1; + return 0; +} + +static void UpdateNotifyFreeReleaseData(UpdateNotifyReleaseData *d) { + if (!d) + return; + if (d->szVersionPublic) mir_free(d->szVersionPublic); + if (d->szVersion) mir_free(d->szVersion); + if (d->szDownload) mir_free(d->szDownload); + if (d->szNotes) mir_free(d->szNotes); +} + +static void UpdateNotifyReleaseLogUpdate(UpdateNotifyReleaseData *d) { + if (!UpdateNotifyReleaseDataValid(d)) + return; + #ifdef _WIN64 + Netlib_Logf(hNetlibUser, "Update server version: %s [%s] [64-bit]", d->szVersionPublic, d->szVersion); + #elif defined(_UNICODE) + Netlib_Logf(hNetlibUser, "Update server version: %s [%s] [Unicode]", d->szVersionPublic, d->szVersion); + #else + Netlib_Logf(hNetlibUser, "Update server version: %s [%s] [ANSI]", d->szVersionPublic, d->szVersion); + #endif + +} + +static void UpdateNotifyReleaseCopyData(UpdateNotifyReleaseData *d, UpdateNotifyData *und) { + if (!UpdateNotifyReleaseDataValid(d)||!und) + return; + mir_snprintf(und->version, sizeof(und->version), "%s", d->szVersionPublic); + mir_snprintf(und->versionReal, sizeof(und->versionReal), "%s", d->szVersion); + mir_snprintf(und->notesUrl, sizeof(und->notesUrl), "%s", d->szNotes); + mir_snprintf(und->downloadUrl, sizeof(und->downloadUrl), "%s", d->szDownload); +} + +static int UpdateNotifyMakeRequest(UpdateNotifyData *und) { + NETLIBHTTPREQUEST req; + NETLIBHTTPREQUEST *resp; + NETLIBHTTPHEADER headers[1]; + DWORD dwVersion; + char szVersion[32], szUrl[256], szVersionText[128], szUserAgent[64]; + int isUnicode, isAlphaCheck, isBetaCheck; + DBVARIANT dbv; + + if (!und) + return 0; + und->version[0] = 0; + und->versionReal[0] = 0; + und->notesUrl[0] = 0; + und->downloadUrl[0] = 0; + und->reqTime = time(NULL); + + DBWriteContactSettingDword(NULL, UN_MOD, UN_LASTCHECK, und->reqTime); + CallService(MS_SYSTEM_GETVERSIONTEXT, sizeof(szVersionText), (LPARAM)szVersionText); + isUnicode = strstr(szVersionText, "Unicode") != NULL ? 1 : 0; + isBetaCheck = DBGetContactSettingByte(NULL, UN_MOD, UN_NOTIFYTYPE, UN_NOTIFYTYPE_DEF)==UN_NOTIFYTYPE_BETA?1:0; + isAlphaCheck = DBGetContactSettingByte(NULL, UN_MOD, UN_NOTIFYTYPE, UN_NOTIFYTYPE_DEF)==UN_NOTIFYTYPE_ALPHA?1:0; + dwVersion = CallService(MS_SYSTEM_GETVERSION, 0, 0); + mir_snprintf(szVersion, sizeof(szVersion), "%d.%d.%d.%d", + HIBYTE(HIWORD(dwVersion)), LOBYTE(HIWORD(dwVersion)), + HIBYTE(LOWORD(dwVersion)), LOBYTE(LOWORD(dwVersion))); + if (!DBGetContactSettingString(NULL, UN_MOD, UN_CUSTOMXMLURL, &dbv)) { + mir_snprintf(szUrl, sizeof(szUrl), "%s", dbv.pszVal?dbv.pszVal:UN_URLXML); + DBFreeVariant(&dbv); + } + else mir_snprintf(szUrl, sizeof(szUrl), "%s", UN_URLXML); + ZeroMemory(&req, sizeof(req)); + req.cbSize = sizeof(req); + req.requestType = REQUEST_GET; + req.szUrl = szUrl; + req.flags = 0; + headers[0].szName = "User-Agent"; + headers[0].szValue = szUserAgent; + #ifdef _WIN64 + mir_snprintf(szUserAgent, sizeof(szUserAgent), "Miranda/%s (x64)", szVersion); + #elif defined(_UNICODE) + mir_snprintf(szUserAgent, sizeof(szUserAgent), "Miranda/%s (Unicode)", szVersion); + #else + mir_snprintf(szUserAgent, sizeof(szUserAgent), "Miranda/%s (ANSI)", szVersion); + #endif + req.headersCount = 1; + req.headers = headers; + resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUser, (LPARAM)&req); + if (resp) { + if (resp->resultCode == 200 && resp->dataLength > 0) { + //int i; + int resUpdate = 0; + TCHAR *tXml; + char *tmp; + HXML nodeDoc, n; + + tXml = mir_a2t(resp->pData); + nodeDoc = xun.parseString(tXml, 0, _T("miranda")); + if (nodeDoc) { + int rdStableValid = 0, rdBetaValid = 0, rdAlphaValid = 0; + // stable release + UpdateNotifyReleaseData rdStable; + ZeroMemory(&rdStable, sizeof(rdStable)); + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasestable/versionpublic"), 0)) != NULL && xun.getText(n)) { + rdStable.szVersionPublic = mir_t2a(xun.getText(n)); + } + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasestable/versionreal"), 0)) != NULL && xun.getText(n)) { + rdStable.szVersion = mir_t2a(xun.getText(n)); + if (rdStable.szVersion) + rdStable.dwVersion = UpdateNotifyMakeVersion(rdStable.szVersion); + } + #ifdef _WIN64 + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasestable/downloadx64exe"), 0)) != NULL && xun.getText(n)) { + rdStable.szDownload = mir_t2a(xun.getText(n)); + } + #elif defined(_UNICODE) + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasestable/downloadunicodeexe"), 0)) != NULL && xun.getText(n)) { + rdStable.szDownload = mir_t2a(xun.getText(n)); + } + #else + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasestable/downloadansiexe"), 0)) != NULL && xun.getText(n)) { + rdStable.szDownload = mir_t2a(xun.getText(n)); + } + #endif + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasestable/notesurl"), 0)) != NULL && xun.getText(n)) { + rdStable.szNotes = mir_t2a(xun.getText(n)); + } + rdStableValid = UpdateNotifyReleaseDataValid(&rdStable); + + // beta release + UpdateNotifyReleaseData rdBeta; + ZeroMemory(&rdBeta, sizeof(rdBeta)); + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasebeta/versionpublic"), 0)) != NULL && xun.getText(n)) { + rdBeta.szVersionPublic = mir_t2a(xun.getText(n)); + } + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasebeta/versionreal"), 0)) != NULL && xun.getText(n)) { + rdBeta.szVersion = mir_t2a(xun.getText(n)); + if (rdBeta.szVersion) + rdBeta.dwVersion = UpdateNotifyMakeVersion(rdBeta.szVersion); + } + #ifdef _WIN64 + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasebeta/downloadx64zip"), 0)) != NULL && xun.getText(n)) { + rdBeta.szDownload = mir_t2a(xun.getText(n)); + } + #elif defined(_UNICODE) + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasebeta/downloadunicodeexe"), 0)) != NULL && xun.getText(n)) { + rdBeta.szDownload = mir_t2a(xun.getText(n)); + } + #else + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasebeta/downloadansiexe"), 0)) != NULL && xun.getText(n)) { + rdBeta.szDownload = mir_t2a(xun.getText(n)); + } + #endif + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasebeta/notesurl"), 0)) != NULL && xun.getText(n)) { + rdBeta.szNotes = mir_t2a(xun.getText(n)); + } + rdBetaValid = UpdateNotifyReleaseDataValid(&rdBeta); + + // alpha release + UpdateNotifyReleaseData rdAlpha; + ZeroMemory(&rdAlpha, sizeof(rdAlpha)); + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasealpha/versionpublic"), 0)) != NULL && xun.getText(n)) { + rdAlpha.szVersionPublic = mir_t2a(xun.getText(n)); + } + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasealpha/versionreal"), 0)) != NULL && xun.getText(n)) { + rdAlpha.szVersion = mir_t2a(xun.getText(n)); + if (rdAlpha.szVersion) + rdAlpha.dwVersion = UpdateNotifyMakeVersion(rdAlpha.szVersion); + } + #ifdef _WIN64 + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasealpha/downloadx64zip"), 0)) != NULL && xun.getText(n)) { + rdAlpha.szDownload = mir_t2a(xun.getText(n)); + } + #elif defined(_UNICODE) + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasealpha/downloadunicodezip"), 0)) != NULL && xun.getText(n)) { + rdAlpha.szDownload = mir_t2a(xun.getText(n)); + } + #else + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasealpha/downloadansizip"), 0)) != NULL && xun.getText(n)) { + rdAlpha.szDownload = mir_t2a(xun.getText(n)); + } + #endif + if ((n = xun.getChildByPath(nodeDoc, _T("releases/releasealpha/notesurl"), 0)) != NULL && xun.getText(n)) { + rdAlpha.szNotes = mir_t2a(xun.getText(n)); + } + rdAlphaValid = UpdateNotifyReleaseDataValid(&rdAlpha); + + if (isBetaCheck) { + if (!rdBetaValid&&rdStableValid) { + UpdateNotifyReleaseLogUpdate(&rdStable); + if (UpdateNotifyIsNewer(dwVersion, rdStable.dwVersion)) + resUpdate = 1; + UpdateNotifyReleaseCopyData(&rdStable, und); + } + else if (rdBetaValid&&rdStableValid&&UpdateNotifyIsNewer(rdBeta.dwVersion, rdStable.dwVersion)) { + UpdateNotifyReleaseLogUpdate(&rdStable); + if (UpdateNotifyIsNewer(dwVersion, UpdateNotifyMakeVersion(rdStable.szVersion))) + resUpdate = 1; + UpdateNotifyReleaseCopyData(&rdStable, und); + } + else if (rdBetaValid) { + UpdateNotifyReleaseLogUpdate(&rdBeta); + if (UpdateNotifyIsNewer(dwVersion, rdBeta.dwVersion)) + resUpdate = 1; + UpdateNotifyReleaseCopyData(&rdBeta, und); + } + } + else if (isAlphaCheck) { + if (!rdAlphaValid&&rdStableValid) { + if (UpdateNotifyIsNewer(rdStable.dwVersion, rdAlpha.dwVersion)) { + UpdateNotifyReleaseLogUpdate(&rdAlpha); + if (UpdateNotifyIsNewer(dwVersion, rdAlpha.dwVersion)) + resUpdate = 1; + UpdateNotifyReleaseCopyData(&rdAlpha, und); + } + else { + UpdateNotifyReleaseLogUpdate(&rdStable); + if (UpdateNotifyIsNewer(dwVersion, rdStable.dwVersion)) + resUpdate = 1; + UpdateNotifyReleaseCopyData(&rdStable, und); + } + } + else if (rdAlphaValid&&rdStableValid&&UpdateNotifyIsNewer(rdAlpha.dwVersion, rdStable.dwVersion)) { + UpdateNotifyReleaseLogUpdate(&rdStable); + if (UpdateNotifyIsNewer(dwVersion, rdStable.dwVersion)) + resUpdate = 1; + UpdateNotifyReleaseCopyData(&rdStable, und); + } + else if (!rdAlphaValid&&rdBetaValid&&rdStableValid) { + if (UpdateNotifyIsNewer(rdStable.dwVersion, rdBeta.dwVersion)) { + UpdateNotifyReleaseLogUpdate(&rdBeta); + if (UpdateNotifyIsNewer(dwVersion, rdBeta.dwVersion)) + resUpdate = 1; + UpdateNotifyReleaseCopyData(&rdBeta, und); + } + else { + UpdateNotifyReleaseLogUpdate(&rdStable); + if (UpdateNotifyIsNewer(dwVersion, rdStable.dwVersion)) + resUpdate = 1; + UpdateNotifyReleaseCopyData(&rdStable, und); + } + } + else if (rdAlphaValid) { + UpdateNotifyReleaseLogUpdate(&rdAlpha); + if (UpdateNotifyIsNewer(dwVersion, rdAlpha.dwVersion)) + resUpdate = 1; + UpdateNotifyReleaseCopyData(&rdAlpha, und); + } + } + else { + if (rdStableValid) { + UpdateNotifyReleaseLogUpdate(&rdStable); + if (UpdateNotifyIsNewer(dwVersion, rdStable.dwVersion)) + resUpdate = 1; + UpdateNotifyReleaseCopyData(&rdStable, und); + } + } + + UpdateNotifyFreeReleaseData(&rdStable); + UpdateNotifyFreeReleaseData(&rdBeta); + UpdateNotifyFreeReleaseData(&rdAlpha); + // settings + if ((n = xun.getChildByPath(nodeDoc, _T("settings/ping"), 0)) != NULL && xun.getText(n)) { + tmp = mir_t2a(xun.getText(n)); + if (tmp) { + int pingval = atoi(tmp); + if ((pingval*60*60)>UN_MINCHECKTIME) { + Netlib_Logf(hNetlibUser, "Next update check in %d hours", pingval); + DBWriteContactSettingDword(NULL, UN_MOD, UN_SERVERPERIOD, pingval*60*60); + } + mir_free(tmp); + } + } + if ((n = xun.getChildByPath(nodeDoc, _T("settings/updateurl"), 0)) != NULL && xun.getText(n)) { + tmp = mir_t2a(xun.getText(n)); + if (tmp) { + Netlib_Logf(hNetlibUser, "Update URL has changed (%s)", tmp); + DBWriteContactSettingString(NULL, UN_MOD, UN_CUSTOMXMLURL, tmp); + mir_free(tmp); + } + } + if (resUpdate&&und->version&&und->versionReal&&und->notesUrl&&und->downloadUrl) { + Netlib_Logf(hNetlibUser, "A new version of Miranda IM is available: %s", und->version); + und->isNew = 1; + } + xun.destroyNode(nodeDoc); + } + mir_free(tXml); + } + else Netlib_Logf(hNetlibUser, "Invalid response code from HTTP request"); + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + } + else Netlib_Logf(hNetlibUser, "No response from HTTP request"); + return und->isNew; +} + +static void UpdateNotifyPerform(void *) +{ + UpdateNotifyData und; + DBVARIANT dbv; + + ZeroMemory(&und, sizeof(und)); + UpdateNotifyMakeRequest(&und); + if (und.isNew) { + int notify = 1; + + if (!DBGetContactSettingString(NULL, UN_MOD, UN_CURRENTVERSION, &dbv)) { + if (!strcmp(dbv.pszVal, und.versionReal)) { // already notified of this version + + DWORD dwNotifyLast = DBGetContactSettingDword(NULL, UN_MOD, UN_CURRENTVERSIONFND, 0); + + if (dwNotifyLast>und.reqTime) { // fix last check date if time has changed + DBWriteContactSettingDword(NULL, UN_MOD, UN_CURRENTVERSIONFND, und.reqTime); + notify = 0; + } + else if (und.reqTime-dwNotifyLastisManual) + hwndManualUpdateDlg = hwndDlg; + else hwndUpdateDlg = hwndDlg; + if (und->isNew) { + TCHAR* ptszVer = mir_a2t( und->version ); + mir_sntprintf(szTmp, SIZEOF(szTmp), TranslateT("Miranda IM %s Now Available"), ptszVer); + mir_free(ptszVer); + ShowWindow(GetDlgItem(hwndDlg, IDC_UPDATE), SW_HIDE); + } + else { + mir_sntprintf(szTmp, SIZEOF(szTmp), TranslateT("No Update Available")); + SetDlgItemText(hwndDlg, IDC_MESSAGE, TranslateT("You are running the latest version of Miranda IM. No update is available at this time.")); + EnableWindow(GetDlgItem(hwndDlg, IDC_DOWNLOAD), FALSE); + ShowWindow(GetDlgItem(hwndDlg, IDC_VERSION), SW_HIDE); + } + SetWindowText(hwndDlg, szTmp); + CallService(MS_SYSTEM_GETVERSIONTEXT, sizeof(szVersion), (LPARAM)szVersion); + p = strstr(szVersion, "x64 Unicode"); + if (p) + *p = '\0'; + p = strstr(szVersion, " Unicode"); + if (p) + *p = '\0'; + SetDlgItemTextA(hwndDlg, IDC_CURRENTVERSION, szVersion); + mir_snprintf(szVersionTmp, SIZEOF(szVersionTmp), "%s", und->version?und->version:szVersion); + SetDlgItemTextA(hwndDlg, und->isNew?IDC_VERSION:IDC_UPDATE, szVersionTmp); + if (und->isNew) { + HFONT hFont; + LOGFONT lf; + + hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_VERSION, WM_GETFONT, 0, 0); + GetObject(hFont, sizeof(lf), &lf); + lf.lfWeight = FW_BOLD; + hFont = CreateFontIndirect(&lf); + SendDlgItemMessage(hwndDlg, IDC_VERSION, WM_SETFONT, (WPARAM)hFont, 0); + hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_NEWVERSIONLABEL, WM_GETFONT, 0, 0); + GetObject(hFont, sizeof(lf), &lf); + lf.lfWeight = FW_BOLD; + hFont = CreateFontIndirect(&lf); + SendDlgItemMessage(hwndDlg, IDC_NEWVERSIONLABEL, WM_SETFONT, (WPARAM)hFont, 0); + } + SetFocus(GetDlgItem(hwndDlg, IDOK)); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); + } + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_VERSION: + { + UpdateNotifyData *und = (UpdateNotifyData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if (und&&und->notesUrl) + CallService(MS_UTILS_OPENURL, 1, (LPARAM)und->notesUrl); + break; + } + case IDC_DOWNLOAD: + { + UpdateNotifyData *und = (UpdateNotifyData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if (und&&und->downloadUrl) { + CallService(MS_UTILS_OPENURL, 1, (LPARAM)und->downloadUrl); + DestroyWindow(hwndDlg); + } + break; + } + case IDOK: + case IDCANCEL: + DestroyWindow(hwndDlg); + return TRUE; + } + break; + + case WM_DESTROY: + Window_FreeIcon_IcoLib( hwndDlg ); + break; + } + return FALSE; +} + +static INT_PTR CALLBACK UpdateNotifyOptsProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + CheckDlgButton(hwndDlg, IDC_ENABLEUPDATES, DBGetContactSettingByte(NULL, UN_MOD, UN_ENABLE, UN_ENABLE_DEF) ? BST_CHECKED : BST_UNCHECKED); + switch (DBGetContactSettingByte(NULL, UN_MOD, UN_NOTIFYTYPE, UN_NOTIFYTYPE_STABLE)) { + case UN_NOTIFYTYPE_BETA: CheckDlgButton(hwndDlg, IDC_ENABLEBETA, BST_CHECKED); break; + case UN_NOTIFYTYPE_ALPHA: CheckDlgButton(hwndDlg, IDC_ENABLEALPHA, BST_CHECKED); break; + default: CheckDlgButton(hwndDlg, IDC_ENABLESTABLE, BST_CHECKED); break; + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_ENABLEUPDATES: + case IDC_ENABLEALPHA: + case IDC_ENABLEBETA: + case IDC_ENABLESTABLE: + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + break; + + case WM_NOTIFY: + { + NMHDR *hdr = (NMHDR *)lParam; + if (hdr&&hdr->code==PSN_APPLY) { + DBWriteContactSettingByte(NULL, UN_MOD, UN_ENABLE, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ENABLEUPDATES))); + if (IsDlgButtonChecked(hwndDlg, IDC_ENABLESTABLE)) + DBWriteContactSettingByte(NULL, UN_MOD, UN_NOTIFYTYPE, UN_NOTIFYTYPE_STABLE); + if (IsDlgButtonChecked(hwndDlg, IDC_ENABLEBETA)) + DBWriteContactSettingByte(NULL, UN_MOD, UN_NOTIFYTYPE, UN_NOTIFYTYPE_BETA); + if (IsDlgButtonChecked(hwndDlg, IDC_ENABLEALPHA)) + DBWriteContactSettingByte(NULL, UN_MOD, UN_NOTIFYTYPE, UN_NOTIFYTYPE_ALPHA); + } + break; + } + } + return FALSE; +} -- cgit v1.2.3