[SERVICES]
[reactos.git] / reactos / base / system / services / rpcserver.c
index 193cb9b..58d8b5d 100644 (file)
@@ -24,7 +24,6 @@
 typedef struct _SCMGR_HANDLE
 {
     DWORD Tag;
-    DWORD RefCount;
     DWORD DesiredAccess;
 } SCMGR_HANDLE;
 
@@ -32,9 +31,6 @@ typedef struct _SCMGR_HANDLE
 typedef struct _MANAGER_HANDLE
 {
     SCMGR_HANDLE Handle;
-
-    /* FIXME: Insert more data here */
-
     WCHAR DatabaseName[1];
 } MANAGER_HANDLE, *PMANAGER_HANDLE;
 
@@ -42,12 +38,7 @@ typedef struct _MANAGER_HANDLE
 typedef struct _SERVICE_HANDLE
 {
     SCMGR_HANDLE Handle;
-
-    DWORD DesiredAccess;
     PSERVICE ServiceEntry;
-
-    /* FIXME: Insert more data here */
-
 } SERVICE_HANDLE, *PSERVICE_HANDLE;
 
 
@@ -151,14 +142,14 @@ ScmCreateManagerHandle(LPWSTR lpDatabaseName,
     if (lpDatabaseName == NULL)
         lpDatabaseName = SERVICES_ACTIVE_DATABASEW;
 
-    if (_wcsicmp(lpDatabaseName,SERVICES_FAILED_DATABASEW)==0)
+    if (_wcsicmp(lpDatabaseName, SERVICES_FAILED_DATABASEW) == 0)
     {
-        DPRINT1("Database %S, does not exist\n",lpDatabaseName);
+        DPRINT("Database %S, does not exist\n",lpDatabaseName);
         return ERROR_DATABASE_DOES_NOT_EXIST;
     }
     else if (_wcsicmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0)
     {
-        DPRINT1("Invalid Database name %S.\n",lpDatabaseName);
+        DPRINT("Invalid Database name %S.\n",lpDatabaseName);
         return ERROR_INVALID_NAME;
     }
 
@@ -169,9 +160,6 @@ ScmCreateManagerHandle(LPWSTR lpDatabaseName,
         return ERROR_NOT_ENOUGH_MEMORY;
 
     Ptr->Handle.Tag = MANAGER_TAG;
-    Ptr->Handle.RefCount = 1;
-
-    /* FIXME: initialize more data here */
 
     wcscpy(Ptr->DatabaseName, lpDatabaseName);
 
@@ -194,9 +182,7 @@ ScmCreateServiceHandle(PSERVICE lpServiceEntry,
         return ERROR_NOT_ENOUGH_MEMORY;
 
     Ptr->Handle.Tag = SERVICE_TAG;
-    Ptr->Handle.RefCount = 1;
 
-    /* FIXME: initialize more data here */
     Ptr->ServiceEntry = lpServiceEntry;
 
     *Handle = (SC_HANDLE)Ptr;
@@ -205,6 +191,46 @@ ScmCreateServiceHandle(PSERVICE lpServiceEntry,
 }
 
 
+static PMANAGER_HANDLE
+ScmGetServiceManagerFromHandle(SC_RPC_HANDLE Handle)
+{
+    PMANAGER_HANDLE pManager = NULL;
+
+    _SEH2_TRY
+    {
+        if (((PMANAGER_HANDLE)Handle)->Handle.Tag == MANAGER_TAG)
+            pManager = (PMANAGER_HANDLE)Handle;
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        DPRINT1("Exception: Invalid Service Manager handle!\n");
+    }
+    _SEH2_END;
+
+    return pManager;
+}
+
+
+static PSERVICE_HANDLE
+ScmGetServiceFromHandle(SC_RPC_HANDLE Handle)
+{
+    PSERVICE_HANDLE pService = NULL;
+
+    _SEH2_TRY
+    {
+        if (((PSERVICE_HANDLE)Handle)->Handle.Tag == SERVICE_TAG)
+            pService = (PSERVICE_HANDLE)Handle;
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        DPRINT1("Exception: Invalid Service handle!\n");
+    }
+    _SEH2_END;
+
+    return pService;
+}
+
+
 static DWORD
 ScmCheckAccess(SC_HANDLE Handle,
                DWORD dwDesiredAccess)
@@ -284,7 +310,7 @@ Int_EnumDependentServicesW(HKEY hServicesKey,
                                NULL);
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ERROR! Unable to get number of services keys.\n");
+        DPRINT("ERROR! Unable to get number of services keys.\n");
         return dwError;
     }
 
@@ -341,7 +367,7 @@ Int_EnumDependentServicesW(HKEY hServicesKey,
                     if (!lpCurrentService)
                     {
                         /* This should never happen! */
-                        DPRINT1("This should not happen at this point, report to Developer\n");
+                        DPRINT("This should not happen at this point, report to Developer\n");
                         return ERROR_NOT_FOUND;
                     }
 
@@ -417,42 +443,38 @@ DWORD RCloseServiceHandle(
     if (*hSCObject == 0)
         return ERROR_INVALID_HANDLE;
 
-    hManager = (PMANAGER_HANDLE)*hSCObject;
-    hService = (PSERVICE_HANDLE)*hSCObject;
-    if (hManager->Handle.Tag == MANAGER_TAG)
+    hManager = ScmGetServiceManagerFromHandle(*hSCObject);
+    hService = ScmGetServiceFromHandle(*hSCObject);
+
+    if (hManager != NULL)
     {
         DPRINT("Found manager handle\n");
 
-        hManager->Handle.RefCount--;
-        if (hManager->Handle.RefCount == 0)
-        {
-            /* FIXME: add handle cleanup code */
+        /* FIXME: add handle cleanup code */
 
-            HeapFree(GetProcessHeap(), 0, hManager);
-            hManager = NULL;
-        }
+        HeapFree(GetProcessHeap(), 0, hManager);
+        hManager = NULL;
+
+        *hSCObject = NULL;
 
         DPRINT("RCloseServiceHandle() done\n");
         return ERROR_SUCCESS;
     }
-    else if (hService->Handle.Tag == SERVICE_TAG)
+    else if (hService != NULL)
     {
         DPRINT("Found service handle\n");
 
+        /* Lock the service database exlusively */
+        ScmLockDatabaseExclusive();
+
         /* Get the pointer to the service record */
         lpService = hService->ServiceEntry;
 
-        ASSERT(hService->Handle.RefCount > 0);
+        /* FIXME: add handle cleanup code */
 
-        hService->Handle.RefCount--;
-        if (hService->Handle.RefCount == 0)
-        {
-            /* FIXME: add handle cleanup code */
-
-            /* Free the handle */
-            HeapFree(GetProcessHeap(), 0, hService);
-            hService = NULL;
-        }
+        /* Free the handle */
+        HeapFree(GetProcessHeap(), 0, hService);
+        hService = NULL;
 
         ASSERT(lpService->dwRefCount > 0);
 
@@ -473,7 +495,8 @@ DWORD RCloseServiceHandle(
                                         &hServicesKey);
                 if (dwError != ERROR_SUCCESS)
                 {
-                    DPRINT1("Failed to open services key\n");
+                    DPRINT("Failed to open services key\n");
+                    ScmUnlockDatabase();
                     return dwError;
                 }
 
@@ -488,8 +511,9 @@ DWORD RCloseServiceHandle(
                 /* if pcbBytesNeeded returned a value then there are services running that are dependent on this service*/
                 if (pcbBytesNeeded)
                 {
-                    DPRINT1("Deletion failed due to running dependencies.\n");
+                    DPRINT("Deletion failed due to running dependencies.\n");
                     RegCloseKey(hServicesKey);
+                    ScmUnlockDatabase();
                     return ERROR_SUCCESS;
                 }
 
@@ -504,7 +528,8 @@ DWORD RCloseServiceHandle(
 
                 if (dwError != ERROR_SUCCESS)
                 {
-                    DPRINT1("Failed to Delete the Service Registry key\n");
+                    DPRINT("Failed to Delete the Service Registry key\n");
+                    ScmUnlockDatabase();
                     return dwError;
                 }
 
@@ -513,11 +538,15 @@ DWORD RCloseServiceHandle(
             }
         }
 
+        ScmUnlockDatabase();
+
+        *hSCObject = NULL;
+
         DPRINT("RCloseServiceHandle() done\n");
         return ERROR_SUCCESS;
     }
 
-    DPRINT1("Invalid handle tag (Tag %lx)\n", hManager->Handle.Tag);
+    DPRINT("Invalid handle tag (Tag %lx)\n", hManager->Handle.Tag);
 
     return ERROR_INVALID_HANDLE;
 }
@@ -535,6 +564,8 @@ DWORD RControlService(
     DWORD dwError = ERROR_SUCCESS;
     DWORD pcbBytesNeeded = 0;
     DWORD dwServicesReturned = 0;
+    DWORD dwControlsAccepted;
+    DWORD dwCurrentState;
     HKEY hServicesKey = NULL;
 
     DPRINT("RControlService() called\n");
@@ -543,13 +574,14 @@ DWORD RControlService(
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
     /* Check the service handle */
-    hSvc = (PSERVICE_HANDLE)hService;
-    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
     {
-        DPRINT1("Invalid handle tag!\n");
+        DPRINT1("Invalid service handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
+
     /* Check the service entry point */
     lpService = hSvc->ServiceEntry;
     if (lpService == NULL)
@@ -603,7 +635,7 @@ DWORD RControlService(
                                 &hServicesKey);
         if (dwError != ERROR_SUCCESS)
         {
-            DPRINT1("Failed to open services key\n");
+            DPRINT("Failed to open services key\n");
             return dwError;
         }
 
@@ -635,10 +667,57 @@ DWORD RControlService(
     }
     else
     {
+        dwControlsAccepted = lpService->Status.dwControlsAccepted;
+        dwCurrentState = lpService->Status.dwCurrentState;
+
+        /* Check the current state before sending a control request */
+        switch (dwCurrentState)
+        {
+            case SERVICE_STOP_PENDING:
+            case SERVICE_STOPPED:
+                return ERROR_SERVICE_CANNOT_ACCEPT_CTRL;
+
+            case SERVICE_START_PENDING:
+                switch (dwControl)
+                {
+                    case SERVICE_CONTROL_STOP:
+                        break;
+
+                    case SERVICE_CONTROL_INTERROGATE:
+                        RtlCopyMemory(lpServiceStatus,
+                                      &lpService->Status,
+                                      sizeof(SERVICE_STATUS));
+                        return ERROR_SUCCESS;
+
+                    default:
+                        return ERROR_SERVICE_CANNOT_ACCEPT_CTRL;
+                }
+                break;
+        }
+
+        /* Check if the control code is acceptable to the service */
+        switch (dwControl)
+        {
+            case SERVICE_CONTROL_STOP:
+                if ((dwControlsAccepted & SERVICE_ACCEPT_STOP) == 0)
+                    return ERROR_INVALID_SERVICE_CONTROL;
+                break;
+
+            case SERVICE_CONTROL_PAUSE:
+            case SERVICE_CONTROL_CONTINUE:
+                if ((dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) == 0)
+                    return ERROR_INVALID_SERVICE_CONTROL;
+                break;
+        }
+
         /* Send control code to the service */
         dwError = ScmControlService(lpService,
-                                    dwControl,
-                                    lpServiceStatus);
+                                    dwControl);
+
+        /* Return service status information */
+        RtlCopyMemory(lpServiceStatus,
+                      &lpService->Status,
+                      sizeof(SERVICE_STATUS));
     }
 
     if ((dwError == ERROR_SUCCESS) && (pcbBytesNeeded))
@@ -652,10 +731,6 @@ DWORD RControlService(
         lpService->ThreadId = 0;
     }
 
-    /* Return service status information */
-    RtlCopyMemory(lpServiceStatus,
-                  &lpService->Status,
-                  sizeof(SERVICE_STATUS));
 
     return dwError;
 }
@@ -674,9 +749,12 @@ DWORD RDeleteService(
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
-    hSvc = (PSERVICE_HANDLE)hService;
-    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
+    {
+        DPRINT1("Invalid service handle!\n");
         return ERROR_INVALID_HANDLE;
+    }
 
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   DELETE))
@@ -685,16 +763,18 @@ DWORD RDeleteService(
     lpService = hSvc->ServiceEntry;
     if (lpService == NULL)
     {
-        DPRINT1("lpService == NULL!\n");
+        DPRINT("lpService == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
-    /* FIXME: Acquire service database lock exclusively */
+    /* Lock the service database exclusively */
+    ScmLockDatabaseExclusive();
 
     if (lpService->bDeleted)
     {
-        DPRINT1("The service has already been marked for delete!\n");
-        return ERROR_SERVICE_MARKED_FOR_DELETE;
+        DPRINT("The service has already been marked for delete!\n");
+        dwError = ERROR_SERVICE_MARKED_FOR_DELETE;
+        goto Done;
     }
 
     /* Mark service for delete */
@@ -702,7 +782,9 @@ DWORD RDeleteService(
 
     dwError = ScmMarkServiceForDelete(lpService);
 
-    /* FIXME: Release service database lock */
+Done:;
+    /* Unlock the service database */
+    ScmUnlockDatabase();
 
     DPRINT("RDeleteService() done\n");
 
@@ -721,9 +803,12 @@ DWORD RLockServiceDatabase(
 
     *lpLock = 0;
 
-    hMgr = (PMANAGER_HANDLE)hSCManager;
-    if (!hMgr || hMgr->Handle.Tag != MANAGER_TAG)
+    hMgr = ScmGetServiceManagerFromHandle(hSCManager);
+    if (hMgr == NULL)
+    {
+        DPRINT1("Invalid service manager handle!\n");
         return ERROR_INVALID_HANDLE;
+    }
 
     if (!RtlAreAllAccessesGranted(hMgr->Handle.DesiredAccess,
                                   SC_MANAGER_LOCK))
@@ -758,15 +843,15 @@ DWORD RQueryServiceObjectSecurity(
 
     DPRINT("RQueryServiceObjectSecurity() called\n");
 
-    hSvc = (PSERVICE_HANDLE)hService;
-    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
     {
-        DPRINT1("Invalid handle tag!\n");
+        DPRINT1("Invalid service handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
-    if (dwSecurityInformation & (DACL_SECURITY_INFORMATION ||
-                                 GROUP_SECURITY_INFORMATION ||
+    if (dwSecurityInformation & (DACL_SECURITY_INFORMATION |
+                                 GROUP_SECURITY_INFORMATION |
                                  OWNER_SECURITY_INFORMATION))
         DesiredAccess |= READ_CONTROL;
 
@@ -776,14 +861,14 @@ DWORD RQueryServiceObjectSecurity(
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   DesiredAccess))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
     lpService = hSvc->ServiceEntry;
     if (lpService == NULL)
     {
-        DPRINT1("lpService == NULL!\n");
+        DPRINT("lpService == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
@@ -838,12 +923,12 @@ DWORD RSetServiceObjectSecurity(
     /* NTSTATUS Status; */
     DWORD dwError;
 
-    DPRINT1("RSetServiceObjectSecurity() called\n");
+    DPRINT("RSetServiceObjectSecurity() called\n");
 
-    hSvc = (PSERVICE_HANDLE)hService;
-    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
     {
-        DPRINT1("Invalid handle tag!\n");
+        DPRINT1("Invalid service handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
@@ -875,14 +960,14 @@ DWORD RSetServiceObjectSecurity(
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   DesiredAccess))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
     lpService = hSvc->ServiceEntry;
     if (lpService == NULL)
     {
-        DPRINT1("lpService == NULL!\n");
+        DPRINT("lpService == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
@@ -957,32 +1042,38 @@ DWORD RQueryServiceStatus(
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
-    hSvc = (PSERVICE_HANDLE)hService;
-    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
     {
-        DPRINT1("Invalid handle tag!\n");
+        DPRINT1("Invalid service handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   SERVICE_QUERY_STATUS))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
     lpService = hSvc->ServiceEntry;
     if (lpService == NULL)
     {
-        DPRINT1("lpService == NULL!\n");
+        DPRINT("lpService == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
+    /* Lock the srevice database shared */
+    ScmLockDatabaseShared();
+
     /* Return service status information */
     RtlCopyMemory(lpServiceStatus,
                   &lpService->Status,
                   sizeof(SERVICE_STATUS));
 
+    /* Unlock the service database */
+    ScmUnlockDatabase();
+
     return ERROR_SUCCESS;
 }
 
@@ -1026,21 +1117,21 @@ DWORD RSetServiceStatus(
 
     if (hServiceStatus == 0)
     {
-        DPRINT1("hServiceStatus == NULL!\n");
+        DPRINT("hServiceStatus == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
-    lpService = ScmGetServiceEntryByClientHandle((HANDLE)hServiceStatus);
+    lpService = (PSERVICE)hServiceStatus;
     if (lpService == NULL)
     {
-        DPRINT1("lpService == NULL!\n");
+        DPRINT("lpService == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
     /* Check current state */
     if (!ScmIsValidServiceState(lpServiceStatus->dwCurrentState))
     {
-        DPRINT1("Invalid service state!\n");
+        DPRINT("Invalid service state!\n");
         return ERROR_INVALID_DATA;
     }
 
@@ -1048,22 +1139,27 @@ DWORD RSetServiceStatus(
     if (!(lpServiceStatus->dwServiceType & SERVICE_WIN32) &&
          (lpServiceStatus->dwServiceType & SERVICE_DRIVER))
     {
-        DPRINT1("Invalid service type!\n");
+        DPRINT("Invalid service type!\n");
         return ERROR_INVALID_DATA;
     }
 
     /* Check accepted controls */
     if (lpServiceStatus->dwControlsAccepted & ~0xFF)
     {
-        DPRINT1("Invalid controls accepted!\n");
+        DPRINT("Invalid controls accepted!\n");
         return ERROR_INVALID_DATA;
     }
 
+    /* Lock the service database exclusively */
+    ScmLockDatabaseExclusive();
 
     RtlCopyMemory(&lpService->Status,
                   lpServiceStatus,
                   sizeof(SERVICE_STATUS));
 
+    /* Unlock the service database */
+    ScmUnlockDatabase();
+
     DPRINT("Set %S to %lu\n", lpService->lpDisplayName, lpService->Status.dwCurrentState);
     DPRINT("RSetServiceStatus() done\n");
 
@@ -1085,8 +1181,11 @@ DWORD RNotifyBootConfigStatus(
     SVCCTL_HANDLEW lpMachineName,
     DWORD BootAcceptable)
 {
-    UNIMPLEMENTED;
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    DPRINT1("RNotifyBootConfigStatus(%p %lu) called\n", lpMachineName, BootAcceptable);
+    return ERROR_SUCCESS;
+
+//    UNIMPLEMENTED;
+//    return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
@@ -1136,34 +1235,35 @@ DWORD RChangeServiceConfigW(
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
-    hSvc = (PSERVICE_HANDLE)hService;
-    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
     {
-        DPRINT1("Invalid handle tag!\n");
+        DPRINT1("Invalid service handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   SERVICE_CHANGE_CONFIG))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
     lpService = hSvc->ServiceEntry;
     if (lpService == NULL)
     {
-        DPRINT1("lpService == NULL!\n");
+        DPRINT("lpService == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
-    /* FIXME: Lock database exclusively */
+    /* Lock the service database exclusively */
+    ScmLockDatabaseExclusive();
 
     if (lpService->bDeleted)
     {
-        /* FIXME: Unlock database */
-        DPRINT1("The service has already been marked for delete!\n");
-        return ERROR_SERVICE_MARKED_FOR_DELETE;
+        DPRINT("The service has already been marked for delete!\n");
+        dwError = ERROR_SERVICE_MARKED_FOR_DELETE;
+        goto done;
     }
 
     /* Open the service key */
@@ -1330,12 +1430,13 @@ DWORD RChangeServiceConfigW(
         /* FIXME: Write password */
     }
 
-    /* FIXME: Unlock database */
-
 done:
     if (hServiceKey != NULL)
         RegCloseKey(hServiceKey);
 
+    /* Unlock the service database */
+    ScmUnlockDatabase();
+
     DPRINT("RChangeServiceConfigW() done (Error %lu)\n", dwError);
 
     return dwError;
@@ -1365,14 +1466,14 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
         *RelativeName = LocalAlloc(LMEM_ZEROINIT, ServiceNameLen * sizeof(WCHAR) + sizeof(WCHAR));
         if (*RelativeName == NULL)
         {
-            DPRINT1("Error allocating memory for boot driver name!\n");
+            DPRINT("Error allocating memory for boot driver name!\n");
             return ERROR_NOT_ENOUGH_MEMORY;
         }
 
         /* Copy it */
         wcscpy(*RelativeName, CanonName);
 
-        DPRINT1("Bootdriver name %S\n", *RelativeName);
+        DPRINT("Bootdriver name %S\n", *RelativeName);
         return ERROR_SUCCESS;
     }
 
@@ -1385,7 +1486,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
 
         if (*RelativeName == NULL)
         {
-            DPRINT1("Error allocating memory for boot driver name!\n");
+            DPRINT("Error allocating memory for boot driver name!\n");
             return ERROR_NOT_ENOUGH_MEMORY;
         }
 
@@ -1393,7 +1494,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
         wcscpy(*RelativeName, L"\\SystemRoot\\");
         wcscat(*RelativeName, CanonName + 13);
 
-        DPRINT1("Bootdriver name %S\n", *RelativeName);
+        DPRINT("Bootdriver name %S\n", *RelativeName);
         return ERROR_SUCCESS;
     }
 
@@ -1402,7 +1503,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
 
     if (BufferSize <= 1)
     {
-        DPRINT1("Error during a call to ExpandEnvironmentStringsW()\n");
+        DPRINT("Error during a call to ExpandEnvironmentStringsW()\n");
         return ERROR_INVALID_ENVIRONMENT;
     }
 
@@ -1410,7 +1511,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
     Expanded = LocalAlloc(LMEM_ZEROINIT, BufferSize * sizeof(WCHAR) + sizeof(WCHAR));
     if (!Expanded)
     {
-        DPRINT1("Error allocating memory for boot driver name!\n");
+        DPRINT("Error allocating memory for boot driver name!\n");
         return ERROR_NOT_ENOUGH_MEMORY;
     }
 
@@ -1418,7 +1519,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
     if (ExpandEnvironmentStringsW(L"%SystemRoot%\\", Expanded, BufferSize) >
         BufferSize)
     {
-        DPRINT1("Error during a call to ExpandEnvironmentStringsW()\n");
+        DPRINT("Error during a call to ExpandEnvironmentStringsW()\n");
         LocalFree(Expanded);
         return ERROR_NOT_ENOUGH_MEMORY;
     }
@@ -1426,7 +1527,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
     /* Convert to NY-style path */
     if (!RtlDosPathNameToNtPathName_U(Expanded, &NtPathName, NULL, NULL))
     {
-        DPRINT1("Error during a call to RtlDosPathNameToNtPathName_U()\n");
+        DPRINT("Error during a call to RtlDosPathNameToNtPathName_U()\n");
         return ERROR_INVALID_ENVIRONMENT;
     }
 
@@ -1439,7 +1540,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
     Expanded = LocalAlloc(LMEM_ZEROINIT, NtPathName.Length + sizeof(WCHAR));
     if (!Expanded)
     {
-            DPRINT1("Error allocating memory for boot driver name!\n");
+            DPRINT("Error allocating memory for boot driver name!\n");
             return ERROR_NOT_ENOUGH_MEMORY;
     }
 
@@ -1455,7 +1556,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
             (ServiceNameLen - ExpandedLen) * sizeof(WCHAR) + 13*sizeof(WCHAR));
         if (*RelativeName == NULL)
         {
-            DPRINT1("Error allocating memory for boot driver name!\n");
+            DPRINT("Error allocating memory for boot driver name!\n");
             LocalFree(Expanded);
             return ERROR_NOT_ENOUGH_MEMORY;
         }
@@ -1491,7 +1592,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
             /* Check if required buffer size is sane */
             if (BufferSize > 0xFFFD)
             {
-                DPRINT1("Too large buffer required\n");
+                DPRINT("Too large buffer required\n");
                 *RelativeName = 0;
 
                 if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
@@ -1503,7 +1604,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
             LinkTarget.Buffer = LocalAlloc(LMEM_ZEROINIT, BufferSize + sizeof(WCHAR));
             if (!LinkTarget.Buffer)
             {
-                DPRINT1("Unable to alloc buffer\n");
+                DPRINT("Unable to alloc buffer\n");
                 if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
                 LocalFree(Expanded);
                 return ERROR_NOT_ENOUGH_MEMORY;
@@ -1527,7 +1628,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
 
                     if (*RelativeName == NULL)
                     {
-                        DPRINT1("Unable to alloc buffer\n");
+                        DPRINT("Unable to alloc buffer\n");
                         if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
                         LocalFree(Expanded);
                         RtlFreeUnicodeString(&NtPathName);
@@ -1557,7 +1658,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
             }
             else
             {
-                DPRINT1("Error, Status = %08X\n", Status);
+                DPRINT("Error, Status = %08X\n", Status);
                 if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
                 LocalFree(Expanded);
                 RtlFreeUnicodeString(&NtPathName);
@@ -1566,7 +1667,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
         }
         else
         {
-            DPRINT1("Error, Status = %08X\n", Status);
+            DPRINT("Error, Status = %08X\n", Status);
             if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
             LocalFree(Expanded);
             RtlFreeUnicodeString(&NtPathName);
@@ -1575,7 +1676,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
     }
     else
     {
-        DPRINT1("Error, Status = %08X\n", Status);
+        DPRINT("Error, Status = %08X\n", Status);
         LocalFree(Expanded);
         return ERROR_INVALID_PARAMETER;
     }
@@ -1608,7 +1709,7 @@ ScmCanonDriverImagePath(DWORD dwStartType,
 
         if (*lpCanonName == NULL)
         {
-            DPRINT1("Error allocating memory for canonized service name!\n");
+            DPRINT("Error allocating memory for canonized service name!\n");
             return ERROR_NOT_ENOUGH_MEMORY;
         }
 
@@ -1632,7 +1733,7 @@ ScmCanonDriverImagePath(DWORD dwStartType,
 
         if (*lpCanonName == NULL)
         {
-            DPRINT1("Error allocating memory for canonized service name!\n");
+            DPRINT("Error allocating memory for canonized service name!\n");
             return ERROR_NOT_ENOUGH_MEMORY;
         }
 
@@ -1653,7 +1754,7 @@ ScmCanonDriverImagePath(DWORD dwStartType,
 
         if (*lpCanonName == NULL)
         {
-            DPRINT1("Error allocating memory for canonized service name!\n");
+            DPRINT("Error allocating memory for canonized service name!\n");
             return ERROR_NOT_ENOUGH_MEMORY;
         }
 
@@ -1666,7 +1767,7 @@ ScmCanonDriverImagePath(DWORD dwStartType,
     /* It seems to be a DOS path, convert it */
     if (!RtlDosPathNameToNtPathName_U(lpServiceName, &NtServiceName, NULL, NULL))
     {
-        DPRINT1("RtlDosPathNameToNtPathName_U() failed!\n");
+        DPRINT("RtlDosPathNameToNtPathName_U() failed!\n");
         return ERROR_INVALID_PARAMETER;
     }
 
@@ -1674,7 +1775,7 @@ ScmCanonDriverImagePath(DWORD dwStartType,
 
     if (*lpCanonName == NULL)
     {
-        DPRINT1("Error allocating memory for canonized service name!\n");
+        DPRINT("Error allocating memory for canonized service name!\n");
         RtlFreeUnicodeString(&NtServiceName);
         return ERROR_NOT_ENOUGH_MEMORY;
     }
@@ -1697,7 +1798,7 @@ ScmCanonDriverImagePath(DWORD dwStartType,
     {
         /* There is a problem, free name and return */
         LocalFree(*lpCanonName);
-        DPRINT1("Error converting named!\n");
+        DPRINT("Error converting named!\n");
         return Result;
     }
 
@@ -1756,10 +1857,10 @@ DWORD RCreateServiceW(
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
-    hManager = (PMANAGER_HANDLE)hSCManager;
-    if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
+    hManager = ScmGetServiceManagerFromHandle(hSCManager);
+    if (hManager == NULL)
     {
-        DPRINT1("Invalid manager handle!\n");
+        DPRINT1("Invalid service manager handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
@@ -1767,8 +1868,8 @@ DWORD RCreateServiceW(
     if (!RtlAreAllAccessesGranted(hManager->Handle.DesiredAccess,
                                   SC_MANAGER_CREATE_SERVICE))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n",
-                hManager->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n",
+               hManager->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
@@ -1800,9 +1901,15 @@ DWORD RCreateServiceW(
         return ERROR_INVALID_PARAMETER;
     }
 
+    /* Lock the service database exclusively */
+    ScmLockDatabaseExclusive();
+
     lpService = ScmGetServiceEntryByName(lpServiceName);
     if (lpService)
     {
+        /* Unlock the service database */
+        ScmUnlockDatabase();
+
         /* check if it is marked for deletion */
         if (lpService->bDeleted)
             return ERROR_SERVICE_MARKED_FOR_DELETE;
@@ -1812,7 +1919,12 @@ DWORD RCreateServiceW(
 
     if (lpDisplayName != NULL &&
         ScmGetServiceEntryByDisplayName(lpDisplayName) != NULL)
+    {
+        /* Unlock the service database */
+        ScmUnlockDatabase();
+
         return ERROR_DUPLICATE_SERVICE_NAME;
+    }
 
     if (dwServiceType & SERVICE_DRIVER)
     {
@@ -1827,6 +1939,9 @@ DWORD RCreateServiceW(
         if (dwStartType == SERVICE_BOOT_START ||
             dwStartType == SERVICE_SYSTEM_START)
         {
+            /* Unlock the service database */
+            ScmUnlockDatabase();
+
             return ERROR_INVALID_PARAMETER;
         }
     }
@@ -2015,6 +2130,9 @@ DWORD RCreateServiceW(
     DPRINT("CreateService - lpService->dwRefCount %u\n", lpService->dwRefCount);
 
 done:;
+    /* Unlock the service database */
+    ScmUnlockDatabase();
+
     if (hServiceKey != NULL)
         RegCloseKey(hServiceKey);
 
@@ -2066,7 +2184,6 @@ DWORD REnumDependentServicesW(
     DWORD dwServicesReturned = 0;
     DWORD dwServiceCount;
     HKEY hServicesKey = NULL;
-    LPSC_RPC_HANDLE hSCObject;
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService = NULL;
     PSERVICE *lpServicesArray = NULL;
@@ -2078,16 +2195,21 @@ DWORD REnumDependentServicesW(
 
     DPRINT("REnumDependentServicesW() called\n");
 
-    hSCObject = &hService;
-    hSvc = (PSERVICE_HANDLE) *hSCObject;
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
+    {
+        DPRINT1("Invalid service handle!\n");
+        return ERROR_INVALID_HANDLE;
+    }
+
     lpService = hSvc->ServiceEntry;
 
     /* Check access rights */
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   SC_MANAGER_ENUMERATE_SERVICE))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n",
-                hSvc->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n",
+               hSvc->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
@@ -2123,7 +2245,7 @@ DWORD REnumDependentServicesW(
                                 (dwServicesReturned + 1) * sizeof(PSERVICE));
     if (!lpServicesArray)
     {
-        DPRINT1("Could not allocate a buffer!!\n");
+        DPRINT("Could not allocate a buffer!!\n");
         dwError = ERROR_NOT_ENOUGH_MEMORY;
         goto Done;
     }
@@ -2211,13 +2333,14 @@ DWORD REnumServicesStatusW(
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
-    hManager = (PMANAGER_HANDLE)hSCManager;
-    if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
+    hManager = ScmGetServiceManagerFromHandle(hSCManager);
+    if (hManager == NULL)
     {
-        DPRINT1("Invalid manager handle!\n");
+        DPRINT1("Invalid service manager handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
+
     *pcbBytesNeeded = 0;
     *lpServicesReturned = 0;
 
@@ -2237,7 +2360,7 @@ DWORD REnumServicesStatusW(
     if (!RtlAreAllAccessesGranted(hManager->Handle.DesiredAccess,
                                   SC_MANAGER_ENUMERATE_SERVICE))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n",
+        DPRINT("Insufficient access rights! 0x%lx\n",
                 hManager->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
@@ -2245,7 +2368,8 @@ DWORD REnumServicesStatusW(
     if (lpResumeHandle)
         dwLastResumeCount = *lpResumeHandle;
 
-    /* FIXME: Lock the service list shared */
+    /* Lock the service database shared */
+    ScmLockDatabaseShared();
 
     lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
     if (lpService == NULL)
@@ -2383,7 +2507,8 @@ DWORD REnumServicesStatusW(
     }
 
 Done:;
-    /* FIXME: Unlock the service list */
+    /* Unlock the service database */
+    ScmUnlockDatabase();
 
     DPRINT("REnumServicesStatusW() done (Error %lu)\n", dwError);
 
@@ -2418,7 +2543,7 @@ DWORD ROpenSCManagerW(
                                      &hHandle);
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmCreateManagerHandle() failed (Error %lu)\n", dwError);
+        DPRINT("ScmCreateManagerHandle() failed (Error %lu)\n", dwError);
         return dwError;
     }
 
@@ -2427,7 +2552,7 @@ DWORD ROpenSCManagerW(
                              dwDesiredAccess | SC_MANAGER_CONNECT);
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError);
+        DPRINT("ScmCheckAccess() failed (Error %lu)\n", dwError);
         HeapFree(GetProcessHeap(), 0, hHandle);
         return dwError;
     }
@@ -2451,7 +2576,7 @@ DWORD ROpenServiceW(
     PSERVICE lpService;
     PMANAGER_HANDLE hManager;
     SC_HANDLE hHandle;
-    DWORD dwError;
+    DWORD dwError = ERROR_SUCCESS;
 
     DPRINT("ROpenServiceW() called\n");
     DPRINT("hSCManager = %p\n", hSCManager);
@@ -2462,10 +2587,10 @@ DWORD ROpenServiceW(
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
-    hManager = (PMANAGER_HANDLE)hSCManager;
-    if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
+    hManager = ScmGetServiceManagerFromHandle(hSCManager);
+    if (hManager == NULL)
     {
-        DPRINT1("Invalid manager handle!\n");
+        DPRINT1("Invalid service manager handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
@@ -2475,14 +2600,16 @@ DWORD ROpenServiceW(
     if (!lpServiceName)
         return ERROR_INVALID_ADDRESS;
 
-    /* FIXME: Lock the service list */
+    /* Lock the service database exclusive */
+    ScmLockDatabaseExclusive();
 
     /* Get service database entry */
     lpService = ScmGetServiceEntryByName(lpServiceName);
     if (lpService == NULL)
     {
         DPRINT("Could not find a service!\n");
-        return ERROR_SERVICE_DOES_NOT_EXIST;
+        dwError = ERROR_SERVICE_DOES_NOT_EXIST;
+        goto Done;
     }
 
     /* Create a service handle */
@@ -2490,8 +2617,8 @@ DWORD ROpenServiceW(
                                      &hHandle);
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmCreateServiceHandle() failed (Error %lu)\n", dwError);
-        return dwError;
+        DPRINT("ScmCreateServiceHandle() failed (Error %lu)\n", dwError);
+        goto Done;
     }
 
     /* Check the desired access */
@@ -2499,9 +2626,9 @@ DWORD ROpenServiceW(
                              dwDesiredAccess);
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError);
+        DPRINT("ScmCheckAccess() failed (Error %lu)\n", dwError);
         HeapFree(GetProcessHeap(), 0, hHandle);
-        return dwError;
+        goto Done;
     }
 
     lpService->dwRefCount++;
@@ -2510,9 +2637,13 @@ DWORD ROpenServiceW(
     *lpServiceHandle = (SC_RPC_HANDLE)hHandle;
     DPRINT("*hService = %p\n", *lpServiceHandle);
 
+Done:;
+    /* Unlock the service database */
+    ScmUnlockDatabase();
+
     DPRINT("ROpenServiceW() done\n");
 
-    return ERROR_SUCCESS;
+    return dwError;
 }
 
 
@@ -2542,28 +2673,29 @@ DWORD RQueryServiceConfigW(
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
-    hSvc = (PSERVICE_HANDLE)hService;
-    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
     {
-        DPRINT1("Invalid handle tag!\n");
+        DPRINT1("Invalid service handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   SERVICE_QUERY_CONFIG))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
     lpService = hSvc->ServiceEntry;
     if (lpService == NULL)
     {
-        DPRINT1("lpService == NULL!\n");
+        DPRINT("lpService == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
-    /* FIXME: Lock the service database shared */
+    /* Lock the service database shared */
+    ScmLockDatabaseShared();
 
     dwError = ScmOpenServiceKey(lpService->lpServiceName,
                                 KEY_READ,
@@ -2703,6 +2835,9 @@ DWORD RQueryServiceConfigW(
         *pcbBytesNeeded = dwRequiredSize;
 
 Done:;
+    /* Unlock the service database */
+    ScmUnlockDatabase();
+
     if (lpImagePath != NULL)
         HeapFree(GetProcessHeap(), 0, lpImagePath);
 
@@ -2715,8 +2850,6 @@ Done:;
     if (hServiceKey != NULL)
         RegCloseKey(hServiceKey);
 
-    /* FIXME: Unlock the service database */
-
     DPRINT("RQueryServiceConfigW() done\n");
 
     return dwError;
@@ -2750,24 +2883,24 @@ DWORD RStartServiceW(
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
-    hSvc = (PSERVICE_HANDLE)hService;
-    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
     {
-        DPRINT1("Invalid handle tag!\n");
+        DPRINT1("Invalid service handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   SERVICE_START))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
     lpService = hSvc->ServiceEntry;
     if (lpService == NULL)
     {
-        DPRINT1("lpService == NULL!\n");
+        DPRINT("lpService == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
@@ -2810,7 +2943,7 @@ DWORD RGetServiceDisplayNameW(
 //    hManager = (PMANAGER_HANDLE)hSCManager;
 //    if (hManager->Handle.Tag != MANAGER_TAG)
 //    {
-//        DPRINT1("Invalid manager handle!\n");
+//        DPRINT("Invalid manager handle!\n");
 //        return ERROR_INVALID_HANDLE;
 //    }
 
@@ -2818,7 +2951,7 @@ DWORD RGetServiceDisplayNameW(
     lpService = ScmGetServiceEntryByName(lpServiceName);
     if (lpService == NULL)
     {
-        DPRINT1("Could not find a service!\n");
+        DPRINT("Could not find a service!\n");
 
         /* If the service could not be found and lpcchBuffer is less than 2, windows
            puts null in lpDisplayName and puts 2 in lpcchBuffer */
@@ -2884,7 +3017,7 @@ DWORD RGetServiceKeyNameW(
 //    hManager = (PMANAGER_HANDLE)hSCManager;
 //    if (hManager->Handle.Tag != MANAGER_TAG)
 //    {
-//        DPRINT1("Invalid manager handle!\n");
+//        DPRINT("Invalid manager handle!\n");
 //        return ERROR_INVALID_HANDLE;
 //    }
 
@@ -2892,7 +3025,7 @@ DWORD RGetServiceKeyNameW(
     lpService = ScmGetServiceEntryByDisplayName(lpDisplayName);
     if (lpService == NULL)
     {
-        DPRINT1("Could not find a service!\n");
+        DPRINT("Could not find a service!\n");
 
         /* If the service could not be found and lpcchBuffer is less than 2, windows
            puts null in lpDisplayName and puts 2 in lpcchBuffer */
@@ -2976,34 +3109,35 @@ DWORD RChangeServiceConfigA(
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
-    hSvc = (PSERVICE_HANDLE)hService;
-    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
     {
-        DPRINT1("Invalid handle tag!\n");
+        DPRINT1("Invalid service handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   SERVICE_CHANGE_CONFIG))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
     lpService = hSvc->ServiceEntry;
     if (lpService == NULL)
     {
-        DPRINT1("lpService == NULL!\n");
+        DPRINT("lpService == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
-    /* FIXME: Lock database exclusively */
+    /* Lock the service database exclusively */
+    ScmLockDatabaseExclusive();
 
     if (lpService->bDeleted)
     {
-        /* FIXME: Unlock database */
-        DPRINT1("The service has already been marked for delete!\n");
-        return ERROR_SERVICE_MARKED_FOR_DELETE;
+        DPRINT("The service has already been marked for delete!\n");
+        dwError = ERROR_SERVICE_MARKED_FOR_DELETE;
+        goto done;
     }
 
     /* Open the service key */
@@ -3218,9 +3352,10 @@ DWORD RChangeServiceConfigA(
         /* FIXME: Write password */
     }
 
-    /* FIXME: Unlock database */
-
 done:
+    /* Unlock the service database */
+    ScmUnlockDatabase();
+
     if (hServiceKey != NULL)
         RegCloseKey(hServiceKey);
 
@@ -3394,7 +3529,6 @@ DWORD REnumDependentServicesA(
     DWORD dwServicesReturned = 0;
     DWORD dwServiceCount;
     HKEY hServicesKey = NULL;
-    LPSC_RPC_HANDLE hSCObject;
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService = NULL;
     PSERVICE *lpServicesArray = NULL;
@@ -3406,16 +3540,21 @@ DWORD REnumDependentServicesA(
 
     DPRINT("REnumDependentServicesA() called\n");
 
-    hSCObject = &hService;
-    hSvc = (PSERVICE_HANDLE) *hSCObject;
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
+    {
+        DPRINT1("Invalid service handle!\n");
+        return ERROR_INVALID_HANDLE;
+    }
+
     lpService = hSvc->ServiceEntry;
 
     /* Check access rights */
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   SC_MANAGER_ENUMERATE_SERVICE))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n",
-                hSvc->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n",
+               hSvc->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
@@ -3456,7 +3595,7 @@ DWORD REnumDependentServicesA(
                                 (dwServicesReturned + 1) * sizeof(PSERVICE));
     if (!lpServicesArray)
     {
-        DPRINT1("Could not allocate a buffer!!\n");
+        DPRINT("Could not allocate a buffer!!\n");
         dwError = ERROR_NOT_ENOUGH_MEMORY;
         goto Done;
     }
@@ -3554,7 +3693,7 @@ DWORD REnumServicesStatusA(
         lpStatusPtrW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufSize);
         if (!lpStatusPtrW)
         {
-            DPRINT1("Failed to allocate buffer!\n");
+            DPRINT("Failed to allocate buffer!\n");
             return ERROR_NOT_ENOUGH_MEMORY;
         }
     }
@@ -3716,28 +3855,29 @@ DWORD RQueryServiceConfigA(
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
-    hSvc = (PSERVICE_HANDLE)hService;
-    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
     {
-        DPRINT1("Invalid handle tag!\n");
+        DPRINT1("Invalid service handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   SERVICE_QUERY_CONFIG))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
     lpService = hSvc->ServiceEntry;
     if (lpService == NULL)
     {
-        DPRINT1("lpService == NULL!\n");
+        DPRINT("lpService == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
-    /* FIXME: Lock the service database shared */
+    /* Lock the service database shared */
+    ScmLockDatabaseShared();
 
     dwError = ScmOpenServiceKey(lpService->lpServiceName,
                                 KEY_READ,
@@ -3910,6 +4050,9 @@ DWORD RQueryServiceConfigA(
         *pcbBytesNeeded = dwRequiredSize;
 
 Done:;
+    /* Unlock the service database */
+    ScmUnlockDatabase();
+
     if (lpImagePath != NULL)
         HeapFree(GetProcessHeap(), 0, lpImagePath);
 
@@ -3922,8 +4065,6 @@ Done:;
     if (hServiceKey != NULL)
         RegCloseKey(hServiceKey);
 
-    /* FIXME: Unlock the service database */
-
     DPRINT("RQueryServiceConfigA() done\n");
 
     return dwError;
@@ -3952,29 +4093,29 @@ DWORD RStartServiceA(
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService = NULL;
 
-    DPRINT1("RStartServiceA() called\n");
+    DPRINT("RStartServiceA() called\n");
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
-    hSvc = (PSERVICE_HANDLE)hService;
-    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
     {
-        DPRINT1("Invalid handle tag!\n");
+        DPRINT1("Invalid service handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   SERVICE_START))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
     lpService = hSvc->ServiceEntry;
     if (lpService == NULL)
     {
-        DPRINT1("lpService == NULL!\n");
+        DPRINT("lpService == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
@@ -4017,7 +4158,7 @@ DWORD RGetServiceDisplayNameA(
 //    hManager = (PMANAGER_HANDLE)hSCManager;
 //    if (hManager->Handle.Tag != MANAGER_TAG)
 //    {
-//        DPRINT1("Invalid manager handle!\n");
+//        DPRINT("Invalid manager handle!\n");
 //        return ERROR_INVALID_HANDLE;
 //    }
 
@@ -4044,7 +4185,7 @@ DWORD RGetServiceDisplayNameA(
 
     if (lpService == NULL)
     {
-        DPRINT1("Could not find a service!\n");
+        DPRINT("Could not find a service!\n");
 
         /* If the service could not be found and lpcchBuffer is 0, windows
            puts null in lpDisplayName and puts 1 in lpcchBuffer */
@@ -4140,7 +4281,7 @@ DWORD RGetServiceKeyNameA(
 
     if (lpService == NULL)
     {
-        DPRINT1("Could not find the service!\n");
+        DPRINT("Could not find the service!\n");
 
         /* If the service could not be found and lpcchBuffer is 0,
            put null in lpDisplayName and puts 1 in lpcchBuffer, verified WINXP. */
@@ -4338,34 +4479,35 @@ DWORD RChangeServiceConfig2W(
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
-    hSvc = (PSERVICE_HANDLE)hService;
-    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
     {
-        DPRINT1("Invalid handle tag!\n");
+        DPRINT1("Invalid service handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   SERVICE_CHANGE_CONFIG))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
     lpService = hSvc->ServiceEntry;
     if (lpService == NULL)
     {
-        DPRINT1("lpService == NULL!\n");
+        DPRINT("lpService == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
-    /* FIXME: Lock database exclusively */
+    /* Lock the service database exclusively */
+    ScmLockDatabaseExclusive();
 
     if (lpService->bDeleted)
     {
-        /* FIXME: Unlock database */
-        DPRINT1("The service has already been marked for delete!\n");
-        return ERROR_SERVICE_MARKED_FOR_DELETE;
+        DPRINT("The service has already been marked for delete!\n");
+        dwError = ERROR_SERVICE_MARKED_FOR_DELETE;
+        goto done;
     }
 
     /* Open the service key */
@@ -4385,14 +4527,13 @@ DWORD RChangeServiceConfig2W(
         if (lpServiceDescription != NULL &&
             lpServiceDescription->lpDescription != NULL)
         {
-            DPRINT1("Setting value %S\n", lpServiceDescription->lpDescription);
-            RegSetValueExW(hServiceKey,
-                           L"Description",
-                           0,
-                           REG_SZ,
-                           (LPBYTE)lpServiceDescription->lpDescription,
-                           (wcslen(lpServiceDescription->lpDescription) + 1) * sizeof(WCHAR));
-
+            DPRINT("Setting value %S\n", lpServiceDescription->lpDescription);
+            dwError = RegSetValueExW(hServiceKey,
+                                     L"Description",
+                                     0,
+                                     REG_SZ,
+                                     (LPBYTE)lpServiceDescription->lpDescription,
+                                     (wcslen(lpServiceDescription->lpDescription) + 1) * sizeof(WCHAR));
             if (dwError != ERROR_SUCCESS)
                 goto done;
         }
@@ -4405,7 +4546,9 @@ DWORD RChangeServiceConfig2W(
     }
 
 done:
-    /* FIXME: Unlock database */
+    /* Unlock the service database */
+    ScmUnlockDatabase();
+
     if (hServiceKey != NULL)
         RegCloseKey(hServiceKey);
 
@@ -4430,8 +4573,8 @@ DWORD RQueryServiceConfig2A(
     LPWSTR lpDescriptionW = NULL;
     LPSTR lpDescription = NULL;
 
-    DPRINT1("RQueryServiceConfig2A() called hService %p dwInfoLevel %u, lpBuffer %p cbBufSize %u pcbBytesNeeded %p\n",
-            hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
+    DPRINT("RQueryServiceConfig2A() called hService %p dwInfoLevel %u, lpBuffer %p cbBufSize %u pcbBytesNeeded %p\n",
+           hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
 
     if (!lpBuffer)
         return ERROR_INVALID_ADDRESS;
@@ -4439,28 +4582,29 @@ DWORD RQueryServiceConfig2A(
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
-    hSvc = (PSERVICE_HANDLE)hService;
-    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
     {
-        DPRINT1("Invalid handle tag!\n");
+        DPRINT1("Invalid service handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   SERVICE_QUERY_CONFIG))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
     lpService = hSvc->ServiceEntry;
     if (lpService == NULL)
     {
-        DPRINT1("lpService == NULL!\n");
+        DPRINT("lpService == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
-    /* FIXME: Lock the service database shared */
+    /* Lock the service database shared */
+    ScmLockDatabaseShared();
 
     dwError = ScmOpenServiceKey(lpService->lpServiceName,
                                 KEY_READ,
@@ -4473,42 +4617,40 @@ DWORD RQueryServiceConfig2A(
         LPSERVICE_DESCRIPTIONA lpServiceDescription = (LPSERVICE_DESCRIPTIONA)lpBuffer;
         LPSTR lpStr;
 
-        *pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONA);
-
         dwError = ScmReadString(hServiceKey,
                                 L"Description",
                                 &lpDescriptionW);
+        if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_NOT_FOUND)
+            goto done;
+
+        *pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONA);
         if (dwError == ERROR_SUCCESS)
-        {
             *pcbBytesNeeded += ((wcslen(lpDescriptionW) + 1) * sizeof(WCHAR));
-        }
 
-        if (cbBufSize >= *pcbBytesNeeded)
+        if (cbBufSize < *pcbBytesNeeded)
         {
+            dwError = ERROR_INSUFFICIENT_BUFFER;
+            goto done;
+        }
 
-            if (dwError == ERROR_SUCCESS)
-            {
-                lpStr = (LPSTR)(lpServiceDescription + 1);
+        if (dwError == ERROR_SUCCESS)
+        {
+            lpStr = (LPSTR)(lpServiceDescription + 1);
 
-                WideCharToMultiByte(CP_ACP,
-                                    0,
-                                    lpDescriptionW,
-                                    -1,
-                                    lpStr,
-                                    wcslen(lpDescriptionW),
-                                    NULL,
-                                    NULL);
-                lpServiceDescription->lpDescription = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
-            }
-            else
-            {
-                lpServiceDescription->lpDescription = NULL;
-                goto done;
-            }
+            WideCharToMultiByte(CP_ACP,
+                                0,
+                                lpDescriptionW,
+                                -1,
+                                lpStr,
+                                wcslen(lpDescriptionW),
+                                NULL,
+                                NULL);
+            lpServiceDescription->lpDescription = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
         }
         else
         {
-            dwError = ERROR_INSUFFICIENT_BUFFER;
+            lpServiceDescription->lpDescription = NULL;
+            dwError = ERROR_SUCCESS;
             goto done;
         }
     }
@@ -4520,14 +4662,15 @@ DWORD RQueryServiceConfig2A(
     }
 
 done:
+    /* Unlock the service database */
+    ScmUnlockDatabase();
+
     if (lpDescription != NULL)
         HeapFree(GetProcessHeap(), 0, lpDescription);
 
     if (hServiceKey != NULL)
         RegCloseKey(hServiceKey);
 
-    /* FIXME: Unlock database */
-
     DPRINT("RQueryServiceConfig2W() done (Error %lu)\n", dwError);
 
     return dwError;
@@ -4559,28 +4702,29 @@ DWORD RQueryServiceConfig2W(
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
-    hSvc = (PSERVICE_HANDLE)hService;
-    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
     {
-        DPRINT1("Invalid handle tag!\n");
+        DPRINT1("Invalid service handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   SERVICE_QUERY_CONFIG))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
     lpService = hSvc->ServiceEntry;
     if (lpService == NULL)
     {
-        DPRINT1("lpService == NULL!\n");
+        DPRINT("lpService == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
-    /* FIXME: Lock the service database shared */
+    /* Lock the service database shared */
+    ScmLockDatabaseShared();
 
     dwError = ScmOpenServiceKey(lpService->lpServiceName,
                                 KEY_READ,
@@ -4596,21 +4740,30 @@ DWORD RQueryServiceConfig2W(
         dwError = ScmReadString(hServiceKey,
                                 L"Description",
                                 &lpDescription);
-        if (dwError != ERROR_SUCCESS)
+        if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_NOT_FOUND)
             goto done;
 
-        dwRequiredSize = sizeof(SERVICE_DESCRIPTIONW) + ((wcslen(lpDescription) + 1) * sizeof(WCHAR));
+        *pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONW);
+        if (dwError == ERROR_SUCCESS)
+            *pcbBytesNeeded += ((wcslen(lpDescription) + 1) * sizeof(WCHAR));
 
-        if (cbBufSize < dwRequiredSize)
+        if (cbBufSize < *pcbBytesNeeded)
         {
-            *pcbBytesNeeded = dwRequiredSize;
             dwError = ERROR_INSUFFICIENT_BUFFER;
             goto done;
         }
 
-        lpStr = (LPWSTR)(lpServiceDescription + 1);
-        wcscpy(lpStr, lpDescription);
-        lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
+        if (dwError == ERROR_SUCCESS)
+        {
+            lpStr = (LPWSTR)(lpServiceDescription + 1);
+            wcscpy(lpStr, lpDescription);
+            lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
+        }
+        else
+        {
+            lpServiceDescription->lpDescription = NULL;
+            dwError = ERROR_SUCCESS;
+        }
     }
     else if (dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
     {
@@ -4667,6 +4820,9 @@ DWORD RQueryServiceConfig2W(
     }
 
 done:
+    /* Unlock the service database */
+    ScmUnlockDatabase();
+
     if (lpDescription != NULL)
         HeapFree(GetProcessHeap(), 0, lpDescription);
 
@@ -4679,8 +4835,6 @@ done:
     if (hServiceKey != NULL)
         RegCloseKey(hServiceKey);
 
-    /* FIXME: Unlock database */
-
     DPRINT("RQueryServiceConfig2W() done (Error %lu)\n", dwError);
 
     return dwError;
@@ -4712,27 +4866,30 @@ DWORD RQueryServiceStatusEx(
     if (cbBufSize < sizeof(SERVICE_STATUS_PROCESS))
         return ERROR_INSUFFICIENT_BUFFER;
 
-    hSvc = (PSERVICE_HANDLE)hService;
-    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+    hSvc = ScmGetServiceFromHandle(hService);
+    if (hSvc == NULL)
     {
-        DPRINT1("Invalid handle tag!\n");
+        DPRINT1("Invalid service handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
                                   SERVICE_QUERY_STATUS))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
     lpService = hSvc->ServiceEntry;
     if (lpService == NULL)
     {
-        DPRINT1("lpService == NULL!\n");
+        DPRINT("lpService == NULL!\n");
         return ERROR_INVALID_HANDLE;
     }
 
+    /* Lock the service database shared */
+    ScmLockDatabaseShared();
+
     lpStatus = (LPSERVICE_STATUS_PROCESS)lpBuffer;
 
     /* Return service status information */
@@ -4743,6 +4900,9 @@ DWORD RQueryServiceStatusEx(
     lpStatus->dwProcessId = lpService->ProcessId;      /* FIXME */
     lpStatus->dwServiceFlags = 0;                      /* FIXME */
 
+    /* Unlock the service database */
+    ScmUnlockDatabase();
+
     return ERROR_SUCCESS;
 }
 
@@ -4775,7 +4935,7 @@ DWORD REnumServicesStatusExA(
         pszGroupNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (strlen(pszGroupName) + 1) * sizeof(WCHAR));
         if (!pszGroupNameW)
         {
-             DPRINT1("Failed to allocate buffer!\n");
+             DPRINT("Failed to allocate buffer!\n");
              return ERROR_NOT_ENOUGH_MEMORY;
         }
 
@@ -4792,7 +4952,7 @@ DWORD REnumServicesStatusExA(
         lpStatusPtrW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbBufSize);
         if (!lpStatusPtrW)
         {
-            DPRINT1("Failed to allocate buffer!\n");
+            DPRINT("Failed to allocate buffer!\n");
             return ERROR_NOT_ENOUGH_MEMORY;
         }
     }
@@ -4905,10 +5065,10 @@ DWORD REnumServicesStatusExW(
     if (InfoLevel != SC_ENUM_PROCESS_INFO)
         return ERROR_INVALID_LEVEL;
 
-    hManager = (PMANAGER_HANDLE)hSCManager;
-    if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
+    hManager = ScmGetServiceManagerFromHandle(hSCManager);
+    if (hManager == NULL)
     {
-        DPRINT1("Invalid manager handle!\n");
+        DPRINT1("Invalid service manager handle!\n");
         return ERROR_INVALID_HANDLE;
     }
 
@@ -4917,13 +5077,13 @@ DWORD REnumServicesStatusExW(
 
     if ((dwServiceType!=SERVICE_DRIVER) && (dwServiceType!=SERVICE_WIN32))
     {
-        DPRINT1("Not a valid Service Type!\n");
+        DPRINT("Not a valid Service Type!\n");
         return ERROR_INVALID_PARAMETER;
     }
 
     if ((dwServiceState<SERVICE_ACTIVE) || (dwServiceState>SERVICE_STATE_ALL))
     {
-        DPRINT1("Not a valid Service State!\n");
+        DPRINT("Not a valid Service State!\n");
         return ERROR_INVALID_PARAMETER;
     }
 
@@ -4931,14 +5091,16 @@ DWORD REnumServicesStatusExW(
     if (!RtlAreAllAccessesGranted(hManager->Handle.DesiredAccess,
                                   SC_MANAGER_ENUMERATE_SERVICE))
     {
-        DPRINT1("Insufficient access rights! 0x%lx\n",
-                hManager->Handle.DesiredAccess);
+        DPRINT("Insufficient access rights! 0x%lx\n",
+               hManager->Handle.DesiredAccess);
         return ERROR_ACCESS_DENIED;
     }
 
-    if (lpResumeIndex) dwLastResumeCount = *lpResumeIndex;
+    if (lpResumeIndex)
+        dwLastResumeCount = *lpResumeIndex;
 
-    /* Lock the service list shared */
+    /* Lock the service database shared */
+    ScmLockDatabaseShared();
 
     lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
     if (lpService == NULL)
@@ -5140,7 +5302,8 @@ DWORD REnumServicesStatusExW(
     }
 
 Done:;
-    /* Unlock the service list */
+    /* Unlock the service database */
+    ScmUnlockDatabase();
 
     DPRINT("REnumServicesStatusExW() done (Error %lu)\n", dwError);