sc.exe now supports basic starting, stopping, creation and deletion of services.

Still early days and very bare bones, so not including into build yet

svn path=/trunk/; revision=19000
This commit is contained in:
Ged Murphy 2005-11-04 18:19:09 +00:00
parent 8886eb415a
commit cfb2293f95
8 changed files with 117 additions and 84 deletions

View file

@ -16,14 +16,26 @@
* control, continue, interrogate, pause, stop * control, continue, interrogate, pause, stop
*/ */
BOOL Control(DWORD Control, TCHAR **Args) BOOL Control(DWORD Control, LPCTSTR ServiceName, LPCTSTR *Args)
{ {
SC_HANDLE hSc; SC_HANDLE hSc;
SERVICE_STATUS Status; SERVICE_STATUS Status;
LPCTSTR ServiceName = *Args;
/* testing */
_tprintf(_T("service to control - %s\n\n"), ServiceName);
_tprintf(_T("command - %lu\n\n"), Control);
_tprintf(_T("Arguments :\n"));
while (*Args)
{
printf("%s\n", *Args);
Args++;
}
hSc = OpenService(hSCManager, ServiceName, DELETE); hSc = OpenService(hSCManager, ServiceName,
SERVICE_INTERROGATE | SERVICE_PAUSE_CONTINUE |
SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL |
SERVICE_QUERY_STATUS);
if (hSc == NULL) if (hSc == NULL)
{ {
@ -40,6 +52,9 @@ BOOL Control(DWORD Control, TCHAR **Args)
} }
CloseServiceHandle(hSc); CloseServiceHandle(hSc);
/* print the status information */
return TRUE; return TRUE;
} }

View file

