mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 14:43:02 +00:00
[SVCHOST]
- Convert tabs to spaces. No code changes. svn path=/trunk/; revision=59357
This commit is contained in:
parent
14e80363be
commit
52a90949ed
2 changed files with 193 additions and 194 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue