diff mbox

[2/5] qga-win: service-win32: Add start_service and stop_service functions

Message ID 20170705075411.6556-3-sameeh@daynix.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sameeh Jubran July 5, 2017, 7:54 a.m. UTC
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(+)

Comments

Michael Roth July 25, 2017, 11:32 p.m. UTC | #1
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 mbox

Patch

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