@ -11,12 +11,14 @@
#include "sc.h" #include "sc.h"
BOOL Create(TCHAR **Args) BOOL Create(LPCTSTR ServiceName, LPCTSTR *ServiceArgs)
{ {
SC_HANDLE hSc; SC_HANDLE hSc;
LPCTSTR ServiceName = *Args; LPCTSTR BinaryPathName = *++ServiceArgs;
LPCTSTR BinaryPathName = *++Args; LPCTSTR *Options = ++ServiceArgs;
LPCTSTR *Options = (LPCTSTR *)++Args;
if ((! ServiceName) || (! BinaryPathName))
return CreateUsage();
/* testing */ /* testing */
printf("service to create - %s\n", ServiceName); printf("service to create - %s\n", ServiceName);
@ -28,7 +30,6 @@ BOOL Create(TCHAR **Args)
Options++; Options++;
} }
hSc = CreateService(hSCManager, hSc = CreateService(hSCManager,
ServiceName, ServiceName,
ServiceName, ServiceName,

View file

@ -11,10 +11,9 @@
#include "sc.h" #include "sc.h"
BOOL Delete(TCHAR **Args) BOOL Delete(LPCTSTR ServiceName)
{ {
SC_HANDLE hSc; SC_HANDLE hSc;
LPCTSTR ServiceName = *Args;
/* testing */ /* testing */
printf("service to delete - %s\n\n", ServiceName); printf("service to delete - %s\n\n", ServiceName);

View file

@ -12,32 +12,31 @@
#include "sc.h" #include "sc.h"
/* local function decs */ /* local function decs */
VOID PrintService(ENUM_SERVICE_STATUS_PROCESS *pSStatus, BOOL bExtended); VOID PrintService(BOOL bExtended);
INT EnumServices(DWORD ServiceType, DWORD ServiceState); INT EnumServices(DWORD ServiceType, DWORD ServiceState);
/* global variables */ /* global variables */
static ENUM_SERVICE_STATUS_PROCESS *pServiceStatus = NULL; static ENUM_SERVICE_STATUS_PROCESS *pServiceStatus = NULL;
BOOL
Query(TCHAR **Args, BOOL bExtended) BOOL Query(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, BOOL bExtended)
{ {
LPCTSTR ServiceName = *Args; if (! ServiceName)
if (! *Args)
{ {
printf("Service name %s\n", ServiceName); // test /* display all running services and drivers */
_tprintf(_T("No service name, displaying all services\n")); // test
/* get default values */ /* get default values */
EnumServices(SERVICE_WIN32, SERVICE_ACTIVE); EnumServices(SERVICE_WIN32, SERVICE_ACTIVE);
/* print default values */ /* print default values */
PrintService(pServiceStatus, bExtended); PrintService(bExtended);
} }
else if (_tcsicmp(ServiceName, _T("type=")) == 0)
if (_tcsicmp(Args[0], _T("type=")) == 0)
{ {
TCHAR *Type = *++Args; LPCTSTR Type = *ServiceArgs;
_tprintf(_T("got type\narg = %s\n"), Type); // test _tprintf(_T("got type\narg = %s\n"), Type); // test
if (_tcsicmp(Type, _T("driver")) == 0) if (_tcsicmp(Type, _T("driver")) == 0)
EnumServices(SERVICE_DRIVER, SERVICE_STATE_ALL); EnumServices(SERVICE_DRIVER, SERVICE_STATE_ALL);
@ -51,11 +50,11 @@ Query(TCHAR **Args, BOOL bExtended)
_tprintf(_T("Must be \"driver\" or \"service\" or \"all\"\n")); _tprintf(_T("Must be \"driver\" or \"service\" or \"all\"\n"));
} }
PrintService(pServiceStatus, bExtended); PrintService(bExtended);
} }
else if(_tcsicmp(Args[0], _T("state=")) == 0) else if(_tcsicmp(ServiceName, _T("state=")) == 0)
{ {
TCHAR *State = *++Args; LPCTSTR State = *ServiceArgs;
if (_tcsicmp(State, _T("active")) == 0) if (_tcsicmp(State, _T("active")) == 0)
EnumServices(SERVICE_DRIVER|SERVICE_WIN32, SERVICE_ACTIVE); EnumServices(SERVICE_DRIVER|SERVICE_WIN32, SERVICE_ACTIVE);
@ -69,27 +68,27 @@ Query(TCHAR **Args, BOOL bExtended)
_tprintf(_T("Must be \"active\" or \"inactive\" or \"all\"\n")); _tprintf(_T("Must be \"active\" or \"inactive\" or \"all\"\n"));
} }
PrintService(pServiceStatus, bExtended); PrintService(bExtended);
} }
/*
else if(_tcsicmp(ServiceName, _T("bufsize=")))
else if(_tcsicmp(ServiceName, _T("ri=")))
else if(_tcsicmp(ServiceName, _T("group=")))
*/
else else
{ {
printf("no args\n"); // test /* print only the service requested */
printf("Service name %s\n", ServiceName); // test
/* get default values */ /* get default values */
EnumServices(SERVICE_WIN32, SERVICE_ACTIVE); EnumServices(SERVICE_WIN32, SERVICE_ACTIVE);
/* print default values */ /* print default values */
PrintService(pServiceStatus, bExtended); PrintService(bExtended);
} }
/*
else if(_tcsicmp(Args[0], _T("bufsize=")))
else if(_tcsicmp(Args[0], _T("ri=")))
else if(_tcsicmp(Args[0], _T("group=")))
*/
} }
@ -100,6 +99,8 @@ INT EnumServices(DWORD ServiceType, DWORD ServiceState)
DWORD BytesNeeded = 0; DWORD BytesNeeded = 0;
DWORD NumServices = 0; DWORD NumServices = 0;
DWORD ResumeHandle = 0; DWORD ResumeHandle = 0;
// hSc = OpenService(hSCManager, ServiceName, SERVICE_QUERY_STATUS);
/* determine required buffer size */ /* determine required buffer size */
if (! EnumServicesStatusEx(hSCManager, if (! EnumServicesStatusEx(hSCManager,
@ -147,8 +148,7 @@ INT EnumServices(DWORD ServiceType, DWORD ServiceState)
VOID VOID
PrintService(ENUM_SERVICE_STATUS_PROCESS *pServiceStatus, PrintService(BOOL bExtended)
BOOL bExtended)
{ {
_tprintf(_T("SERVICE_NAME: %s\n"), pServiceStatus->lpServiceName); _tprintf(_T("SERVICE_NAME: %s\n"), pServiceStatus->lpServiceName);
_tprintf(_T("DISPLAY_NAME: %s\n"), pServiceStatus->lpDisplayName); _tprintf(_T("DISPLAY_NAME: %s\n"), pServiceStatus->lpDisplayName);

View file

@ -44,8 +44,14 @@ DWORD ReportLastError(VOID)
} }
INT ScControl(LPTSTR MachineName, LPCTSTR Command, TCHAR **Args) INT ScControl(LPTSTR MachineName, // remote machine name
LPCTSTR Command, // sc command
LPCTSTR ServiceName, // name of service
LPCTSTR *ServiceArgs, // any options
DWORD ArgCount) // argument counter
{ {
/* count trailing arguments */
ArgCount -= 3;
if (MachineName) if (MachineName)
{ {
@ -61,66 +67,66 @@ INT ScControl(LPTSTR MachineName, LPCTSTR Command, TCHAR **Args)
return -1; return -1;
} }
/* emurate command */
if (_tcsicmp(Command, _T("query")) == 0) if (_tcsicmp(Command, _T("query")) == 0)
Query(Args, FALSE); Query(ServiceName, ServiceArgs, FALSE);
else if (_tcsicmp(Command, _T("queryex")) == 0) else if (_tcsicmp(Command, _T("queryex")) == 0)
Query(Args, TRUE); Query(ServiceName, ServiceArgs, TRUE);
else if (_tcsicmp(Command, _T("start")) == 0) else if (_tcsicmp(Command, _T("start")) == 0)
{ {
if (*Args) if (ServiceName)
Start(0, Args); Start(ServiceName, ServiceArgs, ArgCount);
else else
StartUsage(); StartUsage();
} }
else if (_tcsicmp(Command, _T("pause")) == 0) else if (_tcsicmp(Command, _T("pause")) == 0)
{ {
if (*Args) if (ServiceName)
Control(SERVICE_CONTROL_PAUSE, Args); Control(SERVICE_CONTROL_PAUSE, ServiceName, ServiceArgs);
else else
PauseUsage(); PauseUsage();
} }
else if (_tcsicmp(Command, _T("interrogate")) == 0) else if (_tcsicmp(Command, _T("interrogate")) == 0)
{ {
if (*Args) if (ServiceName)
Control(SERVICE_CONTROL_INTERROGATE, Args); Control(SERVICE_CONTROL_INTERROGATE, ServiceName, ServiceArgs);
else else
InterrogateUsage(); InterrogateUsage();
} }
else if (_tcsicmp(Command, _T("stop")) == 0) else if (_tcsicmp(Command, _T("stop")) == 0)
{ {
if (*Args) if (ServiceName)
Control(SERVICE_CONTROL_STOP, Args); Control(SERVICE_CONTROL_STOP, ServiceName, ServiceArgs);
else else
StopUsage(); StopUsage();
} }
else if (_tcsicmp(Command, _T("continue")) == 0) else if (_tcsicmp(Command, _T("continue")) == 0)
{ {
if (*Args) if (ServiceName)
Control(SERVICE_CONTROL_CONTINUE, Args); Control(SERVICE_CONTROL_CONTINUE, ServiceName, ServiceArgs);
else else
ContinueUsage(); ContinueUsage();
} }
else if (_tcsicmp(Command, _T("delete")) == 0) else if (_tcsicmp(Command, _T("delete")) == 0)
{ {
if (*Args) if (ServiceName)
Delete(Args); Delete(ServiceName);
else else
DeleteUsage(); DeleteUsage();
} }
else if (_tcsicmp(Command, _T("create")) == 0) else if (_tcsicmp(Command, _T("create")) == 0)
{ {
if (*Args) if (*ServiceArgs)
Create(Args); Create(ServiceName, ServiceArgs);
else else
CreateUsage(); CreateUsage();
} }
else if (_tcsicmp(Command, _T("control")) == 0) else if (_tcsicmp(Command, _T("control")) == 0)
{ {
if (*Args) if (ServiceName)
Control((DWORD)NULL, ++Args); Control((DWORD)NULL, ServiceName, ServiceArgs);
else else
ContinueUsage(); ContinueUsage();
} }
@ -130,10 +136,9 @@ INT ScControl(LPTSTR MachineName, LPCTSTR Command, TCHAR **Args)
int _tmain(DWORD argc, LPCTSTR argv[]) int _tmain(DWORD argc, LPCTSTR argv[])
{ {
LPTSTR MachineName = NULL; // remote machine LPTSTR MachineName = NULL; // remote machine
LPCTSTR Command = argv[1]; // sc command LPCTSTR Command = NULL; // sc command
TCHAR **Args = NULL; // rest of args LPCTSTR ServiceName = NULL; // Name of service
if (argc < 2) if (argc < 2)
return MainUsage(); return MainUsage();
@ -146,13 +151,16 @@ int _tmain(DWORD argc, LPCTSTR argv[])
_tcscpy(MachineName, argv[1]); _tcscpy(MachineName, argv[1]);
Command = argv[2]; Command = argv[2];
Args = (TCHAR **)&argv[3]; if (argc > 3)
return ScControl(MachineName, Command, Args); ServiceName = argv[3];
return ScControl(MachineName, Command, ServiceName, &argv[4], argc);
} }
else else
{ {
Args = (TCHAR **)&argv[2]; Command = argv[1];
return ScControl(MachineName, Command, Args); if (argc > 2)
ServiceName = argv[2];
return ScControl(MachineName, Command, ServiceName, &argv[3], argc);
} }
return MainUsage(); return MainUsage();

View file

@ -7,11 +7,11 @@ extern SC_HANDLE hSCManager; // declared in sc.c
//#define DBG //#define DBG
/* control functions */ /* control functions */
BOOL Query(TCHAR **Args, BOOL bExtended); BOOL Query(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, BOOL bExtended);
BOOL Start(INT ArgCount, TCHAR **Args); BOOL Start(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, INT ArgCount);
BOOL Create(TCHAR **Args); BOOL Create(LPCTSTR ServiceName, LPCTSTR *ServiceArgs);
BOOL Delete(TCHAR **Args); BOOL Delete(LPCTSTR ServiceName);
BOOL Control(DWORD Control, TCHAR **Args); BOOL Control(DWORD Control, LPCTSTR ServiceName, LPCTSTR *Args);
/* print and error functions */ /* print and error functions */
DWORD ReportLastError(VOID); DWORD ReportLastError(VOID);
@ -25,3 +25,5 @@ INT ContinueUsage(VOID);
INT StopUsage(VOID); INT StopUsage(VOID);
INT ConfigUsage(VOID); INT ConfigUsage(VOID);
INT DescriptionUsage(VOID); INT DescriptionUsage(VOID);
INT DeleteUsage(VOID);
INT CreateUsage(VOID);

View file

@ -11,14 +11,11 @@
#include "sc.h" #include "sc.h"
BOOL Start(INT ArgCount, TCHAR **Args) BOOL Start(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, INT ArgCount)
{ {
SC_HANDLE hSc; SC_HANDLE hSc;
SERVICE_STATUS_PROCESS ServiceStatus; SERVICE_STATUS_PROCESS ServiceStatus;
LPCTSTR ServiceName = *Args++;
LPCTSTR *ServiceArgs = (LPCTSTR *)Args;
DWORD BytesNeeded; DWORD BytesNeeded;
/* testing */ /* testing */
_tprintf(_T("service to start - %s\n\n"), ServiceName); _tprintf(_T("service to start - %s\n\n"), ServiceName);
@ -28,8 +25,7 @@ BOOL Start(INT ArgCount, TCHAR **Args)
printf("%s\n", *ServiceArgs); printf("%s\n", *ServiceArgs);
ServiceArgs++; ServiceArgs++;
} }
if (! *ServiceArgs)
ServiceArgs = NULL;
/* get a handle to the service requested for starting */ /* get a handle to the service requested for starting */
hSc = OpenService(hSCManager, ServiceName, SERVICE_ALL_ACCESS); hSc = OpenService(hSCManager, ServiceName, SERVICE_ALL_ACCESS);

View file

@ -142,13 +142,25 @@ INT DeleteUsage(VOID)
INT CreateUsage(VOID) INT CreateUsage(VOID)
{ {
_tprintf(_T("DESCRIPTION:\n") _tprintf(_T("Creates a service entry in the registry and Service Database.\n")
_T("Creates a service entry in the registry and Service Database.\n") _T("SYNTAX:\n")
_T(" If the service is running, or another process has an\n") _T("sc create [service name] [binPath= ] <option1> <option2>...\n")
_T(" open handle to the service, the service is simply marked\n") _T("CREATE OPTIONS:\n")
_T(" for deletion.\n") _T("NOTE: The option name includes the equal sign.\n")
_T("USAGE:\n") _T(" type= <own|share|interact|kernel|filesys|rec>\n")
_T(" sc <server> delete [service name]\n")); _T(" (default = own)\n")
_T(" start= <boot|system|auto|demand|disabled>\n")
_T(" (default = demand)\n")
_T(" error= <normal|severe|critical|ignore>\n")
_T(" (default = normal)\n")
_T(" binPath= <BinaryPathName>\n")
_T(" group= <LoadOrderGroup>\n")
_T(" tag= <yes|no>\n")
_T(" depend= <Dependencies(separated by / (forward slash))>\n")
_T(" obj= <AccountName|ObjectName>\n")
_T(" (default = LocalSystem)\n")
_T(" DisplayName= <display name>\n")
_T(" password= <password>\n"));
return 0; return 0;
} }