sync to trunk revision 36500
[reactos.git] / reactos / dll / win32 / advapi32 / service / sctrl.c
index 07fc86a..d6b3380 100644 (file)
@@ -286,7 +286,7 @@ ScStartService(PSCM_CONTROL_PACKET ControlPacket)
 
     lpService->Arguments = HeapAlloc(GetProcessHeap(),
                                      HEAP_ZERO_MEMORY,
-                                     ControlPacket->dwSize * sizeof(WCHAR));
+                                     (ControlPacket->dwSize + 1) * sizeof(WCHAR));
     if (lpService->Arguments == NULL)
         return ERROR_OUTOFMEMORY;
 
@@ -528,10 +528,88 @@ RegisterServiceCtrlHandlerExW(LPCWSTR lpServiceName,
 }
 
 
+/**********************************************************************
+ *     I_ScSetServiceBitsA
+ *
+ * Undocumented
+ *
+ * @implemented
+ */
+BOOL STDCALL
+I_ScSetServiceBitsA(SC_RPC_HANDLE hServiceStatus,
+                    DWORD dwServiceBits,
+                    BOOL bSetBitsOn,
+                    BOOL bUpdateImmediately,
+                    LPSTR lpString)
+{
+    BOOL bResult;
+
+    HandleBind();
+
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        bResult = RI_ScSetServiceBitsA(BindingHandle,
+                                       (SC_RPC_HANDLE)hServiceStatus,
+                                       dwServiceBits,
+                                       bSetBitsOn,
+                                       bUpdateImmediately,
+                                       lpString);
+    }
+    _SEH_HANDLE
+    {
+        SetLastError(ScmRpcStatusToWinError(RpcExceptionCode()));
+        bResult = FALSE;
+    }
+    _SEH_END;
+
+    return bResult;
+}
+
+
+/**********************************************************************
+ *     I_ScSetServiceBitsW
+ *
+ * Undocumented
+ *
+ * @implemented
+ */
+BOOL STDCALL
+I_ScSetServiceBitsW(SC_RPC_HANDLE hServiceStatus,
+                    DWORD dwServiceBits,
+                    BOOL bSetBitsOn,
+                    BOOL bUpdateImmediately,
+                    LPWSTR lpString)
+{
+    BOOL bResult;
+
+    HandleBind();
+
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        bResult = RI_ScSetServiceBitsW(BindingHandle,
+                                       (SC_RPC_HANDLE)hServiceStatus,
+                                       dwServiceBits,
+                                       bSetBitsOn,
+                                       bUpdateImmediately,
+                                       lpString);
+    }
+    _SEH_HANDLE
+    {
+        SetLastError(ScmRpcStatusToWinError(RpcExceptionCode()));
+        bResult = FALSE;
+    }
+    _SEH_END;
+
+    return bResult;
+}
+
+
 /**********************************************************************
  *     SetServiceBits
  *
- * @unimplemented
+ * @implemented
  */
 BOOL STDCALL
 SetServiceBits(SERVICE_STATUS_HANDLE hServiceStatus,
@@ -539,8 +617,11 @@ SetServiceBits(SERVICE_STATUS_HANDLE hServiceStatus,
                BOOL bSetBitsOn,
                BOOL bUpdateImmediately)
 {
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    return I_ScSetServiceBitsW(hServiceStatus,
+                               dwServiceBits,
+                               bSetBitsOn,
+                               bUpdateImmediately,
+                               NULL);
 }
 
 
@@ -621,6 +702,10 @@ StartServiceCtrlDispatcherA(LPSERVICE_TABLE_ENTRYA lpServiceStartTable)
     if (dwError != ERROR_SUCCESS)
     {
         /* Free the service table */
+        for (i = 0; i < dwActiveServiceCount; i++)
+        {
+            RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
+        }
         RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
         lpActiveServices = NULL;
         dwActiveServiceCount = 0;
@@ -633,6 +718,10 @@ StartServiceCtrlDispatcherA(LPSERVICE_TABLE_ENTRYA lpServiceStartTable)
     if (lpMessageBuffer == NULL)
     {
         /* Free the service table */
+        for (i = 0; i < dwActiveServiceCount; i++)
+        {
+            RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
+        }
         RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
         lpActiveServices = NULL;
         dwActiveServiceCount = 0;
@@ -647,6 +736,10 @@ StartServiceCtrlDispatcherA(LPSERVICE_TABLE_ENTRYA lpServiceStartTable)
     RtlFreeHeap(RtlGetProcessHeap(), 0, lpMessageBuffer);
 
     /* Free the service table */
+    for (i = 0; i < dwActiveServiceCount; i++)
+    {
+        RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
+    }
     RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
     lpActiveServices = NULL;
     dwActiveServiceCount = 0;
@@ -699,6 +792,10 @@ StartServiceCtrlDispatcherW(LPSERVICE_TABLE_ENTRYW lpServiceStartTable)
     if (dwError != ERROR_SUCCESS)
     {
         /* Free the service table */
+        for (i = 0; i < dwActiveServiceCount; i++)
+        {
+            RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
+        }
         RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
         lpActiveServices = NULL;
         dwActiveServiceCount = 0;
@@ -711,6 +808,10 @@ StartServiceCtrlDispatcherW(LPSERVICE_TABLE_ENTRYW lpServiceStartTable)
     if (lpMessageBuffer == NULL)
     {
         /* Free the service table */
+        for (i = 0; i < dwActiveServiceCount; i++)
+        {
+            RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
+        }
         RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
         lpActiveServices = NULL;
         dwActiveServiceCount = 0;
@@ -725,6 +826,10 @@ StartServiceCtrlDispatcherW(LPSERVICE_TABLE_ENTRYW lpServiceStartTable)
     RtlFreeHeap(RtlGetProcessHeap(), 0, lpMessageBuffer);
 
     /* Free the service table */
+    for (i = 0; i < dwActiveServiceCount; i++)
+    {
+        RtlFreeUnicodeString(&lpActiveServices[i].ServiceName);
+    }
     RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
     lpActiveServices = NULL;
     dwActiveServiceCount = 0;