Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573/* * PROJECT: ReactOS api tests * LICENSE: GPLv2+ - See COPYING in the top level directory * PURPOSE: Test for QueryServiceConfig2A/W * PROGRAMMER: Hermès BÉLUSCA - MAÏTO */
#include "precomp.h"
#define TESTING_SERVICEW L"Spooler"#define TESTING_SERVICEA "Spooler"
/* * Taken from base/system/services/config.c and adapted. */static DWORDRegReadStringW(HKEY hKey, LPWSTR lpValueName, LPWSTR *lpValue){ DWORD dwError; DWORD dwSize; DWORD dwType;
*lpValue = NULL;
dwSize = 0; dwError = RegQueryValueExW(hKey, lpValueName, 0, &dwType, NULL, &dwSize); if (dwError != ERROR_SUCCESS) return dwError;
*lpValue = HeapAlloc(GetProcessHeap(), 0, dwSize); if (*lpValue == NULL) return ERROR_NOT_ENOUGH_MEMORY;
dwError = RegQueryValueExW(hKey, lpValueName, 0, &dwType, (LPBYTE)*lpValue, &dwSize); if (dwError != ERROR_SUCCESS) { HeapFree(GetProcessHeap(), 0, *lpValue); *lpValue = NULL; }
return dwError;}
static DWORDRegReadStringA(HKEY hKey, LPSTR lpValueName, LPSTR *lpValue){ DWORD dwError; DWORD dwSize; DWORD dwType;
*lpValue = NULL;
dwSize = 0; dwError = RegQueryValueExA(hKey, lpValueName, 0, &dwType, NULL, &dwSize); if (dwError != ERROR_SUCCESS) return dwError;
*lpValue = HeapAlloc(GetProcessHeap(), 0, dwSize); if (*lpValue == NULL) return ERROR_NOT_ENOUGH_MEMORY;
dwError = RegQueryValueExA(hKey, lpValueName, 0, &dwType, (LPBYTE)*lpValue, &dwSize); if (dwError != ERROR_SUCCESS) { HeapFree(GetProcessHeap(), 0, *lpValue); *lpValue = NULL; }
return dwError;}
static int QueryConfig2W(SC_HANDLE hService, LPCWSTR serviceName, DWORD dwInfoLevel){ int iRet = 0; LONG lRet = 0; DWORD dwRet = 0; BOOL bError = FALSE; DWORD dwRequiredSize = 0; LPBYTE lpBuffer = NULL;
WCHAR keyName[256]; HKEY hKey = NULL; DWORD dwType = 0;
/* Get the needed size */ SetLastError(0xdeadbeef); bError = QueryServiceConfig2W(hService, dwInfoLevel, NULL, 0, &dwRequiredSize); ok(bError == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError, GetLastError(), (DWORD)ERROR_INSUFFICIENT_BUFFER); ok(dwRequiredSize != 0, "dwRequiredSize is zero, expected non-zero\n"); if (dwRequiredSize == 0) { skip("Required size is null; cannot proceed with QueryConfig2W --> %lu test\n", dwInfoLevel); return 1; }
/* Allocate memory */ lpBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize); if (lpBuffer == NULL) { skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize); return 2; }
/* Get the actual value */ SetLastError(0xdeadbeef); bError = QueryServiceConfig2W(hService, dwInfoLevel, lpBuffer, dwRequiredSize, &dwRequiredSize); ok(bError, "bError = %u, expected TRUE\n", bError); if (bError == FALSE) { skip("QueryServiceConfig2W returned an error; cannot proceed with QueryConfig2W --> %lu test\n", dwInfoLevel); HeapFree(GetProcessHeap(), 0, lpBuffer); return 3; }
/* Now we can compare the retrieved value with what it's actually stored in the registry */ StringCbPrintfW(keyName, sizeof(keyName), L"System\\CurrentControlSet\\Services\\%s", serviceName); SetLastError(0xdeadbeef); lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName, 0, KEY_QUERY_VALUE, &hKey); ok(lRet == ERROR_SUCCESS, "RegOpenKeyExW failed with 0x%08lx\n", lRet); if (lRet != ERROR_SUCCESS) { skip("No regkey; cannot proceed with QueryConfig2W --> %lu test\n", dwInfoLevel); HeapFree(GetProcessHeap(), 0, lpBuffer); return 4; }
switch (dwInfoLevel) { case SERVICE_CONFIG_DESCRIPTION: { LPSERVICE_DESCRIPTIONW lpDescription = (LPSERVICE_DESCRIPTIONW)lpBuffer; LPWSTR lpszDescription = NULL;
/* Retrieve the description via the registry */ dwRet = RegReadStringW(hKey, L"Description", &lpszDescription); ok(dwRet == ERROR_SUCCESS, "RegReadStringW returned 0x%08lx\n", dwRet); ok(lpszDescription != NULL, "lpszDescription is null, expected non-null\n");
/* Compare it with the description retrieved via QueryServiceConfig2 */ if (lpszDescription) iRet = wcscmp(lpDescription->lpDescription, lpszDescription); else iRet = 0;
ok(iRet == 0, "Retrieved descriptions are different !\n");
/* Memory cleanup */ HeapFree(GetProcessHeap(), 0, lpszDescription);
break; }
case SERVICE_CONFIG_FAILURE_ACTIONS: { LPSERVICE_FAILURE_ACTIONSW lpFailureActions1 = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer; LPSERVICE_FAILURE_ACTIONSW lpFailureActions2 = NULL; LPWSTR lpRebootMessage = NULL; LPWSTR lpFailureCommand = NULL; DWORD i = 0;
/* Retrieve the failure actions via the registry */ lRet = RegQueryValueExW(hKey, L"FailureActions", NULL, &dwType, NULL, &dwRequiredSize); ok(lRet == ERROR_SUCCESS, "RegQueryValueExW returned 0x%08lx\n", lRet); ok(dwType == REG_BINARY, "dwType = %lu, expected REG_BINARY\n", dwType); ok(dwRequiredSize != 0, "dwRequiredSize is zero, expected non-zero\n");
lpFailureActions2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize); if (lpFailureActions2 == NULL) { skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize); break; }
lRet = RegQueryValueExW(hKey, L"FailureActions", NULL, NULL, (LPBYTE)lpFailureActions2, &dwRequiredSize); ok(lRet == ERROR_SUCCESS, "RegQueryValueExW returned 0x%08lx\n", lRet); ok(dwRequiredSize != 0, "dwRequiredSize is zero, expected non-zero\n");
/* Get the strings */ RegReadStringW(hKey, L"FailureCommand", &lpFailureCommand); RegReadStringW(hKey, L"RebootMessage" , &lpRebootMessage );
/* Check the values */ ok(lpFailureActions1->dwResetPeriod == lpFailureActions2->dwResetPeriod, "lpFailureActions1->dwResetPeriod != lpFailureActions2->dwResetPeriod\n");#ifndef _M_AMD64 // Fails on Win 2003 x64 ok(lpFailureActions1->cActions == lpFailureActions2->cActions, "lpFailureActions1->cActions != lpFailureActions2->cActions\n");#endif /* Compare the actions */ if (lpFailureActions1->cActions == lpFailureActions2->cActions) { lpFailureActions2->lpsaActions = (lpFailureActions2->cActions > 0 ? (LPSC_ACTION)(lpFailureActions2 + 1) : NULL);
if (lpFailureActions1->cActions > 0 && lpFailureActions1->lpsaActions != NULL) { for (i = 0; i < lpFailureActions1->cActions; ++i) { ok(lpFailureActions1->lpsaActions[i].Type == lpFailureActions2->lpsaActions[i].Type , "lpFailureActions1->lpsaActions[%lu].Type != lpFailureActions2->lpsaActions[%lu].Type\n" , i, i); ok(lpFailureActions1->lpsaActions[i].Delay == lpFailureActions2->lpsaActions[i].Delay, "lpFailureActions1->lpsaActions[%lu].Delay != lpFailureActions2->lpsaActions[%lu].Delay\n", i, i); } } }
/* TODO: retrieve the strings if they are in MUI format */
/* Compare RebootMsg */ if (lpFailureActions1->lpRebootMsg && lpRebootMessage) iRet = wcscmp(lpFailureActions1->lpRebootMsg, lpRebootMessage); else iRet = 0;
ok(iRet == 0, "Retrieved reboot messages are different !\n");
/* Compare Command */ if (lpFailureActions1->lpCommand && lpFailureCommand) iRet = wcscmp(lpFailureActions1->lpCommand, lpFailureCommand); else iRet = 0;
ok(iRet == 0, "Retrieved commands are different !\n");
/* Memory cleanup */ if (lpRebootMessage) HeapFree(GetProcessHeap(), 0, lpRebootMessage);
if (lpFailureCommand) HeapFree(GetProcessHeap(), 0, lpFailureCommand);
HeapFree(GetProcessHeap(), 0, lpFailureActions2);
break; }
default: skip("Unknown dwInfoLevel %lu, cannot proceed with QueryConfig2W --> %lu test\n", dwInfoLevel, dwInfoLevel); break; }
RegCloseKey(hKey);
HeapFree(GetProcessHeap(), 0, lpBuffer);
return 0;}
static int QueryConfig2A(SC_HANDLE hService, LPCSTR serviceName, DWORD dwInfoLevel){ int iRet = 0; LONG lRet = 0; DWORD dwRet = 0; BOOL bError = FALSE; DWORD dwRequiredSize = 0; LPBYTE lpBuffer = NULL;
CHAR keyName[256]; HKEY hKey = NULL; DWORD dwType = 0;
/* Get the needed size */ SetLastError(0xdeadbeef); bError = QueryServiceConfig2A(hService, dwInfoLevel, NULL, 0, &dwRequiredSize); ok(bError == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError, GetLastError(), (DWORD)ERROR_INSUFFICIENT_BUFFER); ok(dwRequiredSize != 0, "dwRequiredSize is zero, expected non-zero\n"); if (dwRequiredSize == 0) { skip("Required size is null; cannot proceed with QueryConfig2A --> %lu test\n", dwInfoLevel); return 1; }
/* Allocate memory */ lpBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize); if (lpBuffer == NULL) { skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize); return 2; }
/* Get the actual value */ SetLastError(0xdeadbeef); bError = QueryServiceConfig2A(hService, dwInfoLevel, lpBuffer, dwRequiredSize, &dwRequiredSize); ok(bError, "bError = %u, expected TRUE\n", bError); if (bError == FALSE) { skip("QueryServiceConfig2A returned an error; cannot proceed with QueryConfig2A --> %lu test\n", dwInfoLevel); HeapFree(GetProcessHeap(), 0, lpBuffer); return 3; }
/* Now we can compare the retrieved value with what it's actually stored in the registry */ StringCbPrintfA(keyName, sizeof(keyName), "System\\CurrentControlSet\\Services\\%s", serviceName); SetLastError(0xdeadbeef); lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, KEY_QUERY_VALUE, &hKey); ok(lRet == ERROR_SUCCESS, "RegOpenKeyExA failed with 0x%08lx\n", lRet); if (lRet != ERROR_SUCCESS) { skip("No regkey; cannot proceed with QueryConfig2A --> %lu test\n", dwInfoLevel); HeapFree(GetProcessHeap(), 0, lpBuffer); return 4; }
switch (dwInfoLevel) { case SERVICE_CONFIG_DESCRIPTION: { LPSERVICE_DESCRIPTIONA lpDescription = (LPSERVICE_DESCRIPTIONA)lpBuffer; LPSTR lpszDescription = NULL;
/* Retrieve the description via the registry */ dwRet = RegReadStringA(hKey, "Description", &lpszDescription); ok(dwRet == ERROR_SUCCESS, "RegReadStringA returned 0x%08lx\n", dwRet); ok(lpszDescription != NULL, "lpszDescription is null, expected non-null\n");
/* Compare it with the description retrieved via QueryServiceConfig2 */ if (lpszDescription) iRet = strcmp(lpDescription->lpDescription, lpszDescription); else iRet = 0;
ok(iRet == 0, "Retrieved descriptions are different !\n");
/* Memory cleanup */ HeapFree(GetProcessHeap(), 0, lpszDescription);
break; }
case SERVICE_CONFIG_FAILURE_ACTIONS: { LPSERVICE_FAILURE_ACTIONSA lpFailureActions1 = (LPSERVICE_FAILURE_ACTIONSA)lpBuffer; LPSERVICE_FAILURE_ACTIONSA lpFailureActions2 = NULL; LPSTR lpRebootMessage = NULL; LPSTR lpFailureCommand = NULL; DWORD i = 0;
/* Retrieve the failure actions via the registry */ lRet = RegQueryValueExA(hKey, "FailureActions", NULL, &dwType, NULL, &dwRequiredSize); ok(lRet == ERROR_SUCCESS, "RegQueryValueExA returned 0x%08lx\n", lRet); ok(dwType == REG_BINARY, "dwType = %lu, expected REG_BINARY\n", dwType); ok(dwRequiredSize != 0, "dwRequiredSize is zero, expected non-zero\n");
lpFailureActions2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize); if (lpFailureActions2 == NULL) { skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize); break; }
lRet = RegQueryValueExA(hKey, "FailureActions", NULL, NULL, (LPBYTE)lpFailureActions2, &dwRequiredSize); ok(lRet == ERROR_SUCCESS, "RegQueryValueExA returned 0x%08lx\n", lRet); ok(dwRequiredSize != 0, "dwRequiredSize is zero, expected non-zero\n");
/* Get the strings */ RegReadStringA(hKey, "FailureCommand", &lpFailureCommand); RegReadStringA(hKey, "RebootMessage" , &lpRebootMessage );
/* Check the values */ ok(lpFailureActions1->dwResetPeriod == lpFailureActions2->dwResetPeriod, "lpFailureActions1->dwResetPeriod != lpFailureActions2->dwResetPeriod\n");#ifndef _M_AMD64 // Fails on Win 2003 x64 ok(lpFailureActions1->cActions == lpFailureActions2->cActions, "lpFailureActions1->cActions != lpFailureActions2->cActions\n");#endif
/* Compare the actions */ if (lpFailureActions1->cActions == lpFailureActions2->cActions) { lpFailureActions2->lpsaActions = (lpFailureActions2->cActions > 0 ? (LPSC_ACTION)(lpFailureActions2 + 1) : NULL);
if (lpFailureActions1->cActions > 0 && lpFailureActions1->lpsaActions != NULL) { for (i = 0; i < lpFailureActions1->cActions; ++i) { ok(lpFailureActions1->lpsaActions[i].Type == lpFailureActions2->lpsaActions[i].Type , "lpFailureActions1->lpsaActions[%lu].Type != lpFailureActions2->lpsaActions[%lu].Type\n" , i, i); ok(lpFailureActions1->lpsaActions[i].Delay == lpFailureActions2->lpsaActions[i].Delay, "lpFailureActions1->lpsaActions[%lu].Delay != lpFailureActions2->lpsaActions[%lu].Delay\n", i, i); } } }
/* TODO: retrieve the strings if they are in MUI format */
/* Compare RebootMsg */ if (lpFailureActions1->lpRebootMsg && lpRebootMessage) iRet = strcmp(lpFailureActions1->lpRebootMsg, lpRebootMessage); else iRet = 0;
ok(iRet == 0, "Retrieved reboot messages are different !\n");
/* Compare Command */ if (lpFailureActions1->lpCommand && lpFailureCommand) iRet = strcmp(lpFailureActions1->lpCommand, lpFailureCommand); else iRet = 0;
ok(iRet == 0, "Retrieved commands are different !\n");
/* Memory cleanup */ if (lpRebootMessage) HeapFree(GetProcessHeap(), 0, lpRebootMessage);
if (lpFailureCommand) HeapFree(GetProcessHeap(), 0, lpFailureCommand);
HeapFree(GetProcessHeap(), 0, lpFailureActions2);
break; }
default: skip("Unknown dwInfoLevel %lu, cannot proceed with QueryConfig2A --> %lu test\n", dwInfoLevel, dwInfoLevel); break; }
RegCloseKey(hKey);
HeapFree(GetProcessHeap(), 0, lpBuffer);
return 0;}
static void Test_QueryServiceConfig2W(void){ SC_HANDLE hScm = NULL; SC_HANDLE hService = NULL;
SetLastError(0xdeadbeef); hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT); ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError()); if (!hScm) { skip("No service control manager; cannot proceed with QueryServiceConfig2W test\n"); goto cleanup; }
ok_err(ERROR_SUCCESS);
SetLastError(0xdeadbeef); hService = OpenServiceW(hScm, TESTING_SERVICEW, SERVICE_QUERY_CONFIG); ok(hService != NULL, "Failed to open service handle, error=0x%08lx\n", GetLastError()); if (!hService) { skip("Service not found; cannot proceed with QueryServiceConfig2W test\n"); goto cleanup; }
ok_err(ERROR_SUCCESS);
if (QueryConfig2W(hService, TESTING_SERVICEW, SERVICE_CONFIG_DESCRIPTION) != 0) goto cleanup;
if (QueryConfig2W(hService, TESTING_SERVICEW, SERVICE_CONFIG_FAILURE_ACTIONS) != 0) goto cleanup;
cleanup: if (hService) CloseServiceHandle(hService);
if (hScm) CloseServiceHandle(hScm);}
static void Test_QueryServiceConfig2A(void){ SC_HANDLE hScm = NULL; SC_HANDLE hService = NULL;
SetLastError(0xdeadbeef); hScm = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError()); if (!hScm) { skip("No service control manager; cannot proceed with QueryServiceConfig2A test\n"); goto cleanup; }
ok_err(ERROR_SUCCESS);
SetLastError(0xdeadbeef); hService = OpenServiceA(hScm, TESTING_SERVICEA, SERVICE_QUERY_CONFIG); ok(hService != NULL, "Failed to open service handle, error=0x%08lx\n", GetLastError()); if (!hService) { skip("Service not found; cannot proceed with QueryServiceConfig2A test\n"); goto cleanup; }
ok_err(ERROR_SUCCESS);
if (QueryConfig2A(hService, TESTING_SERVICEA, SERVICE_CONFIG_DESCRIPTION) != 0) goto cleanup;
if (QueryConfig2A(hService, TESTING_SERVICEA, SERVICE_CONFIG_FAILURE_ACTIONS) != 0) goto cleanup;
cleanup: if (hService) CloseServiceHandle(hService);
if (hScm) CloseServiceHandle(hScm);}
START_TEST(QueryServiceConfig2){ Test_QueryServiceConfig2W(); Test_QueryServiceConfig2A();}