161 lines
3.9 KiB
C
161 lines
3.9 KiB
C
/*
|
|
Copyright (C) Andrzej Hajda 2006
|
|
Contact: andrzej.hajda@wp.pl
|
|
License: GNU General Public License version 2
|
|
*/
|
|
|
|
#include <windows.h>
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
|
|
#include "shared.h"
|
|
|
|
#if 0
|
|
static void SvcDebugOut(const char *a, int b)
|
|
{
|
|
FILE *f = fopen("C:\\" SERVICE_NAME ".log", "at");
|
|
fprintf(f, a, b);
|
|
fclose(f);
|
|
}
|
|
#else
|
|
#define SvcDebugOut(a,b) 0
|
|
#endif
|
|
|
|
DWORD WINAPI server_loop(LPVOID lpParameter);
|
|
|
|
SERVICE_STATUS winexesvcStatus;
|
|
SERVICE_STATUS_HANDLE winexesvcStatusHandle;
|
|
|
|
VOID WINAPI winexesvcCtrlHandler(DWORD Opcode)
|
|
{
|
|
DWORD status;
|
|
|
|
switch (Opcode) {
|
|
case SERVICE_CONTROL_PAUSE:
|
|
SvcDebugOut(SERVICE_NAME ": winexesvcCtrlHandler: pause\n", 0);
|
|
winexesvcStatus.dwCurrentState = SERVICE_PAUSED;
|
|
break;
|
|
|
|
case SERVICE_CONTROL_CONTINUE:
|
|
SvcDebugOut(SERVICE_NAME ": winexesvcCtrlHandler: continue\n", 0);
|
|
winexesvcStatus.dwCurrentState = SERVICE_RUNNING;
|
|
break;
|
|
|
|
case SERVICE_CONTROL_STOP:
|
|
SvcDebugOut(SERVICE_NAME ": winexesvcCtrlHandler: stop\n", 0);
|
|
winexesvcStatus.dwWin32ExitCode = 0;
|
|
winexesvcStatus.dwCurrentState = SERVICE_STOPPED;
|
|
winexesvcStatus.dwCheckPoint = 0;
|
|
winexesvcStatus.dwWaitHint = 0;
|
|
|
|
if (!SetServiceStatus
|
|
(winexesvcStatusHandle, &winexesvcStatus)) {
|
|
status = GetLastError();
|
|
SvcDebugOut(SERVICE_NAME
|
|
": SetServiceStatus error %ld\n",
|
|
status);
|
|
}
|
|
|
|
SvcDebugOut(SERVICE_NAME ": Leaving winexesvc\n", 0);
|
|
return;
|
|
|
|
case SERVICE_CONTROL_INTERROGATE:
|
|
SvcDebugOut(SERVICE_NAME ": winexesvcCtrlHandler: interrogate\n", 0);
|
|
break;
|
|
|
|
default:
|
|
SvcDebugOut(SERVICE_NAME ": Unrecognized opcode %ld\n",
|
|
Opcode);
|
|
}
|
|
|
|
if (!SetServiceStatus(winexesvcStatusHandle, &winexesvcStatus)) {
|
|
status = GetLastError();
|
|
SvcDebugOut(SERVICE_NAME ": SetServiceStatus error 0x%08X\n",
|
|
status);
|
|
}
|
|
return;
|
|
}
|
|
|
|
DWORD winexesvcInitialization(DWORD argc, LPTSTR * argv,
|
|
DWORD * specificError)
|
|
{
|
|
HANDLE th = CreateThread(NULL, 0, server_loop, NULL, 0, NULL);
|
|
if (th) {
|
|
CloseHandle(th);
|
|
return NO_ERROR;
|
|
}
|
|
return !NO_ERROR;
|
|
}
|
|
|
|
void WINAPI winexesvcStart(DWORD argc, LPTSTR * argv)
|
|
{
|
|
DWORD status;
|
|
DWORD specificError;
|
|
|
|
winexesvcStatus.dwServiceType = SERVICE_WIN32;
|
|
winexesvcStatus.dwCurrentState = SERVICE_START_PENDING;
|
|
winexesvcStatus.dwControlsAccepted =
|
|
SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
|
|
winexesvcStatus.dwWin32ExitCode = 0;
|
|
winexesvcStatus.dwServiceSpecificExitCode = 0;
|
|
winexesvcStatus.dwCheckPoint = 0;
|
|
winexesvcStatus.dwWaitHint = 0;
|
|
|
|
SvcDebugOut(SERVICE_NAME ": RegisterServiceCtrlHandler\n", 0);
|
|
|
|
winexesvcStatusHandle =
|
|
RegisterServiceCtrlHandler(SERVICE_NAME, winexesvcCtrlHandler);
|
|
|
|
if (winexesvcStatusHandle == (SERVICE_STATUS_HANDLE) 0) {
|
|
SvcDebugOut(SERVICE_NAME
|
|
": RegisterServiceCtrlHandler failed %d\n",
|
|
GetLastError());
|
|
return;
|
|
}
|
|
status = winexesvcInitialization(argc, argv, &specificError);
|
|
|
|
if (status != NO_ERROR) {
|
|
winexesvcStatus.dwCurrentState = SERVICE_STOPPED;
|
|
winexesvcStatus.dwCheckPoint = 0;
|
|
winexesvcStatus.dwWaitHint = 0;
|
|
winexesvcStatus.dwWin32ExitCode = status;
|
|
winexesvcStatus.dwServiceSpecificExitCode = specificError;
|
|
|
|
SetServiceStatus(winexesvcStatusHandle, &winexesvcStatus);
|
|
return;
|
|
}
|
|
|
|
winexesvcStatus.dwCurrentState = SERVICE_RUNNING;
|
|
winexesvcStatus.dwCheckPoint = 0;
|
|
winexesvcStatus.dwWaitHint = 0;
|
|
|
|
if (!SetServiceStatus(winexesvcStatusHandle, &winexesvcStatus)) {
|
|
status = GetLastError();
|
|
SvcDebugOut(SERVICE_NAME ": SetServiceStatus error %ld\n",
|
|
status);
|
|
}
|
|
|
|
SvcDebugOut(SERVICE_NAME ": Returning the Main Thread \n", 0);
|
|
|
|
return;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
SERVICE_TABLE_ENTRY DispatchTable[] = {
|
|
{SERVICE_NAME, winexesvcStart},
|
|
{NULL, NULL}
|
|
};
|
|
|
|
SvcDebugOut(SERVICE_NAME ": StartServiceCtrlDispatcher %d\n",
|
|
GetLastError());
|
|
if (!StartServiceCtrlDispatcher(DispatchTable)) {
|
|
SvcDebugOut(SERVICE_NAME
|
|
": StartServiceCtrlDispatcher (%d)\n",
|
|
GetLastError());
|
|
}
|
|
return 0;
|
|
}
|