diff --git a/reactos/base/applications/mscutils/servman/control.c b/reactos/base/applications/mscutils/servman/control.c index 88e470658e5..41fac161aef 100644 --- a/reactos/base/applications/mscutils/servman/control.c +++ b/reactos/base/applications/mscutils/servman/control.c @@ -121,10 +121,11 @@ BOOL DoPause(PMAIN_WND_INFO Info) HWND hProgDlg; hProgDlg = CreateProgressDialog(Info->hMainWnd, - Info->pCurrentService->lpServiceName, IDS_PROGRESS_INFO_PAUSE); if (hProgDlg) { + InitializeProgressDialog(hProgDlg, Info->pCurrentService->lpServiceName); + ret = Control(Info, hProgDlg, SERVICE_CONTROL_PAUSE); @@ -142,10 +143,11 @@ BOOL DoResume(PMAIN_WND_INFO Info) HWND hProgDlg; hProgDlg = CreateProgressDialog(Info->hMainWnd, - Info->pCurrentService->lpServiceName, IDS_PROGRESS_INFO_RESUME); if (hProgDlg) { + InitializeProgressDialog(hProgDlg, Info->pCurrentService->lpServiceName); + ret = Control(Info, hProgDlg, SERVICE_CONTROL_CONTINUE); diff --git a/reactos/base/applications/mscutils/servman/precomp.h b/reactos/base/applications/mscutils/servman/precomp.h index 9edc653b566..3948aa6d20b 100644 --- a/reactos/base/applications/mscutils/servman/precomp.h +++ b/reactos/base/applications/mscutils/servman/precomp.h @@ -97,8 +97,9 @@ BOOL DoResume(PMAIN_WND_INFO Info); /* progress.c */ #define DEFAULT_STEP 0 -HWND CreateProgressDialog(HWND hParent, LPTSTR lpServiceName, UINT LabelId); +HWND CreateProgressDialog(HWND hParent, UINT LabelId); BOOL DestroyProgressDialog(HWND hProgDlg, BOOL bComplete); +VOID InitializeProgressDialog(HWND hProgDlg, LPWSTR lpServiceName); VOID IncrementProgressBar(HWND hProgDlg, UINT NewPos); VOID CompleteProgressBar(HWND hProgDlg); diff --git a/reactos/base/applications/mscutils/servman/progress.c b/reactos/base/applications/mscutils/servman/progress.c index 05063ce0c70..06f4fed6c2d 100644 --- a/reactos/base/applications/mscutils/servman/progress.c +++ b/reactos/base/applications/mscutils/servman/progress.c @@ -75,6 +75,25 @@ IncrementProgressBar(HWND hProgDlg, } } +VOID +InitializeProgressDialog(HWND hProgDlg, + LPWSTR lpServiceName) +{ + /* Write the service name to the dialog */ + SendDlgItemMessageW(hProgDlg, + IDC_SERVCON_NAME, + WM_SETTEXT, + 0, + (LPARAM)lpServiceName); + + /* Set the progress bar to the start */ + SendDlgItemMessageW(hProgDlg, + IDC_SERVCON_PROGRESS, + PBM_SETPOS, + 0, + 0); +} + INT_PTR CALLBACK ProgressDialogProc(HWND hDlg, UINT Message, @@ -124,7 +143,6 @@ ProgressDialogProc(HWND hDlg, HWND CreateProgressDialog(HWND hParent, - LPTSTR lpServiceName, UINT LabelId) { HWND hProgDlg; @@ -153,13 +171,6 @@ CreateProgressDialog(HWND hParent, 0, lpProgStr); } - - /* Write the service name to the dialog */ - SendDlgItemMessageW(hProgDlg, - IDC_SERVCON_NAME, - WM_SETTEXT, - 0, - (LPARAM)lpServiceName); } return hProgDlg; diff --git a/reactos/base/applications/mscutils/servman/start.c b/reactos/base/applications/mscutils/servman/start.c index 0f051f23340..88f5c0a3885 100644 --- a/reactos/base/applications/mscutils/servman/start.c +++ b/reactos/base/applications/mscutils/servman/start.c @@ -116,12 +116,11 @@ DoStart(PMAIN_WND_INFO Info) BOOL bRet = FALSE; hProgDlg = CreateProgressDialog(Info->hMainWnd, - Info->pCurrentService->lpServiceName, IDS_PROGRESS_INFO_START); if (hProgDlg) { - IncrementProgressBar(hProgDlg, DEFAULT_STEP); + InitializeProgressDialog(hProgDlg, Info->pCurrentService->lpServiceName); bRet = DoStartService(Info, hProgDlg); diff --git a/reactos/base/applications/mscutils/servman/stop.c b/reactos/base/applications/mscutils/servman/stop.c index fe8980c6c3a..327abcbb659 100644 --- a/reactos/base/applications/mscutils/servman/stop.c +++ b/reactos/base/applications/mscutils/servman/stop.c @@ -25,8 +25,8 @@ StopService(PMAIN_WND_INFO pInfo, if (hProgress) { - /* Increment the progress bar */ - IncrementProgressBar(hProgress, DEFAULT_STEP); + /* Set the service name and reset the progress bag */ + InitializeProgressDialog(hProgress, lpServiceName); } hSCManager = OpenSCManager(NULL, @@ -62,6 +62,10 @@ StopService(PMAIN_WND_INFO pInfo, while (ServiceStatus.dwCurrentState != SERVICE_STOPPED) { + /* Don't sleep for more than 3 seconds */ + if (ServiceStatus.dwWaitHint > 3000) + ServiceStatus.dwWaitHint = 3000; + Sleep(ServiceStatus.dwWaitHint); if (hProgress) @@ -103,11 +107,41 @@ StopService(PMAIN_WND_INFO pInfo, static BOOL StopDependantServices(PMAIN_WND_INFO pInfo, - LPWSTR lpServiceName) + LPWSTR lpServiceList, + HWND hProgress OPTIONAL) { + LPWSTR lpStr; BOOL bRet = FALSE; - MessageBox(NULL, L"Rewrite StopDependentServices", NULL, 0); + lpStr = lpServiceList; + + /* Loop through all the services in the list */ + while (TRUE) + { + /* Break when we hit the double null */ + if (*lpStr == L'\0' && *(lpStr + 1) == L'\0') + break; + + /* If this isn't our first time in the loop we'll + have been left on a null char */ + if (*lpStr == L'\0') + lpStr++; + + /* Stop the requested service */ + bRet = StopService(pInfo, + lpStr, + hProgress); + + /* Complete the progress bar if we succeeded */ + if (bRet) + { + CompleteProgressBar(hProgress); + } + + /* Move onto the next string */ + while (*lpStr != L'\0') + lpStr++; + } return bRet; } @@ -119,43 +153,57 @@ DoStop(PMAIN_WND_INFO pInfo) HWND hProgress; LPWSTR lpServiceList; BOOL bRet = FALSE; - BOOL bStop = TRUE; + BOOL bStopMainService = TRUE; if (pInfo) { - /* Does this service have anything which depends on it? */ - if (TV2_HasDependantServices(pInfo->pCurrentService->lpServiceName)) + /* Does the service have any dependent services which need stopping first */ + lpServiceList = GetListOfServicesToStop(pInfo->pCurrentService->lpServiceName); + if (lpServiceList) { - /* It does, get a list of all the services which need stopping */ - lpServiceList = GetListOfServicesToStop(pInfo->pCurrentService->lpServiceName); - if (lpServiceList) - { - /* Tag the service list to the main wnd info */ - pInfo->pTag = (PVOID)lpServiceList; + /* Tag the service list to the main wnd info */ + pInfo->pTag = (PVOID)lpServiceList; - /* List them and ask the user if they want to stop them */ - if (DialogBoxParamW(hInstance, - MAKEINTRESOURCEW(IDD_DLG_DEPEND_STOP), - pInfo->hMainWnd, - StopDependsDialogProc, - (LPARAM)pInfo) == IDOK) + /* List them and ask the user if they want to stop them */ + if (DialogBoxParamW(hInstance, + MAKEINTRESOURCEW(IDD_DLG_DEPEND_STOP), + pInfo->hMainWnd, + StopDependsDialogProc, + (LPARAM)pInfo) == IDOK) + { + /* Create a progress window to track the progress of the stopping services */ + hProgress = CreateProgressDialog(pInfo->hMainWnd, + IDS_PROGRESS_INFO_STOP); + + /* Stop all the dependant services */ + StopDependantServices(pInfo, lpServiceList, hProgress); + + /* Now stop the requested one */ + bRet = StopService(pInfo, + pInfo->pCurrentService->lpServiceName, + hProgress); + + /* We've already stopped the main service, don't try to stop it again */ + bStopMainService = FALSE; + + if (hProgress) { - /* Stop all the dependant services */ - StopDependantServices(pInfo, pInfo->pCurrentService->lpServiceName); - } - else - { - /* Don't stop the main service if the user selected not to */ - bStop = FALSE; + /* Complete and destroy the progress bar */ + DestroyProgressDialog(hProgress, TRUE); } } + else + { + /* Don't stop the main service if the user selected not to */ + bStopMainService = FALSE; + } } - if (bStop) + /* If the service has no running dependents, then we stop it here */ + if (bStopMainService) { /* Create a progress window to track the progress of the stopping service */ hProgress = CreateProgressDialog(pInfo->hMainWnd, - pInfo->pCurrentService->lpServiceName, IDS_PROGRESS_INFO_STOP); /* Stop the requested service */ diff --git a/reactos/base/applications/mscutils/servman/stop_dependencies.c b/reactos/base/applications/mscutils/servman/stop_dependencies.c index ca4c021e626..a29d43cb4de 100644 --- a/reactos/base/applications/mscutils/servman/stop_dependencies.c +++ b/reactos/base/applications/mscutils/servman/stop_dependencies.c @@ -95,19 +95,25 @@ BuildListOfServicesToStop(LPWSTR *lpServiceList, { for (i = 0; i < dwCount; i++) { - /* Does this service have any dependents? */ - if (TV2_HasDependantServices(lpServiceStatus[i].lpServiceName)) + /* Does this service need stopping? */ + if (lpServiceStatus[i].ServiceStatus.dwCurrentState != SERVICE_STOPPED && + lpServiceStatus[i].ServiceStatus.dwCurrentState != SERVICE_STOP_PENDING) { - /* recall this function with the dependent */ - BuildListOfServicesToStop(lpServiceList, lpServiceStatus[i].lpServiceName); + /* Does this service have any dependents? */ + if (TV2_HasDependantServices(lpServiceStatus[i].lpServiceName)) + { + /* recall this function with the dependent */ + BuildListOfServicesToStop(lpServiceList, lpServiceStatus[i].lpServiceName); + } + + /* Add the service to the list */ + *lpServiceList = AddServiceToList(lpServiceList, lpServiceStatus[i].lpServiceName); + + /* We've got one */ + bRet = TRUE; } - - /* Add the service to the list */ - *lpServiceList = AddServiceToList(lpServiceList, lpServiceStatus[i].lpServiceName); } - bRet = TRUE; - HeapFree(GetProcessHeap(), 0, lpServiceStatus);