Author: tfaber
Date: Fri Jun 29 11:48:35 2012
New Revision: 56810
URL: 
http://svn.reactos.org/svn/reactos?rev=56810&view=rev
Log:
[ADVAPI32_APITEST]
- Use a define for the service name in QueryServiceConfig2 test. Patch by Hermes Belusca.
Bug 7145.
- Add LockDatabase test for Lock/UnlockServiceDatabase, QueryServiceLockStatus. Patch by
Hermes Belusca. Bug 7146.
Added:
    trunk/rostests/apitests/advapi32/LockDatabase.c   (with props)
Modified:
    trunk/rostests/apitests/advapi32/CMakeLists.txt
    trunk/rostests/apitests/advapi32/QueryServiceConfig2.c
    trunk/rostests/apitests/advapi32/testlist.c
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] Fri Jun 29 11:48:35 2012
@@ -1,6 +1,7 @@
 list(APPEND SOURCE
      CreateService.c
+     LockDatabase.c
      QueryServiceConfig2.c
      testlist.c)
Added: trunk/rostests/apitests/advapi32/LockDatabase.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/advapi32/LockDat…
==============================================================================
--- trunk/rostests/apitests/advapi32/LockDatabase.c (added)
+++ trunk/rostests/apitests/advapi32/LockDatabase.c [iso-8859-1] Fri Jun 29 11:48:35 2012
@@ -1,0 +1,760 @@
+/*
+ * PROJECT:         ReactOS api tests
+ * LICENSE:         GPLv2+ - See COPYING in the top level directory
+ * PURPOSE:         Tests for Lock/UnlockServiceDatabase and QueryServiceLockStatusA/W
+ * PROGRAMMER:      Hermès BÃLUSCA - MAÃTO
+ */
+
+#include <wine/test.h>
+#include <windows.h>
+#include <strsafe.h>
+
+#define TESTING_SERVICE     L"Spooler"
+
+static void Test_LockUnlockServiceDatabase(void)
+{
+    BOOL bError = FALSE;
+
+    SC_HANDLE hScm  = NULL;
+    SC_LOCK   hLock = NULL;
+
+    /* First of all, try to lock / unlock the services database with invalid handles */
+    SetLastError(0xdeadbeef);
+    hScm  = NULL;
+    hLock = LockServiceDatabase(hScm);
+    ok(hLock == NULL, "hLock = 0x%p, expected 0\n", hLock);
+    ok_err(ERROR_INVALID_HANDLE);
+
+    SetLastError(0xdeadbeef);
+    hScm  = (SC_HANDLE)0xdeadbeef;
+    hLock = LockServiceDatabase(hScm);
+    ok(hLock == NULL, "hLock = 0x%p, expected 0\n", hLock);
+    ok_err(ERROR_INVALID_HANDLE);
+
+/** This test seems to make this application crash on Windows 7... I do not know why...
**/
+    SetLastError(0xdeadbeef);
+    hLock = NULL;
+    bError = UnlockServiceDatabase(hLock);
+    ok(bError == FALSE, "bError = %u, expected FALSE\n", bError);
+    ok_err(ERROR_INVALID_SERVICE_LOCK);
+/*****************************************************************************************/
+
+    SetLastError(0xdeadbeef);
+    hLock = (SC_LOCK)0xdeadbeef;
+    bError = UnlockServiceDatabase(hLock);
+    ok(bError == FALSE, "bError = %u, expected FALSE\n", bError);
+    ok_err(ERROR_INVALID_SERVICE_LOCK);
+
+
+    /* Then, try to lock the services database without having rights */
+    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
LockUnlockServiceDatabase test\n");
+        goto cleanup;
+    }
+    ok_err(ERROR_SUCCESS);
+
+    SetLastError(0xdeadbeef);
+    hLock = LockServiceDatabase(hScm);
+    ok(hLock == NULL, "hLock = 0x%p, expected 0\n", hLock);
+    ok_err(ERROR_ACCESS_DENIED);
+
+    if (hLock)
+        UnlockServiceDatabase(hLock);
+    CloseServiceHandle(hScm);
+
+    /* Try to lock the services database with good rights */
+    SetLastError(0xdeadbeef);
+    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_LOCK);
+    ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n",
GetLastError());
+    if (!hScm)
+    {
+        skip("No service control manager; cannot proceed with
LockUnlockServiceDatabase test\n");
+        goto cleanup;
+    }
+    ok_err(ERROR_SUCCESS);
+
+    SetLastError(0xdeadbeef);
+    hLock = LockServiceDatabase(hScm);
+    ok(hLock != NULL, "hLock = 0x%p, expected non-zero\n", hLock);
+    ok_err(ERROR_SUCCESS);
+
+    /* Now unlock it */
+    if (hLock)
+    {
+        SetLastError(0xdeadbeef);
+        bError = UnlockServiceDatabase(hLock);
+        ok(bError == TRUE, "bError = %u, expected TRUE\n", bError);
+        ok_err(ERROR_SUCCESS);
+    }
+
+
+cleanup:
+    if (hScm)
+        CloseServiceHandle(hScm);
+
+    return;
+}
+
+static void Test_LockUnlockServiceDatabaseWithServiceStart(void)
+{
+    BOOL bError = FALSE;
+
+    SC_HANDLE hScm  = NULL;
+    SC_HANDLE hSvc  = NULL;
+    SC_LOCK   hLock = NULL;
+
+    LPQUERY_SERVICE_CONFIGW lpConfig = NULL;
+    DWORD dwRequiredSize = 0;
+    SERVICE_STATUS status;
+    BOOL bWasRunning = FALSE;
+    DWORD dwOldStartType = 0;
+
+    /* Open the services database */
+    SetLastError(0xdeadbeef);
+    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_LOCK);
+    ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n",
GetLastError());
+    if (!hScm)
+    {
+        skip("No service control manager; cannot proceed with
LockUnlockServiceDatabaseWithServiceStart test\n");
+        goto cleanup;
+    }
+    ok_err(ERROR_SUCCESS);
+
+    /* Grab a handle to the testing service */
+    SetLastError(0xdeadbeef);
+    hSvc = OpenServiceW(hScm, TESTING_SERVICE, SERVICE_START | SERVICE_STOP |
SERVICE_CHANGE_CONFIG | SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS);
+    ok(hSvc != NULL, "hSvc = 0x%p, expected non-null, error=0x%08lx\n", hSvc,
GetLastError());
+    if (!hSvc)
+    {
+        skip("Cannot open a handle to service %S; cannot proceed with
LockUnlockServiceDatabaseWithServiceStart test\n", TESTING_SERVICE);
+        goto cleanup;
+    }
+    ok_err(ERROR_SUCCESS);
+
+    /* Lock the services database */
+    SetLastError(0xdeadbeef);
+    hLock = LockServiceDatabase(hScm);
+    ok(hLock != NULL, "hLock = 0x%p, expected non-zero, error=0x%08lx\n",
hLock, GetLastError());
+    if (!hLock)
+    {
+        skip("Cannot lock the services database; cannot proceed with
LockUnlockServiceDatabaseWithServiceStart test\n");
+        goto cleanup;
+    }
+    ok_err(ERROR_SUCCESS);
+
+    /* To proceed further, firstly attempt to stop the testing service */
+    QueryServiceConfigW(hSvc, NULL, 0, &dwRequiredSize);
+    lpConfig = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize);
+    QueryServiceConfigW(hSvc, lpConfig, dwRequiredSize, &dwRequiredSize);
+    dwOldStartType = lpConfig->dwStartType;
+    HeapFree(GetProcessHeap(), 0, lpConfig);
+    if (dwOldStartType == SERVICE_DISABLED)
+    {
+        ChangeServiceConfigW(hSvc,
+                             SERVICE_NO_CHANGE,
+                             SERVICE_DEMAND_START,
+                             SERVICE_NO_CHANGE,
+                             NULL,
+                             NULL,
+                             NULL,
+                             NULL,
+                             NULL,
+                             NULL,
+                             NULL);
+    }
+    QueryServiceStatus(hSvc, &status);
+    bWasRunning = (status.dwCurrentState != SERVICE_STOPPED);
+    if (bWasRunning)
+    {
+        ControlService(hSvc, SERVICE_CONTROL_STOP, &status);
+        Sleep(1000); /* Wait 1 second for the service to stop */
+    }
+
+    /* Now try to start it (this test won't work under Windows Vista / 7 / 8) */
+    SetLastError(0xdeadbeef);
+    bError = StartServiceW(hSvc, 0, NULL);
+    ok(bError == FALSE, "bError = %u, expected FALSE\n", bError);
+    ok_err(ERROR_SERVICE_DATABASE_LOCKED);
+    Sleep(1000); /* Wait 1 second for the service to start */
+
+    /* Stop the testing service */
+    ControlService(hSvc, SERVICE_CONTROL_STOP, &status);
+    Sleep(1000); /* Wait 1 second for the service to stop */
+
+    /* Now unlock the services database */
+    SetLastError(0xdeadbeef);
+    bError = UnlockServiceDatabase(hLock);
+    ok(bError == TRUE, "bError = %u, expected TRUE\n", bError);
+    ok_err(ERROR_SUCCESS);
+
+    /* Try to start again the service, this time the database unlocked */
+    SetLastError(0xdeadbeef);
+    bError = StartServiceW(hSvc, 0, NULL);
+    ok(bError == TRUE, "bError = %u, expected TRUE\n", bError);
+    ok_err(ERROR_SUCCESS);
+    Sleep(1000); /* Wait 1 second for the service to start */
+
+    /* Stop the testing service */
+    ControlService(hSvc, SERVICE_CONTROL_STOP, &status);
+    Sleep(1000); /* Wait 1 second for the service to stop */
+
+    /* Restore its original state */
+    if (bWasRunning)
+    {
+        StartServiceW(hSvc, 0, NULL);
+    }
+
+    if (dwOldStartType == SERVICE_DISABLED)
+    {
+        ChangeServiceConfigW(hSvc,
+                             SERVICE_NO_CHANGE,
+                             SERVICE_DISABLED,
+                             SERVICE_NO_CHANGE,
+                             NULL,
+                             NULL,
+                             NULL,
+                             NULL,
+                             NULL,
+                             NULL,
+                             NULL);
+    }
+
+
+cleanup:
+    if (hSvc)
+        CloseServiceHandle(hSvc);
+
+    if (hScm)
+        CloseServiceHandle(hScm);
+
+    return;
+}
+
+static void Test_QueryLockStatusW(void)
+{
+    BOOL bError = FALSE;
+
+    SC_HANDLE hScm  = NULL;
+    SC_LOCK   hLock = NULL;
+    LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus = NULL;
+    DWORD dwRequiredSize = 0;
+
+    /* Firstly try to get lock status with invalid handles */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusW(hScm,
+                                     NULL,
+                                     0,
+                                     &dwRequiredSize);
+    ok(bError == FALSE && GetLastError() == ERROR_INVALID_HANDLE, "(bError,
GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError,
GetLastError(), (DWORD)ERROR_INVALID_HANDLE);
+    ok(dwRequiredSize == 0, "dwRequiredSize is non-zero, expected zero\n");
+
+    /* Open the services database without having rights */
+    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 QueryLockStatusW
test\n");
+        goto cleanup;
+    }
+    ok_err(ERROR_SUCCESS);
+
+    /* Try to get lock status */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusW(hScm,
+                                     NULL,
+                                     0,
+                                     &dwRequiredSize);
+    ok(bError == FALSE && GetLastError() == ERROR_ACCESS_DENIED, "(bError,
GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError,
GetLastError(), (DWORD)ERROR_ACCESS_DENIED);
+    ok(dwRequiredSize == 0, "dwRequiredSize is non-zero, expected zero\n");
+
+    CloseServiceHandle(hScm);
+
+
+    /*
+     * Query only the lock status.
+     */
+
+    SetLastError(0xdeadbeef);
+    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_QUERY_LOCK_STATUS);
+    ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n",
GetLastError());
+    if (!hScm)
+    {
+        skip("No service control manager; cannot proceed with QueryLockStatusW
test\n");
+        goto cleanup;
+    }
+    ok_err(ERROR_SUCCESS);
+
+    /* Get the needed size */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusW(hScm,
+                                     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 QueryLockStatusW
test\n");
+        goto cleanup;
+    }
+
+    /* Allocate memory */
+    lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize);
+    if (lpLockStatus == NULL)
+    {
+        skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize);
+        goto cleanup;
+    }
+
+    /* Get the actual value */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusW(hScm,
+                                     lpLockStatus,
+                                     dwRequiredSize,
+                                     &dwRequiredSize);
+    ok(bError, "bError = %u, expected TRUE\n", bError);
+
+    /* These conditions must be verified iff the services database wasn't previously
locked */
+    ok(lpLockStatus->fIsLocked == 0, "lpLockStatus->fIsLocked = %lu, expected
0\n", lpLockStatus->fIsLocked);
+    ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null,
expected non-null\n");
+    ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner == 0,
"*lpLockStatus->lpLockOwner != \"\\0\", expected
\"\\0\"\n");
+    ok(lpLockStatus->dwLockDuration == 0, "lpLockStatus->dwLockDuration = %lu,
expected 0\n", lpLockStatus->dwLockDuration);
+
+    HeapFree(GetProcessHeap(), 0, lpLockStatus);
+
+    CloseServiceHandle(hScm);
+
+
+    /*
+     * Now, try to lock the database and check its lock status.
+     */
+
+    SetLastError(0xdeadbeef);
+    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_LOCK | SC_MANAGER_QUERY_LOCK_STATUS);
+    ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n",
GetLastError());
+    if (!hScm)
+    {
+        skip("No service control manager; cannot proceed with QueryLockStatusW
test\n");
+        goto cleanup;
+    }
+    ok_err(ERROR_SUCCESS);
+
+    /* Get the needed size */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusW(hScm,
+                                     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 QueryLockStatusW
test\n");
+        goto cleanup;
+    }
+
+    /* Allocate memory */
+    lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize);
+    if (lpLockStatus == NULL)
+    {
+        skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize);
+        goto cleanup;
+    }
+
+    /* Get the actual value */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusW(hScm,
+                                     lpLockStatus,
+                                     dwRequiredSize,
+                                     &dwRequiredSize);
+    ok(bError, "bError = %u, expected TRUE\n", bError);
+
+    /* These conditions must be verified iff the services database wasn't previously
locked */
+    ok(lpLockStatus->fIsLocked == 0, "lpLockStatus->fIsLocked = %lu, expected
0\n", lpLockStatus->fIsLocked);
+    ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null,
expected non-null\n");
+    ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner == 0,
"*lpLockStatus->lpLockOwner != \"\\0\", expected
\"\\0\"\n");
+    ok(lpLockStatus->dwLockDuration == 0, "lpLockStatus->dwLockDuration = %lu,
expected 0\n", lpLockStatus->dwLockDuration);
+
+    HeapFree(GetProcessHeap(), 0, lpLockStatus);
+
+
+    /*
+     * Try again, this time with the database locked.
+     */
+
+    SetLastError(0xdeadbeef);
+    hLock = LockServiceDatabase(hScm);
+    ok(hLock != NULL, "hLock = 0x%p, expected non-zero\n", hLock);
+    ok_err(ERROR_SUCCESS);
+
+    Sleep(1000); /* Wait 1 second to let lpLockStatus->dwLockDuration increment */
+
+    /* Get the needed size */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusW(hScm,
+                                     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 QueryLockStatusW
test\n");
+        goto cleanup;
+    }
+
+    /* Allocate memory */
+    lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize);
+    if (lpLockStatus == NULL)
+    {
+        skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize);
+        goto cleanup;
+    }
+
+    /* Get the actual value */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusW(hScm,
+                                     lpLockStatus,
+                                     dwRequiredSize,
+                                     &dwRequiredSize);
+    ok(bError, "bError = %u, expected TRUE\n", bError);
+
+    /* These conditions must be verified iff the services database is locked */
+    ok(lpLockStatus->fIsLocked != 0, "lpLockStatus->fIsLocked = %lu, expected
non-zero\n", lpLockStatus->fIsLocked);
+    ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null,
expected non-null\n");
+    ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner != 0,
"*lpLockStatus->lpLockOwner = \"\\0\", expected non-zero\n");
+    ok(lpLockStatus->dwLockDuration != 0, "lpLockStatus->dwLockDuration = %lu,
expected non-zero\n", lpLockStatus->dwLockDuration);
+
+    HeapFree(GetProcessHeap(), 0, lpLockStatus);
+
+
+    /*
+     * Last try, with the database again unlocked.
+     */
+
+    SetLastError(0xdeadbeef);
+    bError = UnlockServiceDatabase(hLock);
+    ok(bError == TRUE, "bError = %u, expected TRUE\n", bError);
+    ok_err(ERROR_SUCCESS);
+    hLock = NULL;
+
+    /* Get the needed size */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusW(hScm,
+                                     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 QueryLockStatusW
test\n");
+        goto cleanup;
+    }
+
+    /* Allocate memory */
+    lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize);
+    if (lpLockStatus == NULL)
+    {
+        skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize);
+        goto cleanup;
+    }
+
+    /* Get the actual value */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusW(hScm,
+                                     lpLockStatus,
+                                     dwRequiredSize,
+                                     &dwRequiredSize);
+    ok(bError, "bError = %u, expected TRUE\n", bError);
+
+    /* These conditions must be verified iff the services database is unlocked */
+    ok(lpLockStatus->fIsLocked == 0, "lpLockStatus->fIsLocked = %lu, expected
0\n", lpLockStatus->fIsLocked);
+    ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null,
expected non-null\n");
+    ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner == 0,
"*lpLockStatus->lpLockOwner != \"\\0\", expected
\"\\0\"\n");
+    ok(lpLockStatus->dwLockDuration == 0, "lpLockStatus->dwLockDuration = %lu,
expected 0\n", lpLockStatus->dwLockDuration);
+
+    HeapFree(GetProcessHeap(), 0, lpLockStatus);
+
+
+cleanup:
+    if (hLock)
+        UnlockServiceDatabase(hLock);
+
+    if (hScm)
+        CloseServiceHandle(hScm);
+
+    return;
+}
+
+static void Test_QueryLockStatusA(void)
+{
+    BOOL bError = FALSE;
+
+    SC_HANDLE hScm  = NULL;
+    SC_LOCK   hLock = NULL;
+    LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus = NULL;
+    DWORD dwRequiredSize = 0;
+
+    /* Firstly try to get lock status with invalid handles */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusA(hScm,
+                                     NULL,
+                                     0,
+                                     &dwRequiredSize);
+    ok(bError == FALSE && GetLastError() == ERROR_INVALID_HANDLE, "(bError,
GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError,
GetLastError(), (DWORD)ERROR_INVALID_HANDLE);
+    ok(dwRequiredSize == 0, "dwRequiredSize is non-zero, expected zero\n");
+
+    /* Open the services database without having rights */
+    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 QueryLockStatusA
test\n");
+        goto cleanup;
+    }
+    ok_err(ERROR_SUCCESS);
+
+    /* Try to get lock status */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusA(hScm,
+                                     NULL,
+                                     0,
+                                     &dwRequiredSize);
+    ok(bError == FALSE && GetLastError() == ERROR_ACCESS_DENIED, "(bError,
GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError,
GetLastError(), (DWORD)ERROR_ACCESS_DENIED);
+    ok(dwRequiredSize == 0, "dwRequiredSize is non-zero, expected zero\n");
+
+    CloseServiceHandle(hScm);
+
+
+    /*
+     * Query only the lock status.
+     */
+
+    SetLastError(0xdeadbeef);
+    hScm = OpenSCManagerA(NULL, NULL, SC_MANAGER_QUERY_LOCK_STATUS);
+    ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n",
GetLastError());
+    if (!hScm)
+    {
+        skip("No service control manager; cannot proceed with QueryLockStatusA
test\n");
+        goto cleanup;
+    }
+    ok_err(ERROR_SUCCESS);
+
+    /* Get the needed size */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusA(hScm,
+                                     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 QueryLockStatusA
test\n");
+        goto cleanup;
+    }
+
+    /* Allocate memory */
+    lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize);
+    if (lpLockStatus == NULL)
+    {
+        skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize);
+        goto cleanup;
+    }
+
+    /* Get the actual value */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusA(hScm,
+                                     lpLockStatus,
+                                     dwRequiredSize,
+                                     &dwRequiredSize);
+    ok(bError, "bError = %u, expected TRUE\n", bError);
+
+    /* These conditions must be verified iff the services database wasn't previously
locked */
+    ok(lpLockStatus->fIsLocked == 0, "lpLockStatus->fIsLocked = %lu, expected
0\n", lpLockStatus->fIsLocked);
+    ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null,
expected non-null\n");
+    ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner == 0,
"*lpLockStatus->lpLockOwner != \"\\0\", expected
\"\\0\"\n");
+    ok(lpLockStatus->dwLockDuration == 0, "lpLockStatus->dwLockDuration = %lu,
expected 0\n", lpLockStatus->dwLockDuration);
+
+    HeapFree(GetProcessHeap(), 0, lpLockStatus);
+
+    CloseServiceHandle(hScm);
+
+
+    /*
+     * Now, try to lock the database and check its lock status.
+     */
+
+    SetLastError(0xdeadbeef);
+    hScm = OpenSCManagerA(NULL, NULL, SC_MANAGER_LOCK | SC_MANAGER_QUERY_LOCK_STATUS);
+    ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n",
GetLastError());
+    if (!hScm)
+    {
+        skip("No service control manager; cannot proceed with QueryLockStatusA
test\n");
+        goto cleanup;
+    }
+    ok_err(ERROR_SUCCESS);
+
+    /* Get the needed size */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusA(hScm,
+                                     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 QueryLockStatusA
test\n");
+        goto cleanup;
+    }
+
+    /* Allocate memory */
+    lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize);
+    if (lpLockStatus == NULL)
+    {
+        skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize);
+        goto cleanup;
+    }
+
+    /* Get the actual value */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusA(hScm,
+                                     lpLockStatus,
+                                     dwRequiredSize,
+                                     &dwRequiredSize);
+    ok(bError, "bError = %u, expected TRUE\n", bError);
+
+    /* These conditions must be verified iff the services database wasn't previously
locked */
+    ok(lpLockStatus->fIsLocked == 0, "lpLockStatus->fIsLocked = %lu, expected
0\n", lpLockStatus->fIsLocked);
+    ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null,
expected non-null\n");
+    ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner == 0,
"*lpLockStatus->lpLockOwner != \"\\0\", expected
\"\\0\"\n");
+    ok(lpLockStatus->dwLockDuration == 0, "lpLockStatus->dwLockDuration = %lu,
expected 0\n", lpLockStatus->dwLockDuration);
+
+    HeapFree(GetProcessHeap(), 0, lpLockStatus);
+
+
+    /*
+     * Try again, this time with the database locked.
+     */
+
+    SetLastError(0xdeadbeef);
+    hLock = LockServiceDatabase(hScm);
+    ok(hLock != NULL, "hLock = 0x%p, expected non-zero\n", hLock);
+    ok_err(ERROR_SUCCESS);
+
+    Sleep(1000); /* Wait 1 second to let lpLockStatus->dwLockDuration increment */
+
+    /* Get the needed size */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusA(hScm,
+                                     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 QueryLockStatusA
test\n");
+        goto cleanup;
+    }
+
+    /* Allocate memory */
+    lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize);
+    if (lpLockStatus == NULL)
+    {
+        skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize);
+        goto cleanup;
+    }
+
+    /* Get the actual value */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusA(hScm,
+                                     lpLockStatus,
+                                     dwRequiredSize,
+                                     &dwRequiredSize);
+    ok(bError, "bError = %u, expected TRUE\n", bError);
+
+    /* These conditions must be verified iff the services database is locked */
+    ok(lpLockStatus->fIsLocked != 0, "lpLockStatus->fIsLocked = %lu, expected
non-zero\n", lpLockStatus->fIsLocked);
+    ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null,
expected non-null\n");
+    ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner != 0,
"*lpLockStatus->lpLockOwner = \"\\0\", expected non-zero\n");
+    ok(lpLockStatus->dwLockDuration != 0, "lpLockStatus->dwLockDuration = %lu,
expected non-zero\n", lpLockStatus->dwLockDuration);
+
+    HeapFree(GetProcessHeap(), 0, lpLockStatus);
+
+
+    /*
+     * Last try, with the database again unlocked.
+     */
+
+    SetLastError(0xdeadbeef);
+    bError = UnlockServiceDatabase(hLock);
+    ok(bError == TRUE, "bError = %u, expected TRUE\n", bError);
+    ok_err(ERROR_SUCCESS);
+    hLock = NULL;
+
+    /* Get the needed size */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusA(hScm,
+                                     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 QueryLockStatusA
test\n");
+        goto cleanup;
+    }
+
+    /* Allocate memory */
+    lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize);
+    if (lpLockStatus == NULL)
+    {
+        skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize);
+        goto cleanup;
+    }
+
+    /* Get the actual value */
+    SetLastError(0xdeadbeef);
+    bError = QueryServiceLockStatusA(hScm,
+                                     lpLockStatus,
+                                     dwRequiredSize,
+                                     &dwRequiredSize);
+    ok(bError, "bError = %u, expected TRUE\n", bError);
+
+    /* These conditions must be verified iff the services database is unlocked */
+    ok(lpLockStatus->fIsLocked == 0, "lpLockStatus->fIsLocked = %lu, expected
0\n", lpLockStatus->fIsLocked);
+    ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null,
expected non-null\n");
+    ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner == 0,
"*lpLockStatus->lpLockOwner != \"\\0\", expected
\"\\0\"\n");
+    ok(lpLockStatus->dwLockDuration == 0, "lpLockStatus->dwLockDuration = %lu,
expected 0\n", lpLockStatus->dwLockDuration);
+
+    HeapFree(GetProcessHeap(), 0, lpLockStatus);
+
+
+cleanup:
+    if (hLock)
+        UnlockServiceDatabase(hLock);
+
+    if (hScm)
+        CloseServiceHandle(hScm);
+
+    return;
+}
+
+
+START_TEST(LockDatabase)
+{
+    Test_LockUnlockServiceDatabase();
+    Test_LockUnlockServiceDatabaseWithServiceStart();
+    Test_QueryLockStatusW();
+    Test_QueryLockStatusA();
+}
Propchange: trunk/rostests/apitests/advapi32/LockDatabase.c
------------------------------------------------------------------------------
    svn:eol-style = native
