set most of trunk svn property eol-style:native
[reactos.git] / reactos / base / applications / servman / control.c
1 /*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/servman/control
5 * PURPOSE: Stops, pauses and resumes a service
6 * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy@gmail.com>
7 *
8 */
9
10 #include "precomp.h"
11
12 BOOL
13 Control(PMAIN_WND_INFO Info,
14 DWORD Control)
15 {
16 HWND hProgBar;
17 SC_HANDLE hSCManager;
18 SC_HANDLE hSc;
19 SERVICE_STATUS_PROCESS ServiceStatus;
20 SERVICE_STATUS Status;
21 LVITEM item;
22 DWORD BytesNeeded = 0;
23 DWORD dwStartTickCount, dwOldCheckPoint;
24
25 item.mask = LVIF_PARAM;
26 item.iItem = Info->SelectedItem;
27 SendMessage(Info->hListView,
28 LVM_GETITEM,
29 0,
30 (LPARAM)&item);
31
32 /* set the progress bar range and step */
33 hProgBar = GetDlgItem(Info->hProgDlg,
34 IDC_SERVCON_PROGRESS);
35 SendMessage(hProgBar,
36 PBM_SETRANGE,
37 0,
38 MAKELPARAM(0, PROGRESSRANGE));
39
40 SendMessage(hProgBar,
41 PBM_SETSTEP,
42 (WPARAM)1,
43 0);
44
45 /* open handle to the SCM */
46 hSCManager = OpenSCManager(NULL,
47 NULL,
48 SC_MANAGER_ALL_ACCESS);
49 if (hSCManager == NULL)
50 {
51 GetError();
52 return FALSE;
53 }
54
55 /* open handle to the service */
56 hSc = OpenService(hSCManager,
57 Info->CurrentService->lpServiceName,
58 SC_MANAGER_ALL_ACCESS);
59 if (hSc == NULL)
60 {
61 GetError();
62 return FALSE;
63 }
64
65 /* process requested action */
66 if (! ControlService(hSc,
67 Control,
68 &Status))
69 {
70 GetError();
71 CloseServiceHandle(hSc);
72 return FALSE;
73 }
74
75 /* query the state of the service */
76 if (! QueryServiceStatusEx(hSc,
77 SC_STATUS_PROCESS_INFO,
78 (LPBYTE)&ServiceStatus,
79 sizeof(SERVICE_STATUS_PROCESS),
80 &BytesNeeded))
81 {
82 GetError();
83 return FALSE;
84 }
85
86 /* Save the tick count and initial checkpoint. */
87 dwStartTickCount = GetTickCount();
88 dwOldCheckPoint = ServiceStatus.dwCheckPoint;
89
90 /* loop whilst service is not running */
91 /* FIXME: needs more control adding. 'Loop' is temparary */
92 while (ServiceStatus.dwCurrentState != Control)
93 {
94 DWORD dwWaitTime;
95
96 dwWaitTime = ServiceStatus.dwWaitHint / 10;
97
98 if (dwWaitTime < 500)
99 dwWaitTime = 500;
100 else if (dwWaitTime > 5000)
101 dwWaitTime = 5000;
102
103 /* increment the progress bar */
104 SendMessage(hProgBar,
105 PBM_STEPIT,
106 0,
107 0);
108
109 /* wait before checking status */
110 Sleep(dwWaitTime);
111
112 /* check status again */
113 if (! QueryServiceStatusEx(hSc,
114 SC_STATUS_PROCESS_INFO,
115 (LPBYTE)&ServiceStatus,
116 sizeof(SERVICE_STATUS_PROCESS),
117 &BytesNeeded))
118 {
119 GetError();
120 return FALSE;
121 }
122
123 if (ServiceStatus.dwCheckPoint > dwOldCheckPoint)
124 {
125 /* The service is making progress. increment the progress bar */
126 SendMessage(hProgBar,
127 PBM_STEPIT,
128 0,
129 0);
130 dwStartTickCount = GetTickCount();
131 dwOldCheckPoint = ServiceStatus.dwCheckPoint;
132 }
133 else
134 {
135 if(GetTickCount() - dwStartTickCount > ServiceStatus.dwWaitHint)
136 {
137 /* No progress made within the wait hint */
138 break;
139 }
140 }
141 }
142
143 CloseServiceHandle(hSc);
144
145 if (ServiceStatus.dwCurrentState == Control)
146 {
147 SendMessage(hProgBar,
148 PBM_DELTAPOS,
149 PROGRESSRANGE,
150 0);
151 Sleep(1000);
152 return TRUE;
153 }
154 else
155 return FALSE;
156
157 }