notlstnr.cpp
来自「funambol window mobile客户端源代码」· C++ 代码 · 共 815 行 · 第 1/2 页
CPP
815 行
/*
* 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".
*/
/* notlstnr.cpp : Defines the entry point for the DLL application.
* Handle all the interaction with Services.exe and
* with the netwotk. Uses class S4JProxy to interact
* with sync4j engine.
*/
#include "stdafx.h"
#include "notlstnr.h"
#include "Notify.h"
#include <stdio.h>
#include <service.h>
#include <iptypes.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <Pmpolicy.h>
#include "http/GPRSConnection.h"
#include "s4jproxy.h"
#include "worker.h"
#include "notify/checknet.h"
#include "notify/s4n_service.h"
#include "notify/addresschange.h"
#include "notify/util.h"
#include "pim/SettingFunctions.h"
#include "base/startcmd.h"
#include "base/util/utils.h"
#include "processUtils.h"
#include "localizationUtils.h"
#include "pim/ClientSettings.h"
#include "CTPConfig.h"
#include "CTPManager.h"
#include "CTPMessage.h"
#define NOTLSTNR_LOG_NAME "notlstnr.txt"
#define NOTLSTNR_LOG_PATH ""
#define NOTLSTNR_LOG_TITLE "Funambol Windows Mobile Notification-Listener Log"
#define NOTLSTNR_MAX_SIZE 100000 // 100k
extern HWND cp_hWnd;
// Service state
static DWORD g_dwServiceState = SERVICE_STATE_UNINITIALIZED;
// Global critical section
static CRITICAL_SECTION g_cs;
//static
DWORD addressChangeHandler(void);
static DWORD acceptConnection(SOCKET sock);
int getPushTypeFromRegistry();
HANDLE moduleHandle = 0;
///////////////////////////////////////////////////////////////////
// Notification Listener: Dll entry
///////////////////////////////////////////////////////////////////
/**
* Dll entry point.
*/
extern "C" BOOL WINAPI DllMain(HANDLE hInstDll, DWORD fdwReason,
LPVOID lpvReserved) {
LogLevel l;
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
g_dwServiceState = SERVICE_STATE_UNINITIALIZED;
InitializeCriticalSection (&g_cs);
// This DLL does not require thread attatch/deatch
DisableThreadLibraryCalls((HMODULE)hInstDll);
// Init LOG:
//Log(1, NOTLSTNR_LOG_PATH, NOTLSTNR_LOG_NAME);
LOG.setLogPath(NOTLSTNR_LOG_PATH);
LOG.setLogName(NOTLSTNR_LOG_NAME);
LOG.reset(NOTLSTNR_LOG_TITLE);
l = getLOGLevel();
LOG.setLevel(l);
LOG.info("Process attach.");
moduleHandle = hInstDll;
break;
case DLL_PROCESS_DETACH:
DeleteCriticalSection (&g_cs);
LOG.info("Process detach.");
moduleHandle = 0;
break;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////
// Notification Listener: service callbaks
///////////////////////////////////////////////////////////////////
/**
* Service callback: not implemented.
*/
APIEXPORT BOOL S4N_Open(
DWORD dwData,
DWORD dwAccess,
DWORD dwShareMode
) {
LOG.debug("Open - dwData: %lx, dwAccess: %lx, dwShareMode: %lx",
dwData, dwAccess, dwShareMode);
return TRUE;
}
/**
* Service callback: not implemented.
*/
APIEXPORT BOOL S4N_Close( DWORD dwData) {
LOG.debug("Close - dwData: %lx", dwData);
return TRUE;
}
/**
* Service callback: close the socket and exit.
*/
APIEXPORT BOOL S4N_Deinit( DWORD dwData) {
LOG.debug("Deinit - dwData: %lx", dwData);
//MessageBox (NULL, TEXT("DeInit"), TEXT("Test"), MB_SETFOREGROUND | MB_OK);
// Stop child threads of STP.
stopWorker();
// Stop CTP process: try to send the BYE message and
// then close the socket connection.
LOG.info("Stopping push service");
CTPManager* ctpManager = CTPManager::getInstance();
ctpManager->stopCTP();
stopCheckInternetConnectionWorker(0);
// Stop CP process (will send a WM_CLOSE msg).
stopClientPush();
// Must release the localization DLL if we used it
if (localizationUtils::isInstantiated()) {
localizationUtils* language = getLocalizationUtils();
if (language) {
delete language;
}
}
// Remove unattended mode
PowerPolicyNotify(PPN_UNATTENDEDMODE, FALSE);
return TRUE;
}
/**
* Service callback: init the service and return the listen port.
*/
APIEXPORT DWORD S4N_Init( DWORD dwData) {
EnterCriticalSection (&g_cs);
LogLevel l = getLOGLevel();
LOG.setLevel(l);
LOG.debug("S4N_Init");
if (g_dwServiceState != SERVICE_STATE_UNINITIALIZED) {
// Someone is trying to load multiple times
LOG.error("S4ND: ERROR: service already initialized on S4N_Init() call");
LeaveCriticalSection (&g_cs);
return 0;
}
g_dwServiceState = SERVICE_STATE_STARTING_UP;
LOG.info("S4ND: S4N_Init success - service is in starting up state");
// Try to connect to Internet (in a thread).
starCheckInternetConnectionWorker();
// Starts the Client-push, in a separate process.
startClientPush();
LeaveCriticalSection (&g_cs);
return getListenerPort();
}
/**
* Service callback: main method containing the service.exe events.
* On IOCTL_SERVICE_REFRESH and IOCTL_SERVICE_NOTIFY_ADDR_CHANGE events, it is invoked
* a new ip address change notification to the server.
* On IOCTL_SERVICE_CONNECTION event it is opened a socket connection listening
* for the server messages
*/
APIEXPORT BOOL S4N_IOControl(
DWORD dwData,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut
)
{
DWORD dwError = ERROR_INVALID_PARAMETER;
//LOG.debug("IOControl - dwCode: %lx", dwCode);
EnterCriticalSection (&g_cs);
switch(dwCode){
// Control code sent to start a service. (services start FIN0:)
case IOCTL_SERVICE_START:
if (g_dwServiceState != SERVICE_STATE_OFF) {
LOG.error("S4ND: ERROR: IOCTL_SERVICE_START fails because service is not off. State=<%d>", g_dwServiceState);
dwError = ERROR_SERVICE_ALREADY_RUNNING;
}
else {
// Notification listener must work in unattended mode
PowerPolicyNotify(PPN_UNATTENDEDMODE, TRUE);
LOG.debug("S4ND: State changed to ON");
g_dwServiceState = SERVICE_STATE_ON;
dwError = ERROR_SUCCESS;
}
break;
// Control code sent to refresh a service. (services refresh FIN0:)
case IOCTL_SERVICE_REFRESH:
if (g_dwServiceState != SERVICE_STATE_ON) {
LOG.error("S4ND:ERROR:IOCTL_SERVICE_REFRESH fails because service is not on. State=<%d>", g_dwServiceState);
dwError = ERROR_SERVICE_NOT_ACTIVE;
}
else {
LOG.debug("S4ND: Stop on a refresh");
g_dwServiceState = SERVICE_STATE_SHUTTING_DOWN;
stopWorker();
//Sleep(1000); no: we don't want to spend time here...
// Shut the service down, re-read configuration
// TODO: close connections? Abort sync?
// (if we have any) and then restart.
LOG.debug("S4ND: Restarting on refresh");
g_dwServiceState = SERVICE_STATE_ON;
dwError = ERROR_SUCCESS;
addressChangeHandler();
}
break;
// Control code sent to stop a service. (services stop S4N0:)
case IOCTL_SERVICE_STOP:
// No longer accept new network connections.
// Close existing connections
if (g_dwServiceState != SERVICE_STATE_ON) {
LOG.error("S4ND:ERROR:IOCTL_SERVICE_STOP fails. Service state is not on. Current State=<%d>", g_dwServiceState);
dwError = ERROR_SERVICE_NOT_ACTIVE;
}
else {
LOG.debug("S4ND: Service stopping");
stopWorker();
g_dwServiceState = SERVICE_STATE_OFF;
dwError = ERROR_SUCCESS;
}
break;
// An application (possibly services.exe itself) is
// querying for the service's running state.
case IOCTL_SERVICE_STATUS:
// No need for critical section since this is an atomic read.
__try {
if (pBufOut && dwLenOut == sizeof(DWORD)) {
*(DWORD *)pBufOut = g_dwServiceState;
if (pdwActualOut)
*pdwActualOut = sizeof(DWORD);
dwError = ERROR_SUCCESS;
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
LOG.error("S4ND: ERROR Invalid pointer on IOCTL_SERVICE_STATUS");
dwError = ERROR_INVALID_PARAMETER;
}
break;
// Services.exe has completed super-service init for this service.
// Incoming super-service connections can come in at anytime now.
case IOCTL_SERVICE_STARTED:
if (g_dwServiceState != SERVICE_STATE_STARTING_UP) {
LOG.error("S4ND:ERROR:IOCTL_SERVICE_STARTED failed because state != starting up. State=<%d>", g_dwServiceState);
dwError = ERROR_SERVICE_ALREADY_RUNNING;
}
else {
LOG.debug("S4ND: IOCTL_SERVICE_STARTED changed state to SERVICE_STATE_ON");
g_dwServiceState = SERVICE_STATE_ON;
dwError = ERROR_SUCCESS;
}
addressChangeHandler();
break;
// IP address changed: notify the server
case IOCTL_SERVICE_NOTIFY_ADDR_CHANGE:
dwError = addressChangeHandler();
break;
// A new connection request
case IOCTL_SERVICE_CONNECTION:
LOG.debug("S4ND: IOCTL_SERVICE_CONNECTION");
if (dwLenIn != sizeof(SOCKET)) {
dwError = ERROR_INVALID_PARAMETER;
}
else {
SOCKET sock;
__try {
sock = * ((SOCKET*)pBufIn);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
break;
}
// Call new connection handler
dwError = acceptConnection(sock);
}
break;
default:
//LOG.debug("IOControl - dwCode: %lx", dwCode);
return TRUE;
}
if (dwError != ERROR_SUCCESS)
SetLastError(dwError);
LeaveCriticalSection(&g_cs);
return (dwError==ERROR_SUCCESS);
}
/**
* Service callback: not implemented.
*/
APIEXPORT DWORD S4N_Read(
DWORD dwData,
LPVOID pBuf,
DWORD dwLen
) {
LOG.debug("Read - dwData: %lx", dwData);
return 0;
}
/**
* Service callback: not implemented.
*/
APIEXPORT DWORD S4N_Write(
DWORD dwData,
LPVOID pInBuf,
DWORD dwInLen
) {
LOG.debug("Write - dwData: %lx", dwData);
return 0;
}
/**
* Service callback: not implemented.
*/
APIEXPORT DWORD S4N_Seek(
DWORD dwData,
long pos,
DWORD type
) {
LOG.debug("Seek - dwData: %lx", dwData);
return 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?