[SERVMAN]

- Rewrite the progress dialog making it responsible for controlling services. (starting, stopping, etc).
- Fixup the rest of the code to make use of running actions through the progress dialog.
- As a side-effect, this should fix CORE-4585 

svn path=/trunk/; revision=67094
This commit is contained in:
Ged Murphy 2015-04-08 17:28:46 +00:00
parent c783e3db2f
commit 6de5a3ef96
7 changed files with 792 additions and 753 deletions

View file

@ -3,180 +3,143 @@
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/mscutils/servman/control.c
* PURPOSE: Pauses and resumes a service
* COPYRIGHT: Copyright 2006-2010 Ged Murphy <gedmurphy@reactos.org>
* COPYRIGHT: Copyright 2006-2015 Ged Murphy <gedmurphy@reactos.org>
*
*/
#include "precomp.h"
static BOOL
DoControl(PMAIN_WND_INFO Info,
HWND hProgress,
DWORD Control)
#define MAX_WAIT_TIME 30000
BOOL
DoControlService(LPWSTR ServiceName,
HWND hProgress,
DWORD Control)
{
SC_HANDLE hSCManager;
SC_HANDLE hService;
SERVICE_STATUS_PROCESS ServiceStatus = {0};
SERVICE_STATUS Status;
DWORD BytesNeeded = 0;
DWORD dwStartTickCount;
DWORD dwOldCheckPoint;
DWORD dwWaitTime;
DWORD dwMaxWait;
DWORD dwReqState;
BOOL bRet = FALSE;
DWORD StartTickCount;
DWORD OldCheckPoint;
DWORD WaitTime;
DWORD MaxWait;
DWORD ReqState;
BOOL Result;
/* Set the state we're interested in */
switch (Control)
{
case SERVICE_CONTROL_PAUSE:
dwReqState = SERVICE_PAUSED;
ReqState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
dwReqState = SERVICE_RUNNING;
ReqState = SERVICE_RUNNING;
break;
default:
/* Unhandled control code */
return FALSE;
}
hSCManager = OpenSCManager(NULL,
NULL,
SC_MANAGER_CONNECT);
if (hSCManager)
hSCManager = OpenSCManagerW(NULL,
NULL,
SC_MANAGER_CONNECT);
if (!hSCManager) return FALSE;
hService = OpenServiceW(hSCManager,
ServiceName,
SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_QUERY_STATUS);
if (!hService)
{
hService = OpenService(hSCManager,
Info->pCurrentService->lpServiceName,
SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_QUERY_STATUS);
if (hService)
CloseServiceHandle(hSCManager);
return FALSE;
}
/* Send the control message to the service */
Result = ControlService(hService,
Control,
&Status);
if (Result)
{
if (hProgress)
{
if (hProgress)
{
/* Increment the progress bar */
IncrementProgressBar(hProgress, DEFAULT_STEP);
}
/* Increment the progress bar */
IncrementProgressBar(hProgress, DEFAULT_STEP);
}
/* Send the control message to the service */
if (ControlService(hService,
Control,
&Status))
/* Get the service status */
Result = QueryServiceStatusEx(hService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ServiceStatus,
sizeof(SERVICE_STATUS_PROCESS),
&BytesNeeded);
if (Result)
{
Result = FALSE;
MaxWait = MAX_WAIT_TIME;
OldCheckPoint = ServiceStatus.dwCheckPoint;
StartTickCount = GetTickCount();
/* Loop until it's at the correct state */
while (ServiceStatus.dwCurrentState != ReqState)
{
/* Get the service status */
if (QueryServiceStatusEx(hService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ServiceStatus,
sizeof(SERVICE_STATUS_PROCESS),
&BytesNeeded))
/* Fixup the wait time */
WaitTime = ServiceStatus.dwWaitHint / 10;
if (WaitTime < 1000) WaitTime = 1000;
else if (WaitTime > 10000) WaitTime = 10000;
/* We don't wanna wait for up to 10 secs without incrementing */
for (int i = WaitTime / 1000; i > 0; i--)
{
/* 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 != dwReqState)
Sleep(1000);
if (hProgress)
{
dwOldCheckPoint = ServiceStatus.dwCheckPoint;
dwWaitTime = ServiceStatus.dwWaitHint / 10;
/* 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)
{
/* 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)
{
/* We have, give up */
break;
}
}
/* Adjust the wait hint times */
if (dwWaitTime < 200)
dwWaitTime = 200;
else if (dwWaitTime > 10000)
dwWaitTime = 10000;
/* Wait before trying again */
Sleep(dwWaitTime);
/* Increment the progress bar */
IncrementProgressBar(hProgress, DEFAULT_STEP);
}
}
if (ServiceStatus.dwCurrentState == dwReqState)
/* Get the latest status info */
if (!QueryServiceStatusEx(hService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ServiceStatus,
sizeof(SERVICE_STATUS_PROCESS),
&BytesNeeded))
{
bRet = TRUE;
/* Something went wrong... */
break;
}
/* Is the service making progress? */
if (ServiceStatus.dwCheckPoint > OldCheckPoint)
{
/* It is, get the latest tickcount to reset the max wait time */
StartTickCount = GetTickCount();
OldCheckPoint = ServiceStatus.dwCheckPoint;
IncrementProgressBar(hProgress, DEFAULT_STEP);
}
else
{
/* It's not, make sure we haven't exceeded our wait time */
if(GetTickCount() >= StartTickCount + MaxWait)
{
/* We have, give up */
break;
}
}
}
CloseServiceHandle(hService);
}
CloseServiceHandle(hSCManager);
if (ServiceStatus.dwCurrentState == ReqState)
{
Result = TRUE;
}
}
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)
{
/* 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
DoResume(PMAIN_WND_INFO Info)
{
HWND hProgress;
BOOL bRet = FALSE;
/* Create a progress window to track the progress of the resuming service */
hProgress = CreateProgressDialog(Info->hMainWnd,
IDS_PROGRESS_INFO_RESUME);
if (hProgress)
{
/* Set the service name and reset the progress bag */
InitializeProgressDialog(hProgress, Info->pCurrentService->lpServiceName);
/* Resume the requested service */
bRet = DoControl(Info, hProgress, SERVICE_CONTROL_CONTINUE);
/* Complete and destroy the progress bar */
DestroyProgressDialog(hProgress, bRet);
}
return bRet;
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
return Result;
}

