Author: gedmurphy Date: Fri Sep 1 20:55:36 2006 New Revision: 23868
URL: http://svn.reactos.org/svn/reactos?rev=23868&view=rev Log: - Use a more generic print service - don't assign a service name at the start as it causes problems when query(ex) doesn't supply one. - Simplify the service starting code. - Add missing options to the print type - rewrite the querying functionality to be cleaner, and use existing code. - remove the braces I left, used for collapsing dbg info
Modified: trunk/reactos/base/applications/sc/control.c trunk/reactos/base/applications/sc/create.c trunk/reactos/base/applications/sc/delete.c trunk/reactos/base/applications/sc/print.c trunk/reactos/base/applications/sc/query.c trunk/reactos/base/applications/sc/sc.c trunk/reactos/base/applications/sc/sc.h trunk/reactos/base/applications/sc/start.c trunk/reactos/base/applications/sc/usage.c
Modified: trunk/reactos/base/applications/sc/control.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/contro... ============================================================================== --- trunk/reactos/base/applications/sc/control.c (original) +++ trunk/reactos/base/applications/sc/control.c Fri Sep 1 20:55:36 2006 @@ -21,7 +21,6 @@ DWORD dwDesiredAccess = 0;
#ifdef SCDBG -{ LPCTSTR *TmpArgs = Args; INT TmpCnt = ArgCount; _tprintf(_T("service to control - %s\n"), ServiceName); @@ -34,7 +33,6 @@ TmpCnt--; } _tprintf(_T("\n")); -} #endif /* SCDBG */
switch (Control) @@ -75,8 +73,16 @@ Control, &Status)) { + SERVICE_STATUS_PROCESS StatusEx; + + /* FIXME: lazy hack ;) */ + CopyMemory(&StatusEx, &Status, sizeof(Status)); + StatusEx.dwProcessId = 0; + StatusEx.dwServiceFlags = 0; + PrintService(ServiceName, - &Status); + &StatusEx, + FALSE);
CloseServiceHandle(hSc); CloseServiceHandle(hSCManager);
Modified: trunk/reactos/base/applications/sc/create.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/create... ============================================================================== --- trunk/reactos/base/applications/sc/create.c (original) +++ trunk/reactos/base/applications/sc/create.c Fri Sep 1 20:55:36 2006 @@ -29,7 +29,6 @@ lpBinaryPathName = *ServiceArgs;
#ifdef SCDBG -{ _tprintf(_T("service name - %s\n"), ServiceName); _tprintf(_T("display name - %s\n"), ServiceName); _tprintf(_T("service type - %lu\n"), dwServiceType); @@ -41,7 +40,6 @@ _tprintf(_T("dependincies - %s\n"), lpDependencies); _tprintf(_T("account start name - %s\n"), lpServiceStartName); _tprintf(_T("account password - %s\n"), lpPassword); -} #endif
if (!ServiceName)
Modified: trunk/reactos/base/applications/sc/delete.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/delete... ============================================================================== --- trunk/reactos/base/applications/sc/delete.c (original) +++ trunk/reactos/base/applications/sc/delete.c Fri Sep 1 20:55:36 2006 @@ -15,9 +15,7 @@ SC_HANDLE hSc = NULL;
#ifdef SCDBG -{ _tprintf(_T("service to delete - %s\n\n"), ServiceName); -} #endif
hSCManager = OpenSCManager(NULL,
Modified: trunk/reactos/base/applications/sc/print.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/print.... ============================================================================== --- trunk/reactos/base/applications/sc/print.c (original) +++ trunk/reactos/base/applications/sc/print.c Fri Sep 1 20:55:36 2006 @@ -1,28 +1,19 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/system/sc/print.c + * PURPOSE: print service info + * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy gedmurphy@gmail.com + * + */ + #include "sc.h"
VOID -PrintServiceEx(LPCTSTR lpServiceName, - LPSERVICE_STATUS_PROCESS pStatusEx) -{ - SERVICE_STATUS Status; - - /*FIXME: quick hack, assign values 1 by 1 */ - CopyMemory(&Status, pStatusEx, sizeof(SERVICE_STATUS)); - - PrintService(lpServiceName, - &Status); - - _tprintf(_T("\tPID : %lu\n"), - pStatusEx->dwProcessId); - _tprintf(_T("\tFLAGS : %lu\n"), - pStatusEx->dwServiceFlags); -} - - -VOID PrintService(LPCTSTR lpServiceName, - LPSERVICE_STATUS pStatus) + LPSERVICE_STATUS_PROCESS pStatus, + BOOL bExtended) { _tprintf(_T("SERVICE_NAME: %s\n"), lpServiceName);
@@ -30,10 +21,30 @@ (unsigned int)pStatus->dwServiceType); switch (pStatus->dwServiceType) { - case 1 : _tprintf(_T("KERNEL_DRIVER\n")); break; - case 2 : _tprintf(_T("FILE_SYSTEM_DRIVER\n")); break; - case 16 : _tprintf(_T("WIN32_OWN_PROCESS\n")); break; - case 32 : _tprintf(_T("WIN32_SHARE_PROCESS\n")); break; + case SERVICE_KERNEL_DRIVER: + _tprintf(_T("KERNEL_DRIVER\n")); + break; + + case SERVICE_FILE_SYSTEM_DRIVER: + _tprintf(_T("FILE_SYSTEM_DRIVER\n")); + break; + + case SERVICE_WIN32_OWN_PROCESS: + _tprintf(_T("WIN32_OWN_PROCESS\n")); + break; + + case SERVICE_WIN32_SHARE_PROCESS: + _tprintf(_T("WIN32_SHARE_PROCESS\n")); + break; + + case SERVICE_WIN32_OWN_PROCESS + SERVICE_INTERACTIVE_PROCESS: + _tprintf(_T("WIN32_OWN_PROCESS (interactive)\n")); + break; + + case SERVICE_WIN32_SHARE_PROCESS + SERVICE_INTERACTIVE_PROCESS: + _tprintf(_T("WIN32_SHARE_PROCESS (interactive)\n")); + break; + default : _tprintf(_T("\n")); break; }
@@ -65,7 +76,7 @@ _tprintf(_T("NOT_PAUSABLE,"));
if (pStatus->dwControlsAccepted & SERVICE_ACCEPT_SHUTDOWN) - _tprintf(_T("???")); + _tprintf(_T("ACCEPTS_SHUTDOWN")); else _tprintf(_T("IGNORES_SHUTDOWN"));
@@ -81,4 +92,14 @@ (unsigned int)pStatus->dwCheckPoint); _tprintf(_T("\tWAIT_HINT : 0x%x\n"), (unsigned int)pStatus->dwWaitHint); + + if (bExtended) + { + _tprintf(_T("\tPID : %lu\n"), + pStatus->dwProcessId); + _tprintf(_T("\tFLAGS : %lu\n"), + pStatus->dwServiceFlags); + } + + _tprintf(_T("\n")); }
Modified: trunk/reactos/base/applications/sc/query.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/query.... ============================================================================== --- trunk/reactos/base/applications/sc/query.c (original) +++ trunk/reactos/base/applications/sc/query.c Fri Sep 1 20:55:36 2006 @@ -1,11 +1,9 @@ /* - * 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 + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/system/sc/query.c + * PURPOSE: queries service info + * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy gedmurphy@gmail.com * */ /* @@ -16,82 +14,20 @@
#include "sc.h"
-/* local function decs */ -VOID PrintService2(BOOL bExtended); -BOOL EnumServices(DWORD ServiceType, DWORD ServiceState); -BOOL QueryService(LPCTSTR ServiceName, BOOL bExtended); - -/* global variables */ -static ENUM_SERVICE_STATUS_PROCESS *pServiceStatus = NULL; -DWORD NumServices = 0; - - -BOOL -Query(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, BOOL bExtended) -{ - if (! ServiceName) /* display all running services and drivers */ - { - /* get default values */ - EnumServices(SERVICE_WIN32, SERVICE_ACTIVE); - - /* print default values */ - PrintService2(bExtended); - } - else if (_tcsicmp(ServiceName, _T("type=")) == 0) - { - LPCTSTR Type = *ServiceArgs; - - if (_tcsicmp(Type, _T("driver")) == 0) - EnumServices(SERVICE_DRIVER, SERVICE_ACTIVE); - else if (_tcsicmp(Type, _T("service")) == 0) - EnumServices(SERVICE_WIN32, SERVICE_ACTIVE); - else if (_tcsicmp(Type, _T("all")) == 0) - EnumServices(SERVICE_DRIVER|SERVICE_WIN32, SERVICE_ACTIVE); - else - { - _tprintf(_T("\nERROR following "type="!\n")); - _tprintf(_T("Must be "driver" or "service" or "all"\n")); - } - - PrintService2(bExtended); - } - else if(_tcsicmp(ServiceName, _T("state=")) == 0) - { - LPCTSTR State = *ServiceArgs; - - if (_tcsicmp(State, _T("inactive")) == 0) - EnumServices(SERVICE_WIN32, SERVICE_INACTIVE); - else if (_tcsicmp(State, _T("all")) == 0) - EnumServices(SERVICE_WIN32, SERVICE_STATE_ALL); - else - { - _tprintf(_T("\nERROR following "state="!\n")); - _tprintf(_T("Must be "active" or "inactive" or "all"\n")); - } - - PrintService2(bExtended); - } -/* - else if(_tcsicmp(ServiceName, _T("bufsize="))) - - else if(_tcsicmp(ServiceName, _T("ri="))) - - else if(_tcsicmp(ServiceName, _T("group="))) -*/ - else /* print only the service requested */ - { - QueryService(ServiceName, bExtended); - } - - return TRUE; -} - - -BOOL -QueryService(LPCTSTR ServiceName, BOOL bExtended) +LPTSTR QueryOpts[] = { + _T("type="), + _T("state="), + _T("bufsize="), + _T("ri="), + _T("group="), +}; + + +LPSERVICE_STATUS_PROCESS +QueryService(LPCTSTR ServiceName) { SC_HANDLE hSCManager; - SERVICE_STATUS_PROCESS *pServiceInfo = NULL; + LPSERVICE_STATUS_PROCESS pServiceInfo = NULL; SC_HANDLE hSc; DWORD BufSiz = 0; DWORD BytesNeeded = 0; @@ -103,120 +39,59 @@ if (hSCManager == NULL) { ReportLastError(); - return FALSE; - } - - hSc = OpenService(hSCManager, ServiceName, SERVICE_QUERY_STATUS); - + return NULL; + } + + hSc = OpenService(hSCManager, + ServiceName, + SERVICE_QUERY_STATUS); if (hSc == NULL) - { - _tprintf(_T("QueryService: openService failed\n")); - ReportLastError(); - return FALSE; - } + goto fail;
Ret = QueryServiceStatusEx(hSc, - SC_STATUS_PROCESS_INFO, - NULL, - BufSiz, - &BytesNeeded); - + SC_STATUS_PROCESS_INFO, + NULL, + BufSiz, + &BytesNeeded); if ((Ret != 0) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) - { - _tprintf(_T("QueryService: First call to QueryServiceStatusEx failed : ")); - ReportLastError(); - return FALSE; - } - else /* Call function again if required size was returned */ - { - /* reserve memory for service info array */ - pServiceInfo = (SERVICE_STATUS_PROCESS *) - HeapAlloc(GetProcessHeap(), 0, BytesNeeded); - if (pServiceInfo == NULL) - { - _tprintf(_T("QueryService: Failed to allocate memory : ")); - ReportLastError(); - return FALSE; - } - - /* fill array with service info */ - if (! QueryServiceStatusEx(hSc, - SC_STATUS_PROCESS_INFO, - (LPBYTE)pServiceInfo, - BytesNeeded, - &BytesNeeded)) - { - _tprintf(_T("QueryService: Second call to QueryServiceStatusEx failed : ")); - ReportLastError(); - HeapFree(GetProcessHeap(), 0, pServiceInfo); - return FALSE; - } - } - - - _tprintf(_T("SERVICE_NAME: %s\n"), ServiceName); - - _tprintf(_T("\tTYPE : %x "), - (unsigned int)pServiceInfo->dwServiceType); - switch (pServiceInfo->dwServiceType) - { - case 1 : _tprintf(_T("KERNEL_DRIVER\n")); break; - case 2 : _tprintf(_T("FILE_SYSTEM_DRIVER\n")); break; - case 16 : _tprintf(_T("WIN32_OWN_PROCESS\n")); break; - case 32 : _tprintf(_T("WIN32_SHARE_PROCESS\n")); break; - default : _tprintf(_T("\n")); break; - } - - _tprintf(_T("\tSTATE : %x "), - (unsigned int)pServiceInfo->dwCurrentState); - - switch (pServiceInfo->dwCurrentState) - { - case 1 : _tprintf(_T("STOPPED\n")); break; - case 2 : _tprintf(_T("START_PENDING\n")); break; - case 3 : _tprintf(_T("STOP_PENDING\n")); break; - case 4 : _tprintf(_T("RUNNING\n")); break; - case 5 : _tprintf(_T("CONTINUE_PENDING\n")); break; - case 6 : _tprintf(_T("PAUSE_PENDING\n")); break; - case 7 : _tprintf(_T("PAUSED\n")); break; - default : _tprintf(_T("\n")); break; - } - -// _tprintf(_T("\n\taccepted : 0x%x\n\n"), -// pServiceStatus[i].ServiceStatusProcess.dwControlsAccepted); -// (STOPPABLE,NOT_PAUSABLE,ACCEPTS_SHUTDOWN) - - _tprintf(_T("\tWIN32_EXIT_CODE : %d (0x%x)\n"), - (unsigned int)pServiceInfo->dwWin32ExitCode, - (unsigned int)pServiceInfo->dwWin32ExitCode); - _tprintf(_T("\tSERVICE_EXIT_CODE : %d (0x%x)\n"), - (unsigned int)pServiceInfo->dwServiceSpecificExitCode, - (unsigned int)pServiceInfo->dwServiceSpecificExitCode); - _tprintf(_T("\tCHECKPOINT : 0x%x\n"), - (unsigned int)pServiceInfo->dwCheckPoint); - _tprintf(_T("\tWAIT_HINT : 0x%x\n"), - (unsigned int)pServiceInfo->dwWaitHint); - if (bExtended) - { - _tprintf(_T("\tPID : %lu\n"), - pServiceInfo->dwProcessId); - _tprintf(_T("\tFLAGS : %lu\n"), - pServiceInfo->dwServiceFlags); - } - - HeapFree(GetProcessHeap(), 0, pServiceInfo); - - return TRUE; + goto fail; + + pServiceInfo = (LPSERVICE_STATUS_PROCESS)HeapAlloc(GetProcessHeap(), + 0, + BytesNeeded); + if (pServiceInfo == NULL) + goto fail; + + if (!QueryServiceStatusEx(hSc, + SC_STATUS_PROCESS_INFO, + (LPBYTE)pServiceInfo, + BytesNeeded, + &BytesNeeded)) + { + goto fail; + } + + return pServiceInfo; + +fail: + ReportLastError(); + if (pServiceInfo) HeapFree(GetProcessHeap(), 0, pServiceInfo); + if (hSc) CloseServiceHandle(hSc); + if (hSCManager) CloseServiceHandle(hSCManager); + return NULL; }
-BOOL -EnumServices(DWORD ServiceType, DWORD ServiceState) +static BOOL +EnumServices(ENUM_SERVICE_STATUS_PROCESS **pServiceStatus, + DWORD ServiceType, + DWORD ServiceState) { SC_HANDLE hSCManager; DWORD BufSize = 0; DWORD BytesNeeded = 0; DWORD ResumeHandle = 0; + DWORD NumServices = 0; DWORD Ret;
hSCManager = OpenSCManager(NULL, @@ -228,120 +103,146 @@ return FALSE; }
- /* determine required buffer size */ Ret = EnumServicesStatusEx(hSCManager, - SC_ENUM_PROCESS_INFO, - ServiceType, - ServiceState, - (LPBYTE)pServiceStatus, - BufSize, - &BytesNeeded, - &NumServices, - &ResumeHandle, - 0); - - if ((Ret != 0) && (GetLastError() != ERROR_MORE_DATA)) - { - _tprintf(_T("EnumServices: First call to EnumServicesStatusEx failed : ")); - ReportLastError(); + SC_ENUM_PROCESS_INFO, + ServiceType, + ServiceState, + (LPBYTE)*pServiceStatus, + BufSize, + &BytesNeeded, + &NumServices, + &ResumeHandle, + 0); + + if ((Ret == 0) && (GetLastError() == ERROR_MORE_DATA)) + { + *pServiceStatus = (ENUM_SERVICE_STATUS_PROCESS *) + HeapAlloc(GetProcessHeap(), + 0, + BytesNeeded); + if (*pServiceStatus != NULL) + { + if (EnumServicesStatusEx(hSCManager, + SC_ENUM_PROCESS_INFO, + ServiceType, + ServiceState, + (LPBYTE)*pServiceStatus, + BytesNeeded, + &BytesNeeded, + &NumServices, + &ResumeHandle, + 0)) + { + return NumServices; + } + } + } + + ReportLastError(); + if (pServiceStatus) + HeapFree(GetProcessHeap(), 0, *pServiceStatus); + + return NumServices; +} + + +BOOL +Query(LPCTSTR *ServiceArgs, + DWORD ArgCount, + BOOL bExtended) +{ + LPENUM_SERVICE_STATUS_PROCESS pServiceStatus = NULL; + DWORD NumServices = 0; + //DWORD ServiceType; + //DWORD ServiceState; + BOOL bServiceName = TRUE; + DWORD OptSize, i; + + LPCTSTR *TmpArgs; + INT TmpCnt; + +#ifdef SCDBG + TmpArgs = ServiceArgs; + TmpCnt = ArgCount; + _tprintf(_T("Arguments:\n")); + while (TmpCnt) + { + _tprintf(_T(" %s\n"), *TmpArgs); + TmpArgs++; + TmpCnt--; + } + _tprintf(_T("\n")); +#endif /* SCDBG */ + + /* display all running services and drivers */ + if (ArgCount == 0) + { + NumServices = EnumServices(&pServiceStatus, + SERVICE_WIN32, + SERVICE_ACTIVE); + + if (NumServices != 0) + { + for (i=0; i < NumServices; i++) + { + PrintService(pServiceStatus[i].lpServiceName, + &pServiceStatus[i].ServiceStatusProcess, + bExtended); + } + + _tprintf(_T("number : %lu\n"), NumServices); + + if (pServiceStatus) + HeapFree(GetProcessHeap(), 0, pServiceStatus); + + return TRUE; + } + return FALSE; } - else /* Call function again if required size was returned */ - { - /* reserve memory for service info array */ - pServiceStatus = (ENUM_SERVICE_STATUS_PROCESS *) - HeapAlloc(GetProcessHeap(), 0, BytesNeeded); - if (pServiceStatus == NULL) - { - _tprintf(_T("EnumServices: Failed to allocate memory : ")); - ReportLastError(); - return FALSE; - } - - /* fill array with service info */ - if (! EnumServicesStatusEx(hSCManager, - SC_ENUM_PROCESS_INFO, - ServiceType, - ServiceState, - (LPBYTE)pServiceStatus, - BytesNeeded, - &BytesNeeded, - &NumServices, - &ResumeHandle, - 0)) - { - _tprintf(_T("EnumServices: Second call to EnumServicesStatusEx failed : ")); - ReportLastError(); - HeapFree(GetProcessHeap(), 0, pServiceStatus); - return FALSE; - } - } + + TmpArgs = ServiceArgs; + TmpCnt = ArgCount; + OptSize = sizeof(QueryOpts) / sizeof(QueryOpts[0]); + while (TmpCnt--) + { + for (i=0; i < OptSize; i++) + { + if (!lstrcmpi(*TmpArgs, QueryOpts[i])) + { + bServiceName = FALSE; + } + } + *TmpArgs++; + } + + + /* FIXME: parse options */ + + + /* print only the service requested */ + if (bServiceName) + { + LPSERVICE_STATUS_PROCESS pStatus; + LPCTSTR ServiceName = *ServiceArgs; + + pStatus = QueryService(ServiceName); + if (bExtended) + { + PrintService(ServiceName, + pStatus, + TRUE); + } + else + { + PrintService(ServiceName, + pStatus, + FALSE); + } + } + + if (pServiceStatus) + HeapFree(GetProcessHeap(), 0, pServiceStatus);
return TRUE; } - - -VOID -PrintService2(BOOL bExtended) -{ - DWORD i; - - for (i=0; i < NumServices; i++) - { - - _tprintf(_T("SERVICE_NAME: %s\n"), pServiceStatus[i].lpServiceName); - _tprintf(_T("DISPLAY_NAME: %s\n"), pServiceStatus[i].lpDisplayName); - - _tprintf(_T("\tTYPE : %x "), - (unsigned int)pServiceStatus[i].ServiceStatusProcess.dwServiceType); - switch (pServiceStatus[i].ServiceStatusProcess.dwServiceType) - { - case 1 : _tprintf(_T("KERNEL_DRIVER\n")); break; - case 2 : _tprintf(_T("FILE_SYSTEM_DRIVER\n")); break; - case 16 : _tprintf(_T("WIN32_OWN_PROCESS\n")); break; - case 32 : _tprintf(_T("WIN32_SHARE_PROCESS\n")); break; - default : _tprintf(_T("\n")); break; - } - - _tprintf(_T("\tSTATE : %x "), - (unsigned int)pServiceStatus[i].ServiceStatusProcess.dwCurrentState); - - switch (pServiceStatus[i].ServiceStatusProcess.dwCurrentState) - { - case 1 : _tprintf(_T("STOPPED\n")); break; - case 2 : _tprintf(_T("START_PENDING\n")); break; - case 3 : _tprintf(_T("STOP_PENDING\n")); break; - case 4 : _tprintf(_T("RUNNING\n")); break; - case 5 : _tprintf(_T("CONTINUE_PENDING\n")); break; - case 6 : _tprintf(_T("PAUSE_PENDING\n")); break; - case 7 : _tprintf(_T("PAUSED\n")); break; - default : _tprintf(_T("\n")); break; - } - - // _tprintf(_T("\n\taccepted : 0x%x\n\n"), - // pServiceStatus[i].ServiceStatusProcess.dwControlsAccepted); - // (STOPPABLE,NOT_PAUSABLE,ACCEPTS_SHUTDOWN) - - _tprintf(_T("\tWIN32_EXIT_CODE : %d (0x%x)\n"), - (unsigned int)pServiceStatus[i].ServiceStatusProcess.dwWin32ExitCode, - (unsigned int)pServiceStatus[i].ServiceStatusProcess.dwWin32ExitCode); - _tprintf(_T("\tSERVICE_EXIT_CODE : %d (0x%x)\n"), - (unsigned int)pServiceStatus[i].ServiceStatusProcess.dwServiceSpecificExitCode, - (unsigned int)pServiceStatus[i].ServiceStatusProcess.dwServiceSpecificExitCode); - _tprintf(_T("\tCHECKPOINT : 0x%x\n"), - (unsigned int)pServiceStatus[i].ServiceStatusProcess.dwCheckPoint); - _tprintf(_T("\tWAIT_HINT : 0x%x\n"), - (unsigned int)pServiceStatus[i].ServiceStatusProcess.dwWaitHint); - if (bExtended) - { - _tprintf(_T("\tPID : %lu\n"), - pServiceStatus[i].ServiceStatusProcess.dwProcessId); - _tprintf(_T("\tFLAGS : %lu\n"), - pServiceStatus[i].ServiceStatusProcess.dwServiceFlags); - } - - _tprintf(_T("\n")); - } - - _tprintf(_T("number : %lu\n"), NumServices); -}
Modified: trunk/reactos/base/applications/sc/sc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/sc.c?r... ============================================================================== --- trunk/reactos/base/applications/sc/sc.c (original) +++ trunk/reactos/base/applications/sc/sc.c Fri Sep 1 20:55:36 2006 @@ -42,10 +42,11 @@ static INT ScControl(LPCTSTR Server, // remote machine name LPCTSTR Command, // sc command - LPCTSTR ServiceName, // name of service LPCTSTR *ServiceArgs, // any options DWORD ArgCount) // argument counter { + LPCTSTR ServiceName = NULL; + if (Server) { _tprintf(_T("Remote service control is not yet implemented\n")); @@ -54,18 +55,21 @@
if (!lstrcmpi(Command, _T("query"))) { - Query(ServiceName, - ServiceArgs, + Query(ServiceArgs, + ArgCount, FALSE); } else if (!lstrcmpi(Command, _T("queryex"))) { - Query(ServiceName, - ServiceArgs, + Query(ServiceArgs, + ArgCount, TRUE); } else if (!lstrcmpi(Command, _T("start"))) { + ServiceName = *ServiceArgs++; + ArgCount--; + if (ServiceName) { Start(ServiceName, @@ -77,6 +81,9 @@ } else if (!lstrcmpi(Command, _T("pause"))) { + ServiceName = *ServiceArgs++; + ArgCount--; + if (ServiceName) { Control(SERVICE_CONTROL_PAUSE, @@ -89,6 +96,9 @@ } else if (!lstrcmpi(Command, _T("interrogate"))) { + ServiceName = *ServiceArgs++; + ArgCount--; + if (ServiceName) { Control(SERVICE_CONTROL_INTERROGATE, @@ -101,6 +111,9 @@ } else if (!lstrcmpi(Command, _T("stop"))) { + ServiceName = *ServiceArgs++; + ArgCount--; + if (ServiceName) { Control(SERVICE_CONTROL_STOP, @@ -113,6 +126,9 @@ } else if (!lstrcmpi(Command, _T("continue"))) { + ServiceName = *ServiceArgs++; + ArgCount--; + if (ServiceName) { Control(SERVICE_CONTROL_CONTINUE, @@ -125,6 +141,9 @@ } else if (!lstrcmpi(Command, _T("delete"))) { + ServiceName = *ServiceArgs++; + ArgCount--; + if (ServiceName) Delete(ServiceName); else @@ -132,6 +151,9 @@ } else if (!lstrcmpi(Command, _T("create"))) { + ServiceName = *ServiceArgs++; + ArgCount--; + if (*ServiceArgs) Create(ServiceName, ServiceArgs); @@ -141,6 +163,9 @@ else if (!lstrcmpi(Command, _T("control"))) { INT CtlValue; + + ServiceName = *ServiceArgs++; + ArgCount--;
CtlValue = _ttoi(ServiceArgs[0]); ServiceArgs++; @@ -170,9 +195,9 @@
int _tmain(int argc, LPCTSTR argv[]) { - LPCTSTR Server = NULL; // remote machine - LPCTSTR Command = NULL; // sc command - LPCTSTR ServiceName = NULL; // name of service + LPCTSTR Server = NULL; // remote machine + LPCTSTR Command = NULL; // sc command + LPCTSTR *Args = NULL; // Any remaining args
if (argc < 2) { @@ -192,25 +217,23 @@ Server = argv[1]; Command = argv[2]; if (argc > 3) - ServiceName = argv[3]; + Args = &argv[3];
return ScControl(Server, Command, - ServiceName, - &argv[4], - argc-4); + Args, + argc-3); } else { Command = argv[1]; if (argc > 2) - ServiceName = argv[2]; + Args = &argv[2];
return ScControl(Server, Command, - ServiceName, - &argv[3], - argc-3); + Args, + argc-2); } }
Modified: trunk/reactos/base/applications/sc/sc.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/sc.h?r... ============================================================================== --- trunk/reactos/base/applications/sc/sc.h (original) +++ trunk/reactos/base/applications/sc/sc.h Fri Sep 1 20:55:36 2006 @@ -3,19 +3,19 @@ #include <stdio.h> #include <tchar.h>
-//#define SCDBG - -VOID PrintService(LPCTSTR ServiceName, LPSERVICE_STATUS pStatus); -VOID PrintServiceEx(LPCTSTR ServiceName, LPSERVICE_STATUS_PROCESS pStatus); +#define SCDBG
/* control functions */ -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, INT ArgCount); +BOOL Query(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended); + +LPSERVICE_STATUS_PROCESS QueryService(LPCTSTR ServiceName);
/* print and error functions */ +VOID PrintService(LPCTSTR ServiceName, LPSERVICE_STATUS_PROCESS pStatus, BOOL bExtended); VOID ReportLastError(VOID);
/* usage functions */
Modified: trunk/reactos/base/applications/sc/start.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/start.... ============================================================================== --- trunk/reactos/base/applications/sc/start.c (original) +++ trunk/reactos/base/applications/sc/start.c Fri Sep 1 20:55:36 2006 @@ -11,15 +11,11 @@
BOOL Start(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, INT ArgCount) { - SC_HANDLE hSCManager = NULL; - SC_HANDLE hSc = NULL; + SC_HANDLE hSCManager; + SC_HANDLE hSc; LPSERVICE_STATUS_PROCESS pServiceInfo = NULL; - DWORD BufSiz = 0; - DWORD BytesNeeded = 0; - DWORD Ret;
#ifdef SCDBG -{ LPCTSTR *TmpArgs = ServiceArgs; INT TmpCnt = ArgCount; _tprintf(_T("service to control - %s\n"), ServiceName); @@ -31,24 +27,23 @@ TmpCnt--; } _tprintf(_T("\n")); -} #endif /* SCDBG */
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSCManager == NULL) - goto fail; + { + ReportLastError(); + return FALSE; + }
hSc = OpenService(hSCManager, ServiceName, SERVICE_START | SERVICE_QUERY_STATUS);
if (hSc == NULL) - { - _tprintf(_T("openService failed\n")); goto fail; - }
if (! StartService(hSc, ArgCount, @@ -58,32 +53,13 @@ goto fail; }
- Ret = QueryServiceStatusEx(hSc, - SC_STATUS_PROCESS_INFO, - NULL, - BufSiz, - &BytesNeeded); - if ((Ret != 0) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) //FIXME: check this - goto fail; - - - pServiceInfo = (LPSERVICE_STATUS_PROCESS)HeapAlloc(GetProcessHeap(), - 0, - BytesNeeded); - if (pServiceInfo == NULL) - goto fail; - - if (!QueryServiceStatusEx(hSc, - SC_STATUS_PROCESS_INFO, - (LPBYTE)pServiceInfo, - BytesNeeded, - &BytesNeeded)) + pServiceInfo = QueryService(ServiceName); + if (pServiceInfo != NULL) { - goto fail; + PrintService(ServiceName, + pServiceInfo, + TRUE); } - - PrintServiceEx(ServiceName, - pServiceInfo);
HeapFree(GetProcessHeap(), 0, pServiceInfo); CloseServiceHandle(hSc);
Modified: trunk/reactos/base/applications/sc/usage.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/usage.... ============================================================================== --- trunk/reactos/base/applications/sc/usage.c (original) +++ trunk/reactos/base/applications/sc/usage.c Fri Sep 1 20:55:36 2006 @@ -1,11 +1,9 @@ /* - * 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 + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/system/sc/usage.c + * PURPOSE: display usage info + * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy gedmurphy@gmail.com * */ #include "sc.h" @@ -26,7 +24,7 @@ _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 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") @@ -63,7 +61,7 @@ _T(" for that service is returned. Further options do not apply in\n") _T(" this case. If the query command is followed by nothing or one of\n") _T(" the options listed below, the services are enumerated.\n") - _T(" type= Type of services to enumerate (driver, service, all)\n") + _T(" type= Type of services to enumerate (driver, service, interact, all)\n") _T(" (default = service)\n") _T(" state= State of services to enumerate (inactive, all)\n") _T(" (default = active)\n") @@ -85,8 +83,8 @@ // _T("sc query bufsize= 50 - Enumerates with a 50 byte buffer.\n") // _T("sc query ri= 14 - Enumerates with resume index = 14\n") // _T("sc queryex group= "" - Enumerates active services not in a group\n") - _T("sc query type= service type= interact - Enumerates all interactive services\n")); -// _T("sc query type= driver group= NDIS - Enumerates all NDIS drivers\n")); + _T("sc query type= service type= interact - Enumerates all interactive services\n") + _T("sc query type= driver group= NDIS - Enumerates all NDIS drivers\n")); } }