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 } 494