--- service.c.orig Mon Jan 30 10:03:35 2006 +++ service.c Mon Jan 30 10:16:33 2006 @@ -16,6 +16,7 @@ service_main(DWORD dwArgc, LPTSTR *lpszArgv); CmdInstallService(); CmdRemoveService(); + CmdStartService(); CmdDebugService(int argc, char **argv); ControlHandler ( DWORD dwCtrlType ); GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize ); @@ -40,8 +41,9 @@ // internal function prototypes VOID WINAPI service_ctrl(DWORD dwCtrlCode); VOID WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv); -VOID CmdInstallService(); -VOID CmdRemoveService(); +int CmdInstallService(); +int CmdRemoveService(); +int CmdStartService(); VOID CmdDebugService(int argc, char **argv); BOOL WINAPI ControlHandler ( DWORD dwCtrlType ); LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize ); @@ -64,7 +66,7 @@ // main service thread. When the this call returns, // the service has stopped, so exit. // -void __cdecl main(int argc, char **argv) +int __cdecl main(int argc, char **argv) { SERVICE_TABLE_ENTRY dispatchTable[] = { @@ -77,11 +79,15 @@ { if ( _stricmp( "install", argv[1]+1 ) == 0 ) { - CmdInstallService(); + return CmdInstallService(); } else if ( _stricmp( "remove", argv[1]+1 ) == 0 ) { - CmdRemoveService(); + return CmdRemoveService(); + } + else if ( _stricmp( "start", argv[1]+1 ) == 0) + { + return CmdStartService(); } else if ( _stricmp( "debug", argv[1]+1 ) == 0 ) { @@ -92,7 +98,7 @@ { goto dispatch; } - exit(0); + return 0; } // if it doesn't match any of the above parameters @@ -101,13 +107,16 @@ dispatch: // this is just to be friendly printf( "%s -install to install the service\n", SZAPPNAME ); + printf( "%s -start to start the service\n", SZAPPNAME ); printf( "%s -remove to remove the service\n", SZAPPNAME ); printf( "%s -debug to run as a console app for debugging\n", SZAPPNAME ); printf( "\nStartServiceCtrlDispatcher being called.\n" ); printf( "This may take several seconds. Please wait.\n" ); if (!StartServiceCtrlDispatcher(dispatchTable)) - AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed.")); + AddToMessageLog(MSG_FLAGS_ERROR, TEXT("StartServiceCtrlDispatcher failed.")); + + return 0; } @@ -267,7 +276,7 @@ // if (!(fResult = SetServiceStatus( sshStatusHandle, &ssStatus))) { - AddToMessageLog(TEXT("SetServiceStatus")); + AddToMessageLog(MSG_FLAGS_ERROR, TEXT("SetServiceStatus")); } } return fResult; @@ -288,28 +297,33 @@ // // COMMENTS: // -VOID AddToMessageLog(LPTSTR lpszMsg) +void AddToMessageLog(DWORD flags, LPTSTR lpszMsg) { TCHAR szMsg [(sizeof(SZSERVICENAME) / sizeof(TCHAR)) + 100 ]; HANDLE hEventSource; - LPTSTR lpszStrings[2]; + LPCSTR lpszStrings[2]; if ( !bDebug ) { + if (flags & MSG_FLAGS_SYS_CODE) dwErr = GetLastError(); + else + dwErr = 0; // Use event logging to log the error. // hEventSource = RegisterEventSource(NULL, TEXT(SZSERVICENAME)); - _stprintf(szMsg, TEXT("%s error: %d"), TEXT(SZSERVICENAME), dwErr); + _stprintf(szMsg, TEXT("%s error: %d"), TEXT(SZSERVICENAME), (int)dwErr); lpszStrings[0] = szMsg; lpszStrings[1] = lpszMsg; if (hEventSource != NULL) { ReportEvent(hEventSource, // handle of event source - EVENTLOG_ERROR_TYPE, // event type + // event type + (flags & MSG_FLAGS_ERROR) + ? EVENTLOG_ERROR_TYPE : EVENTLOG_INFORMATION_TYPE, 0, // event category 0, // event ID NULL, // current user's SID @@ -323,8 +337,10 @@ } } - - +void ResetError (void) +{ + dwErr = 0; +} /////////////////////////////////////////////////////////////////// // @@ -341,21 +357,23 @@ // none // // RETURN VALUE: -// none +// 0 if success // // COMMENTS: // -void CmdInstallService() +int CmdInstallService() { SC_HANDLE schService; SC_HANDLE schSCManager; TCHAR szPath[512]; + int ret = 0; + if ( GetModuleFileName( NULL, szPath, 512 ) == 0 ) { _tprintf(TEXT("Unable to install %s - %s\n"), TEXT(SZSERVICEDISPLAYNAME), GetLastErrorText(szErr, 256)); - return; + return 1; } schSCManager = OpenSCManager( @@ -371,7 +389,7 @@ TEXT(SZSERVICEDISPLAYNAME), // name to display SERVICE_QUERY_STATUS, // desired access SERVICE_WIN32_OWN_PROCESS, // service type - SERVICE_DEMAND_START, // start type + SERVICE_DEMAND_START, // start type -- alternative: SERVICE_AUTO_START SERVICE_ERROR_NORMAL, // error control type szPath, // service's binary NULL, // no load ordering group @@ -388,16 +406,79 @@ else { _tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText(szErr, 256)); + ret = 1; } CloseServiceHandle(schSCManager); } else + { _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256)); + ret = 1; + } + return ret; } +// +// FUNCTION: CmdStartService() +// +// PURPOSE: Start the service +// +// PARAMETERS: +// none +// +// RETURN VALUE: +// 0 if success +// +// COMMENTS: + +int CmdStartService() +{ + int ret = 0; + + SC_HANDLE schSCManager; + SC_HANDLE schService; + // Open a handle to the SC Manager database. + schSCManager = OpenSCManager( + NULL, // local machine + NULL, // ServicesActive database + SC_MANAGER_ALL_ACCESS); // full access rights + + if (NULL == schSCManager) { + _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256)); + ret = 1; + } + + schService = OpenService( + schSCManager, // SCM database + SZSERVICENAME, // service name + SERVICE_ALL_ACCESS); + + if (schService == NULL) { + _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256)); + ret = 1; + } + + if (!StartService( + schService, // handle to service + 0, // number of arguments + NULL) ) // no arguments + { + _tprintf(TEXT("StartService failed - %s\n"), GetLastErrorText(szErr,256)); + ret = 1; + } + else + { + _tprintf(TEXT("Service Started\n")); + ret = 0; + } + CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + return ret; +} + // // FUNCTION: CmdRemoveService() // @@ -407,15 +488,17 @@ // none // // RETURN VALUE: -// none +// 0 if success // // COMMENTS: // -void CmdRemoveService() +int CmdRemoveService() { SC_HANDLE schService; SC_HANDLE schSCManager; + int ret = 0; + schSCManager = OpenSCManager( NULL, // machine (NULL == local) NULL, // database (NULL == default) @@ -447,7 +530,10 @@ if ( ssStatus.dwCurrentState == SERVICE_STOPPED ) _tprintf(TEXT("\n%s stopped.\n"), TEXT(SZSERVICEDISPLAYNAME) ); else + { _tprintf(TEXT("\n%s failed to stop.\n"), TEXT(SZSERVICEDISPLAYNAME) ); + ret = 1; + } } @@ -455,18 +541,28 @@ if ( DeleteService(schService) ) _tprintf(TEXT("%s removed.\n"), TEXT(SZSERVICEDISPLAYNAME) ); else + { _tprintf(TEXT("DeleteService failed - %s\n"), GetLastErrorText(szErr,256)); + ret = 1; + } CloseServiceHandle(schService); } else + { _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256)); + ret = 1; + } CloseServiceHandle(schSCManager); } else + { _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256)); + ret = 1; + } + return ret; } @@ -587,7 +683,7 @@ else { lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0'); //remove cr and newline character - _stprintf( lpszBuf, TEXT("%s (0x%x)"), lpszTemp, GetLastError() ); + _stprintf( lpszBuf, TEXT("%s (0x%x)"), lpszTemp, (int)GetLastError() ); } if ( lpszTemp ) --- service.h.orig Mon Jan 30 10:03:35 2006 +++ service.h Mon Jan 30 10:03:35 2006 @@ -62,13 +62,13 @@ //// todo: change to desired strings //// // name of the executable -#define SZAPPNAME "Simple" +#define SZAPPNAME "openvpnserv" // internal name of the service -#define SZSERVICENAME "SimpleService" +#define SZSERVICENAME "OpenVPNService" // displayed name of the service -#define SZSERVICEDISPLAYNAME "Simple Service" +#define SZSERVICEDISPLAYNAME "OpenVPN Service" // list of service dependencies - "dep1\0dep2\0\0" -#define SZDEPENDENCIES "" +#define SZDEPENDENCIES "TAP0901\0Dhcp\0\0" ////////////////////////////////////////////////////////////////////////////// @@ -126,7 +126,10 @@ // RETURN VALUE: // none // - void AddToMessageLog(LPTSTR lpszMsg); +# define MSG_FLAGS_ERROR (1<<0) +# define MSG_FLAGS_SYS_CODE (1<<1) + void AddToMessageLog(DWORD flags, LPTSTR lpszMsg); + void ResetError (void); //////////////////////////////////////////////////////////////////////////////