Message ID | 20170705075411.6556-3-sameeh@daynix.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Quoting Sameeh Jubran (2017-07-05 02:54:08) > From: Sameeh Jubran <sjubran@redhat.com> > > This commits adds two functions which handle service's start and stop > process in Windows. > > Signed-off-by: Sameeh Jubran <sjubran@redhat.com> > --- > qga/service-win32.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > qga/service-win32.h | 2 ++ > 2 files changed, 54 insertions(+) > > diff --git a/qga/service-win32.c b/qga/service-win32.c > index fd434e3..dc41d63 100644 > --- a/qga/service-win32.c > +++ b/qga/service-win32.c > @@ -95,6 +95,26 @@ static const char *win_escape_arg(const char *to_escape, GString *buffer) > return buffer->str; > } > > + > +static int get_service(const char *service_name, SC_HANDLE* service) SC_HANDLE *service > +{ > + SC_HANDLE manager = NULL; OpenSCManager returns NULL on error so no need to initialize the value here. > + manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); > + if (manager == NULL) { > + printf_win_error("No handle to service control manager"); > + return EXIT_FAILURE; > + } > + > + *service = OpenService(manager, service_name, SERVICE_ALL_ACCESS); > + if (service == NULL) { This should be checking *service AFAICT. > + printf_win_error("Failed to open service"); > + return EXIT_FAILURE; > + } > + > + CloseServiceHandle(manager); > + return EXIT_SUCCESS; > +} > + > int ga_install_service(const char *path, const char *logfile, > const char *state_dir) > { > @@ -188,3 +208,35 @@ int ga_uninstall_service(void) > > return EXIT_SUCCESS; > } > + > +int start_service(const char *service_name) > +{ > + int ret = EXIT_FAILURE; get_service() will set this either way so no need to initialize. > + SC_HANDLE service = NULL; > + ret = get_service(service_name, &service); > + if (ret != EXIT_SUCCESS) { > + return ret; > + } > + ret = StartService(service, 0 , NULL) ? EXIT_SUCCESS : GetLastError(); > + > + CloseServiceHandle(service); > + return ret; > +} > + > +int stop_service(const char *service_name) > +{ > + int ret = EXIT_FAILURE; No need to initialize > + SC_HANDLE service = NULL; > + > + SERVICE_STATUS service_status; > + ret = get_service(service_name, &service); > + > + if (ret != EXIT_SUCCESS) { > + return ret; > + } > + ret = ControlService(service, SERVICE_CONTROL_STOP, &service_status) ? > + EXIT_SUCCESS : GetLastError(); > + > + CloseServiceHandle(service); > + return ret; > +} > diff --git a/qga/service-win32.h b/qga/service-win32.h > index 89e99df..65248ea 100644 > --- a/qga/service-win32.h > +++ b/qga/service-win32.h > @@ -28,5 +28,7 @@ typedef struct GAService { > int ga_install_service(const char *path, const char *logfile, > const char *state_dir); > int ga_uninstall_service(void); > +int start_service(const char *service_name); > +int stop_service(const char *service_name); > > #endif > -- > 2.9.4 >
diff --git a/qga/service-win32.c b/qga/service-win32.c index fd434e3..dc41d63 100644 --- a/qga/service-win32.c +++ b/qga/service-win32.c @@ -95,6 +95,26 @@ static const char *win_escape_arg(const char *to_escape, GString *buffer) return buffer->str; } + +static int get_service(const char *service_name, SC_HANDLE* service) +{ + SC_HANDLE manager = NULL; + manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (manager == NULL) { + printf_win_error("No handle to service control manager"); + return EXIT_FAILURE; + } + + *service = OpenService(manager, service_name, SERVICE_ALL_ACCESS); + if (service == NULL) { + printf_win_error("Failed to open service"); + return EXIT_FAILURE; + } + + CloseServiceHandle(manager); + return EXIT_SUCCESS; +} + int ga_install_service(const char *path, const char *logfile, const char *state_dir) { @@ -188,3 +208,35 @@ int ga_uninstall_service(void) return EXIT_SUCCESS; } + +int start_service(const char *service_name) +{ + int ret = EXIT_FAILURE; + SC_HANDLE service = NULL; + ret = get_service(service_name, &service); + if (ret != EXIT_SUCCESS) { + return ret; + } + ret = StartService(service, 0 , NULL) ? EXIT_SUCCESS : GetLastError(); + + CloseServiceHandle(service); + return ret; +} + +int stop_service(const char *service_name) +{ + int ret = EXIT_FAILURE; + SC_HANDLE service = NULL; + + SERVICE_STATUS service_status; + ret = get_service(service_name, &service); + + if (ret != EXIT_SUCCESS) { + return ret; + } + ret = ControlService(service, SERVICE_CONTROL_STOP, &service_status) ? + EXIT_SUCCESS : GetLastError(); + + CloseServiceHandle(service); + return ret; +} diff --git a/qga/service-win32.h b/qga/service-win32.h index 89e99df..65248ea 100644 --- a/qga/service-win32.h +++ b/qga/service-win32.h @@ -28,5 +28,7 @@ typedef struct GAService { int ga_install_service(const char *path, const char *logfile, const char *state_dir); int ga_uninstall_service(void); +int start_service(const char *service_name); +int stop_service(const char *service_name); #endif