From: Eric Kohl Date: Fri, 29 Aug 2008 11:15:53 +0000 (+0000) Subject: - QueryServiceConfig2A/W: Fail if lpBuffer is NULL but cbBufSize is not 0. X-Git-Tag: backups/umode-network-branch@37897~317 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=532fd2c7b0930f777cabaf3545fcdf86b1b8e876 - QueryServiceConfig2A/W: Fail if lpBuffer is NULL but cbBufSize is not 0. - RChangeServiceConfigW: Update the display name if it has been changed. - RQueryServiceConfigW: Return pointers to empty strings instead of NULL pointers if information is not available. - RQueryServiceConfig2W: Fail if lpBuffer is NULL. - Implement RChangeServiceConfigA, RQueryServiceConfigA and RQueryServiceConfig2A. Patch is based on bug report #3669 by bugboy . svn path=/trunk/; revision=35752 --- diff --git a/reactos/base/system/services/rpcserver.c b/reactos/base/system/services/rpcserver.c index e7902c9e02d..3088efca883 100644 --- a/reactos/base/system/services/rpcserver.c +++ b/reactos/base/system/services/rpcserver.c @@ -801,6 +801,7 @@ DWORD RChangeServiceConfigW( PSERVICE_HANDLE hSvc; PSERVICE lpService = NULL; HKEY hServiceKey = NULL; + LPWSTR lpDisplayNameW = NULL; DPRINT("RChangeServiceConfigW() called\n"); DPRINT("dwServiceType = %lu\n", dwServiceType); @@ -860,7 +861,21 @@ DWORD RChangeServiceConfigW( REG_SZ, (LPBYTE)lpDisplayName, (wcslen(lpDisplayName) + 1) * sizeof(WCHAR)); - /* FIXME: update lpService->lpDisplayName */ + + /* Update the display name */ + lpDisplayNameW = (LPWSTR)HeapAlloc(GetProcessHeap(), + 0, + (wcslen(lpDisplayName) + 1) * sizeof(WCHAR)); + if (lpDisplayNameW == NULL) + { + dwError = ERROR_NOT_ENOUGH_MEMORY; + goto done; + } + + if (lpService->lpDisplayName != lpService->lpServiceName) + HeapFree(GetProcessHeap(), 0, lpService->lpDisplayName); + + lpService->lpDisplayName = lpDisplayNameW; } if (dwServiceType != SERVICE_NO_CHANGE) @@ -2011,7 +2026,8 @@ DWORD RQueryServiceConfigW( LPWSTR lpImagePath = NULL; LPWSTR lpServiceStartName = NULL; DWORD dwRequiredSize; - LPQUERY_SERVICE_CONFIGW lpConfig; + LPQUERY_SERVICE_CONFIGW lpConfig = NULL; + WCHAR lpEmptyString[] = {0,0}; LPWSTR lpStr; DPRINT("RQueryServiceConfigW() called\n"); @@ -2062,17 +2078,25 @@ DWORD RQueryServiceConfigW( if (lpImagePath != NULL) dwRequiredSize += ((wcslen(lpImagePath) + 1) * sizeof(WCHAR)); + else + dwRequiredSize += 2 * sizeof(WCHAR); if (lpService->lpGroup != NULL) dwRequiredSize += ((wcslen(lpService->lpGroup->lpGroupName) + 1) * sizeof(WCHAR)); + else + dwRequiredSize += 2 * sizeof(WCHAR); /* FIXME: Add Dependencies length*/ if (lpServiceStartName != NULL) dwRequiredSize += ((wcslen(lpServiceStartName) + 1) * sizeof(WCHAR)); + else + dwRequiredSize += 2 * sizeof(WCHAR); if (lpService->lpDisplayName != NULL) dwRequiredSize += ((wcslen(lpService->lpDisplayName) + 1) * sizeof(WCHAR)); + else + dwRequiredSize += 2 * sizeof(WCHAR); if (lpServiceConfig == NULL || cbBufSize < dwRequiredSize) { @@ -2091,48 +2115,55 @@ DWORD RQueryServiceConfigW( if (lpImagePath != NULL) { wcscpy(lpStr, lpImagePath); - lpConfig->lpBinaryPathName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); - lpStr += (wcslen(lpImagePath) + 1); } else { - lpConfig->lpBinaryPathName = NULL; + wcscpy(lpStr, lpEmptyString); } + lpConfig->lpBinaryPathName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); + lpStr += (wcslen(lpStr) + 1); + if (lpService->lpGroup != NULL) { wcscpy(lpStr, lpService->lpGroup->lpGroupName); - lpConfig->lpLoadOrderGroup = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); - lpStr += (wcslen(lpService->lpGroup->lpGroupName) + 1); } else { - lpConfig->lpLoadOrderGroup = NULL; + wcscpy(lpStr, lpEmptyString); } + lpConfig->lpLoadOrderGroup = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); + lpStr += (wcslen(lpStr) + 1); + /* FIXME: Append Dependencies */ - lpConfig->lpDependencies = NULL; + wcscpy(lpStr, lpEmptyString); + + lpStr += (wcslen(lpStr) + 1); + lpConfig->lpDependencies = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); if (lpServiceStartName != NULL) { wcscpy(lpStr, lpServiceStartName); - lpConfig->lpServiceStartName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); - lpStr += (wcslen(lpServiceStartName) + 1); } else { - lpConfig->lpServiceStartName = NULL; + wcscpy(lpStr, lpEmptyString); } + lpConfig->lpServiceStartName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); + lpStr += (wcslen(lpStr) + 1); + if (lpService->lpDisplayName != NULL) { wcscpy(lpStr, lpService->lpDisplayName); - lpConfig->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); } else { - lpConfig->lpDisplayName = NULL; + wcscpy(lpStr, lpEmptyString); } + + lpConfig->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); } if (pcbBytesNeeded != NULL) @@ -2388,8 +2419,271 @@ DWORD RChangeServiceConfigA( DWORD dwPwSize, LPSTR lpDisplayName) { - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + DWORD dwError = ERROR_SUCCESS; + PSERVICE_HANDLE hSvc; + PSERVICE lpService = NULL; + HKEY hServiceKey = NULL; + LPWSTR lpDisplayNameW = NULL; + // LPWSTR lpBinaryPathNameW = NULL; + LPWSTR lpLoadOrderGroupW = NULL; + LPWSTR lpDependenciesW = NULL; + // LPWSTR lpPasswordW = NULL; + + DPRINT("RChangeServiceConfigA() called\n"); + DPRINT("dwServiceType = %lu\n", dwServiceType); + DPRINT("dwStartType = %lu\n", dwStartType); + DPRINT("dwErrorControl = %lu\n", dwErrorControl); + DPRINT("lpBinaryPathName = %s\n", lpBinaryPathName); + DPRINT("lpLoadOrderGroup = %s\n", lpLoadOrderGroup); + DPRINT("lpDisplayName = %s\n", lpDisplayName); + + if (ScmShutdown) + return ERROR_SHUTDOWN_IN_PROGRESS; + + hSvc = (PSERVICE_HANDLE)hService; + if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG) + { + DPRINT1("Invalid handle tag!\n"); + return ERROR_INVALID_HANDLE; + } + + if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess, + SERVICE_CHANGE_CONFIG)) + { + DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess); + return ERROR_ACCESS_DENIED; + } + + lpService = hSvc->ServiceEntry; + if (lpService == NULL) + { + DPRINT1("lpService == NULL!\n"); + return ERROR_INVALID_HANDLE; + } + + /* FIXME: Lock database exclusively */ + + if (lpService->bDeleted) + { + /* FIXME: Unlock database */ + DPRINT1("The service has already been marked for delete!\n"); + return ERROR_SERVICE_MARKED_FOR_DELETE; + } + + /* Open the service key */ + dwError = ScmOpenServiceKey(lpService->szServiceName, + KEY_SET_VALUE, + &hServiceKey); + if (dwError != ERROR_SUCCESS) + goto done; + + /* Write service data to the registry */ + + if (lpDisplayName != NULL && *lpDisplayName != 0) + { + /* Set the display name */ + lpDisplayNameW = HeapAlloc(GetProcessHeap(), + 0, + (strlen(lpDisplayName) + 1) * sizeof(WCHAR)); + if (lpDisplayNameW == NULL) + { + dwError = ERROR_NOT_ENOUGH_MEMORY; + goto done; + } + + MultiByteToWideChar(CP_ACP, + 0, + lpDisplayName, + -1, + lpDisplayNameW, + (wcslen(lpDisplayNameW) + 1) * sizeof(WCHAR)); + + RegSetValueExW(hServiceKey, + L"DisplayName", + 0, + REG_SZ, + (LPBYTE)lpDisplayNameW, + (wcslen(lpDisplayNameW) + 1) * sizeof(WCHAR)); + + /* Update lpService->lpDisplayName */ + if (lpService->lpDisplayName) + HeapFree(GetProcessHeap(), 0, lpService->lpDisplayName); + + lpService->lpDisplayName = lpDisplayNameW; + } + + if (dwServiceType != SERVICE_NO_CHANGE) + { + /* Set the service type */ + dwError = RegSetValueExW(hServiceKey, + L"Type", + 0, + REG_DWORD, + (LPBYTE)&dwServiceType, + sizeof(DWORD)); + if (dwError != ERROR_SUCCESS) + goto done; + + lpService->Status.dwServiceType = dwServiceType; + } + + if (dwStartType != SERVICE_NO_CHANGE) + { + /* Set the start value */ + dwError = RegSetValueExW(hServiceKey, + L"Start", + 0, + REG_DWORD, + (LPBYTE)&dwStartType, + sizeof(DWORD)); + if (dwError != ERROR_SUCCESS) + goto done; + + lpService->dwStartType = dwStartType; + } + + if (dwErrorControl != SERVICE_NO_CHANGE) + { + /* Set the error control value */ + dwError = RegSetValueExW(hServiceKey, + L"ErrorControl", + 0, + REG_DWORD, + (LPBYTE)&dwErrorControl, + sizeof(DWORD)); + if (dwError != ERROR_SUCCESS) + goto done; + + lpService->dwErrorControl = dwErrorControl; + } + +#if 0 + /* FIXME: set the new ImagePath value */ + + /* Set the image path */ + if (dwServiceType & SERVICE_WIN32) + { + if (lpBinaryPathName != NULL && *lpBinaryPathName != 0) + { + lpBinaryPathNameW=HeapAlloc(GetProcessHeap(),0, (strlen(lpBinaryPathName)+1) * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, (wcslen(lpBinaryPathNameW)+1) * sizeof(WCHAR)); + dwError = RegSetValueExW(hServiceKey, + L"ImagePath", + 0, + REG_EXPAND_SZ, + (LPBYTE)lpBinaryPathNameW, + (wcslen(lpBinaryPathNameW) + 1) * sizeof(WCHAR)); + if (dwError != ERROR_SUCCESS) + goto done; + } + } + else if (dwServiceType & SERVICE_DRIVER) + { + if (lpImagePath != NULL && *lpImagePath != 0) + { + dwError = RegSetValueExW(hServiceKey, + L"ImagePath", + 0, + REG_EXPAND_SZ, + (LPBYTE)lpImagePath, + (wcslen(lpImagePath) + 1) *sizeof(WCHAR)); + if (dwError != ERROR_SUCCESS) + goto done; + } + } +#endif + + /* Set the group name */ + if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0) + { + lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), + 0, + (strlen(lpLoadOrderGroup)+1) * sizeof(WCHAR)); + if (lpLoadOrderGroupW == NULL) + { + dwError = ERROR_NOT_ENOUGH_MEMORY; + goto done; + } + + MultiByteToWideChar(CP_ACP, + 0, + lpLoadOrderGroup, + -1, + lpLoadOrderGroupW, + (wcslen(lpLoadOrderGroupW) + 1) * sizeof(WCHAR)); + + dwError = RegSetValueExW(hServiceKey, + L"Group", + 0, + REG_SZ, + (LPBYTE)lpLoadOrderGroupW, + (wcslen(lpLoadOrderGroupW) + 1) * sizeof(WCHAR)); + if (dwError != ERROR_SUCCESS) + goto done; + + /* FIXME: Update lpService->lpServiceGroup */ + + HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW); + } + + if (lpdwTagId != NULL) + { + dwError = ScmAssignNewTag(lpService); + if (dwError != ERROR_SUCCESS) + goto done; + + dwError = RegSetValueExW(hServiceKey, + L"Tag", + 0, + REG_DWORD, + (LPBYTE)&lpService->dwTag, + sizeof(DWORD)); + if (dwError != ERROR_SUCCESS) + goto done; + + *lpdwTagId = lpService->dwTag; + } + + /* Write dependencies */ + if (lpDependencies != NULL && *lpDependencies != 0) + { + lpDependenciesW = HeapAlloc(GetProcessHeap(), + 0, + (strlen(lpDependencies)+1) * sizeof(WCHAR)); + if (lpDependenciesW == NULL) + { + dwError = ERROR_NOT_ENOUGH_MEMORY; + goto done; + } + + MultiByteToWideChar(CP_ACP, + 0, + lpDependencies, + dwDependSize, + lpDependenciesW, + (wcslen(lpDependenciesW)+1) * sizeof(WCHAR)); + + dwError = ScmWriteDependencies(hServiceKey, + (LPWSTR)lpDependenciesW, + dwDependSize); + + HeapFree(GetProcessHeap(), 0, lpDependenciesW); + } + + if (lpPassword != NULL) + { + /* FIXME: Write password */ + } + + /* FIXME: Unlock database */ + +done: + if (hServiceKey != NULL) + RegCloseKey(hServiceKey); + + DPRINT("RChangeServiceConfigA() done (Error %lu)\n", dwError); + + return dwError; } @@ -2528,8 +2822,204 @@ DWORD RQueryServiceConfigA( DWORD cbBufSize, LPBOUNDED_DWORD_8K pcbBytesNeeded) { - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + LPQUERY_SERVICE_CONFIGA lpServiceConfig = (LPQUERY_SERVICE_CONFIGA)lpBuf; + DWORD dwError = ERROR_SUCCESS; + PSERVICE_HANDLE hSvc; + PSERVICE lpService = NULL; + HKEY hServiceKey = NULL; + LPWSTR lpImagePath = NULL; + LPWSTR lpServiceStartName = NULL; + DWORD dwRequiredSize; + LPQUERY_SERVICE_CONFIGA lpConfig = NULL; + CHAR lpEmptyString[]={0,0}; + LPSTR lpStr; + + DPRINT("RQueryServiceConfigA() called\n"); + + if (ScmShutdown) + return ERROR_SHUTDOWN_IN_PROGRESS; + + hSvc = (PSERVICE_HANDLE)hService; + if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG) + { + DPRINT1("Invalid handle tag!\n"); + return ERROR_INVALID_HANDLE; + } + + if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess, + SERVICE_QUERY_CONFIG)) + { + DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess); + return ERROR_ACCESS_DENIED; + } + + lpService = hSvc->ServiceEntry; + if (lpService == NULL) + { + DPRINT1("lpService == NULL!\n"); + return ERROR_INVALID_HANDLE; + } + + /* FIXME: Lock the service database shared */ + + dwError = ScmOpenServiceKey(lpService->lpServiceName, + KEY_READ, + &hServiceKey); + if (dwError != ERROR_SUCCESS) + goto Done; + + dwError = ScmReadString(hServiceKey, + L"ImagePath", + &lpImagePath); + if (dwError != ERROR_SUCCESS) + goto Done; + + ScmReadString(hServiceKey, + L"ObjectName", + &lpServiceStartName); + + dwRequiredSize = sizeof(QUERY_SERVICE_CONFIGW); + + if (lpImagePath != NULL) + dwRequiredSize += wcslen(lpImagePath) + 1; + else + dwRequiredSize += 2; + + if (lpService->lpGroup != NULL) + dwRequiredSize += wcslen(lpService->lpGroup->lpGroupName) + 1; + else + dwRequiredSize += 2; + + /* FIXME: Add Dependencies length*/ + dwRequiredSize += 2; + + if (lpServiceStartName != NULL) + dwRequiredSize += wcslen(lpServiceStartName) + 1; + else + dwRequiredSize += 2; + + if (lpService->lpDisplayName != NULL) + dwRequiredSize += wcslen(lpService->lpDisplayName) + 1; + else + dwRequiredSize += 2; + + if (lpServiceConfig == NULL || cbBufSize < dwRequiredSize) + { + dwError = ERROR_INSUFFICIENT_BUFFER; + } + else + { + lpConfig = (LPQUERY_SERVICE_CONFIGA)lpServiceConfig; + lpConfig->dwServiceType = lpService->Status.dwServiceType; + lpConfig->dwStartType = lpService->dwStartType; + lpConfig->dwErrorControl = lpService->dwErrorControl; + lpConfig->dwTagId = lpService->dwTag; + + lpStr = (LPSTR)(lpServiceConfig + 1); + + /* NOTE: Strings that are NULL for QUERY_SERVICE_CONFIG are pointers to empty strings. + Verified in WINXP*/ + + if (lpImagePath) + { + WideCharToMultiByte(CP_ACP, + 0, + lpImagePath, + -1, + lpStr, + wcslen(lpImagePath), + 0, + 0); + } + else + { + strcpy(lpStr, lpEmptyString); + } + + lpConfig->lpBinaryPathName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); + lpStr += (strlen((LPSTR)lpStr) + 1); + + if (lpService->lpGroup) + { + WideCharToMultiByte(CP_ACP, + 0, + lpService->lpGroup->lpGroupName, + -1, + lpStr, + wcslen(lpService->lpGroup->lpGroupName), + 0, + 0); + } + else + { + strcpy(lpStr, lpEmptyString); + } + + lpConfig->lpLoadOrderGroup = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); + lpStr += (strlen(lpStr) + 1); + + /* FIXME: Append Dependencies */ + strcpy(lpStr, lpEmptyString); + + lpConfig->lpDependencies = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); + lpStr += (strlen(lpStr) + 1); + + if (lpServiceStartName) + { + WideCharToMultiByte(CP_ACP, + 0, + lpServiceStartName, + -1, + lpStr, + wcslen(lpServiceStartName), + 0, + 0); + } + else + { + strcpy(lpStr, lpEmptyString); + } + + lpConfig->lpServiceStartName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); + lpStr += (strlen(lpStr) + 1); + + if (lpService->lpDisplayName) + { + WideCharToMultiByte(CP_ACP, + 0, + lpService->lpDisplayName, + -1, + lpStr, + wcslen(lpService->lpDisplayName), + 0, + 0); + } + else + { + strcpy(lpStr, lpEmptyString); + } + + lpConfig->lpDisplayName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); + } + + if (pcbBytesNeeded != NULL) + *pcbBytesNeeded = dwRequiredSize; + +Done:; + if (lpImagePath != NULL) + HeapFree(GetProcessHeap(), 0, lpImagePath); + + if (lpServiceStartName != NULL) + HeapFree(GetProcessHeap(), 0, lpServiceStartName); + + if (hServiceKey != NULL) + RegCloseKey(hServiceKey); + + /* FIXME: Unlock the service database */ + + DPRINT("RQueryServiceConfigA() done\n"); + + return dwError; } @@ -2917,8 +3407,102 @@ DWORD RQueryServiceConfig2A( DWORD cbBufSize, LPBOUNDED_DWORD_8K pcbBytesNeeded) { - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + DWORD dwError = ERROR_SUCCESS; + PSERVICE_HANDLE hSvc; + PSERVICE lpService = NULL; + HKEY hServiceKey = NULL; + DWORD dwRequiredSize; + LPWSTR lpDescriptionW = NULL; + LPSTR lpDescription = NULL; + + DPRINT("RQueryServiceConfig2W() called\n"); + + if (!lpBuffer) + return ERROR_INVALID_ADDRESS; + + if (ScmShutdown) + return ERROR_SHUTDOWN_IN_PROGRESS; + + hSvc = (PSERVICE_HANDLE)hService; + if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG) + { + DPRINT1("Invalid handle tag!\n"); + return ERROR_INVALID_HANDLE; + } + + if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess, + SERVICE_QUERY_CONFIG)) + { + DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess); + return ERROR_ACCESS_DENIED; + } + + lpService = hSvc->ServiceEntry; + if (lpService == NULL) + { + DPRINT1("lpService == NULL!\n"); + return ERROR_INVALID_HANDLE; + } + + /* FIXME: Lock the service database shared */ + + dwError = ScmOpenServiceKey(lpService->lpServiceName, + KEY_READ, + &hServiceKey); + if (dwError != ERROR_SUCCESS) + goto done; + + if (dwInfoLevel & SERVICE_CONFIG_DESCRIPTION) + { + LPSERVICE_DESCRIPTIONA lpServiceDescription = (LPSERVICE_DESCRIPTIONA)lpBuffer; + LPSTR lpStr; + + dwError = ScmReadString(hServiceKey, + L"Description", + &lpDescriptionW); + if (dwError != ERROR_SUCCESS) + goto done; + + dwRequiredSize = sizeof(SERVICE_DESCRIPTIONA) + ((wcslen(lpDescriptionW) + 1)); + + if (cbBufSize < dwRequiredSize) + { + *pcbBytesNeeded = dwRequiredSize; + dwError = ERROR_INSUFFICIENT_BUFFER; + goto done; + } + + lpStr = (LPSTR)(lpServiceDescription + 1); + + WideCharToMultiByte(CP_ACP, + 0, + lpDescriptionW, + -1, + lpStr, + wcslen(lpDescriptionW), + NULL, + NULL); + lpServiceDescription->lpDescription = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription); + } + else if (dwInfoLevel & SERVICE_CONFIG_FAILURE_ACTIONS) + { + UNIMPLEMENTED; + dwError = ERROR_CALL_NOT_IMPLEMENTED; + goto done; + } + +done: + if (lpDescription != NULL) + HeapFree(GetProcessHeap(), 0, lpDescription); + + if (hServiceKey != NULL) + RegCloseKey(hServiceKey); + + /* FIXME: Unlock database */ + + DPRINT("RQueryServiceConfig2W() done (Error %lu)\n", dwError); + + return dwError; } @@ -2940,6 +3524,9 @@ DWORD RQueryServiceConfig2W( DPRINT("RQueryServiceConfig2W() called\n"); + if (!lpBuffer) + return ERROR_INVALID_ADDRESS; + if (ScmShutdown) return ERROR_SHUTDOWN_IN_PROGRESS; @@ -2991,12 +3578,10 @@ DWORD RQueryServiceConfig2W( dwError = ERROR_INSUFFICIENT_BUFFER; goto done; } - else - { - lpStr = (LPWSTR)(lpServiceDescription + 1); - wcscpy(lpStr, lpDescription); - lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription); - } + + lpStr = (LPWSTR)(lpServiceDescription + 1); + wcscpy(lpStr, lpDescription); + lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription); } else if (dwInfoLevel & SERVICE_CONFIG_FAILURE_ACTIONS) { diff --git a/reactos/dll/win32/advapi32/service/scm.c b/reactos/dll/win32/advapi32/service/scm.c index 44df54502f6..98b51b60620 100644 --- a/reactos/dll/win32/advapi32/service/scm.c +++ b/reactos/dll/win32/advapi32/service/scm.c @@ -1831,6 +1831,12 @@ QueryServiceConfig2A(SC_HANDLE hService, TRACE("QueryServiceConfig2A(%p, %lu, %p, %lu, %p)\n", hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded); + if (lpBuffer == NULL && cbBufSize != 0) + { + SetLastError(ERROR_INVALID_ADDRESS); + return FALSE; + } + HandleBind(); _SEH_TRY @@ -1915,6 +1921,12 @@ QueryServiceConfig2W(SC_HANDLE hService, TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n", hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded); + if (lpBuffer == NULL && cbBufSize != 0) + { + SetLastError(ERROR_INVALID_ADDRESS); + return FALSE; + } + HandleBind(); _SEH_TRY