Author: ekohl Date: Mon Jun 13 19:43:02 2016 New Revision: 71633
URL: http://svn.reactos.org/svn/reactos?rev=71633&view=rev Log: [SC] - Move ParseCreateArguments to the misc.c file, rename it to ParseCreateConfigArguments and tweak it for use in the config command. - Implement the config command.
Added: trunk/reactos/base/applications/sc/config.c (with props) trunk/reactos/base/applications/sc/misc.c (with props) Modified: trunk/reactos/base/applications/sc/CMakeLists.txt trunk/reactos/base/applications/sc/create.c trunk/reactos/base/applications/sc/sc.c trunk/reactos/base/applications/sc/sc.h trunk/reactos/base/applications/sc/usage.c
Modified: trunk/reactos/base/applications/sc/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/CMakeL... ============================================================================== --- trunk/reactos/base/applications/sc/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/base/applications/sc/CMakeLists.txt [iso-8859-1] Mon Jun 13 19:43:02 2016 @@ -2,10 +2,12 @@ add_definitions(-DDEFINE_GUID)
list(APPEND SOURCE + config.c control.c create.c delete.c description.c + misc.c print.c qc.c qfailure.c
Added: trunk/reactos/base/applications/sc/config.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/config... ============================================================================== --- trunk/reactos/base/applications/sc/config.c (added) +++ trunk/reactos/base/applications/sc/config.c [iso-8859-1] Mon Jun 13 19:43:02 2016 @@ -0,0 +1,89 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/sc/config.c + * PURPOSE: Set the service configuration + * COPYRIGHT: Copyright 2016 Eric Kohl + * + */ + +#include "sc.h" + +BOOL SetConfig(LPCTSTR *ServiceArgs, INT ArgCount) +{ + SC_HANDLE hManager = NULL; + SC_HANDLE hService = NULL; + BOOL bResult = TRUE; + SERVICE_CREATE_INFO ServiceInfo; + + if (!ParseCreateConfigArguments(ServiceArgs, ArgCount, TRUE, &ServiceInfo)) + { + SetConfigUsage(); + return FALSE; + } + +#ifdef SCDBG + _tprintf(_T("service name - %s\n"), ServiceInfo.lpServiceName); + _tprintf(_T("display name - %s\n"), ServiceInfo.lpDisplayName); + _tprintf(_T("service type - %lu\n"), ServiceInfo.dwServiceType); + _tprintf(_T("start type - %lu\n"), ServiceInfo.dwStartType); + _tprintf(_T("error control - %lu\n"), ServiceInfo.dwErrorControl); + _tprintf(_T("Binary path - %s\n"), ServiceInfo.lpBinaryPathName); + _tprintf(_T("load order group - %s\n"), ServiceInfo.lpLoadOrderGroup); + _tprintf(_T("tag - %lu\n"), ServiceInfo.dwTagId); + _tprintf(_T("dependencies - %s\n"), ServiceInfo.lpDependencies); + _tprintf(_T("account start name - %s\n"), ServiceInfo.lpServiceStartName); + _tprintf(_T("account password - %s\n"), ServiceInfo.lpPassword); +#endif + + hManager = OpenSCManager(NULL, + NULL, + SC_MANAGER_CONNECT); + if (hManager == NULL) + { + _tprintf(_T("[SC] OpenSCManager FAILED %lu:\n\n"), GetLastError()); + bResult = FALSE; + goto done; + } + + hService = OpenService(hManager, + ServiceInfo.lpServiceName, + SERVICE_CHANGE_CONFIG); + if (hService == NULL) + { + _tprintf(_T("[SC] OpenService FAILED %lu:\n\n"), GetLastError()); + bResult = FALSE; + goto done; + } + + if (!ChangeServiceConfig(hService, + ServiceInfo.dwServiceType, + ServiceInfo.dwStartType, + ServiceInfo.dwErrorControl, + ServiceInfo.lpBinaryPathName, + ServiceInfo.lpLoadOrderGroup, + ServiceInfo.bTagId ? &ServiceInfo.dwTagId : NULL, + ServiceInfo.lpDependencies, + ServiceInfo.lpServiceStartName, + ServiceInfo.lpPassword, + ServiceInfo.lpDisplayName)) + { + _tprintf(_T("[SC] ChangeServiceConfig FAILED %lu:\n\n"), GetLastError()); + bResult = FALSE; + goto done; + } + + _tprintf(_T("[SC] ChangeServiceConfig SUCCESS\n\n")); + +done: + if (bResult == FALSE) + ReportLastError(); + + if (hService) + CloseServiceHandle(hService); + + if (hManager) + CloseServiceHandle(hManager); + + return bResult; +}
Propchange: trunk/reactos/base/applications/sc/config.c ------------------------------------------------------------------------------ svn:eol-style = native
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 [iso-8859-1] (original) +++ trunk/reactos/base/applications/sc/create.c [iso-8859-1] Mon Jun 13 19:43:02 2016 @@ -10,163 +10,6 @@
#include "sc.h"
-typedef struct -{ - LPCTSTR lpOption; - DWORD dwValue; -} OPTION_INFO; - -typedef struct -{ - LPCTSTR lpServiceName; - LPCTSTR lpDisplayName; - DWORD dwServiceType; - DWORD dwStartType; - DWORD dwErrorControl; - LPCTSTR lpBinaryPathName; - LPCTSTR lpLoadOrderGroup; - DWORD dwTagId; - LPCTSTR lpDependencies; - LPCTSTR lpServiceStartName; - LPCTSTR lpPassword; - - BOOL bTagId; -} SERVICE_CREATE_INFO, *LPSERVICE_CREATE_INFO; - - -static const OPTION_INFO TypeOpts[] = -{ - { _T("own"), SERVICE_WIN32_OWN_PROCESS }, - { _T("share"), SERVICE_WIN32_SHARE_PROCESS }, - { _T("interact"), SERVICE_INTERACTIVE_PROCESS }, - { _T("kernel"), SERVICE_KERNEL_DRIVER }, - { _T("filesys"), SERVICE_FILE_SYSTEM_DRIVER }, - { _T("rec"), SERVICE_RECOGNIZER_DRIVER } -}; - -static const OPTION_INFO StartOpts[] = -{ - { _T("boot"), SERVICE_BOOT_START }, - { _T("system"), SERVICE_SYSTEM_START }, - { _T("auto"), SERVICE_AUTO_START }, - { _T("demand"), SERVICE_DEMAND_START }, - { _T("disabled"), SERVICE_DISABLED } -}; - -static const OPTION_INFO ErrorOpts[] = -{ - { _T("normal"), SERVICE_ERROR_NORMAL }, - { _T("severe"), SERVICE_ERROR_SEVERE }, - { _T("critical"), SERVICE_ERROR_CRITICAL }, - { _T("ignore"), SERVICE_ERROR_IGNORE } -}; - -static const OPTION_INFO TagOpts[] = -{ - { _T("yes"), TRUE }, - { _T("no"), FALSE } -}; - - -static BOOL ParseCreateArguments( - LPCTSTR *ServiceArgs, - INT ArgCount, - OUT LPSERVICE_CREATE_INFO lpServiceInfo -) -{ - INT i, ArgIndex = 1; - - if (ArgCount < 1) - return FALSE; - - ZeroMemory(lpServiceInfo, sizeof(SERVICE_CREATE_INFO)); - - lpServiceInfo->lpServiceName = ServiceArgs[0]; - - ArgCount--; - - while (ArgCount > 1) - { - if (!lstrcmpi(ServiceArgs[ArgIndex], _T("type="))) - { - for (i = 0; i < sizeof(TypeOpts) / sizeof(TypeOpts[0]); i++) - if (!lstrcmpi(ServiceArgs[ArgIndex + 1], TypeOpts[i].lpOption)) - { - lpServiceInfo->dwServiceType |= TypeOpts[i].dwValue; - break; - } - - if (i == sizeof(TypeOpts) / sizeof(TypeOpts[0])) - break; - } - else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("start="))) - { - for (i = 0; i < sizeof(StartOpts) / sizeof(StartOpts[0]); i++) - if (!lstrcmpi(ServiceArgs[ArgIndex + 1], StartOpts[i].lpOption)) - { - lpServiceInfo->dwStartType = StartOpts[i].dwValue; - break; - } - - if (i == sizeof(StartOpts) / sizeof(StartOpts[0])) - break; - } - else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("error="))) - { - for (i = 0; i < sizeof(ErrorOpts) / sizeof(ErrorOpts[0]); i++) - if (!lstrcmpi(ServiceArgs[ArgIndex + 1], ErrorOpts[i].lpOption)) - { - lpServiceInfo->dwErrorControl = ErrorOpts[i].dwValue; - break; - } - - if (i == sizeof(ErrorOpts) / sizeof(ErrorOpts[0])) - break; - } - else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("tag="))) - { - for (i = 0; i < sizeof(TagOpts) / sizeof(TagOpts[0]); i++) - if (!lstrcmpi(ServiceArgs[ArgIndex + 1], TagOpts[i].lpOption)) - { - lpServiceInfo->bTagId = TagOpts[i].dwValue; - break; - } - - if (i == sizeof(TagOpts) / sizeof(TagOpts[0])) - break; - } - else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("binpath="))) - { - lpServiceInfo->lpBinaryPathName = ServiceArgs[ArgIndex + 1]; - } - else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("group="))) - { - lpServiceInfo->lpLoadOrderGroup = ServiceArgs[ArgIndex + 1]; - } - else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("depend="))) - { - lpServiceInfo->lpDependencies = ServiceArgs[ArgIndex + 1]; - } - else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("obj="))) - { - lpServiceInfo->lpServiceStartName = ServiceArgs[ArgIndex + 1]; - } - else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("displayname="))) - { - lpServiceInfo->lpDisplayName = ServiceArgs[ArgIndex + 1]; - } - else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("password="))) - { - lpServiceInfo->lpPassword = ServiceArgs[ArgIndex + 1]; - } - - ArgIndex += 2; - ArgCount -= 2; - } - - return (ArgCount == 0); -} - BOOL Create(LPCTSTR *ServiceArgs, INT ArgCount) { SC_HANDLE hSCManager; @@ -178,7 +21,7 @@ LPTSTR lpBuffer = NULL; SERVICE_CREATE_INFO ServiceInfo;
- if (!ParseCreateArguments(ServiceArgs, ArgCount, &ServiceInfo)) + if (!ParseCreateConfigArguments(ServiceArgs, ArgCount, FALSE, &ServiceInfo)) { CreateUsage(); return FALSE;
Added: trunk/reactos/base/applications/sc/misc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/misc.c... ============================================================================== --- trunk/reactos/base/applications/sc/misc.c (added) +++ trunk/reactos/base/applications/sc/misc.c [iso-8859-1] Mon Jun 13 19:43:02 2016 @@ -0,0 +1,160 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/sc/misc.c + * PURPOSE: Various functions + * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy gedmurphy@gmail.com + * Roel Messiant roelmessiant@gmail.com + */ + +#include "sc.h" + +typedef struct +{ + LPCTSTR lpOption; + DWORD dwValue; +} OPTION_INFO; + +static const OPTION_INFO TypeOpts[] = +{ + { _T("own"), SERVICE_WIN32_OWN_PROCESS }, + { _T("share"), SERVICE_WIN32_SHARE_PROCESS }, + { _T("interact"), SERVICE_INTERACTIVE_PROCESS }, + { _T("kernel"), SERVICE_KERNEL_DRIVER }, + { _T("filesys"), SERVICE_FILE_SYSTEM_DRIVER }, + { _T("rec"), SERVICE_RECOGNIZER_DRIVER } +}; + +static const OPTION_INFO StartOpts[] = +{ + { _T("boot"), SERVICE_BOOT_START }, + { _T("system"), SERVICE_SYSTEM_START }, + { _T("auto"), SERVICE_AUTO_START }, + { _T("demand"), SERVICE_DEMAND_START }, + { _T("disabled"), SERVICE_DISABLED } +}; + +static const OPTION_INFO ErrorOpts[] = +{ + { _T("normal"), SERVICE_ERROR_NORMAL }, + { _T("severe"), SERVICE_ERROR_SEVERE }, + { _T("critical"), SERVICE_ERROR_CRITICAL }, + { _T("ignore"), SERVICE_ERROR_IGNORE } +}; + +static const OPTION_INFO TagOpts[] = +{ + { _T("yes"), TRUE }, + { _T("no"), FALSE } +}; + + +BOOL +ParseCreateConfigArguments( + LPCTSTR *ServiceArgs, + INT ArgCount, + BOOL bChangeService, + OUT LPSERVICE_CREATE_INFO lpServiceInfo) +{ + INT i, ArgIndex = 1; + + if (ArgCount < 1) + return FALSE; + + ZeroMemory(lpServiceInfo, sizeof(SERVICE_CREATE_INFO)); + + if (bChangeService) + { + lpServiceInfo->dwServiceType = SERVICE_NO_CHANGE; + lpServiceInfo->dwStartType = SERVICE_NO_CHANGE; + lpServiceInfo->dwErrorControl = SERVICE_NO_CHANGE; + } + + lpServiceInfo->lpServiceName = ServiceArgs[0]; + + ArgCount--; + + while (ArgCount > 1) + { + if (!lstrcmpi(ServiceArgs[ArgIndex], _T("type="))) + { + for (i = 0; i < sizeof(TypeOpts) / sizeof(TypeOpts[0]); i++) + if (!lstrcmpi(ServiceArgs[ArgIndex + 1], TypeOpts[i].lpOption)) + { + if (lpServiceInfo->dwServiceType == SERVICE_NO_CHANGE) + lpServiceInfo->dwServiceType = TypeOpts[i].dwValue; + else + lpServiceInfo->dwServiceType |= TypeOpts[i].dwValue; + break; + } + + if (i == sizeof(TypeOpts) / sizeof(TypeOpts[0])) + break; + } + else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("start="))) + { + for (i = 0; i < sizeof(StartOpts) / sizeof(StartOpts[0]); i++) + if (!lstrcmpi(ServiceArgs[ArgIndex + 1], StartOpts[i].lpOption)) + { + lpServiceInfo->dwStartType = StartOpts[i].dwValue; + break; + } + + if (i == sizeof(StartOpts) / sizeof(StartOpts[0])) + break; + } + else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("error="))) + { + for (i = 0; i < sizeof(ErrorOpts) / sizeof(ErrorOpts[0]); i++) + if (!lstrcmpi(ServiceArgs[ArgIndex + 1], ErrorOpts[i].lpOption)) + { + lpServiceInfo->dwErrorControl = ErrorOpts[i].dwValue; + break; + } + + if (i == sizeof(ErrorOpts) / sizeof(ErrorOpts[0])) + break; + } + else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("tag="))) + { + for (i = 0; i < sizeof(TagOpts) / sizeof(TagOpts[0]); i++) + if (!lstrcmpi(ServiceArgs[ArgIndex + 1], TagOpts[i].lpOption)) + { + lpServiceInfo->bTagId = TagOpts[i].dwValue; + break; + } + + if (i == sizeof(TagOpts) / sizeof(TagOpts[0])) + break; + } + else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("binpath="))) + { + lpServiceInfo->lpBinaryPathName = ServiceArgs[ArgIndex + 1]; + } + else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("group="))) + { + lpServiceInfo->lpLoadOrderGroup = ServiceArgs[ArgIndex + 1]; + } + else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("depend="))) + { + lpServiceInfo->lpDependencies = ServiceArgs[ArgIndex + 1]; + } + else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("obj="))) + { + lpServiceInfo->lpServiceStartName = ServiceArgs[ArgIndex + 1]; + } + else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("displayname="))) + { + lpServiceInfo->lpDisplayName = ServiceArgs[ArgIndex + 1]; + } + else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("password="))) + { + lpServiceInfo->lpPassword = ServiceArgs[ArgIndex + 1]; + } + + ArgIndex += 2; + ArgCount -= 2; + } + + return (ArgCount == 0); +}
Propchange: trunk/reactos/base/applications/sc/misc.c ------------------------------------------------------------------------------ svn:eol-style = native
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 [iso-8859-1] (original) +++ trunk/reactos/base/applications/sc/sc.c [iso-8859-1] Mon Jun 13 19:43:02 2016 @@ -264,6 +264,10 @@ else SetDescriptionUsage(); } + else if (!lstrcmpi(Command, _T("config"))) + { + SetConfig(ServiceArgs, ArgCount); + } else { MainUsage();
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 [iso-8859-1] (original) +++ trunk/reactos/base/applications/sc/sc.h [iso-8859-1] Mon Jun 13 19:43:02 2016 @@ -11,6 +11,24 @@
#define SCDBG
+typedef struct +{ + LPCTSTR lpServiceName; + LPCTSTR lpDisplayName; + DWORD dwServiceType; + DWORD dwStartType; + DWORD dwErrorControl; + LPCTSTR lpBinaryPathName; + LPCTSTR lpLoadOrderGroup; + DWORD dwTagId; + LPCTSTR lpDependencies; + LPCTSTR lpServiceStartName; + LPCTSTR lpPassword; + + BOOL bTagId; +} SERVICE_CREATE_INFO, *LPSERVICE_CREATE_INFO; + + /* control functions */ BOOL Start(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, INT ArgCount); BOOL Create(LPCTSTR *ServiceArgs, INT ArgCount); @@ -22,6 +40,7 @@ BOOL SdShow(LPCTSTR ServiceName); BOOL SdSet(LPCTSTR ServiceName, LPCTSTR SecurityDescriptor); BOOL QueryConfig(LPCTSTR ServiceName); +BOOL SetConfig(LPCTSTR *ServiceArgs, INT ArgCount); BOOL QueryDescription(LPCTSTR ServiceName); BOOL SetDescription(LPCTSTR ServiceName, LPCTSTR Description); BOOL QueryFailure(LPCTSTR ServiceName); @@ -30,6 +49,14 @@ VOID PrintService(LPCTSTR ServiceName, LPSERVICE_STATUS_PROCESS pStatus, BOOL bExtended); VOID ReportLastError(VOID);
+/* misc.c */ +BOOL +ParseCreateConfigArguments( + LPCTSTR *ServiceArgs, + INT ArgCount, + BOOL bChangeService, + OUT LPSERVICE_CREATE_INFO lpServiceInfo); + /* usage functions */ VOID MainUsage(VOID); VOID StartUsage(VOID); @@ -37,8 +64,6 @@ VOID InterrogateUsage(VOID); VOID ContinueUsage(VOID); VOID StopUsage(VOID); -VOID ConfigUsage(VOID); -VOID DescriptionUsage(VOID); VOID DeleteUsage(VOID); VOID CreateUsage(VOID); VOID ControlUsage(VOID); @@ -48,5 +73,6 @@ VOID QueryDescriptionUsage(VOID); VOID QueryFailureUsage(VOID); VOID SetDescriptionUsage(VOID); +VOID SetConfigUsage(VOID);
#endif /* _SC_PCH_ */
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 [iso-8859-1] (original) +++ trunk/reactos/base/applications/sc/usage.c [iso-8859-1] Mon Jun 13 19:43:02 2016 @@ -33,7 +33,7 @@ _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("\t config : Changes the configuration of a service (persistant).\n") _T("\t description : Changes the description of a service.\n") // "\t failure : Changes the actions taken by a service upon failure.\n" _T("\t qc : Queries the configuration information for a service.\n") @@ -134,21 +134,6 @@ _T(" sc <server> continue [service name]\n")); }
- -VOID ConfigUsage(VOID) -{ - _tprintf(_T("not yet implemented\n")); -} - - -VOID DescriptionUsage(VOID) -{ - _tprintf(_T("DESCRIPTION:\n") - _T(" Sets the description string for a service.\n") - _T("USAGE:\n") - _T(" sc <server> description [service name]\n")); -} - VOID DeleteUsage(VOID) { _tprintf(_T("DESCRIPTION:\n") @@ -237,4 +222,24 @@ _T(" Sets the description string of a service.\n") _T("USAGE:\n") _T(" sc <server> description [service name] [description]\n")); -} +} + +VOID SetConfigUsage(VOID) +{ + _tprintf(_T("DESCRIPTION:\n") + _T(" Modifies a service entry in the registry and Service Database.\n") + _T("USAGE:\n") + _T(" sc <server> config [service name] <option1> <option2>...\n") + _T("CONFIG OPTIONS:\n") + _T(" NOTE: The option name includes the equal sign.\n") + _T(" type= <own|share|interact|kernel|filesys|rec>\n") + _T(" start= <boot|system|auto|demand|disabled>\n") + _T(" error= <normal|severe|critical|ignore>\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(" DisplayName= <display name>\n") + _T(" password= <password>\n")); +}