📄 notlstnr.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
*/
/* 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 "logutils.h"
#include "s4jproxy.h"
#include "worker.h"
#include "notify/checknet.h"
#include "notify/s4n_service.h"
#include "notify/addresschange.h"
#include "pim/SettingFunctions.h"
#include "base/startcmd.h"
#include "base/util/utils.h"
#include "processUtils.h"
#include "CTPConfig.h"
#include "CTPManager.h"
#include "CTPMessage.h"
#define LOGLEVEL 1
// 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) {
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);
DebugInit(LOGLEVEL, true);
DebugPrint(L"Process attach.");
moduleHandle = hInstDll;
break;
case DLL_PROCESS_DETACH:
DeleteCriticalSection (&g_cs);
DebugPrint(L"Process detach.");
DebugEnd();
moduleHandle = 0;
break;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////
// Notification Listener: service callbaks
///////////////////////////////////////////////////////////////////
/**
* Service callback: not implemented.
*/
APIEXPORT BOOL S4N_Open(
DWORD dwData,
DWORD dwAccess,
DWORD dwShareMode
) {
DebugPrint(TEXT("Open - dwData: %lx, dwAccess: %lx, dwShareMode: %lx"),
dwData, dwAccess, dwShareMode);
return TRUE;
}
/**
* Service callback: not implemented.
*/
APIEXPORT BOOL S4N_Close( DWORD dwData) {
DebugPrint(TEXT("Close - dwData: %lx\n"), dwData);
return TRUE;
}
/**
* Service callback: close the socket and exit.
*/
APIEXPORT BOOL S4N_Deinit( DWORD dwData) {
DebugPrint(TEXT("Deinit - dwData: %lx\n"), 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.
CTPManager* ctpManager = CTPManager::getInstance();
ctpManager->stopCTP();
//stopCheckForNews();
DebugEnd();
// 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);
if (g_dwServiceState != SERVICE_STATE_UNINITIALIZED) {
// Someone is trying to load multiple times
DebugPrint(L"S4ND: ERROR: service already initialized on S4N_Init() call\r\n");
LeaveCriticalSection (&g_cs);
return 0;
}
Log(0, "", "notlstnr.txt");
LOG.setLevel(LOG_LEVEL_DEBUG);
g_dwServiceState = SERVICE_STATE_STARTING_UP;
DebugInit(LOGLEVEL);
DebugPrint(L"S4ND: S4N_Init success - service is in starting up state\r\n");
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;
// DebugPrint(TEXT("IOControl - dwCode: %lx\n"), 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) {
DebugPrint(L"S4ND: ERROR: IOCTL_SERVICE_START"
L" fails because service is not off. "
L"State=<%d>\r\n",g_dwServiceState);
dwError = ERROR_SERVICE_ALREADY_RUNNING;
}
else {
// Notification listener must work in unattended mode
PowerPolicyNotify(PPN_UNATTENDEDMODE, TRUE);
DebugPrint(L"S4ND: State changed to ON\r\n");
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) {
DebugPrint(L"S4ND:ERROR:IOCTL_SERVICE_REFRESH"
L" fails because service is not on. "
L"State=<%d>\r\n",g_dwServiceState);
dwError = ERROR_SERVICE_NOT_ACTIVE;
}
else {
DebugPrint(L"S4ND: Stop on a refresh\r\n");
g_dwServiceState = SERVICE_STATE_SHUTTING_DOWN;
stopWorker();
DebugEnd();
// Wait for tasks to terminate
Sleep(1000);
// Shut the service down, re-read configuration
// TODO: close connections? Abort sync?
// (if we have any) and then restart.
DebugPrint(L"S4ND: Restarting on refresh\r\n");
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) {
DebugPrint(L"S4ND:ERROR:IOCTL_SERVICE_STOP "
L"fails. Service state is not on. "
L"Current State=<%d>\r\n",
g_dwServiceState);
dwError = ERROR_SERVICE_NOT_ACTIVE;
}
else {
DebugPrint(L"S4ND: Service stopping\r\n");
stopWorker();
DebugEnd();
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) {
DebugPrint(L"S4ND: ERROR Invalid pointer "
L"on IOCTL_SERVICE_STATUS\r\n");
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) {
DebugPrint(L"S4ND:ERROR:IOCTL_SERVICE_STARTED"
L" failed because state != starting up. "
L"State=<%d>\r\n",g_dwServiceState);
dwError = ERROR_SERVICE_ALREADY_RUNNING;
}
else {
DebugPrint(L"S4ND: IOCTL_SERVICE_STARTED "
L" changed state to SERVICE_STATE_ON\r\n");
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:
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:
//DebugPrint(TEXT("IOControl - dwCode: %lx\n"), 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
) {
DebugPrint(TEXT("Read - dwData: %lx\n"), dwData);
return 0;
}
/**
* Service callback: not implemented.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -