Author: tfaber
Date: Wed Jun 27 14:55:22 2012
New Revision: 56809
URL: 
http://svn.reactos.org/svn/reactos?rev=56809&view=rev
Log:
[ADVAPI32_APITEST]
- Add test for QueryServiceConfig2 with SERVICE_CONFIG_DESCRIPTION and
SERVICE_CONFIG_FAILURE_ACTIONS. Patch by Hermes Belusca.
- Remove ok_lasterr in favor of ok_err.
See issue #7144 for more details.
Added:
    trunk/rostests/apitests/advapi32/QueryServiceConfig2.c   (with props)
Modified:
    trunk/rostests/apitests/advapi32/   (props changed)
    trunk/rostests/apitests/advapi32/CMakeLists.txt
    trunk/rostests/apitests/advapi32/CreateService.c
    trunk/rostests/apitests/advapi32/testlist.c
Propchange: trunk/rostests/apitests/advapi32/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Wed Jun 27 14:55:22 2012
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)
Propchange: trunk/rostests/apitests/advapi32/
------------------------------------------------------------------------------
    bugtraq:message = See issue #%BUGID% for more details.
Propchange: trunk/rostests/apitests/advapi32/
------------------------------------------------------------------------------
    bugtraq:url = 
http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Propchange: trunk/rostests/apitests/advapi32/
------------------------------------------------------------------------------
    tsvn:logminsize = 10
Modified: trunk/rostests/apitests/advapi32/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/advapi32/CMakeLi…
==============================================================================
--- trunk/rostests/apitests/advapi32/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rostests/apitests/advapi32/CMakeLists.txt [iso-8859-1] Wed Jun 27 14:55:22 2012
@@ -1,8 +1,7 @@
-
-add_definitions(-D_DLL -D__USE_CRTIMP)
 list(APPEND SOURCE
      CreateService.c
+     QueryServiceConfig2.c
      testlist.c)
 add_executable(advapi32_apitest ${SOURCE})
Modified: trunk/rostests/apitests/advapi32/CreateService.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/advapi32/CreateS…
==============================================================================
--- trunk/rostests/apitests/advapi32/CreateService.c [iso-8859-1] (original)
+++ trunk/rostests/apitests/advapi32/CreateService.c [iso-8859-1] Wed Jun 27 14:55:22 2012
@@ -8,8 +8,6 @@
 #include <wine/test.h>
 #include <windows.h>
 #include <strsafe.h>
-
-#define ok_lasterr(err, s) ok(GetLastError() == (err), "%s GetLastError()=0x%08lx,
expected 0x%08lx\n", s, GetLastError(), (DWORD)(err))
 static int MakeService(SC_HANDLE hScm, const wchar_t *serviceName, SC_HANDLE *hService,
DWORD *tag)
 {
@@ -41,7 +39,7 @@
         return 1;
     }
-    ok_lasterr(ERROR_SUCCESS, "CreateServiceW");
+    ok_err(ERROR_SUCCESS);
     ok(*tag != 0, "tag is zero, expected nonzero\n");
@@ -98,7 +96,7 @@
         goto cleanup;
     }
-    ok_lasterr(ERROR_SUCCESS, "OpenSCManagerW");
+    ok_err(ERROR_SUCCESS);
     if (MakeService(hScm, L"advapi32_apitest_CreateService_Test_Service1",
&hService1, &tag1))
         goto cleanup;
Added: trunk/rostests/apitests/advapi32/QueryServiceConfig2.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/advapi32/QuerySe…
==============================================================================
--- trunk/rostests/apitests/advapi32/QueryServiceConfig2.c (added)
+++ trunk/rostests/apitests/advapi32/QueryServiceConfig2.c [iso-8859-1] Wed Jun 27
14:55:22 2012
@@ -1,0 +1,568 @@
+/*
+ * 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 <wine/test.h>
+#include <windows.h>
+#include <strsafe.h>
+
+/*
+ * Taken from base/system/services/config.c and adapted.
+ */
+static DWORD
+RegReadStringW(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 DWORD
+RegReadStringA(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");
+            ok(lpFailureActions1->cActions == lpFailureActions2->cActions,
"lpFailureActions1->cActions != lpFailureActions2->cActions\n");
+
+            /* 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");
+            ok(lpFailureActions1->cActions == lpFailureActions2->cActions,
"lpFailureActions1->cActions != lpFailureActions2->cActions\n");
+
+            /* 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, L"Spooler", 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, L"Spooler", SERVICE_CONFIG_DESCRIPTION) != 0)
+        goto cleanup;
+
+    if (QueryConfig2W(hService, L"Spooler", 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, "Spooler", 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, "Spooler", SERVICE_CONFIG_DESCRIPTION) != 0)
+        goto cleanup;
+
+    if (QueryConfig2A(hService, "Spooler", SERVICE_CONFIG_FAILURE_ACTIONS) !=
0)
+        goto cleanup;
+
+cleanup:
+    if (hService)
+        CloseServiceHandle(hService);
+
+    if (hScm)
+        CloseServiceHandle(hScm);
+}
+
+
+START_TEST(QueryServiceConfig2)
+{
+    Test_QueryServiceConfig2W();
+    Test_QueryServiceConfig2A();
+}
Propchange: trunk/rostests/apitests/advapi32/QueryServiceConfig2.c
------------------------------------------------------------------------------
    svn:eol-style = native
Modified: trunk/rostests/apitests/advapi32/testlist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/advapi32/testlis…
==============================================================================
--- trunk/rostests/apitests/advapi32/testlist.c [iso-8859-1] (original)
+++ trunk/rostests/apitests/advapi32/testlist.c [iso-8859-1] Wed Jun 27 14:55:22 2012
@@ -6,10 +6,12 @@
 #include "wine/test.h"
 extern void func_CreateService(void);
+extern void func_QueryServiceConfig2(void);
 const struct test winetest_testlist[] =
 {
     { "CreateService", func_CreateService },
+    { "QueryServiceConfig2", func_QueryServiceConfig2 },
     { 0, 0 }
 };