[SVCHOST]

- Convert tabs to spaces. No code changes.

svn path=/trunk/; revision=59357
This commit is contained in:
Thomas Faber 2013-06-29 11:10:28 +00:00
parent 14e80363be
commit 52a90949ed
2 changed files with 193 additions and 194 deletions

View file

@ -1,9 +1,9 @@
/* /*
* PROJECT: ReactOS SvcHost * PROJECT: ReactOS SvcHost
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: /base/services/svchost/svchost.c * FILE: /base/services/svchost/svchost.c
* PURPOSE: Provide dll service loader * PURPOSE: Provide dll service loader
* PROGRAMMERS: Gregor Brunmar (gregor.brunmar@home.se) * PROGRAMMERS: Gregor Brunmar (gregor.brunmar@home.se)
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
@ -15,12 +15,12 @@
/* DEFINES *******************************************************************/ /* DEFINES *******************************************************************/
static LPCTSTR SVCHOST_REG_KEY = _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SvcHost"); static LPCTSTR SVCHOST_REG_KEY = _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SvcHost");
static LPCTSTR SERVICE_KEY = _T("SYSTEM\\CurrentControlSet\\Services\\"); static LPCTSTR SERVICE_KEY = _T("SYSTEM\\CurrentControlSet\\Services\\");
static LPCTSTR PARAMETERS_KEY = _T("\\Parameters"); static LPCTSTR PARAMETERS_KEY = _T("\\Parameters");
#define SERVICE_KEY_LENGTH _tcslen(SERVICE_KEY); #define SERVICE_KEY_LENGTH _tcslen(SERVICE_KEY);
#define REG_MAX_DATA_SIZE 2048 #define REG_MAX_DATA_SIZE 2048
static PSERVICE FirstService = NULL; static PSERVICE FirstService = NULL;
@ -28,127 +28,127 @@ static PSERVICE FirstService = NULL;
BOOL PrepareService(LPCTSTR ServiceName) BOOL PrepareService(LPCTSTR ServiceName)
{ {
HKEY hServiceKey; HKEY hServiceKey;
TCHAR ServiceKeyBuffer[MAX_PATH + 1]; TCHAR ServiceKeyBuffer[MAX_PATH + 1];
DWORD LeftOfBuffer = sizeof(ServiceKeyBuffer) / sizeof(ServiceKeyBuffer[0]); DWORD LeftOfBuffer = sizeof(ServiceKeyBuffer) / sizeof(ServiceKeyBuffer[0]);
DWORD KeyType; DWORD KeyType;
PTSTR Buffer = NULL; PTSTR Buffer = NULL;
DWORD BufferSize = MAX_PATH + 1; DWORD BufferSize = MAX_PATH + 1;
LONG RetVal; LONG RetVal;
HINSTANCE hServiceDll; HINSTANCE hServiceDll;
TCHAR DllPath[MAX_PATH + 2]; /* See MSDN on ExpandEnvironmentStrings() for ANSI strings for more details on + 2 */ TCHAR DllPath[MAX_PATH + 2]; /* See MSDN on ExpandEnvironmentStrings() for ANSI strings for more details on + 2 */
LPSERVICE_MAIN_FUNCTION ServiceMainFunc; LPSERVICE_MAIN_FUNCTION ServiceMainFunc;
PSERVICE Service; PSERVICE Service;
/* Compose the registry path to the service's "Parameter" key */ /* Compose the registry path to the service's "Parameter" key */
_tcsncpy(ServiceKeyBuffer, SERVICE_KEY, LeftOfBuffer); _tcsncpy(ServiceKeyBuffer, SERVICE_KEY, LeftOfBuffer);
LeftOfBuffer -= _tcslen(SERVICE_KEY); LeftOfBuffer -= _tcslen(SERVICE_KEY);
_tcsncat(ServiceKeyBuffer, ServiceName, LeftOfBuffer); _tcsncat(ServiceKeyBuffer, ServiceName, LeftOfBuffer);
LeftOfBuffer -= _tcslen(ServiceName); LeftOfBuffer -= _tcslen(ServiceName);
_tcsncat(ServiceKeyBuffer, PARAMETERS_KEY, LeftOfBuffer); _tcsncat(ServiceKeyBuffer, PARAMETERS_KEY, LeftOfBuffer);
LeftOfBuffer -= _tcslen(PARAMETERS_KEY); LeftOfBuffer -= _tcslen(PARAMETERS_KEY);
if (LeftOfBuffer < 0) if (LeftOfBuffer < 0)
{ {
DPRINT1("Buffer overflow for service name: '%s'\n", ServiceName); DPRINT1("Buffer overflow for service name: '%s'\n", ServiceName);
return FALSE; return FALSE;
} }
/* Open the service registry key to find the dll name */ /* Open the service registry key to find the dll name */
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, ServiceKeyBuffer, 0, KEY_READ, &hServiceKey)) if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, ServiceKeyBuffer, 0, KEY_READ, &hServiceKey))
{ {
DPRINT1("Could not open service key (%s)\n", ServiceKeyBuffer); DPRINT1("Could not open service key (%s)\n", ServiceKeyBuffer);
return FALSE; return FALSE;
} }
do do
{ {
if (Buffer) if (Buffer)
HeapFree(GetProcessHeap(), 0, Buffer); HeapFree(GetProcessHeap(), 0, Buffer);
Buffer = HeapAlloc(GetProcessHeap(), 0, BufferSize); Buffer = HeapAlloc(GetProcessHeap(), 0, BufferSize);
if (NULL == Buffer) if (NULL == Buffer)
{ {
DPRINT1("Not enough memory for service: %s\n", ServiceName); DPRINT1("Not enough memory for service: %s\n", ServiceName);
return FALSE; return FALSE;
} }
RetVal = RegQueryValueEx(hServiceKey, _T("ServiceDll"), NULL, &KeyType, (LPBYTE)Buffer, &BufferSize); RetVal = RegQueryValueEx(hServiceKey, _T("ServiceDll"), NULL, &KeyType, (LPBYTE)Buffer, &BufferSize);
} while (ERROR_MORE_DATA == RetVal); } while (ERROR_MORE_DATA == RetVal);
RegCloseKey(hServiceKey); RegCloseKey(hServiceKey);
if (ERROR_SUCCESS != RetVal || 0 == BufferSize) if (ERROR_SUCCESS != RetVal || 0 == BufferSize)
{ {
DPRINT1("Could not read 'ServiceDll' value from service: %s, ErrorCode: 0x%x\n", ServiceName, RetVal); DPRINT1("Could not read 'ServiceDll' value from service: %s, ErrorCode: 0x%x\n", ServiceName, RetVal);
HeapFree(GetProcessHeap(), 0, Buffer); HeapFree(GetProcessHeap(), 0, Buffer);
return FALSE; return FALSE;
} }
/* Convert possible %SystemRoot% to a real path */ /* Convert possible %SystemRoot% to a real path */
BufferSize = ExpandEnvironmentStrings(Buffer, DllPath, _countof(DllPath)); BufferSize = ExpandEnvironmentStrings(Buffer, DllPath, _countof(DllPath));
if (0 == BufferSize) if (0 == BufferSize)
{ {
DPRINT1("Invalid ServiceDll path: %s\n", Buffer); DPRINT1("Invalid ServiceDll path: %s\n", Buffer);
HeapFree(GetProcessHeap(), 0, Buffer); HeapFree(GetProcessHeap(), 0, Buffer);
return FALSE; return FALSE;
} }
HeapFree(GetProcessHeap(), 0, Buffer); HeapFree(GetProcessHeap(), 0, Buffer);
/* Load the service dll */ /* Load the service dll */
DPRINT("Trying to load dll\n"); DPRINT("Trying to load dll\n");
hServiceDll = LoadLibrary(DllPath); hServiceDll = LoadLibrary(DllPath);
if (NULL == hServiceDll) if (NULL == hServiceDll)
{ {
DPRINT1("Unable to load ServiceDll: %s, ErrorCode: %u\n", DllPath, GetLastError()); DPRINT1("Unable to load ServiceDll: %s, ErrorCode: %u\n", DllPath, GetLastError());
return FALSE; return FALSE;
} }
ServiceMainFunc = (LPSERVICE_MAIN_FUNCTION)GetProcAddress(hServiceDll, "ServiceMain"); ServiceMainFunc = (LPSERVICE_MAIN_FUNCTION)GetProcAddress(hServiceDll, "ServiceMain");
/* Allocate a service node in the linked list */ /* Allocate a service node in the linked list */
Service = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE)); Service = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE));
if (NULL == Service) if (NULL == Service)
{ {
DPRINT1("Not enough memory for service: %s\n", ServiceName); DPRINT1("Not enough memory for service: %s\n", ServiceName);
return FALSE; return FALSE;
} }
memset(Service, 0, sizeof(SERVICE)); memset(Service, 0, sizeof(SERVICE));
Service->Name = HeapAlloc(GetProcessHeap(), 0, (_tcslen(ServiceName)+1) * sizeof(TCHAR)); Service->Name = HeapAlloc(GetProcessHeap(), 0, (_tcslen(ServiceName)+1) * sizeof(TCHAR));
if (NULL == Service->Name) if (NULL == Service->Name)
{ {
DPRINT1("Not enough memory for service: %s\n", ServiceName); DPRINT1("Not enough memory for service: %s\n", ServiceName);
HeapFree(GetProcessHeap(), 0, Service); HeapFree(GetProcessHeap(), 0, Service);
return FALSE; return FALSE;
} }
_tcscpy(Service->Name, ServiceName); _tcscpy(Service->Name, ServiceName);
Service->hServiceDll = hServiceDll; Service->hServiceDll = hServiceDll;
Service->ServiceMainFunc = ServiceMainFunc; Service->ServiceMainFunc = ServiceMainFunc;
Service->Next = FirstService; Service->Next = FirstService;
FirstService = Service; FirstService = Service;
return TRUE; return TRUE;
} }
VOID FreeServices(VOID) VOID FreeServices(VOID)
{ {
while (FirstService) while (FirstService)
{ {
PSERVICE Service = FirstService; PSERVICE Service = FirstService;
FirstService = Service->Next; FirstService = Service->Next;
FreeLibrary(Service->hServiceDll); FreeLibrary(Service->hServiceDll);
HeapFree(GetProcessHeap(), 0, Service->Name); HeapFree(GetProcessHeap(), 0, Service->Name);
HeapFree(GetProcessHeap(), 0, Service); HeapFree(GetProcessHeap(), 0, Service);
} }
} }
/* /*
@ -156,107 +156,107 @@ VOID FreeServices(VOID)
*/ */
DWORD LoadServiceCategory(LPCTSTR ServiceCategory) DWORD LoadServiceCategory(LPCTSTR ServiceCategory)
{ {
HKEY hServicesKey; HKEY hServicesKey;
DWORD KeyType; DWORD KeyType;
DWORD BufferSize = REG_MAX_DATA_SIZE; DWORD BufferSize = REG_MAX_DATA_SIZE;
TCHAR Buffer[REG_MAX_DATA_SIZE]; TCHAR Buffer[REG_MAX_DATA_SIZE];
LPCTSTR ServiceName; LPCTSTR ServiceName;
DWORD BufferIndex = 0; DWORD BufferIndex = 0;
DWORD NrOfServices = 0; DWORD NrOfServices = 0;
/* Get all the services in this category */ /* Get all the services in this category */
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, SVCHOST_REG_KEY, 0, KEY_READ, &hServicesKey)) if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, SVCHOST_REG_KEY, 0, KEY_READ, &hServicesKey))
{ {
DPRINT1("Could not open service category: %s\n", ServiceCategory); DPRINT1("Could not open service category: %s\n", ServiceCategory);
return 0; return 0;
} }
if (ERROR_SUCCESS != RegQueryValueEx(hServicesKey, ServiceCategory, NULL, &KeyType, (LPBYTE)Buffer, &BufferSize)) if (ERROR_SUCCESS != RegQueryValueEx(hServicesKey, ServiceCategory, NULL, &KeyType, (LPBYTE)Buffer, &BufferSize))
{ {
DPRINT1("Could not open service category (2): %s\n", ServiceCategory); DPRINT1("Could not open service category (2): %s\n", ServiceCategory);
RegCloseKey(hServicesKey); RegCloseKey(hServicesKey);
return 0; return 0;
} }
/* Clean up */ /* Clean up */
RegCloseKey(hServicesKey); RegCloseKey(hServicesKey);
/* Load services in the category */ /* Load services in the category */
ServiceName = Buffer; ServiceName = Buffer;
while (_T('\0') != ServiceName[0]) while (_T('\0') != ServiceName[0])
{ {
size_t Length; size_t Length;
Length = _tcslen(ServiceName); Length = _tcslen(ServiceName);
if (0 == Length) if (0 == Length)
break; break;
if (TRUE == PrepareService(ServiceName)) if (TRUE == PrepareService(ServiceName))
++NrOfServices; ++NrOfServices;
BufferIndex += Length + 1; BufferIndex += Length + 1;
ServiceName = &Buffer[BufferIndex]; ServiceName = &Buffer[BufferIndex];
} }
return NrOfServices; return NrOfServices;
} }
int _tmain (int argc, LPTSTR argv []) int _tmain (int argc, LPTSTR argv [])
{ {
DWORD NrOfServices; DWORD NrOfServices;
LPSERVICE_TABLE_ENTRY ServiceTable; LPSERVICE_TABLE_ENTRY ServiceTable;
if (argc < 3) if (argc < 3)
{ {
/* MS svchost.exe doesn't seem to print help, should we? */ /* MS svchost.exe doesn't seem to print help, should we? */
return 0; return 0;
} }
if (_tcscmp(argv[1], _T("-k")) != 0) if (_tcscmp(argv[1], _T("-k")) != 0)
{ {
/* For now, we only handle "-k" */ /* For now, we only handle "-k" */
return 0; return 0;
} }
NrOfServices = LoadServiceCategory(argv[2]); NrOfServices = LoadServiceCategory(argv[2]);
DPRINT("NrOfServices: %lu\n", NrOfServices); DPRINT("NrOfServices: %lu\n", NrOfServices);
if (0 == NrOfServices) if (0 == NrOfServices)
return 0; return 0;
ServiceTable = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_TABLE_ENTRY) * (NrOfServices + 1)); ServiceTable = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_TABLE_ENTRY) * (NrOfServices + 1));
if (NULL != ServiceTable) if (NULL != ServiceTable)
{ {
DWORD i; DWORD i;
PSERVICE Service = FirstService; PSERVICE Service = FirstService;
/* Fill the service table */ /* Fill the service table */
for (i = 0; i < NrOfServices; i++) for (i = 0; i < NrOfServices; i++)
{ {
DPRINT("Loading service: %s\n", Service->Name); DPRINT("Loading service: %s\n", Service->Name);
ServiceTable[i].lpServiceName = Service->Name; ServiceTable[i].lpServiceName = Service->Name;
ServiceTable[i].lpServiceProc = Service->ServiceMainFunc; ServiceTable[i].lpServiceProc = Service->ServiceMainFunc;
Service = Service->Next; Service = Service->Next;
} }
/* Set a NULL entry to end the service table */ /* Set a NULL entry to end the service table */
ServiceTable[i].lpServiceName = NULL; ServiceTable[i].lpServiceName = NULL;
ServiceTable[i].lpServiceProc = NULL; ServiceTable[i].lpServiceProc = NULL;
if (FALSE == StartServiceCtrlDispatcher(ServiceTable)) if (FALSE == StartServiceCtrlDispatcher(ServiceTable))
DPRINT1("Failed to start service control dispatcher, ErrorCode: %lu\n", GetLastError()); DPRINT1("Failed to start service control dispatcher, ErrorCode: %lu\n", GetLastError());
HeapFree(GetProcessHeap(), 0, ServiceTable); HeapFree(GetProcessHeap(), 0, ServiceTable);
} }
else else
{ {
DPRINT1("Not enough memory for the service table, trying to allocate %u bytes\n", sizeof(SERVICE_TABLE_ENTRY) * (NrOfServices + 1)); DPRINT1("Not enough memory for the service table, trying to allocate %u bytes\n", sizeof(SERVICE_TABLE_ENTRY) * (NrOfServices + 1));
} }
DPRINT("Freeing services...\n"); DPRINT("Freeing services...\n");
FreeServices(); FreeServices();
return 0; return 0;
} }

View file

@ -1,9 +1,9 @@
/* /*
* PROJECT: ReactOS SvcHost * PROJECT: ReactOS SvcHost
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: /base/services/svchost/svchost.h * FILE: /base/services/svchost/svchost.h
* PURPOSE: Provide dll service loader * PURPOSE: Provide dll service loader
* PROGRAMMERS: Gregor Brunmar (gregor.brunmar@home.se) * PROGRAMMERS: Gregor Brunmar (gregor.brunmar@home.se)
*/ */
#pragma once #pragma once
@ -24,16 +24,15 @@
/* DEFINES *******************************************************************/ /* DEFINES *******************************************************************/
#define CS_TIMEOUT 1000 #define CS_TIMEOUT 1000
typedef struct _SERVICE { typedef struct _SERVICE {
PTSTR Name; PTSTR Name;
HINSTANCE hServiceDll; HINSTANCE hServiceDll;
LPSERVICE_MAIN_FUNCTION ServiceMainFunc; LPSERVICE_MAIN_FUNCTION ServiceMainFunc;
struct _SERVICE *Next; struct _SERVICE *Next;
} SERVICE, *PSERVICE; } SERVICE, *PSERVICE;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
/* EOF */ /* EOF */