/* * PROJECT: ReactOS Services * LICENSE: GPL - See COPYING in the top level directory * FILE: base/system/sc/create.c * PURPOSE: Create a service * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy * Roel Messiant * */ #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; SC_HANDLE hSc; BOOL bRet = FALSE; INT i; INT Length; LPTSTR lpBuffer = NULL; SERVICE_CREATE_INFO ServiceInfo; if (!ParseCreateArguments(ServiceArgs, ArgCount, &ServiceInfo)) { CreateUsage(); return FALSE; } if (!ServiceInfo.dwServiceType) ServiceInfo.dwServiceType = SERVICE_WIN32_OWN_PROCESS; if (!ServiceInfo.dwStartType) ServiceInfo.dwStartType = SERVICE_DEMAND_START; if (!ServiceInfo.dwErrorControl) ServiceInfo.dwErrorControl = SERVICE_ERROR_NORMAL; if (ServiceInfo.lpDependencies) { Length = lstrlen(ServiceInfo.lpDependencies); lpBuffer = HeapAlloc(GetProcessHeap(), 0, (Length + 2) * sizeof(TCHAR)); for (i = 0; i < Length; i++) if (ServiceInfo.lpDependencies[i] == _T('/')) lpBuffer[i] = 0; else lpBuffer[i] = ServiceInfo.lpDependencies[i]; lpBuffer[Length] = 0; lpBuffer[Length + 1] = 0; ServiceInfo.lpDependencies = lpBuffer; } #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 hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (hSCManager != NULL) { hSc = CreateService(hSCManager, ServiceInfo.lpServiceName, ServiceInfo.lpDisplayName, SERVICE_ALL_ACCESS, ServiceInfo.dwServiceType, ServiceInfo.dwStartType, ServiceInfo.dwErrorControl, ServiceInfo.lpBinaryPathName, ServiceInfo.lpLoadOrderGroup, ServiceInfo.bTagId ? &ServiceInfo.dwTagId : NULL, ServiceInfo.lpDependencies, ServiceInfo.lpServiceStartName, ServiceInfo.lpPassword); if (hSc != NULL) { _tprintf(_T("[SC] CreateService SUCCESS\n")); CloseServiceHandle(hSc); bRet = TRUE; } else ReportLastError(); CloseServiceHandle(hSCManager); } else ReportLastError(); if (lpBuffer != NULL) HeapFree(GetProcessHeap(), 0, lpBuffer); return bRet; }