From 40d90158115771edb76ab62278384da588c4b385 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Tue, 5 Jan 2010 18:08:41 +0000 Subject: [PATCH] - Reimplement service stop routines. - Stopping single services should now work again, full dependency trees won't yet. svn path=/trunk/; revision=44951 --- .../applications/mscutils/servman/control.c | 4 +- .../applications/mscutils/servman/precomp.h | 6 +- .../applications/mscutils/servman/progress.c | 136 +++++++++++------- .../applications/mscutils/servman/start.c | 2 +- .../base/applications/mscutils/servman/stop.c | 130 +++++++++++------ 5 files changed, 182 insertions(+), 96 deletions(-) diff --git a/reactos/base/applications/mscutils/servman/control.c b/reactos/base/applications/mscutils/servman/control.c index 8ccf6fc43f4..88e470658e5 100644 --- a/reactos/base/applications/mscutils/servman/control.c +++ b/reactos/base/applications/mscutils/servman/control.c @@ -48,7 +48,7 @@ Control(PMAIN_WND_INFO Info, DWORD dwOldCheckPoint = ServiceStatus.dwCheckPoint; DWORD dwMaxWait = 2000 * 60; // wait for 2 mins - IncrementProgressBar(hProgDlg); + IncrementProgressBar(hProgDlg, DEFAULT_STEP); while (ServiceStatus.dwCurrentState != Control) { @@ -66,7 +66,7 @@ Control(PMAIN_WND_INFO Info, if (ServiceStatus.dwCheckPoint > dwOldCheckPoint) { /* The service is making progress, increment the progress bar */ - IncrementProgressBar(hProgDlg); + IncrementProgressBar(hProgDlg, DEFAULT_STEP); dwStartTickCount = GetTickCount(); dwOldCheckPoint = ServiceStatus.dwCheckPoint; } diff --git a/reactos/base/applications/mscutils/servman/precomp.h b/reactos/base/applications/mscutils/servman/precomp.h index 062cd2daa62..a2f222ee916 100644 --- a/reactos/base/applications/mscutils/servman/precomp.h +++ b/reactos/base/applications/mscutils/servman/precomp.h @@ -94,8 +94,10 @@ BOOL DoPause(PMAIN_WND_INFO Info); BOOL DoResume(PMAIN_WND_INFO Info); /* progress.c */ -HWND CreateProgressDialog(HWND hParent, LPTSTR lpServiceName, UINT Event); -VOID IncrementProgressBar(HWND hProgDlg); +#define DEFAULT_STEP 0 +HWND CreateProgressDialog(HWND hParent, LPTSTR lpServiceName, UINT LabelId); +BOOL DestroyProgressDialog(HWND hProgDlg, BOOL bComplete); +VOID IncrementProgressBar(HWND hProgDlg, UINT NewPos); VOID CompleteProgressBar(HWND hProgDlg); /* query.c */ diff --git a/reactos/base/applications/mscutils/servman/progress.c b/reactos/base/applications/mscutils/servman/progress.c index e6c01feefc2..b38767020d6 100644 --- a/reactos/base/applications/mscutils/servman/progress.c +++ b/reactos/base/applications/mscutils/servman/progress.c @@ -18,41 +18,51 @@ CompleteProgressBar(HWND hProgDlg) hProgBar = GetDlgItem(hProgDlg, IDC_SERVCON_PROGRESS); - if (hProgBar) { INT pos = 0; - pos = SendMessage(hProgBar, - PBM_GETPOS, - 0, - 0); + pos = SendMessageW(hProgBar, + PBM_GETPOS, + 0, + 0); - for (; pos <= PROGRESSRANGE; pos++) + while (pos <= PROGRESSRANGE) { - SendMessage(hProgBar, - PBM_DELTAPOS, - pos, - 0); + SendMessageW(hProgBar, + PBM_DELTAPOS, + pos, + 0); Sleep(15); + pos++; } } } VOID -IncrementProgressBar(HWND hProgDlg) +IncrementProgressBar(HWND hProgDlg, + UINT NewPos) { HWND hProgBar; hProgBar = GetDlgItem(hProgDlg, IDC_SERVCON_PROGRESS); - if (hProgBar) { - SendMessage(hProgBar, - PBM_STEPIT, - 0, - 0); + if (NewPos == DEFAULT_STEP) + { + SendMessageW(hProgBar, + PBM_STEPIT, + 0, + 0); + } + else + { + SendMessageW(hProgBar, + PBM_SETPOS, + NewPos, + 0); + } } } @@ -68,18 +78,21 @@ ProgressDialogProc(HWND hDlg, { HWND hProgBar; - /* set the progress bar range and step */ + /* Get a handle to the progress bar */ hProgBar = GetDlgItem(hDlg, IDC_SERVCON_PROGRESS); - SendMessage(hProgBar, - PBM_SETRANGE, - 0, - MAKELPARAM(0, PROGRESSRANGE)); - SendMessage(hProgBar, - PBM_SETSTEP, - (WPARAM)1, - 0); + /* Set the progress bar range */ + SendMessageW(hProgBar, + PBM_SETRANGE, + 0, + MAKELPARAM(0, PROGRESSRANGE)); + + /* Set the progress bar step */ + SendMessageW(hProgBar, + PBM_SETSTEP, + (WPARAM)1, + 0); } break; @@ -98,43 +111,70 @@ ProgressDialogProc(HWND hDlg, } return TRUE; - } HWND CreateProgressDialog(HWND hParent, LPTSTR lpServiceName, - UINT Event) + UINT LabelId) { HWND hProgDlg; - TCHAR ProgDlgBuf[100]; + LPWSTR lpProgStr; /* open the progress dialog */ - hProgDlg = CreateDialog(hInstance, - MAKEINTRESOURCE(IDD_DLG_PROGRESS), - hParent, - ProgressDialogProc); + hProgDlg = CreateDialogW(hInstance, + MAKEINTRESOURCEW(IDD_DLG_PROGRESS), + hParent, + ProgressDialogProc); if (hProgDlg != NULL) { - /* write the info to the progress dialog */ - LoadString(hInstance, - Event, - ProgDlgBuf, - sizeof(ProgDlgBuf) / sizeof(TCHAR)); + /* Load the label Id */ + if (AllocAndLoadString(&lpProgStr, + hInstance, + LabelId)) + { + /* Write it to the dialog */ + SendDlgItemMessageW(hProgDlg, + IDC_SERVCON_INFO, + WM_SETTEXT, + 0, + (LPARAM)lpProgStr); - SendDlgItemMessage(hProgDlg, - IDC_SERVCON_INFO, - WM_SETTEXT, - 0, - (LPARAM)ProgDlgBuf); + HeapFree(GetProcessHeap(), + 0, + lpProgStr); + } - /* write the service name to the progress dialog */ - SendDlgItemMessage(hProgDlg, - IDC_SERVCON_NAME, - WM_SETTEXT, - 0, - (LPARAM)lpServiceName); + /* Write the service name to the dialog */ + SendDlgItemMessageW(hProgDlg, + IDC_SERVCON_NAME, + WM_SETTEXT, + 0, + (LPARAM)lpServiceName); } return hProgDlg; } + +BOOL +DestroyProgressDialog(HWND hwnd, + BOOL bComplete) +{ + BOOL bRet = FALSE; + + if (hwnd) + { + if (bComplete) + { + /* Complete the progress bar */ + CompleteProgressBar(hwnd); + + /* Wait for asthetics */ + Sleep(500); + } + + bRet = DestroyWindow(hwnd); + } + + return bRet; +} diff --git a/reactos/base/applications/mscutils/servman/start.c b/reactos/base/applications/mscutils/servman/start.c index dfdb4615af2..0f051f23340 100644 --- a/reactos/base/applications/mscutils/servman/start.c +++ b/reactos/base/applications/mscutils/servman/start.c @@ -121,7 +121,7 @@ DoStart(PMAIN_WND_INFO Info) if (hProgDlg) { - IncrementProgressBar(hProgDlg); + IncrementProgressBar(hProgDlg, DEFAULT_STEP); bRet = DoStartService(Info, hProgDlg); diff --git a/reactos/base/applications/mscutils/servman/stop.c b/reactos/base/applications/mscutils/servman/stop.c index 1a97d5f5749..16e3ab239dc 100644 --- a/reactos/base/applications/mscutils/servman/stop.c +++ b/reactos/base/applications/mscutils/servman/stop.c @@ -12,61 +12,98 @@ static BOOL StopService(PMAIN_WND_INFO pInfo, - LPWSTR lpServiceName) + LPWSTR lpServiceName, + HWND hProgress OPTIONAL) { - //SERVICE_STATUS_PROCESS ServiceStatus; - //DWORD dwBytesNeeded; - //DWORD dwStartTime; - // DWORD dwTimeout; - //HWND hProgDlg; + SC_HANDLE hSCManager; + SC_HANDLE hService; + SERVICE_STATUS_PROCESS ServiceStatus; + DWORD dwBytesNeeded; + DWORD dwStartTime; + DWORD dwTimeout; BOOL bRet = FALSE; -/* - dwStartTime = GetTickCount(); - dwTimeout = 30000; // 30 secs - hProgDlg = CreateProgressDialog(pStopInfo->pInfo->hMainWnd, - pStopInfo->pInfo->pCurrentService->lpServiceName, - IDS_PROGRESS_INFO_STOP); - if (hProgDlg) + if (hProgress) { - IncrementProgressBar(hProgDlg); + /* Increment the progress bar */ + IncrementProgressBar(hProgress, DEFAULT_STEP); + } - if (ControlService(hService, - SERVICE_CONTROL_STOP, - (LPSERVICE_STATUS)&ServiceStatus)) + hSCManager = OpenSCManager(NULL, + NULL, + SC_MANAGER_CONNECT); + if (hSCManager) + { + hService = OpenService(hSCManager, + lpServiceName, + SERVICE_STOP | SERVICE_QUERY_STATUS); + if (hService) { - while (ServiceStatus.dwCurrentState != SERVICE_STOPPED) + if (hProgress) { - Sleep(ServiceStatus.dwWaitHint); + /* Increment the progress bar */ + IncrementProgressBar(hProgress, DEFAULT_STEP); + } - if (QueryServiceStatusEx(hService, - SC_STATUS_PROCESS_INFO, - (LPBYTE)&ServiceStatus, - sizeof(SERVICE_STATUS_PROCESS), - &dwBytesNeeded)) + /* Set the wait time to 30 secs */ + dwStartTime = GetTickCount(); + dwTimeout = 30000; + + /* Send the service the stop code */ + if (ControlService(hService, + SERVICE_CONTROL_STOP, + (LPSERVICE_STATUS)&ServiceStatus)) + { + if (hProgress) { - if (GetTickCount() - dwStartTime > dwTimeout) + /* Increment the progress bar */ + IncrementProgressBar(hProgress, DEFAULT_STEP); + } + + while (ServiceStatus.dwCurrentState != SERVICE_STOPPED) + { + Sleep(ServiceStatus.dwWaitHint); + + if (hProgress) { - We exceeded our max wait time, give up - break; + /* Increment the progress bar */ + IncrementProgressBar(hProgress, DEFAULT_STEP); } + + if (QueryServiceStatusEx(hService, + SC_STATUS_PROCESS_INFO, + (LPBYTE)&ServiceStatus, + sizeof(SERVICE_STATUS_PROCESS), + &dwBytesNeeded)) + { + /* Have we exceeded our wait time? */ + if (GetTickCount() - dwStartTime > dwTimeout) + { + /* Yep, give up */ + break; + } + } + } + + /* If the service is stopped, return TRUE */ + if (ServiceStatus.dwCurrentState == SERVICE_STOPPED) + { + bRet = TRUE; } } - if (ServiceStatus.dwCurrentState == SERVICE_STOPPED) - { - bRet = TRUE; - } + CloseServiceHandle(hService); } - CompleteProgressBar(hProgDlg); - Sleep(500); - DestroyWindow(hProgDlg); + CloseServiceHandle(hSCManager); } -*/ + return bRet; } + + + static BOOL StopDependantServices(PMAIN_WND_INFO pInfo, LPWSTR lpServiceName) @@ -118,6 +155,7 @@ StopDependantServices(PMAIN_WND_INFO pInfo, BOOL DoStop(PMAIN_WND_INFO pInfo) { + HWND hProgress; LPWSTR lpServiceList; BOOL bRet = FALSE; @@ -138,18 +176,24 @@ DoStop(PMAIN_WND_INFO pInfo) (LPARAM)lpServiceList) == IDOK) { /* Stop all the dependant services */ - if (StopDependantServices(pInfo, pInfo->pCurrentService->lpServiceName)) - { - /* Finally stop the requested service */ - bRet = StopService(pInfo, pInfo->pCurrentService->lpServiceName); - } + StopDependantServices(pInfo, pInfo->pCurrentService->lpServiceName); } } } - else + + /* Create a progress window to track the progress of the stopping service */ + hProgress = CreateProgressDialog(pInfo->hMainWnd, + pInfo->pCurrentService->lpServiceName, + IDS_PROGRESS_INFO_STOP); + + /* Finally, stop the requested service */ + bRet = StopService(pInfo, + pInfo->pCurrentService->lpServiceName, + hProgress); + + if (hProgress) { - /* No dependants, just stop the service */ - bRet = StopService(pInfo, pInfo->pCurrentService->lpServiceName); + DestroyProgressDialog(hProgress, TRUE); } }