The real, definitive, Visual C++ support branch. Accept no substitutes
[reactos.git] / base / applications / mscutils / servman / control.c
1 /*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/mscutils/servman/control.c
5 * PURPOSE: Stops, pauses and resumes a service
6 * COPYRIGHT: Copyright 2006-2007 Ged Murphy <gedmurphy@reactos.org>
7 *
8 */
9
10 #include "precomp.h"
11
12 BOOL
13 Control(PMAIN_WND_INFO Info,
14 HWND hProgDlg,
15 DWORD Control)
16 {
17 SC_HANDLE hSCManager;
18 SC_HANDLE hSc;
19 SERVICE_STATUS_PROCESS ServiceStatus;
20 SERVICE_STATUS Status;
21 DWORD BytesNeeded = 0;
22 BOOL bRet = FALSE;
23 BOOL bDispErr = TRUE;
24
25 hSCManager = OpenSCManager(NULL,
26 NULL,
27 SC_MANAGER_ALL_ACCESS);
28 if (hSCManager != NULL)
29 {
30 hSc = OpenService(hSCManager,
31 Info->pCurrentService->lpServiceName,
32 SERVICE_ALL_ACCESS);
33 if (hSc != NULL)
34 {
35 if (ControlService(hSc,
36 Control,
37 &Status))
38 {
39 bDispErr = FALSE;
40
41 if (QueryServiceStatusEx(hSc,
42 SC_STATUS_PROCESS_INFO,
43 (LPBYTE)&ServiceStatus,
44 sizeof(SERVICE_STATUS_PROCESS),
45 &BytesNeeded))
46 {
47 DWORD dwStartTickCount = GetTickCount();
48 DWORD dwOldCheckPoint = ServiceStatus.dwCheckPoint;
49 DWORD dwMaxWait = 2000 * 60; // wait for 2 mins
50
51 IncrementProgressBar(hProgDlg);
52
53 while (ServiceStatus.dwCurrentState != Control)
54 {
55 DWORD dwWaitTime = ServiceStatus.dwWaitHint / 10;
56
57 if (!QueryServiceStatusEx(hSc,
58 SC_STATUS_PROCESS_INFO,
59 (LPBYTE)&ServiceStatus,
60 sizeof(SERVICE_STATUS_PROCESS),
61 &BytesNeeded))
62 {
63 break;
64 }
65
66 if (ServiceStatus.dwCheckPoint > dwOldCheckPoint)
67 {
68 /* The service is making progress, increment the progress bar */
69 IncrementProgressBar(hProgDlg);
70 dwStartTickCount = GetTickCount();
71 dwOldCheckPoint = ServiceStatus.dwCheckPoint;
72 }
73 else
74 {
75 if(GetTickCount() >= dwStartTickCount + dwMaxWait)
76 {
77 /* give up */
78 break;
79 }
80 }
81
82 if(dwWaitTime < 200)
83 dwWaitTime = 200;
84 else if (dwWaitTime > 10000)
85 dwWaitTime = 10000;
86
87 Sleep(dwWaitTime);
88 }
89 }
90 }
91
92 CloseServiceHandle(hSc);
93 }
94
95 CloseServiceHandle(hSCManager);
96 }
97
98 if (ServiceStatus.dwCurrentState == Control)
99 {
100 CompleteProgressBar(hProgDlg);
101 Sleep(500);
102 bRet = TRUE;
103 }
104 else
105 {
106 if (bDispErr)
107 GetError();
108 else
109 DisplayString(_T("The service failed to start"));
110 }
111
112 return bRet;
113
114
115 }
116
117
118 BOOL DoPause(PMAIN_WND_INFO Info)
119 {
120 BOOL ret = FALSE;
121 HWND hProgDlg;
122
123 hProgDlg = CreateProgressDialog(Info->hMainWnd,
124 Info->pCurrentService->lpServiceName,
125 IDS_PROGRESS_INFO_PAUSE);
126 if (hProgDlg)
127 {
128 ret = Control(Info,
129 hProgDlg,
130 SERVICE_CONTROL_PAUSE);
131
132 DestroyWindow(hProgDlg);
133 }
134
135 return ret;
136 }
137
138
139 BOOL DoResume(PMAIN_WND_INFO Info)
140 {
141 BOOL ret = FALSE;
142 HWND hProgDlg;
143
144 hProgDlg = CreateProgressDialog(Info->hMainWnd,
145 Info->pCurrentService->lpServiceName,
146 IDS_PROGRESS_INFO_RESUME);
147 if (hProgDlg)
148 {
149 ret = Control(Info,
150 hProgDlg,
151 SERVICE_CONTROL_CONTINUE);
152
153 DestroyWindow(hProgDlg);
154 }
155
156 return ret;
157 }