Files
2019-02-16 00:16:52 +01:00

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;
}