Author: gbrunmar Date: Mon Oct 22 22:06:31 2007 New Revision: 29783
URL: http://svn.reactos.org/svn/reactos?rev=29783&view=rev Log: Added first stub of svchost - not included in the build yet.
Added: trunk/reactos/base/services/svchost/ trunk/reactos/base/services/svchost/svchost.c (with props) trunk/reactos/base/services/svchost/svchost.h (with props) trunk/reactos/base/services/svchost/svchost.rbuild (with props) trunk/reactos/base/services/svchost/svchost.rc (with props)
Added: trunk/reactos/base/services/svchost/svchost.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/svchost/svcho... ============================================================================== --- trunk/reactos/base/services/svchost/svchost.c (added) +++ trunk/reactos/base/services/svchost/svchost.c Mon Oct 22 22:06:31 2007 @@ -1,0 +1,225 @@ +/* + * PROJECT: ReactOS SvcHost + * LICENSE: GPL - See COPYING in the top level directory + * FILE: /base/services/svchost/svchost.c + * PURPOSE: Provide dll service loader + * PROGRAMMERS: Gregor Brunmar (gregor.brunmar@home.se) + */ + +/* INCLUDES ******************************************************************/ + +#include "svchost.h" +#include <debug.h> + +#ifdef _MSC_VER +#undef DPRINT1 +#define DPRINT1 +#endif + +/* DEFINES *******************************************************************/ + +static LPCTSTR SVCHOST_REG_KEY = _T("SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost"); +static LPCTSTR SERVICE_KEY = _T("SYSTEM\CurrentControlSet\Services\"); +static LPCTSTR PARAMETERS_KEY = _T("\Parameters"); + +#define SERVICE_KEY_LENGTH _tcslen(SERVICE_KEY); +#define REG_MAX_DATA_SIZE 2048 + +static PSERVICE FirstService = NULL; + +/* FUNCTIONS *****************************************************************/ + +BOOL PrepareService(LPCTSTR ServiceName) +{ + HKEY hServiceKey; + TCHAR ServiceKeyBuffer[MAX_PATH + 1]; + DWORD LeftOfBuffer = sizeof(ServiceKeyBuffer) / sizeof(ServiceKeyBuffer[0]); + DWORD KeyType; + PTSTR Buffer = NULL; + DWORD BufferSize = MAX_PATH + 1; + LONG RetVal; + HINSTANCE hServiceDll; + TCHAR DllPath[MAX_PATH + 2]; /* See MSDN on ExpandEnvironmentStrings() for ANSI strings for more details on + 2 */ + LPSERVICE_MAIN_FUNCTION ServiceMainFunc; + PSERVICE Service; + + /* Compose the registry path to the service's "Parameter" key */ + _tcsncpy(ServiceKeyBuffer, SERVICE_KEY, LeftOfBuffer); + LeftOfBuffer -= _tcslen(SERVICE_KEY); + _tcsncat(ServiceKeyBuffer, ServiceName, LeftOfBuffer); + LeftOfBuffer -= _tcslen(ServiceName); + _tcsncat(ServiceKeyBuffer, PARAMETERS_KEY, LeftOfBuffer); + LeftOfBuffer -= _tcslen(PARAMETERS_KEY); + + if (LeftOfBuffer < 0) + { + DPRINT1("Buffer overflow for service name: '%s'\n", ServiceName); + return FALSE; + } + + /* Open the service registry key to find the dll name */ + if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, ServiceKeyBuffer, 0, KEY_READ, &hServiceKey)) + { + DPRINT1("Could not open service key (%s)\n", ServiceKeyBuffer); + return FALSE; + } + + do + { + if (Buffer) + HeapFree(GetProcessHeap(), 0, Buffer); + + Buffer = HeapAlloc(GetProcessHeap(), 0, BufferSize); + if (NULL == Buffer) + { + DPRINT1("Not enough memory for service: %s\n", ServiceName); + return FALSE; + } + + RetVal = RegQueryValueEx(hServiceKey, _T("ServiceDll"), NULL, &KeyType, (LPBYTE)Buffer, &BufferSize); + + } while (ERROR_MORE_DATA == RetVal); + + + RegCloseKey(hServiceKey); + + if (ERROR_SUCCESS != RetVal || 0 == BufferSize) + { + DPRINT1("Could not read 'ServiceDll' value from service: %s, ErrorCode: 0x%x\n", ServiceName, RetVal); + HeapFree(GetProcessHeap(), 0, Buffer); + return FALSE; + } + + /* Convert possible %SystemRoot% to a real path */ + BufferSize = ExpandEnvironmentStrings(Buffer, DllPath, sizeof(DllPath)); + if (0 == BufferSize) + { + DPRINT1("Invalid ServiceDll path: %s\n", Buffer); + HeapFree(GetProcessHeap(), 0, Buffer); + return FALSE; + } + + HeapFree(GetProcessHeap(), 0, Buffer); + + /* Load the service dll */ + hServiceDll = LoadLibrary(DllPath); + + if (NULL == hServiceDll) + { + DPRINT1("Unable to load ServiceDll: %s\n", DllPath); + return FALSE; + } + + ServiceMainFunc = (LPSERVICE_MAIN_FUNCTION)GetProcAddress(hServiceDll, "ServiceMain"); + + /* Allocate a service node in the linked list */ + Service = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE)); + if (NULL == Service) + { + DPRINT1("Not enough memory for service: %s\n", ServiceName); + return FALSE; + } + + memset(Service, 0, sizeof(SERVICE)); + Service->Name = HeapAlloc(GetProcessHeap(), 0, _tcslen(ServiceName) + sizeof(TCHAR)); + if (NULL == Service->Name) + { + DPRINT1("Not enough memory for service: %s\n", ServiceName); + HeapFree(GetProcessHeap(), 0, Service); + return FALSE; + } + _tcscpy(Service->Name, ServiceName); + + Service->hServiceDll = hServiceDll; + Service->ServiceMainFunc = ServiceMainFunc; + + Service->Next = FirstService; + FirstService = Service; + + return TRUE; +} + +BOOL FreeServices() +{ + while (FirstService) + { + PSERVICE Service = FirstService; + FirstService = Service->Next; + + FreeLibrary(Service->hServiceDll); + + HeapFree(GetProcessHeap(), 0, Service->Name); + HeapFree(GetProcessHeap(), 0, Service); + } + + return TRUE; +} + +BOOL LoadServiceCategory(LPCTSTR ServiceCategory) +{ + HKEY hServicesKey; + DWORD KeyType; + DWORD BufferSize = REG_MAX_DATA_SIZE; + TCHAR Buffer[REG_MAX_DATA_SIZE]; + LPCTSTR ServiceName; + DWORD BufferIndex = 0; + + /* Get all the services in this category */ + if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, SVCHOST_REG_KEY, 0, KEY_READ, &hServicesKey)) + { + DPRINT1("Could not open service category: %s\n", ServiceCategory); + return FALSE; + } + + if (ERROR_SUCCESS != RegQueryValueEx(hServicesKey, ServiceCategory, NULL, &KeyType, (LPBYTE)Buffer, &BufferSize)) + { + DPRINT1("Could not open service category (2): %s\n", ServiceCategory); + RegCloseKey(hServicesKey); + return FALSE; + } + + /* Clean up */ + RegCloseKey(hServicesKey); + + /* Load services in the category */ + ServiceName = Buffer; + while (_T('\0') != ServiceName[0]) + { + size_t Length; + + Length = _tcslen(ServiceName); + if (0 == Length) + break; + + PrepareService(ServiceName); + + BufferIndex += (Length + 1) * sizeof(TCHAR); + + ServiceName = &Buffer[BufferIndex]; + } + + return TRUE; +} + +int _tmain (int argc, LPTSTR argv []) +{ + if (argc < 3) + { + /* MS svchost.exe doesn't seem to print help, should we? */ + return 1; + } + + if (_tcscmp(argv[1], _T("-k")) != 0) + { + /* For now, we only handle "-k" */ + return 1; + } + + LoadServiceCategory(argv[2]); + + FreeServices(); + + return 0; +} + +/* EOF */
Propchange: trunk/reactos/base/services/svchost/svchost.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/base/services/svchost/svchost.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/svchost/svcho... ============================================================================== --- trunk/reactos/base/services/svchost/svchost.h (added) +++ trunk/reactos/base/services/svchost/svchost.h Mon Oct 22 22:06:31 2007 @@ -1,0 +1,38 @@ +/* + * PROJECT: ReactOS SvcHost + * LICENSE: GPL - See COPYING in the top level directory + * FILE: /base/services/svchost/svchost.h + * PURPOSE: Provide dll service loader + * PROGRAMMERS: Gregor Brunmar (gregor.brunmar@home.se) + */ +#ifndef __SVCHOST_H__ +#define __SVCHOST_H__ + +/* INCLUDES ******************************************************************/ + +#ifdef _MSC_VER +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +#include <stdio.h> +#include <winsock2.h> +#include <tchar.h> + +/* DEFINES *******************************************************************/ + +#define CS_TIMEOUT 1000 + +typedef struct _SERVICE { + PTSTR Name; + HINSTANCE hServiceDll; + LPSERVICE_MAIN_FUNCTION ServiceMainFunc; + struct _SERVICE *Next; +} SERVICE, *PSERVICE; + + +/* FUNCTIONS *****************************************************************/ + +#endif /* __SVCHOST_H__ */ + +/* EOF */ +
Propchange: trunk/reactos/base/services/svchost/svchost.h ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/base/services/svchost/svchost.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/svchost/svcho... ============================================================================== --- trunk/reactos/base/services/svchost/svchost.rbuild (added) +++ trunk/reactos/base/services/svchost/svchost.rbuild Mon Oct 22 22:06:31 2007 @@ -1,0 +1,10 @@ +<?xml version="1.0"?> +<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd"> +<module name="svchost" type="win32cui" installbase="system32" installname="svchost.exe"> + <include base="svchost">.</include> + <define name="__USE_W32API" /> + <library>kernel32</library> + <library>advapi32</library> + <file>svchost.c</file> + <file>svchost.rc</file> +</module>
Propchange: trunk/reactos/base/services/svchost/svchost.rbuild ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/base/services/svchost/svchost.rc URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/svchost/svcho... ============================================================================== --- trunk/reactos/base/services/svchost/svchost.rc (added) +++ trunk/reactos/base/services/svchost/svchost.rc Mon Oct 22 22:06:31 2007 @@ -1,0 +1,6 @@ +/* $Id: svchost.rc 21279 2007-10-22 06:09:58Z gbrunmar $ */ + +#define REACTOS_STR_FILE_DESCRIPTION "SvcHost subsystem\0" +#define REACTOS_STR_INTERNAL_NAME "SvcHost\0" +#define REACTOS_STR_ORIGINAL_FILENAME "SvcHost.exe\0" +#include <reactos/version.rc>
Propchange: trunk/reactos/base/services/svchost/svchost.rc ------------------------------------------------------------------------------ svn:eol-style = native