Clean up the pause and resume code and a few other bits and bobs
authorGed Murphy <gedmurphy@reactos.org>
Tue, 5 Jan 2010 21:43:00 +0000 (21:43 +0000)
committerGed Murphy <gedmurphy@reactos.org>
Tue, 5 Jan 2010 21:43:00 +0000 (21:43 +0000)
svn path=/trunk/; revision=44965

reactos/base/applications/mscutils/servman/control.c
reactos/base/applications/mscutils/servman/precomp.h
reactos/base/applications/mscutils/servman/start.c
reactos/base/applications/mscutils/servman/stop.c

index 41fac16..99582a6 100644 (file)
  * PROJECT:     ReactOS Services
  * LICENSE:     GPL - See COPYING in the top level directory
  * FILE:        base/applications/mscutils/servman/control.c
- * PURPOSE:     Stops, pauses and resumes a service
- * COPYRIGHT:   Copyright 2006-2007 Ged Murphy <gedmurphy@reactos.org>
+ * PURPOSE:     Pauses and resumes a service
+ * COPYRIGHT:   Copyright 2006-2010 Ged Murphy <gedmurphy@reactos.org>
  *
  */
 
 #include "precomp.h"
 
-BOOL
-Control(PMAIN_WND_INFO Info,
-        HWND hProgDlg,
-        DWORD Control)
+static BOOL
+DoControl(PMAIN_WND_INFO Info,
+          HWND hProgress,
+          DWORD Control)
 {
     SC_HANDLE hSCManager;
-    SC_HANDLE hSc;
+    SC_HANDLE hService;
     SERVICE_STATUS_PROCESS ServiceStatus = {0};
     SERVICE_STATUS Status;
     DWORD BytesNeeded = 0;
+    DWORD dwStartTickCount;
+    DWORD dwOldCheckPoint;
+    DWORD dwWaitTime;
+    DWORD dwMaxWait;
     BOOL bRet = FALSE;
-    BOOL bDispErr = TRUE;
 
     hSCManager = OpenSCManager(NULL,
                                NULL,
-                               SC_MANAGER_ALL_ACCESS);
-    if (hSCManager != NULL)
+                               SC_MANAGER_CONNECT);
+    if (hSCManager)
     {
-        hSc = OpenService(hSCManager,
-                          Info->pCurrentService->lpServiceName,
-                          SERVICE_ALL_ACCESS);
-        if (hSc != NULL)
+        hService = OpenService(hSCManager,
+                               Info->pCurrentService->lpServiceName,
+                               SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_QUERY_CONFIG);
+        if (hService)
         {
-            if (ControlService(hSc,
+            if (hProgress)
+            {
+                /* Increment the progress bar */
+                IncrementProgressBar(hProgress, DEFAULT_STEP);
+            }
+
+            /* Send the control message to the service */
+            if (ControlService(hService,
                                Control,
                                &Status))
             {
-                bDispErr = FALSE;
-
-                if (QueryServiceStatusEx(hSc,
+                /* Get the service status */
+                if (QueryServiceStatusEx(hService,
                                          SC_STATUS_PROCESS_INFO,
                                          (LPBYTE)&ServiceStatus,
                                          sizeof(SERVICE_STATUS_PROCESS),
                                          &BytesNeeded))
                 {
-                    DWORD dwStartTickCount = GetTickCount();
-                    DWORD dwOldCheckPoint = ServiceStatus.dwCheckPoint;
-                    DWORD dwMaxWait = 2000 * 60; // wait for 2 mins
-
-                    IncrementProgressBar(hProgDlg, DEFAULT_STEP);
+                    /* We don't want to wait for more than 30 seconds */
+                    dwMaxWait = 30000;
+                    dwStartTickCount = GetTickCount();
 
+                    /* Loop until it's at the correct state */
                     while (ServiceStatus.dwCurrentState != Control)
                     {
-                        DWORD dwWaitTime = ServiceStatus.dwWaitHint / 10;
+                        dwOldCheckPoint = ServiceStatus.dwCheckPoint;
+                        dwWaitTime = ServiceStatus.dwWaitHint / 10;
 
-                        if (!QueryServiceStatusEx(hSc,
+                        /* Get the latest status info */
+                        if (!QueryServiceStatusEx(hService,
                                                   SC_STATUS_PROCESS_INFO,
                                                   (LPBYTE)&ServiceStatus,
                                                   sizeof(SERVICE_STATUS_PROCESS),
                                                   &BytesNeeded))
                         {
+                            /* Something went wrong... */
                             break;
                         }
 
+                        /* Is the service making progress? */
                         if (ServiceStatus.dwCheckPoint > dwOldCheckPoint)
                         {
-                            /* The service is making progress, increment the progress bar */
-                            IncrementProgressBar(hProgDlg, DEFAULT_STEP);
+                            /* It is, get the latest tickcount to reset the max wait time */
                             dwStartTickCount = GetTickCount();
                             dwOldCheckPoint = ServiceStatus.dwCheckPoint;
+                            IncrementProgressBar(hProgress, DEFAULT_STEP);
                         }
                         else
                         {
+                            /* It's not, make sure we haven't exceeded our wait time */
                             if(GetTickCount() >= dwStartTickCount + dwMaxWait)
                             {
-                                /* give up */
+                                /* We have, give up */
                                 break;
                             }
                         }
 
-                        if(dwWaitTime < 200)
+                        /* Adjust the wait hint times */
+                        if (dwWaitTime < 200)
                             dwWaitTime = 200;
                         else if (dwWaitTime > 10000)
                             dwWaitTime = 10000;
 
+                        /* Wait before trying again */
                         Sleep(dwWaitTime);
                     }
                 }
+
+                if (ServiceStatus.dwCurrentState == Control)
+                {
+                    bRet = TRUE;
+                }
             }
 
-            CloseServiceHandle(hSc);
+            CloseServiceHandle(hService);
         }
 
         CloseServiceHandle(hSCManager);
     }
 
-    if (ServiceStatus.dwCurrentState == Control)
-    {
-        CompleteProgressBar(hProgDlg);
-        Sleep(500);
-        bRet = TRUE;
-    }
-    else
-    {
-        if (bDispErr)
-            GetError();
-        else
-            DisplayString(_T("The service failed to start"));
-    }
-
     return bRet;
-
-
 }
 
 
-BOOL DoPause(PMAIN_WND_INFO Info)
+BOOL
+DoPause(PMAIN_WND_INFO Info)
 {
-    BOOL ret = FALSE;
-    HWND hProgDlg;
+    HWND hProgress;
+    BOOL bRet = FALSE;
 
-    hProgDlg = CreateProgressDialog(Info->hMainWnd,
-                                    IDS_PROGRESS_INFO_PAUSE);
-    if (hProgDlg)
+    /* Create a progress window to track the progress of the pausing service */
+    hProgress = CreateProgressDialog(Info->hMainWnd,
+                                     IDS_PROGRESS_INFO_PAUSE);
+    if (hProgress)
     {
-        InitializeProgressDialog(hProgDlg, Info->pCurrentService->lpServiceName);
+        /* Set the service name and reset the progress bag */
+        InitializeProgressDialog(hProgress, Info->pCurrentService->lpServiceName);
 
-        ret = Control(Info,
-                      hProgDlg,
-                      SERVICE_CONTROL_PAUSE);
+        /* Resume the requested service */
+        bRet = DoControl(Info, hProgress, SERVICE_CONTROL_PAUSE);
 
-        DestroyWindow(hProgDlg);
+        /* Complete and destroy the progress bar */
+        DestroyProgressDialog(hProgress, bRet);
     }
 
-    return ret;
+    return bRet;
 }
 
 
-BOOL DoResume(PMAIN_WND_INFO Info)
+BOOL
+DoResume(PMAIN_WND_INFO Info)
 {
-    BOOL ret = FALSE;
-    HWND hProgDlg;
+    HWND hProgress;
+    BOOL bRet = FALSE;
 
-    hProgDlg = CreateProgressDialog(Info->hMainWnd,
-                                    IDS_PROGRESS_INFO_RESUME);
-    if (hProgDlg)
+    /* Create a progress window to track the progress of the resuming service */
+    hProgress = CreateProgressDialog(Info->hMainWnd,
+                                     IDS_PROGRESS_INFO_RESUME);
+    if (hProgress)
     {
-        InitializeProgressDialog(hProgDlg, Info->pCurrentService->lpServiceName);
+        /* Set the service name and reset the progress bag */
+        InitializeProgressDialog(hProgress, Info->pCurrentService->lpServiceName);
 
-        ret = Control(Info,
-                      hProgDlg,
-                      SERVICE_CONTROL_CONTINUE);
+        /* Resume the requested service */
+        bRet = DoControl(Info, hProgress, SERVICE_CONTROL_CONTINUE);
 
-        DestroyWindow(hProgDlg);
+        /* Complete and destroy the progress bar */
+        DestroyProgressDialog(hProgress, bRet);
     }
 
-    return ret;
+    return bRet;
 }
index 3948aa6..9b829ad 100644 (file)
@@ -90,7 +90,7 @@ typedef struct _STOP_INFO
 } STOP_INFO, *PSTOP_INFO;
 
 /* control */
-BOOL Control(PMAIN_WND_INFO Info, HWND hProgDlg, DWORD Control);
+BOOL Control(PMAIN_WND_INFO Info, HWND hProgress, DWORD Control);
 BOOL DoStop(PMAIN_WND_INFO Info);
 BOOL DoPause(PMAIN_WND_INFO Info);
 BOOL DoResume(PMAIN_WND_INFO Info);
@@ -98,10 +98,10 @@ BOOL DoResume(PMAIN_WND_INFO Info);
 /* progress.c */
 #define DEFAULT_STEP 0
 HWND CreateProgressDialog(HWND hParent, UINT LabelId);
-BOOL DestroyProgressDialog(HWND hProgDlg, BOOL bComplete);
-VOID InitializeProgressDialog(HWND hProgDlg, LPWSTR lpServiceName);
-VOID IncrementProgressBar(HWND hProgDlg, UINT NewPos);
-VOID CompleteProgressBar(HWND hProgDlg);
+BOOL DestroyProgressDialog(HWND hProgress, BOOL bComplete);
+VOID InitializeProgressDialog(HWND hProgress, LPWSTR lpServiceName);
+VOID IncrementProgressBar(HWND hProgress, UINT NewPos);
+VOID CompleteProgressBar(HWND hProgress);
 
 /* query.c */
 ENUM_SERVICE_STATUS_PROCESS* GetSelectedService(PMAIN_WND_INFO Info);
index b1522b0..986437e 100644 (file)
@@ -39,6 +39,7 @@ DoStartService(PMAIN_WND_INFO Info,
                 IncrementProgressBar(hProgress, DEFAULT_STEP);
             }
 
+            /* Start the service */
             bRet = StartService(hService,
                                 0,
                                 NULL);
@@ -85,6 +86,7 @@ DoStartService(PMAIN_WND_INFO Info,
                             /* It is, get the latest tickcount to reset the max wait time */
                             dwStartTickCount = GetTickCount();
                             dwOldCheckPoint = ServiceStatus.dwCheckPoint;
+                            IncrementProgressBar(hProgress, DEFAULT_STEP);
                         }
                         else
                         {
index 327abcb..da36ac5 100644 (file)
@@ -197,6 +197,10 @@ DoStop(PMAIN_WND_INFO pInfo)
                 /* Don't stop the main service if the user selected not to */
                 bStopMainService = FALSE;
             }
+
+            HeapFree(GetProcessHeap(),
+                     0,
+                     lpServiceList);
         }
 
         /* If the service has no running dependents, then we stop it here */