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 { 40 SC_HANDLE manager; 41 SC_HANDLE service; 42 TCHAR cmdline[MAX_PATH]; 43 44 if (GetModuleFileName(NULL, cmdline, MAX_PATH) == 0) { 45 printf_win_error("No full path to service's executable"); 46 return EXIT_FAILURE; 47 } 48 49 _snprintf(cmdline, MAX_PATH - strlen(cmdline), "%s -d", cmdline); 50 51 if (path) { 52 _snprintf(cmdline, MAX_PATH - strlen(cmdline), "%s -p %s", cmdline, path); 53 } 54 if (logfile) { 55 _snprintf(cmdline, MAX_PATH - strlen(cmdline), "%s -l %s -v", 56 cmdline, logfile); 57 } 58 59 g_debug("service's cmdline: %s", cmdline); 60 61 manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 62 if (manager == NULL) { 63 printf_win_error("No handle to service control manager"); 64 return EXIT_FAILURE; 65 } 66 67 service = CreateService(manager, QGA_SERVICE_NAME, QGA_SERVICE_DISPLAY_NAME, 68 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, 69 SERVICE_ERROR_NORMAL, cmdline, NULL, NULL, NULL, NULL, NULL); 70 71 if (service) { 72 SERVICE_DESCRIPTION desc = { (char *)QGA_SERVICE_DESCRIPTION }; 73 ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &desc); 74 75 printf("Service was installed successfully.\n"); 76 } else { 77 printf_win_error("Failed to install service"); 78 } 79 80 CloseServiceHandle(service); 81 CloseServiceHandle(manager); 82 83 return (service == NULL); 84 } 85 86 int ga_uninstall_service(void) 87 { 88 SC_HANDLE manager; 89 SC_HANDLE service; 90 91 manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 92 if (manager == NULL) { 93 printf_win_error("No handle to service control manager"); 94 return EXIT_FAILURE; 95 } 96 97 service = OpenService(manager, QGA_SERVICE_NAME, DELETE); 98 if (service == NULL) { 99 printf_win_error("No handle to service"); 100 CloseServiceHandle(manager); 101 return EXIT_FAILURE; 102 } 103 104 if (DeleteService(service) == FALSE) { 105 printf_win_error("Failed to delete service"); 106 } else { 107 printf("Service was deleted successfully.\n"); 108 } 109 110 CloseServiceHandle(service); 111 CloseServiceHandle(manager); 112 113 return EXIT_SUCCESS; 114 } 115