blob: fb7c5ffd9c8716eeb1ff5dbef2ed8521caddc216 [file] [log] [blame]
/* **********************************************************
* 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;
}