ARTICLE AD BOX
Your ServiceHandler() is declared incorrectly.
You have declared it as returning a LPHANDLER_FUNCTION pointer, but that is not what it actually returns. It is returning error codes that are being type-casted into LPHANDLER_FUNCTION, which is just plain wrong.
LPHANDLER_FUNCTION is the type used when you need to create a pointer to a Handler function:
typedef VOID (WINAPI *LPHANDLER_FUNCTION)( DWORD dwControl );This is a pointer to a function that returns VOID, takes in a DWORD, and uses the WINAPI (aka __stdcall) calling convention.
For instance, this type is used by the lpHandlerProc parameter of RegisterServiceCtrlHandler(). This is NOT a type you would typically ever use in your own code, and certainly not as the return type of your ServiceHandler().
I suggest you read the documentation more carefully, nowhere does it ever say to do what you are doing:
LPHANDLER_FUNCTION callback function (winsvc.h)
Writing a Control Handler Function
You need to change this:
LPHANDLER_FUNCTION ServiceHandler(DWORD dwCtrl)To this instead:
VOID WINAPI ServiceHandler(DWORD dwCtrl)And then remove the return statements from ServiceHandler(), as a service handler is not supposed to return any value at all (hence the VOID return type). All error codes and status values must be reported only through SetServiceStatus() (which you have wrapped by ReportSvcStatus()).
VOID WINAPI ServiceHandler(DWORD dwCtrl) { switch (dwCtrl) { case SERVICE_CONTROL_STOP: SetEvent(gServiceStopEvent); break; case SERVICE_CONTROL_INTERROGATE: ReportSvcStatus(...); // report current status as needed... break; default: break; } }On a side note:
The Sleep() inside of your ServiceHandler() is unnecessary and should be removed.
And, the while loop inside of your ServiceWork() is running tight iterations that are constantly polling gServiceStopEvent and doing no other work at all. So, it would be more efficient to simply get rid of the loop completely and instead just call WaitForSingleObject() with an INFINITE timeout:
void ServiceWork(SERVICE_STATUS &ServiceStatus, SERVICE_STATUS_HANDLE &StatusHandle) { // [Service does stuff here] ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0, ServiceStatus, StatusHandle); logfile << "Service is now running." << std::endl; // this point is reached normally WaitForSingleObject(gServiceStopEvent, INFINITE); ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, ServiceStatus, StatusHandle); HANDLE winkeyhproc = FindProcessHandleByName("winkey.exe"); // The service's executable that is supposed to stop with the service if (winkeyhproc) { TerminateProcess(winkeyhproc, 0); CloseHandle(winkeyhproc); logfile << "winkey.exe terminated successfully." << std::endl; } else { logfile << "winkey.exe process not found." << std::endl; } ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0, ServiceStatus, StatusHandle); logfile << "service stopped." << std::endl; }