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/svch…
==============================================================================
--- 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(a)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/svch…
==============================================================================
--- 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(a)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/svch…
==============================================================================
--- 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/svch…
==============================================================================
--- 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