ReactOS 0.4.15-dev-5666-gc548b97
start.c
Go to the documentation of this file.
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-2015 Ged Murphy <gedmurphy@reactos.org>
7 *
8 */
9
10#include "precomp.h"
11
12#define NDEBUG
13#include <debug.h>
14
15#define MAX_WAIT_TIME 30000
16
19 HANDLE hProgress,
20 LPWSTR lpStartParams)
21{
22 SC_HANDLE hSCManager;
23 SC_HANDLE hService;
25 DWORD BytesNeeded = 0;
26 DWORD StartTickCount;
27 DWORD OldCheckPoint;
28 DWORD WaitTime;
29 DWORD MaxWait;
31
32 BOOL bWhiteSpace = TRUE;
33 LPWSTR lpChar;
34 DWORD dwArgsCount = 0;
35 DWORD dwResult = ERROR_SUCCESS;
36 LPCWSTR *lpArgsVector = NULL;
37
38 if (lpStartParams != NULL)
39 {
40 /* Count the number of arguments */
41 lpChar = lpStartParams;
42 while (*lpChar != 0)
43 {
44 if (iswspace(*lpChar))
45 {
46 bWhiteSpace = TRUE;
47 }
48 else
49 {
50 if (bWhiteSpace != FALSE)
51 {
52 dwArgsCount++;
53 bWhiteSpace = FALSE;
54 }
55 }
56
57 lpChar++;
58 }
59
60 /*
61 * Allocate the arguments vector.
62 * Do not add the service name here because services.exe does it for us!
63 */
64 lpArgsVector = LocalAlloc(LMEM_FIXED, dwArgsCount * sizeof(LPCWSTR));
65 if (!lpArgsVector)
66 return GetLastError();
67
68 /* Fill the arguments vector */
69 dwArgsCount = 0;
70 bWhiteSpace = TRUE;
71 lpChar = lpStartParams;
72 while (*lpChar != 0)
73 {
74 if (iswspace(*lpChar))
75 {
76 *lpChar = 0;
77 bWhiteSpace = TRUE;
78 }
79 else
80 {
81 if (bWhiteSpace != FALSE)
82 {
83 lpArgsVector[dwArgsCount] = lpChar;
84 dwArgsCount++;
85 bWhiteSpace = FALSE;
86 }
87 }
88
89 lpChar++;
90 }
91 }
92
94 NULL,
96 if (!hSCManager)
97 {
98 dwResult = GetLastError();
99 if (lpArgsVector)
100 LocalFree((LPVOID)lpArgsVector);
101 return dwResult;
102 }
103
104 hService = OpenServiceW(hSCManager,
107 if (!hService)
108 {
109 dwResult = GetLastError();
111 if (lpArgsVector)
112 LocalFree((LPVOID)lpArgsVector);
113 return dwResult;
114 }
115
116 /* Start the service */
117 Result = StartServiceW(hService,
118 dwArgsCount,
119 lpArgsVector);
121 {
122 /* If it's already running, just return TRUE */
123 Result = TRUE;
124 }
125 else if (Result)
126 {
127 if (hProgress)
128 {
129 /* Increment the progress bar */
131 }
132
133 /* Get the service status to check if it's running */
134 Result = QueryServiceStatusEx(hService,
138 &BytesNeeded);
139 if (Result)
140 {
141 Result = FALSE;
142 MaxWait = MAX_WAIT_TIME;
143 OldCheckPoint = ServiceStatus.dwCheckPoint;
144 StartTickCount = GetTickCount();
145
146 /* Loop until it's running */
148 {
149 int i;
150 /* Fixup the wait time */
151 WaitTime = ServiceStatus.dwWaitHint / 10;
152
153 if (WaitTime < 1000) WaitTime = 1000;
154 else if (WaitTime > 10000) WaitTime = 10000;
155
156 /* We don't wanna wait for up to 10 secs without incrementing */
157 for (i = WaitTime / 1000; i > 0; i--)
158 {
159 Sleep(1000);
160 if (hProgress)
161 {
162 /* Increment the progress bar */
164 }
165 }
166
167
168 /* Get the latest status info */
169 if (!QueryServiceStatusEx(hService,
173 &BytesNeeded))
174 {
175 /* Something went wrong... */
176 dwResult = GetLastError();
177 DPRINT1("QueryServiceStatusEx failed: %d\n", dwResult);
178 break;
179 }
180
181 /* Is the service making progress? */
182 if (ServiceStatus.dwCheckPoint > OldCheckPoint)
183 {
184 /* It is, get the latest tickcount to reset the max wait time */
185 StartTickCount = GetTickCount();
186 OldCheckPoint = ServiceStatus.dwCheckPoint;
187 }
188 else
189 {
190 /* It's not, make sure we haven't exceeded our wait time */
191 if (GetTickCount() >= StartTickCount + MaxWait)
192 {
193 /* We have, give up */
194 DPRINT1("Timeout\n");
196 break;
197 }
198 }
199 }
200 }
201 else
202 {
203 dwResult = GetLastError();
204 }
205
207 {
208 dwResult = ERROR_SUCCESS;
209 }
210 }
211
212 CloseServiceHandle(hService);
214
215 if (lpArgsVector)
216 LocalFree((LPVOID)lpArgsVector);
217
218 return dwResult;
219}
DWORD DoStartService(LPWSTR ServiceName, HANDLE hProgress, LPWSTR lpStartParams)
Definition: start.c:18
#define MAX_WAIT_TIME
Definition: start.c:15
#define DEFAULT_STEP
Definition: precomp.h:110
VOID IncrementProgressBar(HANDLE hProgress, UINT NewPos)
Definition: progress.c:338
#define DPRINT1
Definition: precomp.h:8
static WCHAR ServiceName[]
Definition: browser.c:19
static SERVICE_STATUS ServiceStatus
Definition: browser.c:22
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1373
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define iswspace(_c)
Definition: ctype.h:669
SC_HANDLE hSCManager
Definition: sc.c:12
SC_HANDLE WINAPI OpenSCManagerW(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess)
Definition: scm.c:2016
BOOL WINAPI QueryServiceStatusEx(SC_HANDLE hService, SC_STATUS_TYPE InfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2835
SC_HANDLE WINAPI OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2108
BOOL WINAPI StartServiceW(SC_HANDLE hService, DWORD dwNumServiceArgs, LPCWSTR *lpServiceArgVectors)
Definition: scm.c:2928
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:580
DWORD dwWaitHint
Definition: winsvc.h:105
DWORD dwCurrentState
Definition: winsvc.h:100
DWORD dwCheckPoint
Definition: winsvc.h:104
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
unsigned char * LPBYTE
Definition: typedefs.h:53
DWORD WINAPI GetLastError(void)
Definition: except.c:1040
#define LMEM_FIXED
Definition: winbase.h:368
#define ERROR_SERVICE_ALREADY_RUNNING
Definition: winerror.h:607
#define ERROR_SERVICE_REQUEST_TIMEOUT
Definition: winerror.h:604
#define SERVICE_START
Definition: winsvc.h:57
#define SERVICE_QUERY_STATUS
Definition: winsvc.h:55
@ SC_STATUS_PROCESS_INFO
Definition: winsvc.h:119
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
#define SERVICE_RUNNING
Definition: winsvc.h:24
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185