mirror of
https://github.com/reactos/reactos.git
synced 2024-10-15 05:37:44 +00:00
Clean up the pause and resume code and a few other bits and bobs
svn path=/trunk/; revision=44965
This commit is contained in:
parent
5dfb2cc0c3
commit
d4aca75523
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue