diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index d95796f5f87..802dcaa24d6 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -1321,6 +1321,18 @@ CreateServiceW( SC_HANDLE hSCManager, LPCWSTR lpServiceName, return NULL; } + if (!lpServiceName[0]) + { + SetLastError(ERROR_INVALID_NAME); + return NULL; + } + + if (!lpBinaryPathName[0]) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + r = RegCreateKeyExW(hscm->hkey, lpServiceName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dp); if (r!=ERROR_SUCCESS) diff --git a/dlls/advapi32/tests/service.c b/dlls/advapi32/tests/service.c index 0003db53b62..d383feeafbd 100644 --- a/dlls/advapi32/tests/service.c +++ b/dlls/advapi32/tests/service.c @@ -188,6 +188,38 @@ static void test_create_delete_svc(void) ok(!svc_handle1, "Expected failure\n"); ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); + /* Open the Service Control Manager with minimal rights for creation (verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE') */ + CloseServiceHandle(scm_handle); + SetLastError(0xdeadbeef); + scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE); + if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED)) + { + skip("Not enough rights to get a handle to the manager\n"); + return; + } + + /* Empty strings for servicename and binary name are checked */ + SetLastError(0xdeadbeef); + svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL); + ok(!svc_handle1, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL); + ok(!svc_handle1, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL); + ok(!svc_handle1, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError()); + + /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed an ERROR_INVALID_PARAMETER */ + SetLastError(0xdeadbeef); + svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL); + ok(!svc_handle1, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + CloseServiceHandle(scm_handle); }