From cfb2293f95c199773aee95f25cc2bfd464e2003a Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Fri, 4 Nov 2005 18:19:09 +0000 Subject: [PATCH] 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 --- reactos/subsys/system/sc/control.c | 21 ++++++++-- reactos/subsys/system/sc/create.c | 11 ++--- reactos/subsys/system/sc/delete.c | 3 +- reactos/subsys/system/sc/query.c | 56 +++++++++++++------------- reactos/subsys/system/sc/sc.c | 64 +++++++++++++++++------------- reactos/subsys/system/sc/sc.h | 12 +++--- reactos/subsys/system/sc/start.c | 8 +--- reactos/subsys/system/sc/usage.c | 26 ++++++++---- 8 files changed, 117 insertions(+), 84 deletions(-) diff --git a/reactos/subsys/system/sc/control.c b/reactos/subsys/system/sc/control.c index c2fbfd0f053..e9965d7e37e 100644 --- a/reactos/subsys/system/sc/control.c +++ b/reactos/subsys/system/sc/control.c @@ -16,14 +16,26 @@ * control, continue, interrogate, pause, stop */ -BOOL Control(DWORD Control, TCHAR **Args) +BOOL Control(DWORD Control, LPCTSTR ServiceName, LPCTSTR *Args) { SC_HANDLE hSc; 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) { @@ -40,6 +52,9 @@ BOOL Control(DWORD Control, TCHAR **Args) } CloseServiceHandle(hSc); + + /* print the status information */ + return TRUE; } diff --git a/reactos/subsys/system/sc/create.c b/reactos/subsys/system/sc/create.c index f9ee00f5d61..3fe1e573cdf 100644 --- a/reactos/subsys/system/sc/create.c +++ b/reactos/subsys/system/sc/create.c @@ -11,12 +11,14 @@ #include "sc.h" -BOOL Create(TCHAR **Args) +BOOL Create(LPCTSTR ServiceName, LPCTSTR *ServiceArgs) { SC_HANDLE hSc; - LPCTSTR ServiceName = *Args; - LPCTSTR BinaryPathName = *++Args; - LPCTSTR *Options = (LPCTSTR *)++Args; + LPCTSTR BinaryPathName = *++ServiceArgs; + LPCTSTR *Options = ++ServiceArgs; + + if ((! ServiceName) || (! BinaryPathName)) + return CreateUsage(); /* testing */ printf("service to create - %s\n", ServiceName); @@ -28,7 +30,6 @@ BOOL Create(TCHAR **Args) Options++; } - hSc = CreateService(hSCManager, ServiceName, ServiceName, diff --git a/reactos/subsys/system/sc/delete.c b/reactos/subsys/system/sc/delete.c index f81c986a07e..0a831d97caa 100644 --- a/reactos/subsys/system/sc/delete.c +++ b/reactos/subsys/system/sc/delete.c @@ -11,10 +11,9 @@ #include "sc.h" -BOOL Delete(TCHAR **Args) +BOOL Delete(LPCTSTR ServiceName) { SC_HANDLE hSc; - LPCTSTR ServiceName = *Args; /* testing */ printf("service to delete - %s\n\n", ServiceName); diff --git a/reactos/subsys/system/sc/query.c b/reactos/subsys/system/sc/query.c index 8ddf7430518..f2333017ece 100644 --- a/reactos/subsys/system/sc/query.c +++ b/reactos/subsys/system/sc/query.c @@ -12,32 +12,31 @@ #include "sc.h" /* local function decs */ -VOID PrintService(ENUM_SERVICE_STATUS_PROCESS *pSStatus, BOOL bExtended); +VOID PrintService(BOOL bExtended); INT EnumServices(DWORD ServiceType, DWORD ServiceState); /* global variables */ 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 (! *Args) + if (! ServiceName) { - 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 */ EnumServices(SERVICE_WIN32, SERVICE_ACTIVE); /* print default values */ - PrintService(pServiceStatus, bExtended); + PrintService(bExtended); } - - if (_tcsicmp(Args[0], _T("type=")) == 0) + else if (_tcsicmp(ServiceName, _T("type=")) == 0) { - TCHAR *Type = *++Args; + LPCTSTR Type = *ServiceArgs; + _tprintf(_T("got type\narg = %s\n"), Type); // test if (_tcsicmp(Type, _T("driver")) == 0) 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")); } - 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) 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")); } - PrintService(pServiceStatus, bExtended); + PrintService(bExtended); } +/* + else if(_tcsicmp(ServiceName, _T("bufsize="))) + + else if(_tcsicmp(ServiceName, _T("ri="))) + + else if(_tcsicmp(ServiceName, _T("group="))) +*/ else { - printf("no args\n"); // test + /* print only the service requested */ + printf("Service name %s\n", ServiceName); // test + /* get default values */ EnumServices(SERVICE_WIN32, SERVICE_ACTIVE); /* 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 NumServices = 0; DWORD ResumeHandle = 0; + +// hSc = OpenService(hSCManager, ServiceName, SERVICE_QUERY_STATUS); /* determine required buffer size */ if (! EnumServicesStatusEx(hSCManager, @@ -147,8 +148,7 @@ INT EnumServices(DWORD ServiceType, DWORD ServiceState) VOID -PrintService(ENUM_SERVICE_STATUS_PROCESS *pServiceStatus, - BOOL bExtended) +PrintService(BOOL bExtended) { _tprintf(_T("SERVICE_NAME: %s\n"), pServiceStatus->lpServiceName); _tprintf(_T("DISPLAY_NAME: %s\n"), pServiceStatus->lpDisplayName); diff --git a/reactos/subsys/system/sc/sc.c b/reactos/subsys/system/sc/sc.c index 551460e6efc..a82231f43ee 100644 --- a/reactos/subsys/system/sc/sc.c +++ b/reactos/subsys/system/sc/sc.c @@ -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) { @@ -61,66 +67,66 @@ INT ScControl(LPTSTR MachineName, LPCTSTR Command, TCHAR **Args) return -1; } - + /* emurate command */ if (_tcsicmp(Command, _T("query")) == 0) - Query(Args, FALSE); + Query(ServiceName, ServiceArgs, FALSE); else if (_tcsicmp(Command, _T("queryex")) == 0) - Query(Args, TRUE); + Query(ServiceName, ServiceArgs, TRUE); else if (_tcsicmp(Command, _T("start")) == 0) { - if (*Args) - Start(0, Args); + if (ServiceName) + Start(ServiceName, ServiceArgs, ArgCount); else StartUsage(); } else if (_tcsicmp(Command, _T("pause")) == 0) { - if (*Args) - Control(SERVICE_CONTROL_PAUSE, Args); + if (ServiceName) + Control(SERVICE_CONTROL_PAUSE, ServiceName, ServiceArgs); else PauseUsage(); } else if (_tcsicmp(Command, _T("interrogate")) == 0) { - if (*Args) - Control(SERVICE_CONTROL_INTERROGATE, Args); + if (ServiceName) + Control(SERVICE_CONTROL_INTERROGATE, ServiceName, ServiceArgs); else InterrogateUsage(); } else if (_tcsicmp(Command, _T("stop")) == 0) { - if (*Args) - Control(SERVICE_CONTROL_STOP, Args); + if (ServiceName) + Control(SERVICE_CONTROL_STOP, ServiceName, ServiceArgs); else StopUsage(); } else if (_tcsicmp(Command, _T("continue")) == 0) { - if (*Args) - Control(SERVICE_CONTROL_CONTINUE, Args); + if (ServiceName) + Control(SERVICE_CONTROL_CONTINUE, ServiceName, ServiceArgs); else ContinueUsage(); } else if (_tcsicmp(Command, _T("delete")) == 0) { - if (*Args) - Delete(Args); + if (ServiceName) + Delete(ServiceName); else DeleteUsage(); } else if (_tcsicmp(Command, _T("create")) == 0) { - if (*Args) - Create(Args); + if (*ServiceArgs) + Create(ServiceName, ServiceArgs); else CreateUsage(); } else if (_tcsicmp(Command, _T("control")) == 0) { - if (*Args) - Control((DWORD)NULL, ++Args); + if (ServiceName) + Control((DWORD)NULL, ServiceName, ServiceArgs); else ContinueUsage(); } @@ -130,10 +136,9 @@ INT ScControl(LPTSTR MachineName, LPCTSTR Command, TCHAR **Args) int _tmain(DWORD argc, LPCTSTR argv[]) { - LPTSTR MachineName = NULL; // remote machine - LPCTSTR Command = argv[1]; // sc command - TCHAR **Args = NULL; // rest of args - + LPTSTR MachineName = NULL; // remote machine + LPCTSTR Command = NULL; // sc command + LPCTSTR ServiceName = NULL; // Name of service if (argc < 2) return MainUsage(); @@ -146,13 +151,16 @@ int _tmain(DWORD argc, LPCTSTR argv[]) _tcscpy(MachineName, argv[1]); Command = argv[2]; - Args = (TCHAR **)&argv[3]; - return ScControl(MachineName, Command, Args); + if (argc > 3) + ServiceName = argv[3]; + return ScControl(MachineName, Command, ServiceName, &argv[4], argc); } else { - Args = (TCHAR **)&argv[2]; - return ScControl(MachineName, Command, Args); + Command = argv[1]; + if (argc > 2) + ServiceName = argv[2]; + return ScControl(MachineName, Command, ServiceName, &argv[3], argc); } return MainUsage(); diff --git a/reactos/subsys/system/sc/sc.h b/reactos/subsys/system/sc/sc.h index 5320b2aafb2..43c7fd2be68 100644 --- a/reactos/subsys/system/sc/sc.h +++ b/reactos/subsys/system/sc/sc.h @@ -7,11 +7,11 @@ extern SC_HANDLE hSCManager; // declared in sc.c //#define DBG /* control functions */ -BOOL Query(TCHAR **Args, BOOL bExtended); -BOOL Start(INT ArgCount, TCHAR **Args); -BOOL Create(TCHAR **Args); -BOOL Delete(TCHAR **Args); -BOOL Control(DWORD Control, TCHAR **Args); +BOOL Query(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, BOOL bExtended); +BOOL Start(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, INT ArgCount); +BOOL Create(LPCTSTR ServiceName, LPCTSTR *ServiceArgs); +BOOL Delete(LPCTSTR ServiceName); +BOOL Control(DWORD Control, LPCTSTR ServiceName, LPCTSTR *Args); /* print and error functions */ DWORD ReportLastError(VOID); @@ -25,3 +25,5 @@ INT ContinueUsage(VOID); INT StopUsage(VOID); INT ConfigUsage(VOID); INT DescriptionUsage(VOID); +INT DeleteUsage(VOID); +INT CreateUsage(VOID); diff --git a/reactos/subsys/system/sc/start.c b/reactos/subsys/system/sc/start.c index f945dcd1fae..0ad094df89e 100644 --- a/reactos/subsys/system/sc/start.c +++ b/reactos/subsys/system/sc/start.c @@ -11,14 +11,11 @@ #include "sc.h" -BOOL Start(INT ArgCount, TCHAR **Args) +BOOL Start(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, INT ArgCount) { SC_HANDLE hSc; SERVICE_STATUS_PROCESS ServiceStatus; - LPCTSTR ServiceName = *Args++; - LPCTSTR *ServiceArgs = (LPCTSTR *)Args; DWORD BytesNeeded; - /* testing */ _tprintf(_T("service to start - %s\n\n"), ServiceName); @@ -28,8 +25,7 @@ BOOL Start(INT ArgCount, TCHAR **Args) printf("%s\n", *ServiceArgs); ServiceArgs++; } - if (! *ServiceArgs) - ServiceArgs = NULL; + /* get a handle to the service requested for starting */ hSc = OpenService(hSCManager, ServiceName, SERVICE_ALL_ACCESS); diff --git a/reactos/subsys/system/sc/usage.c b/reactos/subsys/system/sc/usage.c index a5d7b0861a2..b92cd069119 100644 --- a/reactos/subsys/system/sc/usage.c +++ b/reactos/subsys/system/sc/usage.c @@ -142,13 +142,25 @@ INT DeleteUsage(VOID) INT CreateUsage(VOID) { - _tprintf(_T("DESCRIPTION:\n") - _T("Creates a service entry in the registry and Service Database.\n") - _T(" If the service is running, or another process has an\n") - _T(" open handle to the service, the service is simply marked\n") - _T(" for deletion.\n") - _T("USAGE:\n") - _T(" sc delete [service name]\n")); + _tprintf(_T("Creates a service entry in the registry and Service Database.\n") + _T("SYNTAX:\n") + _T("sc create [service name] [binPath= ] ...\n") + _T("CREATE OPTIONS:\n") + _T("NOTE: The option name includes the equal sign.\n") + _T(" type= \n") + _T(" (default = own)\n") + _T(" start= \n") + _T(" (default = demand)\n") + _T(" error= \n") + _T(" (default = normal)\n") + _T(" binPath= \n") + _T(" group= \n") + _T(" tag= \n") + _T(" depend= \n") + _T(" obj= \n") + _T(" (default = LocalSystem)\n") + _T(" DisplayName= \n") + _T(" password= \n")); return 0; } -- 2.17.1