- Implement EnumServicesStatusW.
- Add server stubs for ChangeServiceConfigA, GetServiceDisplayNameA, GetServiceKeyNameA and QueryServiceStatusEx.
Modified: trunk/reactos/include/idl/svcctl.idl
Modified: trunk/reactos/lib/advapi32/service/scm.c
Modified: trunk/reactos/subsys/system/services/rpcserver.c
Modified: trunk/reactos/subsys/system/services/services.h

Modified: trunk/reactos/include/idl/svcctl.idl
--- trunk/reactos/include/idl/svcctl.idl	2005-12-25 10:35:23 UTC (rev 20327)
+++ trunk/reactos/include/idl/svcctl.idl	2005-12-25 14:45:30 UTC (rev 20328)
@@ -11,10 +11,12 @@
 #define SC_HANDLE unsigned int
 #define SC_LOCK unsigned int
 #define SERVICE_STATUS_HANDLE unsigned long
+#define SC_STATUS_TYPE unsigned long
 #define LPSTR char*
 #define LPCSTR char*
 #define LPWSTR wchar_t*
 #define LPCWSTR wchar_t*
+#define LPBYTE unsigned char*
 #define LPDWORD unsigned long*
 
 [
@@ -90,12 +92,12 @@
                                    [in] BOOL BootAcceptable);
 
   /* Function 10 */
-  DWORD ScmrI_ScSetServiceBitsW([in] handle_t BindingHandle,
-                                [in] SERVICE_STATUS_HANDLE hServiceStatus,
-                                [in] DWORD dwServiceBits,
-                                [in] BOOL bSetBitsOn,
-                                [in] BOOL bUpdateImmediately,
-                                [in, string, unique] LPWSTR lpString);
+  DWORD ScmrSetServiceBitsW([in] handle_t BindingHandle,
+                            [in] SERVICE_STATUS_HANDLE hServiceStatus,
+                            [in] DWORD dwServiceBits,
+                            [in] BOOL bSetBitsOn,
+                            [in] BOOL bUpdateImmediately,
+                            [in, string, unique] LPWSTR lpString);
 
   /* Function 11 */
   DWORD ScmrChangeServiceConfigW([in] handle_t BindingHandle,
@@ -136,7 +138,7 @@
   DWORD ScmrEnumDependentServicesW([in] handle_t BindingHandle,
                                    [in] SC_HANDLE hService,
                                    [in] DWORD dwServiceState,
-                                   [out, size_is(cbBufSize)] BYTE *lpServices,
+                                   [out, size_is(cbBufSize)] LPBYTE lpServices,
                                    [in] DWORD cbBufSize,
                                    [out] LPDWORD pcbBytesNeeded,
                                    [out] LPDWORD lpServicesReturned);
@@ -146,7 +148,7 @@
                                 [in] SC_HANDLE hSCManager,
                                 [in] DWORD dwServiceType,
                                 [in] DWORD dwServiceState,
-                                [out, size_is(dwBufSize)] BYTE *lpServices,
+                                [out, size_is(dwBufSize)] LPBYTE lpServices,
                                 [in] DWORD dwBufSize,
                                 [out] LPDWORD pcbBytesNeeded,
                                 [out] LPDWORD lpServicesReturned,
@@ -169,11 +171,23 @@
   /* Function 17 */
   DWORD ScmrQueryServiceConfigW([in] handle_t BindingHandle,
                                 [in] SC_HANDLE hService,
-                                [out, unique, size_is(cbBufSize)] BYTE *lpServiceConfig,
+                                [out, unique, size_is(cbBufSize)] LPBYTE lpServiceConfig,
                                 [in] DWORD cbBufSize,
-                                [out] DWORD *pcbBytesNeeded);
+                                [out] LPDWORD pcbBytesNeeded);
 
+  /* Function 18 */
+  DWORD ScmrQueryServiceLockStatusW([in] handle_t BindingHandle,
+                                    [in] SC_HANDLE hSCManager,
+                                    [out, size_is(cbBufSize), unique] LPBYTE lpLockStatus,
+                                    [in] DWORD cbBufSize,
+                                    [out] LPDWORD pcbBytesNeeded);
 
+  /* Function 19 */
+//  DWORD ScmrStartServiceW([in] handle_t BindingHandle,
+//                          [in] SC_HANDLE hService,
+//                          [in] DWORD dwNumServiceArgs,
+//                          [in, string, size_is(dwNumServiceArgs, ), unique] LPWSTR *lpServiceArgVectors);
+
   /* Function 20 */
   DWORD ScmrGetServiceDisplayNameW([in] handle_t BindingHandle,
                                    [in] SC_HANDLE hSCManager,
@@ -188,7 +202,69 @@
                                [out, size_is(*lpcchBuffer), unique] LPWSTR lpServiceName,
                                [in, out, ref] LPDWORD lpcchBuffer);
 
