- Create another branch for networking fixes
[reactos.git] / base / applications / mscutils / servman / start.c
1 /*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/mscutils/servman/start.c
5 * PURPOSE: Start a service
6 * COPYRIGHT: Copyright 2005-2009 Ged Murphy <gedmurphy@reactos.org>
7 *
8 */
9
10 #include "precomp.h"
11
12 static BOOL
13 DoStartService(PMAIN_WND_INFO Info,
14 HWND hProgDlg)
15 {
16 SC_HANDLE hSCManager;
17 SC_HANDLE hService;
18 SERVICE_STATUS_PROCESS ServiceStatus;
19 DWORD BytesNeeded = 0;
20 DWORD dwStartTickCount;
21 DWORD dwOldCheckPoint;
22 DWORD dwWaitTime;
23 DWORD dwMaxWait;
24 BOOL bRet = FALSE;
25
26 hSCManager = OpenSCManager(NULL,
27 NULL,
28 SC_MANAGER_ALL_ACCESS);
29 if (!hSCManager)
30 {
31 return FALSE;
32 }
33
34 hService = OpenService(hSCManager,
35 Info->pCurrentService->lpServiceName,
36 SERVICE_START | SERVICE_QUERY_STATUS);
37 if (hService)
38 {
39 bRet = StartService(hService,
40 0,
41 NULL);
42 if (!bRet && GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)
43 {
44 bRet = TRUE;
45 }
46 else if (bRet)
47 {
48 bRet = FALSE;
49
50 if (QueryServiceStatusEx(hService,
51 SC_STATUS_PROCESS_INFO,
52 (LPBYTE)&ServiceStatus,
53 sizeof(SERVICE_STATUS_PROCESS),
54 &BytesNeeded))
55 {
56 dwStartTickCount = GetTickCount();
57 dwOldCheckPoint = ServiceStatus.dwCheckPoint;
58 dwMaxWait = 30000; // 30 secs
59
60 while (ServiceStatus.dwCurrentState != SERVICE_RUNNING)
61 {
62 dwWaitTime = ServiceStatus.dwWaitHint / 10;
63
64 if (!QueryServiceStatusEx(hService,
65 SC_STATUS_PROCESS_INFO,
66 (LPBYTE)&ServiceStatus,
67 sizeof(SERVICE_STATUS_PROCESS),
68 &BytesNeeded))
69 {
70 break;
71 }
72
73 if (ServiceStatus.dwCheckPoint > dwOldCheckPoint)
74 {
75 /* The service is making progress*/
76 dwStartTickCount = GetTickCount();
77 dwOldCheckPoint = ServiceStatus.dwCheckPoint;
78 }
79 else
80 {
81 if (GetTickCount() >= dwStartTickCount + dwMaxWait)
82 {
83 /* We exceeded our max wait time, give up */
84 break;
85 }
86 }
87
88 if (dwWaitTime < 200)
89 dwWaitTime = 200;
90 else if (dwWaitTime > 10000)
91 dwWaitTime = 10000;
92
93 Sleep(dwWaitTime);
94 }
95
96 if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
97 {
98 bRet = TRUE;
99 }
100 }
101 }
102
103 CloseServiceHandle(hService);
104 }
105
106 CloseServiceHandle(hSCManager);
107
108
109 return bRet;
110 }
111
112 BOOL
113 DoStart(PMAIN_WND_INFO Info)
114 {
115 HWND hProgDlg;
116 BOOL bRet = FALSE;
117
118 hProgDlg = CreateProgressDialog(Info->hMainWnd,
119 Info->pCurrentService->lpServiceName,
120 IDS_PROGRESS_INFO_START);
121
122 if (hProgDlg)
123 {
124 IncrementProgressBar(hProgDlg);
125
126 bRet = DoStartService(Info,
127 hProgDlg);
128
129 if (bRet)
130 {
131 CompleteProgressBar(hProgDlg);
132 Sleep(500);
133 bRet = TRUE;
134 }
135 else
136 {
137 GetError();
138 }
139
140 DestroyWindow(hProgDlg);
141 }
142
143 return bRet;
144 }
145