Clean up the pause and resume code and a few other bits and bobs

svn path=/trunk/; revision=44965
This commit is contained in:
Ged Murphy 2010-01-05 21:43:00 +00:00
parent 5dfb2cc0c3
commit d4aca75523
4 changed files with 98 additions and 82 deletions

View file

@ -2,158 +2,168 @@
* PROJECT: ReactOS Services * PROJECT: ReactOS Services
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/mscutils/servman/control.c * FILE: base/applications/mscutils/servman/control.c
* PURPOSE: Stops, pauses and resumes a service * PURPOSE: Pauses and resumes a service
* COPYRIGHT: Copyright 2006-2007 Ged Murphy <gedmurphy@reactos.org> * COPYRIGHT: Copyright 2006-2010 Ged Murphy <gedmurphy@reactos.org>
* *
*/ */
#include "precomp.h" #include "precomp.h"
BOOL static BOOL
Control(PMAIN_WND_INFO Info, DoControl(PMAIN_WND_INFO Info,
HWND hProgDlg, HWND hProgress,
DWORD Control) DWORD Control)
{ {
SC_HANDLE hSCManager; SC_HANDLE hSCManager;
SC_HANDLE hSc; SC_HANDLE hService;
SERVICE_STATUS_PROCESS ServiceStatus = {0}; SERVICE_STATUS_PROCESS ServiceStatus = {0};
SERVICE_STATUS Status; SERVICE_STATUS Status;
DWORD BytesNeeded = 0; DWORD BytesNeeded = 0;
DWORD dwStartTickCount;
DWORD dwOldCheckPoint;
DWORD dwWaitTime;
DWORD dwMaxWait;
BOOL bRet = FALSE; BOOL bRet = FALSE;
BOOL bDispErr = TRUE;
hSCManager = OpenSCManager(NULL, hSCManager = OpenSCManager(NULL,
NULL, NULL,
SC_MANAGER_ALL_ACCESS); SC_MANAGER_CONNECT);
if (hSCManager != NULL) if (hSCManager)
{ {
hSc = OpenService(hSCManager, hService = OpenService(hSCManager,
Info->pCurrentService->lpServiceName, Info->pCurrentService->lpServiceName,
SERVICE_ALL_ACCESS); SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_QUERY_CONFIG);
if (hSc != NULL) 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, Control,
&Status)) &Status))
{ {
bDispErr = FALSE; /* Get the service status */
if (QueryServiceStatusEx(hService,
if (QueryServiceStatusEx(hSc,
SC_STATUS_PROCESS_INFO, SC_STATUS_PROCESS_INFO,
(LPBYTE)&ServiceStatus, (LPBYTE)&ServiceStatus,
sizeof(SERVICE_STATUS_PROCESS), sizeof(SERVICE_STATUS_PROCESS),
&BytesNeeded)) &BytesNeeded))
{ {
DWORD dwStartTickCount = GetTickCount(); /* We don't want to wait for more than 30 seconds */
DWORD dwOldCheckPoint = ServiceStatus.dwCheckPoint; dwMaxWait = 30000;
DWORD dwMaxWait = 2000 * 60; // wait for 2 mins dwStartTickCount = GetTickCount();
IncrementProgressBar(hProgDlg, DEFAULT_STEP);
/* Loop until it's at the correct state */
while (ServiceStatus.dwCurrentState != Control) 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, SC_STATUS_PROCESS_INFO,
(LPBYTE)&ServiceStatus, (LPBYTE)&ServiceStatus,
sizeof(SERVICE_STATUS_PROCESS), sizeof(SERVICE_STATUS_PROCESS),
&BytesNeeded)) &BytesNeeded))
{ {
/* Something went wrong... */
break; break;
} }
/* Is the service making progress? */
if (ServiceStatus.dwCheckPoint > dwOldCheckPoint) if (ServiceStatus.dwCheckPoint > dwOldCheckPoint)
{ {
/* The service is making progress, increment the progress bar */ /* It is, get the latest tickcount to reset the max wait time */
IncrementProgressBar(hProgDlg, DEFAULT_STEP);
dwStartTickCount = GetTickCount(); dwStartTickCount = GetTickCount();
dwOldCheckPoint = ServiceStatus.dwCheckPoint; dwOldCheckPoint = ServiceStatus.dwCheckPoint;
IncrementProgressBar(hProgress, DEFAULT_STEP);
} }
else else
{ {
/* It's not, make sure we haven't exceeded our wait time */
if(GetTickCount() >= dwStartTickCount + dwMaxWait) if(GetTickCount() >= dwStartTickCount + dwMaxWait)
{ {
/* give up */ /* We have, give up */
break; break;
} }
} }
if(dwWaitTime < 200) /* Adjust the wait hint times */
if (dwWaitTime < 200)
dwWaitTime = 200; dwWaitTime = 200;
else if (dwWaitTime > 10000) else if (dwWaitTime > 10000)
dwWaitTime = 10000; dwWaitTime = 10000;
/* Wait before trying again */
Sleep(dwWaitTime); Sleep(dwWaitTime);
} }
} }
if (ServiceStatus.dwCurrentState == Control)
{
bRet = TRUE;
}
} }
CloseServiceHandle(hSc); CloseServiceHandle(hService);
} }
CloseServiceHandle(hSCManager); 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); /* Set the service name and reset the progress bag */
Sleep(500); InitializeProgressDialog(hProgress, Info->pCurrentService->lpServiceName);
bRet = TRUE;
} /* Resume the requested service */
else bRet = DoControl(Info, hProgress, SERVICE_CONTROL_PAUSE);
{
if (bDispErr) /* Complete and destroy the progress bar */
GetError(); DestroyProgressDialog(hProgress, bRet);
else
DisplayString(_T("The service failed to start"));
} }
return bRet; return bRet;
} }
BOOL DoPause(PMAIN_WND_INFO Info) BOOL
DoResume(PMAIN_WND_INFO Info)
{ {
BOOL ret = FALSE; HWND hProgress;
HWND hProgDlg; BOOL bRet = FALSE;
hProgDlg = CreateProgressDialog(Info->hMainWnd, /* Create a progress window to track the progress of the resuming service */
IDS_PROGRESS_INFO_PAUSE); hProgress = CreateProgressDialog(Info->hMainWnd,
if (hProgDlg) 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, /* Resume the requested service */
hProgDlg, bRet = DoControl(Info, hProgress, SERVICE_CONTROL_CONTINUE);
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 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;
} }

View file

@ -90,7 +90,7 @@ typedef struct _STOP_INFO
} STOP_INFO, *PSTOP_INFO; } STOP_INFO, *PSTOP_INFO;
/* control */ /* 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 DoStop(PMAIN_WND_INFO Info);
BOOL DoPause(PMAIN_WND_INFO Info); BOOL DoPause(PMAIN_WND_INFO Info);
BOOL DoResume(PMAIN_WND_INFO Info); BOOL DoResume(PMAIN_WND_INFO Info);
@ -98,10 +98,10 @@ BOOL DoResume(PMAIN_WND_INFO Info);
/* progress.c */ /* progress.c */
#define DEFAULT_STEP 0 #define DEFAULT_STEP 0
HWND CreateProgressDialog(HWND hParent, UINT LabelId); HWND CreateProgressDialog(HWND hParent, UINT LabelId);
BOOL DestroyProgressDialog(HWND hProgDlg, BOOL bComplete); BOOL DestroyProgressDialog(HWND hProgress, BOOL bComplete);
VOID InitializeProgressDialog(HWND hProgDlg, LPWSTR lpServiceName); VOID InitializeProgressDialog(HWND hProgress, LPWSTR lpServiceName);
VOID IncrementProgressBar(HWND hProgDlg, UINT NewPos); VOID IncrementProgressBar(HWND hProgress, UINT NewPos);
VOID CompleteProgressBar(HWND hProgDlg); VOID CompleteProgressBar(HWND hProgress);
/* query.c */ /* query.c */
ENUM_SERVICE_STATUS_PROCESS* GetSelectedService(PMAIN_WND_INFO Info); ENUM_SERVICE_STATUS_PROCESS* GetSelectedService(PMAIN_WND_INFO Info);

