diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/vmpi/vmpi_service/service_helpers.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/vmpi/vmpi_service/service_helpers.cpp')
| -rw-r--r-- | utils/vmpi/vmpi_service/service_helpers.cpp | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/utils/vmpi/vmpi_service/service_helpers.cpp b/utils/vmpi/vmpi_service/service_helpers.cpp new file mode 100644 index 0000000..a20c5df --- /dev/null +++ b/utils/vmpi/vmpi_service/service_helpers.cpp @@ -0,0 +1,181 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "stdafx.h" +#include "service_helpers.h" + + +static CRITICAL_SECTION g_CtrlHandlerMutex; + +static void (*g_pInternalServiceFn)( void *pParam ) = NULL; +static void *g_pInternalServiceParam = NULL; + +static volatile bool g_bShouldExit = false; + + +SERVICE_STATUS MyServiceStatus; +SERVICE_STATUS_HANDLE MyServiceStatusHandle = NULL; + + +void WINAPI MyServiceCtrlHandler( DWORD Opcode ) +{ + DWORD status; + + switch(Opcode) + { + case SERVICE_CONTROL_STOP: + // Do whatever it takes to stop here. + ServiceHelpers_ExitEarly(); + + MyServiceStatus.dwWin32ExitCode = 0; + MyServiceStatus.dwCurrentState = SERVICE_STOPPED; + + if ( !SetServiceStatus( MyServiceStatusHandle, &MyServiceStatus) ) + { + status = GetLastError(); + Msg( "[MY_SERVICE] SetServiceStatus error %ld\n", status ); + } + + Msg( "[MY_SERVICE] Leaving MyService \n" ); + return; + + case SERVICE_CONTROL_INTERROGATE: + // Fall through to send current status. + break; + + default: + Msg("[MY_SERVICE] Unrecognized opcode %ld\n", Opcode ); + } + + // Send current status. + if ( !SetServiceStatus( MyServiceStatusHandle, &MyServiceStatus ) ) + { + status = GetLastError(); + Msg( "[MY_SERVICE] SetServiceStatus error %ld\n", status ); + } +} + + +void WINAPI MyServiceStart( DWORD argc, LPTSTR *argv ) +{ + DWORD status; + + MyServiceStatus.dwServiceType = SERVICE_WIN32; + MyServiceStatus.dwCurrentState = SERVICE_START_PENDING; + MyServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + MyServiceStatus.dwWin32ExitCode = 0; + MyServiceStatus.dwServiceSpecificExitCode = 0; + MyServiceStatus.dwCheckPoint = 0; + MyServiceStatus.dwWaitHint = 0; + + MyServiceStatusHandle = RegisterServiceCtrlHandler( "MyService", MyServiceCtrlHandler ); + if ( MyServiceStatusHandle == (SERVICE_STATUS_HANDLE)0 ) + { + Msg("[MY_SERVICE] RegisterServiceCtrlHandler failed %d\n", GetLastError() ); + return; + } + + // Initialization complete - report running status. + MyServiceStatus.dwCurrentState = SERVICE_RUNNING; + + if ( !SetServiceStatus( MyServiceStatusHandle, &MyServiceStatus ) ) + { + status = GetLastError(); + Msg( "[MY_SERVICE] SetServiceStatus error %ld\n", status ); + } + + + // Run the app's main in-thread loop. + g_pInternalServiceFn( g_pInternalServiceParam ); + + + // Tell the SCM that we're stopped. + MyServiceStatus.dwCurrentState = SERVICE_STOPPED; + MyServiceStatus.dwWin32ExitCode = NO_ERROR; + MyServiceStatus.dwServiceSpecificExitCode = 0; + SetServiceStatus( MyServiceStatusHandle, &MyServiceStatus ); + + + // This is where the service does its work. + Msg( "[MY_SERVICE] Returning the Main Thread \n" ); +} + + +void ServiceHelpers_Init() +{ + InitializeCriticalSection( &g_CtrlHandlerMutex ); +} + + +bool ServiceHelpers_StartService( const char *pServiceName, void (*pFn)( void *pParam ), void *pParam ) +{ + // Ok, just run the service. + const SERVICE_TABLE_ENTRY DispatchTable[2] = + { + { (char*)pServiceName, MyServiceStart }, + { NULL, NULL } + }; + + g_pInternalServiceFn = pFn; + g_pInternalServiceParam = pParam; + + if ( StartServiceCtrlDispatcher( DispatchTable ) ) + { + return true; + } + else + { + Msg( "StartServiceCtrlDispatcher error = '%s'\n", GetLastErrorString() ); + return false; + } +} + + +void ServiceHelpers_ExitEarly() +{ + EnterCriticalSection( &g_CtrlHandlerMutex ); + g_bShouldExit = true; + LeaveCriticalSection( &g_CtrlHandlerMutex ); +} + + +bool ServiceHelpers_ShouldExit() +{ + EnterCriticalSection( &g_CtrlHandlerMutex ); + bool bRet = g_bShouldExit; + LeaveCriticalSection( &g_CtrlHandlerMutex ); + + return bRet; +} + + +char* GetLastErrorString() +{ + static char err[2048]; + + LPVOID lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL + ); + + strncpy( err, (char*)lpMsgBuf, sizeof( err ) ); + LocalFree( lpMsgBuf ); + + err[ sizeof( err ) - 1 ] = 0; + + return err; +} + + |