mirror of
https://github.com/reactos/reactos.git
synced 2024-07-11 07:05:12 +00:00
[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:
parent
c783e3db2f
commit
6de5a3ef96
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in a new issue