1 /* 2 * QEMU Guest Agent helpers for win32 service management 3 * 4 * Copyright IBM Corp. 2012 5 * 6 * Authors: 7 * Gal Hammer <ghammer@redhat.com> 8 * Michael Roth <mdroth@linux.vnet.ibm.com> 9 * 10 * This work is licensed under the terms of the GNU GPL, version 2 or later. 11 * See the COPYING file in the top-level directory. 12 */ 13 #include <stdlib.h> 14 #include <stdio.h> 15 #include <glib.h> 16 #include <windows.h> 17 #include "qga/service-win32.h" 18 19 static int printf_win_error(const char *text) 20 { 21 DWORD err = GetLastError(); 22 char *message; 23 int n; 24 25 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 26 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 27 NULL, 28 err, 29 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 30 (char *)&message, 0, 31 NULL); 32 n = printf("%s. (Error: %d) %s", text, (int)err, message); 33 LocalFree(message); 34 35 return n; 36 } 37 38 int ga_install_service(const char *path, const char *logfile, 39 const char *state_dir) 40 { 41 SC_HANDLE manager; 42 SC_HANDLE service; 43 TCHAR module_fname[MAX_PATH]; 44 GString *cmdline; 45 46 if (GetModuleFileName(NULL, module_fname, MAX_PATH) == 0) { 47 printf_win_error("No full path to service's executable"); 48 return EXIT_FAILURE; 49 } 50 51 cmdline = g_string_new(module_fname); 52 g_string_append(cmdline, " -d"); 53 54 if (path) { 55 g_string_append_printf(cmdline, " -p %s", path); 56 } 57 if (logfile) { 58 g_string_append_printf(cmdline, " -l %s -v", logfile); 59 } 60 if (state_dir) { 61 g_string_append_printf(cmdline, " -t %s", state_dir); 62 } 63 64 g_debug("service's cmdline: %s", cmdline->str); 65 66 manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 67 if (manager == NULL) { 68 printf_win_error("No handle to service control manager"); 69 g_string_free(cmdline, TRUE); 70 return EXIT_FAILURE; 71 } 72 73 service = CreateService(manager, QGA_SERVICE_NAME, QGA_SERVICE_DISPLAY_NAME, 74 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, 75 SERVICE_ERROR_NORMAL, cmdline->str, NULL, NULL, NULL, NULL, NULL); 76 77 if (service) { 78 SERVICE_DESCRIPTION desc = { (char *)QGA_SERVICE_DESCRIPTION }; 79 ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &desc); 80 81 printf("Service was installed successfully.\n"); 82 } else { 83 printf_win_error("Failed to install service"); 84 } 85 86 CloseServiceHandle(service); 87 CloseServiceHandle(manager); 88 89 g_string_free(cmdline, TRUE); 90 return (service == NULL); 91 } 92 93 int ga_uninstall_service(void) 94 { 95 SC_HANDLE manager; 96 SC_HANDLE service; 97 98 manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 99 if (manager == NULL) { 100 printf_win_error("No handle to service control manager"); 101 return EXIT_FAILURE; 102 } 103 104 service = OpenService(manager, QGA_SERVICE_NAME, DELETE); 105 if (service == NULL) { 106 printf_win_error("No handle to service"); 107 CloseServiceHandle(manager); 108 return EXIT_FAILURE; 109 } 110 111 if (DeleteService(service) == FALSE) { 112 printf_win_error("Failed to delete service"); 113 } else { 114 printf("Service was deleted successfully.\n"); 115 } 116 117 CloseServiceHandle(service); 118 CloseServiceHandle(manager); 119 120 return EXIT_SUCCESS; 121 } 122