Matthew Booth
2013-Aug-29 15:09 UTC
[Libguestfs] [PATCH 1/6] Rationalise whitespace to 4 space indentation with no trailing spaces
RHSrvAny.c was using a mixture of 4 space indentation, and tabs with a width of 4. This commit rationalises the whitespace to use only 4 space indentation, and removes trailing whitespace. --- RHSrvAny/RHSrvAny.c | 537 ++++++++++++++++++++++++++-------------------------- RHSrvAny/RHSrvAny.h | 1 - RHSrvAny/resource.h | 2 +- 3 files changed, 269 insertions(+), 271 deletions(-) diff --git a/RHSrvAny/RHSrvAny.c b/RHSrvAny/RHSrvAny.c index 3d4c3b4..a28f973 100644 --- a/RHSrvAny/RHSrvAny.c +++ b/RHSrvAny/RHSrvAny.c @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4 -*- */ /* RHSrvAny - Turn any Windows program into a Windows service. * Written by Yuval Kashtan. * Copyright (C) 2010 Red Hat Inc. @@ -42,82 +41,82 @@ #define SVCNAME TEXT("RHSrvAny") -SERVICE_STATUS gSvcStatus; +SERVICE_STATUS gSvcStatus; HANDLE ghSvcStopEvent = NULL; -SERVICE_STATUS_HANDLE gSvcStatusHandle; +SERVICE_STATUS_HANDLE gSvcStatusHandle; VOID SvcInstall (void); -VOID WINAPI SvcCtrlHandler (DWORD); -VOID WINAPI SvcMain (DWORD, LPTSTR *); +VOID WINAPI SvcCtrlHandler (DWORD); +VOID WINAPI SvcMain (DWORD, LPTSTR *); VOID SvcReportEvent (LPTSTR); -VOID SvcInit (DWORD, LPTSTR *); +VOID SvcInit (DWORD, LPTSTR *); VOID ReportSvcStatus (DWORD, DWORD, DWORD); int main (int argc, char **a_argv) -{ +{ /* For compatibility with MinGW, see: - http://demosten-eng.blogspot.com/2008/08/mingw-and-unicode-support.html */ + http://demosten-eng.blogspot.com/2008/08/mingw-and-unicode-support.html */ TCHAR **argv; - argv = CommandLineToArgvW (GetCommandLineW (), &argc); - - SERVICE_TABLE_ENTRY DispatchTable[] = { - { - SVCNAME, - (LPSERVICE_MAIN_FUNCTION) SvcMain - }, - { NULL, NULL } - }; - - if( - lstrcmpi( - argv[1], - TEXT("install") - ) == 0 - ) { - SvcInstall(); - return EXIT_SUCCESS; - } - - if (!StartServiceCtrlDispatcher( DispatchTable )) - { - SvcReportEvent(TEXT("StartServiceCtrlDispatcher")); - return EXIT_FAILURE; + argv = CommandLineToArgvW (GetCommandLineW (), &argc); + + SERVICE_TABLE_ENTRY DispatchTable[] = { + { + SVCNAME, + (LPSERVICE_MAIN_FUNCTION) SvcMain + }, + { NULL, NULL } + }; + + if( + lstrcmpi( + argv[1], + TEXT("install") + ) == 0 + ) { + SvcInstall(); + return EXIT_SUCCESS; } - return EXIT_SUCCESS; -} + if (!StartServiceCtrlDispatcher( DispatchTable )) + { + SvcReportEvent(TEXT("StartServiceCtrlDispatcher")); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} -VOID +VOID SvcInstall() { - SC_HANDLE schSCManager; - SC_HANDLE schService; - TCHAR szPath[MAX_PATH]; - - if ( - !GetModuleFileName( - NULL, - szPath, - MAX_PATH - ) - ) { - printf("Cannot install service (%d)\n", (int) GetLastError()); - return; - } - - schSCManager = OpenSCManager( - NULL, - NULL, - SC_MANAGER_ALL_ACCESS - ); - + SC_HANDLE schSCManager; + SC_HANDLE schService; + TCHAR szPath[MAX_PATH]; + + if ( + !GetModuleFileName( + NULL, + szPath, + MAX_PATH + ) + ) { + printf("Cannot install service (%d)\n", (int) GetLastError()); + return; + } + + schSCManager = OpenSCManager( + NULL, + NULL, + SC_MANAGER_ALL_ACCESS + ); + if (NULL == schSCManager) { - printf("OpenSCManager failed (%d)\n", (int) GetLastError()); - return; + printf("OpenSCManager failed (%d)\n", (int) GetLastError()); + return; } - schService = CreateService ( + schService = CreateService ( schSCManager, SVCNAME, SVCNAME, @@ -131,212 +130,212 @@ SvcInstall() { NULL, NULL, NULL - ); - + ); + if (schService == NULL) { printf ( - "CreateService failed (%d)\n", - (int) GetLastError() - ); + "CreateService failed (%d)\n", + (int) GetLastError() + ); CloseServiceHandle (schSCManager); return; } - else { - printf("Service installed successfully\n"); - } + else { + printf("Service installed successfully\n"); + } - CloseServiceHandle (schService); + CloseServiceHandle (schService); CloseServiceHandle (schSCManager); } -VOID -WINAPI +VOID +WINAPI SvcMain ( - DWORD dwArgc, - LPTSTR *lpszArgv + DWORD dwArgc, + LPTSTR *lpszArgv ) { - gSvcStatusHandle = RegisterServiceCtrlHandler ( - SVCNAME, - SvcCtrlHandler - ); - - if (!gSvcStatusHandle) { - SvcReportEvent(TEXT("RegisterServiceCtrlHandler")); - return; - } - - gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - gSvcStatus.dwServiceSpecificExitCode = 0; - - ReportSvcStatus ( - SERVICE_START_PENDING, - NO_ERROR, - 3000 - ); - - SvcInit ( - dwArgc, - lpszArgv - ); + gSvcStatusHandle = RegisterServiceCtrlHandler ( + SVCNAME, + SvcCtrlHandler + ); + + if (!gSvcStatusHandle) { + SvcReportEvent(TEXT("RegisterServiceCtrlHandler")); + return; + } + + gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + gSvcStatus.dwServiceSpecificExitCode = 0; + + ReportSvcStatus ( + SERVICE_START_PENDING, + NO_ERROR, + 3000 + ); + + SvcInit ( + dwArgc, + lpszArgv + ); } BOOL RegistryRead ( - HKEY hHive, - wchar_t *szKeyPath, - wchar_t *szValue, - wchar_t *szData, - DWORD *nSize + HKEY hHive, + wchar_t *szKeyPath, + wchar_t *szValue, + wchar_t *szData, + DWORD *nSize ) { - HKEY hKey; - long lSuccess; - - lSuccess = RegOpenKey ( - hHive, - szKeyPath, - &hKey - ); - - if (lSuccess == ERROR_SUCCESS) { - lSuccess = RegQueryValueEx ( - hKey, - szValue, - NULL, - NULL, - (LPBYTE) szData, - nSize - ); - - if (lSuccess == ERROR_SUCCESS) { - return (TRUE); - } - } - - return (FALSE); + HKEY hKey; + long lSuccess; + + lSuccess = RegOpenKey ( + hHive, + szKeyPath, + &hKey + ); + + if (lSuccess == ERROR_SUCCESS) { + lSuccess = RegQueryValueEx ( + hKey, + szValue, + NULL, + NULL, + (LPBYTE) szData, + nSize + ); + + if (lSuccess == ERROR_SUCCESS) { + return (TRUE); + } + } + + return (FALSE); } -VOID +VOID SvcInit ( - DWORD dwArgc, - LPTSTR *lpszArgv + DWORD dwArgc, + LPTSTR *lpszArgv ) { - DWORD nSize; - BOOL fSuccess; + DWORD nSize; + BOOL fSuccess; STARTUPINFO si; - wchar_t szPWD[1024]; + wchar_t szPWD[1024]; PROCESS_INFORMATION pi; - wchar_t szCmdLine[1024]; - wchar_t szRegistryPath[1024]; + wchar_t szCmdLine[1024]; + wchar_t szRegistryPath[1024]; - // TO_DO: Declare and set any required variables. - // Be sure to periodically call ReportSvcStatus() with + // TO_DO: Declare and set any required variables. + // Be sure to periodically call ReportSvcStatus() with // SERVICE_START_PENDING. If initialization fails, call // ReportSvcStatus with SERVICE_STOPPED. // Create an event. The control handler function, SvcCtrlHandler, // signals this event when it receives the stop control code. - ghSvcStopEvent = CreateEvent ( - NULL, - TRUE, - FALSE, - NULL - ); + ghSvcStopEvent = CreateEvent ( + NULL, + TRUE, + FALSE, + NULL + ); if (ghSvcStopEvent == NULL) { ReportSvcStatus ( - SERVICE_STOPPED, - NO_ERROR, - 0 - ); + SERVICE_STOPPED, + NO_ERROR, + 0 + ); return; } // Report running status when initialization is complete. ReportSvcStatus ( - SERVICE_RUNNING, - NO_ERROR, - 0 - ); + SERVICE_RUNNING, + NO_ERROR, + 0 + ); // TO_DO: Perform work until service stops. ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); - nSize=1024; + nSize=1024; #ifdef HAVE_SWPRINTF_S - swprintf_s ( - szRegistryPath, - nSize, + swprintf_s ( + szRegistryPath, + nSize, #else - snwprintf ( - szRegistryPath, - sizeof szRegistryPath, + snwprintf ( + szRegistryPath, + sizeof szRegistryPath, #endif - L"SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", - SVCNAME - ); - - fSuccess = RegistryRead ( - HKEY_LOCAL_MACHINE, - szRegistryPath, - L"CommandLine", - szCmdLine, - &nSize - ); - - if (fSuccess) { - fSuccess = RegistryRead ( - HKEY_LOCAL_MACHINE, - szRegistryPath, - L"PWD", - szPWD, - &nSize - ); - } - - if (fSuccess) { - fSuccess = CreateProcess ( - NULL, - szCmdLine, - NULL, - NULL, - FALSE, - ( - CREATE_NO_WINDOW - ), - NULL, - szPWD, - &si, - &pi - ); - } - - // treat errors + L"SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", + SVCNAME + ); + + fSuccess = RegistryRead ( + HKEY_LOCAL_MACHINE, + szRegistryPath, + L"CommandLine", + szCmdLine, + &nSize + ); + + if (fSuccess) { + fSuccess = RegistryRead ( + HKEY_LOCAL_MACHINE, + szRegistryPath, + L"PWD", + szPWD, + &nSize + ); + } + + if (fSuccess) { + fSuccess = CreateProcess ( + NULL, + szCmdLine, + NULL, + NULL, + FALSE, + ( + CREATE_NO_WINDOW + ), + NULL, + szPWD, + &si, + &pi + ); + } + + // treat errors while(1) { // Check whether to stop the service. WaitForSingleObject ( - ghSvcStopEvent, - INFINITE - ); + ghSvcStopEvent, + INFINITE + ); ReportSvcStatus ( - SERVICE_STOPPED, - NO_ERROR, - 0 - ); + SERVICE_STOPPED, + NO_ERROR, + 0 + ); return; } } VOID ReportSvcStatus ( - DWORD dwCurrentState, - DWORD dwWin32ExitCode, - DWORD dwWaitHint + DWORD dwCurrentState, + DWORD dwWin32ExitCode, + DWORD dwWaitHint ) { static DWORD dwCheckPoint = 1; @@ -345,99 +344,99 @@ VOID ReportSvcStatus ( gSvcStatus.dwWin32ExitCode = dwWin32ExitCode; gSvcStatus.dwWaitHint = dwWaitHint; - if (dwCurrentState == SERVICE_START_PENDING) { - gSvcStatus.dwControlsAccepted = 0; - } - else { - gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; - } - - if ( - (dwCurrentState == SERVICE_RUNNING) || - (dwCurrentState == SERVICE_STOPPED) - ) { - gSvcStatus.dwCheckPoint = 0; - } else { - gSvcStatus.dwCheckPoint = dwCheckPoint++; - } - - // Report the status of the service to the SCM. - SetServiceStatus ( - gSvcStatusHandle, - &gSvcStatus - ); + if (dwCurrentState == SERVICE_START_PENDING) { + gSvcStatus.dwControlsAccepted = 0; + } + else { + gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + } + + if ( + (dwCurrentState == SERVICE_RUNNING) || + (dwCurrentState == SERVICE_STOPPED) + ) { + gSvcStatus.dwCheckPoint = 0; + } else { + gSvcStatus.dwCheckPoint = dwCheckPoint++; + } + + // Report the status of the service to the SCM. + SetServiceStatus ( + gSvcStatusHandle, + &gSvcStatus + ); } -VOID -WINAPI +VOID +WINAPI SvcCtrlHandler ( - DWORD dwCtrl + DWORD dwCtrl ) { - switch(dwCtrl) { - case SERVICE_CONTROL_STOP: + switch(dwCtrl) { + case SERVICE_CONTROL_STOP: ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); /* Signal the service to stop. */ SetEvent(ghSvcStopEvent); - + return; - - case SERVICE_CONTROL_INTERROGATE: + + case SERVICE_CONTROL_INTERROGATE: /* Fall through to send current status. */ - break; - - default: break; - } + + default: + break; + } ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0); } /* Logs messages to the event log */ -VOID +VOID SvcReportEvent ( - LPTSTR szFunction -) { + LPTSTR szFunction +) { TCHAR Buffer[80]; HANDLE hEventSource; LPCTSTR lpszStrings[2]; hEventSource = RegisterEventSource ( - NULL, - SVCNAME - ); + NULL, + SVCNAME + ); if ( - NULL != hEventSource - ) { + NULL != hEventSource + ) { #ifdef HAVE_STRINGCCHPRINTF - StringCchPrintf + StringCchPrintf #else - snwprintf + snwprintf #endif - ( - Buffer, - 80, - TEXT("%s failed with %d"), - szFunction, - GetLastError() - ); + ( + Buffer, + 80, + TEXT("%s failed with %d"), + szFunction, + GetLastError() + ); lpszStrings[0] = SVCNAME; lpszStrings[1] = Buffer; - ReportEvent ( - hEventSource, - EVENTLOG_ERROR_TYPE, - 0, - SVC_ERROR, - NULL, - 2, - 0, - lpszStrings, - NULL - ); - - DeregisterEventSource (hEventSource); + ReportEvent ( + hEventSource, + EVENTLOG_ERROR_TYPE, + 0, + SVC_ERROR, + NULL, + 2, + 0, + lpszStrings, + NULL + ); + + DeregisterEventSource (hEventSource); } } diff --git a/RHSrvAny/RHSrvAny.h b/RHSrvAny/RHSrvAny.h index 72ada2a..f439056 100644 --- a/RHSrvAny/RHSrvAny.h +++ b/RHSrvAny/RHSrvAny.h @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4 -*- */ /* RHSrvAny - Turn any Windows program into a Windows service. * Written by Yuval Kashtan. * Copyright (C) 2010 Red Hat Inc. diff --git a/RHSrvAny/resource.h b/RHSrvAny/resource.h index ad31821..14bba9b 100644 --- a/RHSrvAny/resource.h +++ b/RHSrvAny/resource.h @@ -4,7 +4,7 @@ // // Next default values for new objects -// +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 -- 1.8.3.1
Matthew Booth
2013-Aug-29 15:09 UTC
[Libguestfs] [PATCH 2/6] Allow service name to be given on the command line
--- RHSrvAny/RHSrvAny.c | 65 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/RHSrvAny/RHSrvAny.c b/RHSrvAny/RHSrvAny.c index a28f973..31caaeb 100644 --- a/RHSrvAny/RHSrvAny.c +++ b/RHSrvAny/RHSrvAny.c @@ -1,6 +1,6 @@ /* RHSrvAny - Turn any Windows program into a Windows service. * Written by Yuval Kashtan. - * Copyright (C) 2010 Red Hat Inc. + * Copyright (C) 2010,2013 Red Hat Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,7 +39,7 @@ #include "RHSrvAny.h" -#define SVCNAME TEXT("RHSrvAny") +static TCHAR *svcname = TEXT("RHSrvAny"); SERVICE_STATUS gSvcStatus; HANDLE ghSvcStopEvent = NULL; @@ -53,6 +53,14 @@ VOID SvcReportEvent (LPTSTR); VOID SvcInit (DWORD, LPTSTR *); VOID ReportSvcStatus (DWORD, DWORD, DWORD); +static int +argument_error (const char *msg) +{ + printf("%s\n", msg); + + return EXIT_FAILURE; +} + int main (int argc, char **a_argv) { @@ -61,24 +69,43 @@ main (int argc, char **a_argv) TCHAR **argv; argv = CommandLineToArgvW (GetCommandLineW (), &argc); + size_t i; + for (i = 1; i < argc; i++) { + TCHAR *arg = argv[i]; + + if (arg[0] == _T('-')) { + if (lstrcmpi(arg + 1, _T("s")) == 0) { + if (i == argc) { + return argument_error("Option -s requires an argument"); + } + + svcname = argv[++i]; + } + + else { + return argument_error("Unknown option"); + } + } + + /* Stop parsing arguments when we hit something which isn't an option */ + else { + break; + } + } + + if (lstrcmpi(argv[i], TEXT("install")) == 0) { + SvcInstall(); + return EXIT_SUCCESS; + } + SERVICE_TABLE_ENTRY DispatchTable[] = { { - SVCNAME, + svcname, (LPSERVICE_MAIN_FUNCTION) SvcMain }, { NULL, NULL } }; - if( - lstrcmpi( - argv[1], - TEXT("install") - ) == 0 - ) { - SvcInstall(); - return EXIT_SUCCESS; - } - if (!StartServiceCtrlDispatcher( DispatchTable )) { SvcReportEvent(TEXT("StartServiceCtrlDispatcher")); @@ -118,8 +145,8 @@ SvcInstall() { schService = CreateService ( schSCManager, - SVCNAME, - SVCNAME, + svcname, + svcname, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, @@ -155,7 +182,7 @@ SvcMain ( LPTSTR *lpszArgv ) { gSvcStatusHandle = RegisterServiceCtrlHandler ( - SVCNAME, + svcname, SvcCtrlHandler ); @@ -274,7 +301,7 @@ SvcInit ( sizeof szRegistryPath, #endif L"SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", - SVCNAME + svcname ); fSuccess = RegistryRead ( @@ -403,7 +430,7 @@ SvcReportEvent ( hEventSource = RegisterEventSource ( NULL, - SVCNAME + svcname ); if ( @@ -422,7 +449,7 @@ SvcReportEvent ( GetLastError() ); - lpszStrings[0] = SVCNAME; + lpszStrings[0] = svcname; lpszStrings[1] = Buffer; ReportEvent ( -- 1.8.3.1
Matthew Booth
2013-Aug-29 15:09 UTC
[Libguestfs] [PATCH 3/6] Remove problematic swprintf_s
Using swprintf_s results in a link error when executed on Windows 2003. Given that its use isn't important here and an alternative is already available, this change simply removes it. --- RHSrvAny/RHSrvAny.c | 7 ------- configure.ac | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/RHSrvAny/RHSrvAny.c b/RHSrvAny/RHSrvAny.c index 31caaeb..10317a4 100644 --- a/RHSrvAny/RHSrvAny.c +++ b/RHSrvAny/RHSrvAny.c @@ -22,7 +22,6 @@ #else /* Assume we're not using autoconf, eg. for Visual C++. */ #define HAVE_STRSAFE 1 -#define HAVE_SWPRINTF_S 1 #define HAVE_STRINGCCHPRINTF 1 #endif /* HAVE_CONFIG_H */ @@ -291,15 +290,9 @@ SvcInit ( ZeroMemory( &pi, sizeof(pi) ); nSize=1024; -#ifdef HAVE_SWPRINTF_S - swprintf_s ( - szRegistryPath, - nSize, -#else snwprintf ( szRegistryPath, sizeof szRegistryPath, -#endif L"SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", svcname ); diff --git a/configure.ac b/configure.ac index cc2a584..e58941d 100644 --- a/configure.ac +++ b/configure.ac @@ -39,7 +39,7 @@ dnl Check for headers which are not present in some versions of MinGW. AC_CHECK_HEADERS([strsafe.h]) dnl Check for functions which are not present in some versions of MinGW. -AC_CHECK_FUNCS([swprintf_s StringCchPrintf]) +AC_CHECK_FUNCS([StringCchPrintf]) dnl Produce output files. AC_CONFIG_HEADERS([config.h]) -- 1.8.3.1
Matthew Booth
2013-Aug-29 15:09 UTC
[Libguestfs] [PATCH 4/6] Declare non-exported functions static
--- RHSrvAny/RHSrvAny.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/RHSrvAny/RHSrvAny.c b/RHSrvAny/RHSrvAny.c index 10317a4..4bd7ef2 100644 --- a/RHSrvAny/RHSrvAny.c +++ b/RHSrvAny/RHSrvAny.c @@ -40,17 +40,18 @@ static TCHAR *svcname = TEXT("RHSrvAny"); -SERVICE_STATUS gSvcStatus; -HANDLE ghSvcStopEvent = NULL; -SERVICE_STATUS_HANDLE gSvcStatusHandle; +static SERVICE_STATUS gSvcStatus; +static HANDLE ghSvcStopEvent = NULL; +static SERVICE_STATUS_HANDLE gSvcStatusHandle; + +static VOID SvcInstall (void); -VOID SvcInstall (void); VOID WINAPI SvcCtrlHandler (DWORD); VOID WINAPI SvcMain (DWORD, LPTSTR *); -VOID SvcReportEvent (LPTSTR); -VOID SvcInit (DWORD, LPTSTR *); -VOID ReportSvcStatus (DWORD, DWORD, DWORD); +static VOID SvcReportEvent (LPTSTR); +static VOID SvcInit (DWORD, LPTSTR *); +static VOID ReportSvcStatus (DWORD, DWORD, DWORD); static int argument_error (const char *msg) @@ -114,7 +115,7 @@ main (int argc, char **a_argv) return EXIT_SUCCESS; } -VOID +static VOID SvcInstall() { SC_HANDLE schSCManager; SC_HANDLE schService; @@ -205,7 +206,7 @@ SvcMain ( ); } -BOOL +static BOOL RegistryRead ( HKEY hHive, wchar_t *szKeyPath, @@ -240,7 +241,7 @@ RegistryRead ( return (FALSE); } -VOID +static VOID SvcInit ( DWORD dwArgc, LPTSTR *lpszArgv @@ -352,7 +353,8 @@ SvcInit ( } } -VOID ReportSvcStatus ( +static VOID +ReportSvcStatus ( DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint @@ -413,7 +415,7 @@ SvcCtrlHandler ( } /* Logs messages to the event log */ -VOID +static VOID SvcReportEvent ( LPTSTR szFunction ) { -- 1.8.3.1
Matthew Booth
2013-Aug-29 15:09 UTC
[Libguestfs] [PATCH 5/6] Make install directive use service name explicitly
install now sets ImagePath to be: <BINPATH> -s <SVCNAME> --- RHSrvAny/RHSrvAny.c | 54 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/RHSrvAny/RHSrvAny.c b/RHSrvAny/RHSrvAny.c index 4bd7ef2..75ce7c4 100644 --- a/RHSrvAny/RHSrvAny.c +++ b/RHSrvAny/RHSrvAny.c @@ -44,7 +44,7 @@ static SERVICE_STATUS gSvcStatus; static HANDLE ghSvcStopEvent = NULL; static SERVICE_STATUS_HANDLE gSvcStatusHandle; -static VOID SvcInstall (void); +static int SvcInstall (void); VOID WINAPI SvcCtrlHandler (DWORD); VOID WINAPI SvcMain (DWORD, LPTSTR *); @@ -94,8 +94,7 @@ main (int argc, char **a_argv) } if (lstrcmpi(argv[i], TEXT("install")) == 0) { - SvcInstall(); - return EXIT_SUCCESS; + return SvcInstall(); } SERVICE_TABLE_ENTRY DispatchTable[] = { @@ -115,22 +114,12 @@ main (int argc, char **a_argv) return EXIT_SUCCESS; } -static VOID +static int SvcInstall() { SC_HANDLE schSCManager; SC_HANDLE schService; TCHAR szPath[MAX_PATH]; - - if ( - !GetModuleFileName( - NULL, - szPath, - MAX_PATH - ) - ) { - printf("Cannot install service (%d)\n", (int) GetLastError()); - return; - } + wchar_t imagePath[MAX_PATH]; schSCManager = OpenSCManager( NULL, @@ -140,7 +129,20 @@ SvcInstall() { if (NULL == schSCManager) { printf("OpenSCManager failed (%d)\n", (int) GetLastError()); - return; + return EXIT_FAILURE; + } + + /* Get the full path of the current executable in szPath */ + if (GetModuleFileName(NULL, szPath, MAX_PATH) == 0) { + printf("GetModuleFileName failed (%d)\n", (int) GetLastError()); + return EXIT_FAILURE; + } + + /* Construct ImagePath, which is actually a command line in this instance */ + if (snwprintf(imagePath, MAX_PATH, L"%s -s %s", szPath, svcname) >= MAX_PATH) + { + printf("ImagePath exceeded %d characters\n", MAX_PATH); + return EXIT_FAILURE; } schService = CreateService ( @@ -151,7 +153,7 @@ SvcInstall() { SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, - szPath, + imagePath, NULL, NULL, NULL, @@ -160,12 +162,18 @@ SvcInstall() { ); if (schService == NULL) { - printf ( - "CreateService failed (%d)\n", - (int) GetLastError() - ); + DWORD err = GetLastError(); + switch (err) { + case ERROR_SERVICE_EXISTS: + printf("A service with this name already exists\n"); + break; + + default: + printf("CreateService failed (%d)\n", (int) err); + } + CloseServiceHandle (schSCManager); - return; + return EXIT_FAILURE; } else { printf("Service installed successfully\n"); @@ -173,6 +181,8 @@ SvcInstall() { CloseServiceHandle (schService); CloseServiceHandle (schSCManager); + + return EXIT_SUCCESS; } VOID -- 1.8.3.1
--- RHSrvAny/RHSrvAny.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/RHSrvAny/RHSrvAny.c b/RHSrvAny/RHSrvAny.c index 75ce7c4..3639d22 100644 --- a/RHSrvAny/RHSrvAny.c +++ b/RHSrvAny/RHSrvAny.c @@ -45,6 +45,7 @@ static HANDLE ghSvcStopEvent = NULL; static SERVICE_STATUS_HANDLE gSvcStatusHandle; static int SvcInstall (void); +static int SvcUninstall (void); VOID WINAPI SvcCtrlHandler (DWORD); VOID WINAPI SvcMain (DWORD, LPTSTR *); @@ -95,6 +96,8 @@ main (int argc, char **a_argv) if (lstrcmpi(argv[i], TEXT("install")) == 0) { return SvcInstall(); + } else if (lstrcmpi(argv[i], TEXT("uninstall")) == 0) { + return SvcUninstall(); } SERVICE_TABLE_ENTRY DispatchTable[] = { @@ -115,6 +118,65 @@ main (int argc, char **a_argv) } static int +SvcUninstall() { + SC_HANDLE schSCManager = NULL; + SC_HANDLE schService = NULL; + + schSCManager = OpenSCManager( + NULL, + NULL, + SC_MANAGER_ALL_ACCESS + ); + + if (NULL == schSCManager) { + printf("OpenSCManager failed (%d)\n", (int) GetLastError()); + return EXIT_FAILURE; + } + + schService = OpenService( + schSCManager, + svcname, + SERVICE_ALL_ACCESS + ); + + if (schService == NULL) { + DWORD err = GetLastError(); + switch (err) { + case ERROR_ACCESS_DENIED: + printf("You do not have permission to uninstall this service\n"); + break; + + case ERROR_SERVICE_DOES_NOT_EXIST: + printf("The service does not exist\n"); + break; + + default: + printf("OpenService failed (%d)\n", (int) err); + } + + goto error; + } + + if (DeleteService(schService) == 0) { + printf("DeleteService failed (%d)\n", (int) GetLastError()); + goto error; + } else { + printf("Service uninstalled successfully\n"); + } + + CloseServiceHandle (schService); + CloseServiceHandle (schSCManager); + + return EXIT_SUCCESS; + +error: + if (schService) CloseServiceHandle (schService); + if (schSCManager) CloseServiceHandle (schSCManager); + + return EXIT_FAILURE; +} + +static int SvcInstall() { SC_HANDLE schSCManager; SC_HANDLE schService; -- 1.8.3.1