ReactOS  0.4.15-dev-1150-g593bcce
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 VOID ShowError(DWORD dwLastError)
30 {
31  LPWSTR lpMsg;
32 
36  NULL,
37  dwLastError,
39  (LPWSTR)&lpMsg,
40  0, NULL))
41  {
42  return;
43  }
44 
46  LocalFree(lpMsg);
47 }
48 
49 static VOID
52  ULONG LabelId)
53 {
54  LPWSTR lpProgStr;
55 
56  /* Load the label Id */
57  if (AllocAndLoadString(&lpProgStr,
58  hInstance,
59  LabelId))
60  {
61  /* Write it to the dialog */
64  WM_SETTEXT,
65  0,
66  (LPARAM)lpProgStr);
67 
68  LocalFree(lpProgStr);
69  }
70 
71  /* Write the service name to the dialog */
74  WM_SETTEXT,
75  0,
77 
78  /* Set the progress bar to the start */
81  PBM_SETPOS,
82  0,
83  0);
84 }
85 
86 unsigned int __stdcall ActionThread(void* Param)
87 {
88  PPROGRESS_DATA ProgressData = (PPROGRESS_DATA)Param;
89  DWORD dwResult;
90 
91  if (ProgressData->Action == ACTION_START)
92  {
93  /* Setup the progress dialog for this action */
94  ResetProgressDialog(ProgressData->hDlg,
95  ProgressData->ServiceName,
97 
98  /* Start the service */
99  dwResult = DoStartService(ProgressData->ServiceName,
100  ProgressData->hProgress,
101  ProgressData->Param);
102  if (dwResult == ERROR_SUCCESS)
103  {
104  /* We're done, slide the progress bar up to the top */
105  CompleteProgressBar(ProgressData->hProgress);
106  }
107  else
108  {
109  ShowError(dwResult);
110  }
111  }
112  else if (ProgressData->Action == ACTION_STOP || ProgressData->Action == ACTION_RESTART)
113  {
114  /* Check if there are and dependants to stop */
115  if (ProgressData->StopDepends && ProgressData->ServiceList)
116  {
117  LPWSTR lpStr = ProgressData->ServiceList;
118 
119  /* Loop through all the services in the list */
120  for (;;)
121  {
122  /* Break when we hit the double null */
123  if (*lpStr == L'\0' && *(lpStr + 1) == L'\0')
124  break;
125 
126  /* If this isn't our first time in the loop we'll
127  have been left on a null char */
128  if (*lpStr == L'\0')
129  lpStr++;
130 
131  ResetProgressDialog(ProgressData->hDlg,
132  lpStr,
134 
135  /* Stop the requested service */
136  dwResult = DoStopService(ProgressData->ServiceName,
137  ProgressData->hProgress);
138  if (dwResult == ERROR_SUCCESS)
139  {
140  CompleteProgressBar(ProgressData->hProgress);
141  }
142  else
143  {
144  ShowError(dwResult);
145  }
146 
147  /* Move onto the next string */
148  while (*lpStr != L'\0')
149  lpStr++;
150  }
151  }
152 
153  ResetProgressDialog(ProgressData->hDlg,
154  ProgressData->ServiceName,
156 
157  dwResult = DoStopService(ProgressData->ServiceName,
158  ProgressData->hProgress);
159  if (dwResult == ERROR_SUCCESS)
160  {
161  CompleteProgressBar(ProgressData->hProgress);
162  }
163  else
164  {
165  ShowError(dwResult);
166  }
167 
168 
169  /* If this was a restart, we'll need to start the service back up */
170  if (ProgressData->Action == ACTION_RESTART)
171  {
172  /* Setup the progress dialog for this action */
173  ResetProgressDialog(ProgressData->hDlg,
174  ProgressData->ServiceName,
176 
177  /* Start the service */
178  dwResult = DoStartService(ProgressData->ServiceName,
179  ProgressData->hProgress,
180  NULL);
181  if (dwResult == ERROR_SUCCESS)
182  {
183  /* We're done, slide the progress bar up to the top */
184  CompleteProgressBar(ProgressData->hProgress);
185  }
186  else
187  {
188  ShowError(dwResult);
189  }
190  }
191  }
192  else if (ProgressData->Action == ACTION_PAUSE)
193  {
194  /* Setup the progress dialog for this action */
195  ResetProgressDialog(ProgressData->hDlg,
196  ProgressData->ServiceName,
198 
199  /* Pause the service */
200  dwResult = DoControlService(ProgressData->ServiceName,
201  ProgressData->hProgress,
203  if (dwResult == ERROR_SUCCESS)
204  {
205  /* We're done, slide the progress bar up to the top */
206  CompleteProgressBar(ProgressData->hProgress);
207  }
208  else
209  {
210  ShowError(dwResult);
211  }
212  }
213  else if (ProgressData->Action == ACTION_RESUME)
214  {
215  /* Setup the progress dialog for this action */
216  ResetProgressDialog(ProgressData->hDlg,
217  ProgressData->ServiceName,
219 
220  /* resume the service */
221  dwResult = DoControlService(ProgressData->ServiceName,
222  ProgressData->hProgress,
224  if (dwResult == ERROR_SUCCESS)
225  {
226  /* We're done, slide the progress bar up to the top */
227  CompleteProgressBar(ProgressData->hProgress);
228  }
229  else
230  {
231  ShowError(dwResult);
232  }
233  }
234 
235 
236  EndDialog(ProgressData->hDlg, IDOK);
237 
238  _endthreadex(0);
239  return 0;
240 }
241 
242 static BOOL
244  UINT Message,
245  WPARAM wParam,
246  LPARAM lParam)
247 {
248  PPROGRESS_DATA ProgressData = (PPROGRESS_DATA)lParam;
249  HANDLE hThread;
250 
251  ProgressData->hDlg = hDlg;
252 
253  /* Get a handle to the progress bar */
254  ProgressData->hProgress = GetDlgItem(hDlg,
256  if (!ProgressData->hProgress)
257  return FALSE;
258 
259  /* Set the progress bar range */
260  SendMessageW(ProgressData->hProgress,
261  PBM_SETRANGE,
262  0,
264 
265  /* Set the progress bar step */
266  SendMessageW(ProgressData->hProgress,
267  PBM_SETSTEP,
268  (WPARAM)1,
269  0);
270 
271  /* Create a thread to handle the service control */
272  hThread = (HANDLE)_beginthreadex(NULL, 0, &ActionThread, ProgressData, 0, NULL);
273  if (!hThread) return FALSE;
274 
276 
277  return TRUE;
278 }
279 
282  UINT Message,
283  WPARAM wParam,
284  LPARAM lParam)
285 {
286  switch(Message)
287  {
288  case WM_INITDIALOG:
289  {
290  return InitProgressDialog(hDlg, Message, wParam, lParam);
291  }
292 
293  case WM_COMMAND:
294  switch(LOWORD(wParam))
295  {
296  case IDOK:
297  EndDialog(hDlg, wParam);
298  break;
299 
300  }
301  break;
302 
303  default:
304  return FALSE;
305  }
306 
307  return TRUE;
308 }
309 
310 VOID
312 {
313  HWND hProgBar = (HWND)hProgress;
314  UINT Pos = 0;
315 
316  /* Get the current position */
317  Pos = SendMessageW(hProgBar,
318  PBM_GETPOS,
319  0,
320  0);
321 
322  /* Loop until we hit the max */
323  while (Pos <= PROGRESS_RANGE)
324  {
325  /* Increment the progress bar */
326  SendMessageW(hProgBar,
327  PBM_DELTAPOS,
328  Pos,
329  0);
330 
331  /* Wait for 15ms to give it a smooth feel */
332  Sleep(15);
333  Pos++;
334  }
335 }
336 
337 VOID
339  UINT Step)
340 {
341  HWND hProgBar = (HWND)hProgress;
342  UINT Position;
343 
344  /* Don't allow the progress to reach to complete*/
345  Position = SendMessageW(hProgBar,
346  PBM_GETPOS,
347  0,
348  0);
350  {
351  /* Do we want to increment the default amount? */
352  if (Step == DEFAULT_STEP)
353  {
354  /* Use the step value we set on create */
355  SendMessageW(hProgBar,
356  PBM_STEPIT,
357  0,
358  0);
359  }
360  else
361  {
362  /* Use the value passed */
363  SendMessageW(hProgBar,
364  PBM_SETPOS,
365  Step,
366  0);
367  }
368  }
369 }
370 
371 BOOL
374  LPWSTR DisplayName,
375  UINT Action,
376  PVOID Param)
377 {
378  PROGRESS_DATA ProgressData;
379  LPWSTR ServiceList;
380  BOOL StopDepends;
381  INT_PTR Result;
382 
383  StopDepends = FALSE;
384  ServiceList = NULL;
385 
386 
387  /* Check if we'll be stopping the service */
389  {
390  /* Does the service have any dependent services which need stopping first */
391  ServiceList = GetListOfServicesToStop(ServiceName);
392  if (ServiceList)
393  {
394  /* Ask the user if they want to stop the dependants */
395  StopDepends = CreateStopDependsDialog(hParent,
396  ServiceName,
397  DisplayName,
398  ServiceList);
399 
400  /* Exit early if the user decided not to stop the dependants */
401  if (StopDepends == FALSE)
402  {
403  HeapFree(GetProcessHeap(), 0, ServiceList);
404  return FALSE;
405  }
406  }
407  }
408 
409  ProgressData.hDlg = NULL;
410  ProgressData.ServiceName = ServiceName;
411  ProgressData.Action = Action;
412  ProgressData.StopDepends = StopDepends;
413  ProgressData.ServiceList = ServiceList;
414  ProgressData.Param = Param;
415 
418  hParent,
420  (LPARAM)&ProgressData);
421 
422  if (ServiceList)
423  HeapFree(GetProcessHeap(), 0, ServiceList);
424 
425  return (Result == IDOK);
426 }
BOOL CreateStopDependsDialog(HWND hParent, LPWSTR ServiceName, LPWSTR DisplayName, LPWSTR ServiceList)
#define IDOK
Definition: winuser.h:824
#define CloseHandle
Definition: compat.h:487
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define IDD_DLG_PROGRESS
Definition: resource.h:203
static VOID ResetProgressDialog(HWND hDlg, LPWSTR ServiceName, ULONG LabelId)
Definition: progress.c:50
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:210
#define ERROR_SUCCESS
Definition: deptool.c:10
#define ACTION_START
Definition: precomp.h:39
#define TRUE
Definition: types.h:120
DWORD DoStartService(LPWSTR ServiceName, HANDLE hProgress, LPWSTR lpStartParams)
Definition: start.c:18
HWND hProgress
Definition: progress.c:20
unsigned int __stdcall ActionThread(void *Param)
Definition: progress.c:86
static COORD Position
Definition: mouse.c:34
#define ACTION_STOP
Definition: precomp.h:40
#define MAKELPARAM(l, h)
Definition: winuser.h:3983
static BOOL InitProgressDialog(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam)
Definition: progress.c:243
#define CALLBACK
Definition: compat.h:35
ush Pos
Definition: deflate.h:92
HANDLE HWND
Definition: compat.h:19
INT_PTR CALLBACK ProgressDialogProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam)
Definition: progress.c:281
#define PBM_SETPOS
Definition: commctrl.h:2180
UINT_PTR WPARAM
Definition: windef.h:207
BOOL StopDepends
Definition: progress.c:23
LPWSTR ServiceList
Definition: progress.c:24
int32_t INT_PTR
Definition: typedefs.h:64
_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
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
WPARAM wParam
Definition: combotst.c:138
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
DWORD DoStopService(LPWSTR ServiceName, HANDLE hProgress)
#define PBM_SETRANGE
Definition: commctrl.h:2179
PVOID Param
Definition: progress.c:25
HINSTANCE hInstance
Definition: charmap.c:20
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:400
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:2183
_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
LONG_PTR LPARAM
Definition: windef.h:208
#define IDC_SERVCON_PROGRESS
Definition: resource.h:204
#define ACTION_RESUME
Definition: precomp.h:42
VOID ShowError(DWORD dwLastError)
Definition: progress.c:29
#define PBM_SETSTEP
Definition: commctrl.h:2182
#define WM_SETTEXT
Definition: winuser.h:1599
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:404
VOID IncrementProgressBar(HANDLE hProgress, UINT Step)
Definition: progress.c:338
DWORD DoControlService(LPWSTR ServiceName, HWND hProgress, DWORD Control)
Definition: control.c:18
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define GetProcessHeap()
Definition: compat.h:484
int WINAPI MessageBoxW(_In_opt_ HWND, _In_opt_ LPCWSTR, _In_opt_ LPCWSTR, _In_ UINT)
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
#define IDS_PROGRESS_INFO_STOP
Definition: resource.h:208
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING _In_opt_ PSTRING _In_ ULONG _In_ ULONG Action
Definition: fsrtlfuncs.h:738
struct _PROGRESS_DATA * PPROGRESS_DATA
#define PROGRESS_STEP_MAX
Definition: progress.c:15
PVOID HANDLE
Definition: typedefs.h:73
unsigned long DWORD
Definition: ntddk_ex.h:95
#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:311
#define SERVICE_CONTROL_PAUSE
Definition: winsvc.h:37
static const WCHAR L[]
Definition: oid.c:1250
BOOL RunActionWithProgress(HWND hParent, LPWSTR ServiceName, LPWSTR DisplayName, UINT Action, PVOID Param)
Definition: progress.c:372
#define MB_ICONERROR
Definition: winuser.h:781
const DOCKBAR PVOID HWND hParent
Definition: tooldock.h:22
#define IDC_SERVCON_INFO
Definition: resource.h:205
#define WM_COMMAND
Definition: winuser.h:1722
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:401
#define ACTION_PAUSE
Definition: precomp.h:41
struct _PROGRESS_DATA PROGRESS_DATA
#define PBM_DELTAPOS
Definition: commctrl.h:2181
#define DEFAULT_STEP
Definition: precomp.h:110
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
unsigned int UINT
Definition: ndis.h:50
#define MB_OK
Definition: winuser.h:784
HANDLE hThread
Definition: wizard.c:27
#define IDS_PROGRESS_INFO_START
Definition: resource.h:207
LPWSTR GetListOfServicesToStop(LPWSTR lpServiceName)
#define IDS_PROGRESS_INFO_PAUSE
Definition: resource.h:209
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:206
ULONG Action
Definition: progress.c:22
#define WM_INITDIALOG
Definition: winuser.h:1721
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
#define HeapFree(x, y, z)
Definition: compat.h:483
#define PBM_GETPOS
Definition: commctrl.h:2190
#define ACTION_RESTART
Definition: precomp.h:43
#define LANG_USER_DEFAULT
Definition: tnerror.cpp:50