Something went wrong. Try again.
Reactos
Something went wrong. Try again.
9.2 kB · 327 lines
C
at listview
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328/* * 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 }};
BOOLParseCreateConfigArguments( 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);}
BOOLParseFailureActions( IN LPCTSTR lpActions, OUT DWORD *pcActions, OUT SC_ACTION **ppActions){ SC_ACTION *pActions = NULL; LPTSTR pStringBuffer = NULL; LPTSTR p; INT_PTR nLength; INT nCount = 0;
*pcActions = 0; *ppActions = NULL;
nLength = _tcslen(lpActions);
/* Allocate the string buffer */ pStringBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 2) * sizeof(TCHAR)); if (pStringBuffer == NULL) { return FALSE; }
/* Copy the actions string into the string buffer */ CopyMemory(pStringBuffer, lpActions, nLength * sizeof(TCHAR));
/* Replace all slashes by null characters */ p = pStringBuffer; while (*p != _T('\0')) { if (*p == _T('/')) *p = _T('\0'); p++; }
/* Count the arguments in the buffer */ p = pStringBuffer; while (*p != _T('\0')) { nCount++;
nLength = _tcslen(p); p = (LPTSTR)((LONG_PTR)p + ((nLength + 1) * sizeof(TCHAR))); }
/* Allocate the actions buffer */ pActions = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nCount / 2 * sizeof(SC_ACTION)); if (pActions == NULL) { HeapFree(GetProcessHeap(), 0, pStringBuffer); return FALSE; }
/* Parse the string buffer */ nCount = 0; p = pStringBuffer; while (*p != _T('\0')) { nLength = _tcslen(p);
if (nCount % 2 == 0) { /* Action */ if (!lstrcmpi(p, _T("reboot"))) pActions[nCount / 2].Type = SC_ACTION_REBOOT; else if (!lstrcmpi(p, _T("restart"))) pActions[nCount / 2].Type = SC_ACTION_RESTART; else if (!lstrcmpi(p, _T("run"))) pActions[nCount / 2].Type = SC_ACTION_RUN_COMMAND; else break; } else { /* Delay */ pActions[nCount / 2].Delay = _tcstoul(p, NULL, 10); if (pActions[nCount / 2].Delay == 0 && errno == ERANGE) break; }
p = (LPTSTR)((LONG_PTR)p + ((nLength + 1) * sizeof(TCHAR))); nCount++; }
/* Free the string buffer */ HeapFree(GetProcessHeap(), 0, pStringBuffer);
*pcActions = nCount / 2; *ppActions = pActions;
return TRUE;}
BOOLParseFailureArguments( IN LPCTSTR *ServiceArgs, IN INT ArgCount, OUT LPCTSTR *ppServiceName, OUT LPSERVICE_FAILURE_ACTIONS pFailureActions){ INT ArgIndex = 1; LPCTSTR lpActions = NULL; LPCTSTR lpReset = NULL;
if (ArgCount < 1) return FALSE;
ZeroMemory(pFailureActions, sizeof(SERVICE_FAILURE_ACTIONS));
*ppServiceName = ServiceArgs[0];
ArgCount--;
while (ArgCount > 1) { if (!lstrcmpi(ServiceArgs[ArgIndex], _T("actions="))) { lpActions = (LPTSTR)ServiceArgs[ArgIndex + 1]; } else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("command="))) { pFailureActions->lpCommand = (LPTSTR)ServiceArgs[ArgIndex + 1]; } else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("reboot="))) { pFailureActions->lpRebootMsg = (LPTSTR)ServiceArgs[ArgIndex + 1]; } else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("reset="))) { lpReset = (LPTSTR)ServiceArgs[ArgIndex + 1]; }
ArgIndex += 2; ArgCount -= 2; }
if ((lpReset == NULL && lpActions != NULL) || (lpReset != NULL && lpActions == NULL)) { _tprintf(_T("ERROR: The reset and actions options must be used simultaneously.\n\n")); return FALSE; }
if (lpReset != NULL) { if (!lstrcmpi(lpReset, _T("infinite"))) pFailureActions->dwResetPeriod = INFINITE; else pFailureActions->dwResetPeriod = _ttoi(lpReset); }
if (lpActions != NULL) { if (!ParseFailureActions(lpActions, &pFailureActions->cActions, &pFailureActions->lpsaActions)) { return FALSE; } }
return (ArgCount == 0);}