Forward StartServiceA/W to services.exe
authorEric Kohl <eric.kohl@reactos.org>
Sat, 31 Dec 2005 11:33:46 +0000 (11:33 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 31 Dec 2005 11:33:46 +0000 (11:33 +0000)
svn path=/trunk/; revision=20480

reactos/include/idl/svcctl.idl
reactos/lib/advapi32/service/scm.c
reactos/subsys/system/services/rpcserver.c

index d270274..5003d61 100644 (file)
@@ -184,6 +184,13 @@ cpp_quote("#endif")
                                     [out] LPDWORD pcbBytesNeeded);\r
 \r
   /* Function 19 */\r
                                     [out] LPDWORD pcbBytesNeeded);\r
 \r
   /* Function 19 */\r
+  DWORD ScmrStartServiceW([in] handle_t BindingHandle,\r
+                          [in] SC_HANDLE hService,\r
+                          [in] DWORD dwNumServiceArgs,\r
+                          [in, size_is(cbBufSize)] LPBYTE lpServiceArgBuffer,\r
+                          [in] DWORD cbBufSize);\r
+\r
+  /* FIXME: This is the correct interface but WIDL doesn't support it yet! */\r
 //  DWORD ScmrStartServiceW([in] handle_t BindingHandle,\r
 //                          [in] SC_HANDLE hService,\r
 //                          [in] DWORD dwNumServiceArgs,\r
 //  DWORD ScmrStartServiceW([in] handle_t BindingHandle,\r
 //                          [in] SC_HANDLE hService,\r
 //                          [in] DWORD dwNumServiceArgs,\r
@@ -288,13 +295,20 @@ cpp_quote("#endif")
                                 [out] LPDWORD pcbBytesNeeded);\r
 \r
   /* Function 30 */\r
                                 [out] LPDWORD pcbBytesNeeded);\r
 \r
   /* Function 30 */\r
-//  DWORD ScmrQueryServiceLockStatusA([in] handle_t BindingHandle,\r
-//                                    [in] SC_HANDLE hSCManager,\r
-//                                    [out, unique, size_is(cbBufSize)] LPBYTE lpLockStatus,\r
-//                                    [in] DWORD cbBufSize,\r
-//                                    [out] LPDWORD pcbBytesNeeded);\r
+  DWORD ScmrQueryServiceLockStatusA([in] handle_t BindingHandle,\r
+                                    [in] SC_HANDLE hSCManager,\r
+                                    [out, unique, size_is(cbBufSize)] LPBYTE lpLockStatus,\r
+                                    [in] DWORD cbBufSize,\r
+                                    [out] LPDWORD pcbBytesNeeded);\r
 \r
   /* Function 31 */\r
 \r
   /* Function 31 */\r
+  DWORD ScmrStartServiceA([in] handle_t BindingHandle,\r
+                          [in] SC_HANDLE hService,\r
+                          [in] DWORD dwNumServiceArgs,\r
+                          [in, size_is(cbBufSize)] LPBYTE lpServiceArgBuffer,\r
+                          [in] DWORD cbBufSize);\r
+\r
+  /* FIXME: This is the correct interface but WIDL doesn't support it yet! */\r
 //  DWORD ScmrStartServiceA([in] handle_t BindingHandle,\r
 //                          [in] SC_HANDLE hService,\r
 //                          [in] DWORD dwNumServiceArgs,\r
 //  DWORD ScmrStartServiceA([in] handle_t BindingHandle,\r
 //                          [in] SC_HANDLE hService,\r
 //                          [in] DWORD dwNumServiceArgs,\r
@@ -314,20 +328,24 @@ cpp_quote("#endif")
                                [out, unique, size_is(*lpcchBuffer)] LPSTR lpServiceName,\r
                                [in, out, ref] LPDWORD lpcchBuffer);\r
 \r
                                [out, unique, size_is(*lpcchBuffer)] LPSTR lpServiceName,\r
                                [in, out, ref] LPDWORD lpcchBuffer);\r
 \r
-  /* Function 35 */\r
+  /* Function 34 */\r
   /* ScmrGetCurrentGroupStateW */\r
 \r
   /* Function 35 */\r
   /* ScmrEnumServiceGroupW */\r
 \r
   /* Function 36 */\r
   /* ScmrGetCurrentGroupStateW */\r
 \r
   /* Function 35 */\r
   /* ScmrEnumServiceGroupW */\r
 \r
   /* Function 36 */\r