+  /* Function 22 */
+  DWORD ScmrSetServiceBitsA([in] handle_t BindingHandle,
+                            [in] SERVICE_STATUS_HANDLE hServiceStatus,
+                            [in] DWORD dwServiceBits,
+                            [in] BOOL bSetBitsOn,
+                            [in] BOOL bUpdateImmediately,
+                            [in, string, unique] LPSTR lpString);
 
+  /* Function 23 */
+  DWORD ScmrChangeServiceConfigA([in] handle_t BindingHandle,
+                                 [in] SC_HANDLE hSCManager,
+                                 [in] DWORD dwServiceType,
+                                 [in] DWORD dwStartType,
+                                 [in] DWORD dwErrorControl,
+                                 [in, string, unique] LPCSTR lpBinaryPathName,
+                                 [in, string, unique] LPCSTR lpLoadOrderGroup,
+                                 [in, out, unique] LPDWORD lpdwTagId,
+                                 [in, size_is(dwDependenciesLength), unique] LPCSTR lpDependencies,
+                                 [in] DWORD dwDependenciesLength,
+                                 [in, string, unique] LPCSTR lpServiceStartName,
+                                 [in, size_is(dwPasswordLength), unique] LPCSTR lpPassword,
+                                 [in] DWORD dwPasswordLength,
+                                 [in, string, unique] LPCSTR lpDisplayName);
+
+  /* Function 24 */
+  DWORD ScmrCreateServiceA([in] handle_t BindingHandle,
+                           [in] SC_HANDLE hSCManager,
+                           [in, string, ref] LPCSTR lpServiceName,
+                           [in, string, unique] LPCSTR lpDisplayName,
+                           [in] DWORD dwDesiredAccess,
+                           [in] DWORD dwServiceType,
+                           [in] DWORD dwStartType,
+                           [in] DWORD dwErrorControl,
+                           [in, string, ref] LPCSTR lpBinaryPathName,
+                           [in, string, unique] LPCSTR lpLoadOrderGroup,
+                           [in, out, unique] LPDWORD lpdwTagId,
+                           [in, size_is(dwDependenciesLength), unique] LPCSTR lpDependencies,
+                           [in] DWORD dwDependenciesLength,
+                           [in, string, unique] LPCSTR lpServiceStartName,
+                           [in, size_is(dwPasswordLength), unique] LPCSTR lpPassword,
+                           [in] DWORD dwPasswordLength,
+                           [out] SC_HANDLE *hService);
+
+  /* Function 25 */
+  DWORD ScmrEnumDependentServicesA([in] handle_t BindingHandle,
+                                   [in] SC_HANDLE hService,
+                                   [in] DWORD dwServiceState,
+                                   [out, size_is(cbBufSize)] LPBYTE lpServices,
+                                   [in] DWORD cbBufSize,
+                                   [out] LPDWORD pcbBytesNeeded,
+                                   [out] LPDWORD lpServicesReturned);
+
+  /* Function 26 */
+  DWORD ScmrEnumServicesStatusA([in] handle_t BindingHandle,
+                                [in] SC_HANDLE hSCManager,
+                                [in] DWORD dwServiceType,
+                                [in] DWORD dwServiceState,
+                                [out, size_is(dwBufSize)] LPBYTE lpServices,
+                                [in] DWORD dwBufSize,
+                                [out] LPDWORD pcbBytesNeeded,
+                                [out] LPDWORD lpServicesReturned,
+                                [in, out, unique] LPDWORD lpResumeHandle);
+
   /* Function 27 */
   DWORD ScmrOpenSCManagerA([in] handle_t BindingHandle,
                            [in, string, unique] LPCSTR lpMachineName,
@@ -202,4 +278,73 @@
                              [in, string] LPCSTR lpServiceName,
                              [in] DWORD dwDesiredAccess,
                              [out] SC_HANDLE *hScm);
