[SERVMAN]
[reactos.git] / reactos / base / applications / mscutils / servman / propsheet_general.c
1 /*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/mscutils/servman/propsheet_general.c
5 * PURPOSE: Property dialog box message handler
6 * COPYRIGHT: Copyright 2006-2009 Ged Murphy <gedmurphy@reactos.org>
7 *
8 */
9
10 #include "precomp.h"
11
12
13 typedef struct _PAGEDATA
14 {
15 PSERVICEPROPSHEET dlgInfo;
16 BOOL bDisplayNameChanged;
17 BOOL bDescriptionChanged;
18 BOOL bBinaryPathChanged;
19 BOOL bStartTypeChanged;
20 } PAGEDATA, *PPAGEDATA;
21
22
23 static VOID
24 SetButtonStates(PSERVICEPROPSHEET dlgInfo,
25 HWND hwndDlg)
26 {
27 HWND hButton;
28 LPQUERY_SERVICE_CONFIG lpServiceConfig;
29 DWORD Flags, State;
30 UINT i;
31
32 Flags = dlgInfo->pService->ServiceStatusProcess.dwControlsAccepted;
33 State = dlgInfo->pService->ServiceStatusProcess.dwCurrentState;
34
35 for (i = IDC_START; i <= IDC_RESUME; i++)
36 {
37 hButton = GetDlgItem(hwndDlg, i);
38 EnableWindow (hButton, FALSE);
39 }
40
41 lpServiceConfig = GetServiceConfig(dlgInfo->pService->lpServiceName);
42 if (State == SERVICE_STOPPED &&
43 lpServiceConfig && lpServiceConfig->dwStartType != SERVICE_DISABLED)
44 {
45 hButton = GetDlgItem(hwndDlg, IDC_START);
46 EnableWindow (hButton, TRUE);
47 }
48 else if ( (Flags & SERVICE_ACCEPT_STOP) && (State == SERVICE_RUNNING) )
49 {
50 hButton = GetDlgItem(hwndDlg, IDC_STOP);
51 EnableWindow (hButton, TRUE);
52 }
53 else if ( (Flags & SERVICE_ACCEPT_PAUSE_CONTINUE) && (State == SERVICE_RUNNING) )
54 {
55 hButton = GetDlgItem(hwndDlg, IDC_PAUSE);
56 EnableWindow (hButton, TRUE);
57 }
58
59 hButton = GetDlgItem(hwndDlg, IDC_START_PARAM);
60 EnableWindow(hButton, (State == SERVICE_STOPPED && lpServiceConfig && lpServiceConfig->dwStartType != SERVICE_DISABLED));
61
62 if (lpServiceConfig)
63 HeapFree(GetProcessHeap(), 0, lpServiceConfig);
64
65 /* set the main toolbar */
66 SetMenuAndButtonStates(dlgInfo->Info);
67 }
68
69 static VOID
70 SetServiceStatusText(PSERVICEPROPSHEET dlgInfo,
71 HWND hwndDlg)
72 {
73 LPWSTR lpStatus;
74 UINT id;
75
76 if (dlgInfo->pService->ServiceStatusProcess.dwCurrentState == SERVICE_RUNNING)
77 {
78 id = IDS_SERVICES_STARTED;
79 }
80 else
81 {
82 id = IDS_SERVICES_STOPPED;
83 }
84
85 if (AllocAndLoadString(&lpStatus,
86 hInstance,
87 id))
88 {
89 SendDlgItemMessageW(hwndDlg,
90 IDC_SERV_STATUS,
91 WM_SETTEXT,
92 0,
93 (LPARAM)lpStatus);
94 LocalFree(lpStatus);
95 }
96 }
97
98 /*
99 * Fills the 'startup type' combo box with possible
100 * values and sets it to value of the selected item
101 */
102 static VOID
103 SetStartupType(LPWSTR lpServiceName,
104 HWND hwndDlg)
105 {
106 HWND hList;
107 LPQUERY_SERVICE_CONFIG pServiceConfig;
108 LPWSTR lpBuf;
109 DWORD StartUp = 0;
110 UINT i;
111
112 hList = GetDlgItem(hwndDlg, IDC_START_TYPE);
113
114 for (i = IDS_SERVICES_AUTO; i <= IDS_SERVICES_DIS; i++)
115 {
116 if (AllocAndLoadString(&lpBuf,
117 hInstance,
118 i))
119 {
120 SendMessageW(hList,
121 CB_ADDSTRING,
122 0,
123 (LPARAM)lpBuf);
124 LocalFree(lpBuf);
125 }
126 }
127
128 pServiceConfig = GetServiceConfig(lpServiceName);
129
130 if (pServiceConfig)
131 {
132 switch (pServiceConfig->dwStartType)
133 {
134 case SERVICE_AUTO_START: StartUp = 0; break;
135 case SERVICE_DEMAND_START: StartUp = 1; break;
136 case SERVICE_DISABLED: StartUp = 2; break;
137 }
138
139 SendMessageW(hList,
140 CB_SETCURSEL,
141 StartUp,
142 0);
143
144 HeapFree(ProcessHeap,
145 0,
146 pServiceConfig);
147 }
148 }
149
150 /*
151 * Populates the General Properties dialog with
152 * the relevant service information
153 */
154 static VOID
155 InitGeneralPage(PSERVICEPROPSHEET dlgInfo,
156 HWND hwndDlg)
157 {
158 LPQUERY_SERVICE_CONFIG pServiceConfig;
159 LPWSTR lpDescription;
160
161 /* set the service name */
162 SendDlgItemMessageW(hwndDlg,
163 IDC_SERV_NAME,
164 WM_SETTEXT,
165 0,
166 (LPARAM)dlgInfo->pService->lpServiceName);
167
168 /* set the display name */
169 SendDlgItemMessageW(hwndDlg,
170 IDC_DISP_NAME,
171 WM_SETTEXT,
172 0,
173 (LPARAM)dlgInfo->pService->lpDisplayName);
174
175 /* set the description */
176 if ((lpDescription = GetServiceDescription(dlgInfo->pService->lpServiceName)))
177 {
178 SendDlgItemMessageW(hwndDlg,
179 IDC_DESCRIPTION,
180 WM_SETTEXT,
181 0,
182 (LPARAM)lpDescription);
183
184 HeapFree(ProcessHeap,
185 0,
186 lpDescription);
187 }
188
189 pServiceConfig = GetServiceConfig(dlgInfo->pService->lpServiceName);
190 if (pServiceConfig)
191 {
192 SendDlgItemMessageW(hwndDlg,
193 IDC_EXEPATH,
194 WM_SETTEXT,
195 0,
196 (LPARAM)pServiceConfig->lpBinaryPathName);
197 HeapFree(ProcessHeap,
198 0,
199 pServiceConfig);
200 }
201
202
203 /* set startup type */
204 SetStartupType(dlgInfo->pService->lpServiceName, hwndDlg);
205
206 SetServiceStatusText(dlgInfo,
207 hwndDlg);
208
209 if (dlgInfo->Info->bIsUserAnAdmin)
210 {
211 EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), TRUE);
212 }
213 }
214
215 VOID
216 SaveDlgInfo(PPAGEDATA pPageData,
217 HWND hwndDlg)
218 {
219 LPQUERY_SERVICE_CONFIG pServiceConfig = NULL;
220 PWSTR pDisplayName = NULL;
221 PWSTR pDescription;
222 INT nLength;
223 DWORD StartUp;
224
225 pServiceConfig = HeapAlloc(ProcessHeap,
226 HEAP_ZERO_MEMORY,
227 sizeof(*pServiceConfig));
228 if (pServiceConfig)
229 {
230 pServiceConfig->dwServiceType = SERVICE_NO_CHANGE;
231 pServiceConfig->dwErrorControl = SERVICE_NO_CHANGE;
232 pServiceConfig->dwStartType = SERVICE_NO_CHANGE;
233
234 if (pPageData->bStartTypeChanged)
235 {
236 StartUp = SendDlgItemMessageW(hwndDlg, IDC_START_TYPE, CB_GETCURSEL, 0, 0);
237 switch (StartUp)
238 {
239 case 0:
240 pServiceConfig->dwStartType = SERVICE_AUTO_START;
241 break;
242
243 case 1:
244 pServiceConfig->dwStartType = SERVICE_DEMAND_START;
245 break;
246 case 2:
247 pServiceConfig->dwStartType = SERVICE_DISABLED;
248 break;
249 }
250 }
251
252 if (pPageData->bBinaryPathChanged)
253 {
254 nLength = SendDlgItemMessageW(hwndDlg, IDC_EXEPATH, WM_GETTEXTLENGTH, 0, 0);
255 pServiceConfig->lpBinaryPathName = HeapAlloc(ProcessHeap,
256 HEAP_ZERO_MEMORY,
257 (nLength + 1) * sizeof(WCHAR));
258 if (pServiceConfig->lpBinaryPathName != NULL)
259 SendDlgItemMessageW(hwndDlg, IDC_EXEPATH, WM_GETTEXT, nLength + 1, (LPARAM)pServiceConfig->lpBinaryPathName);
260 }
261
262 if (pPageData->bDisplayNameChanged)
263 {
264 nLength = SendDlgItemMessageW(hwndDlg, IDC_DISP_NAME, WM_GETTEXTLENGTH, 0, 0);
265 pDisplayName = HeapAlloc(ProcessHeap,
266 HEAP_ZERO_MEMORY,
267 (nLength + 1) * sizeof(WCHAR));
268 if (pDisplayName != NULL)
269 {
270 SendDlgItemMessageW(hwndDlg, IDC_DISP_NAME, WM_GETTEXT, nLength + 1, (LPARAM)pDisplayName);
271
272 if (pPageData->dlgInfo->pService->lpDisplayName)
273 HeapFree(ProcessHeap, 0, pPageData->dlgInfo->pService->lpDisplayName);
274
275 pPageData->dlgInfo->pService->lpDisplayName = pDisplayName;
276 pServiceConfig->lpDisplayName = pDisplayName;
277 }
278 }
279
280 if (SetServiceConfig(pServiceConfig,
281 pPageData->dlgInfo->pService->lpServiceName,
282 NULL))
283 {
284 if (pPageData->bDisplayNameChanged)
285 ChangeListViewText(pPageData->dlgInfo->Info,
286 pPageData->dlgInfo->pService,
287 LVNAME);
288
289 if (pPageData->bStartTypeChanged)
290 ChangeListViewText(pPageData->dlgInfo->Info,
291 pPageData->dlgInfo->pService,
292 LVSTARTUP);
293 }
294
295 if (pServiceConfig->lpBinaryPathName != NULL)
296 HeapFree(ProcessHeap, 0, pServiceConfig->lpBinaryPathName);
297
298 HeapFree(ProcessHeap, 0, pServiceConfig);
299 }
300
301 if (pPageData->bDescriptionChanged)
302 {
303 nLength = SendDlgItemMessageW(hwndDlg, IDC_DESCRIPTION, WM_GETTEXTLENGTH, 0, 0);
304 pDescription = HeapAlloc(ProcessHeap, HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR));
305 if (pDescription != NULL)
306 {
307 SendDlgItemMessageW(hwndDlg, IDC_DESCRIPTION, WM_GETTEXT, nLength + 1, (LPARAM)pDescription);
308
309 if (SetServiceDescription(pPageData->dlgInfo->pService->lpServiceName,
310 pDescription))
311 {
312 ChangeListViewText(pPageData->dlgInfo->Info,
313 pPageData->dlgInfo->pService,
314 LVDESC);
315 }
316
317 HeapFree(ProcessHeap, 0, pDescription);
318 }
319 }
320 }
321
322 /*
323 * General Property dialog callback.
324 * Controls messages to the General dialog
325 */
326 INT_PTR CALLBACK
327 GeneralPageProc(HWND hwndDlg,
328 UINT uMsg,
329 WPARAM wParam,
330 LPARAM lParam)
331 {
332 PPAGEDATA pPageData;
333
334 /* Get the window context */
335 pPageData = (PPAGEDATA)GetWindowLongPtr(hwndDlg,
336 GWLP_USERDATA);
337 if (pPageData == NULL && uMsg != WM_INITDIALOG)
338 {
339 return FALSE;
340 }
341
342 switch (uMsg)
343 {
344 case WM_INITDIALOG:
345 pPageData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PAGEDATA));
346 if (pPageData != NULL)
347 {
348 SetWindowLongPtr(hwndDlg,
349 GWLP_USERDATA,
350 (LONG_PTR)pPageData);
351
352 pPageData->dlgInfo = (PSERVICEPROPSHEET)(((LPPROPSHEETPAGE)lParam)->lParam);
353 if (pPageData->dlgInfo != NULL)
354 {
355 InitGeneralPage(pPageData->dlgInfo, hwndDlg);
356 SetButtonStates(pPageData->dlgInfo, hwndDlg);
357 }
358 }
359 break;
360
361 case WM_DESTROY:
362 HeapFree(GetProcessHeap(), 0, pPageData);
363 break;
364
365 case WM_COMMAND:
366 switch(LOWORD(wParam))
367 {
368 case IDC_START_TYPE:
369 if (HIWORD(wParam) == CBN_SELCHANGE)
370 {
371 pPageData->bStartTypeChanged = TRUE;
372 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
373 }
374 break;
375
376 case IDC_DISP_NAME:
377 if (HIWORD(wParam) == EN_CHANGE)
378 {
379 pPageData->bDisplayNameChanged = TRUE;
380 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
381 }
382 break;
383
384 case IDC_DESCRIPTION:
385 if (HIWORD(wParam) == EN_CHANGE)
386 {
387 pPageData->bDescriptionChanged = TRUE;
388 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
389 }
390 break;
391
392 case IDC_EXEPATH:
393 if (HIWORD(wParam) == EN_CHANGE)
394 {
395 pPageData->bBinaryPathChanged = TRUE;
396 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
397 }
398 break;
399
400 case IDC_START:
401 {
402 WCHAR szStartParams[256];
403 LPWSTR lpStartParams = NULL;
404
405 if (GetDlgItemText(hwndDlg, IDC_START_PARAM, szStartParams, 256) > 0)
406 lpStartParams = szStartParams;
407
408 EnableWindow(GetDlgItem(hwndDlg, IDC_START_PARAM), FALSE);
409
410 RunActionWithProgress(hwndDlg,
411 pPageData->dlgInfo->pService->lpServiceName,
412 pPageData->dlgInfo->pService->lpDisplayName,
413 ACTION_START,
414 lpStartParams);
415
416 UpdateServiceStatus(pPageData->dlgInfo->pService);
417 ChangeListViewText(pPageData->dlgInfo->Info, pPageData->dlgInfo->pService, LVSTATUS);
418 SetButtonStates(pPageData->dlgInfo, hwndDlg);
419 SetServiceStatusText(pPageData->dlgInfo, hwndDlg);
420 break;
421 }
422
423 case IDC_STOP:
424 RunActionWithProgress(hwndDlg,
425 pPageData->dlgInfo->pService->lpServiceName,
426 pPageData->dlgInfo->pService->lpDisplayName,
427 ACTION_STOP,
428 NULL);
429
430 UpdateServiceStatus(pPageData->dlgInfo->pService);
431 ChangeListViewText(pPageData->dlgInfo->Info, pPageData->dlgInfo->pService, LVSTATUS);
432 SetButtonStates(pPageData->dlgInfo, hwndDlg);
433 SetServiceStatusText(pPageData->dlgInfo, hwndDlg);
434 break;
435
436 case IDC_PAUSE:
437 RunActionWithProgress(hwndDlg,
438 pPageData->dlgInfo->pService->lpServiceName,
439 pPageData->dlgInfo->pService->lpDisplayName,
440 ACTION_PAUSE,
441 NULL);
442
443 UpdateServiceStatus(pPageData->dlgInfo->pService);
444 ChangeListViewText(pPageData->dlgInfo->Info, pPageData->dlgInfo->pService, LVSTATUS);
445 SetButtonStates(pPageData->dlgInfo, hwndDlg);
446 SetServiceStatusText(pPageData->dlgInfo, hwndDlg);
447 break;
448
449 case IDC_RESUME:
450 RunActionWithProgress(hwndDlg,
451 pPageData->dlgInfo->pService->lpServiceName,
452 pPageData->dlgInfo->pService->lpDisplayName,
453 ACTION_RESUME,
454 NULL);
455
456 UpdateServiceStatus(pPageData->dlgInfo->pService);
457 ChangeListViewText(pPageData->dlgInfo->Info, pPageData->dlgInfo->pService, LVSTATUS);
458 SetButtonStates(pPageData->dlgInfo, hwndDlg);
459 SetServiceStatusText(pPageData->dlgInfo, hwndDlg);
460 break;
461
462 case IDC_EDIT:
463 SendDlgItemMessage(hwndDlg, IDC_DISP_NAME, EM_SETREADONLY, FALSE, 0);
464 SendDlgItemMessage(hwndDlg, IDC_DESCRIPTION, EM_SETREADONLY, FALSE, 0);
465 SendDlgItemMessage(hwndDlg, IDC_EXEPATH, EM_SETREADONLY, FALSE, 0);
466 EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), FALSE);
467 break;
468 }
469 break;
470
471 case WM_NOTIFY:
472 switch (((LPNMHDR)lParam)->code)
473 {
474 case PSN_APPLY:
475 if (pPageData->bDisplayNameChanged ||
476 pPageData->bDescriptionChanged ||
477 pPageData->bBinaryPathChanged ||
478 pPageData->bStartTypeChanged)
479 {
480 SaveDlgInfo(pPageData, hwndDlg);
481 SetButtonStates(pPageData->dlgInfo, hwndDlg);
482 pPageData->bDisplayNameChanged = FALSE;
483 pPageData->bDescriptionChanged = FALSE;
484 pPageData->bBinaryPathChanged = FALSE;
485 pPageData->bStartTypeChanged = FALSE;
486 }
487 break;
488 }
489 break;
490 }
491
492 return FALSE;
493 }