From d1ffae9c3b44422332d85eaa74eba63e52553874 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Fri, 25 Dec 2009 15:08:03 +0000 Subject: [PATCH] RQueryServiceConfigA/W: Add missing dependency information. svn path=/trunk/; revision=44759 --- reactos/base/system/services/config.c | 121 ++++++++++++++++++++++- reactos/base/system/services/rpcserver.c | 115 ++++++++++++++++----- reactos/base/system/services/services.h | 5 + 3 files changed, 218 insertions(+), 23 deletions(-) diff --git a/reactos/base/system/services/config.c b/reactos/base/system/services/config.c index 18705e692c7..b056af5c86c 100644 --- a/reactos/base/system/services/config.c +++ b/reactos/base/system/services/config.c @@ -300,5 +300,124 @@ done: return dwError; } -/* EOF */ +DWORD +ScmReadDependencies(HKEY hServiceKey, + LPWSTR *lpDependencies, + DWORD *lpdwDependenciesLength) +{ + LPWSTR lpGroups = NULL; + LPWSTR lpServices = NULL; + DWORD dwGroupsLength = 0; + DWORD dwServicesLength = 0; + LPWSTR lpSrc; + LPWSTR lpDest; + DWORD len; + DWORD dwTotalLength; + + *lpDependencies = NULL; + *lpdwDependenciesLength = 0; + + /* Read the dependency values */ + ScmReadString(hServiceKey, + L"DependOnGroup", + &lpGroups); + + ScmReadString(hServiceKey, + L"DependOnService", + &lpServices); + + /* Leave, if there are no dependencies */ + if (lpGroups == NULL && lpServices == NULL) + return ERROR_SUCCESS; + + /* Determine the total buffer size for the dependencies */ + if (lpGroups) + { + DPRINT("Groups:\n"); + lpSrc = lpGroups; + while (*lpSrc != 0) + { + DPRINT(" %S\n", lpSrc); + + len = wcslen(lpSrc) + 1; + dwGroupsLength += len + 1; + + lpSrc = lpSrc + len; + } + } + + if (lpServices) + { + DPRINT("Services:\n"); + lpSrc = lpServices; + while (*lpSrc != 0) + { + DPRINT(" %S\n", lpSrc); + + len = wcslen(lpSrc) + 1; + dwServicesLength += len; + + lpSrc = lpSrc + len; + } + } + + dwTotalLength = dwGroupsLength + dwServicesLength + 1; + DPRINT("dwTotalLength: %lu\n", dwTotalLength); + + /* Allocate the common buffer for the dependencies */ + *lpDependencies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwTotalLength * sizeof(WCHAR)); + if (*lpDependencies == NULL) + { + if (lpGroups) + HeapFree(GetProcessHeap(), 0, lpGroups); + + if (lpServices) + HeapFree(GetProcessHeap(), 0, lpServices); + + return ERROR_NOT_ENOUGH_MEMORY; + } + + /* Return the allocated buffer length in characters */ + *lpdwDependenciesLength = dwTotalLength; + + /* Copy the service dependencies into the common buffer */ + lpDest = *lpDependencies; + if (lpServices) + { + memcpy(lpDest, + lpServices, + dwServicesLength * sizeof(WCHAR)); + + lpDest = lpDest + dwServicesLength; + } + + /* Copy the group dependencies into the common buffer */ + if (lpGroups) + { + lpSrc = lpGroups; + while (*lpSrc != 0) + { + len = wcslen(lpSrc) + 1; + + *lpDest = SC_GROUP_IDENTIFIERW; + lpDest++; + + wcscpy(lpDest, lpSrc); + + lpDest = lpDest + len; + lpSrc = lpSrc + len; + } + } + + /* Free the temporary buffers */ + if (lpGroups) + HeapFree(GetProcessHeap(), 0, lpGroups); + + if (lpServices) + HeapFree(GetProcessHeap(), 0, lpServices); + + return ERROR_SUCCESS; +} + +/* EOF */ diff --git a/reactos/base/system/services/rpcserver.c b/reactos/base/system/services/rpcserver.c index 18541ecb835..e11507a1068 100644 --- a/reactos/base/system/services/rpcserver.c +++ b/reactos/base/system/services/rpcserver.c @@ -2521,6 +2521,8 @@ DWORD RQueryServiceConfigW( HKEY hServiceKey = NULL; LPWSTR lpImagePath = NULL; LPWSTR lpServiceStartName = NULL; + LPWSTR lpDependencies = NULL; + DWORD dwDependenciesLength = 0; DWORD dwRequiredSize; LPQUERY_SERVICE_CONFIGW lpConfig = NULL; WCHAR lpEmptyString[] = {0,0}; @@ -2560,16 +2562,23 @@ DWORD RQueryServiceConfigW( if (dwError != ERROR_SUCCESS) goto Done; + /* Read the image path */ dwError = ScmReadString(hServiceKey, L"ImagePath", &lpImagePath); if (dwError != ERROR_SUCCESS) goto Done; + /* Read the service start name */ ScmReadString(hServiceKey, L"ObjectName", &lpServiceStartName); + /* Read the dependencies */ + ScmReadDependencies(hServiceKey, + &lpDependencies, + &dwDependenciesLength); + dwRequiredSize = sizeof(QUERY_SERVICE_CONFIGW); if (lpImagePath != NULL) @@ -2582,7 +2591,10 @@ DWORD RQueryServiceConfigW( else dwRequiredSize += 2 * sizeof(WCHAR); - /* FIXME: Add Dependencies length*/ + if (lpDependencies != NULL) + dwRequiredSize += dwDependenciesLength * sizeof(WCHAR); + else + dwRequiredSize += 2 * sizeof(WCHAR); if (lpServiceStartName != NULL) dwRequiredSize += ((wcslen(lpServiceStartName) + 1) * sizeof(WCHAR)); @@ -2608,6 +2620,7 @@ DWORD RQueryServiceConfigW( lpStr = (LPWSTR)(lpConfig + 1); + /* Append the image path */ if (lpImagePath != NULL) { wcscpy(lpStr, lpImagePath); @@ -2620,6 +2633,7 @@ DWORD RQueryServiceConfigW( lpConfig->lpBinaryPathName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); lpStr += (wcslen(lpStr) + 1); + /* Append the group name */ if (lpService->lpGroup != NULL) { wcscpy(lpStr, lpService->lpGroup->lpGroupName); @@ -2632,12 +2646,25 @@ DWORD RQueryServiceConfigW( lpConfig->lpLoadOrderGroup = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); lpStr += (wcslen(lpStr) + 1); - /* FIXME: Append Dependencies */ - wcscpy(lpStr, lpEmptyString); + /* Append Dependencies */ + if (lpDependencies != NULL) + { + memcpy(lpStr, + lpDependencies, + dwDependenciesLength * sizeof(WCHAR)); + } + else + { + wcscpy(lpStr, lpEmptyString); + } - lpStr += (wcslen(lpStr) + 1); lpConfig->lpDependencies = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); + if (lpDependencies != NULL) + lpStr += dwDependenciesLength * sizeof(WCHAR); + else + lpStr += (wcslen(lpStr) + 1); + /* Append the service start name */ if (lpServiceStartName != NULL) { wcscpy(lpStr, lpServiceStartName); @@ -2650,6 +2677,7 @@ DWORD RQueryServiceConfigW( lpConfig->lpServiceStartName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); lpStr += (wcslen(lpStr) + 1); + /* Append the display name */ if (lpService->lpDisplayName != NULL) { wcscpy(lpStr, lpService->lpDisplayName); @@ -2672,6 +2700,9 @@ Done:; if (lpServiceStartName != NULL) HeapFree(GetProcessHeap(), 0, lpServiceStartName); + if (lpDependencies != NULL) + HeapFree(GetProcessHeap(), 0, lpDependencies); + if (hServiceKey != NULL) RegCloseKey(hServiceKey); @@ -3537,6 +3568,8 @@ DWORD RQueryServiceConfigA( HKEY hServiceKey = NULL; LPWSTR lpImagePath = NULL; LPWSTR lpServiceStartName = NULL; + LPWSTR lpDependencies = NULL; + DWORD dwDependenciesLength = 0; DWORD dwRequiredSize; LPQUERY_SERVICE_CONFIGA lpConfig = NULL; CHAR lpEmptyString[]={0,0}; @@ -3576,16 +3609,23 @@ DWORD RQueryServiceConfigA( if (dwError != ERROR_SUCCESS) goto Done; + /* Read the image path */ dwError = ScmReadString(hServiceKey, L"ImagePath", &lpImagePath); if (dwError != ERROR_SUCCESS) goto Done; + /* Read the service start name */ ScmReadString(hServiceKey, L"ObjectName", &lpServiceStartName); + /* Read the dependencies */ + ScmReadDependencies(hServiceKey, + &lpDependencies, + &dwDependenciesLength); + dwRequiredSize = sizeof(QUERY_SERVICE_CONFIGW); if (lpImagePath != NULL) @@ -3598,8 +3638,11 @@ DWORD RQueryServiceConfigA( else dwRequiredSize += 2; - /* FIXME: Add Dependencies length*/ - dwRequiredSize += 2; + /* Add Dependencies length */ + if (lpDependencies != NULL) + dwRequiredSize += dwDependenciesLength; + else + dwRequiredSize += 2; if (lpServiceStartName != NULL) dwRequiredSize += wcslen(lpServiceStartName) + 1; @@ -3635,7 +3678,7 @@ DWORD RQueryServiceConfigA( lpImagePath, -1, lpStr, - wcslen(lpImagePath)+1, + wcslen(lpImagePath) + 1, 0, 0); } @@ -3654,7 +3697,7 @@ DWORD RQueryServiceConfigA( lpService->lpGroup->lpGroupName, -1, lpStr, - wcslen(lpService->lpGroup->lpGroupName)+1, + wcslen(lpService->lpGroup->lpGroupName) + 1, 0, 0); } @@ -3666,11 +3709,28 @@ DWORD RQueryServiceConfigA( lpConfig->lpLoadOrderGroup = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); lpStr += (strlen(lpStr) + 1); - /* FIXME: Append Dependencies */ - strcpy(lpStr, lpEmptyString); + /* Append Dependencies */ + if (lpDependencies) + { + WideCharToMultiByte(CP_ACP, + 0, + lpDependencies, + dwDependenciesLength, + lpStr, + dwDependenciesLength, + 0, + 0); + } + else + { + strcpy(lpStr, lpEmptyString); + } lpConfig->lpDependencies = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); - lpStr += (strlen(lpStr) + 1); + if (lpDependencies) + lpStr += dwDependenciesLength; + else + lpStr += (strlen(lpStr) + 1); if (lpServiceStartName) { @@ -3679,7 +3739,7 @@ DWORD RQueryServiceConfigA( lpServiceStartName, -1, lpStr, - wcslen(lpServiceStartName)+1, + wcslen(lpServiceStartName) + 1, 0, 0); } @@ -3698,7 +3758,7 @@ DWORD RQueryServiceConfigA( lpService->lpDisplayName, -1, lpStr, - wcslen(lpService->lpDisplayName)+1, + wcslen(lpService->lpDisplayName) + 1, 0, 0); } @@ -3720,6 +3780,9 @@ Done:; if (lpServiceStartName != NULL) HeapFree(GetProcessHeap(), 0, lpServiceStartName); + if (lpDependencies != NULL) + HeapFree(GetProcessHeap(), 0, lpDependencies); + if (hServiceKey != NULL) RegCloseKey(hServiceKey); @@ -4231,7 +4294,8 @@ DWORD RQueryServiceConfig2A( LPWSTR lpDescriptionW = NULL; LPSTR lpDescription = NULL; - DPRINT1("RQueryServiceConfig2A() called hService %p dwInfoLevel %u, lpBuffer %p cbBufSize %u pcbBytesNeeded %p\n",hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded); + DPRINT1("RQueryServiceConfig2A() called hService %p dwInfoLevel %u, lpBuffer %p cbBufSize %u pcbBytesNeeded %p\n", + hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded); if (!lpBuffer) return ERROR_INVALID_ADDRESS; @@ -4268,7 +4332,7 @@ DWORD RQueryServiceConfig2A( if (dwError != ERROR_SUCCESS) goto done; - if (dwInfoLevel & SERVICE_CONFIG_DESCRIPTION) + if (dwInfoLevel == SERVICE_CONFIG_DESCRIPTION) { LPSERVICE_DESCRIPTIONA lpServiceDescription = (LPSERVICE_DESCRIPTIONA)lpBuffer; LPSTR lpStr; @@ -4388,7 +4452,7 @@ DWORD RQueryServiceConfig2W( if (dwError != ERROR_SUCCESS) goto done; - if (dwInfoLevel & SERVICE_CONFIG_DESCRIPTION) + if (dwInfoLevel == SERVICE_CONFIG_DESCRIPTION) { LPSERVICE_DESCRIPTIONW lpServiceDescription = (LPSERVICE_DESCRIPTIONW)lpBuffer; LPWSTR lpStr; @@ -4412,7 +4476,7 @@ DWORD RQueryServiceConfig2W( wcscpy(lpStr, lpDescription); lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription); } - else if (dwInfoLevel & SERVICE_CONFIG_FAILURE_ACTIONS) + else if (dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS) { LPWSTR lpStr; LPSERVICE_FAILURE_ACTIONSW lpFailureActions = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer; @@ -4578,6 +4642,7 @@ DWORD REnumServicesStatusExA( DPRINT1("Failed to allocate buffer!\n"); return ERROR_NOT_ENOUGH_MEMORY; } + MultiByteToWideChar(CP_ACP, 0, pszGroupName, @@ -4608,7 +4673,8 @@ DWORD REnumServicesStatusExA( pszGroupNameW); /* if no services were returned then we are Done */ - if (*lpServicesReturned == 0) goto Done; + if (*lpServicesReturned == 0) + goto Done; lpStatusPtrA = (LPENUM_SERVICE_STATUS_PROCESSA)lpBuffer; lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer + @@ -4657,9 +4723,11 @@ DWORD REnumServicesStatusExA( } Done:; - if (pszGroupNameW) HeapFree(GetProcessHeap(), 0, pszGroupNameW); + if (pszGroupNameW) + HeapFree(GetProcessHeap(), 0, pszGroupNameW); - if (lpStatusPtrW) HeapFree(GetProcessHeap(), 0, lpStatusPtrW); + if (lpStatusPtrW) + HeapFree(GetProcessHeap(), 0, lpStatusPtrW); DPRINT("REnumServicesStatusExA() done (Error %lu)\n", dwError); @@ -4843,7 +4911,9 @@ DWORD REnumServicesStatusExW( DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize); - if (lpResumeIndex) *lpResumeIndex = dwLastResumeCount; + if (lpResumeIndex) + *lpResumeIndex = dwLastResumeCount; + *lpServicesReturned = dwServiceCount; *pcbBytesNeeded = dwRequiredSize; @@ -4929,7 +4999,8 @@ DWORD REnumServicesStatusExW( if (dwError == 0) { *pcbBytesNeeded = 0; - if (lpResumeIndex) *lpResumeIndex = 0; + if (lpResumeIndex) + *lpResumeIndex = 0; } Done:; diff --git a/reactos/base/system/services/services.h b/reactos/base/system/services/services.h index 07ceebbcdb3..23022dc2c92 100644 --- a/reactos/base/system/services/services.h +++ b/reactos/base/system/services/services.h @@ -92,6 +92,11 @@ DWORD ScmReadString(HKEY hServiceKey, LPWSTR lpValueName, LPWSTR *lpValue); +DWORD +ScmReadDependencies(HKEY hServiceKey, + LPWSTR *lpDependencies, + DWORD *lpdwDependenciesLength); + /* database.c */