Modified: trunk/rostests/apitests/advapi32/QueryServiceConfig2.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/advapi32/QuerySe…
==============================================================================
--- trunk/rostests/apitests/advapi32/QueryServiceConfig2.c [iso-8859-1] (original)
+++ trunk/rostests/apitests/advapi32/QueryServiceConfig2.c [iso-8859-1] Fri Jun 29
11:48:35 2012
@@ -2,12 +2,15 @@
  * 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
+ * PROGRAMMER:      Hermès BÃLUSCA - MAÃTO
  */
 #include <wine/test.h>
 #include <windows.h>
 #include <strsafe.h>
+
+#define TESTING_SERVICEW     L"Spooler"
+#define TESTING_SERVICEA      "Spooler"
 /*
  * Taken from base/system/services/config.c and adapted.
@@ -495,7 +498,7 @@
     ok_err(ERROR_SUCCESS);
     SetLastError(0xdeadbeef);
-    hService = OpenServiceW(hScm, L"Spooler", SERVICE_QUERY_CONFIG);
+    hService = OpenServiceW(hScm, TESTING_SERVICEW, SERVICE_QUERY_CONFIG);
     ok(hService != NULL, "Failed to open service handle, error=0x%08lx\n",
GetLastError());
     if (!hService)
     {
@@ -505,10 +508,10 @@
     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)
+    if (QueryConfig2W(hService, TESTING_SERVICEW, SERVICE_CONFIG_DESCRIPTION) != 0)
+        goto cleanup;
+
+    if (QueryConfig2W(hService, TESTING_SERVICEW, SERVICE_CONFIG_FAILURE_ACTIONS) != 0)
         goto cleanup;
 cleanup:
@@ -536,7 +539,7 @@
     ok_err(ERROR_SUCCESS);
     SetLastError(0xdeadbeef);
-    hService = OpenServiceA(hScm, "Spooler", SERVICE_QUERY_CONFIG);
+    hService = OpenServiceA(hScm, TESTING_SERVICEA, SERVICE_QUERY_CONFIG);
     ok(hService != NULL, "Failed to open service handle, error=0x%08lx\n",
GetLastError());
     if (!hService)
     {
@@ -546,10 +549,10 @@
     ok_err(ERROR_SUCCESS);
-    if (QueryConfig2A(hService, "Spooler", SERVICE_CONFIG_DESCRIPTION) != 0)
-        goto cleanup;
-
-    if (QueryConfig2A(hService, "Spooler", SERVICE_CONFIG_FAILURE_ACTIONS) !=
0)
+    if (QueryConfig2A(hService, TESTING_SERVICEA, SERVICE_CONFIG_DESCRIPTION) != 0)
+        goto cleanup;
+
+    if (QueryConfig2A(hService, TESTING_SERVICEA, SERVICE_CONFIG_FAILURE_ACTIONS) != 0)
         goto cleanup;
 cleanup:
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] Fri Jun 29 11:48:35 2012
@@ -6,11 +6,13 @@
 #include "wine/test.h"
 extern void func_CreateService(void);
+extern void func_LockDatabase(void);
 extern void func_QueryServiceConfig2(void);
 const struct test winetest_testlist[] =
 {
     { "CreateService", func_CreateService },
+    { "LockDatabase" , func_LockDatabase },
     { "QueryServiceConfig2", func_QueryServiceConfig2 },
     { 0, 0 }