View file

@ -3,7 +3,7 @@
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/mscutils/servman/mainwnd.c
* PURPOSE: Main window message handler
* COPYRIGHT: Copyright 2006-2007 Ged Murphy <gedmurphy@reactos.org>
* COPYRIGHT: Copyright 2006-20015 Ged Murphy <gedmurphy@reactos.org>
*
*/
@ -11,7 +11,7 @@
#include <windowsx.h>
static const TCHAR szMainWndClass[] = TEXT("ServManWndClass");
static const WCHAR szMainWndClass[] = L"ServManWndClass";
BOOL bSortAscending = TRUE;
@ -126,17 +126,17 @@ UpdateMainStatusBar(PMAIN_WND_INFO Info)
VOID
UpdateServiceCount(PMAIN_WND_INFO Info)
{
LPTSTR lpNumServices;
LPWSTR lpNumServices;
if (AllocAndLoadString(&lpNumServices,
hInstance,
IDS_NUM_SERVICES))
{
TCHAR szNumServices[32];
WCHAR szNumServices[32];
INT NumListedServ = ListView_GetItemCount(Info->hListView);
_sntprintf(szNumServices,
_snwprintf(szNumServices,
31,
lpNumServices,
NumListedServ);
@ -257,7 +257,7 @@ CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
Param1 = (ENUM_SERVICE_STATUS_PROCESS *)lParam2;
Param2 = (ENUM_SERVICE_STATUS_PROCESS *)lParam1;
}
return _tcsicmp(Param1->lpDisplayName, Param2->lpDisplayName);
return _wcsicmp(Param1->lpDisplayName, Param2->lpDisplayName);
}
@ -344,24 +344,24 @@ InitMainWnd(PMAIN_WND_INFO Info)
{
if (!pCreateToolbar(Info))
{
DisplayString(_T("error creating toolbar"));
DisplayString(L"error creating toolbar");
return FALSE;
}
if (!CreateListView(Info))
{
DisplayString(_T("error creating list view"));
DisplayString(L"error creating list view");
return FALSE;
}
if (!CreateStatusBar(Info))
DisplayString(_T("error creating status bar"));
DisplayString(L"error creating status bar");
/* Create Popup Menu */
Info->hShortcutMenu = LoadMenu(hInstance,
MAKEINTRESOURCE(IDR_POPUP));
Info->bIsUserAnAdmin = IsUserAnAdmin();
Info->bIsUserAnAdmin = TRUE;// IsUserAnAdmin();
if (Info->bIsUserAnAdmin)
{
HMENU hMainMenu = GetMenu(Info->hMainWnd);
@ -418,7 +418,7 @@ MainWndCommand(PMAIN_WND_INFO Info,
SendMessage(Info->hStatus,
SB_SETTEXT,
1,
_T('\0'));
L'\0');
}
break;
@ -457,11 +457,11 @@ MainWndCommand(PMAIN_WND_INFO Info,
}
else
{
TCHAR Buf[60];
WCHAR Buf[60];
LoadString(hInstance,
IDS_DELETE_STOP,
Buf,
sizeof(Buf) / sizeof(TCHAR));
sizeof(Buf) / sizeof(WCHAR));
DisplayString(Buf);
}
@ -472,50 +472,73 @@ MainWndCommand(PMAIN_WND_INFO Info,
case ID_START:
{
if (DoStart(Info, NULL))
{
UpdateServiceStatus(Info->pCurrentService);
ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
SetMenuAndButtonStates(Info);
SetFocus(Info->hListView);
}
RunActionWithProgress(Info->hMainWnd,
Info->pCurrentService->lpServiceName,
Info->pCurrentService->lpDisplayName,
ACTION_START);
UpdateServiceStatus(Info->pCurrentService);
ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
SetMenuAndButtonStates(Info);
SetFocus(Info->hListView);
}
break;
case ID_STOP:
if (DoStop(Info))
{
UpdateServiceStatus(Info->pCurrentService);
ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
SetMenuAndButtonStates(Info);
SetFocus(Info->hListView);
}
RunActionWithProgress(Info->hMainWnd,
Info->pCurrentService->lpServiceName,
Info->pCurrentService->lpDisplayName,
ACTION_STOP);
UpdateServiceStatus(Info->pCurrentService);
ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
SetMenuAndButtonStates(Info);
SetFocus(Info->hListView);
break;
case ID_PAUSE:
DoPause(Info);
RunActionWithProgress(Info->hMainWnd,
Info->pCurrentService->lpServiceName,
Info->pCurrentService->lpDisplayName,
ACTION_PAUSE);
UpdateServiceStatus(Info->pCurrentService);
ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
SetMenuAndButtonStates(Info);
SetFocus(Info->hListView);
break;
case ID_RESUME:
DoResume(Info);
RunActionWithProgress(Info->hMainWnd,
Info->pCurrentService->lpServiceName,
Info->pCurrentService->lpDisplayName,
ACTION_RESUME);
UpdateServiceStatus(Info->pCurrentService);
ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
SetMenuAndButtonStates(Info);
SetFocus(Info->hListView);
break;
case ID_RESTART:
if (DoStop(Info))
{
DoStart(Info, NULL);
UpdateServiceStatus(Info->pCurrentService);
ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
SetMenuAndButtonStates(Info);
SetFocus(Info->hListView);
}
RunActionWithProgress(Info->hMainWnd,
Info->pCurrentService->lpServiceName,
Info->pCurrentService->lpDisplayName,
ACTION_RESTART);
UpdateServiceStatus(Info->pCurrentService);
ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
SetMenuAndButtonStates(Info);
SetFocus(Info->hListView);
break;
case ID_HELP:
MessageBox(NULL,
_T("Help is not yet implemented\n"),
_T("Note!"),
MB_OK | MB_ICONINFORMATION);
MessageBoxW(NULL,
L"Help is not yet implemented\n",
L"Note!",
MB_OK | MB_ICONINFORMATION);
SetFocus(Info->hListView);
break;

View file

@ -1,6 +1,7 @@
#ifndef __SERVMAN_PRECOMP_H
#define __SERVMAN_PRECOMP_H
#if 0
#include <stdarg.h>
#define WIN32_NO_STATUS
@ -12,10 +13,14 @@
#include <wingdi.h>
#include <winsvc.h>
#include <wincon.h>
#include <tchar.h>
#include <shlobj.h>
#include <strsafe.h>
#else
#include <windows.h>
#include <Commctrl.h>
#include <process.h>
#include <Strsafe.h>
#endif
#include "resource.h"
#ifdef _MSC_VER
@ -23,17 +28,23 @@
#endif
#define NO_ITEM_SELECTED -1
#define MAX_KEY_LENGTH 256
#define MAX_KEY_LENGTH 256
#define LVNAME 0
#define LVDESC 1
#define LVSTATUS 2
#define LVSTARTUP 3
#define LVLOGONAS 4
#define LVNAME 0
#define LVDESC 1
#define LVSTATUS 2
#define LVSTARTUP 3
#define LVLOGONAS 4
#define IMAGE_UNKNOWN 0
#define IMAGE_SERVICE 1
#define IMAGE_DRIVER 2
#define IMAGE_UNKNOWN 0
#define IMAGE_SERVICE 1
#define IMAGE_DRIVER 2
#define ACTION_START 1
#define ACTION_STOP 2
#define ACTION_PAUSE 3
#define ACTION_RESUME 4
#define ACTION_RESTART 5
typedef struct _MAIN_WND_INFO
{
@ -86,38 +97,24 @@ VOID SetListViewStyle(HWND hListView, DWORD View);
VOID ListViewSelectionChanged(PMAIN_WND_INFO Info, LPNMLISTVIEW pnmv);
BOOL CreateListView(PMAIN_WND_INFO Info);
/* start */
BOOL DoStart(PMAIN_WND_INFO Info, LPWSTR lpStartParams);
/* stop */
typedef struct _STOP_INFO
{
PMAIN_WND_INFO pInfo;
SC_HANDLE hSCManager;
SC_HANDLE hMainService;
} STOP_INFO, *PSTOP_INFO;
/* 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);
/* start / stop / control */
BOOL DoStartService(LPWSTR ServiceName, HANDLE hProgress, LPWSTR lpStartParams);
BOOL DoStopService(LPWSTR ServiceName, HANDLE hProgress);
BOOL DoControlService(LPWSTR ServiceName, HWND hProgress, DWORD Control);
/* progress.c */
#define DEFAULT_STEP 0
HWND CreateProgressDialog(HWND hParent, UINT LabelId);
BOOL DestroyProgressDialog(HWND hProgress, BOOL bComplete);
VOID InitializeProgressDialog(HWND hProgress, LPWSTR lpServiceName);
VOID IncrementProgressBar(HWND hProgress, UINT NewPos);
VOID CompleteProgressBar(HWND hProgress);
BOOL RunActionWithProgress(HWND hParent, LPWSTR ServiceName, LPWSTR DisplayName, UINT Action);
VOID IncrementProgressBar(HANDLE hProgress, UINT NewPos);
VOID CompleteProgressBar(HANDLE hProgress);
/* query.c */
ENUM_SERVICE_STATUS_PROCESS* GetSelectedService(PMAIN_WND_INFO Info);
LPQUERY_SERVICE_CONFIG GetServiceConfig(LPTSTR lpServiceName);
BOOL SetServiceConfig(LPQUERY_SERVICE_CONFIG pServiceConfig, LPTSTR lpServiceName, LPTSTR lpPassword);
LPTSTR GetServiceDescription(LPTSTR lpServiceName);
BOOL SetServiceDescription(LPTSTR lpServiceName, LPTSTR lpDescription);
LPTSTR GetExecutablePath(LPTSTR lpServiceName);
LPQUERY_SERVICE_CONFIG GetServiceConfig(LPWSTR lpServiceName);
BOOL SetServiceConfig(LPQUERY_SERVICE_CONFIG pServiceConfig, LPWSTR lpServiceName, LPWSTR lpPassword);
LPWSTR GetServiceDescription(LPWSTR lpServiceName);
BOOL SetServiceDescription(LPWSTR lpServiceName, LPWSTR lpDescription);
LPWSTR GetExecutablePath(LPWSTR lpServiceName);
BOOL RefreshServiceList(PMAIN_WND_INFO Info);
BOOL UpdateServiceStatus(ENUM_SERVICE_STATUS_PROCESS* pService);
BOOL GetServiceList(PMAIN_WND_INFO Info, DWORD *NumServices);
@ -135,19 +132,24 @@ typedef struct _SERVICEPROPSHEET
} SERVICEPROPSHEET, *PSERVICEPROPSHEET;
HTREEITEM AddItemToTreeView(HWND hTreeView, HTREEITEM hRoot, LPTSTR lpDisplayName, LPTSTR lpServiceName, ULONG serviceType, BOOL bHasChildren);
HTREEITEM AddItemToTreeView(HWND hTreeView, HTREEITEM hRoot, LPWSTR lpDisplayName, LPWSTR lpServiceName, ULONG serviceType, BOOL bHasChildren);
/* stop_dependencies */
INT_PTR CALLBACK StopDependsDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
LPWSTR GetListOfServicesToStop(LPWSTR lpServiceName);
BOOL
CreateStopDependsDialog(HWND hParent,
LPWSTR ServiceName,
LPWSTR DisplayName,
LPWSTR ServiceList);
/* tv1_dependencies */
BOOL TV1_Initialize(PSERVICEPROPSHEET pDlgInfo, LPTSTR lpServiceName);
VOID TV1_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, HTREEITEM hParent, LPTSTR lpServiceName);
BOOL TV1_Initialize(PSERVICEPROPSHEET pDlgInfo, LPWSTR lpServiceName);
VOID TV1_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, HTREEITEM hParent, LPWSTR lpServiceName);
/* tv2_dependencies */
BOOL TV2_Initialize(PSERVICEPROPSHEET pDlgInfo, LPTSTR lpServiceName);
VOID TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, HTREEITEM hParent, LPTSTR lpServiceName);
BOOL TV2_Initialize(PSERVICEPROPSHEET pDlgInfo, LPWSTR lpServiceName);
VOID TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, HTREEITEM hParent, LPWSTR lpServiceName);
BOOL TV2_HasDependantServices(LPWSTR lpServiceName);
LPENUM_SERVICE_STATUS TV2_GetDependants(LPWSTR lpServiceName, LPDWORD lpdwCount);
@ -167,12 +169,12 @@ INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg,
VOID ExportFile(PMAIN_WND_INFO Info);
/* misc.c */
INT AllocAndLoadString(OUT LPTSTR *lpTarget,
INT AllocAndLoadString(OUT LPWSTR *lpTarget,
IN HINSTANCE hInst,
IN UINT uID);
DWORD LoadAndFormatString(IN HINSTANCE hInstance,
IN UINT uID,
OUT LPTSTR *lpTarget,
OUT LPWSTR *lpTarget,
...);
BOOL StatusBarLoadAndFormatString(IN HWND hStatusBar,
IN INT PartId,
@ -183,11 +185,11 @@ BOOL StatusBarLoadString(IN HWND hStatusBar,
IN INT PartId,
IN HINSTANCE hInstance,
IN UINT uID);
INT GetTextFromEdit(OUT LPTSTR lpString,
INT GetTextFromEdit(OUT LPWSTR lpString,
IN HWND hDlg,
IN UINT Res);
VOID GetError(VOID);
VOID DisplayString(PTCHAR);
VOID DisplayString(PWCHAR);
HIMAGELIST InitImageList(UINT StartResource,
UINT EndResource,
UINT Width,

View file

@ -3,97 +3,227 @@
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/mscutils/servman/progress.c
* PURPOSE: Progress dialog box message handler
* COPYRIGHT: Copyright 2006-2010 Ged Murphy <gedmurphy@reactos.org>
* COPYRIGHT: Copyright 2006-2015 Ged Murphy <gedmurphy@reactos.org>
*
*/
#include "precomp.h"
#define PROGRESSRANGE 20
#define PROGRESS_RANGE 20
#define PROGRESS_STEP_MAX 15
VOID
CompleteProgressBar(HWND hProgDlg)
typedef struct _PROGRESS_DATA
{
HWND hProgBar;
UINT Pos = 0;
HWND hDlg;
HWND hProgress;
LPWSTR ServiceName;
ULONG Action;
BOOL StopDepends;
LPWSTR ServiceList;
/* Get a handle to the progress bar */
hProgBar = GetDlgItem(hProgDlg,
IDC_SERVCON_PROGRESS);
if (hProgBar)
} PROGRESS_DATA, *PPROGRESS_DATA;
static VOID
ResetProgressDialog(HWND hDlg,
LPWSTR ServiceName,
ULONG LabelId)
{
LPWSTR lpProgStr;
/* Load the label Id */
if (AllocAndLoadString(&lpProgStr,
hInstance,
LabelId))
{
/* Get the current position */
Pos = SendMessageW(hProgBar,
PBM_GETPOS,
0,
0);
/* Write it to the dialog */
SendDlgItemMessageW(hDlg,
IDC_SERVCON_INFO,
WM_SETTEXT,
0,
(LPARAM)lpProgStr);
/* Loop until we hit the max */
while (Pos <= PROGRESSRANGE)
{
/* Increment the progress bar */
SendMessageW(hProgBar,
PBM_DELTAPOS,
Pos,
0);
/* Wait for 15ms, it gives it a smooth feel */
Sleep(15);
Pos++;
}
LocalFree(lpProgStr);
}
}
VOID
IncrementProgressBar(HWND hProgDlg,
UINT NewPos)
{
HWND hProgBar;
/* Get a handle to the progress bar */
hProgBar = GetDlgItem(hProgDlg,
IDC_SERVCON_PROGRESS);
if (hProgBar)
{
/* Do we want to increment the default amount? */
if (NewPos == DEFAULT_STEP)
{
/* Yes, use the step value we set on create */
SendMessageW(hProgBar,
PBM_STEPIT,
0,
0);
}
else
{
/* No, use the value passed */
SendMessageW(hProgBar,
PBM_SETPOS,
NewPos,
0);
}
}
}
VOID
InitializeProgressDialog(HWND hProgDlg,
LPWSTR lpServiceName)
{
/* Write the service name to the dialog */
SendDlgItemMessageW(hProgDlg,
SendDlgItemMessageW(hDlg,
IDC_SERVCON_NAME,
WM_SETTEXT,
0,
(LPARAM)lpServiceName);
(LPARAM)ServiceName);
/* Set the progress bar to the start */
SendDlgItemMessageW(hProgDlg,
SendDlgItemMessageW(hDlg,
IDC_SERVCON_PROGRESS,
PBM_SETPOS,
0,
0);
}
unsigned int __stdcall ActionThread(void* Param)
{
PPROGRESS_DATA ProgressData = (PPROGRESS_DATA)Param;
if (ProgressData->Action == ACTION_START)
{
/* Setup the progress dialog for this action */
ResetProgressDialog(ProgressData->hDlg,
ProgressData->ServiceName,
IDS_PROGRESS_INFO_START);
/* Start the service */
if (DoStartService(ProgressData->ServiceName,
ProgressData->hProgress,
NULL))
{
/* We're done, slide the progress bar up to the top */
CompleteProgressBar(ProgressData->hProgress);
}
}
else if (ProgressData->Action == ACTION_STOP || ProgressData->Action == ACTION_RESTART)
{
/* Check if there are and dependants to stop */
if (ProgressData->StopDepends && ProgressData->ServiceList)
{
LPWSTR lpStr = ProgressData->ServiceList;
/* Loop through all the services in the list */
for (;;)
{
/* 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++;
ResetProgressDialog(ProgressData->hDlg,
lpStr,
IDS_PROGRESS_INFO_STOP);
/* Stop the requested service */
if (DoStopService(ProgressData->ServiceName,
ProgressData->hProgress))
{
CompleteProgressBar(ProgressData->hProgress);
}
/* Move onto the next string */
while (*lpStr != L'\0')
lpStr++;
}
}
ResetProgressDialog(ProgressData->hDlg,
ProgressData->ServiceName,
IDS_PROGRESS_INFO_STOP);
if (DoStopService(ProgressData->ServiceName,
ProgressData->hProgress))
{
CompleteProgressBar(ProgressData->hProgress);
}
/* If this was a restart, we'll need to start the service back up */
if (ProgressData->Action == ACTION_RESTART)
{
/* Setup the progress dialog for this action */
ResetProgressDialog(ProgressData->hDlg,
ProgressData->ServiceName,
IDS_PROGRESS_INFO_START);
/* Start the service */
if (DoStartService(ProgressData->ServiceName,
ProgressData->hProgress,
NULL))
{
/* We're done, slide the progress bar up to the top */
CompleteProgressBar(ProgressData->hProgress);
}
}
}
else if (ProgressData->Action == ACTION_PAUSE)
{
/* Setup the progress dialog for this action */
ResetProgressDialog(ProgressData->hDlg,
ProgressData->ServiceName,
IDS_PROGRESS_INFO_PAUSE);
/* Pause the service */
if (DoControlService(ProgressData->ServiceName,
ProgressData->hProgress,
SERVICE_CONTROL_PAUSE))
{
/* We're done, slide the progress bar up to the top */
CompleteProgressBar(ProgressData->hProgress);
}
}
else if (ProgressData->Action == ACTION_RESUME)
{
/* Setup the progress dialog for this action */
ResetProgressDialog(ProgressData->hDlg,
ProgressData->ServiceName,
IDS_PROGRESS_INFO_RESUME);
/* resume the service */
if (DoControlService(ProgressData->ServiceName,
ProgressData->hProgress,
SERVICE_CONTROL_CONTINUE))
{
/* We're done, slide the progress bar up to the top */
CompleteProgressBar(ProgressData->hProgress);
}
}
EndDialog(ProgressData->hDlg, IDOK);
_endthreadex(0);
return 0;
}
static BOOL
InitDialog(HWND hDlg,
UINT Message,
WPARAM wParam,
LPARAM lParam)
{
PPROGRESS_DATA ProgressData = (PPROGRESS_DATA)lParam;
HANDLE hThread;
ProgressData->hDlg = hDlg;
/* Get a handle to the progress bar */
ProgressData->hProgress = GetDlgItem(hDlg,
IDC_SERVCON_PROGRESS);
if (!ProgressData->hProgress)
return FALSE;
/* Set the progress bar range */
SendMessageW(ProgressData->hProgress,
PBM_SETRANGE,
0,
MAKELPARAM(0, PROGRESS_RANGE));
/* Set the progress bar step */
SendMessageW(ProgressData->hProgress,
PBM_SETSTEP,
(WPARAM)1,
0);
/* Create a thread to handle the service control */
hThread = (HANDLE)_beginthreadex(NULL, 0, &ActionThread, ProgressData, 0, NULL);
if (!hThread) return FALSE;
CloseHandle(hThread);
return TRUE;
}
INT_PTR CALLBACK
ProgressDialogProc(HWND hDlg,
UINT Message,
@ -104,35 +234,21 @@ ProgressDialogProc(HWND hDlg,
{
case WM_INITDIALOG:
{
HWND hProgBar;
/* Get a handle to the progress bar */
hProgBar = GetDlgItem(hDlg,
IDC_SERVCON_PROGRESS);
/* Set the progress bar range */
SendMessageW(hProgBar,
PBM_SETRANGE,
0,
MAKELPARAM(0, PROGRESSRANGE));
/* Set the progress bar step */
SendMessageW(hProgBar,
PBM_SETSTEP,
(WPARAM)1,
0);
return InitDialog(hDlg,
Message,
wParam,
lParam);
}
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
DestroyWindow(hDlg);
break;
EndDialog(hDlg, wParam);
break;
}
break;
break;
default:
return FALSE;
@ -141,64 +257,115 @@ ProgressDialogProc(HWND hDlg,
return TRUE;
}
HWND
CreateProgressDialog(HWND hParent,
UINT LabelId)
VOID
CompleteProgressBar(HANDLE hProgress)
{
HWND hProgDlg;
LPWSTR lpProgStr;
HWND hProgBar = (HWND)hProgress;
UINT Pos = 0;
/* open the progress dialog */
hProgDlg = CreateDialogW(hInstance,
MAKEINTRESOURCEW(IDD_DLG_PROGRESS),
hParent,
ProgressDialogProc);
if (hProgDlg != NULL)
/* Get the current position */
Pos = SendMessageW(hProgBar,
PBM_GETPOS,
0,
0);
/* Loop until we hit the max */
while (Pos <= PROGRESS_RANGE)
{
/* Load the label Id */
if (AllocAndLoadString(&lpProgStr,
hInstance,
LabelId))
{
/* Write it to the dialog */
SendDlgItemMessageW(hProgDlg,
IDC_SERVCON_INFO,
WM_SETTEXT,
0,
(LPARAM)lpProgStr);
/* Increment the progress bar */
SendMessageW(hProgBar,
PBM_DELTAPOS,
Pos,
0);
LocalFree(lpProgStr);
}
/* Finally, show and update the progress dialog */
ShowWindow(hProgDlg, SW_SHOWNORMAL);
UpdateWindow(hProgDlg);
// TODO: Add a message loop for it ?
/* Wait for 15ms to give it a smooth feel */
Sleep(15);
Pos++;
}
}
return hProgDlg;
VOID
IncrementProgressBar(HANDLE hProgress,
UINT Step)
{
HWND hProgBar = (HWND)hProgress;
UINT Position;
/* Don't allow the progress to reach to complete*/
Position = SendMessageW(hProgBar,
PBM_GETPOS,
0,
0);
if (Position < PROGRESS_STEP_MAX)
{
/* Do we want to increment the default amount? */
if (Step == DEFAULT_STEP)
{
/* Use the step value we set on create */
SendMessageW(hProgBar,
PBM_STEPIT,
0,
0);
}
else
{
/* Use the value passed */
SendMessageW(hProgBar,
PBM_SETPOS,
Step,
0);
}
}
}
BOOL
DestroyProgressDialog(HWND hwnd,
BOOL bComplete)
RunActionWithProgress(HWND hParent,
LPWSTR ServiceName,
LPWSTR DisplayName,
UINT Action)
{
BOOL bRet = FALSE;
PROGRESS_DATA ProgressData;
LPWSTR ServiceList;
BOOL StopDepends;
INT_PTR Result;
if (hwnd)
StopDepends = FALSE;
ServiceList = NULL;
/* Check if we'll be stopping the service */
if (Action == ACTION_STOP || Action == ACTION_RESTART)
{
if (bComplete)
/* Does the service have any dependent services which need stopping first */
ServiceList = GetListOfServicesToStop(ServiceName);
if (ServiceList)
{
/* Complete the progress bar */
CompleteProgressBar(hwnd);
/* Ask the user if they want to stop the dependants */
StopDepends = CreateStopDependsDialog(hParent,
ServiceName,
DisplayName,
ServiceList);
/* Wait, for asthetics */
Sleep(500);
/* Exit early if the user decided not to stop the dependants */
if (StopDepends == FALSE)
return FALSE;
}
bRet = DestroyWindow(hwnd);
}
return bRet;
ProgressData.hDlg = NULL;
ProgressData.ServiceName = ServiceName;
ProgressData.Action = Action;
ProgressData.StopDepends = StopDepends;
ProgressData.ServiceList = ServiceList;
Result = DialogBoxParamW(hInstance,
MAKEINTRESOURCEW(IDD_DLG_PROGRESS),
hParent,
ProgressDialogProc,
(LPARAM)&ProgressData);
if (ServiceList)
HeapFree(GetProcessHeap(), 0, ServiceList);
return (Result == IDOK);
}

View file

@ -3,26 +3,28 @@
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/mscutils/servman/start.c
* PURPOSE: Start a service
* COPYRIGHT: Copyright 2005-2010 Ged Murphy <gedmurphy@reactos.org>
* COPYRIGHT: Copyright 2005-2015 Ged Murphy <gedmurphy@reactos.org>
*
*/
#include "precomp.h"
static BOOL
DoStartService(PMAIN_WND_INFO Info,
HWND hProgress,
#define MAX_WAIT_TIME 30000
BOOL
DoStartService(LPWSTR ServiceName,
HANDLE hProgress,
LPWSTR lpStartParams)
{
SC_HANDLE hSCManager;
SC_HANDLE hService;
SERVICE_STATUS_PROCESS ServiceStatus;
DWORD BytesNeeded = 0;
DWORD dwStartTickCount;
DWORD dwOldCheckPoint;
DWORD dwWaitTime;
DWORD dwMaxWait;
BOOL bRet = FALSE;
DWORD StartTickCount;
DWORD OldCheckPoint;
DWORD WaitTime;
DWORD MaxWait;
BOOL Result = FALSE;
BOOL bWhiteSpace = TRUE;
LPWSTR lpChar;
@ -57,7 +59,7 @@ DoStartService(PMAIN_WND_INFO Info,
return FALSE;
/* Make the service name the first argument */
lpArgsVector[0] = Info->pCurrentService->lpServiceName;
lpArgsVector[0] = ServiceName;
/* Fill the arguments vector */
dwArgsCount = 1;
@ -84,130 +86,120 @@ DoStartService(PMAIN_WND_INFO Info,
}
}
hSCManager = OpenSCManager(NULL,
NULL,
SC_MANAGER_CONNECT);
if (hSCManager)
hSCManager = OpenSCManagerW(NULL,
NULL,
SC_MANAGER_CONNECT);
if (!hSCManager)
{
hService = OpenService(hSCManager,
Info->pCurrentService->lpServiceName,
SERVICE_START | SERVICE_QUERY_STATUS);
if (hService)
if (lpArgsVector)
LocalFree((LPVOID)lpArgsVector);
return FALSE;
}
hService = OpenServiceW(hSCManager,
ServiceName,
SERVICE_START | SERVICE_QUERY_STATUS);
if (!hService)
{
CloseServiceHandle(hSCManager);
if (lpArgsVector)
LocalFree((LPVOID)lpArgsVector);
return FALSE;
}
/* Start the service */
Result = StartServiceW(hService,
dwArgsCount,
lpArgsVector);
if (!Result && GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)
{
/* If it's already running, just return TRUE */
Result = TRUE;
}
else if (Result)
{
if (hProgress)
{
if (hProgress)
{
/* Increment the progress bar */
IncrementProgressBar(hProgress, DEFAULT_STEP);
}
/* Increment the progress bar */
IncrementProgressBar(hProgress, DEFAULT_STEP);
}
/* Start the service */
bRet = StartService(hService,
dwArgsCount,
lpArgsVector);
if (!bRet && GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)
{
/* If it's already running, just return TRUE */
bRet = TRUE;
}
else if (bRet)
{
bRet = FALSE;
/* Get the service status to check if it's running */
Result = QueryServiceStatusEx(hService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ServiceStatus,
sizeof(SERVICE_STATUS_PROCESS),
&BytesNeeded);
if (Result)
{
Result = FALSE;
MaxWait = MAX_WAIT_TIME;
OldCheckPoint = ServiceStatus.dwCheckPoint;
StartTickCount = GetTickCount();
/* Get the service status to check if it's running */
if (QueryServiceStatusEx(hService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ServiceStatus,
sizeof(SERVICE_STATUS_PROCESS),
&BytesNeeded))
/* Loop until it's running */
while (ServiceStatus.dwCurrentState != SERVICE_RUNNING)
{
/* Fixup the wait time */
WaitTime = ServiceStatus.dwWaitHint / 10;
if (WaitTime < 1000) WaitTime = 1000;
else if (WaitTime > 10000) WaitTime = 10000;
/* We don't wanna wait for up to 10 secs without incrementing */
for (int i = WaitTime / 1000; i > 0; i--)
{
/* We don't want to wait for more than 30 seconds */
dwMaxWait = 30000;
dwStartTickCount = GetTickCount();
/* Loop until it's running */
while (ServiceStatus.dwCurrentState != SERVICE_RUNNING)
Sleep(1000);
if (hProgress)
{
dwOldCheckPoint = ServiceStatus.dwCheckPoint;
dwWaitTime = ServiceStatus.dwWaitHint / 10;
/* 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)
{
/* 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)
{
/* We have, give up */
break;
}
}
/* Adjust the wait hint times */
if (dwWaitTime < 200)
dwWaitTime = 200;
else if (dwWaitTime > 10000)
dwWaitTime = 10000;
/* Wait before trying again */
Sleep(dwWaitTime);
/* Increment the progress bar */
IncrementProgressBar(hProgress, DEFAULT_STEP);
}
}
if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
/* Get the latest status info */
if (!QueryServiceStatusEx(hService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ServiceStatus,
sizeof(SERVICE_STATUS_PROCESS),
&BytesNeeded))
{
bRet = TRUE;
/* Something went wrong... */
break;
}
/* Is the service making progress? */
if (ServiceStatus.dwCheckPoint > OldCheckPoint)
{
/* It is, get the latest tickcount to reset the max wait time */
StartTickCount = GetTickCount();
OldCheckPoint = ServiceStatus.dwCheckPoint;
}
else
{
/* It's not, make sure we haven't exceeded our wait time */
if (GetTickCount() >= StartTickCount + MaxWait)
{
/* We have, give up */
break;
}
}
}
CloseServiceHandle(hService);
}
CloseServiceHandle(hSCManager);
if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{
Result = TRUE;
}
}
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
if (lpArgsVector)
LocalFree((LPVOID)lpArgsVector);
return bRet;
}
BOOL
DoStart(PMAIN_WND_INFO Info, LPWSTR lpStartParams)
{
HWND hProgress;
BOOL bRet = FALSE;
/* Create a progress window to track the progress of the stopping service */
hProgress = CreateProgressDialog(Info->hMainWnd,
IDS_PROGRESS_INFO_START);
if (hProgress)
{
/* Set the service name and reset the progress bag */
InitializeProgressDialog(hProgress, Info->pCurrentService->lpServiceName);
/* Start the requested service */
bRet = DoStartService(Info, hProgress, lpStartParams);
/* Complete and destroy the progress bar */
DestroyProgressDialog(hProgress, bRet);
}
return bRet;
return Result;
}

View file

@ -3,223 +3,107 @@
* 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>
* COPYRIGHT: Copyright 2006-2015 Ged Murphy <gedmurphy@reactos.org>
*
*/
#include "precomp.h"
static BOOL
StopService(PMAIN_WND_INFO pInfo,
LPWSTR lpServiceName,
HWND hProgress OPTIONAL)
#define MAX_WAIT_TIME 30000
BOOL
DoStopService(_In_z_ LPWSTR ServiceName,
_In_opt_ HANDLE hProgress)
{
SC_HANDLE hSCManager;
SC_HANDLE hService;
SERVICE_STATUS_PROCESS ServiceStatus;
DWORD dwBytesNeeded;
DWORD dwStartTime;
DWORD dwTimeout;
DWORD BytesNeeded;
DWORD StartTime;
DWORD WaitTime;
DWORD Timeout;
BOOL bRet = FALSE;
hSCManager = OpenSCManagerW(NULL,
NULL,
SC_MANAGER_CONNECT);
if (!hSCManager) return FALSE;
hService = OpenServiceW(hSCManager,
ServiceName,
SERVICE_STOP | SERVICE_QUERY_STATUS);
if (!hService)
{
CloseServiceHandle(hSCManager);
return FALSE;
}
if (hProgress)
{
/* Set the service name and reset the progress bag */
InitializeProgressDialog(hProgress, lpServiceName);
/* Increment the progress bar */
IncrementProgressBar(hProgress, DEFAULT_STEP);
}
hSCManager = OpenSCManager(NULL,
NULL,
SC_MANAGER_CONNECT);
if (hSCManager)
/* Set the start and max wait times */
StartTime = GetTickCount();
Timeout = MAX_WAIT_TIME;
/* Send the service the stop code */
if (ControlService(hService,
SERVICE_CONTROL_STOP,
(LPSERVICE_STATUS)&ServiceStatus))
{
hService = OpenService(hSCManager,
lpServiceName,
SERVICE_STOP | SERVICE_QUERY_STATUS);
if (hService)
if (hProgress)
{
if (hProgress)
{
/* Increment the progress bar */
IncrementProgressBar(hProgress, DEFAULT_STEP);
}
/* Increment the progress bar */
IncrementProgressBar(hProgress, DEFAULT_STEP);
}
/* Set the wait time to 30 secs */
dwStartTime = GetTickCount();
dwTimeout = 30000;
while (ServiceStatus.dwCurrentState != SERVICE_STOPPED)
{
/* Fixup the wait time */
WaitTime = ServiceStatus.dwWaitHint / 10;
/* Send the service the stop code */
if (ControlService(hService,
SERVICE_CONTROL_STOP,
(LPSERVICE_STATUS)&ServiceStatus))
if (WaitTime < 1000) WaitTime = 1000;
else if (WaitTime > 10000) WaitTime = 10000;
/* We don't wanna wait for up to 10 secs without incrementing */
for (int i = WaitTime / 1000; i > 0; i--)
{
Sleep(1000);
if (hProgress)
{
/* Increment the progress bar */
IncrementProgressBar(hProgress, DEFAULT_STEP);
}
}
while (ServiceStatus.dwCurrentState != SERVICE_STOPPED)
if (QueryServiceStatusEx(hService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ServiceStatus,
sizeof(SERVICE_STATUS_PROCESS),
&BytesNeeded))
{
/* Have we exceeded our wait time? */
if (GetTickCount() - StartTime > Timeout)
{
/* 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;
/* Yep, give up */
break;
}
}
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)
/* If the service is stopped, return TRUE */
if (ServiceStatus.dwCurrentState == SERVICE_STOPPED)
{
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);
}
bRet = TRUE;
}
}
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
return bRet;
}

View file

@ -3,12 +3,20 @@
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/mscutils/servman/stop_dependencies.c
* PURPOSE: Routines related to stopping dependent services
* COPYRIGHT: Copyright 2006-2010 Ged Murphy <gedmurphy@reactos.org>
* COPYRIGHT: Copyright 2006-2015 Ged Murphy <gedmurphy@reactos.org>
*
*/
#include "precomp.h"
typedef struct _STOP_DATA
{
LPWSTR ServiceName;
LPWSTR DisplayName;
LPWSTR ServiceList;
} STOP_DATA, *PSTOP_DATA;
static LPWSTR
AddServiceToList(LPWSTR *lpServiceList,
LPWSTR lpServiceToAdd)
@ -46,7 +54,7 @@ AddServiceToList(LPWSTR *lpServiceList,
dwCurSize = 0;
/* Get the list size */
while (TRUE)
for (;;)
{
/* Break when we hit the double null */
if (*ptr == L'\0' && *(ptr + 1) == L'\0')
@ -98,13 +106,6 @@ BuildListOfServicesToStop(LPWSTR *lpServiceList,
if (lpServiceStatus[i].ServiceStatus.dwCurrentState != SERVICE_STOPPED &&
lpServiceStatus[i].ServiceStatus.dwCurrentState != SERVICE_STOP_PENDING)
{
/* Does this service have any dependents? */
if (TV2_HasDependantServices(lpServiceStatus[i].lpServiceName))
{
/* recall this function with the dependent */
BuildListOfServicesToStop(lpServiceList, lpServiceStatus[i].lpServiceName);
}
/* Add the service to the list */
*lpServiceList = AddServiceToList(lpServiceList, lpServiceStatus[i].lpServiceName);
@ -143,7 +144,7 @@ AddServiceNamesToStop(HWND hServiceListBox,
lpStr = lpServiceList;
/* Loop through all the services in the list */
while (TRUE)
for (;;)
{
/* Break when we hit the double null */
if (*lpStr == L'\0' && *(lpStr + 1) == L'\0')
@ -174,117 +175,100 @@ AddServiceNamesToStop(HWND hServiceListBox,
}
static BOOL
DoInitDependsDialog(PMAIN_WND_INFO pInfo,
HWND hDlg)
InitDialog(HWND hDlg,
UINT Message,
WPARAM wParam,
LPARAM lParam)
{
PSTOP_DATA StopData;
HWND hServiceListBox;
LPWSTR lpPartialStr, lpStr;
DWORD fullLen;
HICON hIcon = NULL;
BOOL bRet = FALSE;
if (pInfo)
StopData = (PSTOP_DATA)lParam;
/* Load the icon for the window */
hIcon = (HICON)LoadImageW(hInstance,
MAKEINTRESOURCE(IDI_SM_ICON),
IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CXSMICON),
0);
if (hIcon)
{
/* Tag the info to the window */
SetWindowLongPtrW(hDlg,
GWLP_USERDATA,
(LONG_PTR)pInfo);
/* Load the icon for the window */
hIcon = (HICON)LoadImageW(hInstance,
MAKEINTRESOURCE(IDI_SM_ICON),
IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CXSMICON),
0);
if (hIcon)
{
/* Set it */
SendMessageW(hDlg,
WM_SETICON,
ICON_SMALL,
(LPARAM)hIcon);
DestroyIcon(hIcon);
}
/* Load the stop depends note */
if (AllocAndLoadString(&lpPartialStr,
hInstance,
IDS_STOP_DEPENDS))
{
/* Get the length required */
fullLen = wcslen(lpPartialStr) + wcslen(pInfo->pCurrentService->lpDisplayName) + 1;
lpStr = HeapAlloc(ProcessHeap,
0,
fullLen * sizeof(WCHAR));
if (lpStr)
{
/* Add the service name to the depends note */
_snwprintf(lpStr,
fullLen,
lpPartialStr,
pInfo->pCurrentService->lpDisplayName);
/* Add the string to the dialog */
SendDlgItemMessageW(hDlg,
IDC_STOP_DEPENDS,
WM_SETTEXT,
0,
(LPARAM)lpStr);
HeapFree(ProcessHeap,
0,
lpStr);
bRet = TRUE;
}
LocalFree(lpPartialStr);
}
/* Display the list of services which need stopping */
hServiceListBox = GetDlgItem(hDlg,
IDC_STOP_DEPENDS_LB);
if (hServiceListBox)
{
AddServiceNamesToStop(hServiceListBox,
(LPWSTR)pInfo->pTag);
}
/* Set it */
SendMessageW(hDlg,
WM_SETICON,
ICON_SMALL,
(LPARAM)hIcon);
DestroyIcon(hIcon);
}
/* Load the stop depends note */
if (AllocAndLoadString(&lpPartialStr,
hInstance,
IDS_STOP_DEPENDS))
{
/* Get the length required */
fullLen = wcslen(lpPartialStr) + wcslen(StopData->DisplayName) + 1;
lpStr = HeapAlloc(ProcessHeap,
0,
fullLen * sizeof(WCHAR));
if (lpStr)
{
/* Add the service name to the depends note */
_snwprintf(lpStr,
fullLen,
lpPartialStr,
StopData->DisplayName);
/* Add the string to the dialog */
SendDlgItemMessageW(hDlg,
IDC_STOP_DEPENDS,
WM_SETTEXT,
0,
(LPARAM)lpStr);
HeapFree(ProcessHeap,
0,
lpStr);
bRet = TRUE;
}
LocalFree(lpPartialStr);
}
/* Display the list of services which need stopping */
hServiceListBox = GetDlgItem(hDlg, IDC_STOP_DEPENDS_LB);
if (hServiceListBox)
{
AddServiceNamesToStop(hServiceListBox,
(LPWSTR)StopData->ServiceList);
}
return bRet;
}
INT_PTR CALLBACK
StopDependsDialogProc(HWND hDlg,
UINT message,
UINT Message,
WPARAM wParam,
LPARAM lParam)
{
PMAIN_WND_INFO pInfo = NULL;
/* Get the window context */
pInfo = (PMAIN_WND_INFO)GetWindowLongPtrW(hDlg,
GWLP_USERDATA);
if (pInfo == NULL && message != WM_INITDIALOG)
{
return FALSE;
}
switch (message)
switch (Message)
{
case WM_INITDIALOG:
{
BOOL bRet = FALSE;
pInfo = (PMAIN_WND_INFO)lParam;
if (pInfo != NULL)
{
bRet = DoInitDependsDialog(pInfo, hDlg);
}
return bRet;
return InitDialog(hDlg,
Message,
wParam,
lParam);
}
case WM_COMMAND:
@ -304,3 +288,27 @@ StopDependsDialogProc(HWND hDlg,
return FALSE;
}
BOOL
CreateStopDependsDialog(HWND hParent,
LPWSTR ServiceName,
LPWSTR DisplayName,
LPWSTR ServiceList)
{
STOP_DATA StopData;
INT_PTR Result;
StopData.ServiceName = ServiceName;
StopData.DisplayName = DisplayName;
StopData.ServiceList = ServiceList;
Result = DialogBoxParamW(hInstance,
MAKEINTRESOURCEW(IDD_DLG_DEPEND_STOP),
hParent,
StopDependsDialogProc,
(LPARAM)&StopData);
if (Result == IDOK)
return TRUE;
return FALSE;
}