- Reimplement service stop routines.

- Stopping single services should now work again, full dependency trees won't yet.

svn path=/trunk/; revision=44951
This commit is contained in:
Ged Murphy 2010-01-05 18:08:41 +00:00
parent 05c33f5b6b
commit 40d9015811
5 changed files with 182 additions and 96 deletions

View file

@ -48,7 +48,7 @@ Control(PMAIN_WND_INFO Info,
DWORD dwOldCheckPoint = ServiceStatus.dwCheckPoint; DWORD dwOldCheckPoint = ServiceStatus.dwCheckPoint;
DWORD dwMaxWait = 2000 * 60; // wait for 2 mins DWORD dwMaxWait = 2000 * 60; // wait for 2 mins
IncrementProgressBar(hProgDlg); IncrementProgressBar(hProgDlg, DEFAULT_STEP);
while (ServiceStatus.dwCurrentState != Control) while (ServiceStatus.dwCurrentState != Control)
{ {
@ -66,7 +66,7 @@ Control(PMAIN_WND_INFO Info,
if (ServiceStatus.dwCheckPoint > dwOldCheckPoint) if (ServiceStatus.dwCheckPoint > dwOldCheckPoint)
{ {
/* The service is making progress, increment the progress bar */ /* The service is making progress, increment the progress bar */
IncrementProgressBar(hProgDlg); IncrementProgressBar(hProgDlg, DEFAULT_STEP);
dwStartTickCount = GetTickCount(); dwStartTickCount = GetTickCount();
dwOldCheckPoint = ServiceStatus.dwCheckPoint; dwOldCheckPoint = ServiceStatus.dwCheckPoint;
} }

View file

@ -94,8 +94,10 @@ BOOL DoPause(PMAIN_WND_INFO Info);
BOOL DoResume(PMAIN_WND_INFO Info); BOOL DoResume(PMAIN_WND_INFO Info);
/* progress.c */ /* progress.c */
HWND CreateProgressDialog(HWND hParent, LPTSTR lpServiceName, UINT Event); #define DEFAULT_STEP 0
VOID IncrementProgressBar(HWND hProgDlg); HWND CreateProgressDialog(HWND hParent, LPTSTR lpServiceName, UINT LabelId);
BOOL DestroyProgressDialog(HWND hProgDlg, BOOL bComplete);
VOID IncrementProgressBar(HWND hProgDlg, UINT NewPos);
VOID CompleteProgressBar(HWND hProgDlg); VOID CompleteProgressBar(HWND hProgDlg);
/* query.c */ /* query.c */

View file

@ -18,41 +18,51 @@ CompleteProgressBar(HWND hProgDlg)
hProgBar = GetDlgItem(hProgDlg, hProgBar = GetDlgItem(hProgDlg,
IDC_SERVCON_PROGRESS); IDC_SERVCON_PROGRESS);
if (hProgBar) if (hProgBar)
{ {
INT pos = 0; INT pos = 0;
pos = SendMessage(hProgBar, pos = SendMessageW(hProgBar,
PBM_GETPOS, PBM_GETPOS,
0, 0,
0); 0);
for (; pos <= PROGRESSRANGE; pos++) while (pos <= PROGRESSRANGE)
{ {
SendMessage(hProgBar, SendMessageW(hProgBar,
PBM_DELTAPOS, PBM_DELTAPOS,
pos, pos,
0); 0);
Sleep(15); Sleep(15);
pos++;
} }
} }
} }
VOID VOID
IncrementProgressBar(HWND hProgDlg) IncrementProgressBar(HWND hProgDlg,
UINT NewPos)
{ {
HWND hProgBar; HWND hProgBar;
hProgBar = GetDlgItem(hProgDlg, hProgBar = GetDlgItem(hProgDlg,
IDC_SERVCON_PROGRESS); IDC_SERVCON_PROGRESS);
if (hProgBar) if (hProgBar)
{ {
SendMessage(hProgBar, if (NewPos == DEFAULT_STEP)
PBM_STEPIT, {
0, SendMessageW(hProgBar,
0); PBM_STEPIT,
0,
0);
}
else
{
SendMessageW(hProgBar,
PBM_SETPOS,
NewPos,
0);
}
} }
} }
@ -68,18 +78,21 @@ ProgressDialogProc(HWND hDlg,
{ {
HWND hProgBar; HWND hProgBar;
/* set the progress bar range and step */ /* Get a handle to the progress bar */
hProgBar = GetDlgItem(hDlg, hProgBar = GetDlgItem(hDlg,
IDC_SERVCON_PROGRESS); IDC_SERVCON_PROGRESS);
SendMessage(hProgBar,
PBM_SETRANGE,
0,
MAKELPARAM(0, PROGRESSRANGE));
SendMessage(hProgBar, /* Set the progress bar range */
PBM_SETSTEP, SendMessageW(hProgBar,
(WPARAM)1, PBM_SETRANGE,
0); 0,
MAKELPARAM(0, PROGRESSRANGE));
/* Set the progress bar step */
SendMessageW(hProgBar,
PBM_SETSTEP,
(WPARAM)1,
0);
} }
break; break;
@ -98,43 +111,70 @@ ProgressDialogProc(HWND hDlg,
} }
return TRUE; return TRUE;
} }
HWND HWND
CreateProgressDialog(HWND hParent, CreateProgressDialog(HWND hParent,
LPTSTR lpServiceName, LPTSTR lpServiceName,
UINT Event) UINT LabelId)
{ {
HWND hProgDlg; HWND hProgDlg;
TCHAR ProgDlgBuf[100]; LPWSTR lpProgStr;
/* open the progress dialog */ /* open the progress dialog */
hProgDlg = CreateDialog(hInstance, hProgDlg = CreateDialogW(hInstance,
MAKEINTRESOURCE(IDD_DLG_PROGRESS), MAKEINTRESOURCEW(IDD_DLG_PROGRESS),
hParent, hParent,
ProgressDialogProc); ProgressDialogProc);
if (hProgDlg != NULL) if (hProgDlg != NULL)
{ {
/* write the info to the progress dialog */ /* Load the label Id */
LoadString(hInstance, if (AllocAndLoadString(&lpProgStr,
Event, hInstance,
ProgDlgBuf, LabelId))
sizeof(ProgDlgBuf) / sizeof(TCHAR)); {
/* Write it to the dialog */
SendDlgItemMessageW(hProgDlg,
IDC_SERVCON_INFO,
WM_SETTEXT,
0,
(LPARAM)lpProgStr);
SendDlgItemMessage(hProgDlg, HeapFree(GetProcessHeap(),
IDC_SERVCON_INFO, 0,
WM_SETTEXT, lpProgStr);
0, }
(LPARAM)ProgDlgBuf);
/* write the service name to the progress dialog */ /* Write the service name to the dialog */
SendDlgItemMessage(hProgDlg, SendDlgItemMessageW(hProgDlg,
IDC_SERVCON_NAME, IDC_SERVCON_NAME,
WM_SETTEXT, WM_SETTEXT,
0, 0,
(LPARAM)lpServiceName); (LPARAM)lpServiceName);
} }
return hProgDlg; 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;
}

View file

@ -121,7 +121,7 @@ DoStart(PMAIN_WND_INFO Info)
if (hProgDlg) if (hProgDlg)
{ {
IncrementProgressBar(hProgDlg); IncrementProgressBar(hProgDlg, DEFAULT_STEP);
bRet = DoStartService(Info, bRet = DoStartService(Info,
hProgDlg); hProgDlg);

View file

@ -12,61 +12,98 @@
static BOOL static BOOL
StopService(PMAIN_WND_INFO pInfo, StopService(PMAIN_WND_INFO pInfo,
LPWSTR lpServiceName) LPWSTR lpServiceName,
HWND hProgress OPTIONAL)
{ {
//SERVICE_STATUS_PROCESS ServiceStatus; SC_HANDLE hSCManager;
//DWORD dwBytesNeeded; SC_HANDLE hService;
//DWORD dwStartTime; SERVICE_STATUS_PROCESS ServiceStatus;
// DWORD dwTimeout; DWORD dwBytesNeeded;
//HWND hProgDlg; DWORD dwStartTime;
DWORD dwTimeout;
BOOL bRet = FALSE; BOOL bRet = FALSE;
/*
dwStartTime = GetTickCount();
dwTimeout = 30000; // 30 secs
hProgDlg = CreateProgressDialog(pStopInfo->pInfo->hMainWnd, if (hProgress)
pStopInfo->pInfo->pCurrentService->lpServiceName,
IDS_PROGRESS_INFO_STOP);
if (hProgDlg)
{ {
IncrementProgressBar(hProgDlg); /* Increment the progress bar */
IncrementProgressBar(hProgress, DEFAULT_STEP);
}
if (ControlService(hService, hSCManager = OpenSCManager(NULL,
SERVICE_CONTROL_STOP, NULL,
(LPSERVICE_STATUS)&ServiceStatus)) 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, /* Set the wait time to 30 secs */
SC_STATUS_PROCESS_INFO, dwStartTime = GetTickCount();
(LPBYTE)&ServiceStatus, dwTimeout = 30000;
sizeof(SERVICE_STATUS_PROCESS),
&dwBytesNeeded)) /* 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 /* Increment the progress bar */
break; 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) CloseServiceHandle(hService);
{
bRet = TRUE;
}
} }
CompleteProgressBar(hProgDlg); CloseServiceHandle(hSCManager);
Sleep(500);
DestroyWindow(hProgDlg);
} }
*/
return bRet; return bRet;
} }
static BOOL static BOOL
StopDependantServices(PMAIN_WND_INFO pInfo, StopDependantServices(PMAIN_WND_INFO pInfo,
LPWSTR lpServiceName) LPWSTR lpServiceName)
@ -118,6 +155,7 @@ StopDependantServices(PMAIN_WND_INFO pInfo,
BOOL BOOL
DoStop(PMAIN_WND_INFO pInfo) DoStop(PMAIN_WND_INFO pInfo)
{ {
HWND hProgress;
LPWSTR lpServiceList; LPWSTR lpServiceList;
BOOL bRet = FALSE; BOOL bRet = FALSE;
@ -138,18 +176,24 @@ DoStop(PMAIN_WND_INFO pInfo)
(LPARAM)lpServiceList) == IDOK) (LPARAM)lpServiceList) == IDOK)
{ {
/* Stop all the dependant services */ /* Stop all the dependant services */
if (StopDependantServices(pInfo, pInfo->pCurrentService->lpServiceName)) StopDependantServices(pInfo, pInfo->pCurrentService->lpServiceName);
{
/* Finally stop the requested service */
bRet = StopService(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 */ DestroyProgressDialog(hProgress, TRUE);
bRet = StopService(pInfo, pInfo->pCurrentService->lpServiceName);
} }
} }