[ADVAPI32]
[reactos.git] / reactos / dll / win32 / advapi32 / service / sctrl.c
index abfe426..4a9767f 100644 (file)
@@ -177,7 +177,7 @@ ScServiceMainStub(LPVOID Context)
         (lpService->ThreadParams.W.lpServiceMain)(lpService->ThreadParams.W.dwArgCount,
                                                   lpService->ThreadParams.W.lpArgVector);
 
-        if (lpService->ThreadParams.A.lpArgVector != NULL)
+        if (lpService->ThreadParams.W.lpArgVector != NULL)
         {
             HeapFree(GetProcessHeap(),
                      0,
@@ -240,7 +240,7 @@ ScConnectControlPipe(HANDLE *hPipe)
 
     swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", dwServiceCurrent);
 
-    if (!WaitNamedPipeW(NtControlPipeName, 15000))
+    if (!WaitNamedPipeW(NtControlPipeName, 30000))
     {
         ERR("WaitNamedPipe(%S) failed (Error %lu)\n", NtControlPipeName, GetLastError());
         return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
@@ -248,7 +248,7 @@ ScConnectControlPipe(HANDLE *hPipe)
 
     *hPipe = CreateFileW(NtControlPipeName,
                          GENERIC_READ | GENERIC_WRITE,
-                         0,
+                         FILE_SHARE_READ | FILE_SHARE_WRITE,
                          NULL,
                          OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL,
@@ -288,34 +288,53 @@ ScBuildUnicodeArgsVector(PSCM_CONTROL_PACKET ControlPacket,
 {
     LPWSTR *lpVector;
     LPWSTR *lpArg;
+    LPWSTR pszServiceName;
+    DWORD cbServiceName;
+    DWORD cbTotal;
     DWORD i;
 
+    if (ControlPacket == NULL || lpArgCount == NULL || lpArgVector == NULL)
+        return ERROR_INVALID_PARAMETER;
+
     *lpArgCount = 0;
     *lpArgVector = NULL;
 
+    pszServiceName = (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
+    cbServiceName = lstrlenW(pszServiceName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
+
+    cbTotal = cbServiceName + sizeof(LPWSTR);
     if (ControlPacket->dwArgumentsCount > 0)
-    {
-        lpVector = HeapAlloc(GetProcessHeap(),
-                             HEAP_ZERO_MEMORY,
-                             ControlPacket->dwSize - ControlPacket->dwArgumentsOffset);
-        if (lpVector == NULL)
-            return ERROR_OUTOFMEMORY;
+        cbTotal += ControlPacket->dwSize - ControlPacket->dwArgumentsOffset;
 
-        memcpy(lpVector,
+    lpVector = HeapAlloc(GetProcessHeap(),
+                         HEAP_ZERO_MEMORY,
+                         cbTotal);
+    if (lpVector == NULL)
+        return ERROR_OUTOFMEMORY;
+
+    lpArg = lpVector;
+    *lpArg = (LPWSTR)(lpArg + 1);
+    lpArg++;
+
+    memcpy(lpArg, pszServiceName, cbServiceName);
+    lpArg = (LPWSTR*)((ULONG_PTR)lpArg + cbServiceName);
+
+    if (ControlPacket->dwArgumentsCount > 0)
+    {
+        memcpy(lpArg,
                ((PBYTE)ControlPacket + ControlPacket->dwArgumentsOffset),
                ControlPacket->dwSize - ControlPacket->dwArgumentsOffset);
 
-        lpArg = lpVector;
         for (i = 0; i < ControlPacket->dwArgumentsCount; i++)
         {
             *lpArg = (LPWSTR)((ULONG_PTR)lpArg + (ULONG_PTR)*lpArg);
             lpArg++;
         }
-
-        *lpArgCount = ControlPacket->dwArgumentsCount;
-        *lpArgVector = lpVector;
     }
 
+    *lpArgCount = ControlPacket->dwArgumentsCount + 1;
+    *lpArgVector = lpVector;
+
     return ERROR_SUCCESS;
 }
 
@@ -328,19 +347,36 @@ ScBuildAnsiArgsVector(PSCM_CONTROL_PACKET ControlPacket,
     LPSTR *lpVector;
     LPSTR *lpPtr;
     LPWSTR lpUnicodeString;
+    LPWSTR pszServiceName;
     LPSTR lpAnsiString;
+    DWORD cbServiceName;
     DWORD dwVectorSize;
     DWORD dwUnicodeSize;
-    DWORD dwAnsiSize;
+    DWORD dwAnsiSize = 0;
+    DWORD dwAnsiNameSize = 0;
     DWORD i;
 
+    if (ControlPacket == NULL || lpArgCount == NULL || lpArgVector == NULL)
+        return ERROR_INVALID_PARAMETER;
+
     *lpArgCount = 0;
     *lpArgVector = NULL;
 
+    pszServiceName = (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
+    cbServiceName = lstrlenW(pszServiceName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
+
+    dwAnsiNameSize = WideCharToMultiByte(CP_ACP,
+                                         0,
+                                         pszServiceName,
+                                         cbServiceName,
+                                         NULL,
+                                         0,
+                                         NULL,
+                                         NULL);
+
+    dwVectorSize = ControlPacket->dwArgumentsCount * sizeof(LPWSTR);
     if (ControlPacket->dwArgumentsCount > 0)
     {
-        dwVectorSize = ControlPacket->dwArgumentsCount * sizeof(LPWSTR);
-
         lpUnicodeString = (LPWSTR)((PBYTE)ControlPacket +
                                    ControlPacket->dwArgumentsOffset +
                                    dwVectorSize);
@@ -356,15 +392,31 @@ ScBuildAnsiArgsVector(PSCM_CONTROL_PACKET ControlPacket,
                                          0,
                                          NULL,
                                          NULL);
+    }
+
+    dwVectorSize += sizeof(LPWSTR);
+
+    lpVector = HeapAlloc(GetProcessHeap(),
+                         HEAP_ZERO_MEMORY,
+                         dwVectorSize + dwAnsiNameSize + dwAnsiSize);
+    if (lpVector == NULL)
+        return ERROR_OUTOFMEMORY;
 
-        lpVector = HeapAlloc(GetProcessHeap(),
-                             HEAP_ZERO_MEMORY,
-                             dwVectorSize + dwAnsiSize);
-        if (lpVector == NULL)
-            return ERROR_OUTOFMEMORY;
+    lpPtr = (LPSTR*)lpVector;
+    lpAnsiString = (LPSTR)((ULONG_PTR)lpVector + dwVectorSize);
 
-        lpPtr = (LPSTR*)lpVector;
-        lpAnsiString = (LPSTR)((ULONG_PTR)lpVector + dwVectorSize);
+    WideCharToMultiByte(CP_ACP,
+                        0,
+                        pszServiceName,
+                        cbServiceName,
+                        lpAnsiString,
+                        dwAnsiNameSize,
+                        NULL,
+                        NULL);
+
+    if (ControlPacket->dwArgumentsCount > 0)
+    {
+        lpAnsiString = (LPSTR)((ULONG_PTR)lpAnsiString + dwAnsiNameSize);
 
         WideCharToMultiByte(CP_ACP,
                             0,
@@ -374,19 +426,20 @@ ScBuildAnsiArgsVector(PSCM_CONTROL_PACKET ControlPacket,
                             dwAnsiSize,
                             NULL,
                             NULL);
+    }
 
-        for (i = 0; i < ControlPacket->dwArgumentsCount; i++)
-        {
-            *lpPtr = lpAnsiString;
-
-            lpPtr++;
-            lpAnsiString += (strlen(lpAnsiString) + 1);
-        }
+    lpAnsiString = (LPSTR)((ULONG_PTR)lpVector + dwVectorSize);
+    for (i = 0; i < ControlPacket->dwArgumentsCount + 1; i++)
+    {
+        *lpPtr = lpAnsiString;
 
-        *lpArgCount = ControlPacket->dwArgumentsCount;
-        *lpArgVector = lpVector;
+        lpPtr++;
+        lpAnsiString += (strlen(lpAnsiString) + 1);
     }
 
+    *lpArgCount = ControlPacket->dwArgumentsCount + 1;
+    *lpArgVector = lpVector;
+
     return ERROR_SUCCESS;
 }
 
@@ -399,6 +452,9 @@ ScStartService(PACTIVE_SERVICE lpService,
     DWORD ThreadId;
     DWORD dwError;
 
+    if (lpService == NULL || ControlPacket == NULL)
+        return ERROR_INVALID_PARAMETER;
+
     TRACE("ScStartService() called\n");
     TRACE("Size: %lu\n", ControlPacket->dwSize);
     TRACE("Service: %S\n", (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset));
@@ -470,6 +526,9 @@ static DWORD
 ScControlService(PACTIVE_SERVICE lpService,
                  PSCM_CONTROL_PACKET ControlPacket)
 {
+    if (lpService == NULL || ControlPacket == NULL)
+        return ERROR_INVALID_PARAMETER;
+
     TRACE("ScControlService() called\n");
     TRACE("Size: %lu\n", ControlPacket->dwSize);
     TRACE("Service: %S\n", (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset));
@@ -505,6 +564,9 @@ ScServiceDispatcher(HANDLE hPipe,
 
     TRACE("ScDispatcherLoop() called\n");
 
+    if (ControlPacket == NULL || dwBufferSize < sizeof(SCM_CONTROL_PACKET))
+        return FALSE;
+
     while (TRUE)
     {
         /* Read command from the control pipe */
@@ -533,14 +595,14 @@ ScServiceDispatcher(HANDLE hPipe,
             {
                 case SERVICE_CONTROL_START_SHARE:
                 case SERVICE_CONTROL_START_OWN:
-                    TRACE("Start command - recieved SERVICE_CONTROL_START\n");
+                    TRACE("Start command - received SERVICE_CONTROL_START\n");
                     dwError = ScStartService(lpService, ControlPacket);
                     if (dwError == ERROR_SUCCESS)
                         dwRunningServices++;
                     break;
 
                 case SERVICE_CONTROL_STOP:
-                    TRACE("Stop command - recieved SERVICE_CONTROL_STOP\n");
+                    TRACE("Stop command - received SERVICE_CONTROL_STOP\n");
                     dwError = ScControlService(lpService, ControlPacket);
                     if (dwError == ERROR_SUCCESS)
                         dwRunningServices--;