X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fbase%2Fsystem%2Fservices%2Frpcserver.c;h=a5b7f9f1ea602e196ec8dbb49d2c3d292ce9bcc2;hp=5ffd2d91a412a7e34586592a1a20b80f678292eb;hb=d7117cdb17c53beabd4e30365158661d0574d17e;hpb=18922ff0a490685fda05a935fcec14372934bf09 diff --git a/reactos/base/system/services/rpcserver.c b/reactos/base/system/services/rpcserver.c index 5ffd2d91a41..a5b7f9f1ea6 100644 --- a/reactos/base/system/services/rpcserver.c +++ b/reactos/base/system/services/rpcserver.c @@ -1282,7 +1282,11 @@ DWORD RChangeServiceConfigW( (wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR)); if (dwError != ERROR_SUCCESS) goto done; - /* FIXME: Update lpService->lpServiceGroup */ + + dwError = ScmSetServiceGroup(lpService, + lpLoadOrderGroup); + if (dwError != ERROR_SUCCESS) + goto done; } if (lpdwTagId != NULL) @@ -1729,6 +1733,7 @@ DWORD RCreateServiceW( SC_HANDLE hServiceHandle = NULL; LPWSTR lpImagePath = NULL; HKEY hServiceKey = NULL; + LPWSTR lpObjectName; DPRINT("RCreateServiceW() called\n"); DPRINT("lpServiceName = %S\n", lpServiceName); @@ -1969,15 +1974,16 @@ DWORD RCreateServiceW( goto done; } - /* If a non driver and NULL for lpServiceName, write ObjectName as LocalSystem */ - if ((dwServiceType & SERVICE_WIN32) && (!lpServiceName)) + /* Write service start name */ + if (dwServiceType & SERVICE_WIN32) { + lpObjectName = (lpServiceStartName != NULL) ? (LPWSTR)lpServiceStartName : L"LocalSystem"; dwError = RegSetValueExW(hServiceKey, L"ObjectName", 0, REG_SZ, - (LPBYTE)L"LocalSystem", - 24); + (LPBYTE)lpObjectName, + (wcslen(lpObjectName) + 1) * sizeof(WCHAR)); if (dwError != ERROR_SUCCESS) goto done; } @@ -2228,7 +2234,8 @@ DWORD REnumServicesStatusW( return ERROR_ACCESS_DENIED; } - if (lpResumeHandle) dwLastResumeCount = *lpResumeHandle; + if (lpResumeHandle) + dwLastResumeCount = *lpResumeHandle; /* FIXME: Lock the service list shared */ @@ -2306,7 +2313,9 @@ DWORD REnumServicesStatusW( DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize); - if (lpResumeHandle) *lpResumeHandle = dwLastResumeCount; + if (lpResumeHandle) + *lpResumeHandle = dwLastResumeCount; + *lpServicesReturned = dwServiceCount; *pcbBytesNeeded = dwRequiredSize; @@ -2513,6 +2522,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}; @@ -2552,16 +2563,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) @@ -2574,7 +2592,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)); @@ -2600,6 +2621,7 @@ DWORD RQueryServiceConfigW( lpStr = (LPWSTR)(lpConfig + 1); + /* Append the image path */ if (lpImagePath != NULL) { wcscpy(lpStr, lpImagePath); @@ -2612,6 +2634,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); @@ -2624,12 +2647,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); @@ -2642,6 +2678,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); @@ -2664,6 +2701,9 @@ Done:; if (lpServiceStartName != NULL) HeapFree(GetProcessHeap(), 0, lpServiceStartName); + if (lpDependencies != NULL) + HeapFree(GetProcessHeap(), 0, lpDependencies); + if (hServiceKey != NULL) RegCloseKey(hServiceKey); @@ -2772,11 +2812,11 @@ DWORD RGetServiceDisplayNameW( { 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) + /* If the service could not be found and lpcchBuffer is less than 2, windows + puts null in lpDisplayName and puts 2 in lpcchBuffer */ + if (*lpcchBuffer < 2) { - *lpcchBuffer = 1; + *lpcchBuffer = 2; if (lpDisplayName != NULL) { *lpDisplayName = '\0'; @@ -2846,9 +2886,9 @@ DWORD RGetServiceKeyNameW( { DPRINT1("Could not find a service!\n"); - /* If the service could not be found and lpcchBuffer is 0, windows + /* If the service could not be found and lpcchBuffer is less than 2, windows puts null in lpDisplayName and puts 2 in lpcchBuffer */ - if (*lpcchBuffer == 0) + if (*lpcchBuffer < 2) { *lpcchBuffer = 2; if (lpServiceName != NULL) @@ -3054,7 +3094,7 @@ DWORD RChangeServiceConfigA( if (lpBinaryPathName != NULL && *lpBinaryPathName != 0) { lpBinaryPathNameW=HeapAlloc(GetProcessHeap(),0, (strlen(lpBinaryPathName)+1) * sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, wcslen(lpBinaryPathNameW)+1); + MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, strlen(lpBinaryPathName)+1); dwError = RegSetValueExW(hServiceKey, L"ImagePath", 0, @@ -3086,7 +3126,7 @@ DWORD RChangeServiceConfigA( { lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), 0, - (strlen(lpLoadOrderGroup)+1) * sizeof(WCHAR)); + (strlen(lpLoadOrderGroup) + 1) * sizeof(WCHAR)); if (lpLoadOrderGroupW == NULL) { dwError = ERROR_NOT_ENOUGH_MEMORY; @@ -3098,7 +3138,7 @@ DWORD RChangeServiceConfigA( lpLoadOrderGroup, -1, lpLoadOrderGroupW, - wcslen(lpLoadOrderGroupW) + 1); + strlen(lpLoadOrderGroup) + 1); dwError = RegSetValueExW(hServiceKey, L"Group", @@ -3107,11 +3147,18 @@ DWORD RChangeServiceConfigA( (LPBYTE)lpLoadOrderGroupW, (wcslen(lpLoadOrderGroupW) + 1) * sizeof(WCHAR)); if (dwError != ERROR_SUCCESS) + { + HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW); goto done; + } - /* FIXME: Update lpService->lpServiceGroup */ + dwError = ScmSetServiceGroup(lpService, + lpLoadOrderGroupW); HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW); + + if (dwError != ERROR_SUCCESS) + goto done; } if (lpdwTagId != NULL) @@ -3137,7 +3184,7 @@ DWORD RChangeServiceConfigA( { lpDependenciesW = HeapAlloc(GetProcessHeap(), 0, - (strlen(lpDependencies)+1) * sizeof(WCHAR)); + (strlen(lpDependencies) + 1) * sizeof(WCHAR)); if (lpDependenciesW == NULL) { dwError = ERROR_NOT_ENOUGH_MEMORY; @@ -3149,7 +3196,7 @@ DWORD RChangeServiceConfigA( lpDependencies, dwDependSize, lpDependenciesW, - wcslen(lpDependenciesW)+1); + strlen(lpDependencies) + 1); dwError = ScmWriteDependencies(hServiceKey, (LPWSTR)lpDependenciesW, @@ -3194,8 +3241,135 @@ DWORD RCreateServiceA( DWORD dwPwSize, LPSC_RPC_HANDLE lpServiceHandle) { - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + DWORD dwError = ERROR_SUCCESS; + LPWSTR lpServiceNameW = NULL; + LPWSTR lpDisplayNameW = NULL; + LPWSTR lpBinaryPathNameW = NULL; + LPWSTR lpLoadOrderGroupW = NULL; + LPWSTR lpDependenciesW = NULL; + LPWSTR lpServiceStartNameW = NULL; + DWORD dwDependenciesLength = 0; + DWORD dwLength; + int len; + LPSTR lpStr; + + if (lpServiceName) + { + len = MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, NULL, 0); + lpServiceNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!lpServiceNameW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto cleanup; + } + MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, lpServiceNameW, len); + } + + if (lpDisplayName) + { + len = MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, NULL, 0); + lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!lpDisplayNameW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto cleanup; + } + MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len); + } + + if (lpBinaryPathName) + { + len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0); + lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!lpBinaryPathNameW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto cleanup; + } + MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len); + } + + if (lpLoadOrderGroup) + { + len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0); + lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!lpLoadOrderGroupW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto cleanup; + } + MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len); + } + + if (lpDependencies) + { + lpStr = (LPSTR)lpDependencies; + while (*lpStr) + { + dwLength = strlen(lpStr) + 1; + dwDependenciesLength += dwLength; + lpStr = lpStr + dwLength; + } + dwDependenciesLength++; + + lpDependenciesW = HeapAlloc(GetProcessHeap(), 0, dwDependenciesLength * sizeof(WCHAR)); + if (!lpDependenciesW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto cleanup; + } + MultiByteToWideChar(CP_ACP, 0, (LPSTR)lpDependencies, dwDependenciesLength, lpDependenciesW, dwDependenciesLength); + } + + if (lpServiceStartName) + { + len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0); + lpServiceStartNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!lpServiceStartNameW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto cleanup; + } + MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len); + } + + dwError = RCreateServiceW(hSCManager, + lpServiceNameW, + lpDisplayNameW, + dwDesiredAccess, + dwServiceType, + dwStartType, + dwErrorControl, + lpBinaryPathNameW, + lpLoadOrderGroupW, + lpdwTagId, + (LPBYTE)lpDependenciesW, + dwDependenciesLength, + lpServiceStartNameW, + lpPassword, + dwPwSize, + lpServiceHandle); + +cleanup: + if (lpServiceNameW !=NULL) + HeapFree(GetProcessHeap(), 0, lpServiceNameW); + + if (lpDisplayNameW != NULL) + HeapFree(GetProcessHeap(), 0, lpDisplayNameW); + + if (lpBinaryPathNameW != NULL) + HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW); + + if (lpLoadOrderGroupW != NULL) + HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW); + + if (lpDependenciesW != NULL) + HeapFree(GetProcessHeap(), 0, lpDependenciesW); + + if (lpServiceStartNameW != NULL) + HeapFree(GetProcessHeap(), 0, lpServiceStartNameW); + + return dwError; } @@ -3244,7 +3418,8 @@ DWORD REnumDependentServicesA( KEY_READ, &hServicesKey); - if (dwError != ERROR_SUCCESS) return dwError; + if (dwError != ERROR_SUCCESS) + return dwError; /* NOTE: Windows calculates the pcbBytesNeeded based on WCHAR strings for both EnumDependentServicesA and EnumDependentServicesW. So returned pcbBytesNeeded @@ -3376,8 +3551,7 @@ DWORD REnumServicesStatusA( } } - dwError = REnumServicesStatusW(//BindingHandle, - hSCManager, + dwError = REnumServicesStatusW(hSCManager, dwServiceType, dwServiceState, (LPBYTE)lpStatusPtrW, @@ -3387,7 +3561,8 @@ DWORD REnumServicesStatusA( lpResumeHandle); /* if no services were returned then we are Done */ - if (*lpServicesReturned == 0) goto Done; + if (*lpServicesReturned == 0) + goto Done; lpStatusPtrA = (LPENUM_SERVICE_STATUSA)lpBuffer; lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer + @@ -3434,7 +3609,8 @@ DWORD REnumServicesStatusA( } Done:; - if (lpStatusPtrW) HeapFree(GetProcessHeap(), 0, lpStatusPtrW); + if (lpStatusPtrW) + HeapFree(GetProcessHeap(), 0, lpStatusPtrW); DPRINT("REnumServicesStatusA() done (Error %lu)\n", dwError); @@ -3463,8 +3639,7 @@ DWORD ROpenSCManagerA( RtlCreateUnicodeStringFromAsciiz(&DatabaseName, lpDatabaseName); - dwError = ROpenSCManagerW(//BindingHandle, - lpMachineName ? MachineName.Buffer : NULL, + dwError = ROpenSCManagerW(lpMachineName ? MachineName.Buffer : NULL, lpDatabaseName ? DatabaseName.Buffer : NULL, dwDesiredAccess, lpScHandle); @@ -3495,8 +3670,7 @@ DWORD ROpenServiceA( RtlCreateUnicodeStringFromAsciiz(&ServiceName, lpServiceName); - dwError = ROpenServiceW(//BindingHandle, - hSCManager, + dwError = ROpenServiceW(hSCManager, lpServiceName ? ServiceName.Buffer : NULL, dwDesiredAccess, lpServiceHandle); @@ -3522,6 +3696,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}; @@ -3561,16 +3737,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) @@ -3578,13 +3761,16 @@ DWORD RQueryServiceConfigA( else dwRequiredSize += 2; - if (lpService->lpGroup != NULL) + if ((lpService->lpGroup != NULL) && (lpService->lpGroup->lpGroupName != NULL)) dwRequiredSize += wcslen(lpService->lpGroup->lpGroupName) + 1; 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; @@ -3620,7 +3806,7 @@ DWORD RQueryServiceConfigA( lpImagePath, -1, lpStr, - wcslen(lpImagePath)+1, + wcslen(lpImagePath) + 1, 0, 0); } @@ -3632,14 +3818,14 @@ DWORD RQueryServiceConfigA( lpConfig->lpBinaryPathName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig); lpStr += (strlen((LPSTR)lpStr) + 1); - if (lpService->lpGroup) + if (lpService->lpGroup && lpService->lpGroup->lpGroupName) { WideCharToMultiByte(CP_ACP, 0, lpService->lpGroup->lpGroupName, -1, lpStr, - wcslen(lpService->lpGroup->lpGroupName)+1, + wcslen(lpService->lpGroup->lpGroupName) + 1, 0, 0); } @@ -3651,11 +3837,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) { @@ -3664,7 +3867,7 @@ DWORD RQueryServiceConfigA( lpServiceStartName, -1, lpStr, - wcslen(lpServiceStartName)+1, + wcslen(lpServiceStartName) + 1, 0, 0); } @@ -3683,7 +3886,7 @@ DWORD RQueryServiceConfigA( lpService->lpDisplayName, -1, lpStr, - wcslen(lpService->lpDisplayName)+1, + wcslen(lpService->lpDisplayName) + 1, 0, 0); } @@ -3705,6 +3908,9 @@ Done:; if (lpServiceStartName != NULL) HeapFree(GetProcessHeap(), 0, lpServiceStartName); + if (lpDependencies != NULL) + HeapFree(GetProcessHeap(), 0, lpDependencies); + if (hServiceKey != NULL) RegCloseKey(hServiceKey); @@ -3950,8 +4156,8 @@ DWORD RGetServiceKeyNameA( 0, lpService->lpServiceName, wcslen(lpService->lpServiceName), - lpServiceName + 1, - dwLength, + lpServiceName, + dwLength + 1, NULL, NULL); return ERROR_SUCCESS; @@ -4012,33 +4218,36 @@ DWORD RChangeServiceConfig2A( if (InfoW.dwInfoLevel == SERVICE_CONFIG_DESCRIPTION) { - LPSERVICE_DESCRIPTIONW lpServiceDesriptonW; - LPSERVICE_DESCRIPTIONA lpServiceDesriptonA; + LPSERVICE_DESCRIPTIONW lpServiceDescriptonW; + LPSERVICE_DESCRIPTIONA lpServiceDescriptonA; - lpServiceDesriptonA = Info.psd; + lpServiceDescriptonA = Info.psd; - if (lpServiceDesriptonA && - lpServiceDesriptonA->lpDescription) - { - dwLength = (strlen(lpServiceDesriptonA->lpDescription) + 1) * sizeof(WCHAR); + ///if (lpServiceDescriptonA && + ///lpServiceDescriptonA->lpDescription) + ///{ + dwLength = (strlen(Info.lpDescription) + 1) * sizeof(WCHAR); - lpServiceDesriptonW = HeapAlloc(GetProcessHeap(), + lpServiceDescriptonW = HeapAlloc(GetProcessHeap(), 0, dwLength + sizeof(SERVICE_DESCRIPTIONW)); - if (!lpServiceDesriptonW) + if (!lpServiceDescriptonW) { return ERROR_NOT_ENOUGH_MEMORY; } + lpServiceDescriptonW->lpDescription = (LPWSTR)(lpServiceDescriptonW + 1); + MultiByteToWideChar(CP_ACP, 0, - lpServiceDesriptonA->lpDescription, + Info.lpDescription, -1, - lpServiceDesriptonW->lpDescription, + lpServiceDescriptonW->lpDescription, dwLength); - ptr = lpServiceDesriptonW; - } + ptr = lpServiceDescriptonW; + InfoW.psd = lpServiceDescriptonW; + ///} } else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS) { @@ -4162,12 +4371,13 @@ DWORD RChangeServiceConfig2W( { LPSERVICE_DESCRIPTIONW lpServiceDescription; - lpServiceDescription = (LPSERVICE_DESCRIPTIONW)&Info; - lpServiceDescription->lpDescription = (LPWSTR)(&Info + sizeof(LPSERVICE_DESCRIPTIONW)); + lpServiceDescription = (LPSERVICE_DESCRIPTIONW)Info.psd; + lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpServiceDescription + sizeof(LPSERVICE_DESCRIPTIONW)); if (lpServiceDescription != NULL && lpServiceDescription->lpDescription != NULL) { + DPRINT1("Setting value %S\n", lpServiceDescription->lpDescription); RegSetValueExW(hServiceKey, L"Description", 0, @@ -4212,7 +4422,8 @@ DWORD RQueryServiceConfig2A( LPWSTR lpDescriptionW = NULL; LPSTR lpDescription = NULL; - DPRINT("RQueryServiceConfig2W() called\n"); + 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; @@ -4249,7 +4460,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; @@ -4261,7 +4472,7 @@ DWORD RQueryServiceConfig2A( &lpDescriptionW); if (dwError == ERROR_SUCCESS) { - *pcbBytesNeeded += ((wcslen(lpDescriptionW) + 1)); + *pcbBytesNeeded += ((wcslen(lpDescriptionW) + 1) * sizeof(WCHAR)); } if (cbBufSize >= *pcbBytesNeeded) @@ -4284,11 +4495,13 @@ DWORD RQueryServiceConfig2A( else { lpServiceDescription->lpDescription = NULL; + goto done; } } else { dwError = ERROR_INSUFFICIENT_BUFFER; + goto done; } } else if (dwInfoLevel & SERVICE_CONFIG_FAILURE_ACTIONS) @@ -4327,6 +4540,8 @@ DWORD RQueryServiceConfig2W( HKEY hServiceKey = NULL; DWORD dwRequiredSize; LPWSTR lpDescription = NULL; + LPWSTR lpFailureCommand = NULL; + LPWSTR lpRebootMessage = NULL; DPRINT("RQueryServiceConfig2W() called\n"); @@ -4365,7 +4580,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; @@ -4389,10 +4604,57 @@ 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; + UNIMPLEMENTED; - dwError = ERROR_CALL_NOT_IMPLEMENTED; + + dwError = ScmReadString(hServiceKey, + L"FailureCommand", + &lpFailureCommand); + + dwError = ScmReadString(hServiceKey, + L"RebootMessage", + &lpRebootMessage); + + dwRequiredSize = sizeof(SERVICE_FAILURE_ACTIONSW); + + if (lpFailureCommand) + dwRequiredSize += (wcslen(lpFailureCommand) + 1) * sizeof(WCHAR); + + if (lpRebootMessage) + dwRequiredSize += (wcslen(lpRebootMessage) + 1) * sizeof(WCHAR); + + if (cbBufSize < dwRequiredSize) + { + *pcbBytesNeeded = dwRequiredSize; + dwError = ERROR_INSUFFICIENT_BUFFER; + goto done; + } + + lpFailureActions->cActions = 0; + lpFailureActions->dwResetPeriod = 0; + lpFailureActions->lpCommand = NULL; + lpFailureActions->lpRebootMsg = NULL; + lpFailureActions->lpsaActions = NULL; + + lpStr = (LPWSTR)(lpFailureActions + 1); + if (lpRebootMessage) + { + wcscpy(lpStr, lpRebootMessage); + lpFailureActions->lpRebootMsg = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpRebootMessage); + lpStr += wcslen(lpRebootMessage) + 1; + } + + if (lpFailureCommand) + { + wcscpy(lpStr, lpFailureCommand); + lpFailureActions->lpCommand = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpFailureCommand); + lpStr += wcslen(lpRebootMessage) + 1; + } + dwError = STATUS_SUCCESS; goto done; } @@ -4400,6 +4662,12 @@ done: if (lpDescription != NULL) HeapFree(GetProcessHeap(), 0, lpDescription); + if (lpRebootMessage != NULL) + HeapFree(GetProcessHeap(), 0, lpRebootMessage); + + if (lpFailureCommand != NULL) + HeapFree(GetProcessHeap(), 0, lpFailureCommand); + if (hServiceKey != NULL) RegCloseKey(hServiceKey); @@ -4502,6 +4770,7 @@ DWORD REnumServicesStatusExA( DPRINT1("Failed to allocate buffer!\n"); return ERROR_NOT_ENOUGH_MEMORY; } + MultiByteToWideChar(CP_ACP, 0, pszGroupName, @@ -4532,7 +4801,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 + @@ -4581,9 +4851,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); @@ -4767,7 +5039,9 @@ DWORD REnumServicesStatusExW( DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize); - if (lpResumeIndex) *lpResumeIndex = dwLastResumeCount; + if (lpResumeIndex) + *lpResumeIndex = dwLastResumeCount; + *lpServicesReturned = dwServiceCount; *pcbBytesNeeded = dwRequiredSize; @@ -4853,7 +5127,8 @@ DWORD REnumServicesStatusExW( if (dwError == 0) { *pcbBytesNeeded = 0; - if (lpResumeIndex) *lpResumeIndex = 0; + if (lpResumeIndex) + *lpResumeIndex = 0; } Done:; @@ -5023,7 +5298,7 @@ DWORD RFunction55( } -void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) +void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len) { return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); }