Index: svchost.c =================================================================== --- base/services/svchost/svchost.c (revision 59350) +++ base/services/svchost/svchost.c (working copy) @@ -1,9 +1,9 @@ /* - * 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) + * 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 ******************************************************************/ @@ -15,249 +15,273 @@ /* 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"); +static PCWSTR SVCHOST_REG_KEY = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SvcHost"; +static PCWSTR SERVICE_KEY = L"SYSTEM\\CurrentControlSet\\Services\\"; +static PCWSTR PARAMETERS_KEY = L"\\Parameters"; -#define SERVICE_KEY_LENGTH _tcslen(SERVICE_KEY); -#define REG_MAX_DATA_SIZE 2048 +#define REG_MAX_DATA_SIZE 2048 static PSERVICE FirstService = NULL; /* FUNCTIONS *****************************************************************/ -BOOL PrepareService(LPCTSTR ServiceName) +BOOL PrepareService(PCWSTR 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; + HKEY hServiceKey; + WCHAR ServiceKeyBuffer[MAX_PATH + 1]; + DWORD KeyType; + PWSTR Buffer = NULL; + DWORD BufferSize = (MAX_PATH + 1) * sizeof(WCHAR); + LONG RetVal; + HINSTANCE hServiceDll; + PWSTR DllPath; + DWORD DllPathSize; + 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); + /* Compose the registry path to the service's "Parameter" key */ + if (FAILED(StringCbCopy(ServiceKeyBuffer, sizeof(ServiceKeyBuffer), SERVICE_KEY))) + { + DPRINT1("Buffer overflow for service name: '%ls'\n", ServiceName); + return FALSE; + } - if (LeftOfBuffer < 0) - { - DPRINT1("Buffer overflow for service name: '%s'\n", ServiceName); - return FALSE; - } + if (FAILED(StringCbCat(ServiceKeyBuffer, sizeof(ServiceKeyBuffer), ServiceName))) + { + DPRINT1("Buffer overflow for service name: '%ls'\n", ServiceName); + return FALSE; + } + if (FAILED(StringCbCat(ServiceKeyBuffer, sizeof(ServiceKeyBuffer), PARAMETERS_KEY))) + { + DPRINT1("Buffer overflow for service name: '%ls'\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; - } + /* Open the service registry key to find the dll name */ + RetVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ServiceKeyBuffer, 0, KEY_READ, &hServiceKey); + if (RetVal != ERROR_SUCCESS) + { + DPRINT1("Could not open service key (%ls)\n", ServiceKeyBuffer); + return FALSE; + } - do - { - if (Buffer) - HeapFree(GetProcessHeap(), 0, Buffer); + 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; - } + Buffer = HeapAlloc(GetProcessHeap(), 0, BufferSize); + if (Buffer == NULL) + { + DPRINT1("Not enough memory for service: %ls\n", ServiceName); + return FALSE; + } - RetVal = RegQueryValueEx(hServiceKey, _T("ServiceDll"), NULL, &KeyType, (LPBYTE)Buffer, &BufferSize); + RetVal = RegQueryValueEx(hServiceKey, L"ServiceDll", NULL, &KeyType, (LPBYTE)Buffer, &BufferSize); - } while (ERROR_MORE_DATA == RetVal); + } while (RetVal == ERROR_MORE_DATA); + RegCloseKey(hServiceKey); - RegCloseKey(hServiceKey); + if (RetVal != ERROR_SUCCESS || BufferSize == 0) + { + DPRINT1("Could not read 'ServiceDll' value from service: %ls, ErrorCode: 0x%lx\n", ServiceName, RetVal); + HeapFree(GetProcessHeap(), 0, Buffer); + return FALSE; + } - 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; - } + if (KeyType == REG_EXPAND_SZ) + { + /* Convert possible %SystemRoot% to a real path */ + DllPathSize = ExpandEnvironmentStrings(Buffer, NULL, 0); + if (DllPathSize == 0) + { + DPRINT1("Invalid ServiceDll path: %ls, ErrorCode: %lu\n", Buffer, GetLastError()); + HeapFree(GetProcessHeap(), 0, Buffer); + return FALSE; + } + DllPath = HeapAlloc(GetProcessHeap(), 0, DllPathSize * sizeof(WCHAR)); + if (DllPath == NULL) + { + DPRINT1("Not enough memory for service: %ls\n", ServiceName); + HeapFree(GetProcessHeap(), 0, Buffer); + return FALSE; + } + if (ExpandEnvironmentStrings(Buffer, DllPath, DllPathSize) != DllPathSize) + { + DPRINT1("Invalid ServiceDll path: %ls, ErrorCode: %lu\n", Buffer, GetLastError()); + HeapFree(GetProcessHeap(), 0, DllPath); + HeapFree(GetProcessHeap(), 0, Buffer); + return FALSE; + } + } - /* Convert possible %SystemRoot% to a real path */ - BufferSize = ExpandEnvironmentStrings(Buffer, DllPath, _countof(DllPath)); - if (0 == BufferSize) - { - DPRINT1("Invalid ServiceDll path: %s\n", Buffer); - HeapFree(GetProcessHeap(), 0, Buffer); - return FALSE; - } + HeapFree(GetProcessHeap(), 0, Buffer); - HeapFree(GetProcessHeap(), 0, Buffer); + /* Load the service dll */ + DPRINT("Trying to load dll\n"); + hServiceDll = LoadLibrary(DllPath); + if (hServiceDll == NULL) + { + DPRINT1("Unable to load ServiceDll: %ls, ErrorCode: %lu\n", DllPath, GetLastError()); + HeapFree(GetProcessHeap(), 0, DllPath); + return FALSE; + } - /* Load the service dll */ - DPRINT("Trying to load dll\n"); - hServiceDll = LoadLibrary(DllPath); + HeapFree(GetProcessHeap(), 0, DllPath); - if (NULL == hServiceDll) - { - DPRINT1("Unable to load ServiceDll: %s, ErrorCode: %u\n", DllPath, GetLastError()); - return FALSE; - } + ServiceMainFunc = (LPSERVICE_MAIN_FUNCTION)GetProcAddress(hServiceDll, "ServiceMain"); - ServiceMainFunc = (LPSERVICE_MAIN_FUNCTION)GetProcAddress(hServiceDll, "ServiceMain"); + /* Allocate a service node in the linked list */ + Service = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SERVICE)); + if (Service == NULL) + { + DPRINT1("Not enough memory for service: %ls\n", ServiceName); + return FALSE; + } - /* 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; - } + Service->Name = HeapAlloc(GetProcessHeap(), 0, (wcslen(ServiceName) + 1) * sizeof(WCHAR)); + if (Service->Name == NULL) + { + DPRINT1("Not enough memory for service: %ls\n", ServiceName); + HeapFree(GetProcessHeap(), 0, Service); + return FALSE; + } + wcscpy(Service->Name, ServiceName); - memset(Service, 0, sizeof(SERVICE)); - Service->Name = HeapAlloc(GetProcessHeap(), 0, (_tcslen(ServiceName)+1) * 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->hServiceDll = hServiceDll; - Service->ServiceMainFunc = ServiceMainFunc; + Service->Next = FirstService; + FirstService = Service; - Service->Next = FirstService; - FirstService = Service; - - return TRUE; + return TRUE; } VOID FreeServices(VOID) { - while (FirstService) - { - PSERVICE Service = FirstService; - FirstService = Service->Next; + while (FirstService) + { + PSERVICE Service = FirstService; + FirstService = Service->Next; - FreeLibrary(Service->hServiceDll); + FreeLibrary(Service->hServiceDll); - HeapFree(GetProcessHeap(), 0, Service->Name); - HeapFree(GetProcessHeap(), 0, Service); - } + HeapFree(GetProcessHeap(), 0, Service->Name); + HeapFree(GetProcessHeap(), 0, Service); + } } /* * Returns the number of services successfully loaded from the category */ -DWORD LoadServiceCategory(LPCTSTR ServiceCategory) +DWORD LoadServiceCategory(PCWSTR ServiceCategory) { - HKEY hServicesKey; - DWORD KeyType; - DWORD BufferSize = REG_MAX_DATA_SIZE; - TCHAR Buffer[REG_MAX_DATA_SIZE]; - LPCTSTR ServiceName; - DWORD BufferIndex = 0; - DWORD NrOfServices = 0; + HKEY hServicesKey; + DWORD KeyType; + WCHAR Buffer[REG_MAX_DATA_SIZE]; + DWORD BufferSize = sizeof(Buffer); + PCWSTR ServiceName; + DWORD BufferIndex = 0; + DWORD NrOfServices = 0; + LONG RetVal; - /* 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 0; - } + /* Get all the services in this category */ + RetVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SVCHOST_REG_KEY, 0, KEY_READ, &hServicesKey); + if (RetVal != ERROR_SUCCESS) + { + DPRINT1("Could not open service category: %ls\n", ServiceCategory); + return 0; + } - if (ERROR_SUCCESS != RegQueryValueEx(hServicesKey, ServiceCategory, NULL, &KeyType, (LPBYTE)Buffer, &BufferSize)) - { - DPRINT1("Could not open service category (2): %s\n", ServiceCategory); - RegCloseKey(hServicesKey); - return 0; - } + RetVal = RegQueryValueEx(hServicesKey, ServiceCategory, NULL, &KeyType, (LPBYTE)Buffer, &BufferSize); + if (RetVal != ERROR_SUCCESS) + { + DPRINT1("Could not open service category (2): %ls\n", ServiceCategory); + RegCloseKey(hServicesKey); + return 0; + } - /* Clean up */ - RegCloseKey(hServicesKey); + /* 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; + /* Load services in the category */ + ServiceName = Buffer; + while (ServiceName[0] != UNICODE_NULL) + { + size_t Length; - if (TRUE == PrepareService(ServiceName)) - ++NrOfServices; + Length = wcslen(ServiceName); + if (Length == 0) + break; - BufferIndex += Length + 1; + if (PrepareService(ServiceName)) + ++NrOfServices; - ServiceName = &Buffer[BufferIndex]; - } + BufferIndex += Length + 1; - return NrOfServices; + ServiceName = &Buffer[BufferIndex]; + } + + return NrOfServices; } -int _tmain (int argc, LPTSTR argv []) +int wmain(int argc, wchar_t **argv) { - DWORD NrOfServices; - LPSERVICE_TABLE_ENTRY ServiceTable; + DWORD NrOfServices; + LPSERVICE_TABLE_ENTRY ServiceTable; - if (argc < 3) - { - /* MS svchost.exe doesn't seem to print help, should we? */ - return 0; - } + if (argc < 3) + { + /* MS svchost.exe doesn't seem to print help, should we? */ + return 0; + } - if (_tcscmp(argv[1], _T("-k")) != 0) - { - /* For now, we only handle "-k" */ - return 0; - } + if (wcscmp(argv[1], L"-k")) + { + /* For now, we only handle "-k" */ + return 0; + } - NrOfServices = LoadServiceCategory(argv[2]); + NrOfServices = LoadServiceCategory(argv[2]); - DPRINT("NrOfServices: %lu\n", NrOfServices); - if (0 == NrOfServices) - return 0; + DPRINT("NrOfServices: %lu\n", NrOfServices); + if (NrOfServices == 0) + return 0; - ServiceTable = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_TABLE_ENTRY) * (NrOfServices + 1)); + ServiceTable = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_TABLE_ENTRY) * (NrOfServices + 1)); + if (ServiceTable != NULL) + { + DWORD i; + PSERVICE Service = FirstService; - if (NULL != ServiceTable) - { - DWORD i; - PSERVICE Service = FirstService; + /* Fill the service table */ + for (i = 0; i < NrOfServices; i++) + { + DPRINT("Loading service: %ls\n", Service->Name); + ServiceTable[i].lpServiceName = Service->Name; + ServiceTable[i].lpServiceProc = Service->ServiceMainFunc; + Service = Service->Next; + } + ASSERT(Service == NULL); - /* Fill the service table */ - for (i = 0; i < NrOfServices; i++) - { - DPRINT("Loading service: %s\n", Service->Name); - ServiceTable[i].lpServiceName = Service->Name; - ServiceTable[i].lpServiceProc = Service->ServiceMainFunc; - Service = Service->Next; - } + /* Set a NULL entry to end the service table */ + ServiceTable[i].lpServiceName = NULL; + ServiceTable[i].lpServiceProc = NULL; - /* Set a NULL entry to end the service table */ - ServiceTable[i].lpServiceName = NULL; - ServiceTable[i].lpServiceProc = NULL; + if (!StartServiceCtrlDispatcher(ServiceTable)) + DPRINT1("Failed to start service control dispatcher, ErrorCode: %lu\n", GetLastError()); - if (FALSE == StartServiceCtrlDispatcher(ServiceTable)) - DPRINT1("Failed to start service control dispatcher, ErrorCode: %lu\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, ServiceTable); + } + else + { + DPRINT1("Not enough memory for the service table, trying to allocate %u bytes\n", sizeof(SERVICE_TABLE_ENTRY) * (NrOfServices + 1)); + } - HeapFree(GetProcessHeap(), 0, ServiceTable); - } - else - { - DPRINT1("Not enough memory for the service table, trying to allocate %u bytes\n", sizeof(SERVICE_TABLE_ENTRY) * (NrOfServices + 1)); - } + DPRINT("Freeing services...\n"); + FreeServices(); - DPRINT("Freeing services...\n"); - FreeServices(); - return 0; } Index: svchost.h =================================================================== --- base/services/svchost/svchost.h (revision 59350) +++ base/services/svchost/svchost.h (working copy) @@ -10,30 +10,25 @@ /* INCLUDES ******************************************************************/ -#if 0 -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif - #include #include #include #include #include #include -#include +#include /* DEFINES *******************************************************************/ -#define CS_TIMEOUT 1000 +#define CS_TIMEOUT 1000 typedef struct _SERVICE { - PTSTR Name; - HINSTANCE hServiceDll; - LPSERVICE_MAIN_FUNCTION ServiceMainFunc; - struct _SERVICE *Next; + PWSTR Name; + HINSTANCE hServiceDll; + LPSERVICE_MAIN_FUNCTION ServiceMainFunc; + struct _SERVICE *Next; } SERVICE, *PSERVICE; - /* FUNCTIONS *****************************************************************/ /* EOF */