Improve swedish translations and add new translations to swedish.
[reactos.git] / base / applications / mscutils / servman / progress.c
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 {
19 HWND hDlg;
20 HWND hProgress;
21 LPWSTR ServiceName;
22 ULONG Action;
23 BOOL StopDepends;
24 LPWSTR ServiceList;
25 PVOID Param;
26
27 } PROGRESS_DATA, *PPROGRESS_DATA;
28
29
30 static VOID
31 ResetProgressDialog(HWND hDlg,
32 LPWSTR ServiceName,
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 */
43 SendDlgItemMessageW(hDlg,
44 IDC_SERVCON_INFO,
45 WM_SETTEXT,
46 0,
47 (LPARAM)lpProgStr);
48
49 LocalFree(lpProgStr);
50 }
51
52 /* Write the service name to the dialog */
53 SendDlgItemMessageW(hDlg,
54 IDC_SERVCON_NAME,
55 WM_SETTEXT,
56 0,
57 (LPARAM)ServiceName);
58
59 /* Set the progress bar to the start */
60 SendDlgItemMessageW(hDlg,
61 IDC_SERVCON_PROGRESS,
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,
76 IDS_PROGRESS_INFO_START);
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,
108 IDS_PROGRESS_INFO_STOP);
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,
125 IDS_PROGRESS_INFO_STOP);
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,
140 IDS_PROGRESS_INFO_START);
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,
157 IDS_PROGRESS_INFO_PAUSE);
158
159 /* Pause the service */
160 if (DoControlService(ProgressData->ServiceName,
161 ProgressData->hProgress,
162 SERVICE_CONTROL_PAUSE))
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,
173 IDS_PROGRESS_INFO_RESUME);
174
175 /* resume the service */
176 if (DoControlService(ProgressData->ServiceName,
177 ProgressData->hProgress,
178 SERVICE_CONTROL_CONTINUE))
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
193 InitProgressDialog(HWND hDlg,
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,
205 IDC_SERVCON_PROGRESS);
206 if (!ProgressData->hProgress)
207 return FALSE;
208
209 /* Set the progress bar range */
210 SendMessageW(ProgressData->hProgress,
211 PBM_SETRANGE,
212 0,
213 MAKELPARAM(0, PROGRESS_RANGE));
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
230 INT_PTR CALLBACK
231 ProgressDialogProc(HWND hDlg,
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
261 CompleteProgressBar(HANDLE hProgress)
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
288 IncrementProgressBar(HANDLE hProgress,
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
322 RunActionWithProgress(HWND hParent,
323 LPWSTR ServiceName,
324 LPWSTR DisplayName,
325 UINT Action,
326 PVOID Param)
327 {
328 PROGRESS_DATA ProgressData;
329 LPWSTR ServiceList;
330 BOOL StopDepends;
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,
367 MAKEINTRESOURCEW(IDD_DLG_PROGRESS),
368 hParent,
369 ProgressDialogProc,
370 (LPARAM)&ProgressData);
371
372 if (ServiceList)
373 HeapFree(GetProcessHeap(), 0, ServiceList);
374
375 return (Result == IDOK);
376 }