advapi32/tests: Add tests for EnumServicesStatusExA.

oldstable
Paul Vriens 2008-08-21 17:18:41 +02:00 committed by Alexandre Julliard
parent ce64e0d055
commit f0a821a1ae
1 changed files with 401 additions and 0 deletions

View File

@ -34,6 +34,9 @@
static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms */
static BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID);
static BOOL (WINAPI *pEnumServicesStatusExA)(SC_HANDLE, SC_ENUM_TYPE, DWORD,
DWORD, LPBYTE, DWORD, LPDWORD,
LPDWORD, LPDWORD, LPCSTR);
static BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
static BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
static BOOL (WINAPI *pQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE,
@ -44,6 +47,7 @@ static void init_function_pointers(void)
HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
pChangeServiceConfig2A = (void*)GetProcAddress(hadvapi32, "ChangeServiceConfig2A");
pEnumServicesStatusExA= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExA");
pQueryServiceConfig2A= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2A");
pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2W");
pQueryServiceStatusEx= (void*)GetProcAddress(hadvapi32, "QueryServiceStatusEx");
@ -959,6 +963,7 @@ static void test_enum_svc(void)
DWORD drivercountactive, servicecountactive;
DWORD drivercountinactive, servicecountinactive;
ENUM_SERVICE_STATUS *services;
ENUM_SERVICE_STATUS_PROCESS *exservices;
INT i;
/* All NULL or wrong */
@ -1301,6 +1306,402 @@ static void test_enum_svc(void)
}
CloseServiceHandle(scm_handle);
/* More or less the same for EnumServicesStatusExA */
/* All NULL or wrong */
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(NULL, 1, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
ok(!ret, "Expected failure\n");
todo_wine
ok(GetLastError() == ERROR_INVALID_LEVEL,
"Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
/* All NULL or wrong, just the info level is correct */
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(NULL, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
ok(!ret, "Expected failure\n");
todo_wine
ok(GetLastError() == ERROR_INVALID_HANDLE,
"Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
/* Open the service control manager with not enough rights at first */
scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
/* Valid handle and info level but rest is still NULL or wrong */
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
ok(!ret, "Expected failure\n");
todo_wine
ok(GetLastError() == ERROR_INVALID_ADDRESS ||
GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
"Unexpected last error %d\n", GetLastError());
/* Don't specify the two required pointers */
needed = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, NULL, NULL, NULL);
ok(!ret, "Expected failure\n");
ok(needed == 0xdeadbeef, "Expected no change to the needed buffer variable\n");
todo_wine
ok(GetLastError() == ERROR_INVALID_ADDRESS ||
GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
"Unexpected last error %d\n", GetLastError());
/* Don't specify the two required pointers */
returned = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, NULL, &returned, NULL, NULL);
ok(!ret, "Expected failure\n");
todo_wine
{
ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n");
ok(GetLastError() == ERROR_INVALID_ADDRESS ||
GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
"Unexpected last error %d\n", GetLastError());
}
/* No valid servicetype and servicestate */
needed = 0xdeadbeef;
returned = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, &returned, NULL, NULL);
ok(!ret, "Expected failure\n");
ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
todo_wine
{
ok(needed == 0, "Expected needed buffer size to be set to 0, got %d\n", needed);
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
}
/* No valid servicestate */
needed = 0xdeadbeef;
returned = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, 0, NULL, 0,
&needed, &returned, NULL, NULL);
ok(!ret, "Expected failure\n");
ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
todo_wine
{
ok(needed == 0, "Expected needed buffer size to be set to 0, got %d\n", needed);
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
}
/* No valid servicetype */
needed = 0xdeadbeef;
returned = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(scm_handle, 0, 0, SERVICE_STATE_ALL, NULL, 0,
&needed, &returned, NULL, NULL);
ok(!ret, "Expected failure\n");
ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
todo_wine
{
ok(needed == 0, "Expected needed buffer size to be set to 0, got %d\n", needed);
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
}
/* No valid servicetype and servicestate and unknown service group */
needed = 0xdeadbeef;
returned = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed,
&returned, NULL, "deadbeef_group");
ok(!ret, "Expected failure\n");
ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
todo_wine
{
ok(needed == 0, "Expected needed buffer size to be set to 0, got %d\n", needed);
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
}
/* All parameters are correct but our access rights are wrong */
needed = 0xdeadbeef;
returned = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
NULL, 0, &needed, &returned, NULL, NULL);
ok(!ret, "Expected failure\n");
todo_wine
ok(needed == 0, "Expected needed buffer size to be set to 0, got %d\n", needed);
ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
ok(GetLastError() == ERROR_ACCESS_DENIED,
"Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
/* All parameters are correct, access rights are wrong but the
* group name won't be checked yet.
*/
needed = 0xdeadbeef;
returned = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
NULL, 0, &needed, &returned, NULL, "deadbeef_group");
ok(!ret, "Expected failure\n");
todo_wine
ok(needed == 0, "Expected needed buffer size to be set to 0, got %d\n", needed);
ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
ok(GetLastError() == ERROR_ACCESS_DENIED,
"Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
/* Open the service control manager with the needed rights */
CloseServiceHandle(scm_handle);
scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
/* All parameters are correct and the group will be checked */
needed = 0xdeadbeef;
returned = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
NULL, 0, &needed, &returned, NULL, "deadbeef_group");
ok(!ret, "Expected failure\n");
ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
todo_wine
{
ok(needed == 0, "Expected needed buffer size to be set to 0, got %d\n", needed);
ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
"Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
}
/* TODO: Create a test that makes sure we enumerate all services that don't
* belong to a group. (specifying "").
*/
/* All parameters are correct. Request the needed buffer size */
needed = 0xdeadbeef;
returned = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
NULL, 0, &needed, &returned, NULL, NULL);
ok(!ret, "Expected failure\n");
ok(returned == 0, "Expected no service returned, got %d\n", returned);
todo_wine
{
ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
ok(GetLastError() == ERROR_MORE_DATA,
"Expected ERROR_MORE_DATA, got %d\n", GetLastError());
}
/* Store the needed bytes */
tempneeded = needed;
/* Allocate the correct needed bytes */
exservices = HeapAlloc(GetProcessHeap(), 0, needed);
bufsize = needed;
needed = 0xdeadbeef;
returned = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
(BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL);
todo_wine
{
ok(ret, "Expected success\n");
ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
ok(returned == tempreturned, "Expected the same number of service from this function\n");
ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
GetLastError() == 0xdeadbeef /* NT4, XP and Vista */ ||
GetLastError() == ERROR_IO_PENDING /* W2K */,
"Unexpected last error %d\n", GetLastError());
}
HeapFree(GetProcessHeap(), 0, exservices);
/* Store the number of returned services */
tempreturned = returned;
/* Allocate less then the needed bytes and don't specify a resume handle */
exservices = HeapAlloc(GetProcessHeap(), 0, tempneeded - 1);
bufsize = tempneeded - 1;
needed = 0xdeadbeef;
returned = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
(BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL);
ok(!ret, "Expected failure\n");
todo_wine
{
ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
ok(returned == (tempreturned - 1), "Expected one service less to be returned\n");
ok(GetLastError() == ERROR_MORE_DATA,
"Expected ERROR_MORE_DATA, got %d\n", GetLastError());
}
HeapFree(GetProcessHeap(), 0, exservices);
/* Allocate less then the needed bytes, this time with a correct resume handle */
exservices = HeapAlloc(GetProcessHeap(), 0, tempneeded - 1);
bufsize = tempneeded - 1;
needed = 0xdeadbeef;
returned = 0xdeadbeef;
resume = 0;
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
(BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL);
ok(!ret, "Expected failure\n");
todo_wine
{
ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
ok(returned == (tempreturned - 1), "Expected one service less to be returned\n");
ok(resume, "Expected a resume handle\n");
ok(GetLastError() == ERROR_MORE_DATA,
"Expected ERROR_MORE_DATA, got %d\n", GetLastError());
}
HeapFree(GetProcessHeap(), 0, exservices);
/* Fetch that last service but pass a bigger buffer size */
exservices = HeapAlloc(GetProcessHeap(), 0, tempneeded);
bufsize = tempneeded;
needed = 0xdeadbeef;
returned = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
(BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL);
todo_wine
{
ok(ret, "Expected success\n");
ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
ok(returned == 1, "Expected only 1 service to be returned\n");
ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
GetLastError() == 0xdeadbeef /* NT4, XP and Vista */ ||
GetLastError() == ERROR_IO_PENDING /* W2K */,
"Unexpected last error %d\n", GetLastError());
}
ok(resume == 0, "Expected the resume handle to be 0\n");
HeapFree(GetProcessHeap(), 0, exservices);
/* See if things add up */
/* Get the number of active driver services */
pEnumServicesStatusExA(scm_handle, 0, SERVICE_DRIVER, SERVICE_ACTIVE,
NULL, 0, &needed, &returned, NULL, NULL);
exservices = HeapAlloc(GetProcessHeap(), 0, needed);
pEnumServicesStatusExA(scm_handle, 0, SERVICE_DRIVER, SERVICE_ACTIVE,
(BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL);
HeapFree(GetProcessHeap(), 0, exservices);
/* Store the number of active driver services */
drivercountactive = returned;
/* Get the number of inactive driver services */
pEnumServicesStatusExA(scm_handle, 0, SERVICE_DRIVER, SERVICE_INACTIVE,
NULL, 0, &needed, &returned, NULL, NULL);
exservices = HeapAlloc(GetProcessHeap(), 0, needed);
pEnumServicesStatusExA(scm_handle, 0, SERVICE_DRIVER, SERVICE_INACTIVE,
(BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
HeapFree(GetProcessHeap(), 0, exservices);
drivercountinactive = returned;
/* Get the number of driver services */
pEnumServicesStatusExA(scm_handle, 0, SERVICE_DRIVER, SERVICE_STATE_ALL,
NULL, 0, &needed, &returned, NULL, NULL);
exservices = HeapAlloc(GetProcessHeap(), 0, needed);
pEnumServicesStatusExA(scm_handle, 0, SERVICE_DRIVER, SERVICE_STATE_ALL,
(BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
HeapFree(GetProcessHeap(), 0, exservices);
/* Check if total is the same as active and inactive driver services */
ok(returned == (drivercountactive + drivercountinactive),
"Something wrong in the calculation\n");
/* Get the number of active win32 services */
pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE,
NULL, 0, &needed, &returned, NULL, NULL);
exservices = HeapAlloc(GetProcessHeap(), 0, needed);
pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE,
(BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
HeapFree(GetProcessHeap(), 0, exservices);
servicecountactive = returned;
/* Get the number of inactive win32 services */
pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE,
NULL, 0, &needed, &returned, NULL, NULL);
exservices = HeapAlloc(GetProcessHeap(), 0, needed);
pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE,
(BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
HeapFree(GetProcessHeap(), 0, exservices);
servicecountinactive = returned;
/* Get the number of win32 services */
pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
NULL, 0, &needed, &returned, NULL, NULL);
exservices = HeapAlloc(GetProcessHeap(), 0, needed);
pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
(BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
HeapFree(GetProcessHeap(), 0, exservices);
/* Check if total is the same as active and inactive win32 services */
ok(returned == (servicecountactive + servicecountinactive),
"Something wrong in the calculation\n");
/* Get the number of all services */
pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER,
SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL, NULL);
exservices = HeapAlloc(GetProcessHeap(), 0, needed);
pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER,
SERVICE_STATE_ALL, (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
/* Check if total is the same as all those single calls */
ok(returned == (drivercountactive + drivercountinactive + servicecountactive + servicecountinactive),
"Something wrong in the calculation\n");
/* Loop through all those returned services */
for (i = 0; i < returned; i++)
{
SERVICE_STATUS_PROCESS status = exservices[i].ServiceStatusProcess;
/* lpServiceName and lpDisplayName should always be filled */
ok(lstrlenA(exservices[i].lpServiceName) > 0, "Expected a service name\n");
ok(lstrlenA(exservices[i].lpDisplayName) > 0, "Expected a display name\n");
/* Decrement the counters to see if the functions calls return the
* same numbers as the contents of these structures.
* Check some process id specifics.
*/
if (status.dwServiceType & (SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER))
{
if (status.dwCurrentState == SERVICE_RUNNING)
drivercountactive--;
else
drivercountinactive--;
/* We shouldn't have a process id for drivers */
ok(status.dwProcessId == 0,
"This driver shouldn't have an associated process id\n");
}
if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS))
{
if (status.dwCurrentState == SERVICE_RUNNING)
{
/* We expect a process id for every running service */
ok(status.dwProcessId > 0, "Expected a process id for this running service (%s)\n",
exservices[i].lpServiceName);
servicecountactive--;
}
else
{
/* We shouldn't have a process id for inactive services */
ok(status.dwProcessId == 0, "This service shouldn't have an associated process id\n");
servicecountinactive--;
}
}
}
HeapFree(GetProcessHeap(), 0, exservices);
ok(drivercountactive == 0, "Active driver mismatch\n");
ok(drivercountinactive == 0, "Inactive driver mismatch\n");
ok(servicecountactive == 0, "Active services mismatch\n");
ok(servicecountinactive == 0, "Inactive services mismatch\n");
CloseServiceHandle(scm_handle);
}
static void test_close(void)