summaryrefslogtreecommitdiff
path: root/utils/vmpi/vmpi_service/service_helpers.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/vmpi/vmpi_service/service_helpers.cpp
downloadarchived-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.cpp181
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;
+}
+
+