-  /* ScmrChangeServiceConfig2A */\r
+//  DWORD ScmrChangeServiceConfig2A([in] handle_t BindingHandle,\r
+//                                  [in] SC_HANDLE hService,\r
+//                                  [in] DWORD dwInfoLevel,\r
+//                                  [in, size_is(dwInfoSize)] LPBYTE lpInfo,\r
+//                                  [in] DWORD dwInfoSize);\r
 \r
   /* Function 37 */\r
   DWORD ScmrChangeServiceConfig2W([in] handle_t BindingHandle,\r
                                   [in] SC_HANDLE hService,\r
                                   [in] DWORD dwInfoLevel,\r
 \r
   /* Function 37 */\r
   DWORD ScmrChangeServiceConfig2W([in] handle_t BindingHandle,\r
                                   [in] SC_HANDLE hService,\r
                                   [in] DWORD dwInfoLevel,\r
-                                  [in, size_is(dwInfoSize)] unsigned char *lpInfo,\r
+                                  [in, size_is(dwInfoSize)] LPBYTE lpInfo,\r
                                   [in] DWORD dwInfoSize);\r
 \r
   /* Function 38 */\r
                                   [in] DWORD dwInfoSize);\r
 \r
   /* Function 38 */\r
index c917180..eb50852 100644 (file)
@@ -1557,32 +1557,89 @@ SetServiceObjectSecurity(SC_HANDLE hService,
 /**********************************************************************
  *  StartServiceA
  *
 /**********************************************************************
  *  StartServiceA
  *
- * @unimplemented
+ * @implemented
  */
  */
-BOOL
-STDCALL
-StartServiceA(
-    SC_HANDLE   hService,
-    DWORD       dwNumServiceArgs,
-    LPCSTR      *lpServiceArgVectors)
+BOOL STDCALL
+StartServiceA(SC_HANDLE hService,
+              DWORD dwNumServiceArgs,
+              LPCSTR *lpServiceArgVectors)
 {
 {
-    DPRINT1("StartServiceA is unimplemented\n");
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+#if 0
+    DWORD dwError;
+
+    DPRINT("StartServiceA()\n");
+
+    HandleBind();
+
+    /* Call to services.exe using RPC */
+    dwError = ScmrStartServiceA(BindingHandle,
+                                hService,
+                                dwNumServiceArgs,
+                                lpServiceArgVectors);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("ScmrStartServiceA() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
+
+    return TRUE;
+#endif
+    LPSTR lpBuffer;
+    LPSTR lpStr;
+    DWORD dwError;
+    DWORD dwBufSize;
+    DWORD i;
+
+    dwBufSize = 0;
+    for (i = 0; i < dwNumServiceArgs; i++)
+    {
+        dwBufSize += (strlen(lpServiceArgVectors[i]) + 1);
+    }
+    DPRINT1("dwBufSize: %lu\n", dwBufSize);
+
+    lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwBufSize);
+    if (lpBuffer == NULL)
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return FALSE;
+    }
+
+    lpStr = lpBuffer;
+    for (i = 0; i < dwNumServiceArgs; i++)
+    {
+        strcpy(lpStr, lpServiceArgVectors[i]);
+        lpStr += (strlen(lpServiceArgVectors[i]) + 1);
+    }
+
+    dwError = ScmrStartServiceA(BindingHandle,
+                                (unsigned int)hService,
+                                dwNumServiceArgs,
+                                (unsigned char *)lpBuffer,
+                                dwBufSize);
+
+    HeapFree(GetProcessHeap(), 0, lpBuffer);
+
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("ScmrStartServiceA() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
 
 /**********************************************************************
  *  StartServiceW
  *
 }
 
 
 /**********************************************************************
  *  StartServiceW
  *
- * @unimplemented
+ * @implemented
  */
  */
-BOOL
-STDCALL
-StartServiceW(
-    SC_HANDLE   hService,
-    DWORD       dwNumServiceArgs,
-    LPCWSTR     *lpServiceArgVectors)
+BOOL STDCALL
+StartServiceW(SC_HANDLE hService,
+              DWORD dwNumServiceArgs,
+              LPCWSTR *lpServiceArgVectors)
 {
 #if 0
     DWORD dwError;
 {
 #if 0
     DWORD dwError;
@@ -1593,6 +1650,7 @@ StartServiceW(
 
     /* Call to services.exe using RPC */
     dwError = ScmrStartServiceW(BindingHandle,
 
     /* Call to services.exe using RPC */
     dwError = ScmrStartServiceW(BindingHandle,
+                                hService,
                                 dwNumServiceArgs,
                                 lpServiceArgVectors);
     if (dwError != ERROR_SUCCESS)
                                 dwNumServiceArgs,
                                 lpServiceArgVectors);
     if (dwError != ERROR_SUCCESS)
@@ -1604,9 +1662,48 @@ StartServiceW(
 
     return TRUE;
 #endif
 
     return TRUE;
 #endif
-    DPRINT1("StartServiceW is unimplemented, but returns success...\n");
-    //SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    //return FALSE;
+    LPWSTR lpBuffer;
+    LPWSTR lpStr;
+    DWORD dwError;
+    DWORD dwBufSize;
+    DWORD i;
+
+    dwBufSize = 0;
+    for (i = 0; i < dwNumServiceArgs; i++)
+    {
+        dwBufSize += ((wcslen(lpServiceArgVectors[i]) + 1) * sizeof(WCHAR));
+    }
+    DPRINT1("dwBufSize: %lu\n", dwBufSize);
+
+    lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwBufSize);
+    if (lpBuffer == NULL)
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return FALSE;
+    }
+
+    lpStr = lpBuffer;
+    for (i = 0; i < dwNumServiceArgs; i++)
+    {
+        wcscpy(lpStr, lpServiceArgVectors[i]);
+        lpStr += (wcslen(lpServiceArgVectors[i]) + 1);
+    }
+
+    dwError = ScmrStartServiceW(BindingHandle,
+                                (unsigned int)hService,
+                                dwNumServiceArgs,
+                                (unsigned char *)lpBuffer,
+                                dwBufSize);
+
+    HeapFree(GetProcessHeap(), 0, lpBuffer);
+
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("ScmrStartServiceW() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
+
     return TRUE;
 }
 
     return TRUE;
 }
 
index f982ab3..d88703f 100644 (file)
@@ -1730,7 +1730,53 @@ ScmrQueryServiceLockStatusW(handle_t BindingHandle,
 
 
 /* Function 19 */
 
 
 /* Function 19 */
-/* ScmrStartServiceW */
+unsigned long
+ScmrStartServiceW(handle_t BindingHandle,
+                  unsigned int hService,
+                  unsigned long dwNumServiceArgs,
+                  unsigned char *lpServiceArgBuffer,
+                  unsigned long cbBufSize)
+{
+    DWORD dwError = ERROR_SUCCESS;
+    PSERVICE_HANDLE hSvc;
+    PSERVICE lpService = NULL;
+
+    DPRINT1("ScmrStartServiceW() called\n");
+
+    if (ScmShutdown)
+        return ERROR_SHUTDOWN_IN_PROGRESS;
+
+    hSvc = (PSERVICE_HANDLE)hService;
+    if (hSvc->Handle.Tag != SERVICE_TAG)
+    {
+        DPRINT1("Invalid handle tag!\n");
+        return ERROR_INVALID_HANDLE;
+    }
+
+    if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+                                  SERVICE_START))
+    {
+        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->dwStartType == SERVICE_DISABLED)
+        return ERROR_SERVICE_DISABLED;
+
+    if (lpService->bDeleted)
+        return ERROR_SERVICE_MARKED_FOR_DELETE;
+
+    /* FIXME: Start the service */
+
+    return dwError;
+}
 
 
 /* Function 20 */
 
 
 /* Function 20 */
@@ -2019,7 +2065,17 @@ ScmrQueryServiceLockStatusA(handle_t BindingHandle,
 
 
 /* Function 31 */
 
 
 /* Function 31 */
-/* ScmrStartServiceA */
+unsigned long
+ScmrStartServiceA(handle_t BindingHandle,
+                  unsigned int hService,
+                  unsigned long dwNumServiceArgs,
+                  unsigned char *lpServiceArgBuffer,
+                  unsigned long cbBufSize)
+{
+    DPRINT1("ScmrStartServiceA() called\n");
+    return ERROR_SUCCESS;
+//    return ERROR_CALL_NOT_IMPLEMENTED;
+}
 
 
 /* Function 32 */
 
 
 /* Function 32 */