ReactOS 0.4.15-dev-7907-g95bf896
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
17typedef struct _PROGRESS_DATA
18{
26
28
29VOID 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
49static VOID
52 ULONG LabelId)
53{
54 LPWSTR lpProgStr;
55
56 /* Load the label Id */
57 if (AllocAndLoadString(&lpProgStr,
59 LabelId))
60 {
61 /* Write it to the dialog */
65 0,
66 (LPARAM)lpProgStr);
67
68 LocalFree(lpProgStr);
69 }
70
71 /* Write the service name to the dialog */
75 0,
77
78 /* Set the progress bar to the start */
82 0,
83 0);
84}
85
86unsigned 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
242static BOOL
247{
248 PPROGRESS_DATA ProgressData = (PPROGRESS_DATA)lParam;
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,
262 0,
264
265 /* Set the progress bar step */
266 SendMessageW(ProgressData->hProgress,
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
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
310VOID
312{
313 HWND hProgBar = (HWND)hProgress;
314 UINT Pos = 0;
315
316 /* Get the current position */
317 Pos = SendMessageW(hProgBar,
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,
328 Pos,
329 0);
330
331 /* Wait for 15ms to give it a smooth feel */
332 Sleep(15);
333 Pos++;
334 }
335}
336
337VOID
339 UINT Step)
340{
341 HWND hProgBar = (HWND)hProgress;
343
344 /* Don't allow the progress to reach to complete*/
345 Position = SendMessageW(hProgBar,
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,
357 0,
358 0);
359 }
360 else
361 {
362 /* Use the value passed */
363 SendMessageW(hProgBar,
365 Step,
366 0);
367 }
368 }
369}
370
371BOOL
374 LPWSTR DisplayName,
375 UINT Action,
376 PVOID Param)
377{
378 PROGRESS_DATA ProgressData;
379 LPWSTR ServiceList;
380 BOOL StopDepends;
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 */
392 if (ServiceList)
393 {
394 /* Ask the user if they want to stop the dependants */
395 StopDepends = CreateStopDependsDialog(hParent,
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}
INT AllocAndLoadString(OUT LPTSTR *lpTarget, IN HINSTANCE hInst, IN UINT uID)
Definition: misc.c:59
DWORD DoControlService(LPWSTR ServiceName, HWND hProgress, DWORD Control)
Definition: control.c:18
LPWSTR GetListOfServicesToStop(LPWSTR lpServiceName)
#define ACTION_START
Definition: precomp.h:40
#define ACTION_RESTART
Definition: precomp.h:44
DWORD DoStartService(LPWSTR ServiceName, HANDLE hProgress, LPWSTR lpStartParams)
Definition: start.c:18
#define DEFAULT_STEP
Definition: precomp.h:111
BOOL CreateStopDependsDialog(HWND hParent, LPWSTR ServiceName, LPWSTR DisplayName, LPWSTR ServiceList)
#define ACTION_PAUSE
Definition: precomp.h:42
DWORD DoStopService(LPWSTR ServiceName, HANDLE hProgress)
#define ACTION_STOP
Definition: precomp.h:41
#define ACTION_RESUME
Definition: precomp.h:43
unsigned int __stdcall ActionThread(void *Param)
Definition: progress.c:86
struct _PROGRESS_DATA PROGRESS_DATA
struct _PROGRESS_DATA * PPROGRESS_DATA
static VOID ResetProgressDialog(HWND hDlg, LPWSTR ServiceName, ULONG LabelId)
Definition: progress.c:50
INT_PTR CALLBACK ProgressDialogProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam)
Definition: progress.c:281
VOID ShowError(DWORD dwLastError)
Definition: progress.c:29
BOOL RunActionWithProgress(HWND hParent, LPWSTR ServiceName, LPWSTR DisplayName, UINT Action, PVOID Param)
Definition: progress.c:372
VOID IncrementProgressBar(HANDLE hProgress, UINT Step)
Definition: progress.c:338
#define PROGRESS_STEP_MAX
Definition: progress.c:15
VOID CompleteProgressBar(HANDLE hProgress)
Definition: progress.c:311
#define PROGRESS_RANGE
Definition: progress.c:14
static BOOL InitProgressDialog(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam)
Definition: progress.c:243
#define IDS_PROGRESS_INFO_STOP
Definition: resource.h:208
#define IDD_DLG_PROGRESS
Definition: resource.h:203
#define IDC_SERVCON_INFO
Definition: resource.h:205
#define IDC_SERVCON_NAME
Definition: resource.h:206
#define IDS_PROGRESS_INFO_START
Definition: resource.h:207
#define IDS_PROGRESS_INFO_PAUSE
Definition: resource.h:209
#define IDC_SERVCON_PROGRESS
Definition: resource.h:204
#define IDS_PROGRESS_INFO_RESUME
Definition: resource.h:210
static WCHAR ServiceName[]
Definition: browser.c:19
HINSTANCE hInstance
Definition: charmap.c:19
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
ush Pos
Definition: deflate.h:92
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
HANDLE HWND
Definition: compat.h:19
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
static const WCHAR Message[]
Definition: register.c:74
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
unsigned int UINT
Definition: ndis.h:50
HANDLE hThread
Definition: wizard.c:28
#define L(x)
Definition: ntvdm.h:50
#define LOWORD(l)
Definition: pedump.c:82
#define PBM_SETSTEP
Definition: commctrl.h:2186
#define PBM_GETPOS
Definition: commctrl.h:2194
#define PBM_DELTAPOS
Definition: commctrl.h:2185
#define PBM_SETPOS
Definition: commctrl.h:2184
#define PBM_SETRANGE
Definition: commctrl.h:2183
#define PBM_STEPIT
Definition: commctrl.h:2187
_CRTIMP void __cdecl _endthreadex(_In_ unsigned _Retval)
_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)
LPWSTR ServiceList
Definition: progress.c:24
BOOL StopDepends
Definition: progress.c:23
HWND hProgress
Definition: progress.c:20
ULONG Action
Definition: progress.c:22
PVOID Param
Definition: progress.c:25
LPWSTR ServiceName
Definition: progress.c:21
static COORD Position
Definition: mouse.c:34
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define LANG_USER_DEFAULT
Definition: tnerror.cpp:50
int32_t INT_PTR
Definition: typedefs.h:64
PVOID HANDLE
Definition: typedefs.h:73
#define __stdcall
Definition: typedefs.h:25
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:420
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:423
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:419
LONG_PTR LPARAM
Definition: windef.h:208
UINT_PTR WPARAM
Definition: windef.h:207
#define SERVICE_CONTROL_CONTINUE
Definition: winsvc.h:38
#define SERVICE_CONTROL_PAUSE
Definition: winsvc.h:37
#define MAKELPARAM(l, h)
Definition: winuser.h:4008
#define WM_COMMAND
Definition: winuser.h:1740
#define WM_INITDIALOG
Definition: winuser.h:1739
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
#define IDOK
Definition: winuser.h:830
LRESULT WINAPI SendDlgItemMessageW(_In_ HWND, _In_ int, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define MB_ICONERROR
Definition: winuser.h:787
#define WM_SETTEXT
Definition: winuser.h:1617
#define MB_OK
Definition: winuser.h:790
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
INT_PTR WINAPI DialogBoxParamW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
_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:409
WCHAR * LPWSTR
Definition: xmlstorage.h:184