/************************************************************************************************* * Utility for the Win32 service control manager * Copyright (C) 2004-2007 Mikio Hirabayashi * This file is part of Hyper Estraier. * Hyper Estraier is free software; you can redistribute it and/or modify it under the terms of * the GNU Lesser General Public License as published by the Free Software Foundation; either * version 2.1 of the License or any later version. Hyper Estraier is distributed in the hope * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * You should have received a copy of the GNU Lesser General Public License along with Hyper * Estraier; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA. *************************************************************************************************/ #include #include #include /* global variables */ const char *g_progname = NULL; /* function prototypes */ int main(int argc, char **argv); static void printferror(const char *format, ...); static void printfinfo(const char *format, ...); static void usage(void); static int runinstall(int argc, char **argv); static int rununinstall(int argc, char **argv); static int procinstall(const char *name, const char *label, const char *path); static int procuninstall(const char *name); /* main routine */ int main(int argc, char **argv){ int rv; g_progname = argv[0]; if(argc < 2) usage(); rv = 0; if(!strcmp(argv[1], "install")){ rv = runinstall(argc, argv); } else if(!strcmp(argv[1], "uninstall")){ rv = rununinstall(argc, argv); } else { usage(); } return rv; } /* print formatted error string and flush the buffer */ static void printferror(const char *format, ...){ va_list ap; va_start(ap, format); fprintf(stderr, "%s: ERROR: ", g_progname); vfprintf(stderr, format, ap); fputc('\n', stderr); fflush(stderr); va_end(ap); } /* print formatted information string and flush the buffer */ static void printfinfo(const char *format, ...){ va_list ap; va_start(ap, format); printf("%s: INFO: ", g_progname); vprintf(format, ap); putchar('\n'); fflush(stdout); va_end(ap); } /* print the usage and exit */ static void usage(void){ fprintf(stderr, "%s: utility for the Win32 service control manager\n", g_progname); fprintf(stderr, "\n"); fprintf(stderr, "usage:\n"); fprintf(stderr, " %s install name label command ...\n", g_progname); fprintf(stderr, " %s uninstall name\n", g_progname); fprintf(stderr, "\n"); exit(1); } /* parse arguments of the install command */ static int runinstall(int argc, char **argv){ char *name, *label, path[8192], *wp; int i, rv; name = NULL; label = NULL; wp = path; for(i = 2; i < argc; i++){ if(!name && argv[i][0] == '-'){ usage(); } else if(!name){ name = argv[i]; } else if(!label){ label = argv[i]; } else { if(wp > path) wp += sprintf(wp, " "); wp += sprintf(wp, "%s", argv[i]); } } *wp = '\0'; if(!name || !label) usage(); rv = procinstall(name, label, path); return rv; } /* parse arguments of the uninstall command */ static int rununinstall(int argc, char **argv){ char *name; int i, rv; name = NULL; for(i = 2; i < argc; i++){ if(!name && argv[i][0] == '-'){ usage(); } else if(!name){ name = argv[i]; } else { usage(); } } if(!name); rv = procuninstall(name); return rv; } /* perform the install command */ static int procinstall(const char *name, const char *label, const char *path){ SC_HANDLE scm, svc; printfinfo("installing %s ...", name); if(!(scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE))){ printferror("the SCM could not open: %d", GetLastError()); return 1; } if(!(svc = CreateService(scm, name, label, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, path, 0, 0, 0, 0, 0))){ printferror("the new service could not be created: %d", GetLastError()); CloseServiceHandle(scm); return 1; } CloseServiceHandle(svc); CloseServiceHandle(scm); printfinfo("done"); return 0; } /* perform the uninstall command */ static int procuninstall(const char *name){ SC_HANDLE scm, svc; SERVICE_STATUS st; printfinfo("uninstalling %s ...", name); if(!(scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE))){ printferror("the SCM could not open: %d", GetLastError()); return 1; } if(!(svc = OpenService(scm, name, SERVICE_ALL_ACCESS | DELETE))){ printferror("the service could not open: %d", GetLastError()); CloseServiceHandle(scm); return 1; } if(!QueryServiceStatus(svc, &st)){ printferror("the service did not finish successfully: %d", GetLastError()); CloseServiceHandle(svc); CloseServiceHandle(scm); return 1; } if(st.dwCurrentState != SERVICE_STOPPED){ if(!ControlService(svc, SERVICE_CONTROL_STOP, &st)){ printferror("the service did not finish successfully: %d", GetLastError()); CloseServiceHandle(svc); CloseServiceHandle(scm); return 1; } Sleep(500); } if(!DeleteService(svc)){ printferror("the service could not be deleted: %d", GetLastError()); CloseServiceHandle(svc); CloseServiceHandle(scm); return 1; } CloseServiceHandle(svc); CloseServiceHandle(scm); printfinfo("done"); return 0; } /* END OF FILE */