blob: 77ad368fadb38975dec43fb92658c71a69437296 [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;
}