You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
4.5 KiB
185 lines
4.5 KiB
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#define SERVICE_NAME TEXT("6to4")
|
|
|
|
HANDLE g_hServiceStatusHandle = INVALID_HANDLE_VALUE;
|
|
HANDLE g_hDeviceNotificationHandle = INVALID_HANDLE_VALUE;
|
|
SERVICE_STATUS g_ServiceStatus;
|
|
|
|
VOID
|
|
Set6to4ServiceStatus(
|
|
IN DWORD dwState,
|
|
IN DWORD dwErr)
|
|
{
|
|
BOOL bOk;
|
|
|
|
Trace1(FSM, _T("Setting state to %d"), dwState);
|
|
|
|
g_ServiceStatus.dwCurrentState = dwState;
|
|
g_ServiceStatus.dwCheckPoint = 0;
|
|
g_ServiceStatus.dwWin32ExitCode= dwErr;
|
|
#ifndef STANDALONE
|
|
bOk = SetServiceStatus(g_hServiceStatusHandle, &g_ServiceStatus);
|
|
if (!bOk) {
|
|
Trace0(ERR, _T("SetServiceStatus returned failure"));
|
|
}
|
|
#endif
|
|
|
|
if (dwState == SERVICE_STOPPED) {
|
|
Cleanup6to4();
|
|
|
|
// Uninitialize tracing and error logging.
|
|
UNINITIALIZE_TRACING_LOGGING();
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
OnStartup()
|
|
{
|
|
int i;
|
|
DWORD dwErr;
|
|
WSADATA wsaData;
|
|
|
|
ENTER_API();
|
|
|
|
// Initialize tracing and error logging. Continue irrespective of
|
|
// success or failure. NOTE: TracePrintf and ReportEvent both have
|
|
// built in checks for validity of TRACEID and LOGHANDLE.
|
|
INITIALIZE_TRACING_LOGGING();
|
|
|
|
TraceEnter("OnStartup");
|
|
|
|
dwErr = Start6to4();
|
|
|
|
TraceLeave("OnStartup");
|
|
LEAVE_API();
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
VOID
|
|
OnStop(
|
|
IN DWORD dwErr)
|
|
{
|
|
DWORD i;
|
|
|
|
ENTER_API();
|
|
TraceEnter("OnStop");
|
|
|
|
Set6to4ServiceStatus(SERVICE_STOP_PENDING, dwErr);
|
|
|
|
if (Stop6to4()) {
|
|
Set6to4ServiceStatus(SERVICE_STOPPED, dwErr);
|
|
}
|
|
|
|
if (g_hDeviceNotificationHandle != INVALID_HANDLE_VALUE) {
|
|
UnregisterDeviceNotification(g_hDeviceNotificationHandle);
|
|
}
|
|
|
|
TraceLeave("OnStop");
|
|
|
|
LEAVE_API();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// ServiceMain - main entry point called by svchost or by the
|
|
// standalone main.
|
|
//
|
|
|
|
DWORD WINAPI
|
|
ServiceHandler(
|
|
IN DWORD dwControl,
|
|
IN DWORD dwEventType,
|
|
IN PVOID pvEventData,
|
|
IN PVOID pvContext)
|
|
{
|
|
switch (dwControl) {
|
|
case SERVICE_CONTROL_DEVICEEVENT:
|
|
if (g_ServiceStatus.dwCurrentState == SERVICE_RUNNING) {
|
|
ENTER_API();
|
|
ShipwormDeviceChangeNotification(dwEventType, pvEventData);
|
|
LEAVE_API();
|
|
}
|
|
return NO_ERROR;
|
|
|
|
case SERVICE_CONTROL_STOP:
|
|
OnStop(NO_ERROR);
|
|
return NO_ERROR;
|
|
|
|
case SERVICE_CONTROL_PARAMCHANGE:
|
|
OnConfigChange();
|
|
return NO_ERROR;
|
|
|
|
default:
|
|
Trace2(ANY, L"ServiceHandler %u (%u)", dwControl, dwEventType);
|
|
break;
|
|
}
|
|
|
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
|
|
VOID WINAPI
|
|
ServiceMain(
|
|
IN ULONG argc,
|
|
IN LPWSTR *argv)
|
|
{
|
|
DWORD dwErr = NO_ERROR;
|
|
DEV_BROADCAST_DEVICEINTERFACE PnpFilter;
|
|
|
|
do {
|
|
#ifndef STANDALONE
|
|
g_hServiceStatusHandle = RegisterServiceCtrlHandlerEx(
|
|
SERVICE_NAME, ServiceHandler, NULL);
|
|
|
|
// RegisterServiceCtrlHandler returns NULL on failure
|
|
if (g_hServiceStatusHandle == NULL) {
|
|
dwErr = GetLastError();
|
|
break;
|
|
}
|
|
|
|
// Register for adapter arrival and removal notifications.
|
|
ZeroMemory (&PnpFilter, sizeof(PnpFilter));
|
|
PnpFilter.dbcc_size = sizeof(PnpFilter);
|
|
PnpFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
|
PnpFilter.dbcc_classguid = GUID_NDIS_LAN_CLASS;
|
|
g_hDeviceNotificationHandle = RegisterDeviceNotification (
|
|
(HANDLE) g_hServiceStatusHandle,
|
|
&PnpFilter,
|
|
DEVICE_NOTIFY_SERVICE_HANDLE);
|
|
|
|
if (g_hDeviceNotificationHandle == NULL) {
|
|
dwErr = GetLastError();
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
ZeroMemory(&g_ServiceStatus, sizeof(g_ServiceStatus));
|
|
g_ServiceStatus.dwServiceType =
|
|
SERVICE_WIN32_SHARE_PROCESS | SERVICE_INTERACTIVE_PROCESS;
|
|
g_ServiceStatus.dwControlsAccepted =
|
|
SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PARAMCHANGE;
|
|
Set6to4ServiceStatus(SERVICE_START_PENDING, NO_ERROR);
|
|
|
|
// Do startup processing
|
|
dwErr = OnStartup();
|
|
if (dwErr) {
|
|
break;
|
|
}
|
|
|
|
#ifndef STANDALONE
|
|
Set6to4ServiceStatus(SERVICE_RUNNING, NO_ERROR);
|
|
// Wait until shutdown time
|
|
|
|
return;
|
|
#endif
|
|
|
|
} while (FALSE);
|
|
|
|
#ifndef STANDALONE
|
|
OnStop(dwErr);
|
|
#endif
|
|
|
|
return;
|
|
}
|