www.pudn.com > PIPMasq.zip > ntservices.cpp
#include "stdafx.h" #include#include #include #include #include "PIPMasq.h" #include char *SERVICE_NAME = "PIPMasqService"; HANDLE terminateEvent = NULL; SERVICE_STATUS_HANDLE serviceStatusHandle; BOOL pauseService = FALSE; BOOL runningService = FALSE; PROCESS_INFORMATION pi; HANDLE threadHandle = 0; void ErrorHandler(char *s, DWORD err) { cout << s << endl; cout << "Error number: " << err << endl; ExitProcess(err); } BOOL InitService() { DWORD id; threadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) ServiceThread, 0, 0, &id); if (threadHandle==0) return FALSE; else { runningService = TRUE; return TRUE; } } VOID ResumeService() { pauseService=FALSE; ResumeThread(threadHandle); } VOID PauseService() { pauseService = TRUE; SuspendThread(threadHandle); } VOID StopService() { WSACleanup(); runningService=FALSE; TerminateProcess(pi.hProcess, 0); SetEvent(terminateEvent); } BOOL SendStatusToSCM (DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint) { BOOL success; SERVICE_STATUS serviceStatus; serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; serviceStatus.dwCurrentState = dwCurrentState; if (dwCurrentState == SERVICE_START_PENDING) serviceStatus.dwControlsAccepted = 0; else serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN; if (dwServiceSpecificExitCode == 0) serviceStatus.dwWin32ExitCode = dwWin32ExitCode; else serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; serviceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode; serviceStatus.dwCheckPoint = dwCheckPoint; serviceStatus.dwWaitHint = dwWaitHint; success = SetServiceStatus (serviceStatusHandle, &serviceStatus); if (!success) StopService(); return success; } VOID ServiceCtrlHandler (DWORD controlCode) { DWORD currentState = 0; BOOL success; switch(controlCode) { case SERVICE_CONTROL_STOP: currentState = SERVICE_STOP_PENDING; success = SendStatusToSCM( SERVICE_STOP_PENDING, NO_ERROR, 0, 1, 5000); StopService(); return; case SERVICE_CONTROL_PAUSE: if (runningService && !pauseService) { success = SendStatusToSCM( SERVICE_PAUSE_PENDING, NO_ERROR, 0, 1, 1000); PauseService(); currentState = SERVICE_PAUSED; } break; case SERVICE_CONTROL_CONTINUE: if (runningService && pauseService) { success = SendStatusToSCM( SERVICE_CONTINUE_PENDING, NO_ERROR, 0, 1, 1000); ResumeService(); currentState = SERVICE_RUNNING; } break; case SERVICE_CONTROL_INTERROGATE: break; case SERVICE_CONTROL_SHUTDOWN: return; default: break; } SendStatusToSCM(currentState, NO_ERROR, 0, 0, 0); } VOID terminate(DWORD error) { if (terminateEvent) CloseHandle(terminateEvent); if (serviceStatusHandle) SendStatusToSCM(SERVICE_STOPPED, error, 0, 0, 0); if (threadHandle) CloseHandle(threadHandle); } VOID ServiceMain(DWORD argc, LPTSTR *argv) { BOOL success; serviceStatusHandle = RegisterServiceCtrlHandler( SERVICE_NAME, (LPHANDLER_FUNCTION) ServiceCtrlHandler); if (!serviceStatusHandle) { terminate(GetLastError()); return; } success = SendStatusToSCM( SERVICE_START_PENDING, NO_ERROR, 0, 1, 5000); if (!success) { terminate(GetLastError()); return; } terminateEvent = CreateEvent (0, TRUE, FALSE,0); if (!terminateEvent) { terminate(GetLastError()); return; } success = SendStatusToSCM( SERVICE_START_PENDING,NO_ERROR, 0, 2, 1000); if (!success) { terminate(GetLastError()); return; } success = SendStatusToSCM( SERVICE_START_PENDING, NO_ERROR, 0, 3, 5000); if (!success) { terminate(GetLastError()); return; } success = InitService(); if (!success) { terminate(GetLastError()); return; } success = SendStatusToSCM( SERVICE_RUNNING, NO_ERROR, 0, 0, 0); if (!success) { terminate(GetLastError()); return; } WaitForSingleObject (terminateEvent, INFINITE); terminate(0); } VOID main(int argc, char* argv[]) { if (!((argc == 2) && (strcmp("-exec", argv[1]) == 0))) { if (argc == 2) { if (strcmp("-install", argv[1]) == 0) install(); else if (strcmp("-remove", argv[1]) == 0) remove(); exit(0); } else { printf("Usage: \n"); printf("PIPMasqService -install\n"); printf(" This is to install PIPMasqService as a NT Service\n"); printf("PIPMasqService -remove\n"); printf(" This is to remove PIPMasqService\n"); printf("After install it, you can start PIPMasqService from NT Services Panel.\n\n"); exit(0); } } SERVICE_TABLE_ENTRY serviceTable[] = { { SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain}, { NULL, NULL } }; BOOL success; success = StartServiceCtrlDispatcher(serviceTable); if (!success) ErrorHandler("In StartServiceCtrlDispatcher", GetLastError()); }