ReactOS  0.4.12-dev-18-gf469aca
control.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/control.c
5  * PURPOSE: Pauses and resumes a service
6  * COPYRIGHT: Copyright 2006-2015 Ged Murphy <gedmurphy@reactos.org>
7  *
8  */
9 
10 #include "precomp.h"
11 
12 #define MAX_WAIT_TIME 30000
13 
14 BOOL
16  HWND hProgress,
17  DWORD Control)
18 {
19  SC_HANDLE hSCManager;
20  SC_HANDLE hService;
23  DWORD BytesNeeded = 0;
24  DWORD StartTickCount;
25  DWORD OldCheckPoint;
26  DWORD WaitTime;
27  DWORD MaxWait;
28  DWORD ReqState, i;
29  BOOL Result;
30 
31  /* Set the state we're interested in */
32  switch (Control)
33  {
35  ReqState = SERVICE_PAUSED;
36  break;
38  ReqState = SERVICE_RUNNING;
39  break;
40  default:
41  /* Unhandled control code */
42  return FALSE;
43  }
44 
45  hSCManager = OpenSCManagerW(NULL,
46  NULL,
48  if (!hSCManager) return FALSE;
49 
50  hService = OpenServiceW(hSCManager,
51  ServiceName,
53  if (!hService)
54  {
55  CloseServiceHandle(hSCManager);
56  return FALSE;
57  }
58 
59  /* Send the control message to the service */
60  Result = ControlService(hService,
61  Control,
62  &Status);
63  if (Result)
64  {
65  if (hProgress)
66  {
67  /* Increment the progress bar */
69  }
70 
71  /* Get the service status */
72  Result = QueryServiceStatusEx(hService,
74  (LPBYTE)&ServiceStatus,
75  sizeof(SERVICE_STATUS_PROCESS),
76  &BytesNeeded);
77  if (Result)
78  {
79  Result = FALSE;
80  MaxWait = MAX_WAIT_TIME;
81  OldCheckPoint = ServiceStatus.dwCheckPoint;
82  StartTickCount = GetTickCount();
83 
84  /* Loop until it's at the correct state */
85  while (ServiceStatus.dwCurrentState != ReqState)
86  {
87  /* Fixup the wait time */
88  WaitTime = ServiceStatus.dwWaitHint / 10;
89 
90  if (WaitTime < 1000) WaitTime = 1000;
91  else if (WaitTime > 10000) WaitTime = 10000;
92 
93  /* We don't wanna wait for up to 10 secs without incrementing */
94  for (i = WaitTime / 1000; i > 0; i--)
95  {
96  Sleep(1000);
97  if (hProgress)
98  {
99  /* Increment the progress bar */
101  }
102  }
103 
104  /* Get the latest status info */
105  if (!QueryServiceStatusEx(hService,
107  (LPBYTE)&ServiceStatus,
108  sizeof(SERVICE_STATUS_PROCESS),
109  &BytesNeeded))
110  {
111  /* Something went wrong... */
112  break;
113  }
114 
115  /* Is the service making progress? */
116  if (ServiceStatus.dwCheckPoint > OldCheckPoint)
117  {
118  /* It is, get the latest tickcount to reset the max wait time */
119  StartTickCount = GetTickCount();
120  OldCheckPoint = ServiceStatus.dwCheckPoint;
122  }
123  else
124  {
125  /* It's not, make sure we haven't exceeded our wait time */
126  if(GetTickCount() >= StartTickCount + MaxWait)
127  {
128  /* We have, give up */
129  break;
130  }
131  }
132  }
133  }
134 
135  if (ServiceStatus.dwCurrentState == ReqState)
136  {
137  Result = TRUE;
138  }
139  }
140 
141  CloseServiceHandle(hService);
142  CloseServiceHandle(hSCManager);
143 
144  return Result;
145 }
#define TRUE
Definition: types.h:120
#define MAX_WAIT_TIME
Definition: control.c:12
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
#define SERVICE_PAUSED
Definition: winsvc.h:27
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
#define SERVICE_INTERROGATE
Definition: winsvc.h:60
BOOL WINAPI QueryServiceStatusEx(SC_HANDLE hService, SC_STATUS_TYPE InfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2829
GLenum GLclampf GLint i
Definition: glfuncs.h:14
unsigned char * LPBYTE
Definition: typedefs.h:52
#define SERVICE_RUNNING
Definition: winsvc.h:24
SC_HANDLE WINAPI OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2102
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:576
smooth NULL
Definition: ftsmooth.c:416
BOOL Control(DWORD Control, LPCTSTR ServiceName, LPCTSTR *Args, INT ArgCount)
Definition: control.c:13
_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
#define SERVICE_QUERY_STATUS
Definition: winsvc.h:55
unsigned int BOOL
Definition: ntddk_ex.h:94
LPTSTR ServiceName
Definition: ServiceMain.c:15
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SERVICE_CONTROL_PAUSE
Definition: winsvc.h:37
SC_HANDLE WINAPI OpenSCManagerW(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess)
Definition: scm.c:2010
SC_HANDLE hSCManager
Definition: sc.c:12
Status
Definition: gdiplustypes.h:24
VOID IncrementProgressBar(HANDLE hProgress, UINT NewPos)
Definition: progress.c:288
#define DEFAULT_STEP
Definition: precomp.h:108
#define SERVICE_CONTROL_CONTINUE
Definition: winsvc.h:38
BOOL WINAPI ControlService(SC_HANDLE hService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:618
SERVICE_STATUS ServiceStatus
Definition: dhcpcsvc.c:18
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define SERVICE_PAUSE_CONTINUE
Definition: winsvc.h:59
BOOL DoControlService(LPWSTR ServiceName, HWND hProgress, DWORD Control)
Definition: control.c:15