+
+  /* Function 29 */
+  DWORD ScmrQueryServiceConfigA([in] handle_t BindingHandle,
+                                [in] SC_HANDLE hService,
+                                [out, unique, size_is(cbBufSize)] LPBYTE lpServiceConfig,
+                                [in] DWORD cbBufSize,
+                                [out] LPDWORD pcbBytesNeeded);
+
+  /* Function 30 */
+//  DWORD ScmrQueryServiceLockStatusA([in] handle_t BindingHandle,
+//                                    [in] SC_HANDLE hSCManager,
+//                                    [out, size_is(cbBufSize), unique] LPBYTE lpLockStatus,
+//                                    [in] DWORD cbBufSize,
+//                                    [out] LPDWORD pcbBytesNeeded);
+
+  /* Function 31 */
+//  DWORD ScmrStartServiceA([in] handle_t BindingHandle,
+//                          [in] SC_HANDLE hService,
+//                          [in] DWORD dwNumServiceArgs,
+//                          [in, string, size_is(dwNumServiceArgs, ), unique] LPSTR *lpServiceArgVectors);
+
+  /* Function 32 */
+  DWORD ScmrGetServiceDisplayNameA([in] handle_t BindingHandle,
+                                   [in] SC_HANDLE hSCManager,
+                                   [in, string, ref] LPCSTR lpServiceName,
+                                   [out, size_is(*lpcchBuffer), unique] LPSTR lpDisplayName,
+                                   [in, out, ref] LPDWORD lpcchBuffer);
+
+  /* Function 33 */
+  DWORD ScmrGetServiceKeyNameA([in] handle_t BindingHandle,
+                               [in] SC_HANDLE hSCManager,
+                               [in, string, ref] LPCSTR lpDisplayName,
+                               [out, size_is(*lpcchBuffer), unique] LPSTR lpServiceName,
+                               [in, out, ref] LPDWORD lpcchBuffer);
+
+  /* Function 35 */
+  /* ScmrGetCurrentGroupStateW */
+
+  /* Function 35 */
+  /* ScmrEnumServiceGroupW */
+
+  /* Function 36 */
+  /* ScmrChangeServiceConfig2A */
+
+  /* Function 37 */
+  /* ScmrChangeServiceConfig2W */
+
+  /* Function 38 */
+  /* ScmrQueryServiceConfig2A */
+
+  /* Function 39 */
+  /* ScmrQueryServiceConfig2W */
+
+  /* Function 40 */
+  DWORD ScmrQueryServiceStatusEx([in] handle_t BindingHandle,
+                                 [in] SC_HANDLE hService,
+                                 [in] SC_STATUS_TYPE InfoLevel,
+                                 [out, size_is(cbBufSize)] LPBYTE lpBuffer,
+                                 [in] DWORD cbBufSize,
+                                 [out] LPDWORD pcbBytesNeeded);
+
+  /* Function 41 */
+  /* ScmrEnumServicesStatusExA */
+
+  /* Function 42 */
+  /* ScmrEnumServicesStatusExW */
+
+  /* Function 43 */
+  /* ScmrSendTSMessage */
 }

Modified: trunk/reactos/lib/advapi32/service/scm.c
--- trunk/reactos/lib/advapi32/service/scm.c	2005-12-25 10:35:23 UTC (rev 20327)
+++ trunk/reactos/lib/advapi32/service/scm.c	2005-12-25 14:45:30 UTC (rev 20328)
@@ -80,26 +80,68 @@
 /**********************************************************************
  *  ChangeServiceConfigA
  *
- * @unimplemented
+ * @implemented
  */
