mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 06:15:26 +00:00
Added first stub of svchost - not included in the build yet.
svn path=/trunk/; revision=29783
This commit is contained in:
parent
fa46551b04
commit
9e306bf2f4
4 changed files with 279 additions and 0 deletions
225
reactos/base/services/svchost/svchost.c
Normal file
225
reactos/base/services/svchost/svchost.c
Normal file
|
@ -0,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 */
|
38
reactos/base/services/svchost/svchost.h
Normal file
38
reactos/base/services/svchost/svchost.h
Normal file
|
@ -0,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 */
|
||||
|
10
reactos/base/services/svchost/svchost.rbuild
Normal file
10
reactos/base/services/svchost/svchost.rbuild
Normal file
|
@ -0,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>
|
6
reactos/base/services/svchost/svchost.rc
Normal file
6
reactos/base/services/svchost/svchost.rc
Normal file
|
@ -0,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>
|
Loading…
Reference in a new issue