| /* ********************************************************** |
| * Copyright (c) 2003-2006 VMware, Inc. All rights reserved. |
| * **********************************************************/ |
| |
| /* |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * * Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * |
| * * Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * * Neither the name of VMware, Inc. nor the names of its contributors may be |
| * used to endorse or promote products derived from this software without |
| * specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE |
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
| * DAMAGE. |
| */ |
| |
| /* |
| * svccntrl.c |
| * |
| * command-line tool for manipulating services |
| * |
| * (c) determina, inc. all rights reserved |
| */ |
| |
| #include "configure.h" |
| #include "mfapi.h" |
| #include "services.h" |
| |
| #include <stdio.h> |
| |
| WCHAR *longbuff; |
| ServiceHandle foundsvc = INVALID_SERVICE_HANDLE; |
| |
| BOOL |
| show_svcs_cb(ServiceHandle service, void **param) |
| { |
| static const char *automatic = "auto"; |
| static const char *manual = "manual"; |
| static const char *disabled = "disabled"; |
| static const char *unknown = "<unknown>"; |
| const char *typename; |
| DWORD type = get_service_start_type(service); |
| typename = (type == SERVICE_AUTO_START |
| ? automatic |
| : (type == SERVICE_DEMAND_START |
| ? manual |
| : (type == SERVICE_DISABLED ? disabled : unknown))); |
| printf("%S %s\n", get_service_name(service), typename); |
| return TRUE; |
| } |
| |
| BOOL |
| finddispname_cb(ServiceHandle svc, void **param) |
| { |
| if (!wcsicmp(longbuff, get_service_display_name(svc))) { |
| foundsvc = svc; |
| return FALSE; |
| } |
| return TRUE; |
| } |
| |
| void |
| usage() |
| { |
| fprintf(stderr, |
| "Usage:\nsvcctrl svcname [ -auto | -manual | -restart | -disabled ] [-help] " |
| "[-show] [-dep svc2] [-depreset] [-v]\n"); |
| exit(1); |
| } |
| |
| void |
| help() |
| { |
| |
| fprintf(stderr, "Options:\n"); |
| fprintf(stderr, " -auto\\tt\tset the service to run automatically\n"); |
| fprintf(stderr, " -manual\t\tset the service to manual control\n"); |
| fprintf(stderr, " -restart\t\tset the service to auto-restart\n"); |
| fprintf(stderr, " -disabled\t\tdisable the service\n"); |
| fprintf(stderr, " -show\t\t\tshow all installed services and start types\n"); |
| fprintf(stderr, " -dep svc2\t\tmake the service dependent on svc2\n"); |
| fprintf(stderr, " -depreset\t\treset service dependencies\n"); |
| fprintf(stderr, " -v\t\t\tdisplay version information\n\n"); |
| exit(1); |
| } |
| |
| ServiceHandle |
| get_svc(char *buf) |
| { |
| ServiceHandle svc; |
| WCHAR w_buf[MAX_PATH]; |
| |
| _snwprintf(w_buf, MAX_PATH, L"%S", buf); |
| svc = get_service_by_name(w_buf); |
| if (svc == INVALID_SERVICE_HANDLE) { |
| longbuff = w_buf; |
| enumerate_services(&finddispname_cb, NULL); |
| svc = foundsvc; |
| } |
| return svc; |
| } |
| |
| int |
| main(int argc, char **argv) |
| { |
| int res = 0, sauto = 0, sman = 0, sdis = 0, show = 0, depreset = 0, srestart = 0; |
| char *dep = NULL; |
| |
| char *svcname = NULL; |
| int argidx = 1; |
| ServiceHandle svc; |
| WCHAR w_buf[MAX_PATH]; |
| |
| svcname = argv[argidx++]; |
| |
| while (argidx < argc) { |
| |
| if (!strcmp(argv[argidx], "-help")) { |
| help(); |
| } else if (!strcmp(argv[argidx], "-auto")) { |
| sauto = 1; |
| } else if (!strcmp(argv[argidx], "-manual")) { |
| sman = 1; |
| } else if (!strcmp(argv[argidx], "-restart")) { |
| srestart = 1; |
| } else if (!strcmp(argv[argidx], "-show")) { |
| show = 1; |
| } else if (!strcmp(argv[argidx], "-depreset")) { |
| depreset = 1; |
| } else if (!strcmp(argv[argidx], "-dep")) { |
| if (argidx + 1 >= argc) |
| usage(); |
| dep = argv[++argidx]; |
| } else if (!strcmp(argv[argidx], "-disabled")) { |
| sdis = 1; |
| } else if (!strcmp(argv[argidx], "-v")) { |
| #ifdef BUILD_NUMBER |
| printf("svccntrl.exe build %d -- %s\n", BUILD_NUMBER, __DATE__); |
| #else |
| printf("svccntrl.exe custom build -- %s, %s\n", __DATE__, __TIME__); |
| #endif |
| } else { |
| fprintf(stderr, "Unknown option: %s\n", argv[argidx]); |
| usage(); |
| } |
| argidx++; |
| } |
| |
| if (argc < 3) |
| usage(); |
| |
| if (sauto + sman + sdis + show + srestart != 1 && dep == NULL && !depreset) { |
| fprintf(stderr, "Bad combination of options.\n"); |
| usage(); |
| } |
| |
| services_init(); |
| |
| if (show) { |
| enumerate_services(&show_svcs_cb, NULL); |
| } else { |
| |
| _snwprintf(w_buf, MAX_PATH, L"%S", svcname); |
| |
| if (srestart) { |
| res = set_service_restart_type(w_buf, FALSE); |
| if (res != ERROR_SUCCESS) { |
| fprintf(stderr, "Error %d updating the configuration\n", res); |
| } |
| } else if (dep) { |
| ServiceHandle svc2; |
| svc = get_svc(svcname); |
| svc2 = get_svc(dep); |
| if (svc == INVALID_SERVICE_HANDLE || svc2 == INVALID_SERVICE_HANDLE) { |
| fprintf(stderr, "Invalid services: %s, %s\n", svcname, dep); |
| } else { |
| res = add_dependent_service(svc, svc2); |
| if (res != ERROR_SUCCESS) |
| fprintf(stderr, "Error %d setting dependencies\n", res); |
| } |
| } else if (depreset) { |
| svc = get_svc(svcname); |
| if (svc == INVALID_SERVICE_HANDLE) { |
| fprintf(stderr, "Invalid service: %s\n", svcname); |
| } else { |
| res = reset_dependent_services(svc); |
| if (res != ERROR_SUCCESS) |
| fprintf(stderr, "Error %d resetting dependencies\n", res); |
| } |
| } else { |
| svc = get_svc(svcname); |
| |
| if (svc == INVALID_SERVICE_HANDLE) { |
| fprintf(stderr, "Invalid service: %s\n", svcname); |
| } else { |
| res = set_service_start_type(svc, |
| sauto ? SERVICE_AUTO_START |
| : sman ? SERVICE_DEMAND_START |
| : sdis ? SERVICE_DISABLED |
| : SERVICE_NO_CHANGE); |
| if (res != ERROR_SUCCESS) |
| fprintf(stderr, "There was an error setting the configuration\n"); |
| } |
| } |
| } |
| |
| services_cleanup(); |
| |
| return 0; |
| } |