From b1d48577f8fd315e29160ffc080d803889084d6c Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Fri, 29 Aug 2008 10:01:06 +0000 Subject: [PATCH] - GetServiceDisplayNameA/W and GetServiceKeyNameA/W: Fix returned name size. - RGetServiceDisplayNameW: Return the service name if the display name is not available. - Implement RGetServiceDisplayNameA and RGetServiceKeyNameA. svn path=/trunk/; revision=35748 --- reactos/base/system/services/rpcserver.c | 208 +++++++++++++++++++++-- reactos/dll/win32/advapi32/service/scm.c | 20 ++- 2 files changed, 208 insertions(+), 20 deletions(-) diff --git a/reactos/base/system/services/rpcserver.c b/reactos/base/system/services/rpcserver.c index 77baac1c323..416cc13f502 100644 --- a/reactos/base/system/services/rpcserver.c +++ b/reactos/base/system/services/rpcserver.c @@ -2241,15 +2241,37 @@ DWORD RGetServiceDisplayNameW( if (lpService == NULL) { DPRINT1("Could not find a service!\n"); + + /* If the service could not be found and lpcchBuffer is 0, windows + puts null in lpDisplayName and puts 1 in lpcchBuffer */ + if (*lpcchBuffer == 0) + { + *lpcchBuffer = 1; + *lpDisplayName = '\0'; + } + return ERROR_SERVICE_DOES_NOT_EXIST; } - dwLength = wcslen(lpService->lpDisplayName) + 1; + if (!lpService->lpDisplayName) + { + dwLength = wcslen(lpService->lpServiceName); - if (lpDisplayName != NULL && - *lpcchBuffer >= dwLength) + if (lpServiceName != NULL && + *lpcchBuffer > dwLength) + { + wcscpy(lpDisplayName, lpService->lpServiceName); + } + } + else { - wcscpy(lpDisplayName, lpService->lpDisplayName); + dwLength = wcslen(lpService->lpDisplayName); + + if (lpDisplayName != NULL && + *lpcchBuffer > dwLength) + { + wcscpy(lpDisplayName, lpService->lpDisplayName); + } } dwError = (*lpcchBuffer > dwLength) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER; @@ -2291,20 +2313,31 @@ DWORD RGetServiceKeyNameW( if (lpService == NULL) { DPRINT1("Could not find a service!\n"); + + /* If the service could not be found and lpcchBuffer is 0, windows + puts null in lpDisplayName and puts 2 in lpcchBuffer */ + if (*lpcchBuffer == 0) + { + *lpcchBuffer = 2; + *lpServiceName = '\0'; + } + return ERROR_SERVICE_DOES_NOT_EXIST; } - dwLength = wcslen(lpService->lpServiceName) + 1; + dwLength = wcslen(lpService->lpServiceName); if (lpServiceName != NULL && - *lpcchBuffer >= dwLength) + *lpcchBuffer > dwLength) { wcscpy(lpServiceName, lpService->lpServiceName); + *lpcchBuffer = dwLength; + return ERROR_SUCCESS; } dwError = (*lpcchBuffer > dwLength) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER; - *lpcchBuffer = dwLength; + *lpcchBuffer = dwLength * 2; return dwError; } @@ -2559,8 +2592,97 @@ DWORD RGetServiceDisplayNameA( LPSTR lpDisplayName, LPBOUNDED_DWORD_4K lpcchBuffer) { - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; +// PMANAGER_HANDLE hManager; + PSERVICE lpService; + DWORD dwLength; + DWORD dwError; + LPWSTR lpServiceNameW; + + DPRINT("RGetServiceDisplayNameA() called\n"); + DPRINT("hSCManager = %p\n", hSCManager); + DPRINT("lpServiceName: %s\n", lpServiceName); + DPRINT("lpDisplayName: %p\n", lpDisplayName); + DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer); + +// hManager = (PMANAGER_HANDLE)hSCManager; +// if (hManager->Handle.Tag != MANAGER_TAG) +// { +// DPRINT1("Invalid manager handle!\n"); +// return ERROR_INVALID_HANDLE; +// } + + dwLength = strlen(lpServiceName) + 1; + lpServiceNameW = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + dwLength * sizeof(WCHAR)); + if (!lpServiceNameW) + return ERROR_NOT_ENOUGH_MEMORY; + + MultiByteToWideChar(CP_ACP, + 0, + lpServiceName, + strlen(lpServiceName), + lpServiceNameW, + dwLength); + + lpService = ScmGetServiceEntryByName(lpServiceNameW); + + HeapFree(GetProcessHeap(), 0, lpServiceNameW); + + if (lpService == NULL) + { + DPRINT1("Could not find a service!\n"); + + /* If the service could not be found and lpcchBuffer is 0, windows + puts null in lpDisplayName and puts 1 in lpcchBuffer */ + if (*lpcchBuffer == 0) + { + *lpcchBuffer = 1; + *lpDisplayName = '\0'; + } + return ERROR_SERVICE_DOES_NOT_EXIST; + } + + if (!lpService->lpDisplayName) + { + dwLength = wcslen(lpService->lpServiceName); + if (lpServiceName != NULL && + *lpcchBuffer > dwLength) + { + WideCharToMultiByte(CP_ACP, + 0, + lpService->lpServiceName, + wcslen(lpService->lpServiceName), + lpDisplayName, + *lpcchBuffer, + NULL, + NULL); + return ERROR_SUCCESS; + } + } + else + { + dwLength = wcslen(lpService->lpDisplayName); + if (lpDisplayName != NULL && + *lpcchBuffer > dwLength) + { + WideCharToMultiByte(CP_ACP, + 0, + lpService->lpDisplayName, + wcslen(lpService->lpDisplayName), + lpDisplayName, + *lpcchBuffer, + NULL, + NULL); + return ERROR_SUCCESS; + } + } + + dwError = (*lpcchBuffer > dwLength) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER; + + *lpcchBuffer = dwLength * 2; + + return dwError; } @@ -2569,11 +2691,73 @@ DWORD RGetServiceKeyNameA( handle_t BindingHandle, SC_RPC_HANDLE hSCManager, LPSTR lpDisplayName, - LPSTR lpKeyName, + LPSTR lpServiceName, LPBOUNDED_DWORD_4K lpcchBuffer) { - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + PSERVICE lpService; + DWORD dwLength; + DWORD dwError; + LPWSTR lpDisplayNameW; + + DPRINT("RGetServiceKeyNameA() called\n"); + DPRINT("hSCManager = %p\n", hSCManager); + DPRINT("lpDisplayName: %s\n", lpDisplayName); + DPRINT("lpServiceName: %p\n", lpServiceName); + DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer); + + dwLength = strlen(lpDisplayName) + 1; + lpDisplayNameW = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + dwLength * sizeof(WCHAR)); + if (!lpDisplayNameW) + return ERROR_NOT_ENOUGH_MEMORY; + + MultiByteToWideChar(CP_ACP, + 0, + lpDisplayName, + strlen(lpDisplayName), + lpDisplayNameW, + dwLength); + + lpService = ScmGetServiceEntryByDisplayName(lpDisplayNameW); + + HeapFree(GetProcessHeap(), 0, lpDisplayNameW); + + if (lpService == NULL) + { + DPRINT1("Could not find the service!\n"); + + /* If the service could not be found and lpcchBuffer is 0, + put null in lpDisplayName and puts 1 in lpcchBuffer, verified WINXP. */ + if (*lpcchBuffer == 0) + { + *lpcchBuffer = 1; + *lpServiceName = '\0'; + } + + return ERROR_SERVICE_DOES_NOT_EXIST; + } + + dwLength = wcslen(lpService->lpServiceName); + if (lpService != NULL && + *lpcchBuffer > dwLength) + { + WideCharToMultiByte(CP_ACP, + 0, + lpService->lpServiceName, + wcslen(lpService->lpServiceName), + lpServiceName, + dwLength, + NULL, + NULL); + return ERROR_SUCCESS; + } + + dwError = (*lpcchBuffer > dwLength) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER; + + *lpcchBuffer = dwLength * 2; + + return dwError; } diff --git a/reactos/dll/win32/advapi32/service/scm.c b/reactos/dll/win32/advapi32/service/scm.c index 52c36981709..44df54502f6 100644 --- a/reactos/dll/win32/advapi32/service/scm.c +++ b/reactos/dll/win32/advapi32/service/scm.c @@ -1227,6 +1227,9 @@ GetServiceDisplayNameA(SC_HANDLE hSCManager, TRACE("GetServiceDisplayNameA() called\n"); + if (!lpDisplayName) + *lpcchBuffer = 0; + HandleBind(); _SEH_TRY @@ -1253,8 +1256,6 @@ GetServiceDisplayNameA(SC_HANDLE hSCManager, return FALSE; } - (*lpcchBuffer)--; - return TRUE; } @@ -1274,6 +1275,9 @@ GetServiceDisplayNameW(SC_HANDLE hSCManager, TRACE("GetServiceDisplayNameW() called\n"); + if (!lpDisplayName) + *lpcchBuffer = 0; + HandleBind(); _SEH_TRY @@ -1297,8 +1301,6 @@ GetServiceDisplayNameW(SC_HANDLE hSCManager, return FALSE; } - (*lpcchBuffer)--; - return TRUE; } @@ -1318,6 +1320,9 @@ GetServiceKeyNameA(SC_HANDLE hSCManager, TRACE("GetServiceKeyNameA() called\n"); + if (!lpServiceName) + *lpcchBuffer = 0; + HandleBind(); _SEH_TRY @@ -1341,8 +1346,6 @@ GetServiceKeyNameA(SC_HANDLE hSCManager, return FALSE; } - (*lpcchBuffer)--; - return TRUE; } @@ -1362,6 +1365,9 @@ GetServiceKeyNameW(SC_HANDLE hSCManager, TRACE("GetServiceKeyNameW() called\n"); + if (!lpDisplayName) + *lpcchBuffer = 0; + HandleBind(); _SEH_TRY @@ -1385,8 +1391,6 @@ GetServiceKeyNameW(SC_HANDLE hSCManager, return FALSE; } - (*lpcchBuffer)--; - return TRUE; } -- 2.17.1