-BOOL
-STDCALL
-ChangeServiceConfigA(
-    SC_HANDLE   hService,
-    DWORD       dwServiceType,
-    DWORD       dwStartType,
-    DWORD       dwErrorControl,
-    LPCSTR      lpBinaryPathName,
-    LPCSTR      lpLoadOrderGroup,
-    LPDWORD     lpdwTagId,
-    LPCSTR      lpDependencies,
-    LPCSTR      lpServiceStartName,
-    LPCSTR      lpPassword,
-    LPCSTR      lpDisplayName)
+BOOL STDCALL
+ChangeServiceConfigA(SC_HANDLE hService,
+                     DWORD dwServiceType,
+                     DWORD dwStartType,
+                     DWORD dwErrorControl,
+                     LPCSTR lpBinaryPathName,
+                     LPCSTR lpLoadOrderGroup,
+                     LPDWORD lpdwTagId,
+                     LPCSTR lpDependencies,
+                     LPCSTR lpServiceStartName,
+                     LPCSTR lpPassword,
+                     LPCSTR lpDisplayName)
 {
-    DPRINT1("ChangeServiceConfigA is unimplemented\n");
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    DWORD dwError;
+    DWORD dwDependenciesLength = 0;
+    DWORD dwLength;
+    LPSTR lpStr;
+
+    DPRINT("ChangeServiceConfigA() called\n");
+
+    /* Calculate the Dependencies length*/
+    if (lpDependencies != NULL)
+    {
+        lpStr = (LPSTR)lpDependencies;
+        while (*lpStr)
+        {
+            dwLength = strlen(lpStr) + 1;
+            dwDependenciesLength += dwLength;
+            lpStr = lpStr + dwLength;
+        }
+        dwDependenciesLength++;
+    }
+
+    /* FIXME: Encrypt the password */
+
+    HandleBind();
+
+    /* Call to services.exe using RPC */
+    dwError = ScmrChangeServiceConfigA(BindingHandle,
+                                       (unsigned int)hService,
+                                       dwServiceType,
+                                       dwStartType,
+                                       dwErrorControl,
+                                       (LPSTR)lpBinaryPathName,
+                                       (LPSTR)lpLoadOrderGroup,
+                                       lpdwTagId,
+                                       (LPSTR)lpDependencies,
+                                       dwDependenciesLength,
+                                       (LPSTR)lpServiceStartName,
+                                       NULL,              /* FIXME: lpPassword */
+                                       0,                 /* FIXME: dwPasswordLength */
+                                       (LPSTR)lpDisplayName);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("ScmrChangeServiceConfigA() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
 
@@ -540,15 +582,15 @@
 BOOL
 STDCALL
 EnumServiceGroupW(
-    DWORD   Unknown0,
-    DWORD   Unknown1,
-    DWORD   Unknown2,
-    DWORD   Unknown3,
-    DWORD   Unknown4,
-    DWORD   Unknown5,
-    DWORD   Unknown6,
-    DWORD   Unknown7,
-    DWORD   Unknown8)
+    SC_HANDLE               hSCManager,
+    DWORD                   dwServiceType,
+    DWORD                   dwServiceState,
+    LPENUM_SERVICE_STATUSA  lpServices,
+    DWORD                   cbBufSize,
+    LPDWORD                 pcbBytesNeeded,
+    LPDWORD                 lpServicesReturned,
+    LPDWORD                 lpResumeHandle,
+    LPCWSTR                 lpGroup)
 {
     DPRINT1("EnumServiceGroupW is unimplemented\n");
     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
@@ -582,10 +624,9 @@
 /**********************************************************************
  *  EnumServicesStatusW
  *
- * @unimplemented
+ * @implemented
  */
-BOOL
-STDCALL
+BOOL STDCALL
 EnumServicesStatusW(SC_HANDLE hSCManager,
                     DWORD dwServiceType,
                     DWORD dwServiceState,
@@ -595,10 +636,11 @@
                     LPDWORD lpServicesReturned,
                     LPDWORD lpResumeHandle)
 {
-#if 0
+    LPENUM_SERVICE_STATUSW lpStatusPtr;
     DWORD dwError = ERROR_SUCCESS;
+    DWORD dwCount;
 
-    DPRINT1("EnumServicesStatusW() called\n");
+    DPRINT("EnumServicesStatusW() called\n");
 
     HandleBind();
 
@@ -611,23 +653,31 @@
                                       pcbBytesNeeded,
                                       lpServicesReturned,
                                       lpResumeHandle);
+
+    lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices;
+    for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
+    {
+        if (lpStatusPtr->lpServiceName)
+            lpStatusPtr->lpServiceName =
+                (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
+
+        if (lpStatusPtr->lpDisplayName)
+            lpStatusPtr->lpDisplayName =
+                (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
+
+        lpStatusPtr++;
+    }
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrEnumServicesStatusW() failed (Error %lu)\n", dwError);
+        DPRINT("ScmrEnumServicesStatusW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
 
+    DPRINT("ScmrEnumServicesStatusW() done\n");
 
-
-    DPRINT1("ScmrEnumServicesStatusW() done\n");
-
     return TRUE;
-#endif
-
-    DPRINT1("EnumServicesStatusW is unimplemented\n");
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
 }
 
 
@@ -682,19 +732,35 @@
 /**********************************************************************
  *  GetServiceDisplayNameA
  *
- * @unimplemented
+ * @implemented
  */
-BOOL
-STDCALL
-GetServiceDisplayNameA(
-    SC_HANDLE   hSCManager,
-    LPCSTR      lpServiceName,
-    LPSTR       lpDisplayName,
-    LPDWORD     lpcchBuffer)
+BOOL STDCALL
+GetServiceDisplayNameA(SC_HANDLE hSCManager,
+                       LPCSTR lpServiceName,
+                       LPSTR lpDisplayName,
+                       LPDWORD lpcchBuffer)
 {
-    DPRINT1("GetServiceDisplayNameA is unimplemented\n");
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    DWORD dwError;
+
+    DPRINT("GetServiceDisplayNameA() called\n");
+
+    HandleBind();
+
+    dwError = ScmrGetServiceDisplayNameA(BindingHandle,
+                                         (unsigned int)hSCManager,
+                                         (LPSTR)lpServiceName,
+                                         lpDisplayName,
+                                         lpcchBuffer);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("ScmrGetServiceDisplayNameA() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
+
+    (*lpcchBuffer)--;
+
+    return TRUE;
 }
 
 
@@ -736,19 +802,35 @@
 /**********************************************************************
  *  GetServiceKeyNameA
  *
- * @unimplemented
+ * @implemented
  */
-BOOL
-STDCALL
-GetServiceKeyNameA(
-    SC_HANDLE   hSCManager,
-    LPCSTR      lpDisplayName,
-    LPSTR       lpServiceName,
-    LPDWORD     lpcchBuffer)
+BOOL STDCALL
+GetServiceKeyNameA(SC_HANDLE hSCManager,
+                   LPCSTR lpDisplayName,
+                   LPSTR lpServiceName,
+                   LPDWORD lpcchBuffer)
 {
-    DPRINT1("GetServiceKeyNameA is unimplemented\n");
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    DWORD dwError;
+
+    DPRINT("GetServiceKeyNameA() called\n");
+
+    HandleBind();
+
+    dwError = ScmrGetServiceKeyNameA(BindingHandle,
+                                     (unsigned int)hSCManager,
+                                     (LPSTR)lpDisplayName,
+                                     lpServiceName,
+                                     lpcchBuffer);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("ScmrGetServiceKeyNameA() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
+
+    (*lpcchBuffer)--;
+
+    return TRUE;
 }
 
 
@@ -1014,19 +1096,63 @@
 /**********************************************************************
  *  QueryServiceConfigA
  *
- * @unimplemented
+ * @implemented
  */
-BOOL
-STDCALL
-QueryServiceConfigA(
-    SC_HANDLE       hService,
-    LPQUERY_SERVICE_CONFIGA lpServiceConfig,
-    DWORD           cbBufSize,
-    LPDWORD         pcbBytesNeeded)
+BOOL STDCALL
+QueryServiceConfigA(SC_HANDLE hService,
+                    LPQUERY_SERVICE_CONFIGA lpServiceConfig,
+                    DWORD cbBufSize,
+                    LPDWORD pcbBytesNeeded)
 {
-    DPRINT1("QueryServiceConfigA is unimplemented\n");
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    DWORD dwError;
+
+    DPRINT("QueryServiceConfigA(%p, %p, %lu, %p)\n",
+           hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
+
+    HandleBind();
+
+    /* Call to services.exe using RPC */
+    dwError = ScmrQueryServiceConfigA(BindingHandle,
+                                      (unsigned int)hService,
+                                      (unsigned char *)lpServiceConfig,
+                                      cbBufSize,
+                                      pcbBytesNeeded);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT("ScmrQueryServiceConfigA() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
+
+    /* Adjust the pointers */
+    if (lpServiceConfig->lpBinaryPathName)
+        lpServiceConfig->lpBinaryPathName =
+            (LPSTR)((ULONG_PTR)lpServiceConfig +
+                    (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
+
+    if (lpServiceConfig->lpLoadOrderGroup)
+        lpServiceConfig->lpLoadOrderGroup =
+            (LPSTR)((ULONG_PTR)lpServiceConfig +
+                    (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
+
+    if (lpServiceConfig->lpDependencies)
+        lpServiceConfig->lpDependencies =
+            (LPSTR)((ULONG_PTR)lpServiceConfig +
+                    (ULONG_PTR)lpServiceConfig->lpDependencies);
+
+    if (lpServiceConfig->lpServiceStartName)
+        lpServiceConfig->lpServiceStartName =
+            (LPSTR)((ULONG_PTR)lpServiceConfig +
+                    (ULONG_PTR)lpServiceConfig->lpServiceStartName);
+
+    if (lpServiceConfig->lpDisplayName)
+        lpServiceConfig->lpDisplayName =
+           (LPSTR)((ULONG_PTR)lpServiceConfig +
+                   (ULONG_PTR)lpServiceConfig->lpDisplayName);
+
+    DPRINT("QueryServiceConfigA() done\n");
+
+    return TRUE;
 }
 
 
@@ -1240,19 +1366,36 @@
 /**********************************************************************
  *  QueryServiceStatusEx
  *
- * @unimplemented
+ * @implemented
  */
-BOOL
-STDCALL
-QueryServiceStatusEx(SC_HANDLE  hService,
-  SC_STATUS_TYPE  InfoLevel,
-  LPBYTE  lpBuffer,
-  DWORD  cbBufSize,
-  LPDWORD  pcbBytesNeeded)
+BOOL STDCALL
+QueryServiceStatusEx(SC_HANDLE hService,
+                     SC_STATUS_TYPE InfoLevel,
+                     LPBYTE lpBuffer,
+                     DWORD cbBufSize,
+                     LPDWORD pcbBytesNeeded)
 {
-    DPRINT1("QueryServiceStatusEx is unimplemented\n");
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    DWORD dwError;
+
+    DPRINT("QueryServiceStatusEx() called\n");
+
+    HandleBind();
+
+    /* Call to services.exe using RPC */
+    dwError = ScmrQueryServiceStatusEx(BindingHandle,
+                                       (unsigned int)hService,
+                                       InfoLevel,
+                                       lpBuffer,
+                                       cbBufSize,
+                                       pcbBytesNeeded);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("ScmrQueryServiceStatusEx() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
 
@@ -1350,6 +1493,26 @@
     DWORD       dwNumServiceArgs,
     LPCWSTR     *lpServiceArgVectors)
 {
+#if 0
+    DWORD dwError;
+
+    DPRINT("StartServiceW()\n", ScLock);
+
+    HandleBind();
+
+    /* Call to services.exe using RPC */
+    dwError = ScmrStartServiceW(BindingHandle,
+                                dwNumServiceArgs,
+                                lpServiceArgVectors);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("ScmrStartServiceW() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
+
+    return TRUE;
+#endif
     DPRINT1("StartServiceW is unimplemented, but returns success...\n");
     //SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     //return FALSE;

Modified: trunk/reactos/subsys/system/services/rpcserver.c
--- trunk/reactos/subsys/system/services/rpcserver.c	2005-12-25 10:35:23 UTC (rev 20327)
+++ trunk/reactos/subsys/system/services/rpcserver.c	2005-12-25 14:45:30 UTC (rev 20328)
@@ -444,6 +444,8 @@
                                   SC_MANAGER_LOCK))
         return ERROR_ACCESS_DENIED;
 
+//    return ScmLockDatabase(0, hMgr->0xC, hLock);
+
     /* FIXME: Lock the database */
     *hLock = 0x12345678; /* Dummy! */
 
@@ -460,6 +462,7 @@
                                unsigned long dwSecuityDescriptorSize,
                                unsigned long *pcbBytesNeeded)
 {
+#if 0
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService;
     ULONG DesiredAccess = 0;
@@ -467,7 +470,7 @@
     DWORD dwBytesNeeded;
     DWORD dwError;
 
-    DPRINT("ScmrQueryServiceSecurity() called\n");
+    DPRINT("ScmrQueryServiceObjectSecurity() called\n");
 
     hSvc = (PSERVICE_HANDLE)hService;
     if (hSvc->Handle.Tag != SERVICE_TAG)
@@ -528,6 +531,9 @@
     }
 
     return dwError;
+#endif
+    DPRINT1("ScmrQueryServiceObjectSecurity() is unimplemented\n");
+    return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
@@ -539,7 +545,114 @@
                              unsigned char *lpSecurityDescriptor,
                              unsigned long dwSecuityDescriptorSize)
 {
-    DPRINT1("ScmrSetServiceSecurity() is unimplemented\n");
+#if 0
+    PSERVICE_HANDLE hSvc;
+    PSERVICE lpService;
+    ULONG DesiredAccess = 0;
+    HANDLE hToken = NULL;
+    HKEY hServiceKey;
+    NTSTATUS Status;
+    DWORD dwError;
+
+    DPRINT1("ScmrSetServiceObjectSecurity() called\n");
+
+    hSvc = (PSERVICE_HANDLE)hService;
+    if (hSvc->Handle.Tag != SERVICE_TAG)
+    {
+        DPRINT1("Invalid handle tag!\n");
+        return ERROR_INVALID_HANDLE;
+    }
+
+    if (dwSecurityInformation == 0 ||
+        dwSecurityInformation & ~0xF)
+        return 0x57;
+
+    if (!RtlValidSecurityDescriptor((PSECURITY_DESCRIPTOR)lpSecurityDescriptor))
+        return 0x57;
+
+    if (dwSecurityInformation & SACL_SECURITY_INFORMATION)
+        DesiredAccess |= ACCESS_SYSTEM_SECURITY;
+
+    if (dwSecurityInformation & DACL_SECURITY_INFORMATION)
+        DesiredAccess |= 0x40000;
+
+    if (dwSecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
+        DesiredAccess |= 0x80000;
+
+    if ((dwSecurityInformation & OWNER_SECURITY_INFORMATION) &&
+        (((PSECURITY_DESCRIPTOR)lpSecurityDescriptor)->Owner == NULL))
+        return 0x57;
+
+    if ((dwSecurityInformation & GROUP_SECURITY_INFORMATION) &&
+        (((PSECURITY_DESCRIPTOR)lpSecurityDescriptor)->Group == NULL))
+        return 0x57;
+
+    if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+                                  DesiredAccess))
+    {
+        DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+        return ERROR_ACCESS_DENIED;
+    }
+
+    lpService = hSvc->ServiceEntry;
+    if (lpService == NULL)
+    {
+        DPRINT1("lpService == NULL!\n");
+        return ERROR_INVALID_HANDLE;
+    }
+
+    if (lpService->bDeleted)
+        return 0x430;
+
+//    RpcImpersonateClient(NULL);
+
+    Status = NtOpenThreadToken(NtCurrentThread(),
+                               8,
+                               1,
+                               &hToken);
+    if (!NT_SUCCESS(Status))
+        return RtlNtStatusToDosError(Status);
+
+//    RpcRevertToSelf();
+
+    /* FIXME: Lock service database */
+
+    Status = RtlSetSecurityObject(dwSecurityInformation,
+                                  (PSECURITY_DESCRIPTOR)lpSecurityDescriptor,
+                                  &lpService->lpSecurityDescriptor,
+                                  &ScmServiceMapping,
+                                  hToken);
+    if (!NT_SUCCESS(Status))
+    {
+        dwError = RtlNtStatusToDosError(Status);
+        goto Done;
+    }
+
+    dwError = ScmOpenServiceKey(lpService->lpServiceName,
+                                0x20006,
+                                &hServiceKey);
+    if (dwError != ERROR_SUCCESS)
+        goto Done;
+
+//    dwError = ScmWriteSecurityDescriptor(hServiceKey,
+//                                         lpService->lpSecurityDescriptor);
+
+    RegFlushKey(hServiceKey);
+    RegCloseKey(hServiceKey);
+
+Done:;
+
+    if (hToken != NULL)
+        NtClose(hToken);
+
+    /* FIXME: Unlock service database */
+
+    DPRINT1("ScmrSetServiceObjectSecurity() done (Error %lu)\n", dwError);
+
+    return dwError;
+#endif
+
+    DPRINT1("ScmrSetServiceObjectSecurity() is unimplemented\n");
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
@@ -617,22 +730,22 @@
 {
     DPRINT1("ScmrNotifyBootConfigStatus() called\n");
     /* FIXME */
-    return ERROR_SUCCESS;
+    return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 10 */
 unsigned long
-ScmrI_ScSetServiceBitsW(handle_t BindingHandle,
-                        unsigned long hServiceStatus,
-                        unsigned long dwServiceBits,
-                        unsigned long bSetBitsOn,
-                        unsigned long bUpdateImmediately,
-                        wchar_t *lpString)
+ScmrSetServiceBitsW(handle_t BindingHandle,
+                    unsigned long hServiceStatus,
+                    unsigned long dwServiceBits,
+                    unsigned long bSetBitsOn,
+                    unsigned long bUpdateImmediately,
+                    wchar_t *lpString)
 {
-    DPRINT1("ScmrI_ScSetServiceBitsW() called\n");
+    DPRINT1("ScmrSetServiceBitsW() called\n");
     /* FIXME */
-    return ERROR_SUCCESS;
+    return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
@@ -1161,8 +1274,17 @@
     PMANAGER_HANDLE hManager;
     PSERVICE lpService;
     DWORD dwError = ERROR_SUCCESS;
+    PLIST_ENTRY ServiceEntry;
+    PSERVICE CurrentService;
+    DWORD dwState;
+    DWORD dwRequiredSize;
+    DWORD dwServiceCount;
+    DWORD dwSize;
+    DWORD dwLastResumeCount;
+    LPENUM_SERVICE_STATUSW lpStatusPtr;
+    LPWSTR lpStringPtr;
 
-    DPRINT1("ScmrEnumServicesStatusW() called\n");
+    DPRINT("ScmrEnumServicesStatusW() called\n");
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
@@ -1186,28 +1308,152 @@
     *pcbBytesNeeded = 0;
     *lpServicesReturned = 0;
 
+    dwLastResumeCount = *lpResumeHandle;
+
     /* Lock the service list shared */
 
-    lpService = ScmGetServiceEntryByResumeCount(*lpResumeHandle);
+    lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
     if (lpService == NULL)
     {
-        dwError = ERROR_MORE_DATA; /* Hack! */
-        goto done;
+        dwError = ERROR_SUCCESS;
+        goto Done;
     }
 
-    DPRINT1("Service name: %S\n", lpService->lpServiceName);
+    dwRequiredSize = 0;
+    dwServiceCount = 0;
 
-//    DPRINT1("Display name: %S\n", lpService->lpDisplayName);
+    for (ServiceEntry = &lpService->ServiceListEntry;
+         ServiceEntry != &ServiceListHead;
+         ServiceEntry = ServiceEntry->Flink)
+    {
+        CurrentService = CONTAINING_RECORD(ServiceEntry,
+                                           SERVICE,
+                                           ServiceListEntry);
 
+        if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
+            continue;
 
-    *lpResumeHandle = lpService->dwResumeCount;
+        dwState = SERVICE_ACTIVE;
+        if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
+            dwState = SERVICE_INACTIVE;
 
-done:;
+        if ((dwState & dwServiceState) == 0)
+            continue;
+
+        dwSize = sizeof(ENUM_SERVICE_STATUSW) +
+                 ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+                 ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
+
+        if (dwRequiredSize + dwSize <= dwBufSize)
+        {
+            DPRINT("Service name: %S  fit\n", CurrentService->lpServiceName);
+            dwRequiredSize += dwSize;
+            dwServiceCount++;
+            dwLastResumeCount = CurrentService->dwResumeCount;
+        }
+        else
+        {
+            DPRINT("Service name: %S  no fit\n", CurrentService->lpServiceName);
+            break;
+        }
+
+    }
+
+    DPRINT("dwRequiredSize: %lu\n", dwRequiredSize);
+    DPRINT("dwServiceCount: %lu\n", dwServiceCount);
+
+    for (;
+         ServiceEntry != &ServiceListHead;
+         ServiceEntry = ServiceEntry->Flink)
+    {
+        CurrentService = CONTAINING_RECORD(ServiceEntry,
+                                           SERVICE,
+                                           ServiceListEntry);
+
+        if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
+            continue;
+
+        dwState = SERVICE_ACTIVE;
+        if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
+            dwState = SERVICE_INACTIVE;
+
+        if ((dwState & dwServiceState) == 0)
+            continue;
+
+        dwRequiredSize += (sizeof(ENUM_SERVICE_STATUSW) +
+                           ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+                           ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR)));
+
+        dwError = ERROR_MORE_DATA;
+    }
+
+    DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
+
+    *lpResumeHandle = dwLastResumeCount;
+    *lpServicesReturned = dwServiceCount;
+    *pcbBytesNeeded = dwRequiredSize;
+
+    lpStatusPtr = (LPENUM_SERVICE_STATUS)lpServices;
+    lpStringPtr = (LPWSTR)((ULONG_PTR)lpServices +
+                           dwServiceCount * sizeof(ENUM_SERVICE_STATUS));
+
+    dwRequiredSize = 0;
+    for (ServiceEntry = &lpService->ServiceListEntry;
+         ServiceEntry != &ServiceListHead;
+         ServiceEntry = ServiceEntry->Flink)
+    {
+        CurrentService = CONTAINING_RECORD(ServiceEntry,
+                                           SERVICE,
+                                           ServiceListEntry);
+
+        if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
+            continue;
+
+        dwState = SERVICE_ACTIVE;
+        if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
+            dwState = SERVICE_INACTIVE;
+
+        if ((dwState & dwServiceState) == 0)
+            continue;
+
+        dwSize = sizeof(ENUM_SERVICE_STATUSW) +
+                 ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+                 ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
+
+        if (dwRequiredSize + dwSize <= dwBufSize)
+        {
+            /* Copy the service name */
+            wcscpy(lpStringPtr,
+                   CurrentService->lpServiceName);
+            lpStatusPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpServices);
+            lpStringPtr += (wcslen(CurrentService->lpServiceName) + 1);
+
+            /* Copy the display name */
+            wcscpy(lpStringPtr,
+                   CurrentService->lpDisplayName);
+            lpStatusPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpServices);
+            lpStringPtr += (wcslen(CurrentService->lpDisplayName) + 1);
+
+            /* Copy the status information */
+            memcpy(&lpStatusPtr->ServiceStatus,
+                   &CurrentService->Status,
+                   sizeof(SERVICE_STATUS));
[truncated at 1000 lines; 283 more skipped]