reactos/base/applications/mscutils/servman/stop.c
Amine Khaldi 527f2f9057 [SHELL/EXPERIMENTS]
* Create a branch for some evul shell experiments.

svn path=/branches/shell-experiments/; revision=61927
2014-02-02 19:37:27 +00:00

226 lines
6.9 KiB
C

/*
* PROJECT: ReactOS Services
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/mscutils/servman/stop.c
* PURPOSE: Stops running a service
* COPYRIGHT: Copyright 2006-2010 Ged Murphy <gedmurphy@reactos.org>
*
*/
#include "precomp.h"
static BOOL
StopService(PMAIN_WND_INFO pInfo,
LPWSTR lpServiceName,
HWND hProgress OPTIONAL)
{
SC_HANDLE hSCManager;
SC_HANDLE hService;
SERVICE_STATUS_PROCESS ServiceStatus;
DWORD dwBytesNeeded;
DWORD dwStartTime;
DWORD dwTimeout;
BOOL bRet = FALSE;
if (hProgress)
{
/* Set the service name and reset the progress bag */
InitializeProgressDialog(hProgress, lpServiceName);
}
hSCManager = OpenSCManager(NULL,
NULL,
SC_MANAGER_CONNECT);
if (hSCManager)
{
hService = OpenService(hSCManager,
lpServiceName,
SERVICE_STOP | SERVICE_QUERY_STATUS);
if (hService)
{
if (hProgress)
{
/* Increment the progress bar */
IncrementProgressBar(hProgress, DEFAULT_STEP);
}
/* Set the wait time to 30 secs */
dwStartTime = GetTickCount();
dwTimeout = 30000;
/* Send the service the stop code */
if (ControlService(hService,
SERVICE_CONTROL_STOP,
(LPSERVICE_STATUS)&ServiceStatus))
{
if (hProgress)
{
/* Increment the progress bar */
IncrementProgressBar(hProgress, DEFAULT_STEP);
}
while (ServiceStatus.dwCurrentState != SERVICE_STOPPED)
{
/* Don't sleep for more than 3 seconds */
if (ServiceStatus.dwWaitHint > 3000)
ServiceStatus.dwWaitHint = 3000;
Sleep(ServiceStatus.dwWaitHint);
if (hProgress)
{
/* Increment the progress bar */
IncrementProgressBar(hProgress, DEFAULT_STEP);
}
if (QueryServiceStatusEx(hService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ServiceStatus,
sizeof(SERVICE_STATUS_PROCESS),
&dwBytesNeeded))
{
/* Have we exceeded our wait time? */
if (GetTickCount() - dwStartTime > dwTimeout)
{
/* Yep, give up */
break;
}
}
}
/* If the service is stopped, return TRUE */
if (ServiceStatus.dwCurrentState == SERVICE_STOPPED)
{
bRet = TRUE;
}
}
CloseServiceHandle(hService);
}
CloseServiceHandle(hSCManager);
}
return bRet;
}
static BOOL
StopDependantServices(PMAIN_WND_INFO pInfo,
LPWSTR lpServiceList,
HWND hProgress OPTIONAL)
{
LPWSTR lpStr;
BOOL bRet = FALSE;
lpStr = lpServiceList;
/* Loop through all the services in the list */
while (TRUE)
{
/* Break when we hit the double null */
if (*lpStr == L'\0' && *(lpStr + 1) == L'\0')
break;
/* If this isn't our first time in the loop we'll
have been left on a null char */
if (*lpStr == L'\0')
lpStr++;
/* Stop the requested service */
bRet = StopService(pInfo,
lpStr,
hProgress);
/* Complete the progress bar if we succeeded */
if (bRet)
{
CompleteProgressBar(hProgress);
}
/* Move onto the next string */
while (*lpStr != L'\0')
lpStr++;
}
return bRet;
}
BOOL
DoStop(PMAIN_WND_INFO pInfo)
{
HWND hProgress;
LPWSTR lpServiceList;
BOOL bRet = FALSE;
BOOL bStopMainService = TRUE;
if (pInfo)
{
/* Does the service have any dependent services which need stopping first */
lpServiceList = GetListOfServicesToStop(pInfo->pCurrentService->lpServiceName);
if (lpServiceList)
{
/* Tag the service list to the main wnd info */
pInfo->pTag = (PVOID)lpServiceList;
/* List them and ask the user if they want to stop them */
if (DialogBoxParamW(hInstance,
MAKEINTRESOURCEW(IDD_DLG_DEPEND_STOP),
pInfo->hMainWnd,
StopDependsDialogProc,
(LPARAM)pInfo) == IDOK)
{
/* Create a progress window to track the progress of the stopping services */
hProgress = CreateProgressDialog(pInfo->hMainWnd,
IDS_PROGRESS_INFO_STOP);
/* Stop all the dependant services */
StopDependantServices(pInfo, lpServiceList, hProgress);
/* Now stop the requested one */
bRet = StopService(pInfo,
pInfo->pCurrentService->lpServiceName,
hProgress);
/* We've already stopped the main service, don't try to stop it again */
bStopMainService = FALSE;
if (hProgress)
{
/* Complete and destroy the progress bar */
DestroyProgressDialog(hProgress, TRUE);
}
}
else
{
/* 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 */
if (bStopMainService)
{
/* Create a progress window to track the progress of the stopping service */
hProgress = CreateProgressDialog(pInfo->hMainWnd,
IDS_PROGRESS_INFO_STOP);
/* Stop the requested service */
bRet = StopService(pInfo,
pInfo->pCurrentService->lpServiceName,
hProgress);
if (hProgress)
{
/* Complete and destroy the progress bar */
DestroyProgressDialog(hProgress, TRUE);
}
}
}
return bRet;
}