From 3dd0798703d1146ff4331b942214a148939d3d36 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Wed, 2 Nov 2005 21:10:50 +0000 Subject: [PATCH] - Split files - start to implement 'start' - split and rewrite much of the 'query' functionality - a lot of code "altering" Comments are a bit vauge, but it's still very incomplete and untested and most changes aren't worth mentioning. svn path=/trunk/; revision=18958 --- reactos/subsys/system/sc/control.c | 45 +++++++ reactos/subsys/system/sc/create.c | 57 +++++++++ reactos/subsys/system/sc/delete.c | 40 ++++++ reactos/subsys/system/sc/manage.c | 121 ------------------ reactos/subsys/system/sc/query.c | 198 +++++++++++++++++++---------- reactos/subsys/system/sc/sc.c | 107 +++++++++------- reactos/subsys/system/sc/sc.h | 22 ++-- reactos/subsys/system/sc/start.c | 101 +++++++++++++++ reactos/subsys/system/sc/usage.c | 174 +++++++++++++++---------- 9 files changed, 560 insertions(+), 305 deletions(-) create mode 100644 reactos/subsys/system/sc/control.c create mode 100644 reactos/subsys/system/sc/create.c create mode 100644 reactos/subsys/system/sc/delete.c delete mode 100644 reactos/subsys/system/sc/manage.c create mode 100644 reactos/subsys/system/sc/start.c diff --git a/reactos/subsys/system/sc/control.c b/reactos/subsys/system/sc/control.c new file mode 100644 index 00000000000..c2fbfd0f053 --- /dev/null +++ b/reactos/subsys/system/sc/control.c @@ -0,0 +1,45 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS SC utility + * FILE: subsys/system/sc/control.c + * PURPOSE: control ReactOS services + * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com) + * REVISIONS: + * Ged Murphy 20/10/05 Created + * + */ + +#include "sc.h" + +/* + * handles the following commands: + * control, continue, interrogate, pause, stop + */ + +BOOL Control(DWORD Control, TCHAR **Args) +{ + SC_HANDLE hSc; + SERVICE_STATUS Status; + LPCTSTR ServiceName = *Args; + + + hSc = OpenService(hSCManager, ServiceName, DELETE); + + if (hSc == NULL) + { + _tprintf(_T("openService failed\n")); + ReportLastError(); + return FALSE; + } + + if (! ControlService(hSc, Control, &Status)) + { + _tprintf(_T("controlService failed\n")); + ReportLastError(); + return FALSE; + } + + CloseServiceHandle(hSc); + return TRUE; + +} diff --git a/reactos/subsys/system/sc/create.c b/reactos/subsys/system/sc/create.c new file mode 100644 index 00000000000..f9ee00f5d61 --- /dev/null +++ b/reactos/subsys/system/sc/create.c @@ -0,0 +1,57 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS SC utility + * FILE: subsys/system/sc/create.c + * PURPOSE: control ReactOS services + * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com) + * REVISIONS: + * Ged Murphy 20/10/05 Created + * + */ + +#include "sc.h" + +BOOL Create(TCHAR **Args) +{ + SC_HANDLE hSc; + LPCTSTR ServiceName = *Args; + LPCTSTR BinaryPathName = *++Args; + LPCTSTR *Options = (LPCTSTR *)++Args; + + /* testing */ + printf("service to create - %s\n", ServiceName); + printf("Binary path - %s\n", BinaryPathName); + printf("Arguments :\n"); + while (*Options) + { + printf("%s\n", *Options); + Options++; + } + + + hSc = CreateService(hSCManager, + ServiceName, + ServiceName, + SERVICE_ALL_ACCESS, + SERVICE_WIN32_OWN_PROCESS, + SERVICE_DEMAND_START, + SERVICE_ERROR_NORMAL, + BinaryPathName, + NULL, + NULL, + NULL, + NULL, + NULL); + + if (hSc == NULL) + { + _tprintf(_T("CreateService failed\n")); + ReportLastError(); + return FALSE; + } + else + { + CloseServiceHandle(hSc); + return TRUE; + } +} diff --git a/reactos/subsys/system/sc/delete.c b/reactos/subsys/system/sc/delete.c new file mode 100644 index 00000000000..f81c986a07e --- /dev/null +++ b/reactos/subsys/system/sc/delete.c @@ -0,0 +1,40 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS SC utility + * FILE: subsys/system/sc/delete.c + * PURPOSE: control ReactOS services + * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com) + * REVISIONS: + * Ged Murphy 20/10/05 Created + * + */ + +#include "sc.h" + +BOOL Delete(TCHAR **Args) +{ + SC_HANDLE hSc; + LPCTSTR ServiceName = *Args; + + /* testing */ + printf("service to delete - %s\n\n", ServiceName); + + hSc = OpenService(hSCManager, ServiceName, DELETE); + + if (hSc == NULL) + { + _tprintf(_T("openService failed\n")); + ReportLastError(); + return FALSE; + } + + if (! DeleteService(hSc)) + { + _tprintf(_T("DeleteService failed\n")); + ReportLastError(); + return FALSE; + } + + CloseServiceHandle(hSc); + return TRUE; +} diff --git a/reactos/subsys/system/sc/manage.c b/reactos/subsys/system/sc/manage.c deleted file mode 100644 index 51d60639813..00000000000 --- a/reactos/subsys/system/sc/manage.c +++ /dev/null @@ -1,121 +0,0 @@ -#include "sc.h" - -extern SC_HANDLE hSCManager; // declared in sc.c - -BOOL Start(INT ArgCount, TCHAR **Args) -{ - SC_HANDLE hSc; - LPCTSTR ServiceName = *Args++; - LPCTSTR *ServiceArgs = &*Args; - - hSc = OpenService(hSCManager, ServiceName, SERVICE_ALL_ACCESS); - - if (hSc == NULL) - { - dprintf("openService failed\n"); - ReportLastError(); - return FALSE; - } - - if (! StartService(hSc, ArgCount, ServiceArgs)) - { - dprintf("DeleteService failed\n"); - ReportLastError(); - return FALSE; - } - - CloseServiceHandle(hSc); - return TRUE; - -} - - -BOOL Create(TCHAR **Args) -{ - SC_HANDLE hSc; - LPCTSTR Name = *Args; - LPCTSTR BinaryPathName = *++Args; - - - hSc = CreateService(hSCManager, - Name, - Name, - SERVICE_ALL_ACCESS, - SERVICE_WIN32_OWN_PROCESS, - SERVICE_DEMAND_START, - SERVICE_ERROR_NORMAL, - BinaryPathName, - NULL, - NULL, - NULL, - NULL, - NULL); - - if (hSc == NULL) - { - dprintf("CreateService failed (%d)\n"); - ReportLastError(); - return FALSE; - } - else - { - CloseServiceHandle(hSc); - return TRUE; - } -} - -BOOL Delete(TCHAR **Args) -{ - SC_HANDLE hSc; - LPCTSTR ServiceName = *Args; - - hSc = OpenService(hSCManager, ServiceName, DELETE); - - if (hSc == NULL) - { - dprintf("openService failed\n"); - ReportLastError(); - return FALSE; - } - - if (! DeleteService(hSc)) - { - dprintf("DeleteService failed\n"); - ReportLastError(); - return FALSE; - } - - CloseServiceHandle(hSc); - return TRUE; -} - - -BOOL Control(DWORD Control, TCHAR **Args) -{ - SC_HANDLE hSc; - SERVICE_STATUS Status; - LPCTSTR ServiceName = *Args; - - - hSc = OpenService(hSCManager, ServiceName, DELETE); - - if (hSc == NULL) - { - dprintf("openService failed\n"); - ReportLastError(); - return FALSE; - } - - if (! ControlService(hSc, Control, &Status)) - { - dprintf("controlService failed\n"); - ReportLastError(); - return FALSE; - } - - CloseServiceHandle(hSc); - return TRUE; - -} - - diff --git a/reactos/subsys/system/sc/query.c b/reactos/subsys/system/sc/query.c index c9ea1ac8388..8ddf7430518 100644 --- a/reactos/subsys/system/sc/query.c +++ b/reactos/subsys/system/sc/query.c @@ -1,45 +1,111 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS SC utility + * FILE: subsys/system/sc/query.c + * PURPOSE: control ReactOS services + * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com) + * REVISIONS: + * Ged Murphy 20/10/05 Created + * + */ + #include "sc.h" -extern SC_HANDLE hSCManager; /* declared in sc.c */ +/* local function decs */ +VOID PrintService(ENUM_SERVICE_STATUS_PROCESS *pSStatus, BOOL bExtended); +INT EnumServices(DWORD ServiceType, DWORD ServiceState); + +/* global variables */ +static ENUM_SERVICE_STATUS_PROCESS *pServiceStatus = NULL; BOOL Query(TCHAR **Args, BOOL bExtended) { - SC_HANDLE hSc; - ENUM_SERVICE_STATUS_PROCESS *pServiceStatus = NULL; - DWORD BufSize = 0; - DWORD BytesNeeded; - DWORD NumServices; - DWORD ResumeHandle; - INT i; + + LPCTSTR ServiceName = *Args; - /* determine required buffer size */ - EnumServicesStatusEx(hSCManager, - SC_ENUM_PROCESS_INFO, - SERVICE_DRIVER | SERVICE_WIN32, - SERVICE_STATE_ALL, - (LPBYTE)pServiceStatus, - BufSize, - &BytesNeeded, - &NumServices, - &ResumeHandle, - 0); - - /* exit on failure */ - if (GetLastError() != ERROR_MORE_DATA) + if (! *Args) { - ReportLastError(); - return FALSE; + printf("Service name %s\n", ServiceName); // test + + /* get default values */ + EnumServices(SERVICE_WIN32, SERVICE_ACTIVE); + + /* print default values */ + PrintService(pServiceStatus, bExtended); } - /* reserve memory for service info array */ - pServiceStatus = (ENUM_SERVICE_STATUS_PROCESS *) malloc(BytesNeeded); + if (_tcsicmp(Args[0], _T("type=")) == 0) + { + TCHAR *Type = *++Args; + _tprintf(_T("got type\narg = %s\n"), Type); // test + if (_tcsicmp(Type, _T("driver")) == 0) + EnumServices(SERVICE_DRIVER, SERVICE_STATE_ALL); + else if (_tcsicmp(Type, _T("service")) == 0) + EnumServices(SERVICE_WIN32, SERVICE_STATE_ALL); + else if (_tcsicmp(Type, _T("all")) == 0) + EnumServices(SERVICE_DRIVER|SERVICE_WIN32, SERVICE_STATE_ALL); + else + { + _tprintf(_T("\nERROR following \"type=\"!\n")); + _tprintf(_T("Must be \"driver\" or \"service\" or \"all\"\n")); + } + + PrintService(pServiceStatus, bExtended); + } + else if(_tcsicmp(Args[0], _T("state=")) == 0) + { + TCHAR *State = *++Args; - /* fill array with service info */ + if (_tcsicmp(State, _T("active")) == 0) + EnumServices(SERVICE_DRIVER|SERVICE_WIN32, SERVICE_ACTIVE); + else if (_tcsicmp(State, _T("inactive")) == 0) + EnumServices(SERVICE_DRIVER|SERVICE_WIN32, SERVICE_INACTIVE); + else if (_tcsicmp(State, _T("all")) == 0) + EnumServices(SERVICE_DRIVER|SERVICE_WIN32, SERVICE_STATE_ALL); + else + { + _tprintf(_T("\nERROR following \"state=\"!\n")); + _tprintf(_T("Must be \"active\" or \"inactive\" or \"all\"\n")); + } + + PrintService(pServiceStatus, bExtended); + } + else + { + printf("no args\n"); // test + /* get default values */ + EnumServices(SERVICE_WIN32, SERVICE_ACTIVE); + + /* print default values */ + PrintService(pServiceStatus, bExtended); + } + +/* + else if(_tcsicmp(Args[0], _T("bufsize="))) + + else if(_tcsicmp(Args[0], _T("ri="))) + + else if(_tcsicmp(Args[0], _T("group="))) +*/ + + +} + + +INT EnumServices(DWORD ServiceType, DWORD ServiceState) +{ + SC_HANDLE hSc; + DWORD BufSize = 0; + DWORD BytesNeeded = 0; + DWORD NumServices = 0; + DWORD ResumeHandle = 0; + + /* determine required buffer size */ if (! EnumServicesStatusEx(hSCManager, SC_ENUM_PROCESS_INFO, - SERVICE_DRIVER | SERVICE_WIN32, - SERVICE_STATE_ALL, + ServiceType, + ServiceState, (LPBYTE)pServiceStatus, BufSize, &BytesNeeded, @@ -47,34 +113,36 @@ Query(TCHAR **Args, BOOL bExtended) &ResumeHandle, 0)) { - dprintf("Call to EnumServicesStatusEx failed : "); - ReportLastError(); - return FALSE; - } -/* - for (i=0; idwServiceType == SERVICE_WIN32 && - pServiceStatus[i]->dwServiceState == SERVICE_ACTIVE) - PrintService(pServiceStatus[i], bExtended); - continue; + /* reserve memory for service info array */ + pServiceStatus = (ENUM_SERVICE_STATUS_PROCESS *) malloc(BytesNeeded); + + /* fill array with service info */ + if (! EnumServicesStatusEx(hSCManager, + SC_ENUM_PROCESS_INFO, + SERVICE_DRIVER | SERVICE_WIN32, + SERVICE_STATE_ALL, + (LPBYTE)pServiceStatus, + BufSize, + &BytesNeeded, + &NumServices, + &ResumeHandle, + 0)) + { + _tprintf(_T("Second call to EnumServicesStatusEx failed : ")); + ReportLastError(); + return FALSE; + } } - - if(_tcsicmp(Args[0], _T("type=")) - - else if(_tcsicmp(Args[0], _T("state=")) - - else if(_tcsicmp(Args[0], _T("bufsize=")) - - else if(_tcsicmp(Args[0], _T("ri=")) - - else if(_tcsicmp(Args[0], _T("group=")) - -*/ - - + else /* exit on failure */ + { + _tprintf(_T("First call to EnumServicesStatusEx failed : ")); + ReportLastError(); + return FALSE; + } + } } @@ -82,26 +150,26 @@ VOID PrintService(ENUM_SERVICE_STATUS_PROCESS *pServiceStatus, BOOL bExtended) { - dprintf("SERVICE_NAME: %s\n", pServiceStatus->lpServiceName); - dprintf("DISPLAY_NAME: %s\n", pServiceStatus->lpDisplayName); - dprintf("TYPE : %lu\n", + _tprintf(_T("SERVICE_NAME: %s\n"), pServiceStatus->lpServiceName); + _tprintf(_T("DISPLAY_NAME: %s\n"), pServiceStatus->lpDisplayName); + _tprintf(_T("TYPE : %lu\n"), pServiceStatus->ServiceStatusProcess.dwServiceType); - dprintf("STATE : %lu\n", + _tprintf(_T("STATE : %lu\n"), pServiceStatus->ServiceStatusProcess.dwCurrentState); // (STOPPABLE,NOT_PAUSABLE,ACCEPTS_SHUTDOWN) - dprintf("WIN32_EXIT_CODE : %lu \n", + _tprintf(_T("WIN32_EXIT_CODE : %lu \n"), pServiceStatus->ServiceStatusProcess.dwWin32ExitCode); - dprintf("SERVICE_EXIT_CODE : %lu \n", + _tprintf(_T("SERVICE_EXIT_CODE : %lu \n"), pServiceStatus->ServiceStatusProcess.dwServiceSpecificExitCode); - dprintf("CHECKPOINT : %lu\n", + _tprintf(_T("CHECKPOINT : %lu\n"), pServiceStatus->ServiceStatusProcess.dwCheckPoint); - dprintf("WAIT_HINT : %lu\n", + _tprintf(_T("WAIT_HINT : %lu\n"), pServiceStatus->ServiceStatusProcess.dwWaitHint); if (bExtended) { - dprintf("PID : %lu\n", + _tprintf(_T("PID : %lu\n"), pServiceStatus->ServiceStatusProcess.dwProcessId); - dprintf("FLAGS : %lu\n", + _tprintf(_T("FLAGS : %lu\n"), pServiceStatus->ServiceStatusProcess.dwServiceFlags); } } diff --git a/reactos/subsys/system/sc/sc.c b/reactos/subsys/system/sc/sc.c index dd44f5cbf8f..7dfac1fc615 100644 --- a/reactos/subsys/system/sc/sc.c +++ b/reactos/subsys/system/sc/sc.c @@ -1,21 +1,18 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS SC utility + * FILE: subsys/system/sc/sc.c + * PURPOSE: control ReactOS services + * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com) + * REVISIONS: + * Ged Murphy 20/10/05 Created + * + */ + #include "sc.h" -HANDLE OutputHandle; -HANDLE InputHandle; - SC_HANDLE hSCManager; -VOID dprintf(TCHAR* fmt, ...) -{ - va_list args; - char buffer[255]; - - va_start(args, fmt); - wvsprintfA(buffer, fmt, args); - WriteConsole(OutputHandle, buffer, lstrlenA(buffer), NULL, NULL); - va_end(args); -} - DWORD ReportLastError(VOID) { LPVOID lpMsgBuf; @@ -52,18 +49,18 @@ INT ScControl(LPTSTR MachineName, LPCTSTR Command, TCHAR **Args) if (MachineName) { - dprintf("Remote service control is not yet implemented\n"); + _tprintf(_T("Remote service control is not yet implemented\n")); return 2; } - +/* hSCManager = OpenSCManager(MachineName, NULL, SC_MANAGER_ALL_ACCESS); if (hSCManager == NULL) { - dprintf("[SC] OpenSCManager FAILED \n"); + _tprintf(_T("[SC] OpenSCManager FAILED %d:\n\n"), GetLastError()); ReportLastError(); return -1; } - +*/ if (_tcsicmp(Command, _T("query")) == 0) Query(Args, FALSE); @@ -73,46 +70,70 @@ INT ScControl(LPTSTR MachineName, LPCTSTR Command, TCHAR **Args) else if (_tcsicmp(Command, _T("start")) == 0) { - /*if (! **Args) - StartUsage(); + if (*Args) + Start(3, Args); else - Start(Args);*/ + StartUsage(); } else if (_tcsicmp(Command, _T("pause")) == 0) - Control(SERVICE_CONTROL_PAUSE, ++Args); - + { + if (*Args) + Control(SERVICE_CONTROL_PAUSE, Args); + else + PauseUsage(); + } else if (_tcsicmp(Command, _T("interrogate")) == 0) - Control(SERVICE_CONTROL_INTERROGATE, ++Args); - - else if (_tcsicmp(Command, _T("interrogate")) == 0) - Control(SERVICE_CONTROL_INTERROGATE, ++Args); - + { + if (*Args) + Control(SERVICE_CONTROL_INTERROGATE, Args); + else + InterrogateUsage(); + } + else if (_tcsicmp(Command, _T("stop")) == 0) + { + if (*Args) + Control(SERVICE_CONTROL_STOP, Args); + else + StopUsage(); + } else if (_tcsicmp(Command, _T("continue")) == 0) - Control(SERVICE_CONTROL_CONTINUE, ++Args); - + { + if (*Args) + Control(SERVICE_CONTROL_CONTINUE, Args); + else + ContinueUsage(); + } else if (_tcsicmp(Command, _T("delete")) == 0) - Delete(Args); - + { + if (*Args) + Delete(Args); + else + DeleteUsage(); + } else if (_tcsicmp(Command, _T("create")) == 0) - Create(Args); - + { + if (*Args) + Create(Args); + else + CreateUsage(); + } else if (_tcsicmp(Command, _T("control")) == 0) - Control((DWORD)NULL, Args); - + { + if (*Args) + Control((DWORD)NULL, ++Args); + else + ContinueUsage(); + } return 0; } -int main(int argc, char* argv[]) +int _tmain(DWORD argc, LPCTSTR argv[]) { LPTSTR MachineName = NULL; // remote machine LPCTSTR Command = argv[1]; // sc command TCHAR **Args = NULL; // rest of args - /* initialize standard input / output and get handles */ - AllocConsole(); - InputHandle = GetStdHandle(STD_INPUT_HANDLE); - OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE); if (argc < 2) return MainUsage(); @@ -125,12 +146,12 @@ int main(int argc, char* argv[]) _tcscpy(MachineName, argv[1]); Command = argv[2]; - Args = &argv[3]; + Args = (TCHAR **)&argv[3]; return ScControl(MachineName, Command, Args); } else { - Args = &argv[2]; + Args = (TCHAR **)&argv[2]; return ScControl(MachineName, Command, Args); } diff --git a/reactos/subsys/system/sc/sc.h b/reactos/subsys/system/sc/sc.h index c88a05b12c9..5320b2aafb2 100644 --- a/reactos/subsys/system/sc/sc.h +++ b/reactos/subsys/system/sc/sc.h @@ -2,9 +2,21 @@ #include #include -DWORD ReportLastError(VOID); -VOID dprintf(TCHAR* fmt, ...); +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); + +/* print and error functions */ +DWORD ReportLastError(VOID); + +/* usage functions */ INT MainUsage(VOID); INT StartUsage(VOID); INT PauseUsage(VOID); @@ -13,9 +25,3 @@ INT ContinueUsage(VOID); INT StopUsage(VOID); INT ConfigUsage(VOID); INT DescriptionUsage(VOID); - -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); diff --git a/reactos/subsys/system/sc/start.c b/reactos/subsys/system/sc/start.c new file mode 100644 index 00000000000..6e00c130114 --- /dev/null +++ b/reactos/subsys/system/sc/start.c @@ -0,0 +1,101 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS SC utility + * FILE: subsys/system/sc/start.c + * PURPOSE: control ReactOS services + * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com) + * REVISIONS: + * Ged Murphy 20/10/05 Created + * + */ + +#include "sc.h" + +BOOL Start(INT ArgCount, TCHAR **Args) +{ + SC_HANDLE hSc; + SERVICE_STATUS_PROCESS ServiceStatus; + LPCTSTR ServiceName = *Args++; + LPCTSTR *ServiceArgs = (LPCTSTR *)Args; + DWORD BytesNeeded; + + + /* testing */ + printf("service to start - %s\n\n", ServiceName); + printf("Arguments :\n"); + while (*ServiceArgs) + { + printf("%s\n", *ServiceArgs); + ServiceArgs++; + } + + /* get a handle to the service requested for starting */ + hSc = OpenService(hSCManager, ServiceName, SERVICE_ALL_ACCESS); + + if (hSc == NULL) + { + _tprintf(_T("openService failed\n")); + ReportLastError(); + return FALSE; + } + + /* start the service opened */ + if (! StartService(hSc, ArgCount, ServiceArgs)) + { + _tprintf(_T("StartService failed\n")); + ReportLastError(); + return FALSE; + } + + if (! QueryServiceStatusEx( + hSc, + SC_STATUS_PROCESS_INFO, + (LPBYTE)&ServiceStatus, + sizeof(SERVICE_STATUS_PROCESS), + &BytesNeeded)) + { + _tprintf(_T("QueryServiceStatusEx 1 failed\n")); + ReportLastError(); + return FALSE; + } + + + while (ServiceStatus.dwCurrentState == SERVICE_START_PENDING) + { + /* wait before checking status */ + Sleep(ServiceStatus.dwWaitHint); + + /* check status again */ + if (! QueryServiceStatusEx( + hSc, + SC_STATUS_PROCESS_INFO, + (LPBYTE)&ServiceStatus, + sizeof(SERVICE_STATUS_PROCESS), + &BytesNeeded)) + { + _tprintf(_T("QueryServiceStatusEx 2 failed\n")); + ReportLastError(); + return FALSE; + } + } + + CloseServiceHandle(hSc); + + if (ServiceStatus.dwCurrentState == SERVICE_RUNNING) + { + _tprintf(_T("%s is running\n"), ServiceName); + return TRUE; + } + else + { + _tprintf(_T("Failed to start %s\n"), ServiceName); + _tprintf(_T("Curent state: %lu\n"), ServiceStatus.dwCurrentState); + _tprintf(_T("Exit code: %lu\n"), ServiceStatus.dwWin32ExitCode); + _tprintf(_T("Service Specific exit code: %lu\n"), + ServiceStatus.dwServiceSpecificExitCode); + _tprintf(_T("Check point: %lu\n"), ServiceStatus.dwCheckPoint); + _tprintf(_T("Wait hint: %lu\n"), ServiceStatus.dwWaitHint); + + return FALSE; + } +} diff --git a/reactos/subsys/system/sc/usage.c b/reactos/subsys/system/sc/usage.c index f4d61a4d15d..a5d7b0861a2 100644 --- a/reactos/subsys/system/sc/usage.c +++ b/reactos/subsys/system/sc/usage.c @@ -1,45 +1,56 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS SC utility + * FILE: subsys/system/sc/usage.c + * PURPOSE: control ReactOS services + * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com) + * REVISIONS: + * Ged Murphy 20/10/05 Created + * + */ + #include "sc.h" INT MainUsage(VOID) { - dprintf("DESCRIPTION:\n"); - dprintf("\tSC is a command line program used for communicating with\n"); - dprintf("\tthe Service Control Manager and its services.\n"); - dprintf("USAGE:\n"); - dprintf("\tsc [command] [service name] ...\n"); + _tprintf(_T("DESCRIPTION:\n") + _T("\tSC is a command line program used for communicating with\n") + _T("\tthe Service Control Manager and its services.\n") + _T("USAGE:\n") + _T("\tsc [command] [service name] ...\n") - dprintf("\tThe optional parameter has the form \"\\ServerName\"\n"); - dprintf("\tFurther help on commands can be obtained by typing: \"sc [command]\"\n"); - dprintf("\tService Commands:\n"); - dprintf("\t query : Queries the status for a service, or\n"); - dprintf("\t enumerates the status for types of services.\n"); - dprintf("\t queryex : Queries the extended status for a service, or\n"); -// dprintf("\t enumerates the status for types of services.\n"); - dprintf("\t start : Starts a service.\n"); - dprintf("\t pause : Sends a PAUSE control request to a service.\n"); - dprintf("\t interrogate : Sends a INTERROGATE control request to a service.\n"); -// dprintf("\t continue : Sends a CONTINUE control request to a service.\n"); - dprintf("\t stop : Sends a STOP request to a service.\n"); -// dprintf("\t config : Changes the configuration of a service (persistant).\n"); -// dprintf("\t description : Changes the description of a service.\n"); -// dprintf("\t failure : Changes the actions taken by a service upon failure.\n"); -// dprintf("\t qc : Queries the configuration information for a service.\n"); -// dprintf("\t qdescription : Queries the description for a service.\n"); -// dprintf("\t qfailure : Queries the actions taken by a service upon failure.\n"); - dprintf("\t delete : Deletes a service (from the registry).\n"); - dprintf("\t create : Creates a service. (adds it to the registry).\n"); - dprintf("\t control : Sends a control to a service.\n"); -// dprintf("\t sdshow : Displays a service's security descriptor.\n"); -// dprintf("\t sdset : Sets a service's security descriptor.\n"); -// dprintf("\t GetDisplayName : Gets the DisplayName for a service.\n"); -// dprintf("\t GetKeyName : Gets the ServiceKeyName for a service.\n"); -// dprintf("\t EnumDepend : Enumerates Service Dependencies.\n"); -// dprintf("\n"); -// dprintf("\tService Name Independant Commands:\n"); -// dprintf("\t boot : (ok | bad) Indicates whether the last boot should\n"); -// dprintf("\t be saved as the last-known-good boot configuration\n"); -// dprintf("\t Lock : Locks the SCM Database\n"); -// dprintf("\t QueryLock : Queries the LockStatus for the SCM Database\n"); + _T("\tThe optional parameter has the form \"\\ServerName\"\n") + _T("\tFurther help on commands can be obtained by typing: \"sc [command]\"\n") + _T("\tService Commands:\n") + _T("\t query : Queries the status for a service, or\n") + _T("\t enumerates the status for types of services.\n") + _T("\t queryex : Queries the extended status for a service, or\n") +// _T("\t enumerates the status for types of services.\n" + _T("\t start : Starts a service.\n") + _T("\t pause : Sends a PAUSE control request to a service.\n") + _T("\t interrogate : Sends a INTERROGATE control request to a service.\n") + _T("\t continue : Sends a CONTINUE control request to a service.\n") + _T("\t stop : Sends a STOP request to a service.\n") +// "\t config : Changes the configuration of a service (persistant).\n" +// "\t description : Changes the description of a service.\n" +// "\t failure : Changes the actions taken by a service upon failure.\n" +// "\t qc : Queries the configuration information for a service.\n" +// "\t qdescription : Queries the description for a service.\n" +// "\t qfailure : Queries the actions taken by a service upon failure.\n" + _T("\t delete : Deletes a service (from the registry).\n") + _T("\t create : Creates a service. (adds it to the registry).\n") + _T("\t control : Sends a control to a service.\n")); +// "\t sdshow : Displays a service's security descriptor.\n") +// "\t sdset : Sets a service's security descriptor.\n") +// "\t GetDisplayName : Gets the DisplayName for a service.\n") +// "\t GetKeyName : Gets the ServiceKeyName for a service.\n") +// "\t EnumDepend : Enumerates Service Dependencies.\n") +// "\n") +// "\tService Name Independant Commands:\n") +// "\t boot : (ok | bad) Indicates whether the last boot should\n") +// "\t be saved as the last-known-good boot configuration\n") +// "\t Lock : Locks the SCM Database\n") +// "\t QueryLock : Queries the LockStatus for the SCM Database\n") return 0; } @@ -47,10 +58,10 @@ INT MainUsage(VOID) INT StartUsage(VOID) { - dprintf("DESCRIPTION:\n"); - dprintf(" Starts a service running.\n"); - dprintf("USAGE:\n"); - dprintf(" sc start [service name] ...\n"); + _tprintf(_T("DESCRIPTION:\n") + _T(" Starts a service running.\n") + _T("USAGE:\n") + _T(" sc start [service name] ...\n")); return 0; } @@ -58,48 +69,49 @@ INT StartUsage(VOID) INT PauseUsage(VOID) { - dprintf("DESCRIPTION:\n"); - dprintf(" Sends a PAUSE control request to a service.\n"); - dprintf("USAGE:\n"); - dprintf(" sc pause [service name]\n"); + _tprintf(_T("DESCRIPTION:\n") + _T(" Sends a PAUSE control request to a service.\n") + _T("USAGE:\n") + _T(" sc pause [service name]\n")); return 0; } INT InterrogateUsage(VOID) { - dprintf("DESCRIPTION:\n"); - dprintf(" Sends an INTERROGATE control request to a service.\n"); - dprintf("USAGE:\n"); - dprintf(" sc interrogate [service name]\n"); + _tprintf(_T("DESCRIPTION:\n") + _T(" Sends an INTERROGATE control request to a service.\n") + _T("USAGE:\n") + _T(" sc interrogate [service name]\n")); return 0; } -INT ContinueUsage(VOID) -{ - dprintf("DESCRIPTION:\n"); - dprintf(" Sends an CONTINUE control request to a service.\n"); - dprintf("USAGE:\n"); - dprintf(" sc continue [service name]\n"); - - return 0; -} - INT StopUsage(VOID) { - dprintf("DESCRIPTION:\n"); - dprintf(" Sends an STOP control request to a service.\n"); - dprintf("USAGE:\n"); - dprintf(" sc stop [service name]\n"); + _tprintf(_T("DESCRIPTION:\n") + _T(" Sends an STOP control request to a service.\n") + _T("USAGE:\n") + _T(" sc stop [service name]\n")); return 0; } +INT ContinueUsage(VOID) +{ + _tprintf(_T("DESCRIPTION:\n") + _T(" Sends an CONTINUE control request to a service.\n") + _T("USAGE:\n") + _T(" sc continue [service name]\n")); + + return 0; +} + + INT ConfigUsage(VOID) { - dprintf("not yet implemented\n"); + _tprintf(_T("not yet implemented\n")); return 0; } @@ -107,10 +119,36 @@ INT ConfigUsage(VOID) INT DescriptionUsage(VOID) { - dprintf("DESCRIPTION:\n"); - dprintf(" Sets the description string for a service.\n"); - dprintf("USAGE:\n"); - dprintf(" sc description [service name]\n"); + _tprintf(_T("DESCRIPTION:\n") + _T(" Sets the description string for a service.\n") + _T("USAGE:\n") + _T(" sc description [service name]\n")); + + return 0; +} + +INT DeleteUsage(VOID) +{ + _tprintf(_T("DESCRIPTION:\n") + _T(" Deletes a service entry from the registry.\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")); + + return 0; +} + +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")); return 0; }