Index: base/system/services/database.c =================================================================== --- base/system/services/database.c (revision 54342) +++ base/system/services/database.c (working copy) @@ -27,7 +27,7 @@ * Uncomment the line below to use asynchronous IO operations * on the service control pipes. */ -// #define USE_ASYNCHRONOUS_IO +#define USE_ASYNCHRONOUS_IO /* GLOBALS *******************************************************************/ @@ -193,7 +193,7 @@ /* Create a new service image */ pServiceImage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - FIELD_OFFSET(SERVICE_IMAGE, szImagePath[wcslen(ImagePath.Buffer) + 1])); + FIELD_OFFSET(SERVICE_IMAGE, szImagePath[ImagePath.Length / sizeof(WCHAR) + 1])); if (pServiceImage == NULL) { dwError = ERROR_NOT_ENOUGH_MEMORY; @@ -1407,7 +1407,7 @@ return ERROR_SERVICE_REQUEST_TIMEOUT; } - else if (dwError == ERROR_SUCCESS) + else if (dwError == WAIT_OBJECT_0) { bResult = GetOverlappedResult(Service->lpImage->hControlPipe, &Overlapped, @@ -1570,10 +1570,10 @@ return dwError; } - DPRINT("Process Id: %lu Handle %lx\n", + DPRINT("Process Id: %lu Handle %p\n", ProcessInformation.dwProcessId, ProcessInformation.hProcess); - DPRINT("Thread Id: %lu Handle %lx\n", + DPRINT("Thread Id: %lu Handle %p\n", ProcessInformation.dwThreadId, ProcessInformation.hThread); Index: base/system/services/rpcserver.c =================================================================== --- base/system/services/rpcserver.c (revision 54342) +++ base/system/services/rpcserver.c (working copy) @@ -792,7 +792,12 @@ { case SERVICE_STOP_PENDING: case SERVICE_STOPPED: - return ERROR_SERVICE_CANNOT_ACCEPT_CTRL; + RtlCopyMemory(lpServiceStatus, + &lpService->Status, + sizeof(SERVICE_STATUS)); + return dwControl == SERVICE_CONTROL_STOP && dwCurrentState == SERVICE_STOPPED + ? ERROR_SERVICE_NOT_ACTIVE + : ERROR_SERVICE_CANNOT_ACCEPT_CTRL; case SERVICE_START_PENDING: switch (dwControl) @@ -1460,7 +1465,7 @@ lpService->dwErrorControl = dwErrorControl; } -#if 0 +#if 1 /* FIXME: set the new ImagePath value */ /* Set the image path */ @@ -1480,14 +1485,14 @@ } else if (dwServiceType & SERVICE_DRIVER) { - if (lpImagePath != NULL && *lpImagePath != 0) + if (lpBinaryPathName != NULL && *lpBinaryPathName != 0) { dwError = RegSetValueExW(hServiceKey, L"ImagePath", 0, REG_EXPAND_SZ, - (LPBYTE)lpImagePath, - (wcslen(lpImagePath) + 1) *sizeof(WCHAR)); + (LPBYTE)lpBinaryPathName, + (wcslen(lpBinaryPathName) + 1) *sizeof(WCHAR)); if (dwError != ERROR_SUCCESS) goto done; } @@ -3240,7 +3245,7 @@ PSERVICE lpService = NULL; HKEY hServiceKey = NULL; LPWSTR lpDisplayNameW = NULL; - // LPWSTR lpBinaryPathNameW = NULL; + LPWSTR lpBinaryPathNameW = NULL; LPWSTR lpLoadOrderGroupW = NULL; LPWSTR lpDependenciesW = NULL; // LPWSTR lpPasswordW = NULL; @@ -3374,7 +3379,7 @@ lpService->dwErrorControl = dwErrorControl; } -#if 0 +#if 1 /* FIXME: set the new ImagePath value */ /* Set the image path */ @@ -3396,14 +3401,16 @@ } else if (dwServiceType & SERVICE_DRIVER) { - if (lpImagePath != NULL && *lpImagePath != 0) + if (lpBinaryPathName != NULL && *lpBinaryPathName != 0) { + lpBinaryPathNameW=HeapAlloc(GetProcessHeap(),0, (strlen(lpBinaryPathName)+1) * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, strlen(lpBinaryPathName)+1); dwError = RegSetValueExW(hServiceKey, L"ImagePath", 0, REG_EXPAND_SZ, - (LPBYTE)lpImagePath, - (wcslen(lpImagePath) + 1) *sizeof(WCHAR)); + (LPBYTE)lpBinaryPathNameW, + (wcslen(lpBinaryPathNameW) + 1) *sizeof(WCHAR)); if (dwError != ERROR_SUCCESS) goto done; } Index: modules/rostests/winetests/advapi32/service.c =================================================================== --- modules/rostests/winetests/advapi32/service.c (revision 54234) +++ modules/rostests/winetests/advapi32/service.c (working copy) @@ -1033,6 +1033,14 @@ else ok(statusproc->dwProcessId == 0, "Expect no process id for this stopped service\n"); + + /* same call with null needed pointer */ + SetLastError(0xdeadbeef); + ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, NULL); + ok(!ret, "Expected failure\n"); + ok(broken(GetLastError() == ERROR_INVALID_PARAMETER) /* NT4 */ || + GetLastError() == ERROR_INVALID_ADDRESS, "got %d\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, statusproc); CloseServiceHandle(svc_handle); @@ -2072,7 +2080,9 @@ DWORD le1, le2; SERVICE_STATUS status; + trace("Starting service, first time. Let's hope we don't get a test timeout\n"); ret = StartServiceA(svc_handle, 0, NULL); + trace("Started service, first time. Let's hope we don't get a test timeout\n"); le1 = GetLastError(); ok(!ret, "%s: StartServiceA() should have failed\n", name); @@ -2087,7 +2097,9 @@ ok(statusproc.dwProcessId == 0, "%s: ProcessId should be 0 instead of %x\n", name, statusproc.dwProcessId); } + trace("Starting service, second time. Let's hope we don't get a test timeout\n"); ret = StartServiceA(svc_handle, 0, NULL); + trace("Started service, second time. Let's hope we don't get a test timeout\n"); le2 = GetLastError(); ok(!ret, "%s: StartServiceA() should have failed\n", name); ok(le2 == le1, "%s: the second try should yield the same error: %u != %u\n", name, le1, le2);