2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for QueryServiceConfig2A/W
5 * PROGRAMMER: Hermès BÉLUSCA - MAÏTO
14 #define TESTING_SERVICEW L"Spooler"
15 #define TESTING_SERVICEA "Spooler"
18 * Taken from base/system/services/config.c and adapted.
21 RegReadStringW(HKEY hKey
,
32 dwError
= RegQueryValueExW(hKey
,
38 if (dwError
!= ERROR_SUCCESS
)
41 *lpValue
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
43 return ERROR_NOT_ENOUGH_MEMORY
;
45 dwError
= RegQueryValueExW(hKey
,
51 if (dwError
!= ERROR_SUCCESS
)
53 HeapFree(GetProcessHeap(), 0, *lpValue
);
61 RegReadStringA(HKEY hKey
,
72 dwError
= RegQueryValueExA(hKey
,
78 if (dwError
!= ERROR_SUCCESS
)
81 *lpValue
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
83 return ERROR_NOT_ENOUGH_MEMORY
;
85 dwError
= RegQueryValueExA(hKey
,
91 if (dwError
!= ERROR_SUCCESS
)
93 HeapFree(GetProcessHeap(), 0, *lpValue
);
101 static int QueryConfig2W(SC_HANDLE hService
, LPCWSTR serviceName
, DWORD dwInfoLevel
)
107 DWORD dwRequiredSize
= 0;
108 LPBYTE lpBuffer
= NULL
;
114 /* Get the needed size */
115 SetLastError(0xdeadbeef);
116 bError
= QueryServiceConfig2W(hService
,
121 ok(bError
== FALSE
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError
, GetLastError(), (DWORD
)ERROR_INSUFFICIENT_BUFFER
);
122 ok(dwRequiredSize
!= 0, "dwRequiredSize is zero, expected non-zero\n");
123 if (dwRequiredSize
== 0)
125 skip("Required size is null; cannot proceed with QueryConfig2W --> %lu test\n", dwInfoLevel
);
129 /* Allocate memory */
130 lpBuffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwRequiredSize
);
131 if (lpBuffer
== NULL
)
133 skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize
);
137 /* Get the actual value */
138 SetLastError(0xdeadbeef);
139 bError
= QueryServiceConfig2W(hService
,
144 ok(bError
, "bError = %u, expected TRUE\n", bError
);
147 skip("QueryServiceConfig2W returned an error; cannot proceed with QueryConfig2W --> %lu test\n", dwInfoLevel
);
148 HeapFree(GetProcessHeap(), 0, lpBuffer
);
152 /* Now we can compare the retrieved value with what it's actually stored in the registry */
153 StringCbPrintfW(keyName
, sizeof(keyName
), L
"System\\CurrentControlSet\\Services\\%s", serviceName
);
154 SetLastError(0xdeadbeef);
155 lRet
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, keyName
, 0, KEY_QUERY_VALUE
, &hKey
);
156 ok(lRet
== ERROR_SUCCESS
, "RegOpenKeyExW failed with 0x%08lx\n", lRet
);
157 if (lRet
!= ERROR_SUCCESS
)
159 skip("No regkey; cannot proceed with QueryConfig2W --> %lu test\n", dwInfoLevel
);
160 HeapFree(GetProcessHeap(), 0, lpBuffer
);
166 case SERVICE_CONFIG_DESCRIPTION
:
168 LPSERVICE_DESCRIPTIONW lpDescription
= (LPSERVICE_DESCRIPTIONW
)lpBuffer
;
169 LPWSTR lpszDescription
= NULL
;
171 /* Retrieve the description via the registry */
172 dwRet
= RegReadStringW(hKey
, L
"Description", &lpszDescription
);
173 ok(dwRet
== ERROR_SUCCESS
, "RegReadStringW returned 0x%08lx\n", dwRet
);
174 ok(lpszDescription
!= NULL
, "lpszDescription is null, expected non-null\n");
176 /* Compare it with the description retrieved via QueryServiceConfig2 */
178 iRet
= wcscmp(lpDescription
->lpDescription
, lpszDescription
);
182 ok(iRet
== 0, "Retrieved descriptions are different !\n");
186 HeapFree(GetProcessHeap(), 0, lpszDescription
);
191 case SERVICE_CONFIG_FAILURE_ACTIONS
:
193 LPSERVICE_FAILURE_ACTIONSW lpFailureActions1
= (LPSERVICE_FAILURE_ACTIONSW
)lpBuffer
;
194 LPSERVICE_FAILURE_ACTIONSW lpFailureActions2
= NULL
;
195 LPWSTR lpRebootMessage
= NULL
;
196 LPWSTR lpFailureCommand
= NULL
;
199 /* Retrieve the failure actions via the registry */
200 lRet
= RegQueryValueExW(hKey
,
206 ok(lRet
== ERROR_SUCCESS
, "RegQueryValueExW returned 0x%08lx\n", lRet
);
207 ok(dwType
== REG_BINARY
, "dwType = %lu, expected REG_BINARY\n", dwType
);
208 ok(dwRequiredSize
!= 0, "dwRequiredSize is zero, expected non-zero\n");
210 lpFailureActions2
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwRequiredSize
);
211 if (lpFailureActions2
== NULL
)
213 skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize
);
217 lRet
= RegQueryValueExW(hKey
,
221 (LPBYTE
)lpFailureActions2
,
223 ok(lRet
== ERROR_SUCCESS
, "RegQueryValueExW returned 0x%08lx\n", lRet
);
224 ok(dwRequiredSize
!= 0, "dwRequiredSize is zero, expected non-zero\n");
226 /* Get the strings */
227 RegReadStringW(hKey
, L
"FailureCommand", &lpFailureCommand
);
228 RegReadStringW(hKey
, L
"RebootMessage" , &lpRebootMessage
);
230 /* Check the values */
231 ok(lpFailureActions1
->dwResetPeriod
== lpFailureActions2
->dwResetPeriod
, "lpFailureActions1->dwResetPeriod != lpFailureActions2->dwResetPeriod\n");
232 ok(lpFailureActions1
->cActions
== lpFailureActions2
->cActions
, "lpFailureActions1->cActions != lpFailureActions2->cActions\n");
234 /* Compare the actions */
235 if (lpFailureActions1
->cActions
== lpFailureActions2
->cActions
)
237 lpFailureActions2
->lpsaActions
= (lpFailureActions2
->cActions
> 0 ? (LPSC_ACTION
)(lpFailureActions2
+ 1) : NULL
);
239 if (lpFailureActions1
->cActions
> 0 &&
240 lpFailureActions1
->lpsaActions
!= NULL
)
242 for (i
= 0; i
< lpFailureActions1
->cActions
; ++i
)
244 ok(lpFailureActions1
->lpsaActions
[i
].Type
== lpFailureActions2
->lpsaActions
[i
].Type
, "lpFailureActions1->lpsaActions[%lu].Type != lpFailureActions2->lpsaActions[%lu].Type\n" , i
, i
);
245 ok(lpFailureActions1
->lpsaActions
[i
].Delay
== lpFailureActions2
->lpsaActions
[i
].Delay
, "lpFailureActions1->lpsaActions[%lu].Delay != lpFailureActions2->lpsaActions[%lu].Delay\n", i
, i
);
250 /* TODO: retrieve the strings if they are in MUI format */
252 /* Compare RebootMsg */
253 if (lpFailureActions1
->lpRebootMsg
&& lpRebootMessage
)
254 iRet
= wcscmp(lpFailureActions1
->lpRebootMsg
, lpRebootMessage
);
258 ok(iRet
== 0, "Retrieved reboot messages are different !\n");
260 /* Compare Command */
261 if (lpFailureActions1
->lpCommand
&& lpFailureCommand
)
262 iRet
= wcscmp(lpFailureActions1
->lpCommand
, lpFailureCommand
);
266 ok(iRet
== 0, "Retrieved commands are different !\n");
271 HeapFree(GetProcessHeap(), 0, lpRebootMessage
);
273 if (lpFailureCommand
)
274 HeapFree(GetProcessHeap(), 0, lpFailureCommand
);
276 HeapFree(GetProcessHeap(), 0, lpFailureActions2
);
282 skip("Unknown dwInfoLevel %lu, cannot proceed with QueryConfig2W --> %lu test\n", dwInfoLevel
, dwInfoLevel
);
288 HeapFree(GetProcessHeap(), 0, lpBuffer
);
293 static int QueryConfig2A(SC_HANDLE hService
, LPCSTR serviceName
, DWORD dwInfoLevel
)
299 DWORD dwRequiredSize
= 0;
300 LPBYTE lpBuffer
= NULL
;
306 /* Get the needed size */
307 SetLastError(0xdeadbeef);
308 bError
= QueryServiceConfig2A(hService
,
313 ok(bError
== FALSE
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError
, GetLastError(), (DWORD
)ERROR_INSUFFICIENT_BUFFER
);
314 ok(dwRequiredSize
!= 0, "dwRequiredSize is zero, expected non-zero\n");
315 if (dwRequiredSize
== 0)
317 skip("Required size is null; cannot proceed with QueryConfig2A --> %lu test\n", dwInfoLevel
);
321 /* Allocate memory */
322 lpBuffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwRequiredSize
);
323 if (lpBuffer
== NULL
)
325 skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize
);
329 /* Get the actual value */
330 SetLastError(0xdeadbeef);
331 bError
= QueryServiceConfig2A(hService
,
336 ok(bError
, "bError = %u, expected TRUE\n", bError
);
339 skip("QueryServiceConfig2A returned an error; cannot proceed with QueryConfig2A --> %lu test\n", dwInfoLevel
);
340 HeapFree(GetProcessHeap(), 0, lpBuffer
);
344 /* Now we can compare the retrieved value with what it's actually stored in the registry */
345 StringCbPrintfA(keyName
, sizeof(keyName
), "System\\CurrentControlSet\\Services\\%s", serviceName
);
346 SetLastError(0xdeadbeef);
347 lRet
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
, keyName
, 0, KEY_QUERY_VALUE
, &hKey
);
348 ok(lRet
== ERROR_SUCCESS
, "RegOpenKeyExA failed with 0x%08lx\n", lRet
);
349 if (lRet
!= ERROR_SUCCESS
)
351 skip("No regkey; cannot proceed with QueryConfig2A --> %lu test\n", dwInfoLevel
);
352 HeapFree(GetProcessHeap(), 0, lpBuffer
);
358 case SERVICE_CONFIG_DESCRIPTION
:
360 LPSERVICE_DESCRIPTIONA lpDescription
= (LPSERVICE_DESCRIPTIONA
)lpBuffer
;
361 LPSTR lpszDescription
= NULL
;
363 /* Retrieve the description via the registry */
364 dwRet
= RegReadStringA(hKey
, "Description", &lpszDescription
);
365 ok(dwRet
== ERROR_SUCCESS
, "RegReadStringA returned 0x%08lx\n", dwRet
);
366 ok(lpszDescription
!= NULL
, "lpszDescription is null, expected non-null\n");
368 /* Compare it with the description retrieved via QueryServiceConfig2 */
370 iRet
= strcmp(lpDescription
->lpDescription
, lpszDescription
);
374 ok(iRet
== 0, "Retrieved descriptions are different !\n");
378 HeapFree(GetProcessHeap(), 0, lpszDescription
);
383 case SERVICE_CONFIG_FAILURE_ACTIONS
:
385 LPSERVICE_FAILURE_ACTIONSA lpFailureActions1
= (LPSERVICE_FAILURE_ACTIONSA
)lpBuffer
;
386 LPSERVICE_FAILURE_ACTIONSA lpFailureActions2
= NULL
;
387 LPSTR lpRebootMessage
= NULL
;
388 LPSTR lpFailureCommand
= NULL
;
391 /* Retrieve the failure actions via the registry */
392 lRet
= RegQueryValueExA(hKey
,
398 ok(lRet
== ERROR_SUCCESS
, "RegQueryValueExA returned 0x%08lx\n", lRet
);
399 ok(dwType
== REG_BINARY
, "dwType = %lu, expected REG_BINARY\n", dwType
);
400 ok(dwRequiredSize
!= 0, "dwRequiredSize is zero, expected non-zero\n");
402 lpFailureActions2
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwRequiredSize
);
403 if (lpFailureActions2
== NULL
)
405 skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize
);
409 lRet
= RegQueryValueExA(hKey
,
413 (LPBYTE
)lpFailureActions2
,
415 ok(lRet
== ERROR_SUCCESS
, "RegQueryValueExA returned 0x%08lx\n", lRet
);
416 ok(dwRequiredSize
!= 0, "dwRequiredSize is zero, expected non-zero\n");
418 /* Get the strings */
419 RegReadStringA(hKey
, "FailureCommand", &lpFailureCommand
);
420 RegReadStringA(hKey
, "RebootMessage" , &lpRebootMessage
);
422 /* Check the values */
423 ok(lpFailureActions1
->dwResetPeriod
== lpFailureActions2
->dwResetPeriod
, "lpFailureActions1->dwResetPeriod != lpFailureActions2->dwResetPeriod\n");
424 ok(lpFailureActions1
->cActions
== lpFailureActions2
->cActions
, "lpFailureActions1->cActions != lpFailureActions2->cActions\n");
426 /* Compare the actions */
427 if (lpFailureActions1
->cActions
== lpFailureActions2
->cActions
)
429 lpFailureActions2
->lpsaActions
= (lpFailureActions2
->cActions
> 0 ? (LPSC_ACTION
)(lpFailureActions2
+ 1) : NULL
);
431 if (lpFailureActions1
->cActions
> 0 &&
432 lpFailureActions1
->lpsaActions
!= NULL
)
434 for (i
= 0; i
< lpFailureActions1
->cActions
; ++i
)
436 ok(lpFailureActions1
->lpsaActions
[i
].Type
== lpFailureActions2
->lpsaActions
[i
].Type
, "lpFailureActions1->lpsaActions[%lu].Type != lpFailureActions2->lpsaActions[%lu].Type\n" , i
, i
);
437 ok(lpFailureActions1
->lpsaActions
[i
].Delay
== lpFailureActions2
->lpsaActions
[i
].Delay
, "lpFailureActions1->lpsaActions[%lu].Delay != lpFailureActions2->lpsaActions[%lu].Delay\n", i
, i
);
442 /* TODO: retrieve the strings if they are in MUI format */
444 /* Compare RebootMsg */
445 if (lpFailureActions1
->lpRebootMsg
&& lpRebootMessage
)
446 iRet
= strcmp(lpFailureActions1
->lpRebootMsg
, lpRebootMessage
);
450 ok(iRet
== 0, "Retrieved reboot messages are different !\n");
452 /* Compare Command */
453 if (lpFailureActions1
->lpCommand
&& lpFailureCommand
)
454 iRet
= strcmp(lpFailureActions1
->lpCommand
, lpFailureCommand
);
458 ok(iRet
== 0, "Retrieved commands are different !\n");
463 HeapFree(GetProcessHeap(), 0, lpRebootMessage
);
465 if (lpFailureCommand
)
466 HeapFree(GetProcessHeap(), 0, lpFailureCommand
);
468 HeapFree(GetProcessHeap(), 0, lpFailureActions2
);
474 skip("Unknown dwInfoLevel %lu, cannot proceed with QueryConfig2A --> %lu test\n", dwInfoLevel
, dwInfoLevel
);
480 HeapFree(GetProcessHeap(), 0, lpBuffer
);
486 static void Test_QueryServiceConfig2W(void)
488 SC_HANDLE hScm
= NULL
;
489 SC_HANDLE hService
= NULL
;
491 SetLastError(0xdeadbeef);
492 hScm
= OpenSCManagerW(NULL
, NULL
, SC_MANAGER_CONNECT
);
493 ok(hScm
!= NULL
, "Failed to open service manager, error=0x%08lx\n", GetLastError());
496 skip("No service control manager; cannot proceed with QueryServiceConfig2W test\n");
500 ok_err(ERROR_SUCCESS
);
502 SetLastError(0xdeadbeef);
503 hService
= OpenServiceW(hScm
, TESTING_SERVICEW
, SERVICE_QUERY_CONFIG
);
504 ok(hService
!= NULL
, "Failed to open service handle, error=0x%08lx\n", GetLastError());
507 skip("Service not found; cannot proceed with QueryServiceConfig2W test\n");
511 ok_err(ERROR_SUCCESS
);
513 if (QueryConfig2W(hService
, TESTING_SERVICEW
, SERVICE_CONFIG_DESCRIPTION
) != 0)
516 if (QueryConfig2W(hService
, TESTING_SERVICEW
, SERVICE_CONFIG_FAILURE_ACTIONS
) != 0)
521 CloseServiceHandle(hService
);
524 CloseServiceHandle(hScm
);
527 static void Test_QueryServiceConfig2A(void)
529 SC_HANDLE hScm
= NULL
;
530 SC_HANDLE hService
= NULL
;
532 SetLastError(0xdeadbeef);
533 hScm
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
534 ok(hScm
!= NULL
, "Failed to open service manager, error=0x%08lx\n", GetLastError());
537 skip("No service control manager; cannot proceed with QueryServiceConfig2A test\n");
541 ok_err(ERROR_SUCCESS
);
543 SetLastError(0xdeadbeef);
544 hService
= OpenServiceA(hScm
, TESTING_SERVICEA
, SERVICE_QUERY_CONFIG
);
545 ok(hService
!= NULL
, "Failed to open service handle, error=0x%08lx\n", GetLastError());
548 skip("Service not found; cannot proceed with QueryServiceConfig2A test\n");
552 ok_err(ERROR_SUCCESS
);
554 if (QueryConfig2A(hService
, TESTING_SERVICEA
, SERVICE_CONFIG_DESCRIPTION
) != 0)
557 if (QueryConfig2A(hService
, TESTING_SERVICEA
, SERVICE_CONFIG_FAILURE_ACTIONS
) != 0)
562 CloseServiceHandle(hService
);
565 CloseServiceHandle(hScm
);
569 START_TEST(QueryServiceConfig2
)
571 Test_QueryServiceConfig2W();
572 Test_QueryServiceConfig2A();