Author: gedmurphy Date: Tue Jan 5 22:43:00 2010 New Revision: 44965
URL: http://svn.reactos.org/svn/reactos?rev=44965&view=rev Log: Clean up the pause and resume code and a few other bits and bobs
Modified: trunk/reactos/base/applications/mscutils/servman/control.c trunk/reactos/base/applications/mscutils/servman/precomp.h trunk/reactos/base/applications/mscutils/servman/start.c trunk/reactos/base/applications/mscutils/servman/stop.c
Modified: trunk/reactos/base/applications/mscutils/servman/control.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/mscutils/... ============================================================================== --- trunk/reactos/base/applications/mscutils/servman/control.c [iso-8859-1] (original) +++ trunk/reactos/base/applications/mscutils/servman/control.c [iso-8859-1] Tue Jan 5 22:43:00 2010 @@ -2,158 +2,168 @@ * 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 + /* We don't want to wait for more than 30 seconds */ + dwMaxWait = 30000; + dwStartTickCount = GetTickCount();
- IncrementProgressBar(hProgDlg, DEFAULT_STEP); - + /* 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) + return bRet; +} + + +BOOL +DoPause(PMAIN_WND_INFO Info) +{ + HWND hProgress; + BOOL bRet = FALSE; + + /* Create a progress window to track the progress of the pausing service */ + hProgress = CreateProgressDialog(Info->hMainWnd, + IDS_PROGRESS_INFO_PAUSE); + if (hProgress) { - CompleteProgressBar(hProgDlg); - Sleep(500); - bRet = TRUE; - } - else - { - if (bDispErr) - GetError(); - else - DisplayString(_T("The service failed to start")); + /* Set the service name and reset the progress bag */ + InitializeProgressDialog(hProgress, Info->pCurrentService->lpServiceName); + + /* Resume the requested service */ + bRet = DoControl(Info, hProgress, SERVICE_CONTROL_PAUSE); + + /* Complete and destroy the progress bar */ + DestroyProgressDialog(hProgress, bRet); }
return bRet; - - }
-BOOL DoPause(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_PAUSE); - 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_PAUSE); + /* 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; } - - -BOOL DoResume(PMAIN_WND_INFO Info) -{ - BOOL ret = FALSE; - HWND hProgDlg; - - hProgDlg = CreateProgressDialog(Info->hMainWnd, - IDS_PROGRESS_INFO_RESUME); - if (hProgDlg) - { - InitializeProgressDialog(hProgDlg, Info->pCurrentService->lpServiceName); - - ret = Control(Info, - hProgDlg, - SERVICE_CONTROL_CONTINUE); - - DestroyWindow(hProgDlg); - } - - return ret; -}
Modified: trunk/reactos/base/applications/mscutils/servman/precomp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/mscutils/... ============================================================================== --- trunk/reactos/base/applications/mscutils/servman/precomp.h [iso-8859-1] (original) +++ trunk/reactos/base/applications/mscutils/servman/precomp.h [iso-8859-1] Tue Jan 5 22:43:00 2010 @@ -90,7 +90,7 @@ } 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 @@ /* 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);
Modified: trunk/reactos/base/applications/mscutils/servman/start.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/mscutils/... ============================================================================== --- trunk/reactos/base/applications/mscutils/servman/start.c [iso-8859-1] (original) +++ trunk/reactos/base/applications/mscutils/servman/start.c [iso-8859-1] Tue Jan 5 22:43:00 2010 @@ -39,6 +39,7 @@ IncrementProgressBar(hProgress, DEFAULT_STEP); }
+ /* Start the service */ bRet = StartService(hService, 0, NULL); @@ -85,6 +86,7 @@ /* It is, get the latest tickcount to reset the max wait time */ dwStartTickCount = GetTickCount(); dwOldCheckPoint = ServiceStatus.dwCheckPoint; + IncrementProgressBar(hProgress, DEFAULT_STEP); } else {
Modified: trunk/reactos/base/applications/mscutils/servman/stop.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/mscutils/... ============================================================================== --- trunk/reactos/base/applications/mscutils/servman/stop.c [iso-8859-1] (original) +++ trunk/reactos/base/applications/mscutils/servman/stop.c [iso-8859-1] Tue Jan 5 22:43:00 2010 @@ -197,6 +197,10 @@ /* 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 */