📄 startsync.cpp
字号:
/*
* 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 General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY, TITLE, NONINFRINGEMENT 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
*/
// startsync.cpp - main module for the sync application
//
// Windows Header Files:
#include <windows.h>
#include <initguid.h>
#include <Notify.h>
#include <Pmpolicy.h>
#include "base/startcmd.h"
#include "base/util/utils.h"
#include "pim/SettingFunctions.h"
#include "pim/maincpp.h"
#include "notify/addresschange.h"
#include "pim/difftime.h"
#include "usernotify.h"
#include "base/Log.h"
#include "pushmessage.h"
#include "notify/util.h"
#include "notify/timed_msgbox.h"
#include "spds/constants.h"
#include "OTAConfigMessage.h"
#include "OTAConfigMessageHandler.h"
#include <cemapi.h>
#include "pim/utils.h"
#include <string>
#include "customization.h"
using namespace std;
//
// USE the pim/ClientSettings.h. THis must be shared with the same ClientSettings of the
// FunambolClient
//
#include "pim/ClientSettings.h"
#include "OutOfMemoryException.h"
#include "HwndFunctions.h"
#include "localizationUtils.h"
#define DIMCONF 128
#define DIM_PATH 256
#define NOT_RETURN_TO_MAIN_FORM -3
#define NO_SOURCES_FROM_TRANSPORT -12
#ifdef WIN32_PLATFORM_WFSP
#include "funresourcesp.h"
#endif
#ifdef WIN32_PLATFORM_PSPC
#include "funresourceppc.h"
#endif
#define PARAM_AVAILABLE TEXT("available")
#define PARAM_REMOVENOTIF TEXT("removeNotif")
#define PARAM_SCHEDULE TEXT("schedule")
#define PARAM_CRADLE TEXT("cradle")
#define PARAM_ADDRESSCHANGE TEXT("addresschange")
#define PARAM_REGISTER TEXT("register")
#define PARAM_DEREGISTER TEXT("deregister")
#define PARAM_NOTIFY TEXT("/notify")
#define PARAM_TRANSPORT TEXT("transport")
#define PARAM_INCLUSIVE TEXT("inclusive")
#define PARAM_MANUAL TEXT("manual")
#define PARAM_TCPIP TEXT("tcpip")
#define PARAM_REFRESHSERVER TEXT("refresh-from-server")
#define PARAM_REFRESHCLIENT TEXT("refresh-from-client")
#define PARAM_T_REFRESHSERVER TEXT("transport-refresh-from-server")
#define PARAM_T_REFRESHCLIENT TEXT("transport-refresh-from-client")
//--------------------------------------------------------------------- Prototypes
static inline void Alert(const wchar_t *msg, const wchar_t *title=TEXT("Warning"));
static int getPollingTime();
static bool isServerNotified();
static void setServerNotified(bool val);
//static int polling(const wchar_t **sources);
static int schedule(bool notStartNow);
static int sync(const wchar_t **sources, const wchar_t **ids);
static int doSync(const char* mode, const wchar_t **sources, const wchar_t **ids);
int checkRefreshFromServer(const wchar_t** sources);
static bool g_debug = false;
static int retValue = 0;
void setValuesInRegistry(const wchar_t* name, const wchar_t* value);
wchar_t** getEnabledSourcesFromConfig();
void setSourceOnReg(wchar_t** sources);
//--------------------------------------------------------------- Static Functions
static inline void Alert(const wchar_t *msg, const wchar_t *title)
{
#ifdef DEBUG
MessageBox (NULL, msg, title, MB_SETFOREGROUND |MB_OK);
#endif
}
/*
* This function save the process id passed by setProcessId or resetProcessId on the registry
* NOT use the function directly but use (re)setProcessID instead
*/
static void writeProcessIdOnRegistry(unsigned long processId) {
wchar_t pid[128];
wsprintf(pid, TEXT("%lu"), processId);
setClientConfiguration(NULL, PROPERTY_SPDM_PID, pid, NULL);
}
static void resetProcessID() {
writeProcessIdOnRegistry(0);
}
static void setProcessID() {
DWORD processId = GetCurrentProcessId();
writeProcessIdOnRegistry(processId);
}
static int getPollingTime()
{
wchar_t buf[32];
memset(buf, 0, 32*sizeof(wchar_t));
getClientConfigurationInternal (TEXT(""), PROPERTY_SPDM_POLLING_NOTIFICATION,
buf, FALSE);
return wcstol(buf, NULL, 10);
}
static bool isServerNotified()
{
wchar_t buf[10];
memset(buf, 0, 10*sizeof(wchar_t));
getClientConfigurationInternal (TEXT(""), PROPERTY_SPDM_SERVER_NOTIFIED,
buf, FALSE);
return ( wcscmp(buf, TEXT("1")) == 0);
}
static void setServerNotified(bool val)
{
setClientConfiguration(
TEXT(""),
PROPERTY_SPDM_SERVER_NOTIFIED,
( (val) ? TEXT("1") : TEXT("0") ),
NULL);
}
static void getAppName(wchar_t* appName) {
wchar_t path[256];
getClientConfigurationInternal (NULL, PROPERTY_SPDM_PATH_INFO, path, NULL);
wcscpy(appName, path);
wcscat(appName, TEXT("\\"));
wcscat(appName, SYNCAPP);
}
/*
* NOT_RETURN_TO_MAIN_FORM: is the value to avoid to send a message for the result page.
*/
static int schedule(bool notStartNow)
{
long t = getPollingTime();
WCHAR appName[MAX_PATH];
getAppName(appName);
SYSTEMTIME lpTime;
SYSTEMTIME pollTime;
LOG.debug("Schedule start");
//if (t > 0 && !isServerNotified()) {
if (t > 0) {
if (notStartNow == false) {
LOG.debug("Re-scheduling");
//
// Schedule the polling before running the sync.
// it needs to avoid disable of polling if the user stops the sync.
//
GetLocalTime(&lpTime);
pollTime = DT_AddDiff(nano100SecInMin, t, &lpTime);
CeRunAppAtTime(appName,&pollTime);
LOG.debug("sync");
//retValue = sync(NULL, NULL);
retValue = NOT_RETURN_TO_MAIN_FORM;
LOG.debug("Re-scheduling");
LOG.debug(_wcc(appName));
}
// The sync start
else {
GetLocalTime(&lpTime);
pollTime = DT_AddDiff(nano100SecInMin, t, &lpTime);
if (CeRunAppAtTime(appName,&pollTime)) {
retValue = NOT_RETURN_TO_MAIN_FORM;
}
}
}
if (t == 0) {
CeRunAppAtTime(appName,0);
retValue = NOT_RETURN_TO_MAIN_FORM;
}
LOG.debug("Schedule end");
return retValue;
}
static int sync(const wchar_t **sources = NULL, const wchar_t **ids = NULL)
{
return doSync(NULL, sources, ids);
}
static int recover(const char* mode, const wchar_t **sources)
{
return doSync(mode, sources, NULL);
}
//static int inclusive(const wchar_t **sources)
//{
// doSync(mode, sources, NULL);
//}
/**
* @param sources - syncronize the specified sources. Default is NULL: it means the sources
* to sync are the one set in the registry
* @param ids - the ids of the mail to be downloaded with a inclusive filter
* usually it is NULL. Not null only with the "inclusive" command line
*/
static int doSync(const char* mode, const wchar_t **sources, const wchar_t **ids)
{
HANDLE hMutex;//Handle to mutex...
//HWND wnd = NULL;
// Create mutex here
hMutex = CreateMutex(NULL, TRUE, TEXT("FunSyncInProgress") );
switch(GetLastError()) {
case ERROR_SUCCESS:
LOG.debug("Mutex created.");
break;
case ERROR_ALREADY_EXISTS:
if (g_debug)
Alert(TEXT("Another sync in progress"), TEXT("Warning"));
LOG.error("Another sync in progress");
retValue = ERR_ANOTHER_SYNC;
return ERR_ANOTHER_SYNC;
default:
LOG.error("Failed to create mutex");
return -1;
}
/*
wnd = HwndFunctions::getWindowHandle();
// Moved in maincpp
if (wnd) {
HwndFunctions::closePreviousMsgBox();
SendMessage(wnd, (WM_APP+4), NULL, NULL ); //-- send starting sync message to UI
} else {
//MessageBox (NULL, TEXT("wnd empty"), TEXT ("test"), MB_SETFOREGROUND |MB_OK);
}
*/
wchar_t path[DIM_PATH];
getClientConfigurationInternal(NULL, PROPERTY_SPDM_PATH_INFO, path, NULL);
HANDLE handleBubble = CreateThread(NULL, 0, createBubble, NULL, 0, NULL);
if (handleBubble == 0) {
LOG.error("CreateThread failed: <0x%08x>\n", GetLastError());
}
WaitForSingleObject(handleBubble, 0);
setProcessID();
retValue = synchronize(path, sources, ids, mode);
resetProcessID();
CloseHandle( hMutex );
LOG.debug("Mutex released.");
return retValue;
}
static int notify(const wchar_t **sources=NULL)
{
AN_ResponseCode responseCode = notifyAddressChange(TEXT(APPLICATION_URI));
if(responseCode == AN_AddressAccepted ){
setServerNotified(true);
}
else {
setServerNotified(false);
}
return NOT_RETURN_TO_MAIN_FORM;
}
/**
* Parse the command line
*
* @param cmdline - the command line (syntax: command [source,source,...])
*
* @param command (out) - the command name
* @param sources (out) - a NULL terminated array of source names
*/
static int parseCmdLine(const LPTSTR cmdline,
wchar_t **command,
wchar_t ***sources)
{
if( wcsstr(cmdline, TEXT("debug ")) ) {
*command = wstrdup(cmdline+wcslen(TEXT("debug ")));
g_debug = true;
}
else {
*command = wstrdup(cmdline);
g_debug = false;
}
*sources = NULL;
wchar_t *args = wcschr(*command, ' ');
if(!args) {
// in this case comand == cmdline and sources is null
return 0;
}
// terminate command and point to the start of arguments
args[0] = 0; args++;
if (!args[0]) {
// empty args after a space, like before
return 0;
}
int argc;
wchar_t *arg = args;
// Count arguments
for(argc = 1; (arg=wcschr(arg+1, ',')) != 0; argc++);
// Get arg list
wchar_t **srclist = new wchar_t *[argc+1];
arg=args;
int i;
for(i=0; i<argc; i++) {
if(!arg || !arg[0])
return -1;
srclist[i]=arg;
arg=wcschr(arg, ',');
if(arg) {
arg[0]=0; arg++;
}
}
srclist[i]=0;
*sources=srclist;
return 0;
}
static void exitHandler() {
if (retValue != ERR_ANOTHER_SYNC) {
removeNotif();
HwndFunctions::closePreviousMsgBox();
HWND hwnd = HwndFunctions::getWindowHandle();
//HWND hwnd2 = HwndFunctions::getAccountWindowHandle();
//::SendMessage(hwnd2, WM_COMMAND, (WPARAM) 6, NULL);
if (hwnd && retValue != NOT_RETURN_TO_MAIN_FORM) {
SendMessage(hwnd, (WM_APP+3), NULL, (LPARAM)retValue ); // send msg startsync ended
} else if (retValue == -40) {
MessageBox (NULL, getLocalizationUtils()->getLocalizationString(IDS_ERR_OUT_OF_MEMORY), getLocalizationUtils()->getLocalizationString(IDS_FUNAMBOL_ALERT), MB_SETFOREGROUND | MB_ICONWARNING |MB_OK);
//showMessage(IDS_ERR_OUT_OF_MEMORY);
} else if (retValue == -50) {
MessageBox (NULL, getLocalizationUtils()->getLocalizationString(IDS_ERR_LOW_MEM), getLocalizationUtils()->getLocalizationString(IDS_FUNAMBOL_ALERT), MB_SETFOREGROUND | MB_ICONWARNING |MB_OK);
//showMessage(IDS_ERR_LOW_MEM);
}
}
if (retValue == -6) { // sync stopped by the user
// reset the pid property
resetProcessID();
}
}
//------------------------------------------------------------ Public functions
void quit(int value) {
retValue = value;
exit(retValue);
}
//------------------------------------------------------------------------ MAIN
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow) {
_set_new_mode(1);
_set_new_handler(operatorNewHandler);
// Set the exit handler to remove the icon
atexit(exitHandler);
try {
//MessageBox (NULL, TEXT("stsync"), TEXT("title"), MB_SETFOREGROUND |MB_OK);
wchar_t *command, **sources;
HRESULT hr = NOERROR;
HANDLE hevtMsgAvailable= NULL;
HPUSHROUTER hPushRouter = NULL;
PUSHMSG PushMsg = {0};
PowerPolicyNotify(PPN_UNATTENDEDMODE, TRUE);
//SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_BELOW_NORMAL);
if(g_debug){
Alert(lpCmdLine);
}
if (parseCmdLine(lpCmdLine, &command, &sources)) {
Alert(TEXT("Syntax error in command line"), TEXT("StartSync"));
return 1;
}
if(!(wcscmp(command,PARAM_AVAILABLE) == 0 ||
wcscmp(command, PARAM_REMOVENOTIF) == 0 ||
wcscmp(command, PARAM_SCHEDULE) == 0 ||
wcscmp(command, PARAM_CRADLE) == 0 ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -