ReactOS  0.4.11-dev-946-g431643b
progress.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Services
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: base/applications/mscutils/servman/progress.c
5  * PURPOSE: Progress dialog box message handler
6  * COPYRIGHT: Copyright 2006-2015 Ged Murphy <gedmurphy@reactos.org>
7  *
8  */
9 
10 #include "precomp.h"
11 
12 #include <process.h>
13 
14 #define PROGRESS_RANGE 20
15 #define PROGRESS_STEP_MAX 15
16 
17 typedef struct _PROGRESS_DATA
18 {
26 
28 
29 
30 static VOID
33  ULONG LabelId)
34 {
35  LPWSTR lpProgStr;
36 
37  /* Load the label Id */
38  if (AllocAndLoadString(&lpProgStr,
39  hInstance,
40  LabelId))
41  {
42  /* Write it to the dialog */
45  WM_SETTEXT,
46  0,
47  (LPARAM)lpProgStr);
48 
49  LocalFree(lpProgStr);
50  }
51 
52  /* Write the service name to the dialog */
55  WM_SETTEXT,
56  0,
57  (LPARAM)ServiceName);
58 
59  /* Set the progress bar to the start */
62  PBM_SETPOS,
63  0,
64  0);
65 }
66 
67 unsigned int __stdcall ActionThread(void* Param)
68 {
69  PPROGRESS_DATA ProgressData = (PPROGRESS_DATA)Param;
70 
71  if (ProgressData->Action == ACTION_START)
72  {
73  /* Setup the progress dialog for this action */
74  ResetProgressDialog(ProgressData->hDlg,
75  ProgressData->ServiceName,
77 
78  /* Start the service */
79  if (DoStartService(ProgressData->ServiceName,
80  ProgressData->hProgress,
81  ProgressData->Param))
82  {
83  /* We're done, slide the progress bar up to the top */
84  CompleteProgressBar(ProgressData->hProgress);
85  }
86  }
87  else if (ProgressData->Action == ACTION_STOP || ProgressData->Action == ACTION_RESTART)
88  {
89  /* Check if there are and dependants to stop */
90  if (ProgressData->StopDepends && ProgressData->ServiceList)
91  {
92  LPWSTR lpStr = ProgressData->ServiceList;
93 
94  /* Loop through all the services in the list */
95  for (;;)
96  {
97  /* Break when we hit the double null */
98  if (*lpStr == L'\0' && *(lpStr + 1) == L'\0')
99  break;
100 
101  /* If this isn't our first time in the loop we'll
102  have been left on a null char */
103  if (*lpStr == L'\0')
104  lpStr++;
105 
106  ResetProgressDialog(ProgressData->hDlg,
107  lpStr,
109 
110  /* Stop the requested service */
111  if (DoStopService(ProgressData->ServiceName,
112  ProgressData->hProgress))
113  {
114  CompleteProgressBar(ProgressData->hProgress);
115  }
116 
117  /* Move onto the next string */
118  while (*lpStr != L'\0')
119  lpStr++;
120  }
121  }
122 
123  ResetProgressDialog(ProgressData->hDlg,
124  ProgressData->ServiceName,
126 
127  if (DoStopService(ProgressData->ServiceName,
128  ProgressData->hProgress))
129  {
130  CompleteProgressBar(ProgressData->hProgress);
131  }
132 
133 
134  /* If this was a restart, we'll need to start the service back up */
135  if (ProgressData->Action == ACTION_RESTART)
136  {
137  /* Setup the progress dialog for this action */
138  ResetProgressDialog(ProgressData->hDlg,
139  ProgressData->ServiceName,
141 
142  /* Start the service */
143  if (DoStartService(ProgressData->ServiceName,
144  ProgressData->hProgress,
145  NULL))
146  {
147  /* We're done, slide the progress bar up to the top */
148  CompleteProgressBar(ProgressData->hProgress);
149  }
150  }
151  }
152  else if (ProgressData->Action == ACTION_PAUSE)
153  {
154  /* Setup the progress dialog for this action */
155  ResetProgressDialog(ProgressData->hDlg,
156  ProgressData->ServiceName,
158 
159  /* Pause the service */
160  if (DoControlService(ProgressData->ServiceName,
161  ProgressData->hProgress,
163  {
164  /* We're done, slide the progress bar up to the top */
165  CompleteProgressBar(ProgressData->hProgress);
166  }
167  }
168  else if (ProgressData->Action == ACTION_RESUME)
169  {
170  /* Setup the progress dialog for this action */
171  ResetProgressDialog(ProgressData->hDlg,
172  ProgressData->ServiceName,
174 
175  /* resume the service */
176  if (DoControlService(ProgressData->ServiceName,
177  ProgressData->hProgress,
179  {
180  /* We're done, slide the progress bar up to the top */
181  CompleteProgressBar(ProgressData->hProgress);
182  }
183  }
184 
185 
186  EndDialog(ProgressData->hDlg, IDOK);
187 
188  _endthreadex(0);
189  return 0;
190 }
191 
192 static BOOL
194  UINT Message,
195  WPARAM wParam,
196  LPARAM lParam)
197 {
198  PPROGRESS_DATA ProgressData = (PPROGRESS_DATA)lParam;
199  HANDLE hThread;
200 
201  ProgressData->hDlg = hDlg;
202 
203  /* Get a handle to the progress bar */
204  ProgressData->hProgress = GetDlgItem(hDlg,
206  if (!ProgressData->hProgress)
207  return FALSE;
208 
209  /* Set the progress bar range */
210  SendMessageW(ProgressData->hProgress,
211  PBM_SETRANGE,
212  0,
214 
215  /* Set the progress bar step */
216  SendMessageW(ProgressData->hProgress,
217  PBM_SETSTEP,
218  (WPARAM)1,
219  0);
220 
221  /* Create a thread to handle the service control */
222  hThread = (HANDLE)_beginthreadex(NULL, 0, &ActionThread, ProgressData, 0, NULL);
223  if (!hThread) return FALSE;
224 
225  CloseHandle(hThread);
226 
227  return TRUE;
228 }
229 
232  UINT Message,
233  WPARAM wParam,
234  LPARAM lParam)
235 {
236  switch(Message)
237  {
238  case WM_INITDIALOG:
239  {
240  return InitProgressDialog(hDlg, Message, wParam, lParam);
241  }
242 
243  case WM_COMMAND:
244  switch(LOWORD(wParam))
245  {
246  case IDOK:
247  EndDialog(hDlg, wParam);
248  break;
249 
250  }
251  break;
252 
253  default:
254  return FALSE;
255  }
256 
257  return TRUE;
258 }
259 
260 VOID
262 {
263  HWND hProgBar = (HWND)hProgress;
264  UINT Pos = 0;
265 
266  /* Get the current position */
267  Pos = SendMessageW(hProgBar,
268  PBM_GETPOS,
269  0,
270  0);
271 
272  /* Loop until we hit the max */
273  while (Pos <= PROGRESS_RANGE)
274  {
275  /* Increment the progress bar */
276  SendMessageW(hProgBar,
277  PBM_DELTAPOS,
278  Pos,
279  0);
280 
281  /* Wait for 15ms to give it a smooth feel */
282  Sleep(15);
283  Pos++;
284  }
285 }
286 
287 VOID
289  UINT Step)
290 {
291  HWND hProgBar = (HWND)hProgress;
292  UINT Position;
293 
294  /* Don't allow the progress to reach to complete*/
295  Position = SendMessageW(hProgBar,
296  PBM_GETPOS,
297  0,
298  0);
299  if (Position < PROGRESS_STEP_MAX)
300  {
301  /* Do we want to increment the default amount? */
302  if (Step == DEFAULT_STEP)
303  {
304  /* Use the step value we set on create */
305  SendMessageW(hProgBar,
306  PBM_STEPIT,
307  0,
308  0);
309  }
310  else
311  {
312  /* Use the value passed */
313  SendMessageW(hProgBar,
314  PBM_SETPOS,
315  Step,
316  0);
317  }
318  }
319 }
320 
321 BOOL
324  LPWSTR DisplayName,
325  UINT Action,
326  PVOID Param)
327 {
328  PROGRESS_DATA ProgressData;
331  INT_PTR Result;
332 
333  StopDepends = FALSE;
334  ServiceList = NULL;
335 
336 
337  /* Check if we'll be stopping the service */
338  if (Action == ACTION_STOP || Action == ACTION_RESTART)
339  {
340  /* Does the service have any dependent services which need stopping first */
341  ServiceList = GetListOfServicesToStop(ServiceName);
342  if (ServiceList)
343  {
344  /* Ask the user if they want to stop the dependants */
345  StopDepends = CreateStopDependsDialog(hParent,
346  ServiceName,
347  DisplayName,
348  ServiceList);
349 
350  /* Exit early if the user decided not to stop the dependants */
351  if (StopDepends == FALSE)
352  {
353  HeapFree(GetProcessHeap(), 0, ServiceList);
354  return FALSE;
355  }
356  }
357  }
358 
359  ProgressData.hDlg = NULL;
360  ProgressData.ServiceName = ServiceName;
361  ProgressData.Action = Action;
362  ProgressData.StopDepends = StopDepends;
363  ProgressData.ServiceList = ServiceList;
364  ProgressData.Param = Param;
365 
366  Result = DialogBoxParamW(hInstance,
368  hParent,
370  (LPARAM)&ProgressData);
371 
372  if (ServiceList)
373  HeapFree(GetProcessHeap(), 0, ServiceList);
374 
375  return (Result == IDOK);
376 }
BOOL CreateStopDependsDialog(HWND hParent, LPWSTR ServiceName, LPWSTR DisplayName, LPWSTR ServiceList)
#define TRUE
Definition: types.h:120
#define IDOK
Definition: winuser.h:824
#define CloseHandle
Definition: compat.h:398
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
#define IDD_DLG_PROGRESS
Definition: resource.h:205
static VOID ResetProgressDialog(HWND hDlg, LPWSTR ServiceName, ULONG LabelId)
Definition: progress.c:31
INT_PTR WINAPI DialogBoxParamW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
#define IDS_PROGRESS_INFO_RESUME
Definition: resource.h:212
#define ACTION_START
Definition: precomp.h:37
HWND hProgress
Definition: progress.c:20
unsigned int __stdcall ActionThread(void *Param)
Definition: progress.c:67
static COORD Position
Definition: mouse.c:34
BOOL DoStartService(LPWSTR ServiceName, HANDLE hProgress, LPWSTR lpStartParams)
Definition: start.c:15
#define ACTION_STOP
Definition: precomp.h:38
#define MAKELPARAM(l, h)
Definition: winuser.h:3915
static BOOL InitProgressDialog(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam)
Definition: progress.c:193
#define CALLBACK
Definition: compat.h:27
ush Pos
Definition: deflate.h:92
HANDLE HWND
Definition: compat.h:13
INT_PTR CALLBACK ProgressDialogProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam)
Definition: progress.c:231
#define PBM_SETPOS
Definition: commctrl.h:2154
BOOL StopDepends
Definition: progress.c:23
LPWSTR ServiceList
Definition: progress.c:24
int32_t INT_PTR
Definition: typedefs.h:62
_CRTIMP uintptr_t __cdecl _beginthreadex(_In_opt_ void *_Security, _In_ unsigned _StackSize, _In_ unsigned(__stdcall *_StartAddress)(void *), _In_opt_ void *_ArgList, _In_ unsigned _InitFlag, _Out_opt_ unsigned *_ThrdAddr)
static INT AllocAndLoadString(OUT LPTSTR *lpTarget, IN HINSTANCE hInst, IN UINT uID)
Definition: misc.c:60
WPARAM wParam
Definition: combotst.c:138
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
BOOL DoStopService(LPWSTR ServiceName, HANDLE hProgress)
UINT_PTR WPARAM
Definition: windef.h:207
#define PBM_SETRANGE
Definition: commctrl.h:2153
PVOID Param
Definition: progress.c:25
HINSTANCE hInstance
Definition: charmap.c:20
LONG_PTR LPARAM
Definition: windef.h:208
LPWSTR ServiceName
Definition: progress.c:21
_CRTIMP void __cdecl _endthreadex(_In_ unsigned _Retval)
smooth NULL
Definition: ftsmooth.c:416
#define PBM_STEPIT
Definition: commctrl.h:2157
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define IDC_SERVCON_PROGRESS
Definition: resource.h:206
#define ACTION_RESUME
Definition: precomp.h:40
#define PBM_SETSTEP
Definition: commctrl.h:2156
#define WM_SETTEXT
Definition: winuser.h:1599
VOID IncrementProgressBar(HANDLE hProgress, UINT Step)
Definition: progress.c:288
unsigned int BOOL
Definition: ntddk_ex.h:94
#define GetProcessHeap()
Definition: compat.h:395
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
#define IDS_PROGRESS_INFO_STOP
Definition: resource.h:210
unsigned int UINT
Definition: ndis.h:50
struct _PROGRESS_DATA * PPROGRESS_DATA
#define PROGRESS_STEP_MAX
Definition: progress.c:15
PVOID HANDLE
Definition: typedefs.h:71
#define __stdcall
Definition: typedefs.h:25
LRESULT WINAPI SendDlgItemMessageW(_In_ HWND, _In_ int, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
CHAR Message[80]
Definition: alive.c:5
VOID CompleteProgressBar(HANDLE hProgress)
Definition: progress.c:261
#define SERVICE_CONTROL_PAUSE
Definition: winsvc.h:37
static const WCHAR L[]
Definition: oid.c:1087
BOOL RunActionWithProgress(HWND hParent, LPWSTR ServiceName, LPWSTR DisplayName, UINT Action, PVOID Param)
Definition: progress.c:322
const DOCKBAR PVOID HWND hParent
Definition: tooldock.h:22
#define IDC_SERVCON_INFO
Definition: resource.h:207
#define WM_COMMAND
Definition: winuser.h:1716
#define ACTION_PAUSE
Definition: precomp.h:39
struct _PROGRESS_DATA PROGRESS_DATA
#define PBM_DELTAPOS
Definition: commctrl.h:2155
#define DEFAULT_STEP
Definition: precomp.h:108
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define SERVICE_CONTROL_CONTINUE
Definition: winsvc.h:38
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define PROGRESS_RANGE
Definition: progress.c:14
HANDLE hThread
Definition: wizard.c:27
#define IDS_PROGRESS_INFO_START
Definition: resource.h:209
LPWSTR GetListOfServicesToStop(LPWSTR lpServiceName)
#define IDS_PROGRESS_INFO_PAUSE
Definition: resource.h:211
unsigned int ULONG
Definition: retypes.h:1
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define IDC_SERVCON_NAME
Definition: resource.h:208
ULONG Action
Definition: progress.c:22
#define WM_INITDIALOG
Definition: winuser.h:1715
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
BOOL DoControlService(LPWSTR ServiceName, HWND hProgress, DWORD Control)
Definition: control.c:15
#define HeapFree(x, y, z)
Definition: compat.h:394
#define PBM_GETPOS
Definition: commctrl.h:2164
#define ACTION_RESTART
Definition: precomp.h:41