View file

@ -39,6 +39,7 @@ DoStartService(PMAIN_WND_INFO Info,
IncrementProgressBar(hProgress, DEFAULT_STEP); IncrementProgressBar(hProgress, DEFAULT_STEP);
} }
/* Start the service */
bRet = StartService(hService, bRet = StartService(hService,
0, 0,
NULL); NULL);
@ -85,6 +86,7 @@ DoStartService(PMAIN_WND_INFO Info,
/* It is, get the latest tickcount to reset the max wait time */ /* It is, get the latest tickcount to reset the max wait time */
dwStartTickCount = GetTickCount(); dwStartTickCount = GetTickCount();
dwOldCheckPoint = ServiceStatus.dwCheckPoint; dwOldCheckPoint = ServiceStatus.dwCheckPoint;
IncrementProgressBar(hProgress, DEFAULT_STEP);
} }
else else
{ {

View file

@ -197,6 +197,10 @@ DoStop(PMAIN_WND_INFO pInfo)
/* Don't stop the main service if the user selected not to */ /* Don't stop the main service if the user selected not to */
bStopMainService = FALSE; bStopMainService = FALSE;
} }
HeapFree(GetProcessHeap(),
0,
lpServiceList);
} }
/* If the service has no running dependents, then we stop it here */ /* If the service has no running dependents, then we stop it here */