updater.cpp
来自「funambol window mobile客户端源代码」· C++ 代码 · 共 459 行
CPP
459 行
/*
* Funambol is a mobile platform developed by Funambol, Inc.
* Copyright (C) 2003 - 2007 Funambol, Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation with the addition of the following permission
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
* WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* 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 Affero General Public License
* along with this program; if not, see http://www.gnu.org/licenses or write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
*
* You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
* 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License
* version 3, these Appropriate Legal Notices must retain the display of the
* "Powered by Funambol" logo. If the display of the logo is not reasonably
* feasible for technical reasons, the Appropriate Legal Notices must display
* the words "Powered by Funambol".
*/
#include "Updater.h"
#include "pim/difftime.h"
#include "http/WinTransportAgent.h"
#include "http/URL.h"
#include "http/Proxy.h"
#include "http/TransportAgent.h"
#include "http/TransportAgentFactory.h"
#include "base/errors.h"
#include "localizationUtils.h"
#include "pim/maincpp.h"
#include "HwndFunctions.h"
#ifdef WIN32_PLATFORM_WFSP
#include "funresourcesp.h"
#endif
#ifdef WIN32_PLATFORM_PSPC
#include "funresourceppc.h"
#endif
//
// Init static pointer.
//
Updater* Updater::pinstance = NULL;
/*
* Method to get the sole instance
*/
Updater* Updater::getInstance(const char* comp, HWND hwnd, ClientSettings* cs) {
if (pinstance == NULL) {
pinstance = new Updater(comp, hwnd, cs);
}
return pinstance;
}
// method used to get the singleton instance
Updater* getUpdater(const char* comp, HWND hwnd, ClientSettings* cs){
return Updater::getInstance(comp, hwnd, cs);
}
Updater::Updater(const char* comp, HWND hwnd, ClientSettings* cs)
: params(cs->getUpdateParams()) {
component = comp;
version = cs->getDeviceConfig().getOem();
uiHwnd = hwnd;
settings = cs;
readParams();
populateTime();
}
Updater::~Updater() { }
int Updater::storeParams() {
settings->storeUpdateParams();
return 0;
}
int Updater::readParams() {
settings->readUpdateParams();
return 0;
}
int Updater::populateTime() {
FILETIME ft;
SYSTEMTIME st, remindst, httpst, beginning;
int remind = 0, http = 0;
unsigned long lastCheckUpdate = string2long(params.getLastCheckUpdate().c_str());
__int64 llTmp;
// the beginning of the count of the timestamp
beginning.wYear = 1970;
beginning.wMonth = 1;
beginning.wDay = 1;
beginning.wHour = 0;
beginning.wMinute = 0;
beginning.wSecond = 0;
beginning.wMilliseconds = 0;
GetSystemTime(&st);
string t = params.getIntervalRemind();
if (t != "") { remind = atoi(t.c_str()); } else { remind = 0; }
t = params.getIntervalCheckUpdateHttp();
if (t != "") { http = atoi(t.c_str()); } else { http = 0; }
// the offset from the 1970
remindst = DT_AddDiff(nano100SecInMin, remind, &beginning);
httpst = DT_AddDiff(nano100SecInMin, http, &beginning);
// convert all the times into unsigned long
SystemTimeToFileTime(&st, &ft);
memcpy (&llTmp, &ft, sizeof (__int64));
llTmp = (llTmp - 116444736000000000) / 10000000;
currentTime = (unsigned long) llTmp;
SystemTimeToFileTime(&remindst, &ft);
memcpy (&llTmp, &ft, sizeof (__int64));
llTmp = (llTmp - 116444736000000000) / 10000000;
currentRemindTime = (unsigned long) llTmp;
currentRemindTime = currentRemindTime + lastCheckUpdate;
SystemTimeToFileTime(&httpst, &ft);
memcpy (&llTmp, &ft, sizeof (__int64));
llTmp = (llTmp - 116444736000000000) / 10000000;
currentHttpIntervalTime = (unsigned long) llTmp;
currentHttpIntervalTime = currentHttpIntervalTime + lastCheckUpdate;
return 0;
}
int Updater::checkUpdateFromServer() {
requestUpdate();
return 0;
}
int Updater::startManually() {
// set the lastCheckUpdate in the registry to be saved later
params.setLastCheckUpdate(long2string(currentTime));
storeParams();
launchUpdateProcess();
return 0;
}
/**
* check the update on the server.
* return 0 if there is no action to do
* return 1 if there is something to download
*/
int Updater::checkIsToUpdate() {
int ret = 1;
if (currentTime < currentRemindTime) {
LOG.debug("No time to check on local");
ret = 0;
goto finally;
}
// after this check the params are filled with the right information
// If needed, the check is on the server
if (currentTime > currentHttpIntervalTime) {
LOG.info("Check on server location for update");
requestUpdate();
}
// set the lastCheckUpdate in the registry to be saved later
params.setLastCheckUpdate(long2string(currentTime));
storeParams();
if (params.getVersion() == "-1") {
LOG.debug("The version update is -1: nothing to do. Never check the update");
ret = 0;
}
finally:
return ret;
}
int Updater::start() {
// int ret = checkUpdate();
int ret = showMessage(isMandatory());
if (ret == 0) { // response is yes
LOG.info("User chooses to start the update procedure...");
// minimize the window if there is one
if (uiHwnd == NULL) {
uiHwnd = HwndFunctions::getWindowHandle();
}
if (uiHwnd != NULL) {
SendMessage(uiHwnd, ID_MYMSG_OK, NULL, NULL);
}
params.setNow("1");
launchUpdateProcess();
// launch the browser process
// the other stuffs are closed by the uninstall process
//
} else if (ret == 1){
LOG.info("User chooses update later...");
// response is Later
params.setLater("1");
// goto finally;
} else if (ret == 2) {
// response is skip
// message use the Update Software
LOG.info("User chooses to skip the update...");
params.setSkipped(params.getVersion());
OpenMessageBox(uiHwnd, IDS_BUT_OK, IDS_UP_MESSAGE_SKIPPED);
}
storeParams();
return ret;
}
int Updater::startWithoutUI() {
int ret = checkIsToUpdate();
if (ret != 0) {
start();
}
return 0;
}
bool Updater::launchUpdateProcess() {
SHELLEXECUTEINFO lpExecInfo;
memset(&lpExecInfo, 0, sizeof(SHELLEXECUTEINFO));
lpExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
wchar_t* site = toWideChar(params.getUrlUpdate().c_str());
lpExecInfo.lpFile = site;
lpExecInfo.nShow = SW_SHOWNORMAL;
lpExecInfo.lpVerb = _T("open");
ShellExecuteEx(&lpExecInfo);
if (site) { delete [] site; site = NULL; }
return true;
}
bool Updater::isMandatory() {
return (params.getMandatory() != "0") ? true : false;
}
void Updater::updateTime() {
populateTime();
params.setLastCheckUpdate(long2string(currentTime));
storeParams();
}
int Updater::requestUpdate() {
URL url;
string s;
if (params.getUrlCheck().empty() || params.getUrlCheck() == "0") {
url.setURL(settings->getAccessConfig().getSyncURL());
string port;
if (url.port != 0) { port = ":"; port += itow(url.port); }
// compose the url
s = url.protocol;
s += "://";
s += url.host;
s += port;
s += UP_URL_RESOURCE;
} else {
s = params.getUrlCheck().c_str();
}
// add the component and version to the url
s += "?";
s += UP_URL_COMPONENT;
s += component;
s += "&";
s += UP_URL_VERSION;
s += version;
url.setURL(s.c_str());
Proxy proxy;
TransportAgent* transportAgent = NULL;
transportAgent = TransportAgentFactory::getTransportAgent(url, proxy);
string message = "";
char* response = transportAgent->sendMessage(message.c_str());
if (response != NULL) {
parseMessage(response);
} else {
LOG.error("Client update: %i: %s", getLastErrorCode(), getLastErrorMsg());
LOG.error("Uses the stored parameters");
}
if (params.getMandatory() != "0") {
params.setMandatory(params.getVersion());
params.setSkipped("0");
}
return 0;
}
string getNewLine(string& s) {
string newline;
size_t pos1 = s.find("\n");
if(pos1 == string::npos){
LOG.error("Updater: no newlines in message?");
return newline;
}
size_t pos2 = pos1 + 1 ;
while (s[pos1-1] == '\r'){
pos1--;
}
newline = s.substr(pos1, pos2-pos1);
return newline;
}
list<string> getListedString(string& s, string separator) {
list<string> allString;
allString.clear();
size_t seplen = separator.length();
char *base = (char*)s.c_str();
char *p = strstr(base, separator.c_str());
while (p) {
string token(base, p - base);
allString.push_back(token);
base = p + seplen;
p = strstr(base, separator.c_str());
}
string token(base);
allString.push_back(token);
return allString;
}
/*
* return -1: no new lines
*/
int Updater::parseMessage(string message) {
string newline = getNewLine(message);
if (newline == "") {
return -1;
}
string line;
list<string> allString = getListedString(message, newline);
list<string>::iterator it;
for (it = allString.begin(); it != allString.end(); it++) {
line = *it;
if (line.find(UP_MANDATORY) == 0) {
string mand = line.substr(strlen(UP_MANDATORY));
if (mand == "mandatory") {
params.setMandatory("1");
} else {
// if the current update is not mandatory but the previous was,
// the parameter is not overwritten
if (params.getMandatory() == "0") {
params.setMandatory("0");
}
}
} else if (line.find(UP_RELEASE_DATE) == 0) {
params.setReleaseDate(line.substr(strlen(UP_RELEASE_DATE)));
} else if (line.find(UP_SIZE) == 0) {
params.setSize(line.substr(strlen(UP_SIZE)));
} else if (line.find(UP_VERSION) == 0) {
params.setVersion(line.substr(strlen(UP_VERSION)));
} else if (line.find(UP_URL_UPDATE) == 0) {
params.setUrlUpdate(line.substr(strlen(UP_URL_UPDATE)));
} else if (line.find(UP_URL_COMMENT) == 0) {
params.setUrlComment(line.substr(strlen(UP_URL_COMMENT)));
}
}
return 0;
}
int getBuildNumberFromVersion(const char* swv) {
int major=0, minor=0, build=0;
if (!swv) {
return 0;
}
sscanf(swv, "%d.%d.%d", &major, &minor, &build);
return (major*10000 + minor*100 + build);
}
int Updater::showMessage(int type) {
int ret = -1;
int currentVersion = getBuildNumberFromVersion(params.getCurrentVersion().c_str());
int version = getBuildNumberFromVersion(params.getVersion().c_str());
if (params.getCurrentVersion() == params.getVersion()) {
ret = 3;
LOG.debug("The version required is the same installed on the client");
} else if (currentVersion > version) {
ret = 3;
LOG.debug("The version required is lower than the installed on the client");
} else if (!isMandatory()) {
if (params.getVersion() == params.getSkipped()) {
ret = 4;
LOG.debug("The version required is the same just skipped");
} else {
ret = OpenMessageBox(uiHwnd, IDS_BUT_NOW_LATER_SKIP, IDS_UP_MESSAGE);
LOG.debug("Asked if the user want update (no mandatory): response (0Ye, 1La, 2Sk) %i", ret);
}
} else {
ret = OpenMessageBox(uiHwnd, IDS_BUT_NOW_LATER, IDS_UP_MESSAGE);
LOG.debug("Asked if the user want update (mandatory): response (0Ye, 1La) %i", ret);
}
return ret;
}
string Updater::long2string(unsigned long v) {
char tt[256];
sprintf(tt, "%lu", v);
string s(tt);
return s;
}
unsigned long Updater::string2long(string v) {
return (unsigned long)atol(v.c_str());
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?